Skip to content

Commit 8d72da0

Browse files
authored
Merge pull request #829 from common-workflow-language/windows_fixes
Windows fixes Also normalizes the Factory() interface by removing the use of kwargs
2 parents e4a5268 + a7fca56 commit 8d72da0

File tree

9 files changed

+155
-159
lines changed

9 files changed

+155
-159
lines changed

cwltool/docker.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,26 @@ def _get_docker_machine_mounts(): # type: () -> List[Text]
3636
if 'DOCKER_MACHINE_NAME' not in os.environ:
3737
__docker_machine_mounts = []
3838
else:
39-
__docker_machine_mounts = [u'/' + line.split(None, 1)[0]
40-
for line in subprocess.check_output(
41-
['docker-machine', 'ssh',
42-
os.environ['DOCKER_MACHINE_NAME'],
43-
'mount', '-t', 'vboxsf'],
44-
universal_newlines=True).splitlines()]
39+
__docker_machine_mounts = [
40+
u'/' + line.split(None, 1)[0] for line in
41+
subprocess.check_output(
42+
['docker-machine', 'ssh',
43+
os.environ['DOCKER_MACHINE_NAME'], 'mount', '-t',
44+
'vboxsf'],
45+
universal_newlines=True).splitlines()]
4546
return __docker_machine_mounts
4647

4748
def _check_docker_machine_path(path): # type: (Optional[Text]) -> None
4849
if not path:
4950
return
51+
if onWindows():
52+
path = path.lower()
5053
mounts = _get_docker_machine_mounts()
5154
if mounts:
5255
found = False
5356
for mount in mounts:
57+
if onWindows():
58+
mount = mount.lower()
5459
if path.startswith(mount):
5560
found = True
5661
break
@@ -59,9 +64,11 @@ def _check_docker_machine_path(path): # type: (Optional[Text]) -> None
5964
"Input path {path} is not in the list of host paths mounted "
6065
"into the Docker virtual machine named {name}. Already mounted "
6166
"paths: {mounts}.\n"
62-
"See https://docs.docker.com/toolbox/toolbox_install_windows/#optional-add-shared-directories"
63-
" for instructions on how to add this path to your VM.".format(path=path,
64-
name=os.environ["DOCKER_MACHINE_NAME"], mounts=mounts))
67+
"See https://docs.docker.com/toolbox/toolbox_install_windows/"
68+
"#optional-add-shared-directories for instructions on how to "
69+
"add this path to your VM.".format(
70+
path=path, name=os.environ["DOCKER_MACHINE_NAME"],
71+
mounts=mounts))
6572

6673

6774
class DockerCommandLineJob(ContainerCommandLineJob):

cwltool/factory.py

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from __future__ import absolute_import
22

