Skip to content

Commit 428504e

Browse files
Peter Amstutzmr-c
Peter Amstutz
authored andcommitted
Support file system and Dockstore lookups for tools.
1 parent bb968d3 commit 428504e

File tree

3 files changed

+59
-7
lines changed

3 files changed

+59
-7
lines changed

cwltool/load_tool.py

+16-6
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919

2020
_logger = logging.getLogger("cwltool")
2121

22-
def fetch_document(argsworkflow):
23-
# type: (Union[Text, Text, dict[Text, Any]]) -> Tuple[Loader, Dict[Text, Any], Text]
22+
def fetch_document(argsworkflow, resolver=None):
23+
# type: (Union[Text, dict[Text, Any]], Any) -> Tuple[Loader, Dict[Text, Any], Text]
2424
"""Retrieve a CWL document."""
2525
document_loader = Loader({"cwl": "https://w3id.org/cwl/cwl#", "id": "@id"})
2626

@@ -30,8 +30,17 @@ def fetch_document(argsworkflow):
3030
split = urlparse.urlsplit(argsworkflow)
3131
if split.scheme:
3232
uri = argsworkflow
33-
else:
33+
elif os.path.exists(os.path.abspath(argsworkflow)):
3434
uri = "file://" + os.path.abspath(argsworkflow)
35+
elif resolver:
36+
uri = resolver(document_loader, argsworkflow)
37+
38+
if uri is None:
39+
raise ValidationException("Not found: '%s'" % argsworkflow)
40+
41+
if argsworkflow != uri:
42+
_logger.info("Resolved '%s' to '%s'", argsworkflow, uri)
43+
3544
fileuri = urlparse.urldefrag(uri)[0]
3645
workflowobj = document_loader.fetch(fileuri)
3746
elif isinstance(argsworkflow, dict):
@@ -193,9 +202,10 @@ def make_tool(document_loader, avsc_names, metadata, uri, makeTool, kwargs):
193202

194203
def load_tool(argsworkflow, makeTool, kwargs=None,
195204
enable_dev=False,
196-
strict=True):
197-
# type: (Union[Text, dict[Text,Any]], Callable[...,Process], Dict[AnyStr, Any], bool, bool) -> Any
198-
document_loader, workflowobj, uri = fetch_document(argsworkflow)
205+
strict=True,
206+
resolver=None):
207+
# type: (Union[Text, dict[Text, Any]], Callable[...,Process], Dict[AnyStr, Any], bool, bool, Any) -> Any
208+
document_loader, workflowobj, uri = fetch_document(argsworkflow, resolver=resolver)
199209
document_loader, avsc_names, processobj, metadata, uri = validate_document(
200210
document_loader, workflowobj, uri, enable_dev=enable_dev,
201211
strict=strict)

cwltool/main.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from .process import shortname, Process, getListing, relocateOutputs, cleanIntermediate, scandeps, normalizeFilesDirs
2929
from .load_tool import fetch_document, validate_document, make_tool
3030
from . import draft2tool
31+
from .resolver import tool_resolver
3132
from .builder import adjustFileObjs, adjustDirObjs
3233
from .stdfsaccess import StdFsAccess
3334
from .pack import pack
@@ -617,7 +618,7 @@ def main(argsl=None,
617618
return 1
618619

619620
try:
620-
document_loader, workflowobj, uri = fetch_document(args.workflow)
621+
document_loader, workflowobj, uri = fetch_document(args.workflow, resolver=tool_resolver)
621622

622623
if args.print_deps:
623624
printdeps(workflowobj, document_loader, stdout, args.relative_deps, uri)

cwltool/resolver.py

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import os
2+
import logging
3+
import urllib
4+
import urlparse
5+
6+
_logger = logging.getLogger("cwltool")
7+
8+
def resolve_local(document_loader, uri):
9+
if uri.startswith("/"):
10+
return None
11+
shares = [os.environ.get("XDG_DATA_HOME", os.path.join(os.environ["HOME"], ".local", "share"))]
12+
shares.extend(os.environ.get("XDG_DATA_DIRS", "/usr/local/share/:/usr/share/").split(":"))
13+
shares = [os.path.join(s, "commonwl", uri) for s in shares]
14+
shares.insert(0, os.path.join(os.getcwd(), uri))
15+
16+
_logger.debug("Search path is %s", shares)
17+
18+
for s in shares:
19+
if os.path.exists(s):
20+
return ("file://%s" % s)
21+
if os.path.exists("%s.cwl" % s):
22+
return ("file://%s.cwl" % s)
23+
return None
24+
25+
def resolve_ga4gh_tool(document_loader, uri):
26+
ds = "https://staging.dockstore.org:8443/api/ga4gh/v1/tools/%s/versions/master/plain-CWL/descriptor" % urllib.quote(uri, "")
27+
print ds
28+
try:
29+
resp = document_loader.session.head(ds)
30+
resp.raise_for_status()
31+
return ds
32+
except Exception:
33+
pass
34+
return None
35+
36+
def tool_resolver(document_loader, uri):
37+
for r in [resolve_local, resolve_ga4gh_tool]:
38+
ret = r(document_loader, uri)
39+
if ret is not None:
40+
return ret
41+
return uri

0 commit comments

Comments
 (0)