Skip to content

Commit 9d6dc41

Browse files
committed
feat(workflow): add support for multiline commands in "run" key
Before, it was not possible to create a workflow steps like: - name: do_multiple_things run: | cd /some/long/path; \ echo "hello world" > hello.txt; \ cat hello.txt - name: have_many_arguments run: | ./run_something.sh \ --arg1 value1 \ --arg2 value2 \ --arg2 value3 This could end up forcing users to either have very long lines in the workflow, if many arguments had to be given to a tool, *or* have a `cd` prefix for every command in a list of commands if they all had to be executed in a specific directory. This commit adds multiline support, which follows the syntax of shell scripts where a backslash (\) continues the command onto the next line. Signed-off-by: Nadja Brix Koch <n.koch@samsung.com>
1 parent fbb83ef commit 9d6dc41

2 files changed

Lines changed: 91 additions & 1 deletion

File tree

src/cijoe/core/resources.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,16 @@ def dict_normalize(topic: dict):
380380
)
381381
return errors
382382

383-
step["with"]["commands"] = step["run"].splitlines()
383+
# non-empty lines in "run"
384+
lines = filter(None, map(lambda l: l.strip(), step["run"].splitlines()))
385+
step["with"]["commands"] = []
386+
buffer = []
387+
388+
for line in lines:
389+
buffer.append(line)
390+
if not line.strip().endswith("\\"):
391+
step["with"]["commands"].append("\n".join(buffer))
392+
buffer = []
384393

385394
del step["run"]
386395

tests/core/test_workflow.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,84 @@ def test_workflow_report_command_ordering(tmp_path):
118118
):
119119
val = int(Path(key).stem.split("_")[1])
120120
assert count == val
121+
122+
123+
def test_workflow_run(tmp_path):
124+
config_path = (tmp_path / "test-config-empty.toml").resolve()
125+
config_path.write_text("")
126+
127+
data = copy.deepcopy(WORKFLOW_SKELETON)
128+
data["steps"].append(
129+
{
130+
"name": "cmdrunner",
131+
"run": """
132+
echo hello
133+
echo world
134+
""",
135+
}
136+
)
137+
138+
output_path = (tmp_path / "output").resolve()
139+
workflow_file = (tmp_path / "workflow.yaml").resolve()
140+
workflow_file.write_text(yaml.dump(data))
141+
142+
result = subprocess.run(
143+
[
144+
"cijoe",
145+
str(workflow_file),
146+
"--output",
147+
str(output_path),
148+
"--config",
149+
str(config_path),
150+
],
151+
cwd=str(tmp_path),
152+
)
153+
assert result.returncode == 0
154+
155+
runlog = runlog_from_path(output_path / "002_cmdrunner")
156+
157+
assert len(runlog) == 2
158+
159+
for i, v in enumerate(runlog.values()):
160+
if i == 0:
161+
assert "hello" in v["output"]
162+
elif i == 1:
163+
assert "world" in v["output"]
164+
165+
166+
def test_workflow_run_multiline(tmp_path):
167+
config_path = (tmp_path / "test-config-empty.toml").resolve()
168+
config_path.write_text("")
169+
170+
data = copy.deepcopy(WORKFLOW_SKELETON)
171+
data["steps"].append(
172+
{
173+
"name": "cmdrunner",
174+
"run": """
175+
echo hello \
176+
world
177+
""",
178+
}
179+
)
180+
181+
output_path = (tmp_path / "output").resolve()
182+
workflow_file = (tmp_path / "workflow.yaml").resolve()
183+
workflow_file.write_text(yaml.dump(data))
184+
185+
result = subprocess.run(
186+
[
187+
"cijoe",
188+
str(workflow_file),
189+
"--output",
190+
str(output_path),
191+
"--config",
192+
str(config_path),
193+
],
194+
cwd=str(tmp_path),
195+
)
196+
assert result.returncode == 0
197+
198+
runlog = runlog_from_path(output_path / "002_cmdrunner")
199+
200+
assert len(runlog) == 1
201+
assert "hello world" in runlog["cmd_01"]["output"]

0 commit comments

Comments
 (0)