diff --git a/src/commands.rs b/src/commands.rs index 3ce40227796a407e7cd83fe8e806a3363632e896..277764b2f115d52555166b96be2221fcd64a23fe 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -8,6 +8,7 @@ pub mod expire; pub mod identity; pub mod net_test; pub mod oneshot; +pub mod publish; pub mod revocation; pub mod runtime; pub mod smith; diff --git a/src/commands/publish.rs b/src/commands/publish.rs new file mode 100644 index 0000000000000000000000000000000000000000..1608fca33cc47b2b25c1b69c344ba1e46ffc94eb --- /dev/null +++ b/src/commands/publish.rs @@ -0,0 +1,73 @@ +// commands/publish.rs +// This module handles the 'publish' command of the CLI. + +use crate::GcliError; // Custom error type. +use anyhow::anyhow; +use std::fs; // For file system operations. +use std::io::{self, Write}; // For input/output operations. +use std::process::Command; // For executing system commands. // For better error handling. + +/// Asks the user for confirmation before proceeding. +fn confirm_action(version: &str) -> Result<bool, GcliError> { + print!( + "Are you sure you want to publish tag version {}? (y/N) ", + version + ); + io::stdout() + .flush() + .map_err(|e| GcliError::Anyhow(anyhow!(e)))?; // Ensure the output is displayed immediately. + + let mut response = String::new(); + io::stdin() + .read_line(&mut response) + .map_err(|e| GcliError::Anyhow(anyhow!(e)))?; + + Ok(response.trim().eq_ignore_ascii_case("y")) // Checks if the user's input is 'y' (case insensitive). +} + +/// Executes the 'publish' operation. +pub async fn handle_command() -> Result<(), GcliError> { + // Step 1: Read the version number from Cargo.toml + let cargo_toml_content = + fs::read_to_string("Cargo.toml").map_err(|e| GcliError::Anyhow(anyhow!(e)))?; + let version = cargo_toml_content + .lines() + .find(|line| line.starts_with("version =")) + .and_then(|line| line.split('"').nth(1)) + .ok_or_else(|| GcliError::Input("Version not found in Cargo.toml".to_string()))?; + + // Step 2: Check if the git tag already exists + let tag_check_output = Command::new("git") + .args(["tag", "-l", &format!("{}", version)]) + .output() + .map_err(|e| GcliError::Anyhow(anyhow!(e)))?; + + if !tag_check_output.stdout.is_empty() { + return Err(GcliError::Logic(format!("Tag {} already exists", version))); + } + + // Display a confirmation prompt with the version number. + if !confirm_action(&version)? { + println!("Publication cancelled."); + return Ok(()); + } + + // Step 3: Create and push the git tag + Command::new("git") + .args([ + "tag", + "-a", + &format!("{}", version), + "-m", + &format!("Release v{}", version), + ]) + .status() + .map_err(|e| GcliError::Anyhow(anyhow!(e)))?; + + Command::new("git") + .args(["push", "origin", &format!("{}", version)]) + .status() + .map_err(|e| GcliError::Anyhow(anyhow!(e)))?; + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index eb0241866ce02b46fa833eaba50548f2ca3788ee..3a101f875358bb494a44604f7768877530d1c3f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -100,6 +100,8 @@ pub enum Subcommand { /// Cesium #[clap(subcommand, hide = true)] Cesium(commands::cesium::Subcommand), + /// Publish a new git tag with actual version + Publish, } /// main function @@ -135,6 +137,7 @@ async fn main() -> Result<(), GcliError> { Subcommand::Indexer(subcommand) => indexer::handle_command(data, subcommand).await, Subcommand::Config(subcommand) => conf::handle_command(data, subcommand), Subcommand::Cesium(subcommand) => commands::cesium::handle_command(data, subcommand).await, + Subcommand::Publish => commands::publish::handle_command().await, }; if let Err(ref e) = result { println!("{}", e)