warg_cli/commands/
download.rs1use super::CommonOptions;
2use anyhow::Result;
3use clap::Args;
4use dialoguer::{theme::ColorfulTheme, Confirm};
5use std::path::PathBuf;
6use warg_client::ClientError;
7use warg_protocol::{registry::PackageName, VersionReq};
8
9#[derive(Args)]
11#[clap(disable_version_flag = true)]
12pub struct DownloadCommand {
13 #[clap(flatten)]
15 pub common: CommonOptions,
16 #[clap(value_name = "PACKAGE")]
18 pub name: PackageName,
19 #[clap(long, short, value_name = "VERSION")]
21 pub version: Option<String>,
22 #[clap(long, short = 'o')]
24 pub output: Option<PathBuf>,
25}
26
27impl DownloadCommand {
28 pub async fn exec(self) -> Result<()> {
30 let config = self.common.read_config()?;
31 let client = self.common.create_client(&config).await?;
32
33 println!("Downloading `{name}`...", name = self.name);
34
35 let version = match &self.version {
37 Some(version) => VersionReq::parse(&format!("={}", version))?,
38 None => VersionReq::STAR,
39 };
40
41 let download = client
42 .download(&self.name, &version)
43 .await?
44 .ok_or_else(|| ClientError::PackageVersionRequirementDoesNotExist {
45 name: self.name.clone(),
46 version,
47 })?;
48
49 println!(
50 "Downloaded version: {version}\nDigest: {digest}\n",
51 version = download.version,
52 digest = download.digest
53 );
54
55 let default_file_name = format!("{name}.wasm", name = self.name.name());
58 if let Some(path) = self
59 .output
60 .map(|mut p| {
61 if p.extension()
62 .is_some_and(|ext| ext.eq_ignore_ascii_case("wasm"))
63 {
64 p
65 } else {
66 p.push(&default_file_name);
67 p
68 }
69 })
70 .or_else(|| {
71 if Confirm::with_theme(&ColorfulTheme::default())
72 .with_prompt(format!(
73 "Write `{default_file_name}` in current directory? y/N\n",
74 ))
75 .default(true)
76 .interact()
77 .unwrap()
78 {
79 Some(PathBuf::from(default_file_name))
80 } else {
81 None
82 }
83 })
84 {
85 std::fs::copy(download.path, &path)?;
86 println!(
87 "Wrote `{name}` to {path}",
88 name = self.name,
89 path = path.display(),
90 );
91 }
92
93 Ok(())
94 }
95}