-
Notifications
You must be signed in to change notification settings - Fork 354
Expand file tree
/
Copy pathinstall.go
More file actions
115 lines (98 loc) · 2.9 KB
/
Copy pathinstall.go
File metadata and controls
115 lines (98 loc) · 2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Copyright 2024 Jetify Inc. and contributors. All rights reserved.
// Use of this source code is governed by the license in the LICENSE file.
package nix
import (
"context"
_ "embed"
"fmt"
"io"
"os"
"time"
"github.com/briandowns/spinner"
"github.com/fatih/color"
"github.com/mattn/go-isatty"
"go.jetify.com/devbox/internal/boxcli/usererr"
"go.jetify.com/devbox/internal/fileutil"
"go.jetify.com/devbox/nix"
)
func BinaryInstalled() bool {
// Use the same resolver that Devbox uses to run nix commands (searching
// $PATH and well-known install locations), rather than a bare $PATH lookup.
// Otherwise Devbox can wrongly report nix as missing when it exists at a
// known location but isn't on $PATH — e.g. on NixOS, or when a non-POSIX
// login shell such as fish hasn't sourced the Nix profile (issue #2787).
_, err := nix.Default.LookPath()
return err == nil
}
func dirExistsAndIsNotEmpty(dir string) bool {
empty, err := fileutil.IsDirEmpty(dir)
return err == nil && !empty
}
var ensured = false
func Ensured() bool {
return ensured
}
func EnsureNixInstalled(ctx context.Context, writer io.Writer, withDaemonFunc func() *bool) (err error) {
ensured = true
defer func() {
if err != nil {
return
}
// ensure minimum nix version installed
if !nix.AtLeast(MinVersion) {
err = usererr.New(
"Devbox requires nix of version >= %s. Your version is %s. "+
"Please upgrade nix and try again.\n",
MinVersion,
nix.Version(),
)
return
}
}()
if BinaryInstalled() {
return nil
}
if dirExistsAndIsNotEmpty("/nix") {
if _, err = SourceProfile(); err != nil {
return err
} else if BinaryInstalled() {
return nil
}
return usererr.New(
"We found a /nix directory but nix binary is not in your PATH and we " +
"were not able to find it in the usual locations. Your nix installation " +
"might be broken. If restarting your terminal or reinstalling nix " +
"doesn't work, please create an issue at " +
"https://github.com/jetify-com/devbox/issues",
)
}
color.Yellow("\nNix is not installed. Devbox will attempt to install it.\n\n")
installer := nix.Installer{}
if isatty.IsTerminal(os.Stdout.Fd()) {
color.Yellow("Press enter to continue or ctrl-c to exit.\n")
fmt.Scanln() //nolint:errcheck
spinny := spinner.New(spinner.CharSets[11], 100*time.Millisecond, spinner.WithWriter(writer))
spinny.Suffix = " Downloading the Nix installer..."
spinny.Start()
defer spinny.Stop() // reset the terminal in case of a panic
err = installer.Download(ctx)
if err != nil {
return err
}
spinny.Stop()
} else {
fmt.Fprint(writer, "Downloading the Nix installer...")
err = installer.Download(ctx)
if err != nil {
fmt.Fprintln(writer)
return err
}
fmt.Fprintln(writer, " done.")
}
err = installer.Run(ctx)
if err != nil {
return err
}
fmt.Fprintln(writer, "Nix installed successfully. Devbox is ready to use!")
return nil
}