1use crate::graphql::execute_query;
5use graphql_client::*;
6use thiserror::Error;
7
8use crate::data::manifest::Manifest;
9use structopt::StructOpt;
10
11#[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
35pub 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}