Skip to content

Commit cd1ba3d

Browse files
authored
Merge pull request #987 from common-workflow-language/schema_salad_upgrade
upgrade to latest schema_salad; misc cleanups
2 parents b82ce7a + 12f2821 commit cd1ba3d

File tree

9 files changed

+75
-63
lines changed

9 files changed

+75
-63
lines changed

Makefile

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ endif
4343

4444
## all : default task
4545
all:
46-
./setup.py develop
46+
pip install -e .
4747

4848
## help : print this help message and exit
4949
help: Makefile
@@ -89,9 +89,11 @@ pep8: pycodestyle
8989
pycodestyle: $(PYSOURCES)
9090
pycodestyle --exclude=_version.py --show-source --show-pep8 $^ || true
9191

92+
pep8_report.txt: pycodestyle_report.txt
9293
pycodestyle_report.txt: $(PYSOURCES)
9394
pycodestyle --exclude=_version.py $^ > $@ || true
9495

96+
diff_pep8_report: diff_pycodestyle_report
9597
diff_pycodestyle_report: pycodestyle_report.txt
9698
diff-quality --violations=pycodestyle $^
9799

@@ -101,7 +103,7 @@ pydocstyle: $(PYSOURCES)
101103
pydocstyle --ignore=D100,D101,D102,D103 $^ || true
102104

103105
pydocstyle_report.txt: $(PYSOURCES)
104-
pydocstyle setup.py $^ > pydocstyle_report.txt 2>&1 || true
106+
pydocstyle setup.py $^ > $@ 2>&1 || true
105107

106108
diff_pydocstyle_report: pydocstyle_report.txt
107109
diff-quality --violations=pycodestyle $^
@@ -122,7 +124,7 @@ pylint: $(PYSOURCES)
122124

123125
pylint_report.txt: ${PYSOURCES}
124126
pylint --msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}" \
125-
$^ -j$(nproc)> pylint_report.txt || true
127+
$^ -j$(nproc)> $@ || true
126128

127129
diff_pylint_report: pylint_report.txt
128130
diff-quality --violations=pylint pylint_report.txt
@@ -139,6 +141,10 @@ coverage.html: htmlcov/index.html
139141

140142
htmlcov/index.html: .coverage
141143
coverage html
144+
@echo Test coverage of the Python code is now in htmlcov/index.html
145+
146+
coverage-report: .coverage
147+
coverage report
142148

143149
diff-cover: coverage.xml
144150
diff-cover $^
@@ -155,7 +161,7 @@ testcov: $(pysources)
155161
python setup.py test --addopts "--cov cwltool -n$(nproc) --dist=loadfile"
156162

157163
sloccount.sc: ${PYSOURCES} Makefile
158-
sloccount --duplicates --wide --details $^ > sloccount.sc
164+
sloccount --duplicates --wide --details $^ > $@
159165

160166
## sloccount : count lines of code
161167
sloccount: ${PYSOURCES} Makefile
@@ -165,7 +171,6 @@ list-author-emails:
165171
@echo 'name, E-Mail Address'
166172
@git log --format='%aN,%aE' | sort -u | grep -v 'root'
167173

168-
169174
mypy2: ${PYSOURCES}
170175
rm -Rf typeshed/2and3/ruamel/yaml
171176
ln -s $(shell python -c 'from __future__ import print_function; import ruamel.yaml; import os.path; print(os.path.dirname(ruamel.yaml.__file__))') \
@@ -187,9 +192,11 @@ mypy3: ${PYSOURCES}
187192
MYPYPATH=$$MYPYPATH:typeshed/3:typeshed/2and3 mypy --disallow-untyped-calls \
188193
--warn-redundant-casts \
189194
cwltool
190-
191-
release: FORCE
195+
release-test: FORCE
196+
git diff-index --quiet HEAD -- || ( echo You have uncommited changes, please commit them and try again; false )
192197
./release-test.sh
198+
199+
release: release-test
193200
. testenv2/bin/activate && \
194201
testenv2/src/${MODULE}/setup.py sdist bdist_wheel && \
195202
pip install twine && \

