|
35 | 35 | aslist,
|
36 | 36 | )
|
37 | 37 | from .workflow_job import WorkflowJob
|
| 38 | +from cwl_utils import expression |
38 | 39 |
|
39 | 40 |
|
40 | 41 | def default_make_tool(
|
@@ -156,6 +157,43 @@ def job(
|
156 | 157 | output_callbacks: Optional[OutputCallbackType],
|
157 | 158 | runtimeContext: RuntimeContext,
|
158 | 159 | ) -> JobsGeneratorType:
|
| 160 | + # TODO: This is not very efficient and could be improved. |
| 161 | + # |
| 162 | + # See issue #1330. We needed to eager-load the requirements |
| 163 | + # at the workflow level, so that it was not re-evaluated at |
| 164 | + # each step level (since a command-line tool, for instance, |
| 165 | + # won't have the inputs from args, but instead will have the |
| 166 | + # empty/default inputs of a workflow step). |
| 167 | + # |
| 168 | + # The solution below evaluates the requirements and hints for |
| 169 | + # the workflow, for each step of the workflow, and for the |
| 170 | + # embedded tool (command-line or expression tools) of each |
| 171 | + # step. |
| 172 | + # |
| 173 | + # This prevents evaluation at the step level (i.e. the values |
| 174 | + # were already loaded earlier/eagerly). |
| 175 | + def _fix_hints_and_requirements( |
| 176 | + hints_or_requirements: List[CWLObjectType], |
| 177 | + ) -> None: |
| 178 | + for hint_or_requirement in hints_or_requirements: |
| 179 | + for key, value in hint_or_requirement.items(): |
| 180 | + hint_or_requirement[key] = expression.do_eval( |
| 181 | + ex=value, |
| 182 | + jobinput=job_order, |
| 183 | + requirements=self.requirements, |
| 184 | + outdir=runtimeContext.outdir, |
| 185 | + tmpdir=runtimeContext.tmpdir, |
| 186 | + resources={}, |
| 187 | + context=None, |
| 188 | + timeout=runtimeContext.eval_timeout, |
| 189 | + ) |
| 190 | + |
| 191 | + for key in ["hints", "requirements"]: |
| 192 | + _fix_hints_and_requirements(getattr(self, key)) |
| 193 | + for step in self.steps: |
| 194 | + _fix_hints_and_requirements(getattr(step, key)) |
| 195 | + _fix_hints_and_requirements(getattr(step.embedded_tool, key)) |
| 196 | + |
159 | 197 | builder = self._init_job(job_order, runtimeContext)
|
160 | 198 |
|
161 | 199 | if runtimeContext.research_obj is not None:
|
|
0 commit comments