From 1627a616338cf9bf4e28c94f7befdc3b31fd552b Mon Sep 17 00:00:00 2001 From: Flawid DSouza Date: Wed, 13 Nov 2024 14:08:41 +0530 Subject: [PATCH] move all task processors to modules --- src/common.rs | 12 ++++ src/main.rs | 132 +++-------------------------------------- src/modules/command.rs | 89 +++++++++++++++++++++++++++ src/modules/debug.rs | 15 +++++ src/modules/mod.rs | 3 + src/modules/when.rs | 18 ++++++ src/utils.rs | 2 +- 7 files changed, 147 insertions(+), 124 deletions(-) create mode 100644 src/common.rs create mode 100644 src/modules/command.rs create mode 100644 src/modules/debug.rs create mode 100644 src/modules/mod.rs create mode 100644 src/modules/when.rs diff --git a/src/common.rs b/src/common.rs new file mode 100644 index 0000000..f50f979 --- /dev/null +++ b/src/common.rs @@ -0,0 +1,12 @@ +use indexmap::IndexMap; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Deserialize)] +pub struct Debug(pub IndexMap); + +#[derive(Debug, Deserialize, Serialize)] +pub struct Register { + pub stdout: String, + pub stderr: String, + pub rc: i32, +} diff --git a/src/main.rs b/src/main.rs index 7552cc4..5ea8893 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,12 @@ +mod common; +mod modules; mod utils; use clap::{Arg, Command as ClapCommand}; -use colored::*; +use colored::Colorize; use indexmap::IndexMap; -use serde::{Deserialize, Serialize}; +use serde::Deserialize; use serde_json::Value; -use ssh2::Session; use std::path::Path; use std::process::exit; @@ -38,128 +39,13 @@ struct Task { shell: Option, command: Option, register: Option, - debug: Option, + debug: Option, vars: Option>, chdir: Option, when: Option, r#loop: Option>, } -#[derive(Debug, Deserialize)] -struct Debug(IndexMap); - -#[derive(Debug, Deserialize, Serialize)] -struct Register { - stdout: String, - stderr: String, - rc: i32, -} - -fn handle_command_execution( - is_localhost: bool, - session: Option<&Session>, - command: &str, - use_shell: bool, - display_output: bool, - chdir: Option<&str>, - register: Option<&String>, - vars_map: &mut IndexMap, -) -> Result<(), Box> { - let result = if is_localhost { - utils::execute_local_command(command, use_shell, display_output, chdir) - } else { - utils::execute_ssh_command(session.unwrap(), command, use_shell, display_output, chdir) - }; - - match result { - Ok((stdout, stderr, exit_status)) => { - if exit_status != 0 { - return Err(format!( - "Command execution failed with exit status: {}. Stopping further tasks.", - exit_status - ) - .red() - .into()); - } - - if let Some(register) = register { - let register_value = serde_json::to_value(Register { - stdout: stdout.clone(), - stderr: stderr.clone(), - rc: exit_status, - })?; - vars_map.insert(register.clone(), register_value); - println!( - "{}", - format!("Registering output to: {}", register).yellow() - ); - } - } - Err(e) => { - return Err(format!( - "Command execution failed with error: {}. Stopping further tasks.", - e - ) - .red() - .into()); - } - } - - Ok(()) -} - -fn process_commands( - commands: Vec, - is_localhost: bool, - session: Option<&Session>, - use_shell: bool, - task_chdir: Option<&str>, - register: Option<&String>, - vars_map: &mut IndexMap, -) -> Result<(), Box> { - for cmd in commands { - let substituted_cmd = utils::replace_placeholders(&cmd, vars_map); - println!("{}", format!("> {}", substituted_cmd).magenta()); - - let display_output = register.is_none(); - handle_command_execution( - is_localhost, - session, - &substituted_cmd, - use_shell, - display_output, - task_chdir, - register, - vars_map, - )?; - } - - Ok(()) -} - -fn should_run_task(condition: &Option, vars_map: &IndexMap) -> bool { - if let Some(cond) = condition { - let template_str = format!("{{% if {} %}}true{{% else %}}false{{% endif %}}", cond); - let rendered_cond = utils::replace_placeholders(&template_str, vars_map); - if rendered_cond == "false" { - false - } else { - true - } - } else { - true - } -} - -fn process_debug(debug: &Debug, vars_map: &IndexMap) { - println!("{}", "Debug:".blue()); - for (key, msg) in debug.0.iter() { - println!("{}", format!("{}:", key).blue()); - let debug_msg = utils::replace_placeholders(msg, vars_map); - println!("{}", format!("{}", debug_msg).blue()); - } -} - fn main() -> Result<(), Box> { let matches = ClapCommand::new("deploy-helper") .version("1.0.3") @@ -263,7 +149,7 @@ fn main() -> Result<(), Box> { }; for task in &dep.tasks { - if !should_run_task(&task.when, &vars_map) { + if !modules::when::process(&task.when, &vars_map) { println!("{}", format!("Skipping task: {}\n", task.name).yellow()); continue; } @@ -293,12 +179,12 @@ fn main() -> Result<(), Box> { } if let Some(debug) = &task.debug { - process_debug(debug, &vars_map); + modules::debug::process(debug, &vars_map); } if let Some(shell_command) = &task.shell { let commands = utils::split_commands(shell_command); - process_commands( + modules::command::process( commands, is_localhost, session.as_ref(), @@ -311,7 +197,7 @@ fn main() -> Result<(), Box> { if let Some(command) = &task.command { let commands = utils::split_commands(command); - process_commands( + modules::command::process( commands, is_localhost, session.as_ref(), diff --git a/src/modules/command.rs b/src/modules/command.rs new file mode 100644 index 0000000..11176aa --- /dev/null +++ b/src/modules/command.rs @@ -0,0 +1,89 @@ +use colored::Colorize; +use indexmap::IndexMap; +use serde_json::Value; +use ssh2::Session; + +use crate::common; +use crate::utils; + +fn handle_command_execution( + is_localhost: bool, + session: Option<&Session>, + command: &str, + use_shell: bool, + display_output: bool, + chdir: Option<&str>, + register: Option<&String>, + vars_map: &mut IndexMap, +) -> Result<(), Box> { + let result = if is_localhost { + utils::execute_local_command(command, use_shell, display_output, chdir) + } else { + utils::execute_ssh_command(session.unwrap(), command, use_shell, display_output, chdir) + }; + + match result { + Ok((stdout, stderr, exit_status)) => { + if exit_status != 0 { + return Err(format!( + "Command execution failed with exit status: {}. Stopping further tasks.", + exit_status + ) + .red() + .into()); + } + + if let Some(register) = register { + let register_value = serde_json::to_value(common::Register { + stdout: stdout.clone(), + stderr: stderr.clone(), + rc: exit_status, + })?; + vars_map.insert(register.clone(), register_value); + println!( + "{}", + format!("Registering output to: {}", register).yellow() + ); + } + } + Err(e) => { + return Err(format!( + "Command execution failed with error: {}. Stopping further tasks.", + e + ) + .red() + .into()); + } + } + + Ok(()) +} + +pub fn process( + commands: Vec, + is_localhost: bool, + session: Option<&Session>, + use_shell: bool, + task_chdir: Option<&str>, + register: Option<&String>, + vars_map: &mut IndexMap, +) -> Result<(), Box> { + for cmd in commands { + let substituted_cmd = utils::replace_placeholders(&cmd, vars_map); + println!("{}", format!("> {}", substituted_cmd).magenta()); + + let display_output = register.is_none(); + handle_command_execution( + is_localhost, + session, + &substituted_cmd, + use_shell, + display_output, + task_chdir, + register, + vars_map, + )?; + } + + Ok(()) +} diff --git a/src/modules/debug.rs b/src/modules/debug.rs new file mode 100644 index 0000000..d08dbe3 --- /dev/null +++ b/src/modules/debug.rs @@ -0,0 +1,15 @@ +use colored::Colorize; +use indexmap::IndexMap; +use serde_json::Value; + +use crate::common::Debug; +use crate::utils; + +pub fn process(debug: &Debug, vars_map: &IndexMap) { + println!("{}", "Debug:".blue()); + for (key, msg) in debug.0.iter() { + println!("{}", format!("{}:", key).blue()); + let debug_msg = utils::replace_placeholders(msg, vars_map); + println!("{}", format!("{}", debug_msg).blue()); + } +} diff --git a/src/modules/mod.rs b/src/modules/mod.rs new file mode 100644 index 0000000..5eb1720 --- /dev/null +++ b/src/modules/mod.rs @@ -0,0 +1,3 @@ +pub mod command; +pub mod debug; +pub mod when; diff --git a/src/modules/when.rs b/src/modules/when.rs new file mode 100644 index 0000000..e176741 --- /dev/null +++ b/src/modules/when.rs @@ -0,0 +1,18 @@ +use indexmap::IndexMap; +use serde_json::Value; + +use crate::utils; + +pub fn process(condition: &Option, vars_map: &IndexMap) -> bool { + if let Some(cond) = condition { + let template_str = format!("{{% if {} %}}true{{% else %}}false{{% endif %}}", cond); + let rendered_cond = utils::replace_placeholders(&template_str, vars_map); + if rendered_cond == "false" { + false + } else { + true + } + } else { + true + } +} diff --git a/src/utils.rs b/src/utils.rs index 1652984..a414f2f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,4 +1,4 @@ -use colored::*; +use colored::Colorize; use indexmap::IndexMap; use minijinja::{value::Value as MiniJinjaValue, Environment, UndefinedBehavior}; use serde::Deserialize;