From 96718bc123b9dc556ad1a56d476bf3da2804dc77 Mon Sep 17 00:00:00 2001 From: Michael Franklin Date: Fri, 22 Jan 2021 15:48:47 +1100 Subject: [PATCH] Add support for CWL output operator with 1 wildcard selector --- janis_core/operators/operator.py | 2 +- janis_core/translations/cwl.py | 116 +++++++++++++++++++------------ 2 files changed, 73 insertions(+), 45 deletions(-) diff --git a/janis_core/operators/operator.py b/janis_core/operators/operator.py index f06c459d8..7c019abc1 100644 --- a/janis_core/operators/operator.py +++ b/janis_core/operators/operator.py @@ -177,7 +177,7 @@ def to_wdl(self, unwrap_operator, *args): return f"{base}[{index}]" def to_cwl(self, unwrap_operator, *args): - base, index = self.args + base, index = [unwrap_operator(a) for a in self.args] return f"{base}[{index}]" diff --git a/janis_core/translations/cwl.py b/janis_core/translations/cwl.py index 688dc0a22..4a6d4be5c 100644 --- a/janis_core/translations/cwl.py +++ b/janis_core/translations/cwl.py @@ -957,9 +957,10 @@ def unwrap_expression( inputs_dict=inputs_dict, ) elif isinstance(value, WildcardSelector): - raise Exception( - f"A wildcard selector cannot be used as an argument value for '{debugkwargs}'" - ) + return "self" + # raise Exception( + # f"A wildcard selector cannot be used as an argument value for '{debugkwargs}'" + # ) elif isinstance(value, Operator): unwrap_expression_wrap = lambda exp: CwlTranslator.unwrap_expression( exp, @@ -1308,13 +1309,17 @@ def prepare_tool_output_binding( loadcontents = requires_content(output.selector) requires_std = has_std(output.selector) - return cwlgen.CommandOutputBinding( - glob=[STDOUT_NAME, STDERR_NAME] + glob, value_from = ( + [STDOUT_NAME, STDERR_NAME] if requires_std else translate_to_cwl_glob( output.selector, inputsdict, outputtag=output.tag, tool=tool, **debugkwargs - ), - outputEval=prepare_tool_output_eval(tool, output), + ) + ) + + return cwlgen.CommandOutputBinding( + glob=glob, + outputEval=value_from or prepare_tool_output_eval(tool, output), loadContents=loadcontents, ) @@ -1328,12 +1333,6 @@ def prepare_tool_output_eval(tool, output: ToolOutput) -> Optional[str]: :return: """ - if isinstance(output.selector, Operator): - return None - return CwlTranslator.unwrap_expression( - output.selector, code_environment=False, tool=tool, for_output=True - ) - if output.presents_as: return f"""\ ${{ @@ -1341,6 +1340,11 @@ def prepare_tool_output_eval(tool, output: ToolOutput) -> Optional[str]: return self $}} """ + if isinstance(output.selector, Operator): + return None + return CwlTranslator.unwrap_expression( + output.selector, code_environment=False, tool=tool, for_output=True + ) return None @@ -1868,17 +1872,18 @@ def translate_to_cwl_glob(glob, inputsdict, tool, **debugkwargs): return None if isinstance(glob, list): - return [ - translate_to_cwl_glob(g, inputsdict=inputsdict, tool=tool, **debugkwargs) - for g in glob - ] + return ( + [ + translate_to_cwl_glob( + g, inputsdict=inputsdict, tool=tool, **debugkwargs + )[0] + for g in glob + ], + None, + ) if not isinstance(glob, Selector): - Logger.critical( - "String globs are being phased out from tool output selections, please use the provided " - "Selector (InputSelector or WildcardSelector) classes. " + str(debugkwargs) - ) - return glob + return glob, None if isinstance(glob, InputSelector): @@ -1893,46 +1898,69 @@ def translate_to_cwl_glob(glob, inputsdict, tool, **debugkwargs): intype = tinp.input_type if isinstance(intype, Filename): if isinstance(intype.prefix, Selector): - return intype.generated_filename( - replacements={ - "prefix": CwlTranslator.unwrap_expression( - intype.prefix, - inputs_dict=inputsdict, - for_output=True, - code_environment=False, - ) - } + return ( + intype.generated_filename( + replacements={ + "prefix": CwlTranslator.unwrap_expression( + intype.prefix, + inputs_dict=inputsdict, + for_output=True, + code_environment=False, + ) + } + ), + None, ) else: - return intype.generated_filename() + return intype.generated_filename(), None expr = glob if tinp.default: expr = If(IsDefined(glob), expr, tinp.default) - return CwlTranslator.unwrap_expression( - expr, - inputs_dict=inputsdict, - code_environment=False, - for_output=True, - **debugkwargs, + return ( + CwlTranslator.unwrap_expression( + expr, + inputs_dict=inputsdict, + code_environment=False, + for_output=True, + **debugkwargs, + ), + None, ) elif isinstance(glob, StringFormatter): - return translate_string_formatter(glob, None, tool=tool) + return translate_string_formatter(glob, None, tool=tool), None elif isinstance(glob, WildcardSelector): - return glob.wildcard + return glob.wildcard, None if isinstance(glob, Operator): # It's not terribly hard to do this, we'd have to change the output_eval # to use a combination of the presents_as AND - if any(isinstance(o, WildcardSelector) for o in glob.get_leaves()): + + wild_card_selectors = [ + o for o in glob.get_leaves() if isinstance(o, WildcardSelector) + ] + value_from = None + if len(wild_card_selectors) > 1: raise Exception( - f"Janis does NOT currently support operations on the output glob for output '{glob}' in tool '{tool.id()}'" + f"Janis only supports operating on 1 output glob, where this output had {len(wild_card_selectors)} on " + f"the output glob for output '{glob}' in tool '{tool.id()}'" ) - return CwlTranslator.unwrap_expression( - glob, code_environment=False, inputs_dict=inputsdict, **debugkwargs + elif len(wild_card_selectors) == 1: + value_from = CwlTranslator.unwrap_expression( + glob, code_environment=False, inputs_dict=inputsdict, **debugkwargs + ) + glob = wild_card_selectors[0].wildcard + + # elif len(wild_card_selectors) == 0: + + return ( + CwlTranslator.unwrap_expression( + glob, code_environment=False, inputs_dict=inputsdict, **debugkwargs + ), + value_from, ) raise Exception("Unimplemented selector type: " + glob.__class__.__name__)