diff --git a/src/cli/args.rs b/src/cli/args.rs new file mode 100644 index 0000000..ba8ef24 --- /dev/null +++ b/src/cli/args.rs @@ -0,0 +1,133 @@ +use clap::{Parser, Args as ClapArgs, Subcommand, ValueEnum}; +use std::path::PathBuf; + +#[derive(Parser, Debug)] +#[command(name = "git-issue-commit")] +#[command(author, version, about, long_about = None)] +pub struct Args { + #[command(subcommand)] + pub command: Option, + + #[arg(short, long, help = "GitHub issue or PR URL")] + pub url: Option, + + #[arg(short, long, help = "Direct text input for commit message generation")] + pub text: Option, + + #[arg(short, long, value_enum, help = "Type of change (feat, fix, docs, etc.)")] + pub r#type: Option, + + #[arg(short, long, help = "Scope of the change")] + pub scope: Option, + + #[arg(long, help = "Mark as breaking change")] + pub breaking: bool, + + #[arg(short, long, help = "Run in interactive mode")] + pub interactive: bool, + + #[arg(long, help = "Don't actually commit, just show the message")] + pub dry_run: bool, + + #[arg(long, help = "Amend the previous commit")] + pub amend: bool, + + #[arg(long, help = "Skip editing the commit message")] + pub no_edit: bool, +} + +#[derive(Subcommand, Debug)] +pub enum Commands { + #[command(about = "Generate a commit message from an issue URL")] + FromUrl { + #[arg(help = "GitHub or GitLab issue/PR URL")] + url: String, + }, + + #[command(about = "Generate a commit message from text")] + FromText { + #[arg(help = "Text description of the change")] + text: String, + }, + + #[command(about = "Create a commit directly")] + Commit { + #[arg(short, long, help = "GitHub issue or PR URL")] + url: Option, + + #[arg(short, long, help = "Direct text input")] + text: Option, + + #[arg(short, long, value_enum, help = "Type of change")] + r#type: Option, + + #[arg(short, long, help = "Scope of the change")] + scope: Option, + + #[arg(long, help = "Mark as breaking change")] + breaking: bool, + + #[arg(long, help = "Amend previous commit")] + amend: bool, + }, +} + +#[derive(Debug, Clone, ValueEnum)] +pub enum CommitType { + #[value(name = "feat")] + Feat, + #[value(name = "fix")] + Fix, + #[value(name = "docs")] + Docs, + #[value(name = "style")] + Style, + #[value(name = "refactor")] + Refactor, + #[value(name = "perf")] + Perf, + #[value(name = "test")] + Test, + #[value(name = "build")] + Build, + #[value(name = "ci")] + Ci, + #[value(name = "chore")] + Chore, + #[value(name = "revert")] + Revert, +} + +impl Args { + pub fn parse() -> Self { + Args::parse() + } + + pub fn is_interactive(&self) -> bool { + self.interactive + } + + pub fn get_url(&self) -> Option<&String> { + if let Some(ref cmd) = self.command { + match cmd { + Commands::FromUrl { url } => Some(url), + Commands::Commit { url, .. } => url.as_ref(), + _ => None, + } + } else { + self.url.as_ref() + } + } + + pub fn get_text(&self) -> Option<&String> { + if let Some(ref cmd) = self.command { + match cmd { + Commands::FromText { text } => Some(text), + Commands::Commit { text, .. } => text.as_ref(), + _ => None, + } + } else { + self.text.as_ref() + } + } +}