/
main.go
100 lines (85 loc) · 2.71 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
package main
import (
"errors"
"os"
"runtime"
"strings"
"time"
"github.com/jchen42703/create-fullstack/cmd/cliui"
"github.com/jchen42703/create-fullstack/cmd/context"
"github.com/jchen42703/create-fullstack/cmd/root"
"github.com/jchen42703/create-fullstack/internal/executable"
"github.com/jchen42703/create-fullstack/internal/log"
"github.com/spf13/cobra"
)
type exitCode int
const (
exitOK exitCode = 0
exitError exitCode = 1
exitCancel exitCode = 2
exitAuth exitCode = 4
)
func main() {
code := runMain()
os.Exit(int(code))
}
// Based on Github's gh CLI (which also uses cobra)
// https://github.com/cli/cli/blob/trunk/cmd/gh/main.go
func runMain() exitCode {
// TODO: Check for CLI updates
cliUi := cliui.NewColorUi()
// TODO: dynamically get the log file path for different OSes
logFilePath := "./create-fullstack.log"
// Initialize logger. Uses CFS_LOG_LVL env var to determine the log level.
logger, err := log.CreateLogger(logFilePath)
if err != nil {
cliUi.Errorf("Error initializing logger: %s", err.Error())
return exitError
}
// TODO: set the pager command for making viewing logs cleaner.
currentTime := time.Now()
cmdCtx := &context.CmdContext{
Version: "0.0.0-dev",
BuildDate: currentTime.Format("2006-01-02"),
CliUi: cliUi,
ExecutableName: executable.GetPath("create-fullstack"),
Logger: logger,
GlobalPluginsDir: context.GetGlobalPluginsDir(runtime.GOOS),
}
defer func() {
if err := logger.Sync(); err != nil {
// this sync error is safe to ignore, since stdout doesn't support syncing in Linux/OS X
if !strings.HasSuffix(err.Error(), "sync /dev/stdout: invalid argument") {
cliUi.Errorf("Error cleaning up logger: %s", err.Error())
}
}
}()
// // Used to return the file in CreateLogger so we could close it here, but idk why that also
// // threw an error that it was already closed
// defer func() {
// if err := f.Close(); err != nil {
// colorUi.Error(fmt.Sprintf("Error closing log file: %s", err.Error()))
// }
// }()
// 3. Overrides survey's default color
// 4. Build rootCmd
// 5. provide completions for aliases and extensions (includes plugin commands)
// 6. Executes the rootCmd
// 7. Checks if it errors out. Handles the error to provide a better UX.
var SilentErr = errors.New("SilentErr")
rootCmd := root.NewCmdRoot(cmdCtx)
// Only prints usage for flag errors
rootCmd.SetFlagErrorFunc(func(cmd *cobra.Command, err error) error {
cliUi.Error(err.Error() + "\n")
cliUi.Log("\n" + cmd.UsageString())
return SilentErr
})
err = rootCmd.Execute()
if err != nil {
if err != SilentErr {
cliUi.Errorf("Failed to execute command: %s\n", err.Error())
}
return exitError
}
return exitOK
}