Bug fix - expose proper element_identifier in tool action template expansions. (#5049)

xref https://github.com/galaxyproject/tools-iuc/commit/f57f1bf4816f212b83c08e0e3c3782ebba8b7d9a
This commit is contained in:
John Chilton
2017-11-20 23:11:00 +01:00
committed by Björn Grüning
parent 59e9809585
commit a7c8edbaa4
7 changed files with 95 additions and 15 deletions
+3 -3
View File
@@ -257,7 +257,7 @@ class DefaultToolAction(object):
# Add the dbkey to the incoming parameters
incoming["dbkey"] = input_dbkey
# wrapped params are used by change_format action and by output.label; only perform this wrapping once, as needed
wrapped_params = self._wrapped_params(trans, tool, incoming)
wrapped_params = self._wrapped_params(trans, tool, incoming, inp_data)
out_data = odict()
input_collections = dict((k, v[0][0]) for k, v in inp_dataset_collections.items())
@@ -514,8 +514,8 @@ class DefaultToolAction(object):
trans.log_event("Added job to the job queue, id: %s" % str(job.id), tool_id=job.tool_id)
return job, out_data
def _wrapped_params(self, trans, tool, incoming):
wrapped_params = WrappedParameters(trans, tool, incoming)
def _wrapped_params(self, trans, tool, incoming, input_datasets=None):
wrapped_params = WrappedParameters(trans, tool, incoming, input_datasets=input_datasets)
return wrapped_params
def _get_on_text(self, inp_data):
+5 -6
View File
@@ -26,6 +26,7 @@ from galaxy.tools.wrappers import (
DatasetCollectionWrapper,
DatasetFilenameWrapper,
DatasetListWrapper,
ElementIdentifierMapper,
InputValueWrapper,
RawObjectWrapper,
SelectToolParameterWrapper,
@@ -234,11 +235,9 @@ class ToolEvaluator(object):
real_path = dataset.file_name
if real_path in input_dataset_paths:
wrapper_kwds["dataset_path"] = input_dataset_paths[real_path]
identifier_key = identifier_key_dict.get(dataset, None)
if identifier_key:
element_identifier = param_dict.get(identifier_key, None)
if element_identifier:
wrapper_kwds["identifier"] = element_identifier
element_identifier = element_identifier_mapper.identifier(dataset, param_dict)
if element_identifier:
wrapper_kwds["identifier"] = element_identifier
input_values[input.name] = \
DatasetFilenameWrapper(dataset, **wrapper_kwds)
elif isinstance(input, DataCollectionToolParameter):
@@ -266,7 +265,7 @@ class ToolEvaluator(object):
# tools where the inputs don't even get passed through. These
# tools (e.g. UCSC) should really be handled in a special way.
if self.tool.check_values:
identifier_key_dict = dict((v, "%s|__identifier__" % k) for k, v in input_datasets.items()) # allows lookup of identifier through HDA.
element_identifier_mapper = ElementIdentifierMapper(input_datasets)
self.__walk_inputs(self.tool.inputs, param_dict, wrap_input)
def __populate_input_dataset_wrappers(self, param_dict, input_datasets, input_dataset_paths):
+15 -6
View File
@@ -12,6 +12,7 @@ from galaxy.tools.wrappers import (
DatasetCollectionWrapper,
DatasetFilenameWrapper,
DatasetListWrapper,
ElementIdentifierMapper,
InputValueWrapper,
SelectToolParameterWrapper
)
@@ -21,11 +22,12 @@ PARAMS_UNWRAPPED = object()
class WrappedParameters(object):
def __init__(self, trans, tool, incoming):
def __init__(self, trans, tool, incoming, input_datasets=None):
self.trans = trans
self.tool = tool
self.incoming = incoming
self._params = PARAMS_UNWRAPPED
self._input_datasets = input_datasets
@property
def params(self):
@@ -40,6 +42,8 @@ class WrappedParameters(object):
tool = self.tool
incoming = self.incoming
element_identifier_mapper = ElementIdentifierMapper(self._input_datasets)
# Wrap tool inputs as necessary
for input in inputs.values():
if input.name not in input_values and skip_missing_values:
@@ -64,11 +68,16 @@ class WrappedParameters(object):
tool=tool,
name=input.name)
elif isinstance(input, DataToolParameter):
input_values[input.name] = \
DatasetFilenameWrapper(value,
datatypes_registry=trans.app.datatypes_registry,
tool=tool,
name=input.name)
wrapper_kwds = dict(
datatypes_registry=trans.app.datatypes_registry,
tool=tool,
name=input.name
)
element_identifier = element_identifier_mapper.identifier(value, input_values)
if element_identifier:
wrapper_kwds["identifier"] = element_identifier
input_values[input.name] = DatasetFilenameWrapper(value, **wrapper_kwds)
elif isinstance(input, SelectToolParameter):
input_values[input.name] = SelectToolParameterWrapper(input, input_values[input.name], other_values=incoming)
elif isinstance(input, DataCollectionToolParameter):
+18
View File
@@ -430,3 +430,21 @@ class DatasetCollectionWrapper(ToolParameterValueWrapper, HasDatasets):
# not specified or if resulting collection is empty.
return self.__input_supplied and bool(self.__element_instance_list)
__nonzero__ = __bool__
class ElementIdentifierMapper(object):
"""Track mapping of dataset collection elements datasets to element identifiers."""
def __init__(self, input_datasets=None):
if input_datasets is not None:
self.identifier_key_dict = dict((v, "%s|__identifier__" % k) for k, v in input_datasets.items())
else:
self.identifier_key_dict = {}
def identifier(self, dataset_value, input_values):
identifier_key = self.identifier_key_dict.get(dataset_value, None)
element_identifier = None
if identifier_key:
element_identifier = input_values.get(identifier_key, None)
return element_identifier
+30
View File
@@ -978,6 +978,36 @@ class ToolsTestCase(api.ApiTestCase):
output1_content = self.dataset_populator.get_history_dataset_content(history_id, dataset=output1)
self.assertEquals(output1_content.strip(), '\n'.join([d['name'] for d in element_identifiers]))
@skip_without_tool("identifier_in_actions")
def test_identifier_in_actions(self):
history_id = self.dataset_populator.new_history()
element_identifiers = self.dataset_collection_populator.list_identifiers(history_id, contents=["1\t2"])
payload = dict(
instance_type="history",
history_id=history_id,
element_identifiers=json.dumps(element_identifiers),
collection_type="list",
)
create_response = self._post("dataset_collections", payload)
dataset_collection = create_response.json()
inputs = {
"input": {'batch': True, 'values': [{'src': 'hdca', 'id': dataset_collection['id']}]},
}
self.dataset_populator.wait_for_history(history_id, assert_ok=True)
create_response = self._run("identifier_in_actions", history_id, inputs)
self._assert_status_code_is(create_response, 200)
create = create_response.json()
outputs = create['outputs']
output1 = outputs[0]
output_details = self.dataset_populator.get_history_dataset_details(history_id, dataset=output1)
assert output_details["metadata_column_names"][1] == "data1", output_details
@skip_without_tool("cat1")
def test_map_over_nested_collections(self):
history_id = self.dataset_populator.new_history()
@@ -0,0 +1,23 @@
<tool id="identifier_in_actions" name="identifier_in_actions" version="1.0.0">
<command><![CDATA[
cp '$input' '$output'
]]></command>
<inputs>
<param name="input" type="data" multiple="false" />
</inputs>
<outputs>
<data format="tabular" name="output">
<actions>
<action name="column_names" type="metadata" default="First,${input.element_identifier}" />
</actions>
</data>
</outputs>
<tests>
<test>
<param name="input" value="2.tabular" />
<output name="output">
<metadata name="column_names" value="First,2.tabular"/>
</output>
</test>
</tests>
</tool>
@@ -91,6 +91,7 @@
<tool file="identifier_multiple_in_conditional.xml" />
<tool file="identifier_multiple_in_repeat.xml" />
<tool file="identifier_collection.xml" />
<tool file="identifier_in_actions.xml" />
<tool file="tool_directory.xml" />
<tool file="output_action_change_format.xml" />
<tool file="collection_paired_test.xml" />