Exit non-zero from planemo autoupdate when a tool fails to update - #1727
Conversation
cmd_autoupdate built an exit_codes list and returned coalesce_return_codes(...), but click discards a command's return value, so the process always exited 0. Every other planemo command that computes a code hands it to ctx.exit(); autoupdate never did. Also record a failure when autoupdate_tool raises for a reason other than malformed XML - previously only the tool-load-error path was counted. Workflow targets now register an OK code so the pre-existing assert_at_least_one check doesn't turn a workflow-only run into EXIT_CODE_NO_SUCH_TARGET. Pointing autoupdate at a path with neither tools nor workflows now exits 2, as that check always intended. Fixes galaxyproject#1478 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
mvdbeek
left a comment
There was a problem hiding this comment.
Thanks, the malformed-XML fix looks right. One problem before merging: the assert_at_least_one check now takes effect, and it will break the planemo-autoupdate weekly job.
The job runs planemo autoupdate . --skiplist … || errors="…Cannot autoupdate $REPO…" for each repo. If errors ends up non-empty, the job comments on the "Autoupdate errors" issue and runs exit 1. Skipped tools hit continue before an exit code is appended, and skipped workflows are filtered out of workflows. So a repo whose only tool or workflow is on the skip list now exits 2 (EXIT_CODE_NO_SUCH_TARGET); on master it exits 0.
Under the current skip lists, these repos contain nothing but the skipped entry:
- tools-iuc:
tools/optitype,tools/interproscan,data_managers/data_manager_interproscan - bgruening/galaxytools:
tools/diff,chemicaltoolbox/autodock_vina/prepare_box - iwc:
fragment-based-docking-scoring,sars-cov-2-pe-illumina-artic-ivar-analysis,sars-cov-2-ont-artic-variant-calling
To reproduce on this branch: a directory with one tool, with that tool on the skip list, prints Skipping tool … and exits 2.
Suggested fix: count skipped tools and workflows as successful targets, e.g. exit_codes.append(EXIT_CODE_OK) before the continue, and the same for skipped workflows. Alternatively, use assert_at_least_one=False as you offered. A test that covers the skiplist-only case would be good too.
assert_at_least_one only became live in the previous commit, so a path whose only tool or workflow is on --skiplist started exiting 2 instead of 0 - the tool loop `continue`s before appending, and skipped workflows were filtered out of the list entirely. Breaks the weekly planemo-autoupdate job, where several repos contain nothing but a skiplisted entry. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Posted by Claude (AI assistant) on jmchilton's behalf, not authored by them personally. Good catch, confirmed and fixed in a0cb85c. Reproduced against the real job inputs rather than just a synthetic case:
Both print only Went with your first suggestion rather than
An empty directory still exits 2. Two notes on the census, neither affecting the fix:
Two tests added, both in the fast tier (no conda, no Galaxy):
Verified red-to-green: with the source change stashed both fail, with it restored both pass. |
mvdbeek
left a comment
There was a problem hiding this comment.
Awesome, merge away if you're happy
Fixes #1478.
Root cause
planemo autoupdatealready tracked per-tool failures —cmd_autoupdate.clibuilds anexit_codeslist and appendsEXIT_CODE_GENERIC_FAILUREwheneverhandle_tool_load_errorfires. It then did:
Click discards a command callback's return value, so that code never reached the process.
Planemo's exit codes travel via
ctx.exit(), which raisesExitCodeExceptionforcommand_functionto turn intosys.exit().autoupdateis the only command that computesan exit code and forgets to hand it to
ctx.exit()—cmd_lint.py,cmd_shed_lint.py,cmd_workflow_lint.py,cmd_test.py,cmd_run.pyall do. So the accounting was right andthe result was thrown away.
Reproduced exactly as reported: the malformed-XML diagnostics print, "Could not update
<path> due to malformed xml." prints, and the process exits 0.
Changes
ctx.exit(coalesce_return_codes(...))instead ofreturn.autoupdate_toolnow records a failure. Previously only thetool-load-error path counted, so a tool that errored for any other reason printed a red
error and still scored
EXIT_CODE_OK.EXIT_CODE_OK. Without this, wiring upctx.exitwould makeplanemo autoupdate some_workflow.gaexit 2 —assert_at_least_onewas only eversatisfied by the tool loop.
Behavior change worth a look
Because
assert_at_least_one=assert_toolsis now live, pointingautoupdateat a path withneither tools nor workflows exits
EXIT_CODE_NO_SUCH_TARGET(2) rather than 0. That is whatthe existing argument always intended and it matches
planemo lint(tests/test_lint.py:75),but it is a visible change for anyone running
planemo autoupdateover a directory list inCI where some directories hold no tools. Happy to drop it to
assert_at_least_one=Falseifthat is too sharp an edge.
Tests
tests/test_cmd_autoupdate.py, both reusing the existingtests/data/repos/bad_invalid_tool_xmlfixture /
_isolate()rather than adding new data:test_autoupdate_malformed_xml— asserts exit code 1 and the "due to malformed xml" message.test_autoupdate_no_targets— pins the exit-2 behavior above.Both need neither conda nor Galaxy, so they run in the fast tier.
Red-to-green: with the
cmd_autoupdate.pychange stashed, both fail; restored, both pass.Also added
assert result.exit_code == 0totest_autoupdate_workflow_unexisting_tooltoguard the workflow-only path against the
assert_at_least_oneregression described above.🤖 Generated with Claude Code