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