asimov_cli/commands/source/snap/
save.rs1use crate::{BoxError, StandardOptions, SysexitsError::*};
4use asimov_env::paths::asimov_root;
5use asimov_module::normalization::normalize_url;
6use clientele::crates::clap::Args;
7use color_print::ceprintln;
8use miette::Result;
9
10#[derive(Args, Clone, Debug, Default)]
11pub struct SnapSaveArgs {
12 urls: Vec<String>,
14}
15
16pub async fn save(args: &SnapSaveArgs, flags: &StandardOptions) -> Result<(), BoxError> {
17 let registry = asimov_registry::Registry::default();
18
19 let _enabled_modules = registry
20 .enabled_modules()
21 .await
22 .map_err(|e| {
23 ceprintln!("<s,r>error:</> unable to access enabled modules: {e}");
24 match e {
25 asimov_registry::error::EnabledModulesError::DirIo(_, err)
26 if err.kind() == std::io::ErrorKind::NotFound => {
27 ceprintln!("<s,dim>hint:</> There appears to be no installed modules.");
28 ceprintln!("<s,dim>hint:</> Modules may be discovered either on the site <u>https://asimov.directory/modules</>");
29 ceprintln!("<s,dim>hint:</> or on the GitHub organization <u>https://github.com/asimov-modules</>");
30 ceprintln!("<s,dim>hint:</> and installed with <s>asimov module install <<module>></>");
31 },
32 _ => (),
33 };
34 EX_UNAVAILABLE
35 })?;
36
37 let storage =
38 asimov_snapshot::storage::Fs::for_dir(asimov_root().join("snapshots")).map_err(|e| {
39 ceprintln!("<s,r>error:</> failed to create snapshot storage: {e}");
40 EX_UNAVAILABLE
41 })?;
42
43 let mut snapshotter = asimov_snapshot::Snapshotter::new(registry, storage, Default::default());
44
45 for input_url in &args.urls {
46 let input_url = normalize_url(&input_url).unwrap_or_else(|e| {
47 if flags.verbose > 1 {
48 ceprintln!(
49 "<s,y>warning:</> using given unmodified URL, normalization failed: {e}"
50 );
51 }
52 input_url.clone()
53 });
54 snapshotter.snapshot(&input_url).await.map_err(|e| {
55 ceprintln!("<s,r>error:</> failed to create snapshot URL <s>{input_url}</>: {e}");
56 EX_UNAVAILABLE
57 })?;
58 }
59
60 Ok(())
61}