1use anyhow::Result;
2
3use changepacks_core::UpdateType;
4use clap::{Parser, Subcommand, ValueEnum};
5
6use crate::{
7 commands::{
8 ChangepackArgs, CheckArgs, ConfigArgs, InitArgs, PublishArgs, UpdateArgs,
9 handle_changepack, handle_check, handle_config, handle_init, handle_publish, handle_update,
10 },
11 options::FilterOptions,
12};
13mod commands;
14mod finders;
15mod options;
16
17#[derive(ValueEnum, Debug, Clone)]
18enum CliUpdateType {
19 Major,
20 Minor,
21 Patch,
22}
23
24impl From<CliUpdateType> for UpdateType {
25 fn from(value: CliUpdateType) -> Self {
26 match value {
27 CliUpdateType::Major => UpdateType::Major,
28 CliUpdateType::Minor => UpdateType::Minor,
29 CliUpdateType::Patch => UpdateType::Patch,
30 }
31 }
32}
33
34#[derive(Parser, Debug)]
35#[command(author, version, about = "changepacks CLI")]
36struct Cli {
37 #[command(subcommand)]
38 command: Option<Commands>,
39
40 #[arg(short, long)]
41 filter: Option<FilterOptions>,
42
43 #[arg(short, long, default_value = "false")]
44 remote: bool,
45
46 #[arg(short, long, default_value = "false")]
47 yes: bool,
48
49 #[arg(short, long)]
50 message: Option<String>,
51
52 #[arg(short, long)]
53 update_type: Option<CliUpdateType>,
54}
55
56#[derive(Subcommand, Debug)]
57enum Commands {
58 Init(InitArgs),
59 Check(CheckArgs),
60 Update(UpdateArgs),
61 Config(ConfigArgs),
62 Publish(PublishArgs),
63}
64
65pub async fn main(args: &[String]) -> Result<()> {
66 let cli = Cli::parse_from(args);
67 if let Some(command) = cli.command {
68 match command {
69 Commands::Init(args) => handle_init(&args).await?,
70 Commands::Check(args) => handle_check(&args).await?,
71 Commands::Update(args) => handle_update(&args).await?,
72 Commands::Config(args) => handle_config(&args).await?,
73 Commands::Publish(args) => handle_publish(&args).await?,
74 }
75 } else {
76 handle_changepack(&ChangepackArgs {
77 filter: cli.filter,
78 remote: cli.remote,
79 yes: cli.yes,
80 message: cli.message,
81 update_type: cli.update_type.map(Into::into),
82 })
83 .await?;
84 }
85 Ok(())
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91 use rstest::rstest;
92
93 #[rstest]
94 #[case(CliUpdateType::Major, UpdateType::Major)]
95 #[case(CliUpdateType::Minor, UpdateType::Minor)]
96 #[case(CliUpdateType::Patch, UpdateType::Patch)]
97 fn test_cli_update_type_to_update_type(
98 #[case] cli_type: CliUpdateType,
99 #[case] expected: UpdateType,
100 ) {
101 let result: UpdateType = cli_type.into();
102 assert_eq!(result, expected);
103 }
104}