fix(bundler): pass explicit option values when delegating to workflow_add - #4135
fix(bundler): pass explicit option values when delegating to workflow_add#4135jawwad-ali wants to merge 1 commit into
workflow_add#4135Conversation
There was a problem hiding this comment.
Pull request overview
Fixes workflow bundle installation by supplying concrete Typer option values during in-process delegation.
Changes:
- Passes
dev=Falseandfrom_url=Nonetoworkflow_add. - Adds regression coverage verifying both values.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/bundler/services/primitives.py |
Corrects workflow installation delegation. |
tests/unit/test_bundler_primitives.py |
Adds and updates delegation tests. |
Review details
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Balanced
…_add
`specify bundle install` can never install a workflow component. It fails
100% of the time with a nonsensical error about `--dev`.
The bundler delegates to the Typer command callables in-process:
lambda: workflow_add(component.id)
`workflow_add` declares two `typer.Option` parameters. Called from Python
rather than through Typer, those keep their `OptionInfo` sentinels as the
value — and the sentinel is truthy and is not None:
dev default -> OptionInfo truthy=True
from_url default -> OptionInfo is None=False
So `if dev:` takes the local-path branch for every catalog install:
Error: --dev source must be a workflow YAML file, supported archive, or
directory containing workflow.yml: code-review
BundlerError: Failed to install workflow 'code-review'.
`workflow_add` is the only one of the four delegated commands that declares
options; workflow_remove / workflow_step_add / workflow_step_remove take a
bare `typer.Argument` and are safe as written.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4817f62 to
265e131
Compare
|
Rebased onto current In fairness, you should know this is now largely superseded. While it sat, #4284 (041faee, merged Sep 1) landed the identical source fix: lambda: workflow_add(component.id, dev=False, from_url=None),and folded the same regression assertion into the existing test: assert calls == [("bundled-wf", False, None)]That is exactly why this branch conflicted — Resolving the conflict, I took main's side wherever it was equal or better: its What remains unique here is small and entirely additive:
Entirely your call whether that is worth carrying — I'm happy to close this if you would rather not review a near-duplicate, and I won't be offended either way. Verified after the rebase: 26 passed in |
Problem
specify bundle installcan never install a workflow component. It fails 100% of the time, with an error about--devthat has nothing to do with what the user asked for.bundler/services/primitives.pydelegates to the Typer command callables in-process, as its module docstring describes:But
workflow_adddeclares twotyper.Optionparameters (workflows/_commands.py:1712-1716):Called from Python rather than through Typer, an omitted option parameter keeps its
OptionInfosentinel as the value:So
if dev:is always true and the function takes the local-path branch.Reproduction on current
main(bf88c9f)The catalog install path is unreachable.
Why only this call site
A signature survey of all four delegated callables:
workflow_addsource=ArgumentInfo, dev=OptionInfo, from_url=OptionInfoworkflow_removeworkflow_id=ArgumentInfoworkflow_step_addstep_id=ArgumentInfoworkflow_step_removestep_id=ArgumentInfoworkflow_addis the only one that declares options, and it is the only call site that omits them — so the other three are safe exactly as written, and this fix is correctly scoped to one line.Fix
No breaking change. No input that works today behaves differently — today every bundler workflow install fails; afterwards it reaches the catalog path the code always intended.
Verification
srcand passes with the fix — 1 failed → 21 passed.dev is Falseandfrom_url is None, so a future regression to sentinels is caught rather than silently swallowed by a**kwargsstub.lambda wid: ...) had to accept the kwargs; I made it capture them instead of discarding them.tests/unit: no new failures vs a clean-mainbaseline captured onbf88c9f9.uvx ruff@0.15.0 check src tests→ cleanWritten with assistance from Claude Code. Bug found, reproduced, and verified by me on current
main.