Repository navigation
feat(launcher): make devbox its own launcher - #3024
mikeland73 wants to merge 2 commits into
Conversation
Release builds of devbox now do the bash launcher's job: the binary at /usr/local/bin/devbox picks the version to run (DEVBOX_USE_VERSION or current-version), downloads it if needed, and either runs the command itself or execs that version. Version checks run in a detached child process instead of blocking the command. - internal/launcher: version selection, download with checksum verification, background refresh, and launcher replacement. Keeps the bash launcher's env vars, version files, and install dir so older versions keep working. - build.Launcher ldflag (set only by goreleaser) turns it on, so dev and package-manager builds stay plain binaries. - `devbox version update` downloads the latest version itself and only replaces the launcher when the launcher version is bumped, or with the new --launcher flag. - expectedLauncherVersion is now launcher.Version (1.0.0), so bash-launcher users are asked to update, at most once a day. - scripts/install.sh: new installer that installs the binary. - specs: add native-launcher.md and mark perf item 6 done. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
1 similar comment
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
|
@claude ptal |
|
Claude finished @mikeland73's task in 44s —— View job Review of #3024: native launcherI read Checked and looks right
Minor points (non-blocking)
Test gaps
|
Summary
Implements item 6 of
specs/perf-improvements.md. Instead of speeding up the bash launcher in the axiom repo, release builds of devbox now are the launcher. The design is in the newspecs/native-launcher.md.devbox version, median of 30 runs on macOS arm64:Design
internal/launcherruns first inboxcli.Main:DEVBOX_USE_VERSION, otherwisecurrent-version.~/.cache/devbox/bin, first downloading it if needed. Downloads are checked againstchecksums.txt.devbox __launcher-refreshprocess, so commands no longer wait oncurl.When it runs: only in release builds. The new
build.Launcher=trueldflag is set only in.goreleaser.yaml, so dev builds and package-manager builds (nixpkgs, Homebrew) stay plain binaries. It also does nothing for binaries inside the install dir: launchers only run binaries from there, so such a binary is already the version a launcher picked. That rule is what prevents exec loops, and env vars that leak into adevbox shellcan't confuse it.Compatibility with older versions: it keeps the bash launcher's contract that older versions rely on:
LAUNCHER_PATH,LAUNCHER_VERSION,DEVBOX_LATEST_VERSIONcurrent-versionandlatest-versionin the cache dir,auto_updateandchannelin the config dir~/.cache/devbox/bin/<version>_<platform>layoutvercheck'sinstalledBinaryfrom perf(vercheck): switch devbox versions before startup for devbox_version auto #3023 now useslauncher.InstalledBinary. That also fixes the 32-bit ARM directory name, which should bearmv7l.devbox version update:LAUNCHER_PATHonly whenLAUNCHER_VERSIONis older thanexpectedLauncherVersion, or with the new--launcherflag. That's the only time it may ask for sudo. The replacement is a temp file plus rename, falling back tosudowhen the directory isn't writable.LAUNCHER_PATH(not installed with the installer), it returns an error saying to update devbox with the package manager it came from.Migrating existing users:
expectedLauncherVersionis nowlauncher.Version(1.0.0).--quietand for the commands in the existing skip list, such asshellenv.devbox version updatethen replaces the bash script with the binary directly, so the migration doesn't depend on the installer.Installer:
scripts/install.shinstalls the latest release binary to/usr/local/bin/devbox, using sudo only when that directory isn't writable. It writescurrent-versionandlatest-version, so the first run doesn't wait for the network.Follow-ups (not in this PR)
scripts/install.shtoget.jetify.com/devbox. Today that script is published fromaxiom/installers/devbox/install.sh. It has to wait, because it installs the latest release as the launcher.releases.jetify.com/devbox(the bash launcher) published for anything that downloads it directly, and retire it later.Testing
go test ./internal/... ./nix/... ./pkg/...passes.golangci-lintreports no issues on the changed packages.internal/launcheruse a local fake release server and a tempHOME. They cover:DEVBOX_USE_VERSION, including rejecting invalid valueschannelfileauto_updateverchecktest for the once-a-day notice. Theverchecktests now use a temp cache dir.HOME, with a release-style build (Version=0.99.0,Launcher=true) and real GitHub releases:DEVBOX_USE_VERSION, the first run pinning the latest version, and a stale cache starting the background check (12ms)devbox version updatereplaced the script with the binary. Afterwards it ran 0.18.5 withLauncher: 1.0.0.version updatedoesn't replace an up-to-date launcher,--launcherdoes, and a dev build gets the "not installed with the installer" errorscripts/install.sh -f, with its install dir pointed at a temp dir, installed 0.18.5 and wrotecurrent-version🤖 Generated with Claude Code