cinderella

[unmaintained] simple CI engine
Log | Files | Refs | README | LICENSE

commit d53ec6d1d8769a8365db8c96374f76e3db309ff4
parent 238ccfb2b65d08c057255bdff5f9b945f12a7385
Author: Stefan Koch <programming@stefan-koch.name>
Date:   Tue, 17 Sep 2019 21:31:19 +0200

use evalexpr instead of unix 'test' for expression evaluation

Diffstat:
M.cinderella.toml | 2+-
MCargo.lock | 7+++++++
MCargo.toml | 1+
MREADME.md | 9+++++----
Msrc/execution.rs | 42+++++++++++++++++++++++++++++++-----------
Msrc/lib.rs | 2+-
6 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/.cinderella.toml b/.cinderella.toml @@ -11,4 +11,4 @@ commands = [ "rm -f /opt/cinderella/cinderella-{{ branch }}", "mv /opt/cinderella/.cinderella-{{ branch }} /opt/cinderella/cinderella-{{ branch }}", ] -when = "'{{ branch }}' == 'master'" +when = "branch == \"master\"" diff --git a/Cargo.lock b/Cargo.lock @@ -33,6 +33,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "cinderella" version = "0.1.0" dependencies = [ + "evalexpr 5.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "git2 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -41,6 +42,11 @@ dependencies = [ ] [[package]] +name = "evalexpr" +version = "5.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] name = "getopts" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -336,6 +342,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" "checksum cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "b548a4ee81fccb95919d4e22cfea83c7693ebfd78f0495493178db20b3139da7" "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" +"checksum evalexpr 5.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5a8619223d40c23279f9120e2646712ec3eeeb68b546ed993c619d77682bdef8" "checksum getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" "checksum getrandom 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fc344b02d3868feb131e8b5fe2b9b0a1cc42942679af493061fc13b853243872" "checksum git2 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "327d698f86a7ebdfeb86a4238ccdb004828939d3a3555b6ead679541d14e36c0" diff --git a/Cargo.toml b/Cargo.toml @@ -9,6 +9,7 @@ getopts = "0.2" git2 = { version = "0.10.0", features = ["vendored-openssl"] } rand = "0.7.0" toml = { version = "0.5", features = ["preserve_order"] } +evalexpr = "5" [dev-dependencies] tempfile = "3" diff --git a/README.md b/README.md @@ -68,9 +68,10 @@ to run a pipeline only for specific branches: commands = [ "cargo build --release", ] -when = "'{{ branch }}' == 'master'" +when = "branch == \"master\"" ``` -The condition will be executed with the Linux `test` command. Please be aware -that this behaviour will likely change in the future and another test -execution engine might be used. +The condition will be executed with the Rust library +[evalexpr](https://docs.rs/evalexpr/5.0.5/evalexpr/index.html). Unlike in +the commands, variables in the `when` conditions are used without +braces. diff --git a/src/execution.rs b/src/execution.rs @@ -2,6 +2,8 @@ use std::collections::HashMap; use std::process::Command; use std::io::Write; +use evalexpr::{self, Context, HashMapContext, Value}; + use crate::pipeline; pub fn execute<W: Write>( @@ -12,8 +14,7 @@ pub fn execute<W: Write>( for pipeline in pipelines { let execute = match &pipeline.when { Some(when) => { - let test = replace_variables(&when, &variables); - execute_test(&test) + execute_test(&when, &variables) } None => true, }; @@ -56,15 +57,18 @@ fn split_command<'a>(command: &'a str) -> Vec<&'a str> { parts } -fn execute_test(test: &str) -> bool { - let args = split_command(&test); +fn execute_test(test: &str, variables: &HashMap<String, String>) -> bool { + let mut context = HashMapContext::new(); - let status = Command::new("test") - .args(&args) - .status() - .expect(&format!("failed to run test {}", test)); + for (key, value) in variables { + context.set_value(key.to_string(), Value::String(value.clone())) + .unwrap(); + } - status.success() + match evalexpr::eval_boolean_with_context(test, &context) { + Ok(true) => true, + _ => false, + } } fn replace_variables(command: &str, variables: &HashMap<String, String>) @@ -125,11 +129,11 @@ mod tests { } #[test] - fn test_conditional_pipeline() { + fn test_conditional_pipeline_false() { let pipeline = Pipeline { name: String::from("my-test"), commands: vec!["echo 'Building non-master'".to_string()], - when: Some(String::from("\"{{ branch }}\" != \"master\"")), + when: Some(String::from("branch != \"master\"")), }; let mut variables = HashMap::new(); variables.insert(String::from("branch"), String::from("master")); @@ -139,4 +143,20 @@ mod tests { println!("{}", result); assert!(!result.contains("non-master")); } + + #[test] + fn test_conditional_pipeline_true() { + let pipeline = Pipeline { + name: String::from("my-test"), + commands: vec!["echo 'Building master'".to_string()], + when: Some(String::from("branch == \"master\"")), + }; + let mut variables = HashMap::new(); + variables.insert(String::from("branch"), String::from("master")); + + let result = execute_stringout(pipeline, variables); + + println!("{}", result); + assert!(result.contains("Building master")); + } } diff --git a/src/lib.rs b/src/lib.rs @@ -39,7 +39,7 @@ fn cinderella_file(folder: &PathBuf) -> PathBuf { pub fn run(repo_ptr: &RepoPointer) { let repo = vcs::GitSource { - src: String::from(&repo_ptr.repo_url), + src: repo_ptr.repo_url.clone(), }; // generate a temp unique work dir