gitai/features/changelog/
cli.rs1use super::change_log::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 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 ui::print_bordered_content(&changelog);
89
90 if update_file {
92 let path = changelog_path.unwrap_or_else(|| "CHANGELOG.md".to_string());
93 let update_spinner = ui::create_spinner(&format!("Updating changelog file at {path}..."));
94
95 match ChangelogGenerator::update_changelog_file(
96 &changelog,
97 &path,
98 &git_repo_for_update,
99 &to,
100 version_name,
101 ) {
102 Ok(()) => {
103 update_spinner.finish_and_clear();
104 ui::print_success(&format!(
105 "✨ Changelog successfully updated at {}",
106 path.bright_green()
107 ));
108 }
109 Err(e) => {
110 update_spinner.finish_and_clear();
111 ui::print_error(&format!("Failed to update changelog file: {e}"));
112 }
113 }
114 }
115
116 Ok(())
117}
118
119pub async fn handle_release_notes_command(
137 common: CommonParams,
138 from: String,
139 to: Option<String>,
140 repository_url: Option<String>,
141 version_name: Option<String>,
142) -> Result<()> {
143 let mut config = Config::load()?;
145 common.apply_to_config(&mut config)?;
146
147 let spinner = ui::create_spinner("Generating release notes...");
149
150 if let Err(e) = config.check_environment() {
152 ui::print_error(&format!("Error: {e}"));
153 ui::print_info("\nPlease ensure the following:");
154 ui::print_info("1. Git is installed and accessible from the command line.");
155 ui::print_info(
156 "2. You are running this command from within a Git repository or provide a repository URL with --repo.",
157 );
158 ui::print_info("3. You have set up your configuration using 'git config'.");
159 return Err(e);
160 }
161
162 let repo_url = repository_url.or(common.repository_url);
164
165 let git_repo = if let Some(url) = repo_url {
167 Arc::new(GitRepo::clone_remote_repository(&url).context("Failed to clone repository")?)
168 } else {
169 let repo_path = env::current_dir()?;
170 Arc::new(GitRepo::new(&repo_path).context("Failed to create GitRepo")?)
171 };
172
173 let to = to.unwrap_or_else(|| "HEAD".to_string());
175
176 let detail_level = DetailLevel::from_str(&common.detail_level)?;
178
179 let release_notes =
181 ReleaseNotesGenerator::generate(git_repo, &from, &to, &config, detail_level, version_name)
182 .await?;
183
184 spinner.finish_and_clear();
186
187 ui::print_bordered_content(&release_notes);
189
190 Ok(())
191}