Skip to content

Commit 6c1a2d9

Browse files
authored
[#893] fix: Multi-line Python script result in error (#894)
1 parent 5ab3a06 commit 6c1a2d9

File tree

4 files changed

+48
-15
lines changed

4 files changed

+48
-15
lines changed

README.md

+10-5
Original file line numberDiff line numberDiff line change
@@ -368,22 +368,27 @@ You can define positional parameters in the DAG file and override them when runn
368368

369369
```yaml
370370
# Default positional parameters
371-
params: input.csv output.csv 60 # Default values for $1, $2, and $3
371+
params: input.csv output.csv 60 # Default values for $1, $2, and $3
372372

373373
steps:
374374
# Using positional parameters
375-
- name: data processing
376-
command: python
375+
- name: Installation
376+
command: pipx install pandas --include-deps
377+
378+
- name: Data processing
379+
command: pipx run
377380
script: |
378381
import sys
379382
import pandas as pd
380-
383+
381384
input_file = "$1" # First parameter
382385
output_file = "$2" # Second parameter
383386
timeout = "$3" # Third parameter
384-
387+
385388
print(f"Processing {input_file} -> {output_file} with timeout {timeout}s")
386389
# Add your processing logic here
390+
depends:
391+
- Installation
387392
```
388393
389394
Run the DAG with custom parameters:

internal/digraph/executor/command.go

+23-10
Original file line numberDiff line numberDiff line change
@@ -108,26 +108,27 @@ func (cfg *commandConfig) newCmd(ctx context.Context, scriptFile string) (*exec.
108108

109109
var cmd *exec.Cmd
110110
switch {
111+
case cfg.Command != "" && scriptFile != "":
112+
args, err := cfg.evalArgs()
113+
if err != nil {
114+
return nil, fmt.Errorf("failed to evaluate command args: %w", err)
115+
}
116+
cmd = exec.CommandContext(cfg.Ctx, cfg.Command, append(args, scriptFile)...) // nolint: gosec
117+
111118
case cfg.ShellCommand != "" && scriptFile != "":
112119
// If script is provided ignore the shell command args
113120

114-
// nolint: gosec
115-
cmd = exec.CommandContext(cfg.Ctx, cfg.ShellCommand, scriptFile)
121+
cmd = exec.CommandContext(cfg.Ctx, cfg.ShellCommand, scriptFile) // nolint: gosec
116122

117123
case cfg.ShellCommand != "" && cfg.ShellCommandArgs != "":
118124
// nolint: gosec
119125
cmd = exec.CommandContext(cfg.Ctx, cfg.ShellCommand, "-c", cfg.ShellCommandArgs)
120126

121127
default:
122-
args := make([]string, len(cfg.Args))
123-
for i, arg := range cfg.Args {
124-
arg, err := cmdutil.EvalString(cfg.Ctx, arg)
125-
if err != nil {
126-
return nil, fmt.Errorf("failed to evaluate command args: %w", err)
127-
}
128-
args[i] = arg
128+
args, err := cfg.evalArgs()
129+
if err != nil {
130+
return nil, fmt.Errorf("failed to evaluate command args: %w", err)
129131
}
130-
131132
cmd = createDirectCommand(cfg.Ctx, cfg.Command, args, scriptFile)
132133

133134
}
@@ -144,6 +145,18 @@ func (cfg *commandConfig) newCmd(ctx context.Context, scriptFile string) (*exec.
144145
return cmd, nil
145146
}
146147

148+
func (cfg *commandConfig) evalArgs() ([]string, error) {
149+
args := make([]string, len(cfg.Args))
150+
for i, arg := range cfg.Args {
151+
arg, err := cmdutil.EvalString(cfg.Ctx, arg)
152+
if err != nil {
153+
return nil, fmt.Errorf("failed to evaluate command args: %w", err)
154+
}
155+
args[i] = arg
156+
}
157+
return args, nil
158+
}
159+
147160
func init() {
148161
Register("", newCommand)
149162
Register("command", newCommand)

internal/integration/dag_test.go

+7
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ func TestDAGExecution(t *testing.T) {
143143
"OUT1": "Starting server at localhost:8080",
144144
},
145145
},
146+
{
147+
name: "Script",
148+
dag: "perl-script.yaml",
149+
expectedOutputs: map[string]any{
150+
"OUT1": "Hello World",
151+
},
152+
},
146153
{
147154
name: "Issue-810",
148155
dag: "issue-810.yaml",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
steps:
2+
- name: step1
3+
command: perl
4+
script: |
5+
use strict;
6+
use warnings;
7+
print("Hello World\n");
8+
output: OUT1

0 commit comments

Comments
 (0)