mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge branch 'release_22.05' into dev
This commit is contained in:
@@ -581,6 +581,7 @@ class WorkflowContentsManager(UsesAnnotations):
|
||||
source=None,
|
||||
add_to_menu=False,
|
||||
hidden=False,
|
||||
is_subworkflow=False,
|
||||
):
|
||||
data = raw_workflow_description.as_dict
|
||||
# Put parameters in workflow mode
|
||||
@@ -600,6 +601,7 @@ class WorkflowContentsManager(UsesAnnotations):
|
||||
raw_workflow_description,
|
||||
workflow_create_options,
|
||||
name=name,
|
||||
is_subworkflow=is_subworkflow,
|
||||
)
|
||||
if "uuid" in data:
|
||||
workflow.uuid = data["uuid"]
|
||||
@@ -689,7 +691,7 @@ class WorkflowContentsManager(UsesAnnotations):
|
||||
return workflow, errors
|
||||
|
||||
def _workflow_from_raw_description(
|
||||
self, trans, raw_workflow_description, workflow_state_resolution_options, name, **kwds
|
||||
self, trans, raw_workflow_description, workflow_state_resolution_options, name, is_subworkflow=False, **kwds
|
||||
):
|
||||
# don't commit the workflow or attach its part to the sa session - just build a
|
||||
# a transient model to operate on or render.
|
||||
@@ -764,8 +766,12 @@ class WorkflowContentsManager(UsesAnnotations):
|
||||
# Second pass to deal with connections between steps
|
||||
self.__connect_workflow_steps(steps, steps_by_external_id, dry_run)
|
||||
|
||||
# Order the steps if possible
|
||||
attach_ordered_steps(workflow, steps)
|
||||
workflow.has_cycles = True
|
||||
workflow.steps = steps
|
||||
# we can't reorder subworkflows, as step connections would become invalid
|
||||
if not is_subworkflow:
|
||||
# Order the steps if possible
|
||||
attach_ordered_steps(workflow)
|
||||
|
||||
return workflow, missing_tool_tups
|
||||
|
||||
@@ -857,7 +863,7 @@ class WorkflowContentsManager(UsesAnnotations):
|
||||
"""
|
||||
if len(workflow.steps) == 0:
|
||||
raise exceptions.MessageException("Workflow cannot be run because it does not have any steps.")
|
||||
if attach_ordered_steps(workflow, workflow.steps):
|
||||
if attach_ordered_steps(workflow):
|
||||
raise exceptions.MessageException("Workflow cannot be run because it contains cycles.")
|
||||
trans.workflow_building_mode = workflow_building_modes.USE_HISTORY
|
||||
module_injector = WorkflowModuleInjector(trans)
|
||||
@@ -950,7 +956,7 @@ class WorkflowContentsManager(UsesAnnotations):
|
||||
"""
|
||||
if len(workflow.steps) == 0:
|
||||
raise exceptions.MessageException("Workflow cannot be run because it does not have any steps.")
|
||||
if attach_ordered_steps(workflow, workflow.steps):
|
||||
if attach_ordered_steps(workflow):
|
||||
raise exceptions.MessageException("Workflow cannot be run because it contains cycles.")
|
||||
|
||||
# Ensure that the user has a history
|
||||
@@ -1652,6 +1658,7 @@ class WorkflowContentsManager(UsesAnnotations):
|
||||
steps.append(step)
|
||||
external_id = step_dict["id"]
|
||||
steps_by_external_id[external_id] = step
|
||||
step.order_index = external_id
|
||||
if "workflow_outputs" in step_dict:
|
||||
workflow_outputs = step_dict["workflow_outputs"]
|
||||
found_output_names = set()
|
||||
@@ -1718,7 +1725,11 @@ class WorkflowContentsManager(UsesAnnotations):
|
||||
def __build_embedded_subworkflow(self, trans, data, workflow_state_resolution_options):
|
||||
raw_workflow_description = self.ensure_raw_description(data)
|
||||
subworkflow = self.build_workflow_from_raw_description(
|
||||
trans, raw_workflow_description, workflow_state_resolution_options, hidden=True
|
||||
trans,
|
||||
raw_workflow_description,
|
||||
workflow_state_resolution_options,
|
||||
hidden=True,
|
||||
is_subworkflow=True,
|
||||
).workflow
|
||||
return subworkflow
|
||||
|
||||
|
||||
@@ -52,8 +52,9 @@ def extract_workflow(
|
||||
# Workflow to populate
|
||||
workflow = model.Workflow()
|
||||
workflow.name = workflow_name
|
||||
workflow.steps = steps
|
||||
# Order the steps if possible
|
||||
attach_ordered_steps(workflow, steps)
|
||||
attach_ordered_steps(workflow)
|
||||
# And let's try to set up some reasonable locations on the canvas
|
||||
# (these are pretty arbitrary values)
|
||||
levorder = order_workflow_steps_with_levels(steps)
|
||||
|
||||
@@ -10,11 +10,11 @@ from galaxy.util.topsort import (
|
||||
)
|
||||
|
||||
|
||||
def attach_ordered_steps(workflow, steps):
|
||||
def attach_ordered_steps(workflow):
|
||||
"""Attempt to topologically order steps and attach to workflow. If this
|
||||
fails - the workflow contains cycles so it mark it as such.
|
||||
"""
|
||||
ordered_steps = order_workflow_steps(steps)
|
||||
ordered_steps = order_workflow_steps(workflow.steps)
|
||||
workflow.has_cycles = True
|
||||
if ordered_steps:
|
||||
workflow.has_cycles = False
|
||||
@@ -30,6 +30,8 @@ def order_workflow_steps(steps):
|
||||
"""
|
||||
position_data_available = bool(steps)
|
||||
for step in steps:
|
||||
if step.subworkflow:
|
||||
attach_ordered_steps(step.subworkflow)
|
||||
if not step.position or "left" not in step.position or "top" not in step.position:
|
||||
position_data_available = False
|
||||
if position_data_available:
|
||||
|
||||
@@ -5059,6 +5059,65 @@ steps:
|
||||
run_workflow_response = self.workflow_populator.invoke_workflow_raw(uploaded_workflow_id, workflow_request)
|
||||
return run_workflow_response, history_id
|
||||
|
||||
def test_subworkflow_import_order_maintained(self):
|
||||
summary = self._run_workflow(
|
||||
"""
|
||||
class: GalaxyWorkflow
|
||||
inputs:
|
||||
outer_input_1:
|
||||
type: int
|
||||
default: 1
|
||||
position:
|
||||
left: 0
|
||||
top: 0
|
||||
outer_input_2:
|
||||
type: int
|
||||
default: 2
|
||||
position:
|
||||
left: 100
|
||||
top: 0
|
||||
steps:
|
||||
nested_workflow:
|
||||
in:
|
||||
inner_input_1: outer_input_1
|
||||
inner_input_2: outer_input_2
|
||||
run:
|
||||
class: GalaxyWorkflow
|
||||
inputs:
|
||||
inner_input_1:
|
||||
type: int
|
||||
position:
|
||||
left: 100
|
||||
top: 0
|
||||
inner_input_2:
|
||||
type: int
|
||||
position:
|
||||
left: 0
|
||||
top: 0
|
||||
steps: []
|
||||
outputs:
|
||||
- label: nested_out_1
|
||||
outputSource: inner_input_1/output
|
||||
- label: nested_out_2
|
||||
outputSource: inner_input_2/output
|
||||
outputs:
|
||||
- label: out_1
|
||||
outputSource: nested_workflow/nested_out_1
|
||||
- label: out_2
|
||||
outputSource: nested_workflow/nested_out_2
|
||||
""",
|
||||
assert_ok=False,
|
||||
wait=False,
|
||||
)
|
||||
self.workflow_populator.wait_for_invocation(summary.workflow_id, summary.invocation_id)
|
||||
self.workflow_populator.wait_for_history_workflows(
|
||||
summary.history_id, assert_ok=False, expected_invocation_count=2
|
||||
)
|
||||
invocation = self.workflow_populator.get_invocation(summary.invocation_id)
|
||||
output_values = invocation["output_values"]
|
||||
assert output_values["out_1"] == 1
|
||||
assert output_values["out_2"] == 2
|
||||
|
||||
@skip_without_tool("random_lines1")
|
||||
def test_run_replace_params_by_steps(self):
|
||||
workflow_request, history_id, workflow_id, steps = self._setup_random_x2_workflow_steps(
|
||||
|
||||
@@ -27,14 +27,14 @@ migrate_repository = repository.Repository(migrate_repository_directory)
|
||||
|
||||
def create_or_verify_database(url, engine_options=None):
|
||||
"""
|
||||
Check that the database is use-able, possibly creating it if empty (this is
|
||||
Check that the database is useable, possibly creating it if empty (this is
|
||||
the only time we automatically create tables, otherwise we force the
|
||||
user to do it using the management script so they can create backups).
|
||||
|
||||
1) Empty database --> initialize with latest version and return
|
||||
2) Database older than migration support --> fail and require manual update
|
||||
3) Database at state where migrate support introduced --> add version control information but make no changes (might still require manual update)
|
||||
4) Database versioned but out of date --> fail with informative message, user must run "sh manage_db.sh upgrade"
|
||||
4) Database versioned but out of date --> fail with informative message, user must run "sh manage_toolshed_db.sh upgrade"
|
||||
|
||||
"""
|
||||
engine_options = engine_options or {}
|
||||
@@ -81,7 +81,7 @@ def create_or_verify_database(url, engine_options=None):
|
||||
migrate_repository.versions.latest,
|
||||
)
|
||||
exception_msg += "Back up your database and then migrate the schema by running the following from your Galaxy installation directory:"
|
||||
exception_msg += "\n\nsh manage_db.sh upgrade tool_shed\n"
|
||||
exception_msg += "\n\nsh manage_toolshed_db.sh upgrade\n"
|
||||
raise Exception(exception_msg)
|
||||
else:
|
||||
log.info("At database version %d" % db_schema.version)
|
||||
|
||||
@@ -77,7 +77,7 @@ from markupsafe import escape
|
||||
|
||||
item_tag_names = []
|
||||
for ta in item_tags:
|
||||
item_tag_names.append(escape(ta.tag.name))
|
||||
item_tag_names.append(escape(f"#{ta.value}" if ta.value else ta.tag.name))
|
||||
%>
|
||||
|
||||
<div id="tags-${tagged_item_id}"></div>
|
||||
|
||||
Reference in New Issue
Block a user