Skip to content

Commit a859c19

Browse files
committed
ensure packages are installable, and cleanup, enable php testscript
1 parent d782e61 commit a859c19

File tree

5 files changed

+77
-70
lines changed

5 files changed

+77
-70
lines changed

.github/workflows/cli-tests.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,8 @@ jobs:
129129
run-project-tests: ["project-tests", "project-tests-off"]
130130
# Run tests on:
131131
# 1. the oldest supported nix version (which is 2.9.0? But determinate-systems installer has 2.12.0)
132-
# 2. nix version 2.17.0 which introduces a new code path that minimizes nixpkgs downloads.
133-
# 3. latest nix version
134-
nix-version: ["2.12.0", "2.17.0", "2.19.2"]
132+
# 2. latest nix version, must be > 2.17.0 which introduces a new code path that minimizes nixpkgs downloads.
133+
nix-version: ["2.12.0", "2.19.2"]
135134
exclude:
136135
- is-main: "not-main"
137136
os: "${{ inputs.run-mac-tests && 'dummy' || 'macos-latest' }}"

internal/devbox/nixprofile.go

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7-
"slices"
87
"strings"
98

109
"go.jetpack.io/devbox/internal/nix"
1110
"go.jetpack.io/devbox/internal/nix/nixprofile"
1211
)
1312

