Skip to content

Commit 5814521

Browse files
authored
[nix] ensure nix is installed for generate and envsec commands (#1710)
## Summary TSIA ## How was it tested? ran `generate`, `envsec` commands and it worked as expected. Tested version check by temporarily requiring minimum version above mine.
1 parent 11bb6f0 commit 5814521

File tree

5 files changed

+51
-33
lines changed

5 files changed

+51
-33
lines changed

internal/boxcli/envsec.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ type envsecInitCmdFlags struct {
1818

1919
func envsecCmd() *cobra.Command {
2020
cmd := &cobra.Command{
21-
Use: "envsec",
22-
Short: "envsec commands",
21+
Use: "envsec",
22+
Short: "envsec commands",
23+
PreRunE: ensureNixInstalled,
2324
}
2425
cmd.AddCommand(envsecInitCmd())
2526
cmd.Hidden = true

internal/boxcli/generate.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ func generateCmd() *cobra.Command {
2525
flags := &generateCmdFlags{}
2626

2727
command := &cobra.Command{
28-
Use: "generate",
29-
Short: "Generate supporting files for your project",
30-
Args: cobra.MaximumNArgs(0),
28+
Use: "generate",
29+
Short: "Generate supporting files for your project",
30+
Args: cobra.MaximumNArgs(0),
31+
PersistentPreRunE: ensureNixInstalled,
3132
}
3233
command.AddCommand(devcontainerCmd())
3334
command.AddCommand(dockerfileCmd())

internal/boxcli/setup.go

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,12 @@
44
package boxcli
55

66
import (
7-
"fmt"
87
"os"
98

109
"github.com/samber/lo"
1110
"github.com/spf13/cobra"
12-
"go.jetpack.io/devbox/internal/boxcli/usererr"
1311
"go.jetpack.io/devbox/internal/nix"
1412
"go.jetpack.io/devbox/internal/ux"
15-
"go.jetpack.io/devbox/internal/vercheck"
1613
)
1714

1815
const nixDaemonFlag = "daemon"
@@ -51,24 +48,15 @@ func runInstallNixCmd(cmd *cobra.Command) error {
5148

5249
// ensureNixInstalled verifies that nix is installed and that it is of a supported version
5350
func ensureNixInstalled(cmd *cobra.Command, _args []string) error {
54-
if err := nix.EnsureNixInstalled(cmd.ErrOrStderr(), nixDaemonFlagVal(cmd)); err != nil {
55-
return err
56-
}
57-
58-
ver, err := nix.Version()
59-
if err != nil {
60-
return fmt.Errorf("failed to get nix version: %w", err)
61-
}
62-
63-
// ensure minimum nix version installed
64-
if vercheck.SemverCompare(ver, "2.12.0") < 0 {
65-
return usererr.New("Devbox requires nix of version >= 2.12. Your version is %s. Please upgrade nix and try again.\n", ver)
66-
}
67-
return nil
51+
return nix.EnsureNixInstalled(cmd.ErrOrStderr(), nixDaemonFlagVal(cmd))
6852
}
6953

7054
// We return a closure to avoid printing the warning every time and just
7155
// printing it if we actually need the value of the flag.
56+
//
57+
// TODO: devbox.Open should run nix.EnsureNixInstalled and do this logic
58+
// internally. Then setup can decide if it wants to pass in the value of the
59+
// nixDaemonFlag (if changed).
7260
func nixDaemonFlagVal(cmd *cobra.Command) func() *bool {
7361
return func() *bool {
7462
if !cmd.Flags().Changed(nixDaemonFlag) {

internal/devbox/devbox.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ func Open(opts *devopt.Opts) (*Devbox, error) {
124124

125125
if !opts.IgnoreWarnings &&
126126
!legacyPackagesWarningHasBeenShown &&
127+
// HasDeprecatedPackages required nix to be installed. Since not all
128+
// commands require nix to be installed, only show this warning for commands
129+
// that ensure nix.
130+
// This warning can probably be removed soon.
131+
nix.Ensured() &&
127132
box.HasDeprecatedPackages() {
128133
legacyPackagesWarningHasBeenShown = true
129134
globalPath, err := GlobalDataPath()
@@ -481,12 +486,6 @@ func (d *Devbox) GenerateEnvrcFile(ctx context.Context, force bool, envFlags dev
481486
"Remove it or use --force to overwrite it.",
482487
)
483488
}
484-
// confirm .envrc doesn't exist and don't overwrite an existing .envrc
485-
if err := nix.EnsureNixInstalled(
486-
d.stderr, func() *bool { return lo.ToPtr(false) },
487-
); err != nil {
488-
return err
489-
}
490489

491490
// generate all shell files to ensure we can refer to them in the .envrc script
492491
if err := d.ensureStateIsUpToDate(ctx, ensure); err != nil {

internal/nix/install.go

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,13 @@ import (
2121
"go.jetpack.io/devbox/internal/cmdutil"
2222
"go.jetpack.io/devbox/internal/fileutil"
2323
"go.jetpack.io/devbox/internal/ux"
24+
"go.jetpack.io/devbox/internal/vercheck"
2425
)
2526

26-
const rootError = "warning: installing Nix as root is not supported by this script!"
27+
const (
28+
minNixVersion = "2.12.0"
29+
rootError = "warning: installing Nix as root is not supported by this script!"
30+
)
2731

2832
// Install runs the install script for Nix. daemon has 3 states
2933
// nil is unset. false is --no-daemon. true is --daemon.
@@ -95,13 +99,38 @@ func isRoot() bool {
9599
return os.Geteuid() == 0
96100
}
97101

102+
var ensured = false
103+
104+
func Ensured() bool {
105+
return ensured
106+
}
107+
98108
func EnsureNixInstalled(writer io.Writer, withDaemonFunc func() *bool) (err error) {
109+
ensured = true
99110
defer func() {
100-
if err == nil {
101-
// call ComputeSystem to ensure its value is internally cached so other
102-
// callers can rely on just calling System
103-
err = ComputeSystem()
111+
if err != nil {
112+
return
113+
}
114+
version := ""
115+
version, err = Version()
116+
if err != nil {
117+
err = fmt.Errorf("failed to get nix version: %w", err)
118+
return
119+
}
120+
121+
// ensure minimum nix version installed
122+
if vercheck.SemverCompare(version, minNixVersion) < 0 {
123+
err = usererr.New(
124+
"Devbox requires nix of version >= %s. Your version is %s. "+
125+
"Please upgrade nix and try again.\n",
126+
minNixVersion,
127+
version,
128+
)
129+
return
104130
}
131+
// call ComputeSystem to ensure its value is internally cached so other
132+
// callers can rely on just calling System
133+
err = ComputeSystem()
105134
}()
106135

107136
if BinaryInstalled() {

0 commit comments

Comments
 (0)