diff --git a/internal/devbox/devbox.go b/internal/devbox/devbox.go index e90dab2bb64..22a1d22e3de 100644 --- a/internal/devbox/devbox.go +++ b/internal/devbox/devbox.go @@ -249,7 +249,7 @@ func (d *Devbox) Shell(ctx context.Context, envOpts devopt.EnvOptions) error { WithShellStartTime(telemetry.ShellStart()), } - shell, err := NewDevboxShell(d, envOpts, opts...) + shell, err := d.newShell(envOpts, opts...) if err != nil { return err } diff --git a/internal/devbox/shell.go b/internal/devbox/shell.go index df3c714fc13..098a10593e5 100644 --- a/internal/devbox/shell.go +++ b/internal/devbox/shell.go @@ -69,15 +69,15 @@ type DevboxShell struct { type ShellOption func(*DevboxShell) -// NewDevboxShell initializes the DevboxShell struct so it can be used to start a shell environment +// newShell initializes the DevboxShell struct so it can be used to start a shell environment // for the devbox project. -func NewDevboxShell(devbox *Devbox, envOpts devopt.EnvOptions, opts ...ShellOption) (*DevboxShell, error) { - shPath, err := shellPath(devbox, envOpts) +func (d *Devbox) newShell(envOpts devopt.EnvOptions, opts ...ShellOption) (*DevboxShell, error) { + shPath, err := d.shellPath(envOpts) if err != nil { return nil, err } sh := initShellBinaryFields(shPath) - sh.devbox = devbox + sh.devbox = d for _, opt := range opts { opt(sh) @@ -88,7 +88,7 @@ func NewDevboxShell(devbox *Devbox, envOpts devopt.EnvOptions, opts ...ShellOpti } // shellPath returns the path to a shell binary, or error if none found. -func shellPath(devbox *Devbox, envOpts devopt.EnvOptions) (path string, err error) { +func (d *Devbox) shellPath(envOpts devopt.EnvOptions) (path string, err error) { defer func() { if err != nil { path = filepath.Clean(path) @@ -110,7 +110,7 @@ func shellPath(devbox *Devbox, envOpts devopt.EnvOptions) (path string, err erro cmd := exec.Command( "nix", "eval", "--raw", - fmt.Sprintf("%s#bashInteractive", nix.FlakeNixpkgs(devbox.cfg.NixPkgsCommitHash())), + fmt.Sprintf("%s#bashInteractive", d.Lockfile().Stdenv().String()), ) cmd.Args = append(cmd.Args, nix.ExperimentalFlags()...) out, err := cmd.Output() diff --git a/internal/devbox/shell_test.go b/internal/devbox/shell_test.go index 721b0b4d5c8..fc5ddf4e7b3 100644 --- a/internal/devbox/shell_test.go +++ b/internal/devbox/shell_test.go @@ -9,10 +9,12 @@ import ( "io/fs" "os" "path/filepath" + "regexp" "strings" "testing" "github.com/google/go-cmp/cmp" + "go.jetify.com/devbox/internal/devbox/devopt" "go.jetify.com/devbox/internal/envir" "go.jetify.com/devbox/internal/shellgen" ) @@ -105,3 +107,61 @@ If the new shellrc is correct, you can update the golden file with: }) } } + +func TestShellPath(t *testing.T) { + tests := []struct { + name string + envOpts devopt.EnvOptions + expected string + env map[string]string + }{ + { + name: "pure mode enabled", + envOpts: devopt.EnvOptions{ + Pure: true, + }, + expected: `^/nix/store/.*/bin/bash$`, + }, + { + name: "pure mode disabled", + envOpts: devopt.EnvOptions{ + Pure: false, + }, + env: map[string]string{ + envir.Shell: "/usr/local/bin/bash", + }, + expected: "^/usr/local/bin/bash$", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + for k, v := range test.env { + t.Setenv(k, v) + } + tmpDir := t.TempDir() + err := InitConfig(tmpDir) + if err != nil { + t.Fatal("Got InitConfig error:", err) + } + d, err := Open(&devopt.Opts{ + Dir: tmpDir, + Stderr: os.Stderr, + }) + if err != nil { + t.Fatal("Got Open error:", err) + } + gotPath, err := d.shellPath(test.envOpts) + if err != nil { + t.Fatal("Got shellPath error:", err) + } + matched, err := regexp.MatchString(test.expected, gotPath) + if err != nil { + t.Fatal("Got regexp.MatchString error:", err) + } + if !matched { + t.Errorf("Expected shell path %s, but got %s", test.expected, gotPath) + } + }) + } +}