1pub mod init;
7pub mod reset;
8pub mod scan;
9#[cfg(feature = "tui")]
10pub mod setup;
11pub mod status;
12pub mod support;
13pub mod sync_cmd;
14pub mod workspace;
15
16pub use init::run as run_init;
17pub use status::run as run_status;
18pub use sync_cmd::run as run_sync_cmd;
19
20use crate::cli::Command;
21use crate::config::Config;
22use crate::errors::{AppError, Result};
23use crate::output::Output;
24use std::path::Path;
25
26pub(crate) use support::{ensure_base_path, warn_if_concurrency_capped};
27
28pub async fn run_command(
30 command: &Command,
31 config_path: Option<&Path>,
32 output: &Output,
33 quiet: bool,
34) -> Result<()> {
35 if !output.is_json() && !quiet {
37 crate::banner::print_banner();
38 }
39
40 if let Command::Init(args) = command {
42 return run_init(args, output).await;
43 }
44 if let Command::Reset(args) = command {
45 return reset::run(args, output).await;
46 }
47 if let Command::Scan(args) = command {
48 return scan::run(args, config_path, output);
49 }
50 #[cfg(feature = "tui")]
51 if let Command::Setup(args) = command {
52 return setup::run(args, output).await;
53 }
54
55 let config = load_config(config_path)?;
57
58 match command {
59 Command::Init(_) | Command::Reset(_) | Command::Scan(_) => unreachable!(),
60 #[cfg(feature = "tui")]
61 Command::Setup(_) => unreachable!(),
62 Command::Sync(args) => run_sync_cmd(args, &config, output).await,
63 Command::Status(args) => run_status(args, &config, output).await,
64 Command::Workspace(args) => workspace::run(args, &config, output),
65 }
66}
67
68fn load_config(config_path: Option<&Path>) -> Result<Config> {
73 let path = match config_path {
74 Some(p) => p.to_path_buf(),
75 None => Config::default_path()?,
76 };
77 if !path.exists() {
78 return Err(AppError::config(
79 "No configuration found. Run 'gisa init' to create one.",
80 ));
81 }
82 Config::load_from(&path)
83}