1use super::changelog::ChangelogGenerator;
2use super::releasenotes::ReleaseNotesGenerator;
3use crate::common::{CommonParams, DetailLevel};
4use crate::config::Config;
5use crate::git::GitRepo;
6use crate::ui;
7use anyhow::{Context, Result};
8use colored::Colorize;
9use std::env;
10use std::str::FromStr;
11use std::sync::Arc;
12
13pub async fn handle_changelog_command(
33 common: CommonParams,
34 from: String,
35 to: Option<String>,
36 repository_url: Option<String>,
37 update_file: bool,
38 changelog_path: Option<String>,
39 version_name: Option<String>,
40) -> Result<()> {
41 let mut config = Config::load()?;
43 common.apply_to_config(&mut config)?;
44
45 let spinner = ui::create_spinner("Generating changelog...");
47
48 if let Err(e) = config.check_environment() {
50 ui::print_error(&format!("Error: {e}"));
51 ui::print_info("\nPlease ensure the following:");
52 ui::print_info("1. Git is installed and accessible from the command line.");
53 ui::print_info(
54 "2. You are running this command from within a Git repository or provide a repository URL with --repo.",
55 );
56 ui::print_info("3. You have set up your configuration using 'git-iris config'.");
57 return Err(e);
58 }
59
60 let repo_url = repository_url.or(common.repository_url);
62
63 let git_repo = if let Some(url) = repo_url {
65 Arc::new(GitRepo::clone_remote_repository(&url).context("Failed to clone repository")?)
66 } else {
67 let repo_path = env::current_dir()?;
68 Arc::new(GitRepo::new(&repo_path).context("Failed to create GitRepo")?)
69 };
70
71 let git_repo_for_update = Arc::clone(&git_repo);
73
74 let to = to.unwrap_or_else(|| "HEAD".to_string());
76
77 let detail_level = DetailLevel::from_str(&common.detail_level)?;
79
80 let changelog =
82 ChangelogGenerator::generate(git_repo, &from, &to, &config, detail_level).await?;
83
84 spinner.finish_and_clear();
86
87 println!("{}", "━".repeat(50).bright_purple());
88 println!("{}", &changelog);
89 println!("{}", "━".repeat(50).bright_purple());
90
91 if update_file {
93 let path = changelog_path.unwrap_or_else(|| "CHANGELOG.md".to_string());
94 let update_spinner = ui::create_spinner(&format!("Updating changelog file at {path}..."));
95
96 match ChangelogGenerator::update_changelog_file(
97 &changelog,
98 &path,
99 &git_repo_for_update,
100 &to,
101 version_name,
102 ) {
103 Ok(()) => {
104 update_spinner.finish_and_clear();
105 ui::print_success(&format!(
106 "✨ Changelog successfully updated at {}",
107 path.bright_green()
108 ));
109 }
110 Err(e) => {
111 update_spinner.finish_and_clear();
112 ui::print_error(&format!("Failed to update changelog file: {e}"));
113 }
114 }
115 }
116
117 Ok(())
118}
119
120pub async fn handle_release_notes_command(
138 common: CommonParams,
139 from: String,
140 to: Option<String>,
141 repository_url: Option<String>,
142 version_name: Option<String>,
143) -> Result<()> {
144 let mut config = Config::load()?;
146 common.apply_to_config(&mut config)?;
147
148 let spinner = ui::create_spinner("Generating release notes...");
150
151 if let Err(e) = config.check_environment() {
153 ui::print_error(&format!("Error: {e}"));
154 ui::print_info("\nPlease ensure the following:");
155 ui::print_info("1. Git is installed and accessible from the command line.");
156 ui::print_info(
157 "2. You are running this command from within a Git repository or provide a repository URL with --repo.",
158 );
159 ui::print_info("3. You have set up your configuration using 'git-iris config'.");
160 return Err(e);
161 }
162
163 let repo_url = repository_url.or(common.repository_url);
165
166 let git_repo = if let Some(url) = repo_url {
168 Arc::new(GitRepo::clone_remote_repository(&url).context("Failed to clone repository")?)
169 } else {
170 let repo_path = env::current_dir()?;
171 Arc::new(GitRepo::new(&repo_path).context("Failed to create GitRepo")?)
172 };
173
174 let to = to.unwrap_or_else(|| "HEAD".to_string());
176
177 let detail_level = DetailLevel::from_str(&common.detail_level)?;
179
180 let release_notes =
182 ReleaseNotesGenerator::generate(git_repo, &from, &to, &config, detail_level, version_name)
183 .await?;
184
185 spinner.finish_and_clear();
187
188 println!("{}", "━".repeat(50).bright_purple());
189 println!("{}", &release_notes);
190 println!("{}", "━".repeat(50).bright_purple());
191
192 Ok(())
193}