diff --git a/src/config/mod.rs b/src/config/mod.rs index 0f25cf0..1820475 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,6 +1,6 @@ use log::{info, warn}; use serde::{Deserialize, Serialize}; -use std::{fs::File, collections::HashMap}; +use std::{collections::HashMap, fs::File}; pub(crate) mod extension; pub(crate) mod patch; @@ -98,7 +98,7 @@ impl Chart { Some(mut vars) => { vars.extend(global_vars); Some(vars) - }, + } None => Some(global_vars), } }; diff --git a/src/config/patch.rs b/src/config/patch.rs index 9aacb9c..d3b02c0 100644 --- a/src/config/patch.rs +++ b/src/config/patch.rs @@ -62,7 +62,12 @@ impl PatchInterface for YqPatch { fn apply(&self, chart_local_path: String) -> Result<(), Box> { let cmd = match self.op { YqOperations::Add => { - let value = match self.value.clone().unwrap().starts_with(['{', '[', '\"', '\'']) { + let value = match self + .value + .clone() + .unwrap() + .starts_with(['{', '[', '\"', '\'']) + { true => self.value.clone().unwrap(), false => format!("\"{}\"", self.value.clone().unwrap()), }; diff --git a/src/helpers/cli.rs b/src/helpers/cli.rs index 05e89f6..4dea28c 100644 --- a/src/helpers/cli.rs +++ b/src/helpers/cli.rs @@ -1,6 +1,5 @@ -use std::process::{Command, ExitStatus}; - use log::info; +use std::process::Command; pub(crate) fn cli_exec(command: String) -> Result> { info!("executing: {}", command); @@ -37,9 +36,11 @@ pub(crate) fn cli_exec_from_dir( stdout.pop(); Ok(stdout) } + #[cfg(test)] mod tests { use crate::helpers::cli::{cli_exec, cli_exec_from_dir}; + use tempfile::TempDir; #[test] fn test_stderr() { @@ -57,10 +58,19 @@ mod tests { #[test] fn test_stdout_current_dir() { - let dir = tempfile::tempdir().unwrap(); + let dir = TempDir::new().unwrap(); + let dir_str = dir.path().to_str().unwrap().to_string(); let command = "echo $PWD"; - let dir_str = dir.into_path().into_os_string().into_string().unwrap(); let test = cli_exec_from_dir(command.to_string(), dir_str.clone()); assert!(test.unwrap().to_string().contains(dir_str.as_str())); } + + #[test] + fn test_stderr_current_dir() { + let dir = TempDir::new().unwrap(); + let dir_str = dir.path().to_str().unwrap().to_string(); + let command = ">&2 echo \"error\" && exit 1"; + let test = cli_exec_from_dir(command.to_string(), dir_str.clone()); + assert_eq!(test.err().unwrap().to_string(), "error\n".to_string()); + } } diff --git a/src/main.rs b/src/main.rs index 87cf7d5..0367306 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ pub(crate) mod helpers; pub(crate) mod mirror; pub(crate) mod patch; pub(crate) mod source; +pub(crate) mod template; use clap::Parser; use log::{error, info}; diff --git a/src/mirror/custom_command.rs b/src/mirror/custom_command.rs index c4f3983..4e071a2 100644 --- a/src/mirror/custom_command.rs +++ b/src/mirror/custom_command.rs @@ -1,6 +1,5 @@ -use crate::helpers::cli::cli_exec_from_dir; - use super::Target; +use crate::{helpers::cli::cli_exec_from_dir, template}; pub(crate) struct CustomCommands { pub(crate) package: Vec, @@ -15,14 +14,14 @@ impl Target for CustomCommands { dry_run: bool, ) -> Result<(), Box> { for cmd_tmpl in self.package.clone() { - let mut reg = super::register_handlebars(); + let mut reg = template::register_handlebars(); reg.register_template_string("cmd", cmd_tmpl)?; let cmd = reg.render("cmd", &chart_local)?; cli_exec_from_dir(cmd, workdir_path.clone())?; } if !dry_run { for cmd_tmpl in self.upload.clone() { - let mut reg = super::register_handlebars(); + let mut reg = template::register_handlebars(); reg.register_template_string("cmd", cmd_tmpl)?; let cmd = reg.render("cmd", &chart_local)?; cli_exec_from_dir(cmd, workdir_path.clone())?; @@ -31,3 +30,93 @@ impl Target for CustomCommands { Ok(()) } } + +#[cfg(test)] +mod tests { + use super::CustomCommands; + use crate::{mirror::Target, source::ChartLocal}; + use std::{collections::HashMap, fs::create_dir_all, path::Path}; + use tempfile::TempDir; + + fn get_chart_local() -> crate::source::ChartLocal { + let mut vars: HashMap = HashMap::new(); + vars.insert("key".to_string(), "value".to_string()); + ChartLocal { + name: "chart".to_string(), + version: "1.0.0".to_string(), + path: "chart-1.0.0".to_string(), + repo_url: "https:://helm.repo".to_string(), + vars, + } + } + + fn prepare_test_workdir(chart_path: String) -> String { + let workdir = TempDir::new().unwrap().path().to_str().unwrap().to_string(); + println!("test workdir is {}", workdir.clone()); + create_dir_all(format!("{}/{}", workdir, chart_path)).unwrap(); + workdir + } + + #[test] + fn test_package_basic() { + let chart_local = get_chart_local(); + let workdir = prepare_test_workdir(chart_local.path.clone()); + + let custom_commands = CustomCommands { + package: vec!["touch package".to_string()], + upload: vec!["touch upload".to_string()], + }; + + let cc_target: Box = Box::from(custom_commands); + cc_target.push(workdir.clone(), chart_local, true).unwrap(); + + assert!(Path::new(&format!("{}/package", workdir)).exists()); + assert!(!Path::new(&format!("{}/upload", workdir)).exists()); + } + + #[test] + fn test_upload_basic() { + let chart_local = get_chart_local(); + let workdir = prepare_test_workdir(chart_local.path.clone()); + + let custom_commands = CustomCommands { + package: vec!["touch package".to_string()], + upload: vec!["touch upload".to_string()], + }; + + let cc_target: Box = Box::from(custom_commands); + cc_target.push(workdir.clone(), chart_local, false).unwrap(); + + assert!(Path::new(&format!("{}/package", workdir)).exists()); + assert!(Path::new(&format!("{}/upload", workdir)).exists()); + } + + #[test] + fn test_templates() { + let chart_local = get_chart_local(); + let workdir = prepare_test_workdir(chart_local.path.clone()); + + let custom_commands = CustomCommands { + package: vec!["touch {{ name }}-{{ version }}".to_string()], + upload: vec!["touch {{ repo_url }}-{{ vars.key }}".to_string()], + }; + + let cc_target: Box = Box::from(custom_commands); + cc_target + .push(workdir.clone(), chart_local.clone(), true) + .unwrap(); + + assert!(Path::new(&format!( + "{}/{}-{}", + workdir, chart_local.name, chart_local.version + )) + .exists()); + assert!(!Path::new(&format!( + "{}/{}-{}", + workdir, + chart_local.repo_url, + chart_local.vars.get("key").unwrap() + )) + .exists()); + } +} diff --git a/src/mirror/git.rs b/src/mirror/git.rs index bd97eab..5b0a40d 100644 --- a/src/mirror/git.rs +++ b/src/mirror/git.rs @@ -1,4 +1,4 @@ -use crate::{helpers::cli::cli_exec_from_dir, source::ChartLocal}; +use crate::{helpers::cli::cli_exec_from_dir, source::ChartLocal, template}; use dircpy::*; use super::Target; @@ -18,7 +18,7 @@ impl Target for Git { chart_local: ChartLocal, dry_run: bool, ) -> Result<(), Box> { - let mut reg = super::register_handlebars(); + let mut reg = template::register_handlebars(); // Prepare the URL reg.register_template_string("url", self.url.clone())?; let url = reg.render("url", &chart_local)?; diff --git a/src/mirror/mod.rs b/src/mirror/mod.rs index b9731c3..b2826fb 100644 --- a/src/mirror/mod.rs +++ b/src/mirror/mod.rs @@ -1,7 +1,3 @@ -use chrono::prelude::*; -use handlebars::{handlebars_helper, Handlebars}; -use time::{format_description::parse, OffsetDateTime}; - use crate::{config::Mirror, source::ChartLocal}; pub(crate) mod custom_command; @@ -44,13 +40,3 @@ pub(crate) fn mirror_from_mirror_obj( mirror.name ))) } - -handlebars_helper!(date_helper: | | Utc::now().format("%Y-%m-%d").to_string()); -handlebars_helper!(time_helper: | | Utc::now().format("%H-%M-%S").to_string()); - -pub(crate) fn register_handlebars() -> Handlebars<'static> { - let mut handlebars = Handlebars::new(); - handlebars.register_helper("date", Box::new(date_helper)); - handlebars.register_helper("time", Box::new(time_helper)); - handlebars -} diff --git a/src/source/git.rs b/src/source/git.rs index efacf47..6d6dc3a 100644 --- a/src/source/git.rs +++ b/src/source/git.rs @@ -1,4 +1,7 @@ -use std::{fs::{self, rename}, collections::HashMap}; +use std::{ + collections::HashMap, + fs::{self, rename}, +}; use crate::helpers::cli::{cli_exec, cli_exec_from_dir}; use base64::{engine::general_purpose, Engine as _}; @@ -24,7 +27,11 @@ impl From for Git { } impl Repo for Git { - fn pull(&self, workdir_path: String, vars: HashMap) -> Result> { + fn pull( + &self, + workdir_path: String, + vars: HashMap, + ) -> Result> { let repo_local_name = general_purpose::STANDARD_NO_PAD.encode(self.git_url.clone()); let cmd = format!( "git clone {} {}/{}", diff --git a/src/source/helm.rs b/src/source/helm.rs index 7ee2755..0375d23 100644 --- a/src/source/helm.rs +++ b/src/source/helm.rs @@ -1,7 +1,7 @@ use super::{ChartLocal, Repo}; use crate::helpers::cli::{cli_exec, cli_exec_from_dir}; use base64::{engine::general_purpose, Engine as _}; -use std::{fs::rename, collections::HashMap}; +use std::{collections::HashMap, fs::rename}; pub(crate) enum RepoKind { Default, @@ -46,7 +46,11 @@ impl Helm { } } - fn pull_default(&self, workdir_path: String, vars: HashMap) -> Result> { + fn pull_default( + &self, + workdir_path: String, + vars: HashMap, + ) -> Result> { // Add repo and update let repo_local_name = general_purpose::STANDARD_NO_PAD.encode(self.repository_url.clone()); let cmd = format!("helm repo add {} {}", repo_local_name, self.repository_url); @@ -93,7 +97,11 @@ impl Helm { } impl Repo for Helm { - fn pull(&self, workdir_path: String, vars: HashMap) -> Result> { + fn pull( + &self, + workdir_path: String, + vars: HashMap, + ) -> Result> { let repository_kind = self.repo_kind_from_url()?; let path = match repository_kind { RepoKind::Default => self.pull_default(workdir_path, vars)?, diff --git a/src/source/mod.rs b/src/source/mod.rs index dac7c0b..6e37d06 100644 --- a/src/source/mod.rs +++ b/src/source/mod.rs @@ -12,7 +12,7 @@ pub(crate) struct ChartLocal { pub(crate) version: String, pub(crate) path: String, pub(crate) repo_url: String, - pub(crate) vars: HashMap + pub(crate) vars: HashMap, } impl ChartLocal { @@ -22,7 +22,11 @@ impl ChartLocal { } pub(crate) trait Repo { - fn pull(&self, workdir_path: String, vars: HashMap) -> Result>; + fn pull( + &self, + workdir_path: String, + vars: HashMap, + ) -> Result>; } #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] diff --git a/src/template/mod.rs b/src/template/mod.rs new file mode 100644 index 0000000..843ee9f --- /dev/null +++ b/src/template/mod.rs @@ -0,0 +1,43 @@ +use chrono::prelude::*; +use handlebars::{handlebars_helper, Handlebars}; + +handlebars_helper!(date_helper: | | Utc::now().format("%Y-%m-%d").to_string()); +handlebars_helper!(time_helper: | | Utc::now().format("%H-%M-%S").to_string()); + +pub(crate) fn register_handlebars() -> Handlebars<'static> { + let mut handlebars = Handlebars::new(); + handlebars.register_helper("date", Box::new(date_helper)); + handlebars.register_helper("time", Box::new(time_helper)); + handlebars +} + +#[cfg(test)] +mod tests { + use std::collections::HashMap; + + use chrono::Utc; + + use crate::template::register_handlebars; + + #[test] + fn test_date_helper() { + let mut reg = register_handlebars(); + reg.register_template_string("test", "{{ date }}").unwrap(); + let result = reg + .render("test", &HashMap::::new()) + .unwrap(); + let expected = Utc::now().format("%Y-%m-%d").to_string(); + assert_eq!(result, expected); + } + + #[test] + fn test_time_helper() { + let mut reg = register_handlebars(); + reg.register_template_string("test", "{{ time }}").unwrap(); + let result = reg + .render("test", &HashMap::::new()) + .unwrap(); + let expected = Utc::now().format("%H-%M-%S").to_string(); + assert_eq!(result, expected); + } +}