comparison env/lib/python3.7/site-packages/cwltool/update.py @ 0:26e78fe6e8c4 draft

"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author shellac
date Sat, 02 May 2020 07:14:21 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:26e78fe6e8c4
1 from __future__ import absolute_import
2
3 import copy
4 import re
5 from typing import (Any, Callable, Dict, List, MutableMapping, MutableSequence,
6 Optional, Tuple, Union)
7
8 from functools import partial
9
10 from ruamel.yaml.comments import CommentedMap, CommentedSeq
11 from schema_salad import validate
12 from schema_salad.ref_resolver import Loader # pylint: disable=unused-import
13 from six import string_types
14 from six.moves import urllib
15 from typing_extensions import Text
16 from schema_salad.sourceline import SourceLine
17 from .loghandler import _logger
18
19 # move to a regular typing import when Python 3.3-3.6 is no longer supported
20
21 from .utils import visit_class, visit_field, aslist
22
23
24 def v1_0to1_1(doc, loader, baseuri): # pylint: disable=unused-argument
25 # type: (Any, Loader, Text) -> Tuple[Any, Text]
26 """Public updater for v1.0 to v1.1."""
27 doc = copy.deepcopy(doc)
28
29 rewrite = {
30 "http://commonwl.org/cwltool#WorkReuse": "WorkReuse",
31 "http://arvados.org/cwl#ReuseRequirement": "WorkReuse",
32 "http://commonwl.org/cwltool#TimeLimit": "ToolTimeLimit",
33 "http://commonwl.org/cwltool#NetworkAccess": "NetworkAccess",
34 "http://commonwl.org/cwltool#InplaceUpdateRequirement": "InplaceUpdateRequirement",
35 "http://commonwl.org/cwltool#LoadListingRequirement": "LoadListingRequirement"
36 }
37 def rewrite_requirements(t): # type: (MutableMapping[Text, Union[Text, Dict[Text, Any]]]) -> None
38 if "requirements" in t:
39 for r in t["requirements"]:
40 if isinstance(r, MutableMapping):
41 if r["class"] in rewrite:
42 r["class"] = rewrite[r["class"]]
43 else:
44 raise validate.ValidationException(
45 "requirements entries must be dictionaries: {} {}.".format(
46 type(r), r))
47 if "hints" in t:
48 for r in t["hints"]:
49 if isinstance(r, MutableMapping):
50 if r["class"] in rewrite:
51 r["class"] = rewrite[r["class"]]
52 else:
53 raise validate.ValidationException(
54 "hints entries must be dictionaries: {} {}.".format(
55 type(r), r))
56 if "steps" in t:
57 for s in t["steps"]:
58 if isinstance(s, MutableMapping):
59 rewrite_requirements(s)
60 else:
61 raise validate.ValidationException(
62 "steps entries must be dictionaries: {} {}.".format(
63 type(s), s))
64
65
66 def update_secondaryFiles(t, top=False):
67 # type: (Any, bool) -> Union[MutableSequence[MutableMapping[Text, Text]], MutableMapping[Text, Text]]
68 if isinstance(t, CommentedSeq):
69 new_seq = copy.deepcopy(t)
70 for index, entry in enumerate(t):
71 new_seq[index] = update_secondaryFiles(entry)
72 return new_seq
73 elif isinstance(t, MutableSequence):
74 return CommentedSeq([update_secondaryFiles(p) for p in t])
75 elif isinstance(t, MutableMapping):
76 return t
77 elif top:
78 return CommentedSeq([CommentedMap([("pattern", t)])])
79 else:
80 return CommentedMap([("pattern", t)])
81
82 def fix_inputBinding(t): # type: (Dict[Text, Any]) -> None
83 for i in t["inputs"]:
84 if "inputBinding" in i:
85 ib = i["inputBinding"]
86 for k in list(ib.keys()):
87 if k != "loadContents":
88 _logger.warning(SourceLine(ib, k).makeError(
89 "Will ignore field '{}' which is not valid in {} "
90 "inputBinding".format(k, t["class"])))
91 del ib[k]
92
93 visit_class(doc, ("CommandLineTool","Workflow"), rewrite_requirements)
94 visit_class(doc, ("ExpressionTool","Workflow"), fix_inputBinding)
95 visit_field(doc, "secondaryFiles", partial(update_secondaryFiles, top=True))
96
97 upd = doc
98 if isinstance(upd, MutableMapping) and "$graph" in upd:
99 upd = upd["$graph"]
100 for proc in aslist(upd):
101 proc.setdefault("hints", CommentedSeq())
102 proc["hints"].insert(0, CommentedMap([("class", "NetworkAccess"),( "networkAccess", True)]))
103 proc["hints"].insert(0, CommentedMap([("class", "LoadListingRequirement"),("loadListing", "deep_listing")]))
104 if "cwlVersion" in proc:
105 del proc["cwlVersion"]
106
107 return (doc, "v1.1")
108
109 def v1_1_0dev1to1_1(doc, loader, baseuri): # pylint: disable=unused-argument
110 # type: (Any, Loader, Text) -> Tuple[Any, Text]
111 return (doc, "v1.1")
112
113 UPDATES = {
114 u"v1.0": v1_0to1_1,
115 u"v1.1": None
116 } # type: Dict[Text, Optional[Callable[[Any, Loader, Text], Tuple[Any, Text]]]]
117
118 DEVUPDATES = {
119 u"v1.0": v1_0to1_1,
120 u"v1.1.0-dev1": v1_1_0dev1to1_1,
121 u"v1.1": None
122 } # type: Dict[Text, Optional[Callable[[Any, Loader, Text], Tuple[Any, Text]]]]
123
124 ALLUPDATES = UPDATES.copy()
125 ALLUPDATES.update(DEVUPDATES)
126
127 INTERNAL_VERSION = u"v1.1"
128
129 def identity(doc, loader, baseuri): # pylint: disable=unused-argument
130 # type: (Any, Loader, Text) -> Tuple[Any, Union[Text, Text]]
131 """Default, do-nothing, CWL document upgrade function."""
132 return (doc, doc["cwlVersion"])
133
134
135 def checkversion(doc, # type: Union[CommentedSeq, CommentedMap]
136 metadata, # type: CommentedMap
137 enable_dev # type: bool
138 ):
139 # type: (...) -> Tuple[CommentedMap, Text]
140 """Check the validity of the version of the give CWL document.
141
142 Returns the document and the validated version string.
143 """
144 cdoc = None # type: Optional[CommentedMap]
145 if isinstance(doc, CommentedSeq):
146 if not isinstance(metadata, CommentedMap):
147 raise Exception("Expected metadata to be CommentedMap")
148 lc = metadata.lc
149 metadata = copy.deepcopy(metadata)
150 metadata.lc.data = copy.copy(lc.data)
151 metadata.lc.filename = lc.filename
152 metadata[u"$graph"] = doc
153 cdoc = metadata
154 elif isinstance(doc, CommentedMap):
155 cdoc = doc
156 else:
157 raise Exception("Expected CommentedMap or CommentedSeq")
158
159 version = metadata[u"cwlVersion"]
160 cdoc["cwlVersion"] = version
161
162 if version not in UPDATES:
163 if version in DEVUPDATES:
164 if enable_dev:
165 pass
166 else:
167 keys = list(UPDATES.keys())
168 keys.sort()
169 raise validate.ValidationException(
170 u"Version '%s' is a development or deprecated version.\n "
171 "Update your document to a stable version (%s) or use "
172 "--enable-dev to enable support for development and "
173 "deprecated versions." % (version, ", ".join(keys)))
174 else:
175 raise validate.ValidationException(
176 u"Unrecognized version %s" % version)
177
178 return (cdoc, version)
179
180
181 def update(doc, loader, baseuri, enable_dev, metadata):
182 # type: (Union[CommentedSeq, CommentedMap], Loader, Text, bool, Any) -> CommentedMap
183
184 if isinstance(doc, CommentedMap):
185 if metadata.get("http://commonwl.org/cwltool#original_cwlVersion") \
186 or doc.get("http://commonwl.org/cwltool#original_cwlVersion"):
187 return doc
188
189 (cdoc, version) = checkversion(doc, metadata, enable_dev)
190 originalversion = copy.copy(version)
191
192 nextupdate = identity # type: Optional[Callable[[Any, Loader, Text], Tuple[Any, Text]]]
193
194 while nextupdate:
195 (cdoc, version) = nextupdate(cdoc, loader, baseuri)
196 nextupdate = ALLUPDATES[version]
197
198 cdoc[u"cwlVersion"] = version
199 metadata[u"cwlVersion"] = version
200 metadata[u"http://commonwl.org/cwltool#original_cwlVersion"] = originalversion
201 cdoc[u"http://commonwl.org/cwltool#original_cwlVersion"] = originalversion
202
203 return cdoc