Skip to content

feat(pkgdef): wire package definitions into add, lock, install and env - #3002

Open
mikeland73 wants to merge 1 commit into
mikeland73/pkgdef-libfrom
mikeland73/pkgdef-wiring
Open

mikeland73 wants to merge 1 commit into
mikeland73/pkgdef-libfrom
mikeland73/pkgdef-wiring

Conversation

@mikeland73

Copy link
Copy Markdown
Collaborator

Summary

Third PR of the package definitions stack. Teaches Devbox the pkg:<ref>@<version> package string, behind the DEVBOX_FEATURE_PKG_DEFS flag (on in dev builds). While the flag is off, pkg: strings are not recognized at all.

DEVBOX_FEATURE_PKG_DEFS=1 devbox add pkg:./go.pkg.json@1.22
devbox run -- go version   # go version go1.22.12 darwin/arm64, from go.dev
  • pkgtype.IsPkgDef recognizes the scheme and keeps it out of flake detection. devpkg treats such packages as non-nix (shellgen and the nix store paths skip them), splits name and version at the last @, and resolves them through the lockfile so devbox add surfaces the definition's own errors instead of falling back to nixpkgs.
  • devbox.lock gains definition_hash and per-system url/sha256 (additive, lockfile_version unchanged). Remote definitions stay pinned to the hash except on devbox update, which also records a changed hash when version and artifacts are unchanged. A definition without a checksum source gets its digest recorded by the first install (trust on first use), only from the install path, never while computing the environment.
  • installPackages installs package definitions next to runx packages; computeEnv appends their bin directories to PATH. Unsupported system fails with an --exclude-platform hint. Relative file:// URLs stay relative in the lockfile and resolve against the definition's directory when fetching, so lockfiles are portable.
  • Each resolved definition becomes a plugin config (virtenv pkgdef-<name>), so env, shell.init_hook and create_files apply through the plugin manager with InstallDir, Version, CacheDir, System, OS and Arch template variables. A definition that cannot be loaded does not block config loading, so devbox update and devbox rm always work.
  • Local definition files feed the config hash, and installs carry an install fingerprint, so editing a definition's install recipe redoes the install.

The spec's status table is updated accordingly.

Test plan

  • testscripts/pkgdef/pkgdef.test.txt: add with a version prefix, lockfile contents, binary on PATH, env/init hook/create_files templating, version switch, unknown version error, remove
  • Unit tests in internal/pkgdef, internal/devpkg, internal/devbox (update merge records a changed definition hash), internal/plugin, internal/devconfig
  • Manual: real pkgs/go/go.pkg.json on macOS arm64 installs Go 1.22.12 from go.dev with all four platform checksums locked; which go and go env GOROOT point into the cache
  • golangci-lint ./... and gofumpt clean

🤖 Generated with Claude Code

Teach Devbox the "pkg:<ref>@<version>" package string behind the
DEVBOX_FEATURE_PKG_DEFS flag (on in dev builds). See
specs/package-definitions.md.

- pkgtype.IsPkgDef recognizes the scheme and keeps it out of flake
  detection; devpkg treats such packages as non-nix so shellgen and the
  nix store paths skip them, and ValidateExists resolves them through
  the lockfile so `devbox add` surfaces the definition's own errors.
- devbox.lock gains definition_hash and per-system url/sha256. Remote
  definitions are pinned to the hash except on `devbox update`; a
  definition without a checksum source gets its digest recorded by the
  first install (trust on first use) and kept across updates.
- installPackages installs package definitions next to runx packages
  into $XDG_CACHE_HOME/devbox/pkgs and computeEnv appends their bin
  directories to PATH. A definition that does not support the current
  system fails with an --exclude-platform hint.
- Each resolved package definition becomes a plugin config so its env,
  shell.init_hook and create_files apply through the plugin manager,
  with InstallDir, Version, CacheDir, System, OS and Arch template
  variables. Local definition files feed the config hash so edits
  trigger a reinstall.
- Relative file:// URLs in a local definition resolve against its
  directory, which keeps the new testscript self-contained.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@mikeland73
mikeland73 requested a review from savil October 22, 2026 21:33
@mikeland73
mikeland73 added this pull request to stack #3003 October 22, 2026 21:35

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