@@ -5,17 +5,18 @@ package lock
55
66import (
77 "context"
8- "fmt"
98 "io/fs"
9+ "maps"
1010 "path/filepath"
11+ "slices"
1112 "strings"
1213
1314 "github.com/pkg/errors"
14- "github.com/samber/lo"
1515 "go.jetpack.io/devbox/internal/cachehash"
1616 "go.jetpack.io/devbox/internal/devpkg/pkgtype"
1717 "go.jetpack.io/devbox/internal/nix"
1818 "go.jetpack.io/devbox/internal/searcher"
19+ "go.jetpack.io/devbox/nix/flake"
1920 "go.jetpack.io/pkg/runx/impl/types"
2021
2122 "go.jetpack.io/devbox/internal/cuecfg"
@@ -74,25 +75,32 @@ func (f *File) Remove(pkgs ...string) error {
7475// This avoids writing values that may need to be removed in case of error.
7576func (f * File ) Resolve (pkg string ) (* Package , error ) {
7677 entry , hasEntry := f .Packages [pkg ]
78+ if hasEntry && entry .Resolved != "" {
79+ return f .Packages [pkg ], nil
80+ }
7781
78- if ! hasEntry || entry .Resolved == "" {
79- locked := & Package {}
80- var err error
81- if _ , _ , versioned := searcher .ParseVersionedPackage (pkg ); pkgtype .IsRunX (pkg ) || versioned {
82- locked , err = f .FetchResolvedPackage (pkg )
83- if err != nil {
84- return nil , err
85- }
86- } else if IsLegacyPackage (pkg ) {
87- // These are legacy packages without a version. Resolve to nixpkgs with
88- // whatever hash is in the devbox.json
89- locked = & Package {
90- Resolved : f .LegacyNixpkgsPath (pkg ),
91- Source : nixpkgSource ,
92- }
82+ locked := & Package {}
83+ _ , _ , versioned := searcher .ParseVersionedPackage (pkg )
84+ if pkgtype .IsRunX (pkg ) || versioned || pkgtype .IsFlake (pkg ) {
85+ resolved , err := f .FetchResolvedPackage (pkg )
86+ if err != nil {
87+ return nil , err
88+ }
89+ if resolved != nil {
90+ locked = resolved
91+ }
92+ } else if IsLegacyPackage (pkg ) {
93+ // These are legacy packages without a version. Resolve to nixpkgs with
94+ // whatever hash is in the devbox.json
95+ locked = & Package {
96+ Resolved : flake.Installable {
97+ Ref : f .Stdenv (),
98+ AttrPath : pkg ,
99+ }.String (),
100+ Source : nixpkgSource ,
93101 }
94- f .Packages [pkg ] = locked
95102 }
103+ f .Packages [pkg ] = locked
96104
97105 return f .Packages [pkg ], nil
98106}
@@ -133,12 +141,17 @@ func (f *File) Save() error {
133141 return cuecfg .WriteFile (lockFilePath (f .devboxProject .ProjectDir ()), f )
134142}
135143
136- func (f * File ) LegacyNixpkgsPath (pkg string ) string {
137- return fmt .Sprintf (
138- "github:NixOS/nixpkgs/%s#%s" ,
139- f .NixPkgsCommitHash (),
140- pkg ,
141- )
144+ func (f * File ) Stdenv () flake.Ref {
145+ unlocked := f .devboxProject .Stdenv ()
146+ pkg , err := f .Resolve (unlocked .String ())
147+ if err != nil {
148+ return unlocked
149+ }
150+ ref , err := flake .ParseRef (pkg .Resolved )
151+ if err != nil {
152+ return unlocked
153+ }
154+ return ref
142155}
143156
144157func (f * File ) Get (pkg string ) * Package {
@@ -174,10 +187,11 @@ func IsLegacyPackage(pkg string) bool {
174187// Tidy ensures that the lockfile has the set of packages corresponding to the devbox.json config.
175188// It gets rid of older packages that are no longer needed.
176189func (f * File ) Tidy () {
177- f .Packages = lo .PickByKeys (
178- f .Packages ,
179- f .devboxProject .AllPackageNamesIncludingRemovedTriggerPackages (),
180- )
190+ keep := f .devboxProject .AllPackageNamesIncludingRemovedTriggerPackages ()
191+ keep = append (keep , f .devboxProject .Stdenv ().String ())
192+ maps .DeleteFunc (f .Packages , func (key string , pkg * Package ) bool {
193+ return ! slices .Contains (keep , key )
194+ })
181195}
182196
183197// IsUpToDateAndInstalled returns true if the lockfile is up to date and the
0 commit comments