cwltool/builder.py

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
from rdflib.namespace import OWL, RDFS
1010
from ruamel.yaml.comments import CommentedMap
1111
from schema_salad import validate
12-
from schema_salad.schema import AvroSchemaFromJSONData, Names
12+
from schema_salad.schema import Names, convert_to_dict
13+
from schema_salad.avro.schema import make_avsc_object, Schema
1314
from schema_salad.sourceline import SourceLine
1415
from six import iteritems, string_types
1516
from typing_extensions import (TYPE_CHECKING, # pylint: disable=unused-import
@@ -109,27 +110,27 @@ def get_requirement(self,
109110

110111
class Builder(HasReqsHints):
111112
def __init__(self,
112-
job, # type: Dict[Text, Union[Dict[Text, Any], List, Text, None]]
113-
files, # type: List[Dict[Text, Text]]
114-
bindings, # type: List[Dict[Text, Any]]
115-
schemaDefs, # type: Dict[Text, Dict[Text, Any]]
116-
names, # type: Names
117-
requirements, # type: List[Dict[Text, Any]]
118-
hints, # type: List[Dict[Text, Any]]
119-
resources, # type: Dict[str, int]
120-
mutation_manager, # type: Optional[MutationManager]
121-
formatgraph, # type: Optional[Graph]
122-
make_fs_access, # type: Type[StdFsAccess]
123-
fs_access, # type: StdFsAccess
124-
job_script_provider, # type: Optional[Any]
125-
timeout, # type: float
126-
debug, # type: bool
127-
js_console, # type: bool
128-
force_docker_pull, # type: bool
129-
loadListing, # type: Text
130-
outdir, # type: Text
131-
tmpdir, # type: Text
132-
stagedir, # type: Text
113+
job, # type: Dict[Text, Union[Dict[Text, Any], List, Text, None]]
114+
files, # type: List[Dict[Text, Text]]
115+
bindings, # type: List[Dict[Text, Any]]
116+
schemaDefs, # type: Dict[Text, Dict[Text, Any]]
117+
names, # type: Names
118+
requirements, # type: List[Dict[Text, Any]]
119+
hints, # type: List[Dict[Text, Any]]
120+
resources, # type: Dict[str, int]
121+
mutation_manager, # type: Optional[MutationManager]
122+
formatgraph, # type: Optional[Graph]
123+
make_fs_access, # type: Type[StdFsAccess]
124+
fs_access, # type: StdFsAccess
125+
job_script_provider, # type: Optional[Any]
126+
timeout, # type: float
127+
debug, # type: bool
128+
js_console, # type: bool
129+
force_docker_pull, # type: bool
130+
loadListing, # type: Text
131+
outdir, # type: Text
132+
tmpdir, # type: Text
133+
stagedir, # type: Text
133134
): # type: (...) -> None
134135

135136
self.job = job
@@ -208,12 +209,14 @@ def bind_input(self,
208209
if isinstance(schema["type"], MutableSequence):
209210
bound_input = False
210211
for t in schema["type"]:
212+
avsc = None # type: Optional[Schema]
211213
if isinstance(t, string_types) and self.names.has_name(t, ""):
212214
avsc = self.names.get_name(t, "")
213215
elif isinstance(t, MutableMapping) and "name" in t and self.names.has_name(t["name"], ""):
214216
avsc = self.names.get_name(t["name"], "")
215-
else:
216-
avsc = AvroSchemaFromJSONData(t, self.names)
217+
if not avsc:
218+
avsc = make_avsc_object(convert_to_dict(t), self.names)
219+
assert avsc is not None
217220
if validate.validate(avsc, datum):
218221
schema = copy.deepcopy(schema)
219222
schema["type"] = t

cwltool/command_line_tool.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import shellescape
1919
from schema_salad import validate
20+
from schema_salad.avro.schema import Schema
2021
from schema_salad.ref_resolver import file_uri, uri_file_path
2122
from schema_salad.sourceline import SourceLine
2223
from six import string_types
@@ -612,17 +613,17 @@ def makeWorkflowException(msg):
612613

613614
if compute_checksum:
614615
adjustFileObjs(ret, partial(compute_checksums, fs_access))
615-
616-
validate.validate_ex(
617-
self.names.get_name("outputs_record_schema", ""), ret,
616+
expected_schema = cast(Schema, self.names.get_name(
617+
"outputs_record_schema", ""))
618+
validate.validate_ex(expected_schema, ret,
618619
strict=False, logger=_logger_validation_warnings)
619620
if ret is not None and builder.mutation_manager is not None:
620621
adjustFileObjs(ret, builder.mutation_manager.set_generation)
621622
return ret if ret is not None else {}
622623
except validate.ValidationException as e:
623624
raise WorkflowException(
624-
"Error validating output record. " + Text(e) + "\n in " +
625-
json_dumps(ret, indent=4))
625+
"Error validating output record. " + Text(e) + "\n in "
626+
+ json_dumps(ret, indent=4))
626627
finally:
627628
if builder.mutation_manager and readers:
628629
for r in readers.values():

cwltool/process.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -470,12 +470,8 @@ def __init__(self,
470470
SCHEMA_DIR = cast(Dict[Text, Any],
471471
SCHEMA_CACHE["v1.0"][3].idx["https://w3id.org/cwl/cwl#Directory"])
472472

473-
names = schema.make_avro_schema([SCHEMA_FILE, SCHEMA_DIR, SCHEMA_ANY],
474-
Loader({}))[0]
475-
if isinstance(names, schema.SchemaParseException):
476-
raise names
477-
else:
478-
self.names = names
473+
self.names = schema.make_avro_schema([SCHEMA_FILE, SCHEMA_DIR, SCHEMA_ANY],
474+
Loader({}))
479475
self.tool = toolpath_object
480476
self.requirements = copy.deepcopy(getdefault(loadingContext.requirements, []))
481477
self.requirements.extend(self.tool.get("requirements", []))
@@ -506,7 +502,7 @@ def __init__(self,
506502
av = schema.make_valid_avro(sdtypes, {t["name"]: t for t in avroize_type(sdtypes)}, set())
507503
for i in av:
508504
self.schemaDefs[i["name"]] = i # type: ignore
509-
schema.AvroSchemaFromJSONData(av, self.names) # type: ignore
505+
schema.make_avsc_object(schema.convert_to_dict(av), self.names)
510506

511507
# Build record schema from inputs
512508
self.inputs_record_schema = {
@@ -542,12 +538,14 @@ def __init__(self,
542538
self.inputs_record_schema = cast(
543539
Dict[Text, Any], schema.make_valid_avro(
544540
self.inputs_record_schema, {}, set()))
545-
schema.AvroSchemaFromJSONData(self.inputs_record_schema, self.names)
541+
schema.make_avsc_object(
542+
schema.convert_to_dict(self.inputs_record_schema), self.names)
546543
with SourceLine(toolpath_object, "outputs", validate.ValidationException):
547544
self.outputs_record_schema = cast(
548545
Dict[Text, Any],
549546
schema.make_valid_avro(self.outputs_record_schema, {}, set()))
550-
schema.AvroSchemaFromJSONData(self.outputs_record_schema, self.names)
547+
schema.make_avsc_object(
548+
schema.convert_to_dict(self.outputs_record_schema), self.names)
551549

552550
if toolpath_object.get("class") is not None \
553551
and not getdefault(loadingContext.disable_js_validation, False):
@@ -601,8 +599,12 @@ def _init_job(self, joborder, runtime_context):
601599
try:
602600
fill_in_defaults(self.tool[u"inputs"], job, fs_access)
603601
normalizeFilesDirs(job)
604-
validate.validate_ex(self.names.get_name("input_record_schema", ""),
605-
job, strict=False, logger=_logger_validation_warnings)
602+
schema = self.names.get_name("input_record_schema", "")
603+
if schema is None:
604+
raise WorkflowException("Missing input record schema: "
605+
"{}".format(self.names))
606+
validate.validate_ex(schema, job, strict=False,
607+
logger=_logger_validation_warnings)
606608
except (validate.ValidationException, WorkflowException) as err:
607609
raise WorkflowException("Invalid job input record:\n" + Text(err))
608610

@@ -643,10 +645,10 @@ def _init_job(self, joborder, runtime_context):
643645
prefix=getdefault(runtime_context.tmp_outdir_prefix,
644646
DEFAULT_TMP_PREFIX)))
645647
if self.tool[u"class"] != 'Workflow':
646-
tmpdir = fs_access.realpath(runtime_context.tmpdir or
647-
tempfile.mkdtemp())
648-
stagedir = fs_access.realpath(runtime_context.stagedir or
649-
tempfile.mkdtemp())
648+
tmpdir = fs_access.realpath(runtime_context.tmpdir
649+
or tempfile.mkdtemp())
650+
stagedir = fs_access.realpath(runtime_context.stagedir
651+
or tempfile.mkdtemp())
650652

651653
builder = Builder(job,
652654
files,

cwltool/provenance.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,7 @@ def finalize_prov_profile(self, name):
934934
self.document.serialize(provenance_file, format="rdf", rdf_format="json-ld")
935935
prov_ids.append(self.provenance_ns[filename + ".jsonld"])
936936

937-
_logger.debug("[provenance] added provenance: %s", prov_ids)
937+
_logger.debug(u"[provenance] added provenance: %s", prov_ids)
938938
return prov_ids
939939

940940

cwltool/validate_js.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@
66
from typing import (Any, Dict, List, MutableMapping, MutableSequence, Optional,
77
Tuple, Union)
88

9-
import avro.schema # always import after schema_salad, never before
109
from pkg_resources import resource_stream
1110
from ruamel.yaml.comments import CommentedMap # pylint: disable=unused-import
12-
from schema_salad.sourceline import SourceLine
13-
from schema_salad.validate import Schema # pylint: disable=unused-import
14-
from schema_salad.validate import ValidationException, validate_ex
1511
from six import string_types
1612
from typing_extensions import Text # pylint: disable=unused-import
17-
# move to a regular typing import when Python 3.3-3.6 is no longer supported
13+
from schema_salad import avro
14+
from schema_salad.sourceline import SourceLine
15+
from schema_salad.validate import Schema # pylint: disable=unused-import
16+
from schema_salad.validate import validate_ex
1817

1918
from .expression import scanner as scan_expression
2019
from .loghandler import _logger
@@ -60,8 +59,8 @@ def get_expressions(tool, # type: Union[CommentedMap, Any]
6059
if not isinstance(tool, MutableSequence):
6160
return []
6261

63-
return list(itertools.chain(*
64-
map(lambda x: get_expressions(x[1], schema.items, SourceLine(tool, x[0])), enumerate(tool)) # type: ignore # https://github.com/python/mypy/issues/4679
62+
return list(itertools.chain(
63+
*map(lambda x: get_expressions(x[1], schema.items, SourceLine(tool, x[0])), enumerate(tool)) # type: ignore # https://github.com/python/mypy/issues/4679
6564
))
6665

6766
elif isinstance(schema, avro.schema.RecordSchema):
@@ -166,7 +165,7 @@ def validate_js_expressions(tool, schema, jshint_options=None):
166165

167166
default_globals = [u"self", u"inputs", u"runtime", u"console"]
168167

169-
for i, prop in enumerate(reversed(requirements)):
168+
for prop in reversed(requirements):
170169
if prop["class"] == "InlineJavascriptRequirement":
171170
expression_lib = prop.get("expressionLib", [])
172171
break

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ requests>=2.4.3
22
ruamel.yaml>=0.12.4,<=0.15.77
33
rdflib>=4.2.2,<4.3
44
shellescape>=3.4.1,<3.5
5-
schema-salad>=2.7.20180905124720,<3
5+
schema-salad>=2.8,<3
66
typing>=3.5.3; python_version<"3.6"
77
pathlib2==2.3.2; python_version<"3"
88
prov==1.5.1

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
'ruamel.yaml >= 0.12.4, <= 0.15.77',
5454
'rdflib >= 4.2.2, < 4.3.0',
5555
'shellescape >= 3.4.1, < 3.5',
56-
'schema-salad >= 2.7.20180905124720, < 3',
56+
'schema-salad >= 2.8, < 3',
5757
'mypy-extensions',
5858
'six >= 1.9.0', # >= 1.9.0 required by prov
5959
'psutil',

tests/test_provenance.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def folder():
5151

5252
def cwltool(folder, *args):
5353
load_tool.loaders = {}
54-
new_args = ['--no-container', '--provenance', folder]
54+
new_args = ['--provenance', folder]
5555
new_args.extend(args)
5656
# Run within a temporary directory to not pollute git checkout
5757
with temp_dir("cwltool-run") as tmp_dir:

0 commit comments

Comments
 (0)