use anyhow::{Context, Result};
use std::process::Command;
use colored::*;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum IncrementPolicy {
Major,
Minor,
Patch,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VersionConfig {
pub increment_policy: IncrementPolicy,
pub auto_tag: bool,
pub pre_release_prefix: String,
pub auto_increment: bool,
}
pub struct VersionManager {
pub config: VersionConfig,
}
impl VersionManager {
pub fn new() -> Result<Self> {
println!(
"📦 {}", "Advanced version management requires captain binary"
.bright_blue()
);
println!(" Delegating version operations to captain...");
Ok(VersionManager {
config: VersionConfig {
increment_policy: IncrementPolicy::Patch,
auto_tag: false,
pre_release_prefix: "rc".to_string(),
auto_increment: false,
},
})
}
pub fn get_current_version(&self) -> Result<String> {
println!(
"📦 {}", "Getting current version requires captain binary".bright_blue()
);
delegate_to_captain(vec!["version", "current"])
.map(|_| env!("CARGO_PKG_VERSION").to_string())
}
pub fn check_for_updates(&self) -> Result<bool> {
println!(
"📦 {}", "Checking for updates requires captain binary".bright_blue()
);
delegate_to_captain(vec!["version", "check"]).map(|_| false)
}
pub fn update_to_latest(&self) -> Result<()> {
println!(
"📦 {}", "Updating to latest version requires captain binary".bright_blue()
);
delegate_to_captain(vec!["version", "update"])
}
pub fn show_changelog(&self) -> Result<()> {
println!("📦 {}", "Changelog requires captain binary".bright_blue());
delegate_to_captain(vec!["version", "changelog"])
}
pub fn rollback_version(&self, version: &str) -> Result<()> {
println!(
"📦 {}", format!("Rolling back to '{}' requires captain binary", version)
.bright_blue()
);
delegate_to_captain(vec!["version", "rollback", version])
}
pub fn list_versions(&self) -> Result<Vec<String>> {
println!("📦 {}", "Listing versions requires captain binary".bright_blue());
delegate_to_captain(vec!["version", "list"])
.map(|_| vec![env!("CARGO_PKG_VERSION") .to_string()])
}
pub fn init(&mut self, version: String) -> Result<()> {
println!(
"📦 {}", format!("Initializing version '{}' requires captain binary",
version) .bright_blue()
);
delegate_to_captain(vec!["version", "init", & version])
}
pub fn show_info(&self) {
println!("📦 {}", "Version information requires captain binary".bright_blue());
let _ = delegate_to_captain(vec!["version", "info"]);
}
pub fn increment(&mut self) -> Result<String> {
println!(
"📦 {}", "Incrementing version requires captain binary".bright_blue()
);
delegate_to_captain(vec!["version", "increment"])
.map(|_| format!("{}.1", env!("CARGO_PKG_VERSION")))
}
pub fn set_version(&mut self, version: &str) -> Result<()> {
println!(
"📦 {}", format!("Setting version to '{}' requires captain binary",
version) .bright_blue()
);
delegate_to_captain(vec!["version", "set", version])
}
pub fn show_history(&self) -> Result<()> {
println!("📦 {}", "Version history requires captain binary".bright_blue());
delegate_to_captain(vec!["version", "history"])
}
pub fn update_cargo_toml(&mut self) -> Result<()> {
println!("📦 {}", "Updating Cargo.toml requires captain binary".bright_blue());
delegate_to_captain(vec!["version", "update-cargo"])
}
pub fn save_config(&self) -> Result<()> {
println!(
"📦 {}", "Saving version config requires captain binary".bright_blue()
);
delegate_to_captain(vec!["version", "save-config"])
}
}
pub fn delegate_to_captain(args: Vec<&str>) -> Result<()> {
let captain_path = match crate::captain::captain_status::find_captain_binary() {
Some(path) => path,
None => {
println!("❌ {}", "Advanced captain binary not found".red().bold());
println!(
"🔄 {}", "Auto-downloading captain binary from get.cargo.do/".cyan()
);
match crate::captain::captain_status::auto_download_captain() {
Ok(path) => path,
Err(e) => {
println!(
"❌ {}", format!("Failed to download captain: {}", e) .red()
);
println!("💡 {}", "Please run: cm captain install".cyan());
println!(" Or upgrade at: https://cargo.do/pro");
println!();
println!(
"💡 {}",
"Version management features require the captain binary:".cyan()
);
println!(" • Advanced version tracking");
println!(" • Automatic update checking");
println!(" • Version rollback capabilities");
println!(" • Changelog management");
println!(" • Version compatibility analysis");
return Ok(());
}
}
}
};
let output = Command::new(&captain_path)
.args(&args)
.output()
.context("Failed to execute captain binary for version management")?;
if !output.stdout.is_empty() {
print!("{}", String::from_utf8_lossy(& output.stdout));
}
if !output.stderr.is_empty() {
eprint!("{}", String::from_utf8_lossy(& output.stderr));
}
if !output.status.success() {
println!(
"❌ {}", format!("Captain binary exited with status: {}", output.status)
.red()
);
}
Ok(())
}
pub fn get_version_info() -> Result<String> {
println!("📦 {}", "Version information requires captain binary".bright_blue());
delegate_to_captain(vec!["version", "info"])
.map(|_| format!("CargoMate {}", env!("CARGO_PKG_VERSION")))
}
pub fn check_version_compatibility() -> Result<bool> {
println!(
"📦 {}", "Version compatibility check requires captain binary".bright_blue()
);
delegate_to_captain(vec!["version", "compat"]).map(|_| true)
}
pub fn show_version_history() -> Result<()> {
println!("📦 {}", "Version history requires captain binary".bright_blue());
delegate_to_captain(vec!["version", "history"])
}
pub fn validate_version_format(version: &str) -> Result<bool> {
println!(
"📦 {}", format!("Version format validation for '{}' requires captain binary",
version) .bright_blue()
);
delegate_to_captain(vec!["version", "validate", version]).map(|_| true)
}
pub fn get_next_version() -> Result<String> {
println!(
"📦 {}", "Next version calculation requires captain binary".bright_blue()
);
delegate_to_captain(vec!["version", "next"])
.map(|_| "Next version available".to_string())
}
pub fn pre_operation_hook(version: Option<String>) -> Result<()> {
println!("📦 {}", "Pre-operation hook requires captain binary".bright_blue());
match version {
Some(v) => delegate_to_captain(vec!["version", "pre-hook", & v]),
None => delegate_to_captain(vec!["version", "pre-hook"]),
}
}
pub fn post_operation_hook(version: Option<String>) -> Result<()> {
println!("📦 {}", "Post-operation hook requires captain binary".bright_blue());
match version {
Some(v) => delegate_to_captain(vec!["version", "post-hook", & v]),
None => delegate_to_captain(vec!["version", "post-hook"]),
}
}