cargo-governor 1.2.0

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

use crate::error::Result;
use governor_core::domain::version::SemanticVersion;
use governor_core::traits::source_control::{
    SourceControl, format_commit_message, format_tag_name,
};
use governor_git::GitAdapter;
use std::path::{Path, PathBuf};

/// Perform git operations after version bump
pub async fn perform_git_operations(
    workspace_path: &str,
    new_version: &SemanticVersion,
    version_str: &str,
    cargo_toml_path: &Path,
    changelog_path: &Path,
    no_commit: bool,
    no_tag: bool,
    commit_template: Option<&str>,
    tag_template: Option<&str>,
    dry_run: bool,
) -> Result<(Option<String>, bool)> {
    let config = governor_git::GitAdapterConfig {
        repository_path: Some(PathBuf::from(workspace_path)),
        ..Default::default()
    };

    let git = GitAdapter::open(config)
        .map_err(|e| crate::error::Error::Config(format!("Failed to open git repository: {e}")))?;

    let commit_template = commit_template.unwrap_or("chore(release): bump version to {version}");
    let commit_message = format_commit_message(commit_template, new_version);

    let tag_template = tag_template.unwrap_or("v{version}");
    let tag_name = format_tag_name(tag_template, new_version);

    let mut commit_hash = None;
    let mut tag_created = false;

    if !dry_run {
        let mut files_to_commit = vec![cargo_toml_path.to_string_lossy().to_string()];
        if changelog_path.exists() {
            files_to_commit.push(changelog_path.to_string_lossy().to_string());
        }

        if !no_commit {
            if let Ok(hash) = git.commit(&commit_message, &files_to_commit).await {
                commit_hash = Some(hash);
            } else {
                let _ = git.stage_files(&files_to_commit).await;
                if let Ok(hash) = git.commit(&commit_message, &files_to_commit).await {
                    commit_hash = Some(hash);
                }
            }
        }

        if !no_tag
            && git
                .create_tag(&tag_name, &format!("Release {version_str}"))
                .await
                .is_ok()
        {
            tag_created = true;
        }
    }

    Ok((commit_hash, tag_created))
}