Skip to content

Commit

Permalink
Allow the WDL output section to reference itself (#4592)
Browse files Browse the repository at this point in the history
* Make decls be able to reference the previous ones in the output

* Disable kubernetes on CI for now

---------

Co-authored-by: Adam Novak <[email protected]>
  • Loading branch information
stxue1 and adamnovak authored Sep 18, 2023
1 parent 33c850e commit ca1b9ce
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions src/toil/wdl/wdltoil.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,25 @@ def unpack_toil_uri(toil_uri: str) -> Tuple[FileID, str]:

return file_id, file_basename

def evaluate_output_decls(output_decls: List[WDL.Tree.Decl], all_bindings: WDL.Env.Bindings[WDL.Value.Base], standard_library: WDL.StdLib.Base) -> WDL.Env.Bindings[WDL.Value.Base]:
"""
Evaluate output decls with a given bindings environment and standard library.
Creates a new bindings object that only contains the bindings from the given decls.
Guarantees that each decl in `output_decls` can access the variables defined by the previous ones.
:param all_bindings: Environment to use when evaluating decls
:param output_decls: Decls to evaluate
:param standard_library: Standard library
:return: New bindings object with only the output_decls
"""
# all_bindings contains output + previous bindings so that the output can reference its own declarations
# output_bindings only contains the output bindings themselves so that bindings from sections such as the input aren't included
output_bindings: WDL.Env.Bindings[WDL.Value.Base] = WDL.Env.Bindings()
for output_decl in output_decls:
output_value = evaluate_decl(output_decl, all_bindings, standard_library)
all_bindings = all_bindings.bind(output_decl.name, output_value)
output_bindings = output_bindings.bind(output_decl.name, output_value)
return output_bindings

class NonDownloadingSize(WDL.StdLib._Size):
"""
WDL size() implementation that avoids downloading files.
Expand Down Expand Up @@ -1437,9 +1456,7 @@ def patched_run_invocation(*args: Any, **kwargs: Any) -> List[str]:
# objects, and like MiniWDL we can say we only support
# working-directory-based relative paths for globs.
outputs_library = ToilWDLStdLibTaskOutputs(file_store, host_stdout_txt, host_stderr_txt, current_directory_override=workdir_in_container)
output_bindings: WDLBindings = WDL.Env.Bindings()
for output_decl in self._task.outputs:
output_bindings = output_bindings.bind(output_decl.name, evaluate_decl(output_decl, bindings, outputs_library))
output_bindings = evaluate_output_decls(self._task.outputs, bindings, outputs_library)

# Drop any files from the output which don't actually exist
output_bindings = drop_missing_files(output_bindings, current_directory_override=workdir_in_container)
Expand Down Expand Up @@ -2265,9 +2282,9 @@ def run(self, file_store: AbstractFileStore) -> WDLBindings:

# Evaluate all the outputs in the normal, non-task-outputs library context
standard_library = ToilWDLStdLibBase(file_store)
output_bindings: WDL.Env.Bindings[WDL.Value.Base] = WDL.Env.Bindings()
for output_decl in self._outputs:
output_bindings = output_bindings.bind(output_decl.name, evaluate_decl(output_decl, unwrap(self._bindings), standard_library))
# Combine the bindings from the previous job

output_bindings = evaluate_output_decls(self._outputs, unwrap(self._bindings), standard_library)

return self.postprocess(output_bindings)

Expand Down

0 comments on commit ca1b9ce

Please sign in to comment.