Skip to content

Commit 82c9c65

Browse files
authored
Merge pull request #36 from common-workflow-language/test_etools_to_ctools
Start adding tests for etools_to_clt
2 parents 15330a2 + aa1d0df commit 82c9c65

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2275
-991
lines changed
File renamed without changes.

.travis.yml

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,37 @@
1-
language: python
2-
matrix:
3-
include:
4-
- env: TARGET=py3
5-
- env: TARGET=pep8
6-
- env: TARGET=mypy
7-
allow_failures:
8-
- env: TARGET=pep8
9-
- env: TARGET=mypy
1+
dist: xenial
102
services:
11-
- docker
3+
- docker
4+
5+
before_install:
6+
- wget -O- http://neuro.debian.net/lists/xenial.us-nh.full | sudo tee /etc/apt/sources.list.d/neurodebian.sources.list
7+
- sudo apt-key add .travis.singularity_key.txt
8+
- sudo apt-get update
9+
- sudo apt-get install -y singularity-container
10+
11+
language: python
12+
cache:
13+
pip: true
14+
directories:
15+
- .mypy_cache
16+
17+
os:
18+
- linux
1219
install:
13-
- true
14-
script:
15-
- docker build --tag ${TARGET} . -f .travis/${TARGET}.docker
16-
- docker run -v /var/run/docker.sock:/var/run/docker.sock ${TARGET} /bin/bash -c "$(cat .travis/${TARGET}.run)"
20+
- pip install tox-travis
21+
jobs:
22+
include:
23+
- stage: test
24+
python: "3.6"
25+
- stage: test
26+
python: "3.7"
27+
- stage: test
28+
python: "3.8"
29+
- stage: test
30+
python: "3.9-dev"
31+
- stage: release-test
32+
python: "3.8"
33+
script: RELEASE_SKIP=head PYVER=3.8 ${TRAVIS_BUILD_DIR}/release-test.sh
34+
script: tox
1735
deploy:
1836
provider: pypi
1937
username: __token__
@@ -24,3 +42,8 @@ deploy:
2442
repo: common-workflow-language/cwl-utils
2543
password:
2644
secure: AZ+PuKZGoc/xK81zvNekgsZ++7NIwgh3Kw9G173aPxxjwfS9KxqqQ/s1qu/hGgvl1nrGrv+hfMYWSoy8iHV0qJ411DWEfWij0p924HEN4iBvMcPOhvvDOQck2YSdPQAAK3Xkt9EYHC6oMNr8dmof366GPqNSEvlxGvAbo1CP//gPM4Awbd84lhLD/6nsp9A1tLL4dVXDw4doWN3Sa8q1obP6Qa7+vuaU+9bG8cfmmJatGYLRYcK7gaMHY4YS3pMZ+uVNlcCjVXC9ywfpR/WiTUnOO/uFPVO+nZtoE0qHUXbtPur91TeROhGAxDSte4NBbnUOOU2ISn3CLT/QDD7s3yBfB5nur+UIdJILH/9h9JZdv+xqa0P30sX878SN00VkrZUoNbSJWthenSy8CWTJrjo64a88Vr8Yl6grk2ctrSHNyN+erPOx6gKayWyJibpekuFKJM2MxvcqehBARcxy+2YRHedDjrfyS/lZPctwjTDKtCn4kJRulqxsbcBY1zYOc814nyEuPF3b3vldVeYV1k0YmLToZ4XxBHVZcJe7YxoWApCQphC2rKNU+snEGKNIOXx1DQkr8u3E/skiE5Fb1SzHLoKf3UsjMrz09jOTIxer3V4O3t3PyjLrGudIiV7nEaVa/4pDzwNNEN0pKJK0AbuPg0EDloRWY0HQxkJAf7M=
45+
branches:
46+
only:
47+
- main
48+
notifications:
49+
email: false

.travis/mypy.docker

Lines changed: 0 additions & 6 deletions
This file was deleted.

.travis/mypy.run

Whitespace-only changes.

.travis/pep8.docker

Lines changed: 0 additions & 6 deletions
This file was deleted.

.travis/pep8.run

Whitespace-only changes.

.travis/py3.docker

Lines changed: 0 additions & 8 deletions
This file was deleted.

.travis/py3.run

Lines changed: 0 additions & 1 deletion
This file was deleted.

