Skip to content

Commit 87048d8

Browse files
author
Peter Amstutz
committed
Merge branch 'pack'
2 parents d55f6e0 + 2b93aaf commit 87048d8

File tree

3 files changed

+85
-7
lines changed

3 files changed

+85
-7
lines changed

cwltool/load_tool.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from .errors import WorkflowException
1616
from typing import Any, Callable, cast, Dict, Tuple, Union
1717

18+
_logger = logging.getLogger("cwltool")
1819

1920
def fetch_document(argsworkflow):
2021
# type: (Union[str, unicode, dict[unicode, Any]]) -> Tuple[Loader, Dict[unicode, Any], unicode]
@@ -64,6 +65,7 @@ def validate_document(document_loader, workflowobj, uri,
6465
r"^(?:cwl:|https://w3id.org/cwl/cwl#)", "",
6566
workflowobj["cwlVersion"])
6667
else:
68+
_logger.warn("No cwlVersion found, treating this file as draft-2.")
6769
workflowobj["cwlVersion"] = "draft-2"
6870

6971
if workflowobj["cwlVersion"] == "draft-2":
@@ -82,17 +84,17 @@ def validate_document(document_loader, workflowobj, uri,
8284
workflowobj["id"] = fileuri
8385
processobj, metadata = document_loader.resolve_all(workflowobj, fileuri)
8486

87+
if not metadata:
88+
metadata = {"$namespaces": processobj.get("$namespaces", {}),
89+
"$schemas": processobj.get("$schemas", []),
90+
"cwlVersion": processobj["cwlVersion"]}
91+
8592
if preprocess_only:
8693
return document_loader, avsc_names, processobj, metadata, uri
8794

8895
document_loader.validate_links(processobj)
8996
schema.validate_doc(avsc_names, processobj, document_loader, strict)
9097

91-
if not metadata:
92-
metadata = {"$namespaces": processobj.get("$namespaces", {}),
93-
"$schemas": processobj.get("$schemas", []),
94-
"cwlVersion": processobj["cwlVersion"]}
95-
9698
if metadata.get("cwlVersion") != update.LATEST:
9799
processobj = update.update(
98100
processobj, document_loader, fileuri, enable_dev, metadata)

cwltool/main.py

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import os
99
import sys
1010
import logging
11+
import copy
1112
from . import workflow
1213
from .errors import WorkflowException
1314
from . import process
@@ -114,6 +115,7 @@ def arg_parser(): # type: () -> argparse.ArgumentParser
114115
exgroup.add_argument("--print-pre", action="store_true", help="Print CWL document after preprocessing.")
115116
exgroup.add_argument("--print-deps", action="store_true", help="Print CWL document dependencies.")
116117
exgroup.add_argument("--print-input-deps", action="store_true", help="Print input object document dependencies.")
118+
exgroup.add_argument("--pack", action="store_true", help="Combine components into single document and print.")
117119
exgroup.add_argument("--version", action="store_true", help="Print version and exit")
118120

119121
exgroup = parser.add_mutually_exclusive_group()
@@ -417,6 +419,76 @@ def makeRelative(u):
417419

418420
stdout.write(json.dumps(deps, indent=4))
419421

422+
def flatten_deps(d, files):
423+
if isinstance(d, list):
424+
for s in d:
425+
flatten_deps(s, files)
426+
elif isinstance(d, dict):
427+
files.add(d["path"])
428+
if "secondaryFiles" in d:
429+
flatten_deps(d["secondaryFiles"], files)
430+
431+
def find_run(d, runs):
432+
if isinstance(d, list):
433+
for s in d:
434+
find_run(s, runs)
435+
elif isinstance(d, dict):
436+
if "run" in d and isinstance(d["run"], basestring):
437+
runs.add(d["run"])
438+
for s in d.values():
439+
find_run(s, runs)
440+
441+
def replace_refs(d, rewrite, stem, newstem):
442+
if isinstance(d, list):
443+
for s,v in enumerate(d):
444+
if isinstance(v, basestring) and v.startswith(stem):
445+
d[s] = newstem + v[len(stem):]
446+
else:
447+
replace_refs(v, rewrite, stem, newstem)
448+
elif isinstance(d, dict):
449+
if "run" in d and isinstance(d["run"], basestring):
450+
d["run"] = rewrite[d["run"]]
451+
for s,v in d.items():
452+
if isinstance(v, basestring) and v.startswith(stem):
453+
d[s] = newstem + v[len(stem):]
454+
replace_refs(v, rewrite, stem, newstem)
455+
456+
def print_pack(document_loader, processobj, uri, metadata):
457+
def loadref(b, u):
458+
return document_loader.resolve_ref(u, base_url=b)[0]
459+
deps = process.scandeps(uri, processobj,
460+
set(("run",)), set(), loadref)
461+
462+
fdeps = set((uri,))
463+
flatten_deps(deps, fdeps)
464+
465+
runs = set()
466+
for f in fdeps:
467+
find_run(document_loader.idx[f], runs)
468+
469+
rewrite = {}
470+
if isinstance(processobj, list):
471+
for p in processobj:
472+
rewrite[p["id"]] = "#" + shortname(p["id"])
473+
else:
474+
rewrite[uri] = "#main"
475+
476+
for r in runs:
477+
rewrite[r] = "#" + shortname(r)
478+
479+
packed = {"$graph": [], "cwlVersion": metadata["cwlVersion"]}
480+
for r,v in rewrite.items():
481+
dc = copy.deepcopy(document_loader.idx[r])
482+
dc["id"] = v
483+
dc["name"] = v
484+
replace_refs(dc, rewrite, r+"/" if "#" in r else r+"#", v+"/")
485+
packed["$graph"].append(dc)
486+
487+
if len(packed["$graph"]) > 1:
488+
return json.dumps(packed, indent=4)
489+
else:
490+
return json.dumps(packed["$graph"][0], indent=4)
491+
420492
def versionstring():
421493
# type: () -> unicode
422494
pkg = pkg_resources.require("cwltool")
@@ -498,7 +570,11 @@ def main(argsl=None,
498570
document_loader, avsc_names, processobj, metadata, uri \
499571
= validate_document(document_loader, workflowobj, uri,
500572
enable_dev=args.enable_dev, strict=args.strict,
501-
preprocess_only=args.print_pre)
573+
preprocess_only=args.print_pre or args.pack)
574+
575+
if args.pack:
576+
stdout.write(print_pack(document_loader, processobj, uri, metadata))
577+
return 0
502578

503579
if args.print_pre:
504580
stdout.write(json.dumps(processobj, indent=4))

cwltool/process.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ def evalResources(self, builder, kwargs):
408408
}
409409

410410
def validate_hints(self, avsc_names, hints, strict):
411-
# type: (List[Dict[str, Any]], bool) -> None
411+
# type: (Any, List[Dict[str, Any]], bool) -> None
412412
for r in hints:
413413
try:
414414
if avsc_names.get_name(r["class"], "") is not None:

0 commit comments

Comments
 (0)