asimov_cli/commands/source/
fetch.rs1use crate::{BoxError, StandardOptions, SysexitsError::*, shared};
4use asimov_module::{ModuleName, normalization::normalize_url, resolve::Resolver};
5use asimov_runner::{FetcherOptions, GraphOutput};
6use clientele::crates::clap::Args;
7use color_print::ceprintln;
8use miette::Result;
9
10#[derive(Args, Clone, Debug, Default)]
11pub struct SourceFetchArgs {
12 #[clap(long, short = 'M')]
16 module: Option<ModuleName>,
17
18 #[arg(value_name = "FORMAT", short = 'o', long)]
20 output: Option<String>,
21
22 urls: Vec<String>,
23}
24
25pub async fn fetch(args: SourceFetchArgs, flags: &StandardOptions) -> Result<(), BoxError> {
26 let registry = asimov_registry::Registry::default();
27
28 let installed_modules = shared::installed_modules(®istry, Some("fetcher")).await?;
29
30 let resolver = Resolver::try_from_iter(installed_modules.iter()).map_err(|e| {
31 ceprintln!("<s,r>error:</> failed to build resolver: {e}");
32 EX_UNAVAILABLE
33 })?;
34
35 for input_url in args.urls {
36 if flags.verbose > 1 {
37 ceprintln!("<s,c>»</> Fetching <s>{}</>...", input_url);
38 }
39
40 let input_url = normalize_url(&input_url).unwrap_or_else(|e| {
41 if flags.verbose > 1 {
42 ceprintln!(
43 "<s,y>warning:</> using given unmodified URL, normalization failed: {e}"
44 );
45 }
46 input_url.clone()
47 });
48
49 let modules = resolver.resolve(&input_url).map_err(|e| {
50 ceprintln!("<s,r>error:</> unable to handle URL <s>{input_url}</>: {e}");
51 EX_USAGE
52 })?;
53
54 let module = shared::pick_module(
55 ®istry,
56 &input_url,
57 modules.as_slice(),
58 args.module.as_deref(),
59 )
60 .await?;
61
62 let mut fetcher = asimov_runner::Fetcher::new(
63 format!("asimov-{}-fetcher", module.name),
64 &input_url,
65 GraphOutput::Inherited,
66 FetcherOptions::builder()
67 .maybe_output(args.output.as_deref())
68 .maybe_other(flags.debug.then_some("--debug"))
69 .build(),
70 );
71
72 let _ = fetcher.execute().await.map_err(|e| {
73 ceprintln!("<s,r>error:</> fetcher execution failed: {e}");
74 EX_UNAVAILABLE
75 })?;
76
77 if flags.verbose > 0 {
78 ceprintln!("<s,g>✓</> Fetched <s>{}</>.", input_url);
79 }
80 }
81
82 Ok(())
83}