feat(cli): add specify self check and self upgrade stub#2316
feat(cli): add specify self check and self upgrade stub#2316mnriem merged 7 commits intogithub:mainfrom
Conversation
Introduce a new `specify self` Typer sub-app with two subcommands. `specify self check` performs a read-only lookup against the GitHub Releases API, compares the installed version to the latest tag with PEP 440 semantics, and prints one of four verdicts (newer-available, up-to-date, indeterminate, graceful-failure). When a newer stable release is available, the output includes a copy-pasteable `uv tool install --force --from git+...@<tag>` reinstall command. `GH_TOKEN` / `GITHUB_TOKEN` is attached as a bearer credential when set so users behind shared IPs escape the anonymous 60/hour rate limit. `specify self upgrade` is a documented non-destructive stub in this release: three-line guidance output, exit 0, no outbound call, no install-method detection. The real destructive implementation is planned as follow-up work. Failure categorization is a fixed three-entry enum (offline or timeout, rate limited, HTTP <code>). Anything outside those three categories propagates as a non-zero exit so bugs surface instead of being silently swallowed. No machine-readable output, no retries, no caching in this release — see issue github#2282 discussion. Tests mock `urllib.request.urlopen`; the suite performs zero real network calls. Full regression suite: 1586 passed.
Rich's default `highlight=True` applies ANSI color to detected patterns (integers, version strings, paths) whenever stdout is deemed a TTY. This caused intermittent failures in existing pytest assertions in tests/test_cli_version.py and tests/test_extensions.py::TestExtensionRemoveCLI that compare plain-text output without passing through `strip_ansi()`. Setting `Console(highlight=False)` globally makes all CLI output deterministic and fixes the flake without modifying the affected tests. The numeric cyan highlighting was not a documented part of the CLI visual contract.
There was a problem hiding this comment.
Pull request overview
Adds a new specify self CLI surface for checking whether a newer released version is available, and reserves a future self upgrade command as a non-destructive stub.
Changes:
- Introduces
specify self checkto query the latest GitHub release tag and print upgrade/reinstall guidance. - Adds
specify self upgradeas a fixed-output stub (no network, exits 0). - Adds a dedicated test module that mocks
urllib.request.urlopento keep the suite network-isolated.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| tests/test_upgrade.py | Adds tests for version comparison, tag normalization, failure categorization, token header behavior, and the self upgrade stub output/network isolation. |
| src/specify_cli/init.py | Implements release lookup + comparison helpers and wires the new self Typer sub-app into the CLI. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/2 changed files
- Comments generated: 0 new
|
Thank you! |
|
Feel free to bring it the rest of the way! |
|
Thanks for the review and for merging this. I’d like to follow up with a Phase 2 PR for the actual |
That's not the point. The point is that issues are being closed, before completion. Feel free to be a manager, the proper way. |
|
I'm also a paying customer at the moment. So telling me to feel free to develop the product I am paying for is absolutely ludicrous. |
Closes #2282.
Summary
This PR introduces a new
specify selfTyper sub-app, following the direction in the issue discussion.specify self checkperforms a read-only lookup of the latest GitHub release, compares it with the installedspecify-cliversion, and prints either an update verdict or a graceful fallback message. When a newer release exists, it also prints a copy-pasteableuv tool install --force --from git+…@<tag>reinstall command.specify self upgradeis introduced as a reserved, non-destructive stub in this release. It prints a fixed three-line guidance message and exits 0. Actual self-upgrade remains out of scope for this PR.Design Notes
GH_TOKEN/GITHUB_TOKENautomatically when present to avoid anonymous GitHub API rate limits.offline or timeout,rate limited (try setting GH_TOKEN or GITHUB_TOKEN), andHTTP <code>.urllib.request.urlopen, so the feature test suite performs zero real network traffic.Example output
specify self check— up to datespecify self check— newer release available (mocked example)specify self upgradeVerification
uv run pytest -q tests/test_upgrade.pyuv run pytest -quvx ruff check src/specify_cli/__init__.pyuv run specify self --helpuv run specify self check --helpuv run specify self upgrade --helpuv run specify self checkonlineuv run specify self checkofflineGH_TOKEN="SENTINEL-TOKEN-VALUE" uv run specify self check 2>&1 | grep SENTINEL-TOKEN-VALUEreturns no outputuv run specify self upgradeprints the exact three-line stub and exits 0Notes
Console(highlight=False)is included to avoid Rich auto-highlighting plain numeric output, which was causing existing plain-text CLI tests to fail.specify self upgradebehavior is intentionally left for follow-up work.