Skip to main content

commit_wizard/cli/cmd/init/
mod.rs

1use clap::{Args as ClapArgs, Subcommand, ValueEnum};
2use std::fmt;
3
4use crate::{
5    cli::CliResult,
6    core::{configs, context::Context},
7};
8
9#[derive(Debug, Clone, ClapArgs)]
10#[command(about = "Initialize Commit Wizard configuration assets")]
11pub struct Args {
12    #[arg(long, conflicts_with_all = ["full", "profile"])]
13    pub minimal: bool,
14
15    #[arg(long, conflicts_with_all = ["minimal", "profile"])]
16    pub full: bool,
17
18    #[arg(long, default_value_t = InitProfile::Standard, value_enum)]
19    pub profile: InitProfile,
20
21    /// Set multiple keys: --set policy.require_conventional_for_all_commits=true
22    #[arg(long = "set", value_parser = clap::builder::NonEmptyStringValueParser::new())]
23    pub sets: Vec<String>,
24
25    #[command(subcommand)]
26    pub subcommand: Option<InitSubcommand>,
27}
28
29#[derive(Debug, Clone, Copy, ValueEnum, Default)]
30pub enum InitProfile {
31    Minimal,
32    #[default]
33    Standard,
34    Full,
35}
36
37impl InitProfile {
38    pub fn resolved(args: &Args) -> Self {
39        if args.minimal {
40            Self::Minimal
41        } else if args.full {
42            Self::Full
43        } else {
44            args.profile
45        }
46    }
47
48    pub fn as_str(self) -> &'static str {
49        match self {
50            Self::Minimal => "minimal",
51            Self::Standard => "standard",
52            Self::Full => "full",
53        }
54    }
55}
56
57impl fmt::Display for InitProfile {
58    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59        f.write_str((*self).as_str())
60    }
61}
62
63#[derive(Debug, Clone, Subcommand)]
64pub enum InitSubcommand {
65    Project {
66        #[arg(long)]
67        hidden: bool,
68    },
69    Config {
70        #[arg(long, short)]
71        global: bool,
72    },
73    Rules {
74        #[arg(long, short)]
75        global: bool,
76    },
77    Registry {
78        path: std::path::PathBuf,
79        #[arg(long = "rules")]
80        with_rules: bool,
81        #[arg(long)]
82        section: Vec<String>,
83    },
84}
85
86pub async fn run(ctx: &Context, args: Args) -> CliResult<()> {
87    let profile = InitProfile::resolved(&args).to_string();
88
89    match args.subcommand {
90        Some(InitSubcommand::Project { hidden }) => {
91            configs::init_project_config(ctx, hidden, profile)
92        }
93        Some(InitSubcommand::Config { global }) => configs::init_config(ctx, global, profile),
94        Some(InitSubcommand::Rules { global }) => configs::init_rules(ctx, global, profile),
95        Some(InitSubcommand::Registry {
96            path,
97            with_rules,
98            section,
99        }) => configs::init_registry(ctx, path, with_rules, section, profile),
100        None => configs::init_project_config(ctx, true, profile),
101    }
102}