hakoniwa_cli/
cli.rs

1mod completion;
2mod run;
3
4use clap::{Parser, Subcommand};
5use clap_verbosity_flag::{InfoLevel, Verbosity};
6
7use crate::contrib;
8
9const LONG_HELP: &str =
10    "To view the user documentation, please visit https://github.com/souk4711/hakoniwa.";
11
12#[derive(Parser)]
13#[command(name = "hakoniwa", version)]
14#[command(about, long_about = None)]
15#[command(disable_help_subcommand = true, after_help = LONG_HELP)]
16#[command(styles = contrib::clap::styles())]
17struct Cli {
18    #[command(subcommand)]
19    command: Commands,
20
21    #[command(flatten, next_display_order = 100)]
22    verbose: Verbosity<InfoLevel>,
23}
24
25#[allow(clippy::large_enum_variant)]
26#[derive(Subcommand)]
27enum Commands {
28    /// Generate SHELL autocompletions
29    Completion(completion::CompletionCommand),
30
31    /// Run a COMMAND in a container
32    Run(run::RunCommand),
33}
34
35pub fn execute() -> i32 {
36    let cli = Cli::parse();
37
38    let level_filter = cli.verbose.log_level_filter();
39    let debugging = level_filter >= log::LevelFilter::Debug;
40    let timestamp: Option<env_logger::fmt::TimestampPrecision> = if debugging {
41        Some(env_logger::fmt::TimestampPrecision::Seconds)
42    } else {
43        None
44    };
45    env_logger::builder()
46        .format_level(debugging)
47        .format_target(false)
48        .format_timestamp(timestamp)
49        .filter_level(level_filter)
50        .init();
51
52    let r = match &cli.command {
53        Commands::Completion(cmd) => cmd.execute(),
54        Commands::Run(cmd) => cmd.execute(),
55    };
56
57    if let Err(err) = r {
58        log::error!("{}", err);
59        1
60    } else {
61        r.unwrap()
62    }
63}