Skip to content

Commit f38054e

Browse files
committed
Implement doctor command
1 parent 8b06757 commit f38054e

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ Display help about a specific command:
142142
codegame help <cmd>
143143
```
144144

145+
Check for missing dependencies and misconfigurations:
146+
```
147+
codegame doctor
148+
```
149+
145150
## Installation
146151

147152
### Windows

cmd/doctor.go

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"os/exec"
7+
"runtime"
8+
9+
"github.com/Bananenpro/cli"
10+
"github.com/spf13/cobra"
11+
)
12+
13+
type doctorRule interface {
14+
Check() bool
15+
ErrMessage() string
16+
SuccessMessage() string
17+
}
18+
19+
type doctorRuleInactive struct{}
20+
21+
func (d doctorRuleInactive) Check() bool {
22+
return true
23+
}
24+
25+
func (d doctorRuleInactive) ErrMessage() string {
26+
return ""
27+
}
28+
29+
func (d doctorRuleInactive) SuccessMessage() string {
30+
return ""
31+
}
32+
33+
type doctorRuleTool struct {
34+
names []string
35+
message string
36+
}
37+
38+
func newDoctorRuleTool(message string, names ...string) doctorRule {
39+
return doctorRuleTool{
40+
names: names,
41+
message: message,
42+
}
43+
}
44+
45+
func newDoctorRuleToolWithCondition(message string, active bool, names ...string) doctorRule {
46+
if !active {
47+
return doctorRuleInactive{}
48+
}
49+
return doctorRuleTool{
50+
names: names,
51+
message: message,
52+
}
53+
}
54+
55+
func (d doctorRuleTool) Check() bool {
56+
for _, n := range d.names {
57+
if _, err := exec.LookPath(n); err == nil {
58+
return true
59+
}
60+
}
61+
return false
62+
}
63+
64+
func (d doctorRuleTool) ErrMessage() string {
65+
return d.message
66+
}
67+
68+
func (d doctorRuleTool) SuccessMessage() string {
69+
for _, n := range d.names {
70+
if _, err := exec.LookPath(n); err == nil {
71+
return fmt.Sprintf("`%s` is installed.", n)
72+
}
73+
}
74+
panic("SuccessMessage() called but tool is not installed")
75+
}
76+
77+
var installDir = "/usr/local/bin"
78+
79+
func init() {
80+
if runtime.GOOS == "windows" {
81+
installDir = os.Getenv("HOME") + "\\AppData\\Local\\Programs\\codegame-cli"
82+
}
83+
}
84+
85+
type doctorCategory struct {
86+
name string
87+
rules []doctorRule
88+
}
89+
90+
var doctorRules = []doctorCategory{
91+
{name: "CLI", rules: []doctorRule{
92+
newDoctorRuleTool("`codegame` is not in PATH. If you have installed codegame-cli in a custom install directory, make sure to add it to the PATH environment variable. Otherwise, manually add "+installDir+" to the PATH environment variable.", "codegame"),
93+
newDoctorRuleToolWithCondition("Either curl or wget must be installed to use `codegame upgrade`.", runtime.GOOS != "windows", "curl", "wget"),
94+
}},
95+
{name: "C#", rules: []doctorRule{
96+
newDoctorRuleTool("`dotnet` must be installed to develop CodeGame applications using C#. Install it from https://dotnet.microsoft.com/en-us/download.", "dotnet"),
97+
}},
98+
{name: "Go", rules: []doctorRule{
99+
newDoctorRuleTool("`go` must be installed to develop CodeGame applications using the Go programming language. Install it from https://go.dev.", "go"),
100+
}},
101+
{name: "Java", rules: []doctorRule{
102+
newDoctorRuleTool("`java` must be installed to develop CodeGame applications using Java. Install it from https://adoptium.net.", "java"),
103+
newDoctorRuleTool("`mvn` must be installed to develop CodeGame applications using Java. Download it from https://maven.apache.org/download.cgi and follow the instructions at https://maven.apache.org/install.html.", "mvn"),
104+
}},
105+
{name: "JavaScript", rules: []doctorRule{
106+
newDoctorRuleTool("`npm` must be installed to develop CodeGame applications using JavaScript or TypeScript. Install it from https://nodejs.org.", "npm"),
107+
newDoctorRuleTool("`npx` must be installed to run TypeScript or browser based CodeGame applications. Install it using `npm install -g npx`.", "npx"),
108+
}},
109+
}
110+
111+
// doctorCmd represents the doctor command
112+
var doctorCmd = &cobra.Command{
113+
Use: "doctor",
114+
Short: "Check for missing dependencies and misconfigurations.",
115+
Run: func(_ *cobra.Command, _ []string) {
116+
for _, category := range doctorRules {
117+
cli.PrintColor(cli.Cyan, "%s:", category.name)
118+
for _, r := range category.rules {
119+
if _, ok := r.(doctorRuleInactive); ok {
120+
continue
121+
}
122+
if r.Check() {
123+
cli.PrintColor(cli.Green, " √ %s", r.SuccessMessage())
124+
} else {
125+
cli.PrintColor(cli.Red, " x %s", r.ErrMessage())
126+
}
127+
}
128+
}
129+
},
130+
}
131+
132+
func init() {
133+
rootCmd.AddCommand(doctorCmd)
134+
}

0 commit comments

Comments
 (0)