Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/cwltool/update.py @ 0:d30785e31577 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
| author | guerler |
|---|---|
| date | Fri, 31 Jul 2020 00:18:57 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:d30785e31577 |
|---|---|
| 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 |
