1use super::format_commit_result;
2use super::service::IrisCommitService;
3use super::types::format_commit_message;
4use crate::common::CommonParams;
5use crate::config::Config;
6use crate::git::GitRepo;
7use crate::instruction_presets::PresetType;
8use crate::messages;
9use crate::tui::run_tui_commit;
10use crate::ui;
11use anyhow::{Context, Result};
12use std::sync::Arc;
13
14#[allow(clippy::fn_params_excessive_bools)] #[allow(clippy::too_many_lines)] pub async fn handle_gen_command(
17 common: CommonParams,
18 auto_commit: bool,
19 use_gitmoji: bool,
20 print: bool,
21 verify: bool,
22 repository_url: Option<String>,
23) -> Result<()> {
24 if !common.is_valid_preset_for_type(PresetType::Commit) {
26 ui::print_warning(
27 "The specified preset may not be suitable for commit messages. Consider using a commit or general preset instead.",
28 );
29 ui::print_info("Run 'git-iris list-presets' to see available presets for commits.");
30 }
31
32 let mut config = Config::load()?;
33 common.apply_to_config(&mut config)?;
34
35 let repo_url = repository_url.or(common.repository_url.clone());
37
38 let git_repo = GitRepo::new_from_url(repo_url).context("Failed to create GitRepo")?;
40
41 let repo_path = git_repo.repo_path().clone();
42 let provider_name = &config.default_provider;
43
44 let service = Arc::new(
45 IrisCommitService::new(
46 config.clone(),
47 &repo_path,
48 provider_name,
49 use_gitmoji && config.use_gitmoji,
50 verify,
51 git_repo,
52 )
53 .context("Failed to create IrisCommitService")?,
54 );
55
56 if let Err(e) = service.check_environment() {
58 ui::print_error(&format!("Error: {e}"));
59 ui::print_info("\nPlease ensure the following:");
60 ui::print_info("1. Git is installed and accessible from the command line.");
61 ui::print_info(
62 "2. You are running this command from within a Git repository or provide a repository URL with --repo.",
63 );
64 ui::print_info("3. You have set up your configuration using 'git-iris config'.");
65 return Err(e);
66 }
67
68 let git_info = service.get_git_info().await?;
69
70 if git_info.staged_files.is_empty() {
71 ui::print_warning(
72 "No staged changes. Please stage your changes before generating a commit message.",
73 );
74 ui::print_info("You can stage changes using 'git add <file>' or 'git add .'");
75 return Ok(());
76 }
77
78 if let Err(e) = service.pre_commit() {
80 ui::print_error(&format!("Pre-commit failed: {e}"));
81 return Err(e);
82 }
83
84 let effective_instructions = common
85 .instructions
86 .unwrap_or_else(|| config.instructions.clone());
87 let preset_str = common.preset.as_deref().unwrap_or("");
88
89 let spinner = ui::create_spinner("");
91 let random_message = messages::get_waiting_message();
92 spinner.set_message(random_message.text);
93
94 let initial_message = service
96 .generate_message(preset_str, &effective_instructions)
97 .await?;
98
99 spinner.finish_and_clear();
101
102 if print {
103 println!("{}", format_commit_message(&initial_message));
104 return Ok(());
105 }
106
107 if auto_commit {
108 if service.is_remote_repository() {
110 ui::print_error(
111 "Cannot automatically commit to a remote repository. Use --print instead.",
112 );
113 return Err(anyhow::anyhow!(
114 "Auto-commit not supported for remote repositories"
115 ));
116 }
117
118 match service.perform_commit(&format_commit_message(&initial_message)) {
119 Ok(result) => {
120 let output =
121 format_commit_result(&result, &format_commit_message(&initial_message));
122 println!("{output}");
123 }
124 Err(e) => {
125 eprintln!("Failed to commit: {e}");
126 return Err(e);
127 }
128 }
129 return Ok(());
130 }
131
132 if service.is_remote_repository() {
134 ui::print_warning(
135 "Interactive commit not available for remote repositories. Using print mode instead.",
136 );
137 println!("{}", format_commit_message(&initial_message));
138 return Ok(());
139 }
140
141 run_tui_commit(
142 vec![initial_message],
143 effective_instructions,
144 String::from(preset_str),
145 git_info.user_name,
146 git_info.user_email,
147 service,
148 config.use_gitmoji,
149 )
150 .await?;
151
152 Ok(())
153}