wac_cli/commands/
resolve.rs

1use crate::{fmt_err, PackageResolver};
2use anyhow::{Context, Result};
3use clap::Args;
4use std::{fs, path::PathBuf};
5use wac_parser::Document;
6
7fn parse<T, U>(s: &str) -> Result<(T, U)>
8where
9    T: std::str::FromStr,
10    T::Err: Into<anyhow::Error>,
11    U: std::str::FromStr,
12    U::Err: Into<anyhow::Error>,
13{
14    let (k, v) = s.split_once('=').context("value does not contain `=`")?;
15
16    Ok((
17        k.trim().parse().map_err(Into::into)?,
18        v.trim().parse().map_err(Into::into)?,
19    ))
20}
21
22/// Resolves a WAC source file into a DOT representation.
23#[derive(Args)]
24#[clap(disable_version_flag = true)]
25pub struct ResolveCommand {
26    /// The directory to search for package dependencies.
27    #[clap(long, value_name = "PATH", default_value = "deps")]
28    pub deps_dir: PathBuf,
29
30    /// The directory to search for package dependencies.
31    #[clap(long = "dep", short, value_name = "PKG=PATH", value_parser = parse::<String, PathBuf>)]
32    pub deps: Vec<(String, PathBuf)>,
33
34    /// The URL of the registry to use.
35    #[cfg(feature = "registry")]
36    #[clap(long, value_name = "URL")]
37    pub registry: Option<String>,
38
39    /// The path to the source WAC file.
40    #[clap(value_name = "PATH")]
41    pub path: PathBuf,
42}
43
44impl ResolveCommand {
45    /// Executes the command.
46    pub async fn exec(self) -> Result<()> {
47        log::debug!("executing resolve command");
48
49        let contents = fs::read_to_string(&self.path)
50            .with_context(|| format!("failed to read file `{path}`", path = self.path.display()))?;
51
52        let document = Document::parse(&contents).map_err(|e| fmt_err(e, &self.path, &contents))?;
53
54        let mut resolver = PackageResolver::new(
55            self.deps_dir,
56            self.deps.into_iter().collect(),
57            #[cfg(feature = "registry")]
58            self.registry.as_deref(),
59        )
60        .await?;
61
62        let packages = resolver
63            .resolve(&document)
64            .await
65            .map_err(|e| fmt_err(e, &self.path, &contents))?;
66
67        let resolution = document
68            .resolve(packages)
69            .map_err(|e| fmt_err(e, &self.path, &contents))?;
70
71        print!("{:?}", resolution.into_graph());
72
73        Ok(())
74    }
75}