From 35e186f828faf4e42b466a6a3a0b665df7c14e46 Mon Sep 17 00:00:00 2001 From: "R. Tyler Croy" Date: Fri, 1 Jan 2021 15:39:06 -0800 Subject: [PATCH] Explore syntax for built-in tasks. Implementation is still ... crap --- Cargo.lock | 79 +++++++++++++++++++++++++++++++++++++++++++ examples/basic.zplan | 8 ++--- model/Cargo.toml | 1 + model/src/plan/mod.rs | 13 ++++--- model/src/task/mod.rs | 29 ++++++++++++++++ tasks/shell/sh.ztask | 19 ----------- 6 files changed, 120 insertions(+), 29 deletions(-) delete mode 100644 tasks/shell/sh.ztask diff --git a/Cargo.lock b/Cargo.lock index 1c68d8b..7b8abe6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -131,6 +131,16 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +[[package]] +name = "form_urlencoded" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00" +dependencies = [ + "matches", + "percent-encoding", +] + [[package]] name = "generic-array" version = "0.12.3" @@ -192,6 +202,17 @@ dependencies = [ "quick-error 1.2.3", ] +[[package]] +name = "idna" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "itoa" version = "0.4.7" @@ -266,6 +287,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" +[[package]] +name = "matches" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" + [[package]] name = "memchr" version = "2.3.4" @@ -315,6 +342,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + [[package]] name = "pest" version = "2.1.3" @@ -542,6 +575,21 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "tinyvec" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf8dbc19eb42fba10e8feaaec282fb50e2c14b2726d6301dbfeed0f73306a6f" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + [[package]] name = "typenum" version = "1.12.0" @@ -554,12 +602,42 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +[[package]] +name = "unicode-bidi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" +dependencies = [ + "matches", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13e63ab62dbe32aeee58d1c5408d35c36c392bba5d9d3142287219721afe606" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-xid" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +[[package]] +name = "url" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + [[package]] name = "vcpkg" version = "0.2.11" @@ -633,4 +711,5 @@ dependencies = [ "serde_json", "serde_yaml", "ssh2", + "url", ] diff --git a/examples/basic.zplan b/examples/basic.zplan index 9fdfd03..338a303 100644 --- a/examples/basic.zplan +++ b/examples/basic.zplan @@ -12,12 +12,8 @@ task 'tasks/echo' { msg = 'This is nice' } -task 'tasks/shell/bash' { +task 'zap://sh' { script = ''' - ls - touch foo + pwd ''' - - // Don't run again if the foo file is present - provides = 'foo' } diff --git a/model/Cargo.toml b/model/Cargo.toml index 813a64f..748cc2c 100644 --- a/model/Cargo.toml +++ b/model/Cargo.toml @@ -22,3 +22,4 @@ serde_derive = "~1.0" serde_json = "~1.0" serde_yaml = "~0.8" ssh2 = "~0.9.0" +url = "~2.2" diff --git a/model/src/plan/mod.rs b/model/src/plan/mod.rs index 8961e63..9263609 100644 --- a/model/src/plan/mod.rs +++ b/model/src/plan/mod.rs @@ -6,7 +6,7 @@ use pest::Parser; use std::collections::HashMap; use std::path::PathBuf; -use crate::ExecutableTask; +use crate::{ExecutableTask, Task}; #[derive(Parser)] #[grammar = "plan.pest"] @@ -36,10 +36,15 @@ impl Plan { match pair.as_rule() { Rule::string => { let name = parse_str(&mut pair.into_inner())?; - // The .ztask extension is to be omitted in task declarations - let path = PathBuf::from(format!("{}.ztask", name)); + let task = match name.starts_with("zap://") { + true => Task::from_url(&name), + false => { + let path = PathBuf::from(format!("{}.ztask", name)); + Task::from_path(&path) + } + }; - match crate::task::Task::from_path(&path) { + match task { Ok(task) => raw_task = Some(task), Err(err) => { error!("Failed to parse task: {:?}", err); diff --git a/model/src/task/mod.rs b/model/src/task/mod.rs index ee47c54..43c8375 100644 --- a/model/src/task/mod.rs +++ b/model/src/task/mod.rs @@ -7,6 +7,7 @@ use std::collections::HashMap; use std::fs::File; use std::io::Read; use std::path::PathBuf; +use url::Url; #[derive(Parser)] #[grammar = "task.pest"] @@ -180,6 +181,28 @@ impl Task { )) } + pub fn from_url(url: &str) -> Result> { + if let Ok(url) = Url::parse(url) { + println!("UR: {:?}", url); + if let Some(name) = url.host_str() { + // XXX: Temporary hard-coding see #5 + let mut task = Task::new(name); + assert_eq!(name, "sh"); + // This is a hacky temporary workaround for now too + // a real builtin shouldn't need to bother with a handlebars template + task.script.inline = Some("#!/bin/sh\n{{script}}".into()); + return Ok(task); + } + } + + Err(PestError::new_from_pos( + ErrorVariant::CustomError { + message: "Could not find a valid task definition".to_string(), + }, + pest::Position::from_start(url), + )) + } + pub fn from_path(path: &PathBuf) -> Result> { match File::open(path) { Ok(mut file) => { @@ -317,4 +340,10 @@ mod tests { let script = task.script; assert_eq!(script.as_bytes(None).unwrap(), "env".as_bytes()); } + + #[test] + fn task_from_url() { + let task = Task::from_url("zap://sh").expect("Failed to load task from URL"); + assert_eq!(task.name, "sh"); + } } diff --git a/tasks/shell/sh.ztask b/tasks/shell/sh.ztask deleted file mode 100644 index 6aa3acf..0000000 --- a/tasks/shell/sh.ztask +++ /dev/null @@ -1,19 +0,0 @@ -/* - * The sh task is a simple passthrough to /bin/sh on the target machine - */ - -task Sh { - parameters { - script { - required = true - help = 'A script to run via the /bin/sh' - type = string - } - } - - script { - inline = '''#!/bin/sh - {{script}} - ''' - } -}