1use clap::Parser;
2
3pub mod cli;
4pub mod constants;
5pub mod error;
6pub mod git;
7pub mod github;
8pub mod help;
9pub mod identifier;
10pub mod output;
11pub mod remote;
12pub mod repo_manager;
13
14use cli::Cli;
15use error::{Result, WtgError};
16use repo_manager::RepoManager;
17
18pub fn run() -> Result<()> {
20 run_with_args(std::env::args())
21}
22
23pub fn run_with_args<I, T>(args: I) -> Result<()>
25where
26 I: IntoIterator<Item = T>,
27 T: Into<std::ffi::OsString> + Clone,
28{
29 let cli = match Cli::try_parse_from(args) {
30 Ok(cli) => cli,
31 Err(err) => {
32 if err.kind() == clap::error::ErrorKind::DisplayHelp {
34 help::display_help();
35 return Ok(());
36 }
37 return Err(WtgError::Cli {
39 message: err.to_string(),
40 code: err.exit_code(),
41 });
42 }
43 };
44 run_with_cli(cli)
45}
46
47fn run_with_cli(cli: Cli) -> Result<()> {
48 if cli.input.is_none() {
50 help::display_help();
51 return Ok(());
52 }
53
54 let runtime = tokio::runtime::Builder::new_current_thread()
55 .enable_all()
56 .build()?;
57
58 runtime.block_on(run_async(cli))
59}
60
61async fn run_async(cli: Cli) -> Result<()> {
62 let parsed_input = cli.parse_input().ok_or_else(|| WtgError::Cli {
64 message: "Invalid input".to_string(),
65 code: 1,
66 })?;
67
68 let repo_manager = if let Some(owner) = &parsed_input.owner {
70 let repo = parsed_input.repo.as_ref().ok_or_else(|| WtgError::Cli {
71 message: "Invalid repository".to_string(),
72 code: 1,
73 })?;
74 RepoManager::remote(owner.clone(), repo.clone())?
75 } else {
76 RepoManager::local()?
77 };
78
79 let git_repo = repo_manager.git_repo()?;
81
82 let remote_info = repo_manager
84 .remote_info()
85 .map_or_else(|| git_repo.github_remote(), Some);
86
87 if !repo_manager.is_remote() {
89 remote::check_remote_and_snark(remote_info.clone(), git_repo.path());
90 }
91
92 let result = Box::pin(identifier::identify(&parsed_input.query, git_repo)).await?;
94
95 output::display(result)?;
97
98 Ok(())
99}