fix: add missing AnalysisResult import in prompt.rs
Some checks failed
CI / build (push) Failing after 37s

This commit is contained in:
2026-02-01 12:51:45 +00:00
parent 0e167d7c94
commit 570770cf48

View File

@@ -0,0 +1,139 @@
use anyhow::Result;
use colored::Colorize;
use dialoguer::{Confirm, Select};
use crate::analyzer::{analyze_changes, get_all_commit_types, AnalysisResult, CommitType};
use crate::generator::{generate_alternative_messages, generate_message};
use crate::git::{GitRepo, StagedChanges};
pub fn select_commit_type(suggested: CommitType) -> Result<CommitType> {
let all_types = get_all_commit_types();
let type_names: Vec<String> = all_types.iter().map(|t| format!("{}", t)).collect();
let suggested_idx = all_types.iter().position(|t| *t == suggested).unwrap_or(0);
println!("{}", "\nSuggested commit type:".bold().green());
println!(" {}", format!("{}", suggested).green().bold());
let selection = Select::with_theme(&dialoguer::theme::ColorfulTheme::default())
.with_prompt("Select commit type (use ↑/↓ to navigate, Enter to confirm)")
.items(&type_names)
.default(suggested_idx)
.interact()?;
Ok(all_types[selection])
}
pub fn confirm_message(message: &str, alternatives: &[String]) -> Result<(bool, Option<String>)> {
println!("\n{}", "Generated commit message:".bold().green());
println!("\n{}\n", message.bright_white().on_blue());
if !alternatives.is_empty() {
println!("{}", "Alternative messages:".bold().yellow());
for (i, alt) in alternatives.iter().enumerate() {
println!(" {}: {}", (i + 1).to_string().yellow(), alt);
}
}
let confirm = Confirm::with_theme(&dialoguer::theme::ColorfulTheme::default())
.with_prompt("Do you want to use this commit message?")
.default(true)
.interact()?;
if confirm {
Ok((true, None))
} else {
let edit_prompt = Confirm::with_theme(&dialoguer::theme::ColorfulTheme::default())
.with_prompt("Would you like to edit the message manually?")
.default(false)
.interact()?;
if edit_prompt {
let edited = dialoguer::Editor::new()
.edit(&format!(
"\n# Edit your commit message below:\n{}\n",
message
))
.map_err(|e| anyhow::anyhow!("Failed to open editor: {}", e))?;
match edited {
Some(content) => {
let cleaned = content
.lines()
.filter(|l| !l.starts_with('#'))
.collect::<Vec<_>>()
.join("\n")
.trim()
.to_string();
if cleaned.is_empty() {
Ok((false, None))
} else {
Ok((true, Some(cleaned)))
}
}
None => Ok((false, None)),
}
} else {
Ok((false, None))
}
}
}
pub fn interactive_commit(
git_repo: &GitRepo,
suggested_type: CommitType,
staged: &StagedChanges,
) -> Result<Option<String>> {
let selected_type = if git_repo.has_config()? {
select_commit_type(suggested_type)?
} else {
suggested_type
};
let analysis = analyze_changes(staged);
let analysis = AnalysisResult {
commit_type: selected_type,
..analysis
};
let message = generate_message(&analysis, staged);
let alternatives = generate_alternative_messages(&analysis, staged);
let (confirmed, edited_message) = confirm_message(&message, &alternatives)?;
if !confirmed {
println!("{}", "\nCommit aborted by user.".yellow());
return Ok(None);
}
Ok(edited_message.or(Some(message)))
}
pub fn print_staged_summary(staged: &StagedChanges) {
if staged.files.is_empty() {
println!("{}", "No staged changes found.".yellow());
return;
}
println!("{}", "\nStaged changes:".bold().green());
for file in &staged.files {
let status_str = match file.status {
crate::git::FileStatus::Added => "A".green(),
crate::git::FileStatus::Deleted => "D".red(),
crate::git::FileStatus::Modified => "M".yellow(),
crate::git::FileStatus::Renamed => "R".cyan(),
crate::git::FileStatus::Unknown => "?".white(),
};
println!(
" {} {:>6} {:>6} {}",
status_str,
format!("+{}", file.additions).green(),
format!("-{}", file.deletions).red(),
file.path
);
}
println!();
}