13+
// syncFlakeToProfile ensures the buildInputs from the flake's devShell are
14+
// installed in the nix profile.
1415
func (d *Devbox) syncFlakeToProfile(ctx context.Context) error {
1516
profilePath, err := d.profilePath()
1617
if err != nil {
@@ -73,6 +74,7 @@ func (d *Devbox) syncFlakeToProfile(ctx context.Context) error {
7374
Installable: addPath,
7475
// Install in offline mode for speed. We know we should have all the files
7576
// locally in /nix/store since we have run `nix print-dev-env` prior to this.
77+
// Also avoids some "substituter not found for store-path" errors.
7678
Offline: true,
7779
PackageName: storePath.Name,
7880
ProfilePath: profilePath,
@@ -86,30 +88,24 @@ func (d *Devbox) syncFlakeToProfile(ctx context.Context) error {
8688
}
8789

8890
func diffStorePaths(got, want []string) (add, remove []string) {
89-
slices.Sort(got)
90-
slices.Sort(want)
91+
gotSet := map[string]bool{}
92+
for _, g := range got {
93+
gotSet[g] = true
94+
}
95+
wantSet := map[string]bool{}
96+
for _, w := range want {
97+
wantSet[w] = true
98+
}
9199

92-
var gotIdx, wantIdx int
93-
for {
94-
if gotIdx >= len(got) {
95-
add = append(add, want[wantIdx:]...)
96-
break
97-
}
98-
if wantIdx >= len(want) {
99-
remove = append(remove, got[gotIdx:]...)
100-
break
100+
for _, g := range got {
101+
if _, ok := wantSet[g]; !ok {
102+
remove = append(remove, g)
101103
}
104+
}
102105

103-
switch {
104-
case got[gotIdx] == want[wantIdx]:
105-
gotIdx++
106-
wantIdx++
107-
case got[gotIdx] < want[wantIdx]:
108-
remove = append(remove, got[gotIdx])
109-
gotIdx++
110-
case got[gotIdx] > want[wantIdx]:
111-
add = append(add, want[wantIdx])
112-
wantIdx++
106+
for _, w := range want {
107+
if _, ok := gotSet[w]; !ok {
108+
add = append(add, w)
113109
}
114110
}
115111
return add, remove

internal/devbox/packages.go

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,13 @@ func (d *Devbox) ensureStateIsUpToDate(ctx context.Context, mode installMode) er
266266
fmt.Fprintln(d.stderr, "Ensuring packages are installed.")
267267
}
268268

269+
// Validate packages. Must be run up-front and definitely prior to computeEnv
270+
// and syncFlakeToProfile below that will evaluate the flake and may give
271+
// inscrutable errors if the package is uninstallable.
272+
if err := d.validatePackages(); err != nil {
273+
return err
274+
}
275+
269276
// Create plugin directories first because packages might need them
270277
for _, pkg := range d.InstallablePackages() {
271278
if err := d.PluginManager().Create(pkg); err != nil {
@@ -285,13 +292,15 @@ func (d *Devbox) ensureStateIsUpToDate(ctx context.Context, mode installMode) er
285292
return err
286293
}
287294

288-
// Use the printDevEnvCache if we are adding or removing or updating any package,
289-
// AND we are not in the shellenv-enabled environment of the current devbox-project.
290-
usePrintDevEnvCache := mode != ensure && !d.IsEnvEnabled()
291-
if _, err := d.computeEnv(ctx, usePrintDevEnvCache); err != nil {
295+
// Skip the print-dev-env's cache if we are in a devbox-environment. If not,
296+
// skip the cache if we're either installing packages or ensuring
297+
// the project state is up-to-date.
298+
skipPrintDevEnvCache := d.IsEnvEnabled() || (mode == ensure || mode == install)
299+
if _, err := d.computeEnv(ctx, !skipPrintDevEnvCache /*usePrintDevEnvCache*/); err != nil {
292300
return err
293301
}
294302

303+
// Ensure the nix profile has the packages from the flake.
295304
if err := d.syncFlakeToProfile(ctx); err != nil {
296305
return err
297306
}
@@ -379,3 +388,37 @@ func (d *Devbox) InstallRunXPackages(ctx context.Context) error {
379388
}
380389
return nil
381390
}
391+
392+
// validatePackages will ensure that packages are available to be installed
393+
// in the user's current system.
394+
func (d *Devbox) validatePackages() error {
395+
for _, pkg := range d.InstallablePackages() {
396+
397+
inCache, err := pkg.IsInBinaryCache()
398+
if err != nil {
399+
return err
400+
}
401+
402+
if !inCache && nix.IsGithubNixpkgsURL(pkg.URLForFlakeInput()) {
403+
if err := nix.EnsureNixpkgsPrefetched(d.stderr, pkg.HashFromNixPkgsURL()); err != nil {
404+
return err
405+
}
406+
if exists, err := pkg.ValidateInstallsOnSystem(); err != nil {
407+
return err
408+
} else if !exists {
409+
platform := nix.System()
410+
return usererr.New(
411+
"package %s cannot be installed on your platform %s.\n"+
412+
"If you know this package is incompatible with %[2]s, then "+
413+
"you could run `devbox add %[1]s --exclude-platform %[2]s` and re-try.\n"+
414+
"If you think this package should be compatible with %[2]s, then "+
415+
"it's possible this particular version is not available yet from the nix registry. "+
416+
"You could try `devbox add` with a different version for this package.\n",
417+
pkg.Raw,
418+
platform,
419+
)
420+
}
421+
}
422+
}
423+
return nil
424+
}

internal/nix/nixprofile/profile.go

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"github.com/fatih/color"
1616
"github.com/pkg/errors"
1717
"github.com/samber/lo"
18-
"go.jetpack.io/devbox/internal/boxcli/usererr"
1918
"go.jetpack.io/devbox/internal/devpkg"
2019
"go.jetpack.io/devbox/internal/lock"
2120
"go.jetpack.io/devbox/internal/nix"
@@ -207,35 +206,8 @@ type ProfileInstallPackageArgs struct {
207206
// ProfileInstallPackage installs a Devbox package into a profile.
208207
// TODO drop the Profile prefix from this name.
209208
func ProfileInstallPackage(ctx context.Context, args *ProfileInstallPackageArgs) error {
210-
input := devpkg.PackageFromStringWithDefaults(args.Package, args.Lockfile)
211-
212-
inCache, err := input.IsInBinaryCache()
213-
if err != nil {
214-
return err
215-
}
216-
217-
if !inCache && nix.IsGithubNixpkgsURL(input.URLForFlakeInput()) {
218-
if err := nix.EnsureNixpkgsPrefetched(args.Writer, input.HashFromNixPkgsURL()); err != nil {
219-
return err
220-
}
221-
if exists, err := input.ValidateInstallsOnSystem(); err != nil {
222-
return err
223-
} else if !exists {
224-
platform := nix.System()
225-
return usererr.New(
226-
"package %s cannot be installed on your platform %s.\n"+
227-
"If you know this package is incompatible with %[2]s, then "+
228-
"you could run `devbox add %[1]s --exclude-platform %[2]s` and re-try.\n"+
229-
"If you think this package should be compatible with %[2]s, then "+
230-
"it's possible this particular version is not available yet from the nix registry. "+
231-
"You could try `devbox add` with a different version for this package.\n",
232-
input.Raw,
233-
platform,
234-
)
235-
}
236-
}
237-
238-
installable, err := input.Installable()
209+
pkg := devpkg.PackageFromStringWithDefaults(args.Package, args.Lockfile)
210+
installable, err := pkg.Installable()
239211
if err != nil {
240212
return err
241213
}
@@ -244,6 +216,7 @@ func ProfileInstallPackage(ctx context.Context, args *ProfileInstallPackageArgs)
244216
Installable: installable,
245217
PackageName: args.Package,
246218
ProfilePath: args.ProfilePath,
219+
Writer: args.Writer,
247220
})
248221
}
249222

testscripts/languages/php.test.txt

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
exec devbox run php index.php
22
stdout 'done\n'
33

4-
# temporarily disable rm test until we fix. It requires ensuring that package
5-
# in profile matches the flake we are installing.
6-
# For non-flakes, this involves comparing versions. For flakes we need to compare
7-
# the content (or hash)
8-
9-
# exec devbox rm php81Extensions.ds
10-
# exec devbox run php index.php
11-
# stdout 'ds extension is not enabled'
4+
exec devbox rm php81Extensions.ds
5+
exec devbox run php index.php
6+
stdout 'ds extension is not enabled'
127

13-
# exec devbox add php81Extensions.ds
14-
# exec devbox run php index.php
15-
# stdout 'done\n'
8+
exec devbox add php81Extensions.ds
9+
exec devbox run php index.php
10+
stdout 'done\n'
1611

1712
-- devbox.json --
1813
{
1914
"packages": [
2015
"php81@latest",
16+
"php81Packages.composer@latest",
2117
"php81Extensions.ds@latest"
2218
]
2319
}

0 commit comments

Comments
 (0)