cargo-governor 1.2.0

Machine-First, LLM-Ready, CI/CD-Native release automation tool for Rust crates
Documentation
//! Changelog operations for bump service

use crate::error::Result;
use std::fs;
use std::path::Path;

/// Update CHANGELOG.md with new version entry
///
/// # Errors
///
/// Returns an error if:
/// - The CHANGELOG.md file cannot be read
/// - The CHANGELOG.md file cannot be written (when not in dry-run mode)
pub fn update_changelog(path: &Path, version: &str, dry_run: bool) -> Result<bool> {
    let current_content = if path.exists() {
        fs::read_to_string(path)
            .map_err(|e| crate::error::Error::Io(format!("Failed to read CHANGELOG.md: {e}")))?
    } else {
        String::new()
    };

    let date = chrono::Utc::now().format("%Y-%m-%d");
    let new_entry = format!("## [{version}] - {date}\n\n");

    let updated = if current_content.contains("## [Unreleased]") {
        current_content.replace(
            "## [Unreleased]",
            &format!("## [Unreleased]\n\n{}\n", new_entry.trim()),
        )
    } else if current_content.is_empty() {
        format!("# Changelog\n\n## [Unreleased]\n\n{}\n", new_entry.trim())
    } else {
        format!("{}{}\n", current_content.trim_end(), new_entry)
    };

    if !dry_run {
        fs::write(path, updated)
            .map_err(|e| crate::error::Error::Io(format!("Failed to write CHANGELOG.md: {e}")))?;
    }

    Ok(true)
}