-
Notifications
You must be signed in to change notification settings - Fork 731
Expand file tree
/
Copy pathinstall_deps.go
More file actions
264 lines (243 loc) · 8.43 KB
/
Copy pathinstall_deps.go
File metadata and controls
264 lines (243 loc) · 8.43 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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
package system
import "fmt"
// installHintGit returns the platform-specific install hint for git.
func installHintGit(profile PlatformProfile) string {
switch {
case profile.OS == "darwin":
return "brew install git"
case profile.OS == "windows":
return "winget install Git.Git"
case profile.PackageManager == "apt":
return "sudo apt-get install -y git"
case profile.PackageManager == "pacman":
return "sudo pacman -S --noconfirm git"
case profile.PackageManager == "dnf":
return "sudo dnf install -y git"
case profile.PackageManager == "apk":
return "apk add --no-cache git"
default:
return "install git from https://git-scm.com/"
}
}
// installHintCurl returns the platform-specific install hint for curl.
func installHintCurl(profile PlatformProfile) string {
switch {
case profile.OS == "darwin":
return "brew install curl"
case profile.OS == "windows":
return "curl is pre-installed on Windows 10+"
case profile.PackageManager == "apt":
return "sudo apt-get install -y curl"
case profile.PackageManager == "pacman":
return "sudo pacman -S --noconfirm curl"
case profile.PackageManager == "dnf":
return "sudo dnf install -y curl"
case profile.PackageManager == "apk":
return "apk add --no-cache curl"
default:
return "install curl from https://curl.se/"
}
}
// installHintNode returns the platform-specific install hint for Node.js.
func installHintNode(profile PlatformProfile) string {
switch {
case profile.OS == "darwin":
return "brew install node"
case profile.OS == "windows":
return "winget install OpenJS.NodeJS.LTS"
case profile.PackageManager == "apt":
return "curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - && sudo apt-get install -y nodejs"
case profile.PackageManager == "pacman":
return "sudo pacman -S --noconfirm nodejs npm"
case profile.PackageManager == "dnf":
return "curl -fsSL https://rpm.nodesource.com/setup_lts.x | sudo bash - && sudo dnf install -y nodejs"
case profile.PackageManager == "apk":
return "apk add --no-cache nodejs npm"
default:
return "install node from https://nodejs.org/"
}
}
// installHintNpm returns the platform-specific install hint for npm.
func installHintNpm(_ PlatformProfile) string {
// npm comes with node on all platforms.
return "npm is included with node — install node first"
}
// installHintBrew returns the install hint for Homebrew (macOS only).
func installHintBrew() string {
return `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
}
// installHintGo returns the platform-specific install hint for Go.
func installHintGo(profile PlatformProfile) string {
switch {
case profile.OS == "darwin":
return "brew install go"
case profile.OS == "windows":
return "winget install GoLang.Go"
case profile.PackageManager == "apt":
return "sudo apt-get install -y golang"
case profile.PackageManager == "pacman":
return "sudo pacman -S --noconfirm go"
case profile.PackageManager == "dnf":
return "sudo dnf install -y golang"
case profile.PackageManager == "apk":
return "apk add --no-cache go"
default:
return "install go from https://go.dev/dl/"
}
}
// InstallHintForDep returns the platform-specific human-readable install hint for
// the named dependency. Returns an empty string for unknown dependency names.
func InstallHintForDep(name string, profile PlatformProfile) string {
switch name {
case "git":
return installHintGit(profile)
case "curl":
return installHintCurl(profile)
case "node":
return installHintNode(profile)
case "npm":
return installHintNpm(profile)
case "brew":
return installHintBrew()
case "go":
return installHintGo(profile)
default:
return ""
}
}
// InstallCommandsForDep returns the command sequence to install a missing dependency.
// Returns nil if no automatic install is available.
func InstallCommandsForDep(name string, profile PlatformProfile) [][]string {
switch name {
case "git":
return installCommandsGit(profile)
case "curl":
return installCommandsCurl(profile)
case "node":
return installCommandsNode(profile)
case "npm":
// npm comes with node; installing node installs npm.
return nil
case "brew":
return installCommandsBrew(profile)
case "go":
return installCommandsGo(profile)
default:
return nil
}
}
func installCommandsGit(profile PlatformProfile) [][]string {
switch {
case profile.OS == "darwin":
return [][]string{{"brew", "install", "git"}}
case profile.OS == "windows":
return [][]string{{"winget", "install", "--id", "Git.Git", "-e", "--accept-source-agreements", "--accept-package-agreements"}}
case profile.PackageManager == "apt":
return [][]string{{"sudo", "apt-get", "install", "-y", "git"}}
case profile.PackageManager == "pacman":
return [][]string{{"sudo", "pacman", "-S", "--noconfirm", "git"}}
case profile.PackageManager == "dnf":
return [][]string{{"sudo", "dnf", "install", "-y", "git"}}
case profile.PackageManager == "apk":
return [][]string{{"apk", "add", "--no-cache", "git"}}
default:
return nil
}
}
func installCommandsCurl(profile PlatformProfile) [][]string {
switch {
case profile.OS == "darwin":
return [][]string{{"brew", "install", "curl"}}
case profile.OS == "windows":
// curl is pre-installed on Windows 10+, no install command needed.
return nil
case profile.PackageManager == "apt":
return [][]string{{"sudo", "apt-get", "install", "-y", "curl"}}
case profile.PackageManager == "pacman":
return [][]string{{"sudo", "pacman", "-S", "--noconfirm", "curl"}}
case profile.PackageManager == "dnf":
return [][]string{{"sudo", "dnf", "install", "-y", "curl"}}
case profile.PackageManager == "apk":
return [][]string{{"apk", "add", "--no-cache", "curl"}}
default:
return nil
}
}
func installCommandsNode(profile PlatformProfile) [][]string {
switch {
case profile.OS == "darwin":
return [][]string{{"brew", "install", "node"}}
case profile.OS == "windows":
return [][]string{{"winget", "install", "--id", "OpenJS.NodeJS.LTS", "-e", "--accept-source-agreements", "--accept-package-agreements"}}
case profile.PackageManager == "apt":
// NodeSource LTS setup + install.
return [][]string{
{"bash", "-c", "curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -"},
{"sudo", "apt-get", "install", "-y", "nodejs"},
}
case profile.PackageManager == "pacman":
return [][]string{{"sudo", "pacman", "-S", "--noconfirm", "nodejs", "npm"}}
case profile.PackageManager == "dnf":
// Use NodeSource LTS on Fedora/RHEL family for parity with apt-based LTS behavior.
return [][]string{
{"bash", "-c", "curl -fsSL https://rpm.nodesource.com/setup_lts.x | sudo bash -"},
{"sudo", "dnf", "install", "-y", "nodejs"},
}
case profile.PackageManager == "apk":
return [][]string{{"apk", "add", "--no-cache", "nodejs", "npm"}}
default:
return nil
}
}
func installCommandsBrew(profile PlatformProfile) [][]string {
if profile.OS != "darwin" {
return nil
}
return [][]string{
{"bash", "-c", `$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)`},
}
}
func installCommandsGo(profile PlatformProfile) [][]string {
switch {
case profile.OS == "darwin":
return [][]string{{"brew", "install", "go"}}
case profile.OS == "windows":
return [][]string{{"winget", "install", "--id", "GoLang.Go", "-e", "--accept-source-agreements", "--accept-package-agreements"}}
case profile.PackageManager == "apt":
return [][]string{{"sudo", "apt-get", "install", "-y", "golang"}}
case profile.PackageManager == "pacman":
return [][]string{{"sudo", "pacman", "-S", "--noconfirm", "go"}}
case profile.PackageManager == "dnf":
return [][]string{{"sudo", "dnf", "install", "-y", "golang"}}
case profile.PackageManager == "apk":
return [][]string{{"apk", "add", "--no-cache", "go"}}
default:
return nil
}
}
// FormatMissingDepsMessage creates a human-readable message about missing dependencies.
func FormatMissingDepsMessage(report DependencyReport) string {
if report.AllPresent {
return "All required dependencies are present."
}
msg := fmt.Sprintf("Missing %d required dependency(ies): %s\n",
len(report.MissingRequired),
joinStrings(report.MissingRequired))
msg += "\nInstall hints:\n"
for _, dep := range report.Dependencies {
if !dep.Installed && dep.Required {
msg += fmt.Sprintf(" %s: %s\n", dep.Name, dep.InstallHint)
}
}
return msg
}
func joinStrings(values []string) string {
if len(values) == 0 {
return "none"
}
result := values[0]
for i := 1; i < len(values); i++ {
result += ", " + values[i]
}
return result
}