Skip to main content

wapm_cli/commands/
add.rs

1//! Code pertaining to the `add` subcommand: it adds dependencies to
2//! the manifest without installing
3
4use crate::graphql::execute_query;
5use graphql_client::*;
6use thiserror::Error;
7
8use crate::data::manifest::Manifest;
9use structopt::StructOpt;
10
11/// Options for the `add` subcommand
12#[derive(StructOpt, Debug)]
13pub struct AddOpt {
14    packages: Vec<String>,
15}
16
17#[derive(GraphQLQuery)]
18#[graphql(
19    schema_path = "graphql/schema.graphql",
20    query_path = "graphql/queries/get_package_version.graphql",
21    response_derives = "Debug"
22)]
23pub(crate) struct GetPackageVersionQuery;
24
25#[derive(Debug, Error)]
26enum AddError {
27    #[error("There were problems adding packages")]
28    GenericError,
29    #[error("Could not find a manifest in the current directory, try running `wapm init`")]
30    NoManifest,
31    #[error("No packages listed to add")]
32    ArgumentsRequired,
33}
34
35/// Run the add command
36pub fn add(options: AddOpt) -> anyhow::Result<()> {
37    let mut error = false;
38    let mut manifest: Manifest = {
39        let cur_dir = crate::config::Config::get_current_dir()?;
40        Manifest::find_in_directory(cur_dir).map_err(|_| AddError::NoManifest)?
41    };
42
43    if options.packages.is_empty() {
44        return Err(AddError::ArgumentsRequired.into());
45    }
46
47    for (package_name, maybe_version) in options.packages.into_iter().map(|package_str| {
48        if package_str.contains('@') {
49            let mut p = package_str.split('@');
50            let package_name = p.next().unwrap();
51            let package_version = p.next().unwrap();
52            (package_name.to_string(), Some(package_version.to_string()))
53        } else {
54            (package_str, None)
55        }
56    }) {
57        let q = GetPackageVersionQuery::build_query(get_package_version_query::Variables {
58            name: package_name.clone(),
59            version: maybe_version.clone(),
60        });
61        let response: get_package_version_query::ResponseData = execute_query(&q)?;
62
63        if let Some(pv) = response.package_version {
64            info!("Adding {}@{}", &package_name, &pv.version);
65            manifest.add_dependency(package_name, pv.version);
66        } else {
67            error = true;
68            if let Some(ver) = maybe_version {
69                error!("Package \"{}@{}\" was not found", &package_name, &ver);
70            } else {
71                error!("Package \"{}\" was not found", &package_name);
72            }
73        }
74    }
75
76    manifest.save()?;
77
78    if error {
79        Err(AddError::GenericError.into())
80    } else {
81        println!("Packages successfully added!");
82        Ok(())
83    }
84}
85
86#[cfg(feature = "integration_tests")]
87impl AddOpt {
88    pub fn new(packages: Vec<String>) -> Self {
89        AddOpt { packages }
90    }
91}