diff --git a/backend/Cargo.lock b/backend/Cargo.lock index fe13bd9b74..b93b01192e 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -7243,6 +7243,8 @@ dependencies = [ "anyhow", "gosyn", "itertools 0.11.0", + "lazy_static", + "regex", "windmill-parser", ] diff --git a/backend/parsers/windmill-parser-go/Cargo.toml b/backend/parsers/windmill-parser-go/Cargo.toml index 83f95edd1a..ecba62cff4 100644 --- a/backend/parsers/windmill-parser-go/Cargo.toml +++ b/backend/parsers/windmill-parser-go/Cargo.toml @@ -12,4 +12,6 @@ path = "./src/lib.rs" windmill-parser.workspace = true itertools.workspace = true anyhow.workspace = true -gosyn.workspace = true \ No newline at end of file +gosyn.workspace = true +lazy_static.workspace = true +regex.workspace = true \ No newline at end of file diff --git a/backend/parsers/windmill-parser-go/src/lib.rs b/backend/parsers/windmill-parser-go/src/lib.rs index c7e06a102a..01012291f1 100644 --- a/backend/parsers/windmill-parser-go/src/lib.rs +++ b/backend/parsers/windmill-parser-go/src/lib.rs @@ -6,8 +6,13 @@ use gosyn::{ }; use itertools::Itertools; +use regex::Regex; use windmill_parser::{Arg, MainArgSignature, ObjectProperty, Typ}; +lazy_static::lazy_static! { + pub static ref REQUIRE_PARSE: Regex = Regex::new(r"//require (.*)\n").unwrap(); +} + pub fn parse_go_sig(code: &str) -> anyhow::Result { let filtered_code = filter_non_main(code); let file = parse_source(&filtered_code).map_err(|x| anyhow::anyhow!(x.to_string()))?; @@ -46,7 +51,14 @@ pub fn parse_go_imports(code: &str) -> anyhow::Result> { }) .collect(); imports.sort(); - Ok(imports) + Ok([ + imports, + REQUIRE_PARSE + .captures_iter(code) + .map(|x| x[1].to_string()) + .collect_vec(), + ] + .concat()) } fn get_name(param: &Field) -> String { diff --git a/backend/windmill-worker/src/go_executor.rs b/backend/windmill-worker/src/go_executor.rs index 8a5a2ed67c..332de75481 100644 --- a/backend/windmill-worker/src/go_executor.rs +++ b/backend/windmill-worker/src/go_executor.rs @@ -12,7 +12,7 @@ use windmill_common::{ jobs::QueuedJob, utils::calculate_hash, }; -use windmill_parser_go::parse_go_imports; +use windmill_parser_go::{parse_go_imports, REQUIRE_PARSE}; use crate::{ common::{ @@ -296,6 +296,9 @@ async fn gen_go_mod( } } +use std::fs::OpenOptions; +use std::io::prelude::*; + pub async fn install_go_dependencies( job_id: &Uuid, code: &str, @@ -329,6 +332,16 @@ pub async fn install_go_dependencies( None, ) .await?; + + for x in REQUIRE_PARSE.captures_iter(code) { + let mut file = OpenOptions::new() + .write(true) + .append(true) + .open(format!("{job_dir}/go.mod")) + .unwrap(); + + writeln!(file, "require {}\n", &x[1])?; + } } let mut new_lockfile = false; diff --git a/backend/windmill-worker/src/js_eval.rs b/backend/windmill-worker/src/js_eval.rs index c3a27110af..9360287e7f 100644 --- a/backend/windmill-worker/src/js_eval.rs +++ b/backend/windmill-worker/src/js_eval.rs @@ -67,6 +67,7 @@ impl TimersPermission for PermissionsContainer { () } } + pub struct OptAuthedClient(Option); pub async fn eval_timeout( expr: String, @@ -122,8 +123,6 @@ pub async fn eval_timeout( .enable_all() .build()?; - let re = Regex::new(r"import (.*)\n").unwrap(); - let expr = re.replace_all(&expr, "").to_string(); // pretty frail but this it to make the expr more user friendly and not require the user to write await let expr = ["variable", "step", "resource", "result_by_id"] .into_iter() diff --git a/frontend/src/lib/script_helpers.ts b/frontend/src/lib/script_helpers.ts index 1b3b383919..de7d800ab2 100644 --- a/frontend/src/lib/script_helpers.ts +++ b/frontend/src/lib/script_helpers.ts @@ -81,6 +81,9 @@ import ( // wmill "github.com/windmill-labs/windmill-go-client" ) +// Pin dependencies partially in go.mod with a comment starting with "//require": +//require rsc.io/quote v1.5.1 + // the main must return (interface{}, error) func main(x string, nested struct {