Add preset update convenience wrapper - #4599
digimangos wants to merge 13 commits into
Conversation
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The implementation matches the stated contract and includes comprehensive failure and workflow coverage.
Review tier: Balanced
Findings: None
What changed in this PR
Adds a destructive preset update wrapper using existing remove/add flows.
Changes:
- Adds update orchestration, validation, and recovery guidance.
- Documents destructive behavior and limitations.
- Adds unit and end-to-end coverage.
| File | Description |
|---|---|
src/specify_cli/presets/_commands.py |
Implements update and shared priority validation. |
tests/test_presets.py |
Tests orchestration and failures. |
tests/integration/test_preset_update_workflow.py |
Tests real CLI workflows. |
docs/reference/presets.md |
Documents usage and risks. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Thanks @digimangos — this follows the smaller remove-then-add scope we agreed on. Before merging, please correct the Windows retry-command quoting. Please also correct the missing or malformed Drafted for @mnriem by GitHub Copilot (model: GPT-6 Astra). |
cf79748 to
8d85620
Compare
Assisted-by: GitHub Copilot (model: gpt-5.6-luna, autonomous)
Assisted-by: GitHub Copilot Autofix (autonomous) Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Assisted-by: GitHub Copilot Autofix (autonomous) Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Document that update does not preflight-check replacement manifest IDs for --from and --dev sources. Assisted-by: GitHub Copilot (model: gpt-5.6-luna, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 29b77f74-30d5-4969-981b-07a05607e971
Use the same command-line rendering rules as preset update so the retry-command test passes on Windows and POSIX systems. Assisted-by: GitHub Copilot (model: gpt-5.6-luna, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 29b77f74-30d5-4969-981b-07a05607e971
specify preset update foo --priority 0 removed foo before add rejected the priority, leaving the preset gone and printing a retry command that carried the same rejected value, so the retry could never succeed. Validate priority before preset_remove runs. Extract the check into _validate_priority so add, set-priority, and update cannot drift apart on the accepted range or the message they print. The substitution in add and set-priority is behaviour-preserving: same condition, same message, same exit code. Also pass explicit option values in the direct-call update tests. Two of them previously omitted from_url/dev, leaving Typer OptionInfo defaults in place; because those objects are truthy, the tests exercised the mutually-exclusive branch rather than the path they described. Assisted-by: GitHub Copilot (model: gpt-5.6-luna, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 29b77f74-30d5-4969-981b-07a05607e971
State that a failed add after removal can leave a generated constitution reconciled against the stack without the removed preset, and that the normal remove and add passes may rewrite it even when the final resolved content is unchanged. Assisted-by: GitHub Copilot (model: claude-opus-5, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Correct documentation spelling to behavior, synchronization, and optimization. Assisted-by: GitHub Copilot (model: gpt-5.6-luna, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add end-to-end coverage for successful preset replacement and failed replacement retry recovery. Update the preset documentation to describe manifest-diff limitations. Assisted-by: GitHub Copilot (model: gpt-5.6-luna, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Exercise Typer parsing for the required preset ID, unsupported options, and help output. Assisted-by: GitHub Copilot (model: gpt-5.6-luna, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reject explicitly supplied empty --from and --dev values before removing the installed preset, and treat supplied options as mutually exclusive regardless of their contents. Assisted-by: GitHub Copilot (model: gpt-5.6-luna, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
A preset ID starting with a hyphen satisfies manifest validation but Typer parses it as an option, so the printed retry command could not be copy-pasted. Place the source and priority options before a -- separator for such IDs, preserving the existing order for normal ones. Assisted-by: GitHub Copilot (model: claude-opus-5, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Render Windows recovery commands explicitly for PowerShell, using literal argument quoting so shell metacharacters remain part of URLs and paths. Add regression coverage against a real PowerShell parser when available. Assisted-by: GitHub Copilot (model: HydraFusion, autonomous) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
8d85620 to
8b5f516
Compare
|
@mnriem that should be the items covered that you mentioned above. |
Description
Adds
specify preset updateas a deliberately destructive convenience command that runs the existing preset removal flow followed by the existing preset addition flow. It forwards the replacement source and priority options without introducing separate update semantics, rollback, staging, or reconciliation optimizations.Acceptance criteria
Command contract
specify preset update <preset-id>requires one already-installed preset ID.--from,--dev, and--priority.--fromand--devremain mutually exclusive.--allor--dry-runin this iteration.Update behavior
preset removebehavior first, followed by the existingpreset addbehavior only when removal succeeds.--from,--dev, or--priorityvalues are forwarded to add without introducing separate update semantics.--fromor--devvalue determines the replacement source. Update does not attempt to recover or reuse the previous installation source.--fromor--dev, update performs add's normal bundled and catalog resolution by preset ID, regardless of how the previous installation was sourced.--priorityvalue becomes the replacement preset's priority. When omitted, add uses its normal default of10.Failure behavior
specify preset addcommand with the requested preset ID and supplied source and priority options.Documented limitations
--fromor--devsource may leave the preset removed.installed_at, and removes local modifications through normal remove and add behavior.--fromor--devintentionally changes the replacement source.--fromor--dev, add installs the source manifest's preset ID. A mismatched source can therefore remove the requested preset and install a differently identified preset.constitution-templateandconstitution-syncapply, removal reconciles the generated constitution against the intermediate stack and successful addition reconciles it against the final stack..specify/memory/constitution.md.Testing
.venv/bin/python -m pytest tests/test_presets.py -q--from,--dev, and--priorityupdate options.AI Disclosure
Code generated by Copilot CLI, reviewed by Copilot Code Review Agent.
Closes #4427