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