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};
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))
}