33
import os
4-
from typing import Callable as tCallable # pylint: disable=unused-import
5-
from typing import (Any, # pylint: disable=unused-import
4+
from typing import Callable as tCallable # pylint: disable=unused-import
5+
from typing import (Any, # pylint: disable=unused-import
66
Dict, Optional, Text, Tuple, Union)
77

88
from . import load_tool
@@ -29,44 +29,34 @@ def __init__(self, t, factory): # type: (Process, Factory) -> None
2929

3030
def __call__(self, **kwargs):
3131
# type: (**Any) -> Union[Text, Dict[Text, Text]]
32-
runtimeContext = self.factory.runtimeContext.copy()
33-
runtimeContext.basedir = os.getcwd()
34-
out, status = self.factory.executor(self.t, kwargs, runtimeContext)
32+
runtime_context = self.factory.runtime_context.copy()
33+
runtime_context.basedir = os.getcwd()
34+
out, status = self.factory.executor(self.t, kwargs, runtime_context)
3535
if status != "success":
3636
raise WorkflowStatus(out, status)
3737
else:
3838
return out
3939

4040
class Factory(object):
4141
def __init__(self,
42-
executor=None, # type: tCallable[...,Tuple[Dict[Text,Any], Text]]
43-
loadingContext=None, # type: LoadingContext
44-
runtimeContext=None, # type: RuntimeContext
45-
**kwargs
42+
executor=None, # type: tCallable[...,Tuple[Dict[Text,Any], Text]]
43+
loading_context=None, # type: LoadingContext
44+
runtime_context=None # type: RuntimeContext
4645
): # type: (...) -> None
4746
if executor is None:
4847
executor = SingleJobExecutor()
4948
self.executor = executor
50-
51-
new_exec_kwargs = get_default_args()
52-
new_exec_kwargs.update(kwargs)
53-
new_exec_kwargs.pop("job_order")
54-
new_exec_kwargs.pop("workflow")
55-
new_exec_kwargs.pop("outdir")
56-
57-
if loadingContext is None:
58-
self.loadingContext = LoadingContext(new_exec_kwargs)
59-
else:
60-
self.loadingContext = loadingContext
61-
62-
if runtimeContext is None:
63-
self.runtimeContext = RuntimeContext(new_exec_kwargs)
49+
self.loading_context = loading_context
50+
if loading_context is None:
51+
self.loading_context = LoadingContext()
52+
if runtime_context is None:
53+
self.runtime_context = RuntimeContext()
6454
else:
65-
self.runtimeContext = runtimeContext
55+
self.runtime_context = runtime_context
6656

6757
def make(self, cwl):
6858
"""Instantiate a CWL object from a CWl document."""
69-
load = load_tool.load_tool(cwl, self.loadingContext)
59+
load = load_tool.load_tool(cwl, self.loading_context)
7060
if isinstance(load, int):
7161
raise Exception("Error loading tool")
7262
return Callable(load, self)

cwltool/main.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -592,12 +592,13 @@ def main(argsl=None, # type: List[str]
592592
conf_file = getattr(args, "beta_dependency_resolvers_configuration", None) # Text
593593
use_conda_dependencies = getattr(args, "beta_conda_dependencies", None) # Text
594594

595-
job_script_provider = None # type: Optional[DependenciesConfiguration]
596595
if conf_file or use_conda_dependencies:
597596
runtimeContext.job_script_provider = DependenciesConfiguration(args)
598597

599-
runtimeContext.find_default_container = \
600-
functools.partial(find_default_container, args)
598+
runtimeContext.find_default_container = functools.partial(
599+
find_default_container,
600+
default_container=runtimeContext.default_container,
601+
use_biocontainers=args.beta_use_biocontainers)
601602
runtimeContext.make_fs_access = getdefault(runtimeContext.make_fs_access, StdFsAccess)
602603
(out, status) = executor(tool,
603604
initialized_job_order_object,
@@ -674,14 +675,14 @@ def loc_to_path(obj):
674675
_logger.addHandler(defaultStreamHandler)
675676

676677

677-
def find_default_container(args, builder):
678-
# type: (argparse.Namespace, HasReqsHints) -> Optional[Text]
679-
default_container = None
680-
if args.default_container:
681-
default_container = args.default_container
682-
elif args.beta_use_biocontainers:
683-
default_container = get_container_from_software_requirements(args, builder)
684-
678+
def find_default_container(builder, # type: HasReqsHints
679+
default_container=None, # type: Text
680+
use_biocontainers=None, # type: bool
681+
): # type: (...) -> Optional[Text]
682+
"""Default finder for default containers."""
683+
if not default_container and use_biocontainers:
684+
default_container = get_container_from_software_requirements(
685+
use_biocontainers, builder)
685686
return default_container
686687

687688

cwltool/software_requirements.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ def get_dependencies(builder):
100100
return ToolRequirements.from_list(dependencies)
101101

102102

103-
def get_container_from_software_requirements(args, builder):
104-
# type: (argparse.Namespace, HasReqsHints) -> Optional[Text]
105-
if args.beta_use_biocontainers:
103+
def get_container_from_software_requirements(use_biocontainers, builder):
104+
# type: (bool, HasReqsHints) -> Optional[Text]
105+
if use_biocontainers:
106106
ensure_galaxy_lib_available()
107107
from galaxy.tools.deps.containers import ContainerRegistry, AppInfo, ToolInfo, DOCKER_CONTAINER_TYPE
108108
app_info = AppInfo(

tests/test_examples.py

Lines changed: 74 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from cwltool.errors import WorkflowException
2020
from cwltool.main import main
2121
from cwltool.utils import onWindows, subprocess
22+
from cwltool.context import RuntimeContext
2223

2324
from .util import (get_data, get_windows_safe_factory, needs_docker,
2425
needs_singularity, windows_needs_docker)
@@ -152,16 +153,21 @@ def test_factory_bad_outputs(self):
152153

153154
def test_default_args(self):
154155
f = cwltool.factory.Factory()
155-
assert f.runtimeContext.use_container is True
156-
assert f.runtimeContext.on_error == "stop"
156+
assert f.runtime_context.use_container is True
157+
assert f.runtime_context.on_error == "stop"
157158

158159
def test_redefined_args(self):
159-
f = cwltool.factory.Factory(use_container=False, on_error="continue")
160-
assert f.runtimeContext.use_container is False
161-
assert f.runtimeContext.on_error == "continue"
160+
runtime_context = RuntimeContext()
161+
runtime_context.use_container = False
162+
runtime_context.on_error = "continue"
163+
f = cwltool.factory.Factory(runtime_context=runtime_context)
164+
assert f.runtime_context.use_container is False
165+
assert f.runtime_context.on_error == "continue"
162166

163167
def test_partial_scatter(self):
164-
f = cwltool.factory.Factory(on_error="continue")
168+
runtime_context = RuntimeContext()
169+
runtime_context.on_error = "continue"
170+
f = cwltool.factory.Factory(runtime_context=runtime_context)
165171
fail = f.make(get_data("tests/wf/scatterfail.cwl"))
166172
try:
167173
fail()
@@ -173,7 +179,9 @@ def test_partial_scatter(self):
173179
self.fail("Should have raised WorkflowStatus")
174180

175181
def test_partial_output(self):
176-
f = cwltool.factory.Factory(on_error="continue")
182+
runtime_context = RuntimeContext()
183+
runtime_context.on_error = "continue"
184+
f = cwltool.factory.Factory(runtime_context=runtime_context)
177185
fail = f.make(get_data("tests/wf/wffail.cwl"))
178186
try:
179187
fail()
@@ -248,36 +256,32 @@ def loadref(base, p):
248256

249257
sc.sort(key=lambda k: k["basename"])
250258

251-
self.assertEquals([{
252-
"basename": "bar.cwl",
253-
"nameroot": "bar",
254-
"class": "File",
255-
"nameext": ".cwl",
256-
"location": "file:///example/bar.cwl"
257-
},
258-
{
259-
"basename": "data.txt",
260-
"nameroot": "data",
261-
"class": "File",
262-
"nameext": ".txt",
263-
"location": "file:///example/data.txt"
264-
},
265-
{
266-
"basename": "data2",
267-
"class": "Directory",
268-
"location": "file:///example/data2",
269-
"listing": [{
270-
"basename": "data3.txt",
271-
"nameroot": "data3",
272-
"class": "File",
273-
"nameext": ".txt",
274-
"location": "file:///example/data3.txt",
275-
"secondaryFiles": [{
276-
"class": "File",
277-
"basename": "data5.txt",
278-
"location": "file:///example/data5.txt",
279-
"nameext": ".txt",
280-
"nameroot": "data5"
259+
self.assertEquals([
260+
{"basename": "bar.cwl",
261+
"nameroot": "bar",
262+
"class": "File",
263+
"nameext": ".cwl",
264+
"location": "file:///example/bar.cwl"},
265+
{"basename": "data.txt",
266+
"nameroot": "data",
267+
"class": "File",
268+
"nameext": ".txt",
269+
"location": "file:///example/data.txt"},
270+
{"basename": "data2",
271+
"class": "Directory",
272+
"location": "file:///example/data2",
273+
"listing": [
274+
{"basename": "data3.txt",
275+
"nameroot": "data3",
276+
"class": "File",
277+
"nameext": ".txt",
278+
"location": "file:///example/data3.txt",
279+
"secondaryFiles": [
280+
{"class": "File",
281+
"basename": "data5.txt",
282+
"location": "file:///example/data5.txt",
283+
"nameext": ".txt",
284+
"nameroot": "data5"
281285
}]
282286
}]
283287
}, {
@@ -313,39 +317,27 @@ def test_trick_scandeps(self):
313317

314318
class TestDedup(unittest.TestCase):
315319
def test_dedup(self):
316-
ex = [{
317-
"class": "File",
318-
"location": "file:///example/a"
319-
},
320-
{
321-
"class": "File",
322-
"location": "file:///example/a"
323-
},
324-
{
325-
"class": "File",
326-
"location": "file:///example/d"
327-
},
328-
{
329-
"class": "Directory",
330-
"location": "file:///example/c",
331-
"listing": [{
332-
"class": "File",
333-
"location": "file:///example/d"
334-
}]
335-
}]
336-
337-
self.assertEquals([{
338-
"class": "File",
339-
"location": "file:///example/a"
340-
},
341-
{
342-
"class": "Directory",
343-
"location": "file:///example/c",
344-
"listing": [{
345-
"class": "File",
346-
"location": "file:///example/d"
347-
}]
348-
}], cwltool.pathmapper.dedup(ex))
320+
ex = [{"class": "File",
321+
"location": "file:///example/a"},
322+
{"class": "File",
323+
"location": "file:///example/a"},
324+
{"class": "File",
325+
"location": "file:///example/d"},
326+
{"class": "Directory",
327+
"location": "file:///example/c",
328+
"listing": [
329+
{"class": "File",
330+
"location": "file:///example/d"}]}]
331+
332+
self.assertEquals([
333+
{"class": "File",
334+
"location": "file:///example/a"},
335+
{"class": "Directory",
336+
"location": "file:///example/c",
337+
"listing": [
338+
{"class": "File",
339+
"location": "file:///example/d"}]}],
340+
cwltool.pathmapper.dedup(ex))
349341

350342

351343
class TestTypeCompare(unittest.TestCase):
@@ -623,11 +615,9 @@ def test_print_dot(self):
623615

624616
class TestCmdLine(unittest.TestCase):
625617
def get_main_output(self, new_args):
626-
process = subprocess.Popen([
627-
sys.executable,
628-
"-m",
629-
"cwltool"
630-
] + new_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
618+
process = subprocess.Popen(
619+
[sys.executable, "-m", "cwltool"] + new_args,
620+
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
631621

632622
stdout, stderr = process.communicate()
633623
return process.returncode, stdout.decode(), stderr.decode()
@@ -684,15 +674,15 @@ def test_issue_740_fixed(self):
684674
class TestChecksum(TestCmdLine):
685675

686676
def test_compute_checksum(self):
687-
f = cwltool.factory.Factory(compute_checksum=True,
688-
use_container=onWindows())
677+
runtime_context = RuntimeContext()
678+
runtime_context.compute_checksum = True
679+
runtime_context.use_container = onWindows()
680+
f = cwltool.factory.Factory(runtime_context=runtime_context)
689681
echo = f.make(get_data("tests/wf/cat-tool.cwl"))
690-
output = echo(file1={
691-
"class": "File",
692-
"location": get_data("tests/wf/whale.txt")
693-
},
694-
reverse=False
695-
)
682+
output = echo(
683+
file1={"class": "File",
684+
"location": get_data("tests/wf/whale.txt")},
685+
reverse=False)
696686
self.assertEquals(output['output']["checksum"], "sha1$327fc7aedf4f6b69a42a7c8b808dc5a7aff61376")
697687

698688
def test_no_compute_checksum(self):
@@ -721,5 +711,6 @@ def test_singularity_workflow(self):
721711
self.assertIn("completed success", stderr)
722712
self.assertEquals(error_code, 0)
723713

714+
724715
if __name__ == '__main__':
725716
unittest.main()

0 commit comments

Comments
 (0)