Makefile

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# This file is part of cwl-utils,
2+
# https://github.com/common-workflow-language/cwl-utils/, and is
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
17+
18+
# make format to fix most python formatting errors
19+
# make pylint to check Python code for enhanced compliance including naming
20+
# and documentation
21+
# make coverage-report to check coverage of the python scripts by the tests
22+
23+
MODULE=cwl_utils
24+
25+
# `SHELL=bash` doesn't work for some, so don't use BASH-isms like
26+
# `[[` conditional expressions.
27+
PYSOURCES=$(filter-out cwl_utils/parser_v%,$(wildcard ${MODULE}/**.py tests/*.py)) setup.py
28+
DEVPKGS=diff_cover black pylint coverage pep257 pydocstyle flake8 mypy\
29+
isort wheel
30+
DEBDEVPKGS=pep8 python-autopep8 pylint python-coverage pydocstyle sloccount \
31+
python-flake8 python-mock shellcheck
32+
VERSION=$(shell awk '{print $3}' < cwl_utils/__meta__.py )
33+
# VERSION=3.0.$(shell TZ=UTC git log --first-parent --max-count=1 \
34+
# --format=format:%cd --date=format-local:%Y%m%d%H%M%S)
35+
mkfile_dir := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
36+
UNAME_S=$(shell uname -s)
37+
38+
## all : default task
39+
all:
40+
pip install -e .
41+
42+
## help : print this help message and exit
43+
help: Makefile
44+
@sed -n 's/^##//p' $<
45+
46+
## install-dep : install most of the development dependencies via pip
47+
install-dep: install-dependencies
48+
49+
install-dependencies:
50+
pip install --upgrade $(DEVPKGS)
51+
pip install -r requirements.txt
52+
53+
## install-deb-dep: install most of the dev dependencies via apt-get
54+
install-deb-dep:
55+
sudo apt-get install $(DEBDEVPKGS)
56+
57+
## install : install the ${MODULE} module and schema-salad-tool
58+
install: FORCE
59+
pip install .[deps]
60+
61+
## dev : install the ${MODULE} module in dev mode
62+
dev: install-dep
63+
pip install -e .[deps]
64+
65+
66+
## dist : create a module package for distribution
67+
dist: dist/${MODULE}-$(VERSION).tar.gz
68+
69+
dist/${MODULE}-$(VERSION).tar.gz: $(SOURCES)
70+
./setup.py sdist bdist_wheel
71+
72+
## clean : clean up all temporary / machine-generated files
73+
clean: FORCE
74+
rm -f ${MODILE}/*.pyc tests/*.pyc
75+
./setup.py clean --all || true
76+
rm -Rf .coverage
77+
rm -f diff-cover.html
78+
79+
# Linting and code style related targets
80+
## sorting imports using isort: https://github.com/timothycrosley/isort
81+
sort_imports: $(PYSOURCES)
82+
isort $^
83+
84+
pep257: pydocstyle
85+
## pydocstyle : check Python code style
86+
pydocstyle: $(PYSOURCES)
87+
pydocstyle --add-ignore=D100,D101,D102,D103 $^ || true
88+
89+
pydocstyle_report.txt: $(PYSOURCES)
90+
pydocstyle setup.py $^ > $@ 2>&1 || true
91+
92+
diff_pydocstyle_report: pydocstyle_report.txt
93+
diff-quality --compare-branch=main --violations=pydocstyle --fail-under=100 $^
94+
95+
## format : check/fix all code indentation and formatting (runs black)
96+
format: $(PYSOURCES)
97+
black $^
98+
99+
## pylint : run static code analysis on Python code
100+
pylint: $(PYSOURCES)
101+
pylint --msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}" \
102+
$^ -j0|| true
103+
104+
pylint_report.txt: ${PYSOURCES}
105+
pylint --msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}" \
106+
$^ -j0> $@ || true
107+
108+
diff_pylint_report: pylint_report.txt
109+
diff-quality --violations=pylint pylint_report.txt
110+
111+
.coverage: testcov
112+
113+
coverage: .coverage
114+
coverage report
115+
116+
coverage.xml: .coverage
117+
coverage xml
118+
119+
coverage.html: htmlcov/index.html
120+
121+
htmlcov/index.html: .coverage
122+
coverage html
123+
@echo Test coverage of the Python code is now in htmlcov/index.html
124+
125+
coverage-report: .coverage
126+
coverage report
127+
128+
diff-cover: coverage.xml
129+
diff-cover $^
130+
131+
diff-cover.html: coverage.xml
132+
diff-cover $^ --html-report $@
133+
134+
## test : run the ${MODULE} test suite
135+
test: FORCE
136+
python setup.py test # --addopts "-n auto --dist=loadfile"
137+
138+
## testcov : run the ${MODULE} test suite and collect coverage
139+
testcov: $(pysources)
140+
python setup.py test --addopts "--cov ${MODULE}" # -n auto --dist=loadfile"
141+
142+
sloccount.sc: ${PYSOURCES} Makefile
143+
sloccount --duplicates --wide --details $^ > $@
144+
145+
## sloccount : count lines of code
146+
sloccount: ${PYSOURCES} Makefile
147+
sloccount $^
148+
149+
list-author-emails:
150+
@echo 'name, E-Mail Address'
151+
@git log --format='%aN,%aE' | sort -u | grep -v 'root'
152+
153+
mypy3: mypy
154+
mypy: ${PYSOURCES}
155+
if ! test -f $(shell python3 -c 'import ruamel.yaml; import os.path; print(os.path.dirname(ruamel.yaml.__file__))')/py.typed ; \
156+
then \
157+
rm -Rf typeshed/ruamel/yaml ; \
158+
ln -s $(shell python3 -c 'import ruamel.yaml; import os.path; print(os.path.dirname(ruamel.yaml.__file__))') \
159+
typeshed/ruamel/ ; \
160+
fi # if minimally required ruamel.yaml version is 0.15.99 or greater, than the above can be removed
161+
MYPYPATH=$$MYPYPATH:typeshed/ mypy --disallow-untyped-calls \
162+
--warn-redundant-casts \
163+
${MODULE}
164+
165+
mypyc: ${PYSOURCES}
166+
MYPYPATH=typeshed/ CWLTOOL_USE_MYPYC=1 pip install --verbose -e . && pytest --basetemp ./tmp
167+
168+
release-test: FORCE
169+
git diff-index --quiet HEAD -- || ( echo You have uncommited changes, please commit them and try again; false )
170+
./release-test.sh
171+
172+
release: release-test
173+
. testenv2/bin/activate && \
174+
testenv2/src/${MODULE}/setup.py sdist bdist_wheel && \
175+
pip install twine && \
176+
twine upload testenv2/src/${MODULE}/dist/* && \
177+
git tag ${VERSION} && git push --tags
178+
179+
FORCE:
180+
181+
# Use this to print the value of a Makefile variable
182+
# Example `make print-VERSION`
183+
# From https://www.cmcrossroads.com/article/printing-value-makefile-variable
184+
print-% : ; @echo $* = $($*)

cwl_utils/cite_extract.py

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,71 @@
11
#!/usr/bin/env python3
22
import sys
3+
from typing import Iterator, Union, cast
4+
35
import cwl_utils.parser_v1_0 as cwl
46

7+
ProcessType = Union[cwl.Workflow, cwl.CommandLineTool, cwl.ExpressionTool]
8+
59

6-
def main():
10+
def main() -> int:
11+
"""Load the first argument and extract the software requirements."""
712
top = cwl.load_document(sys.argv[1])
813
traverse(top)
14+
return 0
915

1016

11-
def extract_software_packages(process: cwl.Process):
17+
def extract_software_packages(process: ProcessType) -> None:
18+
"""Print software packages found in the given process."""
1219
for req in extract_software_reqs(process):
1320
print(process.id)
1421
process_software_requirement(req)
1522

1623

17-
def extract_software_reqs(process: cwl.Process):
24+
def extract_software_reqs(
25+
process: ProcessType,
26+
) -> Iterator[cwl.SoftwareRequirement]:
27+
"""Return an iterator over any SoftwareRequirements found in the given process."""
1828
if process.requirements:
1929
for req in process.requirements:
2030
if isinstance(req, cwl.SoftwareRequirement):
2131
yield req
2232
if process.hints:
2333
for req in process.hints:
24-
if req['class'] == "SoftwareRequirement":
25-
yield cwl.load_field(req, cwl.SoftwareRequirementLoader,
26-
process.id, process.loadingOptions)
34+
if req["class"] == "SoftwareRequirement":
35+
yield cwl.load_field(
36+
req,
37+
cwl.SoftwareRequirementLoader,
38+
process.id if process.id else "",
39+
process.loadingOptions,
40+
)
2741

2842

29-
def process_software_requirement(req: cwl.SoftwareRequirement):
43+
def process_software_requirement(req: cwl.SoftwareRequirement) -> None:
44+
"""Pretty print the sofware package information."""
3045
for package in req.packages:
31-
print("Package: {}, version: {}, specs: {}".format(
32-
package.package, package.version, package.specs))
46+
print(
47+
"Package: {}, version: {}, specs: {}".format(
48+
package.package, package.version, package.specs
49+
)
50+
)
3351

3452

35-
def traverse(process: cwl.Process):
53+
def traverse(process: ProcessType) -> None:
54+
"""Extract the software packages for this process, and any steps."""
3655
extract_software_packages(process)
3756
if isinstance(process, cwl.Workflow):
3857
traverse_workflow(process)
3958

4059

41-
def get_process_from_step(step: cwl.WorkflowStep):
60+
def get_process_from_step(step: cwl.WorkflowStep) -> ProcessType:
61+
"""Return the process for this step, loading it if needed."""
4262
if isinstance(step.run, str):
43-
return cwl.load_document(step.run)
44-
return step.run
63+
return cast(ProcessType, cwl.load_document(step.run))
64+
return cast(ProcessType, step.run)
4565

4666

47-
def traverse_workflow(workflow: cwl.Workflow):
67+
def traverse_workflow(workflow: cwl.Workflow) -> None:
68+
"""Iterate over the given workflow, extracting the software packages."""
4869
for step in workflow.steps:
4970
extract_software_packages(step)
5071
traverse(get_process_from_step(step))

0 commit comments

Comments
 (0)