mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-18 16:02:10 +00:00
feat: add powershell common parameters support (#8683)
* feat: add powershell common parameters support (-Verbose, -Debug, -ErrorAction, -WhatIf) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add powershell common params to script editor test panel Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: detect CmdletBinding from code instead of schema in script editor Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: ignore commented-out CmdletBinding in powershell detection Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use preference variables for -Verbose/-Debug instead of CLI args Verbose/Debug output goes to PowerShell stream 4/5 which isn't captured by the 2>&1 redirect. Setting $VerbosePreference/$DebugPreference in the wrapper scope propagates to child scripts and output flows through the host to stderr, which Windmill captures as logs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use *>&1 to capture all powershell streams including verbose/debug The previous 2>&1 only captured error stream. Verbose (stream 4) and debug (stream 5) output was silently lost. Using *>&1 redirects all streams to success stream so they flow through Tee-Object into logs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use targeted stream redirects (4>&1 5>&1 2>&1) instead of *>&1 *>&1 breaks $PSCmdlet.ShouldProcess() by redirecting internal streams. Only redirect verbose (4), debug (5), and error (2) to success stream. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: revert to 2>&1 redirect — stream 4/5 redirects break powershell Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: use 4>&1 5>&1 for verbose/debug capture, remove WhatIf support Stream 4/5 redirects capture verbose/debug in the pipeline. WhatIf is removed because $PSCmdlet.ShouldProcess() doesn't work when scripts are invoked through Windmill's wrapper. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: redirect verbose/debug to files to keep result pipeline clean Verbose (4) and debug (5) streams are redirected to separate log files during script execution, then output via Write-Host after the script completes. This keeps them out of the Tee-Object pipeline (used for result extraction) while still showing them in the job logs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: output verbose/debug to stderr via Console.Error for log capture Write-Host goes to stdout which gets mixed with result output and truncated by OSS log threshold. Using [Console]::Error.WriteLine() writes to stderr which Windmill captures separately as logs, with VERBOSE:/DEBUG: prefixes for clarity. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: redirect script output to file only, send verbose/debug to stdout The OSS log storage has a 9KB threshold. Previously, Tee-Object sent the full JSON result to both stdout (logs) and the pipe file, eating the log budget. Now script output goes only to the pipe file (> $pipe), and only verbose/debug messages go to stdout for the log viewer. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: preserve original Tee-Object behavior, append verbose/debug after Keep the original wrapper behavior (Tee-Object to stdout + pipe file). Only add 4>verbose.log 5>debug.log to capture those streams, and output them at the end of logs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: inject preference vars into main.ps1 instead of CLI args Passing -Verbose/-Debug as CLI args causes PowerShell module loading to emit verbose noise. Instead, inject $VerbosePreference/$DebugPreference inside main.ps1's try block so they only affect user code. Stream 4/5 are still redirected to files in the wrapper for log output. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: restore common param toggles from previous job args on Run Again Extract _wm_ps_* keys from loaded args and initialize the toggle states in PowerShellCommonParams. Also strip them from main args so they don't appear as unknown schema form inputs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: show active common param badges when section is collapsed Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: inject ErrorAction as preference variable instead of CLI arg -ErrorAction as a CLI arg only affects the caller, not the script's internal error handling. Setting $ErrorActionPreference inside main.ps1 correctly overrides the default 'Stop' behavior for the user's code. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: ensure full backward compatibility with existing powershell scripts - Only filter common param names when [CmdletBinding()] is present (without it, $Verbose etc. are regular user-defined parameters) - Only add 4>verbose.log 5>debug.log and log output lines when common params are actually enabled — original wrapper is unchanged otherwise Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: lighter styling for common params section Replaced heavy Section component with a subtle inline chevron toggle labeled "Common parameters". Smaller text, secondary color, indented options. Badges still show when collapsed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: rename section to CmdletBinding parameters Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: add ..Default::default() to windmill-parser-r (new parser from main) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: missing comma in graphql parser test + merge main Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: add missing commas before ..Default::default() in parser tests Merge from main brought test constructors with formatting issues from the original automated script (missing comma between last field and ..Default::default()). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: restore comment markers in nu parser test that script broke Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: address PR review — ignore commented CmdletBinding, clear stale params 1. Parser: strip comment lines before detecting [CmdletBinding()] to avoid false positives from commented-out attributes 2. RunForm: always assign psCommonParams (not just when non-empty) so stale settings from a previous run don't leak into later runs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,22 +22,82 @@ pub fn parse_bash_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing bash script".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
/// PowerShell common parameter names that are automatically added by [CmdletBinding()].
|
||||
/// These should be filtered from the parsed signature since they are not user-defined.
|
||||
const POWERSHELL_COMMON_PARAMS: &[&str] = &[
|
||||
"verbose",
|
||||
"debug",
|
||||
"erroraction",
|
||||
"errorvariable",
|
||||
"informationaction",
|
||||
"informationvariable",
|
||||
"outvariable",
|
||||
"outbuffer",
|
||||
"pipelinevariable",
|
||||
"warningaction",
|
||||
"warningvariable",
|
||||
"whatif",
|
||||
"confirm",
|
||||
"progressaction",
|
||||
];
|
||||
|
||||
/// Detects whether the script uses [CmdletBinding()] and whether it declares SupportsShouldProcess.
|
||||
fn detect_cmdlet_binding(code: &str) -> (bool, bool) {
|
||||
let attr_region = match extract_powershell_param_block_with_attributes(code, true) {
|
||||
Some((region, _)) => region,
|
||||
None => return (false, false),
|
||||
};
|
||||
// Strip comment lines to avoid false positives from commented-out [CmdletBinding()]
|
||||
let uncommented: String = attr_region
|
||||
.lines()
|
||||
.filter(|line| !line.trim_start().starts_with('#'))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
let lower = uncommented.to_lowercase();
|
||||
let has_cmd_binding = lower.contains("[cmdletbinding");
|
||||
let supports_should_process = has_cmd_binding
|
||||
&& lower.contains("supportsshouldprocess")
|
||||
&& !lower.contains("supportsshouldprocess=$false")
|
||||
&& !lower.contains("supportsshouldprocess = $false");
|
||||
(has_cmd_binding, supports_should_process)
|
||||
}
|
||||
|
||||
pub fn parse_powershell_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
let parsed = parse_powershell_file(&code)?;
|
||||
if let Some(x) = parsed {
|
||||
let args = x;
|
||||
if let Some(args) = parsed {
|
||||
let (has_cmd_binding, supports_should_process) = detect_cmdlet_binding(code);
|
||||
|
||||
// Filter out common parameters only when CmdletBinding is present
|
||||
// (without CmdletBinding, $Verbose etc. are regular user-defined parameters)
|
||||
let args = if has_cmd_binding {
|
||||
args.into_iter()
|
||||
.filter(|arg| !POWERSHELL_COMMON_PARAMS.contains(&arg.name.to_lowercase().as_str()))
|
||||
.collect()
|
||||
} else {
|
||||
args
|
||||
};
|
||||
|
||||
Ok(MainArgSignature {
|
||||
star_args: false,
|
||||
star_kwargs: false,
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
has_cmd_binding: if has_cmd_binding { Some(true) } else { None },
|
||||
supports_should_process: if supports_should_process {
|
||||
Some(true)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing powershell script".to_string()))
|
||||
@@ -96,7 +156,10 @@ fn parse_bash_file(code: &str) -> anyhow::Result<Option<Vec<Arg>>> {
|
||||
/// This function uses the existing extract_powershell_param_block validation, which already
|
||||
/// ensures that only comments, whitespace, and attributes appear before param. So we can
|
||||
/// simply return everything from the beginning to the end of the param block.
|
||||
pub fn extract_powershell_param_block_with_attributes(code: &str, include_attributes: bool) -> Option<(&str, &str)> {
|
||||
pub fn extract_powershell_param_block_with_attributes(
|
||||
code: &str,
|
||||
include_attributes: bool,
|
||||
) -> Option<(&str, &str)> {
|
||||
// First, use the existing function to validate and find the param block
|
||||
let param_block = extract_powershell_param_block(code, true)?;
|
||||
|
||||
@@ -450,11 +513,15 @@ fn parse_powershell_parameters(content: &str) -> anyhow::Result<Vec<Arg>> {
|
||||
|
||||
// Check if this is a Parameter attribute with Mandatory (case-insensitive)
|
||||
let lower = bracket_content.to_lowercase();
|
||||
if lower.starts_with("parameter(") || lower.starts_with("parameter ") {
|
||||
if lower.starts_with("parameter(")
|
||||
|| lower.starts_with("parameter ")
|
||||
{
|
||||
// Check for Mandatory (case-insensitive)
|
||||
if lower.contains("mandatory") {
|
||||
// Check if it's explicitly set to false
|
||||
if !lower.contains("mandatory=$false") && !lower.contains("mandatory = $false") {
|
||||
if !lower.contains("mandatory=$false")
|
||||
&& !lower.contains("mandatory = $false")
|
||||
{
|
||||
is_mandatory = true;
|
||||
}
|
||||
}
|
||||
@@ -471,7 +538,11 @@ fn parse_powershell_parameters(content: &str) -> anyhow::Result<Vec<Arg>> {
|
||||
// Check if this looks like a type (simple word, possibly with [])
|
||||
let is_type = !bracket_content.contains('(')
|
||||
&& !bracket_content.contains('=')
|
||||
&& (bracket_content.chars().next().unwrap_or(' ').is_alphabetic()
|
||||
&& (bracket_content
|
||||
.chars()
|
||||
.next()
|
||||
.unwrap_or(' ')
|
||||
.is_alphabetic()
|
||||
|| bracket_content.starts_with('['));
|
||||
|
||||
if is_type && !found_dollar {
|
||||
@@ -529,7 +600,9 @@ fn parse_powershell_parameters(content: &str) -> anyhow::Result<Vec<Arg>> {
|
||||
|
||||
while let Some((i, ch)) = chars.peek().copied() {
|
||||
if in_string {
|
||||
if ch == string_char && content.chars().nth(i.saturating_sub(1)) != Some('`') {
|
||||
if ch == string_char
|
||||
&& content.chars().nth(i.saturating_sub(1)) != Some('`')
|
||||
{
|
||||
in_string = false;
|
||||
default_end = i + 1;
|
||||
chars.next();
|
||||
@@ -544,7 +617,9 @@ fn parse_powershell_parameters(content: &str) -> anyhow::Result<Vec<Arg>> {
|
||||
chars.next();
|
||||
} else if ch == ',' {
|
||||
break;
|
||||
} else if ch.is_whitespace() && chars.clone().skip(1).next().map(|(_, c)| c) == Some(',') {
|
||||
} else if ch.is_whitespace()
|
||||
&& chars.clone().skip(1).next().map(|(_, c)| c) == Some(',')
|
||||
{
|
||||
break;
|
||||
} else {
|
||||
default_end = i + 1;
|
||||
@@ -552,12 +627,19 @@ fn parse_powershell_parameters(content: &str) -> anyhow::Result<Vec<Arg>> {
|
||||
}
|
||||
}
|
||||
|
||||
default_value = Some(content[default_start..default_end].trim().to_string());
|
||||
default_value =
|
||||
Some(content[default_start..default_end].trim().to_string());
|
||||
}
|
||||
',' => {
|
||||
// End of parameter, finalize it
|
||||
if let Some(name) = var_name.take() {
|
||||
args.push(finalize_parameter(name, type_annotation.take(), default_value.take(), is_mandatory, validate_set.take())?);
|
||||
args.push(finalize_parameter(
|
||||
name,
|
||||
type_annotation.take(),
|
||||
default_value.take(),
|
||||
is_mandatory,
|
||||
validate_set.take(),
|
||||
)?);
|
||||
}
|
||||
|
||||
// Reset for next parameter
|
||||
@@ -576,7 +658,13 @@ fn parse_powershell_parameters(content: &str) -> anyhow::Result<Vec<Arg>> {
|
||||
|
||||
// Finalize last parameter
|
||||
if let Some(name) = var_name {
|
||||
args.push(finalize_parameter(name, type_annotation, default_value, is_mandatory, validate_set)?);
|
||||
args.push(finalize_parameter(
|
||||
name,
|
||||
type_annotation,
|
||||
default_value,
|
||||
is_mandatory,
|
||||
validate_set,
|
||||
)?);
|
||||
}
|
||||
|
||||
Ok(args)
|
||||
@@ -722,7 +810,8 @@ non_required="${5:-}"
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -813,14 +902,19 @@ non_required="${5:-}"
|
||||
Arg {
|
||||
otyp: Some("string".to_string()), // [string] (last type bracket with Mandatory and ValidateSet)
|
||||
name: "Message".to_string(),
|
||||
typ: Typ::Str(Some(vec!["Green".to_string(), "Blue".to_string(), "Red".to_string()])), // ValidateSet enum
|
||||
typ: Typ::Str(Some(vec![
|
||||
"Green".to_string(),
|
||||
"Blue".to_string(),
|
||||
"Red".to_string()
|
||||
])), // ValidateSet enum
|
||||
default: None,
|
||||
has_default: false, // Required (Mandatory attribute)
|
||||
oidx: None
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
Ok(())
|
||||
@@ -970,19 +1064,13 @@ non_required="${5:-}"
|
||||
|
||||
// Valid: CmdletBinding with comments
|
||||
assert_eq!(
|
||||
extract_powershell_param_block(
|
||||
"# My function\n[CmdletBinding()]\nparam($Name)",
|
||||
false
|
||||
),
|
||||
extract_powershell_param_block("# My function\n[CmdletBinding()]\nparam($Name)", false),
|
||||
Some("$Name")
|
||||
);
|
||||
|
||||
// Valid: CmdletBinding with whitespace variations
|
||||
assert_eq!(
|
||||
extract_powershell_param_block(
|
||||
"[CmdletBinding()] \n param($Name)",
|
||||
false
|
||||
),
|
||||
extract_powershell_param_block("[CmdletBinding()] \n param($Name)", false),
|
||||
Some("$Name")
|
||||
);
|
||||
|
||||
@@ -1204,17 +1292,32 @@ param(
|
||||
// Test with CmdletBinding with parameters
|
||||
let code3 = "[CmdletBinding(DefaultParameterSetName='ByName')]\nparam($Name, $Id)";
|
||||
let result3 = extract_powershell_param_block_with_attributes(code3, true);
|
||||
assert_eq!(result3, Some(("[CmdletBinding(DefaultParameterSetName='ByName')]\nparam($Name, $Id)", "")));
|
||||
assert_eq!(
|
||||
result3,
|
||||
Some((
|
||||
"[CmdletBinding(DefaultParameterSetName='ByName')]\nparam($Name, $Id)",
|
||||
""
|
||||
))
|
||||
);
|
||||
|
||||
// Test with multiple attributes
|
||||
let code4 = "[CmdletBinding()]\n[OutputType([string])]\nparam($Value)";
|
||||
let result4 = extract_powershell_param_block_with_attributes(code4, true);
|
||||
assert_eq!(result4, Some(("[CmdletBinding()]\n[OutputType([string])]\nparam($Value)", "")));
|
||||
assert_eq!(
|
||||
result4,
|
||||
Some((
|
||||
"[CmdletBinding()]\n[OutputType([string])]\nparam($Value)",
|
||||
""
|
||||
))
|
||||
);
|
||||
|
||||
// Test with comment before attributes
|
||||
let code5 = "# My function\n[CmdletBinding()]\nparam($Name)";
|
||||
let result5 = extract_powershell_param_block_with_attributes(code5, true);
|
||||
assert_eq!(result5, Some(("# My function\n[CmdletBinding()]\nparam($Name)", "")));
|
||||
assert_eq!(
|
||||
result5,
|
||||
Some(("# My function\n[CmdletBinding()]\nparam($Name)", ""))
|
||||
);
|
||||
|
||||
// Test with include_attributes = false (should only get param block, not attributes)
|
||||
let code6 = "[CmdletBinding()]\nparam($Name)";
|
||||
@@ -1224,7 +1327,10 @@ param(
|
||||
// Test with code after param
|
||||
let code7 = "[CmdletBinding()]\nparam($Name)\nWrite-Host 'Hello'";
|
||||
let result7 = extract_powershell_param_block_with_attributes(code7, true);
|
||||
assert_eq!(result7, Some(("[CmdletBinding()]\nparam($Name)", "\nWrite-Host 'Hello'")));
|
||||
assert_eq!(
|
||||
result7,
|
||||
Some(("[CmdletBinding()]\nparam($Name)", "\nWrite-Host 'Hello'"))
|
||||
);
|
||||
|
||||
// Test with code after param (without attributes)
|
||||
let code8 = "[CmdletBinding()]\nparam($Name)\nWrite-Host 'Hello'";
|
||||
@@ -1392,10 +1498,85 @@ param(
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_detect_cmdlet_binding() {
|
||||
// Basic CmdletBinding
|
||||
let (has_cb, has_ssp) = detect_cmdlet_binding("[CmdletBinding()]\nparam($Name)");
|
||||
assert!(has_cb);
|
||||
assert!(!has_ssp);
|
||||
|
||||
// CmdletBinding with SupportsShouldProcess
|
||||
let (has_cb, has_ssp) =
|
||||
detect_cmdlet_binding("[CmdletBinding(SupportsShouldProcess=$true)]\nparam($Path)");
|
||||
assert!(has_cb);
|
||||
assert!(has_ssp);
|
||||
|
||||
// CmdletBinding with SupportsShouldProcess=false
|
||||
let (has_cb, has_ssp) =
|
||||
detect_cmdlet_binding("[CmdletBinding(SupportsShouldProcess=$false)]\nparam($Path)");
|
||||
assert!(has_cb);
|
||||
assert!(!has_ssp);
|
||||
|
||||
// No CmdletBinding
|
||||
let (has_cb, has_ssp) = detect_cmdlet_binding("param($Name)");
|
||||
assert!(!has_cb);
|
||||
assert!(!has_ssp);
|
||||
|
||||
// Case insensitive
|
||||
let (has_cb, has_ssp) =
|
||||
detect_cmdlet_binding("[cmdletbinding(supportsshouldprocess=$true)]\nparam($X)");
|
||||
assert!(has_cb);
|
||||
assert!(has_ssp);
|
||||
|
||||
// Commented out CmdletBinding should NOT be detected
|
||||
let (has_cb, has_ssp) =
|
||||
detect_cmdlet_binding("# [CmdletBinding(SupportsShouldProcess=$true)]\nparam($Path)");
|
||||
assert!(!has_cb);
|
||||
assert!(!has_ssp);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_powershell_common_param_filtering() -> anyhow::Result<()> {
|
||||
// Common parameters declared in param() should be filtered out
|
||||
let code = r#"[CmdletBinding()]
|
||||
param(
|
||||
[string]$Name,
|
||||
[switch]$Verbose,
|
||||
[string]$ErrorAction,
|
||||
[int]$Age
|
||||
)"#;
|
||||
let sig = parse_powershell_sig(code)?;
|
||||
assert_eq!(sig.args.len(), 2);
|
||||
assert_eq!(sig.args[0].name, "Name");
|
||||
assert_eq!(sig.args[1].name, "Age");
|
||||
assert_eq!(sig.has_cmd_binding, Some(true));
|
||||
assert_eq!(sig.supports_should_process, None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_powershell_sig_cmdlet_binding_metadata() -> anyhow::Result<()> {
|
||||
// Script without CmdletBinding
|
||||
let code = "param([string]$Name)";
|
||||
let sig = parse_powershell_sig(code)?;
|
||||
assert_eq!(sig.has_cmd_binding, None);
|
||||
assert_eq!(sig.supports_should_process, None);
|
||||
|
||||
// Script with CmdletBinding + SupportsShouldProcess
|
||||
let code = "[CmdletBinding(SupportsShouldProcess=$true)]\nparam([string]$Path)";
|
||||
let sig = parse_powershell_sig(code)?;
|
||||
assert_eq!(sig.has_cmd_binding, Some(true));
|
||||
assert_eq!(sig.supports_should_process, Some(true));
|
||||
assert_eq!(sig.args.len(), 1);
|
||||
assert_eq!(sig.args[0].name, "Path");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ pub fn parse_csharp_sig_meta(code: &str) -> anyhow::Result<CsharpMainSigMeta> {
|
||||
args,
|
||||
has_preprocessor: None,
|
||||
auto_kind,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Ok(CsharpMainSigMeta { is_async, returns_void, class_name, main_sig, is_public })
|
||||
|
||||
@@ -43,6 +43,7 @@ pub fn parse_go_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Ok(MainArgSignature {
|
||||
@@ -51,6 +52,7 @@ pub fn parse_go_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args: vec![],
|
||||
auto_kind: Some("lib".to_string()),
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -244,7 +246,8 @@ func main(x int, y string, z bool, l []string, o struct { Name string `json:"nam
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ pub fn parse_graphql_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing sql".to_string()))
|
||||
@@ -126,7 +127,8 @@ query($i: Int, $arr: [String]!, $wahoo: String = "wahoo") {
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -81,6 +81,7 @@ pub fn parse_java_sig_meta(code: &str) -> anyhow::Result<JavaMainSigMeta> {
|
||||
args,
|
||||
has_preprocessor: None,
|
||||
auto_kind,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Ok(JavaMainSigMeta { returns_void, class_name, main_sig, is_public })
|
||||
|
||||
@@ -56,6 +56,7 @@ mod test {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -83,6 +84,7 @@ mod test {
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -120,6 +122,7 @@ mod test {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -232,6 +235,7 @@ mod test {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -279,6 +283,7 @@ mod test {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -343,6 +348,7 @@ mod test {
|
||||
// },],
|
||||
// auto_kind: None,
|
||||
// has_preprocessor: None,
|
||||
// ..Default::default()
|
||||
// },
|
||||
// sig
|
||||
// );
|
||||
@@ -373,6 +379,7 @@ mod test {
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -420,6 +427,7 @@ mod test {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -448,6 +456,7 @@ mod test {
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -480,6 +489,7 @@ mod test {
|
||||
// },],
|
||||
// auto_kind: None,
|
||||
// has_preprocessor: None,
|
||||
// ..Default::default()
|
||||
// },
|
||||
// sig
|
||||
// );
|
||||
@@ -542,6 +552,7 @@ mod test {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
sig
|
||||
);
|
||||
@@ -635,6 +646,7 @@ mod test {
|
||||
// ],
|
||||
// auto_kind: None,
|
||||
// has_preprocessor: None,
|
||||
// ..Default::default()
|
||||
// },
|
||||
// sig
|
||||
// );
|
||||
|
||||
@@ -101,6 +101,7 @@ pub fn parse_php_signature(
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Ok(MainArgSignature {
|
||||
@@ -109,6 +110,7 @@ pub fn parse_php_signature(
|
||||
args: vec![],
|
||||
auto_kind: Some("lib".to_string()),
|
||||
has_preprocessor,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -180,7 +182,8 @@ function main(string $input1 = \"hey\", bool $input2 = false, int $input3 = 3, f
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -366,6 +366,7 @@ pub fn parse_python_signature(
|
||||
Some("lib".to_string())
|
||||
},
|
||||
has_preprocessor: Some(has_preprocessor),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
@@ -477,6 +478,7 @@ pub fn parse_python_signature(
|
||||
.collect(),
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(has_preprocessor),
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Ok(MainArgSignature {
|
||||
@@ -489,6 +491,7 @@ pub fn parse_python_signature(
|
||||
None
|
||||
},
|
||||
has_preprocessor: Some(has_preprocessor),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -755,7 +758,8 @@ def main(test1: str, name: datetime.datetime = datetime.now(), byte: bytes = byt
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -820,7 +824,8 @@ def main(test1: str,
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -880,7 +885,8 @@ def main(test1: str,
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -924,7 +930,8 @@ def main(test1: Literal["foo", "bar"], test2: List[Literal["foo", "bar"]]): retu
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -955,7 +962,8 @@ def main(test1: DynSelect_foo): return
|
||||
oidx: None
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -979,7 +987,8 @@ def hello(): return
|
||||
star_kwargs: false,
|
||||
args: vec![],
|
||||
auto_kind: Some("lib".to_string()),
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1007,7 +1016,8 @@ def main(): return
|
||||
star_kwargs: false,
|
||||
args: vec![],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(true)
|
||||
has_preprocessor: Some(true),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1072,7 +1082,8 @@ def main(a: list, e: List[int], b: list = [1,2,3,4], c = [1,2,3,4], d = ["a", "b
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1121,7 +1132,8 @@ def main(a: str, b: Optional[str], c: str | None): return
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ pub fn parse_r_sig_meta(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args: args.unwrap_or_default(),
|
||||
has_preprocessor: None,
|
||||
auto_kind: None,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Ok(main_sig)
|
||||
|
||||
@@ -41,6 +41,7 @@ pub fn parse_ruby_sig_meta(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args: args.unwrap_or_default(),
|
||||
has_preprocessor: None,
|
||||
auto_kind,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
Ok(main_sig)
|
||||
|
||||
@@ -30,6 +30,7 @@ pub fn parse_rust_signature(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Ok(MainArgSignature {
|
||||
@@ -38,6 +39,7 @@ pub fn parse_rust_signature(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args: vec![],
|
||||
auto_kind: Some("lib".to_string()),
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ pub fn parse_mysql_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing sql".to_string()))
|
||||
@@ -46,6 +47,7 @@ pub fn parse_oracledb_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing sql".to_string()))
|
||||
@@ -67,6 +69,7 @@ pub fn parse_pgsql_sig_with_typed_schema(code: &str) -> anyhow::Result<(MainArgS
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
},
|
||||
typed_schema,
|
||||
))
|
||||
@@ -85,6 +88,7 @@ pub fn parse_bigquery_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing sql".to_string()))
|
||||
@@ -100,6 +104,7 @@ pub fn parse_duckdb_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing sql".to_string()))
|
||||
@@ -116,6 +121,7 @@ pub fn parse_snowflake_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing sql".to_string()))
|
||||
@@ -132,6 +138,7 @@ pub fn parse_mssql_sig(code: &str) -> anyhow::Result<MainArgSignature> {
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("Error parsing sql".to_string()))
|
||||
@@ -944,7 +951,8 @@ SELECT * FROM table WHERE token=$1::TEXT AND image=$2::BIGINT
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -993,7 +1001,8 @@ SELECT $2::TEXT;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1120,7 +1129,8 @@ SELECT ?, ?;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1168,7 +1178,8 @@ SELECT :param2;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1208,7 +1219,8 @@ SELECT @token;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1256,7 +1268,8 @@ SELECT ?;
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1304,7 +1317,8 @@ SELECT @P2;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1353,7 +1367,8 @@ SELECT * FROM table_name WHERE thing = :name4;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1391,7 +1406,8 @@ SELECT * FROM users WHERE id = $1 AND email = $2::text;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1429,7 +1445,8 @@ SELECT * FROM users LIMIT $1 OFFSET $2;
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1479,7 +1496,8 @@ WHERE id = $1
|
||||
},
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1506,7 +1524,8 @@ SELECT * FROM users WHERE id = ANY($1);
|
||||
oidx: Some(1),
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1535,7 +1554,8 @@ SELECT $1::integer;
|
||||
oidx: Some(1),
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1567,7 +1587,8 @@ SELECT x
|
||||
oidx: None,
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -462,6 +462,7 @@ pub fn parse_deno_signature(
|
||||
},
|
||||
auto_kind,
|
||||
has_preprocessor: Some(has_preprocessor),
|
||||
..Default::default()
|
||||
};
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ mod tests {
|
||||
args: vec![],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -105,6 +106,7 @@ mod tests {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -154,6 +156,7 @@ mod tests {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -203,6 +206,7 @@ mod tests {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -234,6 +238,7 @@ mod tests {
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -265,6 +270,7 @@ mod tests {
|
||||
},],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -305,6 +311,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -343,6 +350,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -401,6 +409,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -459,6 +468,7 @@ mod tests {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -508,6 +518,7 @@ mod tests {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -557,6 +568,7 @@ mod tests {
|
||||
args: vec![],
|
||||
auto_kind: Some("lib".to_string()),
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -584,6 +596,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -613,6 +626,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -642,6 +656,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -691,6 +706,7 @@ mod tests {
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -731,6 +747,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(true),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -761,6 +778,7 @@ mod tests {
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(true),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -141,7 +141,8 @@ export function main(test1?: string, test2: string = \"burkina\",
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -220,7 +221,8 @@ export function main(test2 = \"burkina\",
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -271,7 +273,8 @@ export function main(foo: FooBar, {a, b}: FooBar, {c, d}: FooBar = {a: \"foo\",
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -303,7 +306,8 @@ export function main(foo: (\"foo\" | \"bar\")[]) {
|
||||
oidx: None
|
||||
}],
|
||||
auto_kind: None,
|
||||
has_preprocessor: Some(false)
|
||||
has_preprocessor: Some(false),
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
@@ -447,7 +451,8 @@ Write-Output 'Testing...'
|
||||
}
|
||||
],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ pub fn parse_ansible_sig(inner_content: &str) -> anyhow::Result<MainArgSignature
|
||||
args: vec![],
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
|
||||
@@ -94,6 +95,7 @@ pub fn parse_ansible_sig(inner_content: &str) -> anyhow::Result<MainArgSignature
|
||||
args,
|
||||
auto_kind: None,
|
||||
has_preprocessor: None,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@ pub struct MainArgSignature {
|
||||
pub args: Vec<Arg>,
|
||||
pub auto_kind: Option<String>,
|
||||
pub has_preprocessor: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub has_cmd_binding: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub supports_should_process: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone, Debug, PartialEq)]
|
||||
|
||||
@@ -337,7 +337,7 @@ pub async fn handle_powershell_job(
|
||||
envs: HashMap<String, String>,
|
||||
occupancy_metrics: &mut OccupancyMetrics,
|
||||
) -> Result<Box<RawValue>, Error> {
|
||||
let pwsh_args = {
|
||||
let (pwsh_args, ps_preferences) = {
|
||||
let args = build_args_map(job, client, &db).await?.map(Json);
|
||||
let job_args = if args.is_some() {
|
||||
args.as_ref()
|
||||
@@ -347,7 +347,7 @@ pub async fn handle_powershell_job(
|
||||
|
||||
let parsed_sig = windmill_parser_bash::parse_powershell_sig(&content)?;
|
||||
|
||||
parsed_sig
|
||||
let user_args = parsed_sig
|
||||
.args
|
||||
.iter()
|
||||
.filter_map(|arg| {
|
||||
@@ -384,7 +384,34 @@ pub async fn handle_powershell_job(
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")
|
||||
.join(" ");
|
||||
|
||||
// Extract PowerShell common parameters (_wm_ps_* keys)
|
||||
// All common params are injected as preference variables into main.ps1
|
||||
// (not CLI args) so they only affect user code, not module loading.
|
||||
let mut preference_lines: Vec<String> = Vec::new();
|
||||
if let Some(args_map) = job_args {
|
||||
if let Some(v) = args_map.get("_wm_ps_verbose") {
|
||||
if serde_json::from_str::<bool>(v.get()).unwrap_or(false) {
|
||||
preference_lines.push("$VerbosePreference = 'Continue'".to_string());
|
||||
}
|
||||
}
|
||||
if let Some(v) = args_map.get("_wm_ps_debug") {
|
||||
if serde_json::from_str::<bool>(v.get()).unwrap_or(false) {
|
||||
preference_lines.push("$DebugPreference = 'Continue'".to_string());
|
||||
}
|
||||
}
|
||||
if let Some(v) = args_map.get("_wm_ps_error_action") {
|
||||
if let Ok(action) = serde_json::from_str::<String>(v.get()) {
|
||||
if matches!(action.as_str(), "Stop" | "Continue" | "SilentlyContinue") {
|
||||
preference_lines.push(format!("$ErrorActionPreference = '{action}'"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let ps_preferences = preference_lines.join("\n");
|
||||
|
||||
(user_args, ps_preferences)
|
||||
};
|
||||
|
||||
// Resolve modules from workspace dependencies and/or script imports
|
||||
@@ -570,12 +597,22 @@ $env:PSModulePath = \"{};$PSModulePathBackup\"",
|
||||
}\n";
|
||||
|
||||
// make sure param() with its attributes is first
|
||||
let preferences_section = if ps_preferences.is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
format!("{}\n", ps_preferences)
|
||||
};
|
||||
let content: String = if let Some((param_block, remaining_code)) =
|
||||
windmill_parser_bash::extract_powershell_param_block_with_attributes(&content, true)
|
||||
{
|
||||
format!(
|
||||
"{}\n{}\n{}\n{}\n{}",
|
||||
param_block, profile, strict_termination_start, remaining_code, strict_termination_end
|
||||
"{}\n{}\n{}\n{}{}\n{}",
|
||||
param_block,
|
||||
profile,
|
||||
strict_termination_start,
|
||||
preferences_section,
|
||||
remaining_code,
|
||||
strict_termination_end
|
||||
)
|
||||
} else {
|
||||
format!("{}\n{}", profile, content)
|
||||
@@ -583,18 +620,29 @@ $env:PSModulePath = \"{};$PSModulePathBackup\"",
|
||||
|
||||
write_file(job_dir, "main.ps1", content.as_str())?;
|
||||
|
||||
write_file(
|
||||
job_dir,
|
||||
"wrapper.ps1",
|
||||
&format!(
|
||||
let has_common_params = !ps_preferences.is_empty();
|
||||
let wrapper_content = if has_common_params {
|
||||
format!(
|
||||
"$ErrorActionPreference = 'Stop'\n\
|
||||
$pipe = New-TemporaryFile\n\
|
||||
./main.ps1 {pwsh_args} 4>verbose.log 5>debug.log 2>&1 | Tee-Object -FilePath $pipe\n\
|
||||
Get-Content -Path $pipe | Select-Object -Last 1 | Set-Content -Path './result2.out'\n\
|
||||
if (Test-Path verbose.log) {{ Get-Content verbose.log | ForEach-Object {{ Write-Output \"VERBOSE: $_\" }} }}\n\
|
||||
if (Test-Path debug.log) {{ Get-Content debug.log | ForEach-Object {{ Write-Output \"DEBUG: $_\" }} }}\n\
|
||||
Remove-Item $pipe\n\
|
||||
exit $LASTEXITCODE\n"
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"$ErrorActionPreference = 'Stop'\n\
|
||||
$pipe = New-TemporaryFile\n\
|
||||
./main.ps1 {pwsh_args} 2>&1 | Tee-Object -FilePath $pipe\n\
|
||||
Get-Content -Path $pipe | Select-Object -Last 1 | Set-Content -Path './result2.out'\n\
|
||||
Remove-Item $pipe\n\
|
||||
exit $LASTEXITCODE\n"
|
||||
),
|
||||
)?;
|
||||
)
|
||||
};
|
||||
write_file(job_dir, "wrapper.ps1", &wrapper_content)?;
|
||||
|
||||
let mut reserved_variables =
|
||||
get_reserved_variables(job, &client.token, db, parent_runnable_path).await?;
|
||||
|
||||
Generated
+6
-52
@@ -84,7 +84,7 @@
|
||||
"windmill-parser-wasm-php": "1.647.1",
|
||||
"windmill-parser-wasm-py": "1.657.2",
|
||||
"windmill-parser-wasm-r": "1.668.1",
|
||||
"windmill-parser-wasm-regex": "1.653.0",
|
||||
"windmill-parser-wasm-regex": "^1.670.0",
|
||||
"windmill-parser-wasm-ruby": "1.526.1",
|
||||
"windmill-parser-wasm-rust": "1.647.1",
|
||||
"windmill-parser-wasm-ts": "1.657.2",
|
||||
@@ -844,7 +844,6 @@
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.0.tgz",
|
||||
"integrity": "sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -856,7 +855,6 @@
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.0.tgz",
|
||||
"integrity": "sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -867,7 +865,6 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz",
|
||||
"integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -1357,7 +1354,6 @@
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz",
|
||||
"integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -1514,7 +1510,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1531,7 +1526,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1548,7 +1542,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1565,7 +1558,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1582,7 +1574,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1599,7 +1590,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1616,7 +1606,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1633,7 +1622,6 @@
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1650,7 +1638,6 @@
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1667,7 +1654,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1684,7 +1670,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1701,7 +1686,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1718,7 +1702,6 @@
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -1735,7 +1718,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -1752,7 +1734,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2058,7 +2039,6 @@
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
|
||||
"integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -6867,7 +6847,7 @@
|
||||
"version": "1.21.7",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
|
||||
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"jiti": "bin/jiti.js"
|
||||
@@ -7366,7 +7346,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -7387,7 +7366,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -7408,7 +7386,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -7429,7 +7406,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -7450,7 +7426,6 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -7471,7 +7446,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -7492,7 +7466,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -7513,7 +7486,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -7534,7 +7506,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -7555,7 +7526,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -7576,7 +7546,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -12152,21 +12121,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-check/node_modules/picomatch": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
|
||||
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-eslint-parser": {
|
||||
"version": "0.43.0",
|
||||
"resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.43.0.tgz",
|
||||
@@ -12897,7 +12851,7 @@
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
@@ -13692,9 +13646,9 @@
|
||||
"integrity": "sha512-5YNeUibxpNBvYrxCgQcz1PxGhTFx2CyEpg2udtIhq7bx0d4gF/KDZVupMeQmAObmrEtTSFGUWNRJ4zXSWNrSpQ=="
|
||||
},
|
||||
"node_modules/windmill-parser-wasm-regex": {
|
||||
"version": "1.653.0",
|
||||
"resolved": "https://registry.npmjs.org/windmill-parser-wasm-regex/-/windmill-parser-wasm-regex-1.653.0.tgz",
|
||||
"integrity": "sha512-LEvLhb8uCb/jGMzd+lwP886LcwxuTE+W04wdyqmdqy1JD9FBToKeiqW7CtZWqbWr1oI8yK9U3jmqSqyOcUCzRw=="
|
||||
"version": "1.670.0",
|
||||
"resolved": "https://registry.npmjs.org/windmill-parser-wasm-regex/-/windmill-parser-wasm-regex-1.670.0.tgz",
|
||||
"integrity": "sha512-foQBwLn7L3JpmPSzMYmFhpVvUnXB1KX4v1rGBsm5W6KircwrjW3VXl/Ih9Izjyju2RRK+tYzjN8vvd2Zo7ulKQ=="
|
||||
},
|
||||
"node_modules/windmill-parser-wasm-ruby": {
|
||||
"version": "1.526.1",
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
"windmill-parser-wasm-php": "1.647.1",
|
||||
"windmill-parser-wasm-py": "1.657.2",
|
||||
"windmill-parser-wasm-r": "1.668.1",
|
||||
"windmill-parser-wasm-regex": "1.653.0",
|
||||
"windmill-parser-wasm-regex": "^1.670.0",
|
||||
"windmill-parser-wasm-ruby": "1.526.1",
|
||||
"windmill-parser-wasm-rust": "1.647.1",
|
||||
"windmill-parser-wasm-ts": "1.657.2",
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<script lang="ts">
|
||||
import { Badge } from './common'
|
||||
import Toggle from './Toggle.svelte'
|
||||
import Select from '$lib/components/select/Select.svelte'
|
||||
import { untrack } from 'svelte'
|
||||
import { ChevronRight } from 'lucide-svelte'
|
||||
|
||||
interface Props {
|
||||
args?: Record<string, any>
|
||||
}
|
||||
|
||||
let { args = $bindable({}) }: Props = $props()
|
||||
|
||||
let verbose = $state(false)
|
||||
let debug = $state(false)
|
||||
let errorAction = $state(undefined as string | undefined)
|
||||
let collapsed = $state(true)
|
||||
let initialized = false
|
||||
|
||||
const errorActionItems = [
|
||||
{ label: 'Stop', value: 'Stop' },
|
||||
{ label: 'Continue', value: 'Continue' },
|
||||
{ label: 'SilentlyContinue', value: 'SilentlyContinue' }
|
||||
]
|
||||
|
||||
let activeBadges = $derived.by(() => {
|
||||
const badges: string[] = []
|
||||
if (verbose) badges.push('Verbose')
|
||||
if (debug) badges.push('Debug')
|
||||
if (errorAction) badges.push(`ErrorAction: ${errorAction}`)
|
||||
return badges
|
||||
})
|
||||
|
||||
// Initialize toggles from pre-populated args (e.g. "Run again")
|
||||
$effect(() => {
|
||||
if (!initialized && args && Object.keys(args).length > 0) {
|
||||
initialized = true
|
||||
untrack(() => {
|
||||
verbose = args['_wm_ps_verbose'] === true
|
||||
debug = args['_wm_ps_debug'] === true
|
||||
errorAction = args['_wm_ps_error_action'] ?? undefined
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// Sync toggles → args
|
||||
$effect(() => {
|
||||
const newArgs: Record<string, any> = {}
|
||||
if (verbose) newArgs['_wm_ps_verbose'] = true
|
||||
if (debug) newArgs['_wm_ps_debug'] = true
|
||||
if (errorAction) newArgs['_wm_ps_error_action'] = errorAction
|
||||
args = newArgs
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<button
|
||||
class="flex items-center gap-1 text-xs text-secondary hover:text-primary transition-colors"
|
||||
onclick={() => (collapsed = !collapsed)}
|
||||
>
|
||||
<ChevronRight size={12} class="transition duration-200 {collapsed ? '' : 'rotate-90'}" />
|
||||
CmdletBinding parameters
|
||||
{#if collapsed && activeBadges.length > 0}
|
||||
<div class="flex gap-1 ml-1">
|
||||
{#each activeBadges as label}
|
||||
<Badge color="blue">{label}</Badge>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</button>
|
||||
{#if !collapsed}
|
||||
<div class="flex flex-col gap-2 mt-2 ml-4">
|
||||
<Toggle options={{ right: 'Verbose' }} bind:checked={verbose} size="xs" />
|
||||
<Toggle options={{ right: 'Debug' }} bind:checked={debug} size="xs" />
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-xs text-secondary">ErrorAction</span>
|
||||
<div class="w-40">
|
||||
<Select
|
||||
items={errorActionItems}
|
||||
bind:value={errorAction}
|
||||
placeholder="Default"
|
||||
clearable
|
||||
size="sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -23,15 +23,35 @@
|
||||
import InputSelectedBadge from './schema/InputSelectedBadge.svelte'
|
||||
import { untrack } from 'svelte'
|
||||
import { processSecretArgs } from './secretArgUtils'
|
||||
import PowerShellCommonParams from './PowerShellCommonParams.svelte'
|
||||
|
||||
let reloadArgs = $state(0)
|
||||
let jsonEditor: JsonInputs | undefined = $state(undefined)
|
||||
let schemaHeight = $state(0)
|
||||
let showInputSelectedBadge = $state(false)
|
||||
let savedPreviousArgs: Record<string, any> | undefined = $state(undefined)
|
||||
let psCommonParams: Record<string, any> = $state({})
|
||||
|
||||
function extractPsCommonParams(allArgs: Record<string, any>): {
|
||||
scriptArgs: Record<string, any>
|
||||
commonParams: Record<string, any>
|
||||
} {
|
||||
const scriptArgs: Record<string, any> = {}
|
||||
const commonParams: Record<string, any> = {}
|
||||
for (const [k, v] of Object.entries(allArgs)) {
|
||||
if (k.startsWith('_wm_ps_')) {
|
||||
commonParams[k] = v
|
||||
} else {
|
||||
scriptArgs[k] = v
|
||||
}
|
||||
}
|
||||
return { scriptArgs, commonParams }
|
||||
}
|
||||
|
||||
export async function setArgs(nargs: Record<string, any>) {
|
||||
args = nargs
|
||||
const { scriptArgs, commonParams } = extractPsCommonParams(nargs)
|
||||
args = scriptArgs
|
||||
psCommonParams = commonParams
|
||||
reloadArgs++
|
||||
}
|
||||
|
||||
@@ -46,6 +66,13 @@
|
||||
sendUserToast('Failed to process sensitive args: ' + e, true)
|
||||
return
|
||||
}
|
||||
if (showPsCommonParams) {
|
||||
for (const [k, v] of Object.entries(psCommonParams)) {
|
||||
if (v !== undefined && v !== false && v !== '') {
|
||||
processedArgs[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
runAction(
|
||||
overrideScheduledForStr === null ? undefined : (overrideScheduledForStr ?? scheduledForStr),
|
||||
processedArgs,
|
||||
@@ -64,6 +91,7 @@
|
||||
is_template?: boolean
|
||||
hash?: string
|
||||
kind?: string
|
||||
language?: string
|
||||
can_write?: boolean
|
||||
created_at?: string
|
||||
created_by?: string
|
||||
@@ -109,10 +137,20 @@
|
||||
isValid = $bindable(true)
|
||||
}: Props = $props()
|
||||
|
||||
let showPsCommonParams = $derived(
|
||||
runnable?.language === 'powershell' && runnable?.schema?.['x-windmill-ps-cmd-binding'] === true
|
||||
)
|
||||
|
||||
$effect.pre(() => {
|
||||
if (args == undefined) {
|
||||
args = {}
|
||||
}
|
||||
// Extract _wm_ps_* keys from args on initial load (e.g. "Run again" via URL hash)
|
||||
if (args && Object.keys(args).some((k) => k.startsWith('_wm_ps_'))) {
|
||||
const { scriptArgs, commonParams } = extractPsCommonParams(args)
|
||||
args = scriptArgs
|
||||
psCommonParams = commonParams
|
||||
}
|
||||
})
|
||||
|
||||
let debounced: number | undefined = undefined
|
||||
@@ -307,6 +345,11 @@
|
||||
{:else}
|
||||
<div class="text-xs text-primary">No arguments</div>
|
||||
{/if}
|
||||
{#if showPsCommonParams}
|
||||
<div class="mt-4">
|
||||
<PowerShellCommonParams bind:args={psCommonParams} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if schedulable}
|
||||
<div class="flex gap-2 items-start flex-wrap justify-between mt-2 md:mt-6">
|
||||
<div class="flex-row-reverse flex-wrap flex w-full gap-4">
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
import WacDiagram from '$lib/components/graph/WacDiagram.svelte'
|
||||
import { Pane, Splitpanes } from 'svelte-splitpanes'
|
||||
import SchemaForm from './SchemaForm.svelte'
|
||||
import PowerShellCommonParams from './PowerShellCommonParams.svelte'
|
||||
import LogPanel from './scriptEditor/LogPanel.svelte'
|
||||
import EditorBar, { EDITOR_BAR_WIDTH_THRESHOLD } from './EditorBar.svelte'
|
||||
import JobLoader from './JobLoader.svelte'
|
||||
@@ -188,6 +189,8 @@
|
||||
let initialArgs = structuredClone($state.snapshot(args))
|
||||
let jsonView = $state(false)
|
||||
let schemaHeight = $state(0)
|
||||
let psCommonParams: Record<string, any> = $state({})
|
||||
let showPsCommonParams = $derived(lang === 'powershell' && /^\s*\[CmdletBinding/im.test(code))
|
||||
|
||||
// Module tab state
|
||||
let activeModuleTab: string | null = $state(null)
|
||||
@@ -654,6 +657,13 @@
|
||||
: (args ?? {})
|
||||
const testSchema = activeModuleTab !== null ? testPanelSchema : schema
|
||||
const testArgs = await processSecretArgs(rawTestArgs, testSchema)
|
||||
if (showPsCommonParams) {
|
||||
for (const [k, v] of Object.entries(psCommonParams)) {
|
||||
if (v !== undefined && v !== false && v !== '') {
|
||||
testArgs[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
let job = await jobLoader.runPreview(
|
||||
@@ -1616,6 +1626,13 @@
|
||||
/>
|
||||
{/if}
|
||||
{/key}
|
||||
{#if showPsCommonParams}
|
||||
<div class="mt-2">
|
||||
<PowerShellCommonParams
|
||||
bind:args={psCommonParams}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -467,6 +467,20 @@ export async function inferArgs(
|
||||
schema.required.push(arg.name)
|
||||
}
|
||||
}
|
||||
// Store PowerShell CmdletBinding metadata as schema extensions
|
||||
const psSchema = inferedSchema as MainArgSignature & {
|
||||
has_cmd_binding?: boolean
|
||||
supports_should_process?: boolean
|
||||
}
|
||||
if (language === 'powershell' && psSchema.has_cmd_binding) {
|
||||
;(schema as any)['x-windmill-ps-cmd-binding'] = true
|
||||
;(schema as any)['x-windmill-ps-supports-should-process'] =
|
||||
psSchema.supports_should_process ?? false
|
||||
} else {
|
||||
delete (schema as any)['x-windmill-ps-cmd-binding']
|
||||
delete (schema as any)['x-windmill-ps-supports-should-process']
|
||||
}
|
||||
|
||||
await tick()
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user