Skip to content

fix(nix): parse Nix versions without a patch component#2864

Open
mikeland73 wants to merge 2 commits into
mainfrom
claude/focused-goldberg-bs4px5
Open

fix(nix): parse Nix versions without a patch component#2864
mikeland73 wants to merge 2 commits into
mainfrom
claude/focused-goldberg-bs4px5

Conversation

@mikeland73

Copy link
Copy Markdown
Collaborator

Summary

Fixes #2766.

Newer Nix releases dropped the patch component from their version string. For example, Nix 2.33 reports:

nix (Nix) 2.33pre20251107_479b6b73

(2.33pre…, not 2.33.0pre…). Devbox's versionRegexp required a full major.minor.patch, so it failed to match these strings. parseInfo then returned an empty version, and startup failed with the confusing:

Error: Devbox requires nix of version >= 2.12.0. Your version is . Please upgrade nix and try again.

This blocked devbox shell/init entirely for anyone on a recent Nix.

Fix

  1. versionRegexp — make the patch component optional so it matches both 2.33 and 2.33pre20251107_479b6b73 as well as the existing 2.21.2 / 2.23.0pre20240526_7de033d6 forms.
  2. Info.AtLeast — extract a small Info.semver() helper that coerces a Nix version into a valid semver before comparing. A two-component prerelease such as 2.33pre… coerces to v2.33.0-pre.20251107+479b6b73 (inserting the .0 patch), because the semver package requires major.minor.patch for prerelease versions. Without this, even after the regex matched, the version would still compare as invalid and the check would keep failing.

How was it tested?

  • go test ./nix/ passes.
  • Added regression cases to TestParseVersionInfoShort (2.33, 2.33pre20251107_479b6b73) and to TestVersionInfoAtLeast (verifying 2.33 and 2.33pre… satisfy >= MinVersion and compare correctly against neighboring versions).
  • Verified all pre-existing version/AtLeast assertions (including the #2128 prerelease cases) still pass unchanged.

cc @Electrenator (issue reporter)


Generated by Claude Code

Newer Nix releases drop the patch component from their version string
(e.g. "2.33" and prereleases like "2.33pre20251107_479b6b73"). The
version regexp required major.minor.patch, so it failed to match these,
leaving the detected version empty. Devbox then reported:

    Error: Devbox requires nix of version >= 2.12.0. Your version is .

Make the patch component optional in the regexp, and coerce two-component
prerelease versions into valid semver (inserting a ".0" patch) before
comparing in Info.AtLeast, since semver requires major.minor.patch for
prerelease versions.

Fixes #2766
Copilot AI review requested due to automatic review settings June 11, 2026 14:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates Devbox’s Nix version detection to handle newer Nix releases that omit the patch component (e.g. 2.33 / 2.33pre…), preventing startup failures caused by an unparsed/invalid version.

Changes:

  • Relax versionRegexp to make the patch component optional while continuing to support existing prerelease/build variants.
  • Refactor version comparison logic by introducing an Info.semver() coercion helper and using it in Info.AtLeast.
  • Add regression tests covering patchless versions and patchless prereleases.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
nix/nix.go Accepts patchless Nix versions in parsing and coerces Nix versions into valid semver for comparisons.
nix/nix_test.go Adds regression tests for parsing and AtLeast behavior with patchless versions/prereleases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread nix/nix.go Outdated
if strings.Count(base, ".") == 1 {
base += ".0"
}
return "v" + base + suffix

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in fbf8f80. Info.semver() now validates the coerced value with semver.IsValid and returns "" on failure, matching the docstring and preventing invalid strings from reaching any future callers.


Generated by Claude Code

Match the documented contract by validating the coerced value before
returning it, so semver() never propagates an invalid semver string.
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.

Devbox unable to detect version

3 participants