fix(gh-9): require both uv and uvx before skipping bootstrap download - #10
Open
oliver-cieliszak-natterbox wants to merge 2 commits into
Open
fix(gh-9): require both uv and uvx before skipping bootstrap download#10oliver-cieliszak-natterbox wants to merge 2 commits into
oliver-cieliszak-natterbox wants to merge 2 commits into
Conversation
The skip guard in install.sh and install.ps1 checked uv's version only, so a prefix created before uvx existed could match the pinned version and skip the download, leaving uvx missing while setup.py still wrapped it - a dangling bin/uvx and a broken $..._UVX, with the install reporting success throughout. Both guards now require uv and uvx to be present. Since they ship in one archive, a missing uvx simply re-downloads the pair. setup.py gains _require_bootstrapped() as a backstop for standalone runs: it refuses to configure a prefix whose binaries are absent. It runs before the cooldown check on purpose - _validate_cooldown silently no-ops when uv cannot be run, so validating the prefix first keeps that check honest. TESTING.md gains Tests 9 and 10 plus a Windows counterpart. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Orca Security Scan Summary
| Status | Check | Issues by priority | |
|---|---|---|---|
| Infrastructure as Code | View in Orca | ||
| SAST | View in Orca | ||
| Secrets | View in Orca | ||
| Vulnerabilities | View in Orca |
🛠️ Fix a finding or handle a false positive
- Auto-Fix: Run
/orca-pr-scan-fixto automatically remediate or suppress PR findings. - In-Code: Suppress via inline comments or exception files (see CLI References).
- In Orca: Dismiss or snooze directly via Changing Alert Statuses.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The bootstrap skip guard in
install.shandinstall.ps1now requires bothuvanduvxto be present, not just a matchinguvversion.setup.pygains a_require_bootstrapped()backstop that refuses to configure a prefix whose binaries are missing.TESTING.mdgains Tests 9 and 10 plus a Windows counterpart, and the stale idempotency note inREADME.mdis corrected.Why
Fixes #9. The guard predates
uvx(added in v0.10.0, #4) and was never extended, so it decided onuv's version alone:If
prefix/uvalready matched the pin butprefix/uvxwas absent,uvxwas never fetched - whilesetup.pystill createdbin/uvx -> ../uvx. The result was a dangling symlink and a broken$..._UVX, with the install printing✓all the way toInstall complete!.Reproduced on
mainbefore touching anything (scratchpad prefix,--isolated):The trigger is upgrading a pre-v0.10.0 prefix to a distro version that pins the same uv release, which is an entirely normal bump to make. Not reachable through the current Atlas bootstrap (v0.9.2 pins uv
0.10.6, v0.11.0 pins0.10.12), so this is prevention rather than an outage.How
Both binaries gate the skip. They ship in one archive, so a missing
uvxsimply re-downloads the pair - no separate fetch path, no new failure mode. The→ Downloading uv X.Y.Zmessage is therefore what you see when onlyuvxis missing; a comment in each script explains that rather than making the message conditional.install.batneeded no change - it is a thin shim that shells out toinstall.ps1, so there is no third copy of the guard.The
setup.pybackstop is placed inmain(), not in_create_bin(). Three reasons, the third being the one that actually matters:bin/wrappers, no env files" becomes structural rather than a consequence of statement ordering.==> Creating bin/ wrappersimmediately before a fatal error._validate_cooldown()returnsNonewhenuvcannot be run, i.e. it silently skips validation. Before this change, a prefix missinguvcombined with a bad--cooldownslipped past cooldown validation entirely. Running the prefix check first makesuv's presence a precondition, so the cooldown check is always genuinely performed. Verified both ways below.The check covers
uv,uvxand the venv Python, branched on_IS_WINDOWS. On Windows the same bug is worse in one respect:uvx.cmdis written unconditionally with no symlink involved, so a missinguvx.exeproduces a wrapper that fails later with a confusing error rather than an obviously broken link.Test Steps
TESTING.mdTests 9 and 10 (Linux/macOS) and "Windows: Test 6". Everything below was run on macOS against a real bootstrap of the pinneduv_version = "0.10.12":uvxabsent,$TEST_UVX --versionfailed, install still reported success→ Downloading uv 0.10.12,✓ venv already exists,uvx 0.10.12 (00d72dac7 ...)→ Downloading uv 0.10.12, venv untouched,uvx 0.10.12._bootstrap_uvdoes not takeisolated, so both modes share the guard, but worth confirming rather than assuming✓ uv 0.10.12+✓ venv already exists- no needless re-downloadPython 3.10.20,bin/uvx→uvx 0.10.12setup.pystandalone,uvxremoved1,ERROR: bootstrap incomplete ...naminguvx, nothing writtensetup.pystandalone,uvremoved and--cooldown yesterday1naminguv. Previously the bad cooldown would have gone unvalidateduvrestored,--cooldown yesterdaysetup.pystandalone on a healthy prefix0, unchanged behaviourbash -n install.sh,ast.parse(setup.py)Warning
Not tested on Windows.
pwshis not available on this machine. Theinstall.ps1change is a mirror of the shell one - aTest-Path $UvxExeconjunct on the guard, plus a post-extraction existence check and a reuse of the new$UvxExevariable. Worth a pass through "Windows: Test 6" before the next release.Other Notes
RELEASING.mdgivesrelease.pyownership ofdistro.tomlversion. This is patch-worthy whenever you next cut a release.v0.11.0. If you want this in the Atlas bootstrap, the path is: merge this → cutv0.11.1→ re-point #677. Not doing that unprompted.CLAUDE.md(deliberately removed in70617da) though our standards now expect one, andorigin/developis stale (3 commits, no PR, no releases). Both left alone here.Review & provenance
python-standardssub-agent reviewpython-standardssub-agent (Claude, same family as the generator — does not satisfy §3): 0 blocking, 2 suggestions, both accepted — Google-styleArgs:/Raises:sections added, and the guard relocated from_create_bin()intomain(). The second suggestion is what surfaced the_validate_cooldown()silent-skip interaction, which is now the strongest reason for the placementTESTING.md. Actually run:bash -n install.sh,ast.parse(setup.py), a 120-column check over added lines, and the eleven manual checks in the table above. Not run: any PowerShell execution (nopwshon macOS), any Windows testWorth human attention
_require_bootstrapped()placement is a behaviour change beyond issue uvx not downloaded when uv version already matches, leaving bin/uvx dangling #9. Moving it ahead of_validate_cooldown()means a prefix missinguvnow fails hard where it previously proceeded with an unvalidated cooldown. That is the correct outcome, but it is a second fix riding along with the first and deserves a look on its own terms._create_bin"warn (or fail)". I chosesys.exit(1), on the view that a wrapper pointing at a non-existent binary is never a valid install. If anyone has a legitimate partial-prefix workflow, this breaks it — I could find none.install.ps1is unexecuted. Every claim about the Windows half is by inspection only. The guard is underSet-StrictMode -Version Latest, soTest-Pathon the pre-computed$UvxExewas chosen deliberately over anything that could trip strict mode.uvxis missing, the script prints→ Downloading uv X.Y.Zeven thoughuvis already current. I judged one honest comment cheaper than conditional messaging; disagree freely.README.mdwas stale and is corrected in the second commit. If anyone is relying on "uv download skipped if pinned version already installed" as documented behaviour, that sentence is no longer true and this is the line to argue with.Jira: n/a — tracked in GitHub
Closes #9
🤖 Generated with Claude Code