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