diff --git a/lib/galaxy/tools/actions/__init__.py b/lib/galaxy/tools/actions/__init__.py
index 17f64e88f5f..ada7bd8a67d 100644
--- a/lib/galaxy/tools/actions/__init__.py
+++ b/lib/galaxy/tools/actions/__init__.py
@@ -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):
diff --git a/lib/galaxy/tools/evaluation.py b/lib/galaxy/tools/evaluation.py
index 582f20b019a..075107a51e7 100644
--- a/lib/galaxy/tools/evaluation.py
+++ b/lib/galaxy/tools/evaluation.py
@@ -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):
diff --git a/lib/galaxy/tools/parameters/wrapped.py b/lib/galaxy/tools/parameters/wrapped.py
index c93b69e065b..f35555bad13 100644
--- a/lib/galaxy/tools/parameters/wrapped.py
+++ b/lib/galaxy/tools/parameters/wrapped.py
@@ -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):
diff --git a/lib/galaxy/tools/wrappers.py b/lib/galaxy/tools/wrappers.py
index 1ff41a5eb29..31e3314ea3b 100644
--- a/lib/galaxy/tools/wrappers.py
+++ b/lib/galaxy/tools/wrappers.py
@@ -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
diff --git a/test/api/test_tools.py b/test/api/test_tools.py
index 0dcfe546bac..8846c4dcbc2 100644
--- a/test/api/test_tools.py
+++ b/test/api/test_tools.py
@@ -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()
diff --git a/test/functional/tools/identifier_in_actions.xml b/test/functional/tools/identifier_in_actions.xml
new file mode 100644
index 00000000000..ecccf112a47
--- /dev/null
+++ b/test/functional/tools/identifier_in_actions.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/functional/tools/samples_tool_conf.xml b/test/functional/tools/samples_tool_conf.xml
index 18e55f282f1..acd9d9dd730 100644
--- a/test/functional/tools/samples_tool_conf.xml
+++ b/test/functional/tools/samples_tool_conf.xml
@@ -91,6 +91,7 @@
+