Dpx 693 pr 2 teach lstk update to handle the bundled extensions - #482
Open
carillan81 wants to merge 3 commits into
Open
Dpx 693 pr 2 teach lstk update to handle the bundled extensions#482carillan81 wants to merge 3 commits into
carillan81 wants to merge 3 commits into
Conversation
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
carillan81
marked this pull request as ready for review
September 3, 2026 18:08
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.
Motivation
Once releases ship the bundled extensions (
bundled-extensionsandlstk-extensions.tomlnext tolstk),lstk updateon the binary channel has to replace all three files together, not just the binary. Today it replaces one file,lstk, and ignores everything else in the archive.That has a second-order problem. The first bundling release is installed by the updater users already have, which only replaces
lstk. They land on a current binary with no extensions, and because they are already on the newest version,lstk updatesays "already up to date" until the next release ships. Nobody can fix that retroactively, so the new updater has to detect and repair it.Solution
Set-wise replacement (stage-then-commit). Every member of the archive is copied into the install directory under a
.lstk-newname; only when all copies succeed is each renamed over its final name,lstklast. A file visible under its real name is never half-written, a failure before the last rename leaves a workinglstkto re-run with, and the updater never deletes anlstk-*file it cannot prove it owns (additive-only). An archive containing onlylstkbehaves exactly as before, so pre-bundling releases and rollbacks are unaffected.Repair when current but incomplete. The release stamps the expected set into the binary (
version.bundledSet, via ldflags). When versions match but a stamped member is missing or unusable,lstk updatereinstalls the same release, then re-checks; if the archive still did not deliver the members it fails loudly ("did not restore the bundled extensions") instead of looping. Empty stamp keeps today's pure version comparison. Homebrew and npm never repair; the package manager owns the whole set there. The passive update notice also nudges an incomplete install towardlstk update.Hardening. Windows moves every existing member aside before renaming (a running extension no longer breaks the commit); a squatting symlink or directory at a staging path is refused rather than written through; the install directory is listed literally instead of globbed (a
[in the path used to fail every update); setuid/setgid bits survive the update; a concurrent update cannot truncate another's staging file.Structured output.
UpdateCheckedEventgainsRepairBundled; the--jsoncheck shape gains"repairBundled": truefor a same-version repair (absent otherwise, and scrubbed from the applied shape).Dependencies and follow-ups
dpx-692(PR 1) must merge first or together: it carries the resolver that dispatches bundled commands from the toml. Without it a repaired install has the files but nothing resolves them.bundledSetldflags stamp (tasks.md 5.2) is not yet in.goreleaser.yaml; until it lands on the packaging side the repair path stays dormant and this PR changes nothing user-visible.bundledBinaryBaseNamefromextension.BundledBinaryName(TODO left on the constant).Testing
internal/updatecovers every behaviour above, including the Windows path from any host via agoosparameter. All new behaviour was written test-first.goreleaser, npm publisher): the full transition (published 0.23.0 to bundling release, repair, no-op, bundled-to-bundled upgrade, rollback, forward) passes on the binary channel and npm. Caveat: the currently published bundle predates thebundled-extensions listcontract, so the release gate was run as a warning for that exercise; Homebrew was not executed.Docs
No documentation work needed outside this PR.
docs/structured-output.mdis updated for the newrepairBundledkey, and the update guarantees are documented in theinternal/updatepackage comment. User-facing bundling docs (docs/extensions-bundling.md) live on dpx-692.Review
Human review advisable. This is the update path, the one thing a broken release cannot ship a fix for, and it adds new user-visible behaviour (the repair). Not a self-merge candidate.
Closes DPX-693