1use std::{env, ffi::OsString};
2
3use clap::Parser;
4
5use std::sync::Arc;
6
7use crate::backend::resolve_backend_with_notices;
8use crate::cli::Cli;
9use crate::error::{WtgError, WtgResult};
10use crate::resolution::resolve;
11
12pub mod backend;
13pub mod cli;
14pub mod constants;
15pub mod error;
16pub mod git;
17pub mod github;
18pub mod help;
19pub mod notice;
20pub mod output;
21pub mod parse_input;
22pub mod remote;
23pub mod resolution;
24pub mod semver;
25
26pub fn run() -> WtgResult<()> {
28 run_with_args(env::args())
29}
30
31pub fn run_with_args<I, T>(args: I) -> WtgResult<()>
33where
34 I: IntoIterator<Item = T>,
35 T: Into<OsString> + Clone,
36{
37 let cli = match Cli::try_parse_from(args) {
38 Ok(cli) => cli,
39 Err(err) => {
40 if err.kind() == clap::error::ErrorKind::DisplayHelp {
42 help::display_help();
43 return Ok(());
44 }
45 return Err(WtgError::Cli {
47 message: err.to_string(),
48 code: err.exit_code(),
49 });
50 }
51 };
52 run_with_cli(cli)
53}
54
55fn run_with_cli(cli: Cli) -> WtgResult<()> {
56 if cli.input.is_none() {
58 help::display_help();
59 return Ok(());
60 }
61
62 let runtime = tokio::runtime::Builder::new_current_thread()
63 .enable_all()
64 .build()?;
65
66 runtime.block_on(run_async(cli))
67}
68
69async fn run_async(cli: Cli) -> WtgResult<()> {
70 let parsed_input = cli.parse_input()?;
72
73 let notice_cb = Arc::new(output::print_notice);
76
77 let backend = resolve_backend_with_notices(&parsed_input, cli.fetch, notice_cb)?;
79
80 let query = backend.disambiguate_query(parsed_input.query()).await?;
82 let result = resolve(backend.as_ref(), &query).await?;
83
84 output::display(result)?;
86
87 Ok(())
88}