feat: feat: add multilingual output support for commit, tag, and changelog commands
This commit is contained in:
@@ -3,11 +3,12 @@ use clap::Parser;
|
||||
use colored::Colorize;
|
||||
use dialoguer::{Confirm, Input, Select};
|
||||
|
||||
use crate::config::manager::ConfigManager;
|
||||
use crate::config::{Language, manager::ConfigManager};
|
||||
use crate::config::CommitFormat;
|
||||
use crate::generator::ContentGenerator;
|
||||
use crate::git::{find_repo, GitRepo};
|
||||
use crate::git::commit::{CommitBuilder, create_date_commit_message};
|
||||
use crate::i18n::{Messages, translate_commit_type};
|
||||
use crate::utils::validators::get_commit_types;
|
||||
|
||||
/// Generate and execute conventional commits
|
||||
@@ -79,15 +80,17 @@ impl CommitCommand {
|
||||
// Find git repository
|
||||
let repo = find_repo(std::env::current_dir()?.as_path())?;
|
||||
|
||||
// Check for changes
|
||||
let status = repo.status_summary()?;
|
||||
if status.clean && !self.amend {
|
||||
bail!("No changes to commit. Working tree is clean.");
|
||||
}
|
||||
|
||||
// Load configuration
|
||||
let manager = ConfigManager::new()?;
|
||||
let config = manager.config();
|
||||
let language = manager.get_language().unwrap_or(Language::English);
|
||||
let messages = Messages::new(language);
|
||||
|
||||
// Check for changes
|
||||
let status = repo.status_summary()?;
|
||||
if status.clean && !self.amend {
|
||||
bail!("{}", messages.no_changes());
|
||||
}
|
||||
|
||||
// Determine commit format
|
||||
let format = if self.conventional {
|
||||
@@ -101,7 +104,7 @@ impl CommitCommand {
|
||||
// Stage all if requested
|
||||
if self.all {
|
||||
repo.stage_all()?;
|
||||
println!("{}", "✓ Staged all changes".green());
|
||||
println!("{}", messages.staged_all().green());
|
||||
}
|
||||
|
||||
// Generate or build commit message
|
||||
@@ -113,10 +116,10 @@ impl CommitCommand {
|
||||
self.create_manual_commit(format)?
|
||||
} else if config.commit.auto_generate && !self.yes {
|
||||
// AI-generated commit
|
||||
self.generate_commit(&repo, format).await?
|
||||
self.generate_commit(&repo, format, &messages).await?
|
||||
} else {
|
||||
// Interactive commit creation
|
||||
self.create_interactive_commit(format).await?
|
||||
self.create_interactive_commit(format, &messages).await?
|
||||
};
|
||||
|
||||
// Validate message
|
||||
@@ -132,32 +135,32 @@ impl CommitCommand {
|
||||
// Show commit preview
|
||||
if !self.yes {
|
||||
println!("\n{}", "─".repeat(60));
|
||||
println!("{}", "Commit preview:".bold());
|
||||
println!("{}", messages.commit_preview().bold());
|
||||
println!("{}", "─".repeat(60));
|
||||
println!("{}", commit_message);
|
||||
println!("{}", "─".repeat(60));
|
||||
|
||||
let confirm = Confirm::new()
|
||||
.with_prompt("Do you want to proceed with this commit?")
|
||||
.with_prompt(messages.proceed_commit())
|
||||
.default(true)
|
||||
.interact()?;
|
||||
|
||||
if !confirm {
|
||||
println!("{}", "Commit cancelled.".yellow());
|
||||
println!("{}", messages.commit_cancelled().yellow());
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let result = if self.amend {
|
||||
if self.dry_run {
|
||||
println!("\n{}", "Dry run - commit not amended.".yellow());
|
||||
println!("\n{} {}", messages.dry_run(), "- commit not amended.".yellow());
|
||||
return Ok(());
|
||||
}
|
||||
self.amend_commit(&repo, &commit_message)?;
|
||||
None
|
||||
} else {
|
||||
if self.dry_run {
|
||||
println!("\n{}", "Dry run - commit not created.".yellow());
|
||||
println!("\n{} {}", messages.dry_run(), "- commit not created.".yellow());
|
||||
return Ok(());
|
||||
}
|
||||
CommitBuilder::new()
|
||||
@@ -167,9 +170,9 @@ impl CommitCommand {
|
||||
};
|
||||
|
||||
if let Some(commit_oid) = result {
|
||||
println!("{} {}", "✓ Created commit".green().bold(), commit_oid.to_string()[..8].to_string().cyan());
|
||||
println!("{} {}", messages.commit_created().green().bold(), commit_oid.to_string()[..8].to_string().cyan());
|
||||
} else {
|
||||
println!("{} {}", "✓ Amended commit".green().bold(), "successfully");
|
||||
println!("{} {}", messages.commit_amended().green().bold(), "successfully");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -198,7 +201,7 @@ impl CommitCommand {
|
||||
builder.build_message()
|
||||
}
|
||||
|
||||
async fn generate_commit(&self, repo: &GitRepo, format: CommitFormat) -> Result<String> {
|
||||
async fn generate_commit(&self, repo: &GitRepo, format: CommitFormat, messages: &Messages) -> Result<String> {
|
||||
let manager = ConfigManager::new()?;
|
||||
let config = manager.config();
|
||||
|
||||
@@ -206,7 +209,7 @@ impl CommitCommand {
|
||||
let generator = ContentGenerator::new(&config.llm).await
|
||||
.context("Failed to initialize LLM. Use --manual for manual commit.")?;
|
||||
|
||||
println!("{} AI is analyzing your changes...", "🤖".to_string());
|
||||
println!("{}", messages.ai_analyzing());
|
||||
|
||||
let generated = if self.yes {
|
||||
generator.generate_commit_from_repo(repo, format).await?
|
||||
@@ -217,42 +220,42 @@ impl CommitCommand {
|
||||
Ok(generated.to_conventional())
|
||||
}
|
||||
|
||||
async fn create_interactive_commit(&self, format: CommitFormat) -> Result<String> {
|
||||
async fn create_interactive_commit(&self, format: CommitFormat, messages: &Messages) -> Result<String> {
|
||||
let types = get_commit_types(format == CommitFormat::Commitlint);
|
||||
|
||||
// Select type
|
||||
let type_idx = Select::new()
|
||||
.with_prompt("Select commit type")
|
||||
.with_prompt(messages.select_commit_type())
|
||||
.items(types)
|
||||
.interact()?;
|
||||
let commit_type = types[type_idx].to_string();
|
||||
|
||||
// Enter scope (optional)
|
||||
let scope: String = Input::new()
|
||||
.with_prompt("Scope (optional, press Enter to skip)")
|
||||
.with_prompt(messages.scope_optional())
|
||||
.allow_empty(true)
|
||||
.interact_text()?;
|
||||
let scope = if scope.is_empty() { None } else { Some(scope) };
|
||||
|
||||
// Enter description
|
||||
let description: String = Input::new()
|
||||
.with_prompt("Description")
|
||||
.with_prompt(messages.description())
|
||||
.interact_text()?;
|
||||
|
||||
// Breaking change
|
||||
let breaking = Confirm::new()
|
||||
.with_prompt("Is this a breaking change?")
|
||||
.with_prompt(messages.breaking_change())
|
||||
.default(false)
|
||||
.interact()?;
|
||||
|
||||
// Add body
|
||||
let add_body = Confirm::new()
|
||||
.with_prompt("Add body to commit?")
|
||||
.with_prompt(messages.add_body())
|
||||
.default(false)
|
||||
.interact()?;
|
||||
|
||||
let body = if add_body {
|
||||
let body_text = crate::utils::editor::edit_content("Enter commit body...")?;
|
||||
let body_text = crate::utils::editor::edit_content(messages.enter_commit_body())?;
|
||||
if body_text.trim().is_empty() {
|
||||
None
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user