Skip to content

feat(pkgdef): support the initial package set - #3035

Open
mikeland73 wants to merge 1 commit into
mikeland73/pkgdef-packagesfrom
mikeland73/pkgdef-package-support
Open

mikeland73 wants to merge 1 commit into
mikeland73/pkgdef-packagesfrom
mikeland73/pkgdef-package-support

Conversation

@mikeland73

@mikeland73 mikeland73 commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Fifth PR of the package definitions stack. Implements the format features from #3034 that the initial package set needs, and fixes a wiring bug the package tests found.

Platforms a version isn't published for. A 404 from a checksum file or index, a checksum list without the file, a jq expression that matches nothing, or a GitHub release without the asset all mean ErrNoArtifact. Lock leaves that system out and fails only when no platform has an artifact. Installing on a system the lock entry leaves out is a user error that names the platforms the version is available for.

New format features:

  • install.lookup: read the URL and checksum from a JSON index with a jq expression. Used by python, java and zig.
  • install.version_overrides: partial installs for versions matching a constraint (<11, >=2, <4). They apply before system overrides, and a version override can carry its own system overrides.
  • versions as a list of sources, combined.
  • Lazy pagination: github_releases reads 100 per page, and http_json paginates when its URL contains {{.Page}}. Resolution stops at the first page with a match, so latest costs one request.
  • Versions with +build metadata compare correctly and prefix-match (21.0.12 matches 21.0.12+101). Build metadata containing letters is not a pre-release.
  • Checksums: sha512, sha256:/sha512: prefixes and SRI digests; a new sha512_url type; and github_release, which reads GitHub's asset digests through the authenticated API. devbox.lock gets an omitempty sha512 per system.
  • binaries are made executable after extraction and must exist after install.
  • post_install runs through /bin/sh, with /usr/bin:/bin appended to PATH.
  • Template function splitList.

Other library changes:

  • The client memoizes metadata responses, so locking four systems fetches an index once. Remote definition loads are not memoized, so a changed definition is still detected.
  • The install fingerprint now takes the version, since overrides can make two versions install differently.

Wiring fix. After a version was changed in devbox.json, the first devbox run resolved and installed it but ran without the definition's env and init hook (JAVA_HOME, RUSTUP_TOOLCHAIN, the python venv). Plugin configs are built at config load, before the lock entry exists. ensureStateIsUpToDate now reloads includes after installing when the project has package definitions.

Test plan

  • New unit tests: digest parsing; lock skipping systems without artifacts; lookup (including an install with no locked artifact, and a 404 index); github_release digests (with token, null digest, missing asset); sha512 verification, including against the marker; binaries chmod and the missing-binary error; hooks with an empty PATH; combined version sources; pagination for http_json and GitHub releases (stops early, stops at a 404 or a short page); version overrides precedence and validation; build metadata; constraints
  • testscripts/pkgdef: editing devbox.json to a version not yet in devbox.lock applies env and init hook in the same run. This fails without the fix
  • go test ./internal/..., golangci-lint and gofumpt clean
  • The per-package tests in test(pkgs): install and switch versions of every shipped package #3036 pass on macOS arm64 and Linux arm64

🤖 Generated with Claude Code

Implement what the initial package definitions need:

- Platforms a version is not published for: a 404 from a checksum file
  or index, a checksum list without the file, a jq expression that
  matches nothing or a GitHub release without the asset is ErrNoArtifact.
  Lock leaves those systems out and fails only when none has an artifact;
  installing on a left-out system is an error naming where the version is
  available.
- install.lookup reads the artifact URL and checksum from a JSON index
  (python-build-standalone via uv's index, Temurin, zig).
- install.version_overrides apply partial installs to versions matching a
  constraint such as "<11" (pnpm, yarn, deno).
- versions may be a list of sources (yarn 1 and 2+ are different npm
  packages). github_releases and http_json URLs with {{.Page}} paginate
  lazily, stopping at the first page with a match.
- Versions with +build metadata (21.0.5+11) compare and prefix-match.
- sha512 digests and SRI strings, a sha512_url checksum type, and a
  github_release type that reads GitHub's asset digests. devbox.lock gets
  an omitempty sha512 per system.
- binaries are made executable after extraction and must exist after
  install. post_install hooks run with /bin/sh and /usr/bin:/bin on PATH.
- Metadata requests are memoized per client, so locking four systems
  fetches an index once. Install fingerprints include the version, since
  overrides can make versions install differently.
- ensureStateIsUpToDate reloads plugin configs after installing, so a
  version changed in devbox.json gets its definition's env and init hook
  in the same run instead of the next one.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant