diff --git a/src/cli/commands.rs b/src/cli/commands.rs new file mode 100644 index 0000000..c2019ad --- /dev/null +++ b/src/cli/commands.rs @@ -0,0 +1,88 @@ +use anyhow::Result; +use crate::cli::Args; +use crate::fetcher::fetch_issue_content; +use crate::parser::{parse_issue_content, ConventionalMessage}; +use crate::generator::MessageGenerator; +use crate::interactive::run_interactive_mode; +use std::process::Command; + +pub async fn execute(args: Args) -> Result<()> { + let conventional_msg = if let Some(url) = args.get_url() { + let content = fetch_issue_content(url).await?; + let mut msg = parse_issue_content(&content.title, &content.body); + msg.body = Some(content.body); + msg + } else if let Some(text) = args.get_text() { + let mut msg = parse_issue_content("Generated from text", text); + msg.body = Some(text.to_string()); + msg + } else { + parse_issue_content("", "") + }; + + let mut generator = MessageGenerator::from(conventional_msg); + + if args.is_interactive() { + generator = run_interactive_mode(generator).await?; + } + + let message = generator.format_message(); + + if message.trim().is_empty() { + anyhow::bail!("Generated commit message is empty. Please provide a description or use interactive mode."); + } + + if matches!(args.command, Some(crate::cli::args::Commands::Commit { .. })) { + execute_git_commit(&message, &args)?; + } else { + println!("{}", message); + } + + Ok(()) +} + +fn execute_git_commit(message: &str, args: &Args) -> Result<()> { + let git_repo_check = Command::new("git") + .args(["rev-parse", "--is-inside-work-tree"]) + .output(); + + match git_repo_check { + Ok(output) if output.status.success() => {} + Ok(_) | Err(_) => { + anyhow::bail!("Not in a git repository. Please run this command from the root of a git repository."); + } + } + + let commit_msg_path = std::env::temp_dir().join("COMMIT_EDITMSG"); + std::fs::write(&commit_msg_path, message)?; + + let mut cmd = Command::new("git"); + let commit_msg_str = commit_msg_path.to_str() + .ok_or_else(|| anyhow::anyhow!("Commit message path contains invalid Unicode"))?; + cmd.args(["commit", "-F", commit_msg_str]); + + let amend = args.amend || match &args.command { + Some(crate::cli::args::Commands::Commit { amend, .. }) => *amend, + _ => false, + }; + + if args.dry_run { + println!("[dry-run] Would commit:"); + println!("{}", message); + return Ok(()); + } + + if amend { + cmd.arg("--amend"); + if args.no_edit { + cmd.arg("--no-edit"); + } + } + + let status = cmd.status()?; + if !status.success() { + anyhow::bail!("Git commit failed"); + } + + Ok(()) +}