diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 76fd67296b..5179ccf80a 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -4892,6 +4892,7 @@ dependencies = [ "lazy_static", "phf", "regex", + "serde_json", "unicode-general-category", "windmill-common", "windmill-parser", diff --git a/backend/parsers/windmill-parser-bash/Cargo.toml b/backend/parsers/windmill-parser-bash/Cargo.toml index 0ae341ef8b..22579e82c3 100644 --- a/backend/parsers/windmill-parser-bash/Cargo.toml +++ b/backend/parsers/windmill-parser-bash/Cargo.toml @@ -16,4 +16,5 @@ unicode-general-category.workspace = true itertools.workspace = true anyhow.workspace = true regex.workspace = true -lazy_static.workspace = true \ No newline at end of file +lazy_static.workspace = true +serde_json.workspace = true \ No newline at end of file diff --git a/backend/parsers/windmill-parser-bash/src/lib.rs b/backend/parsers/windmill-parser-bash/src/lib.rs index fdd5f26fe6..a43e079cb7 100644 --- a/backend/parsers/windmill-parser-bash/src/lib.rs +++ b/backend/parsers/windmill-parser-bash/src/lib.rs @@ -1,6 +1,8 @@ #![allow(non_snake_case)] // TODO: switch to parse_* function naming +use anyhow::anyhow; use regex::Regex; +use serde_json::json; use std::collections::HashMap; use windmill_parser::{Arg, MainArgSignature, Typ}; @@ -17,19 +19,32 @@ pub fn parse_bash_sig(code: &str) -> windmill_common::error::Result anyhow::Result>> { - let mut hm = HashMap::new(); - let re = Regex::new(r#"(?m)^(\w+)="\$(\d+)"$"#).unwrap(); - for cap in re.captures_iter(code) { - hm.insert(cap[2].parse::()?, cap[1].to_string()); + let mut hm: HashMap)> = HashMap::new(); + for cap in RE.captures_iter(code) { + hm.insert( + cap.get(2) + .or(cap.get(3)) + .and_then(|x| x.as_str().parse::().ok()) + .ok_or_else(|| anyhow!("Impossible to parse arg digit"))?, + ( + cap[1].to_string(), + cap.get(4).map(|x| x.as_str().to_string()), + ), + ); } let mut args = vec![]; for i in 1..20 { if hm.contains_key(&i) { + let (name, default) = hm.get(&i).unwrap(); args.push(Arg { - name: hm[&i].clone(), + name: name.clone(), typ: Typ::Str(None), - default: None, + default: default.clone().map(|x| json!(x)), otyp: None, has_default: false, }); @@ -43,6 +58,8 @@ fn parse_file(code: &str) -> anyhow::Result>> { #[cfg(test)] mod tests { + use serde_json::json; + use super::*; #[test] @@ -50,8 +67,7 @@ mod tests { let code = r#" token="$1" image="$2" -digest="${3:-latest}" -foo="$4" +digest="${3:-latest with spaces}" "#; //println!("{}", serde_json::to_string()?); @@ -74,6 +90,13 @@ foo="$4" typ: Typ::Str(None), default: None, has_default: false + }, + Arg { + otyp: None, + name: "digest".to_string(), + typ: Typ::Str(None), + default: Some(json!("latest with spaces")), + has_default: false } ] } diff --git a/frontend/src/lib/script_helpers.ts b/frontend/src/lib/script_helpers.ts index c254c43615..b017334d3d 100644 --- a/frontend/src/lib/script_helpers.ts +++ b/frontend/src/lib/script_helpers.ts @@ -114,6 +114,7 @@ export async function main( export const BASH_INIT_CODE = `# arguments of the form X="$I" are parsed as parameters X of type string msg="$1" +dflt="\${2:-default value}" # the last line of the stdout is the return value echo "Hello $msg"