Skip to content

Commit d7184c7

Browse files
GlassOfWhiskeymr-c
andauthored
Discard undeclared fields from cwl.output.json (#2177)
Discards all fields that are present in a `cwl.output.json` file but have not been declared in the `output` object of the related `CommandLineTool`, implementing common-workflow-language/cwl-v1.3#80. Co-authored-by: Michael R. Crusoe <[email protected]>
1 parent 766d58b commit d7184c7

File tree

6 files changed

+110
-2
lines changed

6 files changed

+110
-2
lines changed

cwltool/command_line_tool.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
from mypy_extensions import mypyc_attr
2828
from ruamel.yaml.comments import CommentedMap, CommentedSeq
29-
from schema_salad.avro.schema import Schema
29+
from schema_salad.avro.schema import RecordSchema
3030
from schema_salad.exceptions import ValidationException
3131
from schema_salad.ref_resolver import file_uri, uri_file_path
3232
from schema_salad.sourceline import SourceLine
@@ -1216,6 +1216,7 @@ def collect_output_ports(
12161216
if cwl_version != "v1.0":
12171217
builder.resources["exitCode"] = rcode
12181218
try:
1219+
expected_schema = cast(RecordSchema, self.names.get_name("outputs_record_schema", None))
12191220
fs_access = builder.make_fs_access(outdir)
12201221
custom_output = fs_access.join(outdir, "cwl.output.json")
12211222
if fs_access.exists(custom_output):
@@ -1227,6 +1228,20 @@ def collect_output_ports(
12271228
custom_output,
12281229
json_dumps(ret, indent=4),
12291230
)
1231+
if ORDERED_VERSIONS.index(cast(str, cwl_version)) >= ORDERED_VERSIONS.index(
1232+
"v1.3.0-dev1"
1233+
):
1234+
for k in list(ret):
1235+
found = False
1236+
for field in expected_schema.fields:
1237+
if k == field.name:
1238+
found = True
1239+
break
1240+
if not found:
1241+
_logger.warning(
1242+
f"Discarded undeclared output named {k!r} from {custom_output}."
1243+
)
1244+
ret.pop(k)
12301245
else:
12311246
for i, port in enumerate(ports):
12321247
with SourceLine(
@@ -1257,7 +1272,6 @@ def collect_output_ports(
12571272

12581273
if compute_checksum:
12591274
adjustFileObjs(ret, partial(compute_checksums, fs_access))
1260-
expected_schema = cast(Schema, self.names.get_name("outputs_record_schema", None))
12611275
validate_ex(
12621276
expected_schema,
12631277
ret,

tests/test-cwl-out-v1.0.cwl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class: CommandLineTool
2+
cwlVersion: v1.0
3+
4+
inputs: []
5+
6+
baseCommand: sh
7+
8+
arguments:
9+
- -c
10+
- |
11+
echo '{"foo": 5 }'
12+
13+
stdout: cwl.output.json
14+
15+
outputs: {}

tests/test-cwl-out-v1.1.cwl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class: CommandLineTool
2+
cwlVersion: v1.1
3+
4+
inputs: []
5+
6+
baseCommand: sh
7+
8+
arguments:
9+
- -c
10+
- |
11+
echo '{"foo": 5 }'
12+
13+
stdout: cwl.output.json
14+
15+
outputs: {}

tests/test-cwl-out-v1.2.cwl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class: CommandLineTool
2+
cwlVersion: v1.2
3+
4+
inputs: []
5+
6+
baseCommand: sh
7+
8+
arguments:
9+
- -c
10+
- |
11+
echo '{"foo": 5 }'
12+
13+
stdout: cwl.output.json
14+
15+
outputs: {}

tests/test-cwl-out-v1.3.cwl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class: CommandLineTool
2+
cwlVersion: v1.3.0-dev1
3+
4+
inputs: []
5+
6+
baseCommand: sh
7+
8+
arguments:
9+
- -c
10+
- |
11+
echo '{"foo": 5 }'
12+
13+
stdout: cwl.output.json
14+
15+
outputs: {}

tests/test_cwl_output_json.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import json
2+
3+
from .util import get_data, get_main_output
4+
5+
6+
def test_cwl_output_json_missing_field_v1_0() -> None:
7+
"""Confirm that unknown outputs are propagated from cwl.output.json in CWL v1.0."""
8+
err_code, stdout, _ = get_main_output([get_data("tests/test-cwl-out-v1.0.cwl")])
9+
assert err_code == 0
10+
assert "foo" in json.loads(stdout)
11+
12+
13+
def test_cwl_output_json_missing_field_v1_1() -> None:
14+
"""Confirm that unknown outputs are propagated from cwl.output.json in CWL v1.1."""
15+
err_code, stdout, _ = get_main_output([get_data("tests/test-cwl-out-v1.1.cwl")])
16+
assert err_code == 0
17+
assert "foo" in json.loads(stdout)
18+
19+
20+
def test_cwl_output_json_missing_field_v1_2() -> None:
21+
"""Confirm that unknown outputs are propagated from cwl.output.json in CWL v1.2."""
22+
err_code, stdout, _ = get_main_output([get_data("tests/test-cwl-out-v1.2.cwl")])
23+
assert err_code == 0
24+
assert "foo" in json.loads(stdout)
25+
26+
27+
def test_cwl_output_json_missing_field_v1_3() -> None:
28+
"""Confirm that unknown outputs are propagated from cwl.output.json in CWL v1.3."""
29+
err_code, stdout, stderr = get_main_output(
30+
["--enable-dev", get_data("tests/test-cwl-out-v1.3.cwl")]
31+
)
32+
assert err_code == 0
33+
assert "foo" not in json.loads(stdout)
34+
assert "Discarded undeclared output named 'foo' from" in stderr

0 commit comments

Comments
 (0)