mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge branch 'release_26.0' into dev
This commit is contained in:
@@ -3478,7 +3478,9 @@ class ExpressionTool(Tool):
|
||||
output.extension if output.extension not in ("data", "expression.json") else copy_object.extension
|
||||
)
|
||||
require_metadata_regeneration = copy_object.extension != new_ext
|
||||
visible = output.visible
|
||||
output.copy_from(copy_object, include_metadata=not require_metadata_regeneration)
|
||||
output.visible = visible
|
||||
output.extension = new_ext
|
||||
if require_metadata_regeneration:
|
||||
if app.config.enable_celery_tasks:
|
||||
|
||||
@@ -38,7 +38,7 @@ from .grouping import (
|
||||
)
|
||||
from .workflow_utils import (
|
||||
is_runtime_value,
|
||||
NO_REPLACEMENT,
|
||||
NoReplacement,
|
||||
runtime_to_json,
|
||||
)
|
||||
from .wrapped import flat_to_nested_state
|
||||
@@ -184,33 +184,33 @@ def visit_input_values(
|
||||
new_value = callback(**args)
|
||||
|
||||
# is this good enough ? feels very ugh
|
||||
if new_value == [no_replacement_value]:
|
||||
if isinstance(new_value, list) and len(new_value) == 1 and isinstance(new_value[0], NoReplacement):
|
||||
# Single unspecified value in multiple="true" input with a single null input, pretend it's a singular value
|
||||
new_value = no_replacement_value
|
||||
if isinstance(new_value, list):
|
||||
# Maybe mixed input, I guess tool defaults don't really make sense here ?
|
||||
# Would e.g. be default dataset in multiple="true" input, you wouldn't expect the default to be inserted
|
||||
# if other inputs are connected and provided.
|
||||
new_value = [item if not item == no_replacement_value else None for item in new_value]
|
||||
new_value = [item if not isinstance(item, NoReplacement) else None for item in new_value]
|
||||
|
||||
if no_replacement_value is REPLACE_ON_TRUTHY:
|
||||
replace = bool(new_value)
|
||||
else:
|
||||
replace = new_value != no_replacement_value
|
||||
replace = not isinstance(new_value, NoReplacement) and new_value != no_replacement_value
|
||||
if replace:
|
||||
input_values[input.name] = new_value
|
||||
elif replace_optional_connections:
|
||||
# Only used in workflow context
|
||||
has_default = hasattr(input, "value")
|
||||
if new_value is value is NO_REPLACEMENT or is_runtime_value(value):
|
||||
# NO_REPLACEMENT means value was connected but left unspecified
|
||||
if has_default:
|
||||
# Use default if we have one
|
||||
# Only used in workflow context.
|
||||
# If we reach here the callback returned no_replacement_value,
|
||||
# meaning the connected step did not produce a value (e.g. an
|
||||
# omitted optional parameter_input). Only replace sentinel
|
||||
# values (ConnectedValue, RuntimeValue, NO_REPLACEMENT) with
|
||||
# the tool parameter's own default — preserve valid tool-state
|
||||
# values for unconnected inputs.
|
||||
if isinstance(value, NoReplacement) or is_runtime_value(value):
|
||||
if hasattr(input, "value"):
|
||||
input_values[input.name] = input.value
|
||||
else:
|
||||
# Should fail if input is not optional and does not have default value
|
||||
# Effectively however depends on parameter implementation.
|
||||
# We might want to raise an exception here, instead of depending on a tool parameter value error.
|
||||
input_values[input.name] = None
|
||||
|
||||
def get_current_case(input, input_values):
|
||||
|
||||
@@ -732,13 +732,19 @@ class DatasetsService(ServiceBase, UsesVisualizationMixin):
|
||||
"""
|
||||
hda = self.hda_manager.get_accessible(history_content_id, trans.user)
|
||||
self.hda_manager.ensure_dataset_on_disk(trans, hda)
|
||||
file_ext = hda.metadata.spec.get(metadata_file).get("file_ext", metadata_file)
|
||||
metadata_spec = hda.metadata.spec.get(metadata_file)
|
||||
if metadata_spec is None:
|
||||
raise galaxy_exceptions.RequestParameterInvalidException(f"Unknown metadata file: {metadata_file}")
|
||||
file_ext = metadata_spec.get("file_ext", metadata_file)
|
||||
fname = "".join(c in util.FILENAME_VALID_CHARS and c or "_" for c in hda.name)[0:150]
|
||||
headers = {}
|
||||
headers["Content-Type"] = "application/octet-stream"
|
||||
headers["Content-Disposition"] = f'attachment; filename="Galaxy{hda.hid}-[{fname}].{file_ext}"'
|
||||
mf = hda.metadata.get(metadata_file)
|
||||
assert mf
|
||||
if mf is None:
|
||||
raise galaxy_exceptions.RequestParameterInvalidException(
|
||||
f"Metadata file {metadata_file} is not set for this dataset"
|
||||
)
|
||||
file_path = mf.get_file_name()
|
||||
if open_file:
|
||||
return open(file_path, "rb"), headers
|
||||
|
||||
@@ -9577,6 +9577,56 @@ steps:
|
||||
len(copied_collections_with_tags) > 0
|
||||
), f"Should find copied collection with tags {collection_tags} in new history"
|
||||
|
||||
def test_pick_value_output_visible_with_hidden_inputs(self):
|
||||
"""Test that pick_value output doesn't inherit hidden state from inputs."""
|
||||
with self.dataset_populator.test_history() as history_id:
|
||||
summary = self._run_workflow(
|
||||
"""class: GalaxyWorkflow
|
||||
inputs:
|
||||
input_dataset:
|
||||
type: data
|
||||
outputs:
|
||||
pick_out:
|
||||
outputSource: pick_value/data_param
|
||||
steps:
|
||||
cat_skipped:
|
||||
tool_id: cat1
|
||||
in:
|
||||
input1: input_dataset
|
||||
when: $(false)
|
||||
pick_value:
|
||||
tool_id: pick_value
|
||||
tool_state:
|
||||
style_cond:
|
||||
pick_style: first
|
||||
type_cond:
|
||||
param_type: data
|
||||
pick_from:
|
||||
- __index__: 0
|
||||
value:
|
||||
__class__: RuntimeValue
|
||||
- __index__: 1
|
||||
value:
|
||||
__class__: RuntimeValue
|
||||
in:
|
||||
style_cond|type_cond|pick_from_0|value:
|
||||
source: cat_skipped/out_file1
|
||||
style_cond|type_cond|pick_from_1|value:
|
||||
source: input_dataset
|
||||
""",
|
||||
test_data="""input_dataset:
|
||||
value: 1.bed
|
||||
type: File
|
||||
""",
|
||||
history_id=history_id,
|
||||
)
|
||||
invocation_details = self.workflow_populator.get_invocation(summary.invocation_id, step_details=True)
|
||||
pick_value_hda = invocation_details["outputs"]["pick_out"]
|
||||
dataset_details = self.dataset_populator.get_history_dataset_details(
|
||||
history_id=history_id, content_id=pick_value_hda["id"]
|
||||
)
|
||||
assert dataset_details["visible"], "pick_value output should be visible even when inputs are hidden"
|
||||
|
||||
|
||||
class TestAdminWorkflowsApi(BaseWorkflowsApiTestCase):
|
||||
require_admin_user = True
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
- doc: |
|
||||
Test that omitting an optional text parameter connected to an expression
|
||||
tool that converts text to boolean produces false, correctly skipping
|
||||
the conditional downstream step.
|
||||
job:
|
||||
required_input:
|
||||
type: File
|
||||
value: 1.fasta
|
||||
outputs:
|
||||
out:
|
||||
asserts:
|
||||
has_text:
|
||||
text: "null"
|
||||
- doc: |
|
||||
Test that providing an optional text parameter connected to an expression
|
||||
tool that converts text to boolean produces true, so the conditional
|
||||
downstream step runs.
|
||||
job:
|
||||
required_input:
|
||||
type: File
|
||||
value: 1.fasta
|
||||
optional_text: some_value
|
||||
outputs:
|
||||
out:
|
||||
asserts:
|
||||
has_size:
|
||||
min: 1
|
||||
@@ -0,0 +1,29 @@
|
||||
class: GalaxyWorkflow
|
||||
doc: |
|
||||
Test that an omitted optional text parameter connected to an expression
|
||||
tool (text→boolean conversion, like map_param_value) produces false,
|
||||
allowing conditional (when) steps to be correctly skipped.
|
||||
Regression test for https://github.com/galaxyproject/iwc/pull/1128
|
||||
inputs:
|
||||
required_input:
|
||||
type: data
|
||||
optional_text:
|
||||
type: text
|
||||
optional: true
|
||||
outputs:
|
||||
out:
|
||||
outputSource: cat/out_file1
|
||||
steps:
|
||||
text_to_bool:
|
||||
tool_id: expression_text_to_bool
|
||||
in:
|
||||
text_input:
|
||||
source: optional_text
|
||||
cat:
|
||||
tool_id: cat
|
||||
in:
|
||||
input1:
|
||||
source: required_input
|
||||
when:
|
||||
source: text_to_bool/bool_out
|
||||
when: $(inputs.when)
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -6,7 +6,6 @@ classifiers =
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
Intended Audience :: Science/Research
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -5,7 +5,6 @@ classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Environment :: Console
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Operating System :: POSIX
|
||||
Programming Language :: Python :: 3
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<tool name="expression_text_to_bool" id="expression_text_to_bool" version="0.1.0" tool_type="expression">
|
||||
<expression type="ecma5.1">
|
||||
{
|
||||
var value = $job.text_input;
|
||||
if (value == "false" || value == "False") {
|
||||
return {'bool_out': false};
|
||||
}
|
||||
return {'bool_out': !!value};
|
||||
}
|
||||
</expression>
|
||||
<inputs>
|
||||
<param type="text" label="Text input." name="text_input" />
|
||||
</inputs>
|
||||
<outputs>
|
||||
<output type="boolean" name="bool_out" from="bool_out" />
|
||||
</outputs>
|
||||
<tests>
|
||||
<test>
|
||||
<param name="text_input" value="hello" />
|
||||
<output name="bool_out" value_json="true" />
|
||||
</test>
|
||||
<test>
|
||||
<param name="text_input" value="" />
|
||||
<output name="bool_out" value_json="false" />
|
||||
</test>
|
||||
</tests>
|
||||
</tool>
|
||||
@@ -230,6 +230,7 @@
|
||||
<tool file="expression_null_handling_integer.xml" />
|
||||
<tool file="expression_null_handling_float.xml" />
|
||||
<tool file="expression_null_handling_text.xml" />
|
||||
<tool file="expression_text_to_bool.xml" />
|
||||
<tool file="cheetah_casting.xml" />
|
||||
<tool file="cheetah_problem_unbound_var.xml" />
|
||||
<tool file="cheetah_problem_unbound_var_input.xml" />
|
||||
|
||||
Reference in New Issue
Block a user