Skip to content

Commit 9122399

Browse files
committed
fixes
1 parent a1eb81d commit 9122399

File tree

9 files changed

+94
-54
lines changed

9 files changed

+94
-54
lines changed

internal/devbox/nixprofile.go

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,42 @@ package devbox
33
import (
44
"context"
55
"encoding/json"
6+
"errors"
67
"fmt"
8+
"os"
79
"os/exec"
810
"slices"
911

1012
"go.jetpack.io/devbox/internal/nix"
13+
"go.jetpack.io/devbox/internal/nix/nixprofile"
1114
)
1215

13-
func syncFlakeToProfile(ctx context.Context, flakePath, profilePath string) error {
14-
cmd := exec.CommandContext(ctx, "nix", "eval", "--json", flakePath+"#devShells."+nix.System()+".default.buildInputs")
15-
cmd.Args = append(cmd.Args, nix.ExperimentalFlags()...)
16-
b, err := cmd.Output()
16+
func (d *Devbox) syncFlakeToProfile(ctx context.Context) error {
17+
profilePath, err := d.profilePath()
1718
if err != nil {
19+
return err
20+
}
1821

22+
cmd := nix.CommandContext(ctx, "eval", "--json", d.flakeDir()+"#devShells."+nix.System()+".default.buildInputs")
23+
fmt.Printf("cmd: %v\n", cmd)
24+
cmd.Stderr = os.Stderr
25+
26+
buildInputPaths, err := cmd.Output()
27+
fmt.Printf("buildInputPaths: %s\n", buildInputPaths)
28+
if err != nil {
29+
if execErr := (&exec.ExitError{}); errors.As(err, &execErr) {
30+
fmt.Printf("ExitError: %v\n", execErr)
31+
}
1932
return fmt.Errorf("nix eval devShells: %v", err)
2033
}
2134
storePaths := []string{}
22-
if err := json.Unmarshal(b, &storePaths); err != nil {
23-
return fmt.Errorf("unmarshal store paths: %s: %v", b, err)
35+
if err := json.Unmarshal(buildInputPaths, &storePaths); err != nil {
36+
return fmt.Errorf("unmarshal store paths: %s: %v", buildInputPaths, err)
2437
}
2538

26-
listCmd := exec.CommandContext(ctx, "nix", "profile", "list", "--json", "--profile", profilePath)
27-
listCmd.Args = append(listCmd.Args, nix.ExperimentalFlags()...)
28-
b, err = listCmd.Output()
39+
listCmd := nix.CommandContext(ctx, "profile", "list", "--json", "--profile", profilePath)
40+
fmt.Printf("listCmd: %s\n", listCmd)
41+
buildInputPaths, err = listCmd.Output()
2942
if err != nil {
3043
return err
3144
}
@@ -34,7 +47,7 @@ func syncFlakeToProfile(ctx context.Context, flakePath, profilePath string) erro
3447
StorePaths []string
3548
}
3649
}
37-
if err := json.Unmarshal(b, &profile); err != nil {
50+
if err := json.Unmarshal(buildInputPaths, &profile); err != nil {
3851
return fmt.Errorf("unmarshal profile: %v", err)
3952
}
4053
got := make([]string, 0, len(profile.Elements))
@@ -44,19 +57,32 @@ func syncFlakeToProfile(ctx context.Context, flakePath, profilePath string) erro
4457

4558
add, remove := diffStorePaths(got, storePaths)
4659
if len(remove) > 0 {
47-
removeCmd := exec.CommandContext(ctx, "nix", "profile", "remove", "--profile", profilePath)
60+
removeCmd := nix.CommandContext(ctx, "profile", "remove", "--profile", profilePath)
4861
removeCmd.Args = append(removeCmd.Args, remove...)
49-
removeCmd.Args = append(removeCmd.Args, nix.ExperimentalFlags()...)
62+
fmt.Printf("removeCmd: %s\n", removeCmd)
5063
if err := removeCmd.Run(); err != nil {
5164
return err
5265
}
5366
}
5467
if len(add) > 0 {
55-
addCmd := exec.CommandContext(ctx, "nix", "profile", "install", "--profile", profilePath)
56-
addCmd.Args = append(addCmd.Args, add...)
57-
addCmd.Args = append(addCmd.Args, nix.ExperimentalFlags()...)
58-
if err := addCmd.Run(); err != nil {
59-
return err
68+
total := len(add)
69+
for idx, addPath := range add {
70+
stepNum := idx + 1
71+
72+
stepMsg := fmt.Sprintf("[%d/%d] %s", stepNum, total, addPath)
73+
74+
if err = nixprofile.ProfileInstall(ctx, &nixprofile.ProfileInstallArgs{
75+
CustomStepMessage: stepMsg,
76+
Installable: addPath,
77+
PackageName: addPath, // TODO: parse the name and version from the /nix/store path
78+
ProfilePath: profilePath,
79+
Writer: d.stderr,
80+
}); err != nil {
81+
if execErr := (&exec.ExitError{}); errors.As(err, &execErr) {
82+
fmt.Printf("ExitError: %v\n", execErr)
83+
}
84+
return fmt.Errorf("error installing package %s: %w", addPath, err)
85+
}
6086
}
6187
}
6288
return nil
@@ -66,27 +92,27 @@ func diffStorePaths(got, want []string) (add, remove []string) {
6692
slices.Sort(got)
6793
slices.Sort(want)
6894

69-
var g, w int
95+
var gotIdx, wantIdx int
7096
for {
71-
if g >= len(got) {
72-
add = append(add, want[w:]...)
97+
if gotIdx >= len(got) {
98+
add = append(add, want[wantIdx:]...)
7399
break
74100
}
75-
if w >= len(want) {
76-
remove = append(remove, got[g:]...)
101+
if wantIdx >= len(want) {
102+
remove = append(remove, got[gotIdx:]...)
77103
break
78104
}
79105

80106
switch {
81-
case got[g] == want[w]:
82-
g++
83-
w++
84-
case got[g] < want[w]:
85-
remove = append(remove, got[g])
86-
g++
87-
case got[g] > want[w]:
88-
add = append(add, want[w])
89-
w++
107+
case got[gotIdx] == want[wantIdx]:
108+
gotIdx++
109+
wantIdx++
110+
case got[gotIdx] < want[wantIdx]:
111+
remove = append(remove, got[gotIdx])
112+
gotIdx++
113+
case got[gotIdx] > want[wantIdx]:
114+
add = append(add, want[wantIdx])
115+
wantIdx++
90116
}
91117
}
92118
return add, remove

internal/devbox/packages.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,11 +292,7 @@ func (d *Devbox) ensureStateIsUpToDate(ctx context.Context, mode installMode) er
292292
return err
293293
}
294294

295-
profile, err := d.profilePath()
296-
if err != nil {
297-
return err
298-
}
299-
if err := syncFlakeToProfile(ctx, d.flakeDir(), profile); err != nil {
295+
if err := d.syncFlakeToProfile(ctx); err != nil {
300296
return err
301297
}
302298

internal/devbox/util.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func (d *Devbox) addDevboxUtilityPackage(ctx context.Context, pkg string) error
2626
return err
2727
}
2828

29-
return nixprofile.ProfileInstall(ctx, &nixprofile.ProfileInstallArgs{
29+
return nixprofile.ProfileInstallPackage(ctx, &nixprofile.ProfileInstallPackageArgs{
3030
Lockfile: d.lockfile,
3131
Package: pkg,
3232
ProfilePath: profilePath,

internal/nix/command.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import (
66
)
77

88
func command(args ...string) *exec.Cmd {
9-
return commandContext(context.Background(), args...)
9+
return CommandContext(context.Background(), args...)
1010
}
1111

12-
func commandContext(ctx context.Context, args ...string) *exec.Cmd {
12+
func CommandContext(ctx context.Context, args ...string) *exec.Cmd {
1313
cmd := exec.CommandContext(ctx, "nix", args...)
1414
cmd.Args = append(cmd.Args, ExperimentalFlags()...)
1515
return cmd

internal/nix/nixprofile/profile.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -189,16 +189,16 @@ func parseNixProfileListItem(line string) (*NixProfileListItem, error) {
189189
}, nil
190190
}
191191

192-
type ProfileInstallArgs struct {
192+
type ProfileInstallPackageArgs struct {
193193
CustomStepMessage string
194194
Lockfile *lock.File
195195
Package string
196196
ProfilePath string
197197
Writer io.Writer
198198
}
199199

200-
// ProfileInstall calls nix profile install with default profile
201-
func ProfileInstall(ctx context.Context, args *ProfileInstallArgs) error {
200+
// ProfileInstallPackage calls nix profile install with default profile
201+
func ProfileInstallPackage(ctx context.Context, args *ProfileInstallPackageArgs) error {
202202
input := devpkg.PackageFromStringWithDefaults(args.Package, args.Lockfile)
203203

204204
inCache, err := input.IsInBinaryCache()
@@ -226,20 +226,37 @@ func ProfileInstall(ctx context.Context, args *ProfileInstallArgs) error {
226226
)
227227
}
228228
}
229-
stepMsg := args.Package
229+
230+
installable, err := input.Installable()
231+
if err != nil {
232+
return err
233+
}
234+
return ProfileInstall(ctx, &ProfileInstallArgs{
235+
CustomStepMessage: args.CustomStepMessage,
236+
Installable: installable,
237+
PackageName: args.Package,
238+
ProfilePath: args.ProfilePath,
239+
})
240+
}
241+
242+
type ProfileInstallArgs struct {
243+
CustomStepMessage string
244+
Installable string
245+
PackageName string
246+
ProfilePath string
247+
Writer io.Writer
248+
}
249+
250+
func ProfileInstall(ctx context.Context, args *ProfileInstallArgs) error {
251+
stepMsg := args.PackageName
230252
if args.CustomStepMessage != "" {
231253
stepMsg = args.CustomStepMessage
232254
// Only print this first one if we have a custom message. Otherwise it feels
233255
// repetitive.
234256
fmt.Fprintf(args.Writer, "%s\n", stepMsg)
235257
}
236258

237-
installable, err := input.Installable()
238-
if err != nil {
239-
return err
240-
}
241-
242-
err = nix.ProfileInstall(args.Writer, args.ProfilePath, installable)
259+
err := nix.ProfileInstall(ctx, args.Writer, args.ProfilePath, args.Installable)
243260
if err != nil {
244261
fmt.Fprintf(args.Writer, "%s: ", stepMsg)
245262
color.New(color.FgRed).Fprintf(args.Writer, "Fail\n")

internal/nix/profiles.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package nix
55

66
import (
7+
"context"
78
"encoding/json"
89
"fmt"
910
"io"
@@ -29,7 +30,7 @@ func ProfileList(writer io.Writer, profilePath string, useJSON bool) (string, er
2930
return string(out), nil
3031
}
3132

32-
func ProfileInstall(writer io.Writer, profilePath, installable string) error {
33+
func ProfileInstall(ctx context.Context, writer io.Writer, profilePath, installable string) error {
3334
if !IsInsecureAllowed() && PackageIsInsecure(installable) {
3435
knownVulnerabilities := PackageKnownVulnerabilities(installable)
3536
errString := fmt.Sprintf("Package %s is insecure. \n\n", installable)
@@ -40,7 +41,8 @@ func ProfileInstall(writer io.Writer, profilePath, installable string) error {
4041
return usererr.New(errString)
4142
}
4243

43-
cmd := command(
44+
cmd := CommandContext(
45+
ctx,
4446
"profile", "install",
4547
"--profile", profilePath,
4648
"--impure", // for NIXPKGS_ALLOW_UNFREE

internal/nix/store.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
)
77

88
func StorePathFromHashPart(ctx context.Context, hash, storeAddr string) (string, error) {
9-
cmd := commandContext(ctx, "store", "path-from-hash-part", "--store", storeAddr, hash)
9+
cmd := CommandContext(ctx, "store", "path-from-hash-part", "--store", storeAddr, hash)
1010
resultBytes, err := cmd.Output()
1111
if err != nil {
1212
return "", err

testscripts/languages/php.test.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ stdout 'done\n'
1818
{
1919
"packages": [
2020
"php81@latest",
21-
"php81Packages.composer@latest",
2221
"php81Extensions.ds@latest"
2322
]
2423
}

testscripts/packages/unfree.test.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ exec devbox init
44

55
# we could test with slack and/or vscode. Using slack since it is lighter.
66
exec devbox add slack
7-
stderr 'Installing package: slack.'
7+
stderr 'Adding package "slack@latest" to devbox.json'
88

99
exec devbox rm slack

0 commit comments

Comments
 (0)