Skip to content

Commit e2728a3

Browse files
authored
Merge pull request #42 from common-workflow-language/expr_refactor_cwl_v12
Expr refactor for CWL v1.1+1.2
2 parents 480178d + bf2fb8e commit e2728a3

15 files changed

+4712
-93
lines changed
Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#!/usr/bin/env python3
2+
"""CWL Expression refactoring tool for CWL v1.0 ."""
23
import argparse
34
import copy
45
import hashlib
@@ -42,8 +43,9 @@
4243
def parse_args(args: List[str]) -> argparse.Namespace:
4344
"""Argument parser."""
4445
parser = argparse.ArgumentParser(
45-
description="Tool to upgrade refactor CWL documents so that any CWL expression "
46-
"are separate steps as either ExpressionTools or CommandLineTools."
46+
description="Tool to refactor CWL v1.0 documents so that any CWL expression "
47+
"are separate steps as either ExpressionTools or CommandLineTools. Exit code 7 "
48+
"means a single CWL document was provided but it did not need modification."
4749
)
4850
parser.add_argument(
4951
"--etools",
@@ -83,11 +85,14 @@ def run(args: argparse.Namespace) -> int:
8385
top = cwl.load_document(document)
8486
output = Path(args.dir) / Path(document).name
8587
result, modified = traverse(
86-
top, not args.etools, args.skip_some1, args.skip_some2
88+
top, not args.etools, False, args.skip_some1, args.skip_some2
8789
)
8890
if not modified:
89-
shutil.copyfile(document, output)
90-
continue
91+
if len(args.inputs) > 1:
92+
shutil.copyfile(document, output)
93+
continue
94+
else:
95+
return 7
9196
if not isinstance(result, MutableSequence):
9297
result_json = cwl.save(
9398
result,
@@ -242,15 +247,18 @@ def etool_to_cltool(
242247
process.stdout.write(JSON.stringify(ret));"""
243248
)
244249
contents = escape_expression_field(contents)
245-
listing = [cwl.Dirent("expression.js", contents, writable=None)]
250+
listing = [cwl.Dirent(entryname="expression.js", entry=contents, writable=None)]
246251
iwdr = cwl.InitialWorkDirRequirement(listing)
247252
containerReq = cwl.DockerRequirement(dockerPull="node:slim")
253+
softwareHint = cwl.SoftwareRequirement(
254+
packages=[cwl.SoftwarePackage(package="nodejs")]
255+
)
248256
return cwl.CommandLineTool(
249257
inputs=inputs,
250258
outputs=outputs,
251259
id=etool.id,
252260
requirements=[iwdr],
253-
hints=[containerReq],
261+
hints=[containerReq, softwareHint],
254262
label=etool.label,
255263
doc=etool.doc,
256264
cwlVersion=etool.cwlVersion,
@@ -263,10 +271,10 @@ def etool_to_cltool(
263271

264272
def traverse(
265273
process: Union[cwl.CommandLineTool, cwl.ExpressionTool, cwl.Workflow],
266-
replace_etool: bool = False,
267-
inside: bool = False,
268-
skip_command_line1: bool = False,
269-
skip_command_line2: bool = False,
274+
replace_etool: bool,
275+
inside: bool,
276+
skip_command_line1: bool,
277+
skip_command_line2: bool,
270278
) -> Tuple[Union[cwl.CommandLineTool, cwl.ExpressionTool, cwl.Workflow], bool]:
271279
"""Convert the given process and any subprocesess."""
272280
if not inside and isinstance(process, cwl.CommandLineTool):
@@ -348,9 +356,9 @@ def traverse(
348356

349357
def load_step(
350358
step: cwl.WorkflowStep,
351-
replace_etool: bool = False,
352-
skip_command_line1: bool = False,
353-
skip_command_line2: bool = False,
359+
replace_etool: bool,
360+
skip_command_line1: bool,
361+
skip_command_line2: bool,
354362
) -> bool:
355363
"""If the step's Process is not inline, load and process it."""
356364
modified = False
@@ -700,7 +708,7 @@ def process_workflow_inputs_and_outputs(
700708

701709

702710
def process_workflow_reqs_and_hints(
703-
workflow: cwl.Workflow, replace_etool: bool = False
711+
workflow: cwl.Workflow, replace_etool: bool
704712
) -> bool:
705713
"""
706714
Convert any expressions in a workflow's reqs and hints.
@@ -1029,9 +1037,9 @@ def process_level_reqs(
10291037
process: cwl.CommandLineTool,
10301038
step: cwl.WorkflowStep,
10311039
parent: cwl.Workflow,
1032-
replace_etool: bool = False,
1033-
skip_command_line1: bool = False,
1034-
skip_command_line2: bool = False,
1040+
replace_etool: bool,
1041+
skip_command_line1: bool,
1042+
skip_command_line2: bool,
10351043
) -> bool:
10361044
"""Convert expressions inside a process into new adjacent steps."""
10371045
# This is for reqs inside a Process (CommandLineTool, ExpressionTool)
@@ -1301,9 +1309,9 @@ def traverse_CommandLineTool(
13011309
clt: cwl.CommandLineTool,
13021310
parent: cwl.Workflow,
13031311
step: cwl.WorkflowStep,
1304-
replace_etool: bool = False,
1305-
skip_command_line1: bool = False,
1306-
skip_command_line2: bool = False,
1312+
replace_etool: bool,
1313+
skip_command_line1: bool,
1314+
skip_command_line2: bool,
13071315
) -> bool:
13081316
"""Extract any CWL Expressions within the given CommandLineTool into sibling steps."""
13091317
modified = False
@@ -1592,7 +1600,7 @@ def simplify_step_id(uri: str) -> str:
15921600

15931601
def remove_JSReq(
15941602
process: Union[cwl.CommandLineTool, cwl.WorkflowStep, cwl.Workflow],
1595-
skip_command_line1: bool = False,
1603+
skip_command_line1: bool,
15961604
) -> None:
15971605
"""Since the InlineJavascriptRequiment is longer needed, remove it."""
15981606
if skip_command_line1 and isinstance(process, cwl.CommandLineTool):
@@ -1621,7 +1629,7 @@ def replace_step_clt_expr_with_etool(
16211629
workflow: cwl.Workflow,
16221630
target: cwl.InputParameter,
16231631
step: cwl.WorkflowStep,
1624-
replace_etool: bool = False,
1632+
replace_etool: bool,
16251633
self_name: Optional[str] = None,
16261634
) -> None:
16271635
"""Convert a step level CWL Expression to a sibling expression step."""
@@ -1656,7 +1664,7 @@ def replace_clt_hintreq_expr_with_etool(
16561664
workflow: cwl.Workflow,
16571665
target: cwl.InputParameter,
16581666
step: cwl.WorkflowStep,
1659-
replace_etool: bool = False,
1667+
replace_etool: bool,
16601668
self_name: Optional[str] = None,
16611669
) -> Union[cwl.CommandLineTool, cwl.ExpressionTool]:
16621670
"""Factor out an expression inside a CommandLineTool req or hint into a sibling step."""
@@ -1815,9 +1823,9 @@ def generate_etool_from_expr2(
18151823
def traverse_step(
18161824
step: cwl.WorkflowStep,
18171825
parent: cwl.Workflow,
1818-
replace_etool: bool = False,
1819-
skip_command_line1: bool = False,
1820-
skip_command_line2: bool = False,
1826+
replace_etool: bool,
1827+
skip_command_line1: bool,
1828+
skip_command_line2: bool,
18211829
) -> bool:
18221830
"""Process the given WorkflowStep."""
18231831
modified = False
@@ -1915,7 +1923,12 @@ def traverse_step(
19151923
inp.source = "{}/result".format(etool_id)
19161924
# TODO: skip or special process for sub workflows?
19171925
process_modified = process_level_reqs(
1918-
original_process, step, parent, replace_etool, skip_command_line1
1926+
original_process,
1927+
step,
1928+
parent,
1929+
replace_etool,
1930+
skip_command_line1,
1931+
skip_command_line2,
19191932
)
19201933
if process_modified:
19211934
modified = True
@@ -1958,7 +1971,7 @@ def replace_step_valueFrom_expr_with_etool(
19581971
original_process: Union[cwl.CommandLineTool, cwl.ExpressionTool],
19591972
original_step_ins: List[cwl.WorkflowStepInput],
19601973
source: Union[str, List[Any]],
1961-
replace_etool: bool = False,
1974+
replace_etool: bool,
19621975
source_type: Optional[Union[cwl.InputParameter, cwl.CommandInputParameter]] = None,
19631976
) -> None:
19641977
"""Replace a WorkflowStep level 'valueFrom' expression with a sibling ExpressionTool step."""
@@ -2030,9 +2043,9 @@ def replace_step_valueFrom_expr_with_etool(
20302043

20312044
def traverse_workflow(
20322045
workflow: cwl.Workflow,
2033-
replace_etool: bool = False,
2034-
skip_command_line1: bool = False,
2035-
skip_command_line2: bool = False,
2046+
replace_etool: bool,
2047+
skip_command_line1: bool,
2048+
skip_command_line2: bool,
20362049
) -> Tuple[cwl.Workflow, bool]:
20372050
"""Traverse a workflow, processing each step."""
20382051
modified = False
@@ -2049,7 +2062,7 @@ def traverse_workflow(
20492062
for step in workflow.steps:
20502063
if not step.id.startswith("_expression"):
20512064
step_modified = traverse_step(
2052-
step, workflow, skip_command_line1, skip_command_line2
2065+
step, workflow, replace_etool, skip_command_line1, skip_command_line2
20532066
)
20542067
if step_modified:
20552068
modified = True

0 commit comments

Comments
 (0)