Skip to content

Commit e80b8d3

Browse files
committed
Added command to check your local installs.
1 parent af5217c commit e80b8d3

File tree

1 file changed

+246
-0
lines changed

1 file changed

+246
-0
lines changed

cmd/check.go

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"os/exec"
7+
"regexp"
8+
"strconv"
9+
"strings"
10+
"text/tabwriter"
11+
12+
"github.com/spf13/cobra"
13+
)
14+
15+
func init() {
16+
rootCmd.AddCommand(checkCmd)
17+
}
18+
19+
type requirement struct {
20+
name string
21+
command string
22+
args []string
23+
docsURL string
24+
checker func([]byte) (string, error)
25+
}
26+
27+
type versionError struct {
28+
errorText string
29+
}
30+
31+
type commandError struct {
32+
Command string
33+
ErrorText string
34+
Suggestion string
35+
}
36+
37+
func (e *versionError) Error() string {
38+
return fmt.Sprintf("%s", e.errorText)
39+
}
40+
41+
func (e *commandError) Error() string {
42+
return fmt.Sprintf("%s", e.ErrorText)
43+
}
44+
45+
var checkCmd = &cobra.Command{
46+
Use: "check",
47+
Short: "Print the check number of commit0",
48+
Run: func(cmd *cobra.Command, args []string) {
49+
// Add any new requirements to this slice.
50+
required := []requirement{
51+
{
52+
name: "AWS CLI\t\t",
53+
command: "aws",
54+
args: []string{"--version"},
55+
docsURL: "",
56+
checker: func(output []byte) (string, error) {
57+
ver := ""
58+
re := regexp.MustCompile(`aws-cli/([0-9]+)\.([0-9]+)\.([0-9]+)`)
59+
m := re.FindStringSubmatch(string(output))
60+
major, err := strconv.ParseInt(m[1], 0, 64)
61+
if err != nil {
62+
return ver, err
63+
}
64+
minor, err := strconv.ParseInt(m[2], 0, 64)
65+
if err != nil {
66+
return ver, err
67+
}
68+
patch, err := strconv.ParseInt(m[3], 0, 64)
69+
if err != nil {
70+
return ver, err
71+
}
72+
73+
ver = fmt.Sprintf("%d.%d.%d", major, minor, patch)
74+
75+
if major < 1 || (major == 1 && minor < 16) {
76+
return ver, &versionError{"Requires 1.16 or greater."}
77+
}
78+
79+
return ver, err
80+
}},
81+
{
82+
name: "Kubectl\t\t",
83+
command: "kubectl",
84+
args: []string{"version", "--client=true"},
85+
docsURL: "https://kubernetes.io/docs/tasks/tools/install-kubectl/",
86+
checker: func(output []byte) (string, error) {
87+
ver := ""
88+
re := regexp.MustCompile(`version\.Info{Major:"([0-9]+)", Minor:"([0-9]+)"`)
89+
m := re.FindStringSubmatch(string(output))
90+
major, err := strconv.ParseInt(m[1], 0, 64)
91+
if err != nil {
92+
return ver, err
93+
}
94+
minor, err := strconv.ParseInt(m[2], 0, 64)
95+
if err != nil {
96+
return ver, err
97+
}
98+
99+
ver = fmt.Sprintf("%d.%d", major, minor)
100+
101+
if major < 1 || (major == 1 && minor < 12) {
102+
return ver, &versionError{"Requires 2.12 or greater."}
103+
}
104+
105+
return ver, err
106+
},
107+
},
108+
{
109+
name: "Terraform\t",
110+
command: "terraform",
111+
args: []string{"version"},
112+
docsURL: "https://www.terraform.io/downloads.html",
113+
checker: func(output []byte) (string, error) {
114+
ver := ""
115+
re := regexp.MustCompile(`Terraform v([0-9]+)\.([0-9]+)\.([0-9]+)`)
116+
m := re.FindStringSubmatch(string(output))
117+
major, err := strconv.ParseInt(m[1], 0, 64)
118+
if err != nil {
119+
return ver, err
120+
}
121+
minor, err := strconv.ParseInt(m[2], 0, 64)
122+
if err != nil {
123+
return ver, err
124+
}
125+
patch, err := strconv.ParseInt(m[3], 0, 64)
126+
if err != nil {
127+
return ver, err
128+
}
129+
130+
ver = fmt.Sprintf("%d.%d.%d", major, minor, patch)
131+
132+
if major < 0 || (major == 0 && minor < 12) {
133+
return ver, &versionError{"Zero requires terraform 0.12 or greater."}
134+
}
135+
136+
return ver, err
137+
},
138+
},
139+
{
140+
name: "jq\t\t",
141+
command: "jq",
142+
args: []string{"--version"},
143+
docsURL: "https://stedolan.github.io/jq/download/",
144+
checker: func(output []byte) (string, error) {
145+
ver := ""
146+
re := regexp.MustCompile(`jq-([0-9]+)\.([0-9]+)-`)
147+
m := re.FindStringSubmatch(string(output))
148+
major, err := strconv.ParseInt(m[1], 0, 64)
149+
if err != nil {
150+
return ver, err
151+
}
152+
minor, err := strconv.ParseInt(m[2], 0, 64)
153+
if err != nil {
154+
return ver, err
155+
}
156+
157+
ver = fmt.Sprintf("%d.%d", major, minor)
158+
159+
if major < 1 || (major == 1 && minor < 5) {
160+
return ver, &versionError{"Requires jq version 1.15 or greater."}
161+
}
162+
163+
return ver, err
164+
}},
165+
{
166+
name: "Git\t\t",
167+
command: "git",
168+
args: []string{"version"},
169+
docsURL: "https://git-scm.com/book/en/v2/Getting-Started-Installing-Git",
170+
checker: func(output []byte) (string, error) {
171+
ver := ""
172+
re := regexp.MustCompile(`git version ([0-9]+)\.([0-9]+)\.([0-9]+)`)
173+
m := re.FindStringSubmatch(string(output))
174+
major, err := strconv.ParseInt(m[1], 0, 64)
175+
if err != nil {
176+
return ver, err
177+
}
178+
minor, err := strconv.ParseInt(m[2], 0, 64)
179+
if err != nil {
180+
return ver, err
181+
}
182+
patch, err := strconv.ParseInt(m[3], 0, 64)
183+
if err != nil {
184+
return ver, err
185+
}
186+
187+
ver = fmt.Sprintf("%d.%d.%d", major, minor, patch)
188+
189+
if major < 2 || (major == 2 && minor < 12) {
190+
return ver, &versionError{"Zero requires git version 2.12 or greater."}
191+
}
192+
193+
return ver, err
194+
}},
195+
}
196+
197+
// Store and errors from the commands we run.
198+
errors := []commandError{}
199+
200+
fmt.Println("Checking Zero Requirements...")
201+
for _, r := range required {
202+
fmt.Printf("%s", r.name)
203+
out, err := exec.Command(r.command, r.args...).CombinedOutput()
204+
if err != nil {
205+
cerr := commandError{
206+
fmt.Sprintf("%s %s", r.command, strings.Join(r.args, " ")),
207+
err.Error(),
208+
r.docsURL,
209+
}
210+
errors = append(errors, cerr)
211+
fmt.Printf("\033[0;31mFAIL\033[0m\t\t%s\n", "-")
212+
continue
213+
}
214+
version, err := r.checker(out)
215+
if err != nil {
216+
cerr := commandError{
217+
r.command,
218+
err.Error(),
219+
r.docsURL,
220+
}
221+
errors = append(errors, cerr)
222+
fmt.Printf("\033[0;31mFAIL\033[0m\t\t%s\n", version)
223+
} else {
224+
fmt.Printf("\033[0;32mPASS\033[0m\t\t%s\n", version)
225+
}
226+
}
227+
228+
if len(errors) > 0 {
229+
// initialize tabwriter
230+
w := new(tabwriter.Writer)
231+
232+
// minwidth, tabwidth, padding, padchar, flags
233+
w.Init(os.Stdout, 10, 12, 2, ' ', 0)
234+
235+
defer w.Flush()
236+
237+
fmt.Fprintf(w, "\n %s\t%s\t%s\t", "Command", "Error", "Info")
238+
fmt.Fprintf(w, "\n %s\t%s\t%s\t", "---------", "---------", "---------")
239+
240+
for _, e := range errors {
241+
fmt.Fprintf(w, "\n%s\t%s\t%s\t", e.Command, e.ErrorText, e.Suggestion)
242+
}
243+
}
244+
fmt.Println()
245+
},
246+
}

0 commit comments

Comments
 (0)