1use super::format_commit_result;
2use super::service::IrisCommitService;
3use crate::common::CommonParams;
4use crate::config::Config;
5use crate::context::format_commit_message;
6use crate::llm_providers::LLMProviderType;
7use crate::messages;
8use crate::tui::run_tui_commit;
9use crate::ui;
10use anyhow::{Context, Result};
11use std::str::FromStr;
12use std::sync::Arc;
13
14#[allow(clippy::fn_params_excessive_bools)] pub async fn handle_gen_command(
16 common: CommonParams,
17 auto_commit: bool,
18 use_gitmoji: bool,
19 print: bool,
20 verify: bool,
21) -> Result<()> {
22 let mut config = Config::load()?;
23 common.apply_to_config(&mut config)?;
24 let current_dir = std::env::current_dir()?;
25
26 let provider_type = LLMProviderType::from_str(&config.default_provider)?;
27
28 let service = Arc::new(
29 IrisCommitService::new(
30 config.clone(),
31 ¤t_dir.clone(),
32 provider_type,
33 use_gitmoji && config.use_gitmoji,
34 verify,
35 )
36 .context("Failed to create IrisCommitService")?,
37 );
38
39 if let Err(e) = service.check_environment() {
41 ui::print_error(&format!("Error: {e}"));
42 ui::print_info("\nPlease ensure the following:");
43 ui::print_info("1. Git is installed and accessible from the command line.");
44 ui::print_info("2. You are running this command from within a Git repository.");
45 ui::print_info("3. You have set up your configuration using 'git-iris config'.");
46 return Err(e);
47 }
48
49 let git_info = service.get_git_info().await?;
50
51 if git_info.staged_files.is_empty() {
52 ui::print_warning(
53 "No staged changes. Please stage your changes before generating a commit message.",
54 );
55 ui::print_info("You can stage changes using 'git add <file>' or 'git add .'");
56 return Ok(());
57 }
58
59 if let Err(e) = service.pre_commit() {
61 ui::print_error(&format!("Pre-commit failed: {e}"));
62 return Err(e);
63 }
64
65 let effective_instructions = common
66 .instructions
67 .unwrap_or_else(|| config.instructions.clone());
68 let preset_str = common.preset.as_deref().unwrap_or("");
69
70 let spinner = ui::create_spinner("");
72 let random_message = messages::get_waiting_message();
73 spinner.set_message(random_message.text);
74
75 let initial_message = service
77 .generate_message(preset_str, &effective_instructions)
78 .await?;
79
80 spinner.finish_and_clear();
82
83 if print {
84 println!("{}", format_commit_message(&initial_message));
85 return Ok(());
86 }
87
88 if auto_commit {
89 match service.perform_commit(&format_commit_message(&initial_message)) {
90 Ok(result) => {
91 let output =
92 format_commit_result(&result, &format_commit_message(&initial_message));
93 println!("{output}");
94 }
95 Err(e) => {
96 eprintln!("Failed to commit: {e}");
97 return Err(e);
98 }
99 }
100 return Ok(());
101 }
102
103 run_tui_commit(
104 vec![initial_message],
105 effective_instructions,
106 String::from(preset_str),
107 git_info.user_name,
108 git_info.user_email,
109 service,
110 config.use_gitmoji,
111 )
112 .await?;
113
114 Ok(())
115}