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:
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