diff --git a/lib/galaxy/tools/cwl/parser.py b/lib/galaxy/tools/cwl/parser.py
index 195fdf28e5ed..db8501083704 100644
--- a/lib/galaxy/tools/cwl/parser.py
+++ b/lib/galaxy/tools/cwl/parser.py
@@ -28,7 +28,7 @@
JOB_JSON_FILE = ".cwl_job.json"
SECONDARY_FILES_EXTRA_PREFIX = "__secondary_files__"
-
+DOCKER_REQUIREMENT = "DockerRequirement"
SUPPORTED_TOOL_REQUIREMENTS = [
"CreateFileRequirement",
"DockerRequirement",
@@ -71,10 +71,14 @@ def load_job_proxy(job_directory, strict_cwl_validation=True):
def to_cwl_tool_object(tool_path, strict_cwl_validation=True):
proxy_class = None
cwl_tool = _schema_loader(strict_cwl_validation).tool(path=tool_path)
+
if isinstance(cwl_tool, int):
raise Exception("Failed to load tool.")
raw_tool = cwl_tool.tool
+ # Apply Galaxy hacks to CWL tool representation to bridge semantic differences
+ # between Galaxy and cwltool.
+ _hack_cwl_requirements(cwl_tool)
check_requirements(raw_tool)
if "class" not in raw_tool:
raise Exception("File does not declare a class, not a valid Draft 3+ CWL tool.")
@@ -107,6 +111,22 @@ def _schema_loader(strict_cwl_validation):
return target_schema_loader
+def _hack_cwl_requirements(cwl_tool):
+ raw_tool = cwl_tool.tool
+ if "requirements" in raw_tool:
+ requirements = raw_tool["requirements"]
+ move_to_hint = None
+ for i, r in enumerate(requirements):
+ if r["class"] == DOCKER_REQUIREMENT:
+ move_to_hint = i
+ if move_to_hint is not None:
+ hint = requirements.pop(move_to_hint)
+ if "hints" not in raw_tool:
+ raw_tool["hints"] = []
+ raw_tool["hints"].append(hint)
+ cwl_tool.requirements = raw_tool.get("requirements", [])
+
+
def check_requirements(rec, tool=True):
if isinstance(rec, dict):
if "requirements" in rec:
@@ -246,7 +266,10 @@ def _ensure_cwl_job_initialized(self):
self._output_callback,
basedir=self._job_directory,
select_resources=self._select_resources,
- use_container=False
+ outdir=os.path.join(self._job_directory, "cwloutput"),
+ tmpdir=os.path.join(self._job_directory, "cwltmp"),
+ stagedir=os.path.join(self._job_directory, "cwlstagedir"),
+ use_container=False,
))
self._is_command_line_job = hasattr(self._cwl_job, "command_line")
diff --git a/test/base/populators.py b/test/base/populators.py
index a948c95e321c..7bf85b67fb1c 100644
--- a/test/base/populators.py
+++ b/test/base/populators.py
@@ -69,7 +69,8 @@ def replacement_item(value):
if type_class != "File":
return value
- file_path = value.get("path", None)
+ # TODO: Dispatch on draft 3 vs v1.0+ tools here in the future.
+ file_path = value.get("path", None) or value.get("location", None)
if file_path is None:
return value
@@ -243,8 +244,13 @@ def upload_path(path):
run_response = self.run_tool( tool_id, job_as_dict, history_id, inputs_representation="cwl", assert_ok=assert_ok )
run_object = CwlToolRun( history_id, run_response )
if assert_ok:
- final_state = self.wait_for_job( run_object.job_id )
- assert final_state == "ok"
+ try:
+ final_state = self.wait_for_job( run_object.job_id )
+ assert final_state == "ok"
+ except Exception:
+ self._summarize_history_errors( history_id )
+ raise
+
return run_object
def get_history_dataset_content( self, history_id, wait=True, **kwds ):
diff --git a/test/functional/tools/samples_tool_conf.xml b/test/functional/tools/samples_tool_conf.xml
index ec799374bc9f..054047c5ba78 100644
--- a/test/functional/tools/samples_tool_conf.xml
+++ b/test/functional/tools/samples_tool_conf.xml
@@ -137,6 +137,8 @@
+
+