From 2b8df110d0fad7c874c35c3176bf18d65cbcdbe3 Mon Sep 17 00:00:00 2001 From: John Chilton Date: Tue, 30 Jan 2018 10:20:54 -0500 Subject: [PATCH] Apply rename PJA to collection outputs including $ replacements. Update PJA collection test to test HDCA is renamed also. --- lib/galaxy/jobs/actions/post.py | 24 ++++++++++++++++++++++++ lib/galaxy/workflow/modules.py | 18 ++++++++++++++---- test/api/test_workflows.py | 5 +++++ 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/lib/galaxy/jobs/actions/post.py b/lib/galaxy/jobs/actions/post.py index 18e3c0c1e78..5536c1d1bd5 100644 --- a/lib/galaxy/jobs/actions/post.py +++ b/lib/galaxy/jobs/actions/post.py @@ -85,6 +85,20 @@ class RenameDatasetAction(DefaultJobAction): name = "RenameDatasetAction" verbose_name = "Rename Dataset" + @classmethod + def execute_on_mapped_over(cls, app, sa_session, action, step_outputs, replacement_dict): + # Prevent renaming a dataset to the empty string. + if action.action_arguments and action.action_arguments.get('newname', ''): + new_name = action.action_arguments['newname'] + + if replacement_dict: + for k, v in replacement_dict.items(): + new_name = new_name.replace("${%s}" % k, v) + + for name, step_output in step_outputs.items(): + if action.output_name == '' or name == action.output_name: + step_output.name = new_name + @classmethod def execute(cls, app, sa_session, action, job, replacement_dict): # Prevent renaming a dataset to the empty string. @@ -380,8 +394,13 @@ class ActionBox(object): 'ColumnSetAction', 'EmailAction', 'DeleteIntermediatesAction', 'TagDatasetAction', 'RemoveTagDatasetAction'] + # Actions that can be applied ahead of the job execution while workflow is still + # being scheduled and jobs created. immediate_actions = ['ChangeDatatypeAction', 'RenameDatasetAction', 'TagDatasetAction', 'RemoveTagDatasetAction'] + # Actions that will be applied to implicit mapped over collection outputs and not + # just individual outputs when steps include mapped over tools and implicit collection outputs. + mapped_over_output_actions = ['RenameDatasetAction'] @classmethod def get_short_str(cls, action): @@ -412,6 +431,11 @@ class ActionBox(object): pass return npd + @classmethod + def execute_on_mapped_over(cls, app, sa_session, pja, step_outputs, replacement_dict=None): + if pja.action_type in ActionBox.actions: + ActionBox.actions[pja.action_type].execute_on_mapped_over(app, sa_session, pja, step_outputs, replacement_dict) + @classmethod def execute(cls, app, sa_session, pja, job, replacement_dict=None): if pja.action_type in ActionBox.actions: diff --git a/lib/galaxy/workflow/modules.py b/lib/galaxy/workflow/modules.py index 863761d8c23..dabd99ea428 100644 --- a/lib/galaxy/workflow/modules.py +++ b/lib/galaxy/workflow/modules.py @@ -932,7 +932,7 @@ class ToolModule(WorkflowModule): step_outputs = dict(execution_tracker.output_datasets) step_outputs.update(execution_tracker.output_collections) progress.set_step_outputs(invocation_step, step_outputs, already_persisted=not invocation_step.is_new) - + self._handle_mapped_over_post_job_actions(step, step_outputs, invocation.replacement_dict) if execution_tracker.execution_errors: message = "Failed to create one or more job(s) for workflow step." raise Exception(message) @@ -971,6 +971,18 @@ class ToolModule(WorkflowModule): visit_input_values(tool.inputs, step.state.inputs, callback) return collections_to_match + def _effective_post_job_actions(self, step): + effective_post_job_actions = step.post_job_actions[:] + for key, value in self.runtime_post_job_actions.items(): + effective_post_job_actions.append(self.__to_pja(key, value, None)) + return effective_post_job_actions + + def _handle_mapped_over_post_job_actions(self, step, step_outputs, replacement_dict): + effective_post_job_actions = self._effective_post_job_actions(step) + for pja in effective_post_job_actions: + if pja.action_type in ActionBox.immediate_actions: + ActionBox.execute_on_mapped_over(self.trans.app, self.trans.sa_session, pja, step_outputs, replacement_dict) + def _handle_post_job_actions(self, step, job, replacement_dict): # Create new PJA associations with the created job, to be run on completion. # PJA Parameter Replacement (only applies to immediate actions-- rename specifically, for now) @@ -979,9 +991,7 @@ class ToolModule(WorkflowModule): # Combine workflow and runtime post job actions into the effective post # job actions for this execution. flush_required = False - effective_post_job_actions = step.post_job_actions[:] - for key, value in self.runtime_post_job_actions.items(): - effective_post_job_actions.append(self.__to_pja(key, value, None)) + effective_post_job_actions = self._effective_post_job_actions(step) for pja in effective_post_job_actions: if pja.action_type in ActionBox.immediate_actions: ActionBox.execute(self.trans.app, self.trans.sa_session, pja, job, replacement_dict) diff --git a/test/api/test_workflows.py b/test/api/test_workflows.py index 3cadfea5e4d..020074dc48e 100644 --- a/test/api/test_workflows.py +++ b/test/api/test_workflows.py @@ -2029,6 +2029,11 @@ test_data: content = self.dataset_populator.get_history_dataset_details(history_id, hid=4, wait=True, assert_ok=True) name = content["name"] assert name == "my new name", name + assert content["history_content_type"] == "dataset" + content = self.dataset_populator.get_history_collection_details(history_id, hid=3, wait=True, assert_ok=True) + name = content["name"] + assert content["history_content_type"] == "dataset_collection", content + assert name == "my new name", name @skip_without_tool("create_2") def test_run_rename_multiple_outputs(self):