Skip to content

Commit e2ec740

Browse files
author
Peter Amstutz
authored
"checklinks" flag should not be based on do_validate (#1106)
* "checklinks" flag should not be based on do_validate This flag is used internally by schema salad to determine when it is appropriate to run checklinks, but checklinks must not be skipped entirely as it includes updating fields in certain circumstances. * Add http://arvados.org/cwl#ReuseRequirement extension to updates * Make sure to use the cwlVersion declared at the root of the document. * Add test for do_validate and outputSource. * Use builder.outdir (container) not passed in outdir (host). * Test for getting cwlVersion from root document in load_tool.
1 parent cb81b22 commit e2ec740

File tree

4 files changed

+54
-8
lines changed

4 files changed

+54
-8
lines changed

cwltool/command_line_tool.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -677,8 +677,8 @@ def collect_output(self,
677677
globpatterns.extend(aslist(gb))
678678

679679
for gb in globpatterns:
680-
if gb.startswith(outdir):
681-
gb = gb[len(outdir) + 1:]
680+
if gb.startswith(builder.outdir):
681+
gb = gb[len(builder.outdir) + 1:]
682682
elif gb == ".":
683683
gb = outdir
684684
elif gb.startswith("/"):

cwltool/load_tool.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def resolve_and_validate_document(loadingContext,
208208

209209
jobobj = None
210210
if "cwl:tool" in workflowobj:
211-
jobobj, _ = loadingContext.loader.resolve_all(workflowobj, uri, checklinks=loadingContext.do_validate)
211+
jobobj, _ = loadingContext.loader.resolve_all(workflowobj, uri)
212212
uri = urllib.parse.urljoin(uri, workflowobj["https://w3id.org/cwl/cwl#tool"])
213213
del cast(dict, jobobj)["https://w3id.org/cwl/cwl#tool"]
214214

@@ -219,6 +219,11 @@ def resolve_and_validate_document(loadingContext,
219219
cwlVersion = loadingContext.metadata.get("cwlVersion")
220220
if not cwlVersion:
221221
cwlVersion = workflowobj.get("cwlVersion")
222+
if not cwlVersion and fileuri != uri:
223+
# The tool we're loading is a fragment of a bigger file. Get
224+
# the document root element and look for cwlVersion there.
225+
metadata = fetch_document(fileuri, loadingContext)[1]
226+
cwlVersion = metadata.get("cwlVersion")
222227
if not cwlVersion:
223228
raise ValidationException(
224229
"No cwlVersion found. "
@@ -281,9 +286,7 @@ def resolve_and_validate_document(loadingContext,
281286
if cwlVersion == "v1.0":
282287
_add_blank_ids(workflowobj)
283288

284-
workflowobj["id"] = fileuri
285-
processobj, metadata = document_loader.resolve_all(
286-
workflowobj, fileuri, checklinks=loadingContext.do_validate)
289+
processobj, metadata = document_loader.resolve_all(workflowobj, fileuri)
287290
if loadingContext.metadata:
288291
metadata = loadingContext.metadata
289292
if not isinstance(processobj, (CommentedMap, CommentedSeq)):
@@ -301,6 +304,8 @@ def resolve_and_validate_document(loadingContext,
301304

302305
# None means default behavior (do update)
303306
if loadingContext.do_update in (True, None):
307+
if "cwlVersion" not in metadata:
308+
metadata["cwlVersion"] = cwlVersion
304309
processobj = cast(CommentedMap, cmap(update.update(
305310
processobj, document_loader, fileuri, loadingContext.enable_dev, metadata)))
306311
if isinstance(processobj, MutableMapping):
@@ -309,6 +314,8 @@ def resolve_and_validate_document(loadingContext,
309314
document_loader.idx[metadata["id"]] = metadata
310315
for po in processobj:
311316
document_loader.idx[po["id"]] = po
317+
else:
318+
raise Exception("'processobj' was not MutableMapping or MutableSequence %s" % type(processobj))
312319

313320
if jobobj is not None:
314321
loadingContext.jobdefaults = jobobj

cwltool/update.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ def v1_0to1_1_0dev1(doc, loader, baseuri): # pylint: disable=unused-argument
2727

2828
rewrite = {
2929
"http://commonwl.org/cwltool#WorkReuse": "WorkReuse",
30+
"http://arvados.org/cwl#ReuseRequirement": "WorkReuse",
3031
"http://commonwl.org/cwltool#TimeLimit": "ToolTimeLimit",
3132
"http://commonwl.org/cwltool#NetworkAccess": "NetworkAccess",
3233
"http://commonwl.org/cwltool#InplaceUpdateRequirement": "InplaceUpdateRequirement",
33-
"http://commonwl.org/cwltool#LoadListingRequirement": "LoadListingRequirement",
34-
"http://commonwl.org/cwltool#WorkReuse": "WorkReuse",
34+
"http://commonwl.org/cwltool#LoadListingRequirement": "LoadListingRequirement"
3535
}
3636
def rewrite_requirements(t):
3737
if "requirements" in t:
@@ -73,6 +73,8 @@ def fix_inputBinding(t):
7373
proc.setdefault("hints", [])
7474
proc["hints"].insert(0, {"class": "NetworkAccess", "networkAccess": True})
7575
proc["hints"].insert(0, {"class": "LoadListingRequirement", "loadListing": "deep_listing"})
76+
if "cwlVersion" in proc:
77+
del proc["cwlVersion"]
7678

7779
return (doc, "v1.1.0-dev1")
7880

tests/test_load_tool.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
from cwltool.load_tool import load_tool
22
from cwltool.context import LoadingContext, RuntimeContext
33
from cwltool.errors import WorkflowException
4+
from cwltool.update import INTERNAL_VERSION
45
import pytest
56
from .util import (get_data, get_main_output,
67
get_windows_safe_factory,
78
needs_docker, working_directory,
89
needs_singularity, temp_dir,
910
windows_needs_docker)
11+
from cwltool.resolver import Path, resolve_local
12+
from .test_fetch import norm
1013

1114
@windows_needs_docker
1215
def test_check_version():
@@ -42,3 +45,37 @@ def test_use_metadata():
4245
tooldata = tool.tool.copy()
4346
del tooldata["cwlVersion"]
4447
tool2 = load_tool(tooldata, loadingContext)
48+
49+
def test_checklink_outputSource():
50+
"""Test that outputSource is resolved correctly independent of value
51+
of do_validate.
52+
53+
"""
54+
55+
outsrc = norm(Path(get_data("tests/wf/1st-workflow.cwl")).as_uri())+"#argument/classfile"
56+
57+
loadingContext = LoadingContext({"do_validate": True})
58+
tool = load_tool(get_data("tests/wf/1st-workflow.cwl"), loadingContext)
59+
assert norm(tool.tool["outputs"][0]["outputSource"]) == outsrc
60+
61+
loadingContext = LoadingContext({"do_validate": False})
62+
tool = load_tool(get_data("tests/wf/1st-workflow.cwl"), loadingContext)
63+
assert norm(tool.tool["outputs"][0]["outputSource"]) == outsrc
64+
65+
def test_load_graph_fragment():
66+
"""Test that outputSource is resolved correctly independent of value
67+
of do_validate.
68+
69+
"""
70+
71+
loadingContext = LoadingContext()
72+
uri = Path(get_data("tests/wf/scatter-wf4.cwl")).as_uri()+"#main"
73+
tool = load_tool(uri, loadingContext)
74+
75+
rs, metadata = tool.doc_loader.resolve_ref(uri)
76+
# Reload from a dict (in 'rs'), not a URI. The dict is a fragment
77+
# of original document and doesn't have cwlVersion set, so test
78+
# that it correctly looks up the root document to get the
79+
# cwlVersion.
80+
tool = load_tool(tool.tool, loadingContext)
81+
assert tool.metadata["cwlVersion"] == INTERNAL_VERSION

0 commit comments

Comments
 (0)