Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix autoupdate for workflows with overlapping tool updates #1452

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 20 additions & 21 deletions planemo/commands/cmd_autoupdate.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,27 +138,26 @@ def cli(ctx, paths, **kwds): # noqa C901
with engine_context(ctx, **kwds) as galaxy_engine:
with galaxy_engine.ensure_runnables_served(modified_workflows) as config:
for workflow in modified_workflows:
if config.updated_repos.get(workflow.path) or kwds.get("engine") == "external_galaxy":
info("Auto-updating workflow %s" % workflow.path)
updated_workflow = autoupdate.autoupdate_wf(ctx, config, workflow)

if workflow.path.endswith(".ga"):
with open(workflow.path) as f:
original_workflow = json.load(f)
edited_workflow = autoupdate.fix_workflow_ga(original_workflow, updated_workflow)
with open(workflow.path, "w") as f:
json.dump(edited_workflow, f, indent=4)
else:
with open(workflow.path) as f:
original_workflow = yaml.load(f, Loader=yaml.SafeLoader)
edited_workflow = autoupdate.fix_workflow_gxformat2(original_workflow, updated_workflow)
with open(workflow.path, "w") as f:
yaml.dump(edited_workflow, f)
if original_workflow.get("release"):
info(
f"The workflow release number has been updated from "
f"{original_workflow.get('release')} to {edited_workflow.get('release')}."
)
info("Auto-updating workflow %s" % workflow.path)
updated_workflow = autoupdate.autoupdate_wf(ctx, config, workflow)

if workflow.path.endswith(".ga"):
with open(workflow.path) as f:
original_workflow = json.load(f)
edited_workflow = autoupdate.fix_workflow_ga(original_workflow, updated_workflow)
with open(workflow.path, "w") as f:
json.dump(edited_workflow, f, indent=4)
else:
with open(workflow.path) as f:
original_workflow = yaml.load(f, Loader=yaml.SafeLoader)
edited_workflow = autoupdate.fix_workflow_gxformat2(original_workflow, updated_workflow)
with open(workflow.path, "w") as f:
yaml.dump(edited_workflow, f)
if original_workflow.get("release"):
info(
f"The workflow release number has been updated from "
f"{original_workflow.get('release')} to {edited_workflow.get('release')}."
)

if kwds["test"]:
if not modified_files and not modified_workflows:
Expand Down
59 changes: 35 additions & 24 deletions tests/test_cmd_autoupdate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import json
import os
import shutil
import tempfile
from contextlib import contextmanager

Expand Down Expand Up @@ -33,7 +34,7 @@ def create_tmp_test_tool_file(tool_version):
) as t:
t.write(xml_str)
t.flush()
yield t.name
yield os.path.realpath(t.name)


class CmdAutoupdateTestCase(CliTestCase):
Expand Down Expand Up @@ -80,31 +81,41 @@ def test_autoupdate_no_update_needed(self):
result = self._runner.invoke(self._cli.planemo, autoupdate_command)
assert f"No updates required or made to {xmlfile}." in result.output

def test_autoupdate_workflow(self):
def test_autoupdate_multiple_workflows(self):
"""Test autoupdate command for a workflow is needed."""
with self._isolate_with_test_data("wf_repos/autoupdate_tests") as f:
wf_file = os.path.realpath(os.path.join(f, "diff-refactor-test.ga"))
autoupdate_command = ["autoupdate", wf_file]
with self._isolate_with_test_data("wf_repos/autoupdate_tests") as f, tempfile.TemporaryDirectory(
dir=f, prefix="autoupdate_test"
) as isolated_dir:
source_file = os.path.join(f, "diff-refactor-test.ga")
# We update identical workflows in the same autoupdate call,
# both workflows must be updated.
targets = [os.path.join(isolated_dir, wf) for wf in ("wf1.ga", "wf2.ga")]
for target in targets:
shutil.copy(source_file, target)
autoupdate_command = ["autoupdate", *targets]
result = self._runner.invoke(self._cli.planemo, autoupdate_command)
assert f"Auto-updating workflow {wf_file}" in result.output
with open(wf_file) as g:
wf = json.load(g)
# check tool within parent wf has updated
assert wf["steps"]["1"]["tool_version"] == "3.7+galaxy0"
# check tool within subworkflow has updated
assert wf["steps"]["2"]["subworkflow"]["steps"]["1"]["tool_version"] == "3.7+galaxy0"
assert (
wf["steps"]["2"]["subworkflow"]["steps"]["1"]["tool_id"]
== "toolshed.g2.bx.psu.edu/repos/bgruening/diff/diff/3.7+galaxy0"
)
assert wf["version"] == 2
assert wf["release"] == "0.1.1"

result = self._runner.invoke(self._cli.planemo, autoupdate_command) # rerun on already updated WF
assert "No newer tool versions were found, so the workflow was not updated." in result.output

assert "Auto-updating workflow" in result.output
for wf_file in targets:
with open(wf_file) as g:
wf = json.load(g)
# check tool within parent wf has updated
assert wf["steps"]["1"]["tool_version"] == "3.7+galaxy0"
# check tool within subworkflow has updated
assert wf["steps"]["2"]["subworkflow"]["steps"]["1"]["tool_version"] == "3.7+galaxy0"
assert (
wf["steps"]["2"]["subworkflow"]["steps"]["1"]["tool_id"]
== "toolshed.g2.bx.psu.edu/repos/bgruening/diff/diff/3.7+galaxy0"
)
assert wf["version"] == 2
assert wf["release"] == "0.1.1"

result = self._runner.invoke(self._cli.planemo, autoupdate_command) # rerun on already updated WF
assert "No newer tool versions were found, so the workflow was not updated." in result.output

def test_autoupdate_gxformat2_workflow(self):
with self._isolate_with_test_data("wf_repos/autoupdate_tests") as f:
wf_file = os.path.join(f, "diff-refactor-test.gxwf.yml")
autoupdate_command[1] = wf_file
autoupdate_command = ["autoupdate", wf_file]
result = self._runner.invoke(self._cli.planemo, autoupdate_command)
assert f"Auto-updating workflow {wf_file}" in result.output

Expand All @@ -117,7 +128,7 @@ def test_autoupdate_workflow(self):

def test_autoupdate_workflow_from_multiple_tool_sheds(self):
with self._isolate_with_test_data("wf_repos/autoupdate_tests") as f:
wf_file = os.path.realpath(os.path.join(f, "wf_autoupdate_test_multiple_repos.ga"))
wf_file = os.path.join(f, "wf_autoupdate_test_multiple_repos.ga")
autoupdate_command = ["autoupdate", wf_file]
result = self._runner.invoke(self._cli.planemo, autoupdate_command)
assert f"Auto-updating workflow {wf_file}" in result.output
Expand Down
2 changes: 1 addition & 1 deletion tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def _isolate_with_test_data(self, relative_path):
with self._isolate() as f:
repo = os.path.join(TEST_DATA_DIR, relative_path)
self._copy_directory(repo, f)
yield f
yield os.path.realpath(f)

def _copy_repo(self, name, dest):
repo = os.path.join(TEST_REPOS_DIR, name)
Expand Down
Loading