-
Notifications
You must be signed in to change notification settings - Fork 810
/
main.go
executable file
·158 lines (127 loc) · 3.46 KB
/
main.go
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
// Package main serves as the executable entrypoint.
package main
//go:generate go run ../../build/embed.go
import (
"fmt"
"os"
"runtime"
"strings"
"github.com/docopt/docopt-go"
"github.com/mitchellh/go-homedir"
"github.com/cheat/cheat/internal/cheatpath"
"github.com/cheat/cheat/internal/config"
"github.com/cheat/cheat/internal/installer"
)
const version = "4.4.2"
func main() {
// initialize options
opts, err := docopt.ParseArgs(usage(), nil, version)
if err != nil {
// panic here, because this should never happen
panic(fmt.Errorf("docopt failed to parse: %v", err))
}
// if --init was passed, we don't want to attempt to load a config file.
// Instead, just execute cmd_init and exit
if opts["--init"] != nil && opts["--init"] == true {
cmdInit()
os.Exit(0)
}
// get the user's home directory
home, err := homedir.Dir()
if err != nil {
fmt.Fprintf(os.Stderr, "failed to get user home directory: %v\n", err)
os.Exit(1)
}
// read the envvars into a map of strings
envvars := map[string]string{}
for _, e := range os.Environ() {
pair := strings.SplitN(e, "=", 2)
if runtime.GOOS == "windows" {
pair[0] = strings.ToUpper(pair[0])
}
envvars[pair[0]] = pair[1]
}
// identify the os-specifc paths at which configs may be located
confpaths, err := config.Paths(runtime.GOOS, home, envvars)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to load config: %v\n", err)
os.Exit(1)
}
// search for the config file in the above paths
confpath, err := config.Path(confpaths)
if err != nil {
// prompt the user to create a config file
yes, err := installer.Prompt(
"A config file was not found. Would you like to create one now? [Y/n]",
true,
)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to create config: %v\n", err)
os.Exit(1)
}
// exit early on a negative answer
if !yes {
os.Exit(0)
}
// choose a confpath
confpath = confpaths[0]
// run the installer
if err := installer.Run(configs(), confpath); err != nil {
fmt.Fprintf(os.Stderr, "failed to run installer: %v\n", err)
os.Exit(1)
}
// notify the user and exit
fmt.Printf("Created config file: %s\n", confpath)
fmt.Println("Please read this file for advanced configuration information.")
os.Exit(0)
}
// initialize the configs
conf, err := config.New(opts, confpath, true)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to load config: %v\n", err)
os.Exit(1)
}
// assert that the configs are valid
if err := conf.Validate(); err != nil {
fmt.Fprintf(os.Stderr, "failed to load config: %v\n", err)
os.Exit(1)
}
// filter the cheatpaths if --path was passed
if opts["--path"] != nil {
conf.Cheatpaths, err = cheatpath.Filter(
conf.Cheatpaths,
opts["--path"].(string),
)
if err != nil {
fmt.Fprintf(os.Stderr, "invalid option --path: %v\n", err)
os.Exit(1)
}
}
// determine which command to execute
var cmd func(map[string]interface{}, config.Config)
switch {
case opts["--conf"].(bool):
cmd = cmdConf
case opts["--directories"].(bool):
cmd = cmdDirectories
case opts["--edit"] != nil:
cmd = cmdEdit
case opts["--list"].(bool):
cmd = cmdList
case opts["--tags"].(bool):
cmd = cmdTags
case opts["--search"] != nil:
cmd = cmdSearch
case opts["--rm"] != nil:
cmd = cmdRemove
case opts["<cheatsheet>"] != nil:
cmd = cmdView
case opts["--tag"] != nil && opts["--tag"].(string) != "":
cmd = cmdList
default:
fmt.Println(usage())
os.Exit(0)
}
// execute the command
cmd(opts, conf)
}