-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
155 lines (126 loc) · 4.1 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
package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/Helcaraxan/goality/lib/printer"
"github.com/Helcaraxan/goality/lib/report"
)
type commonArgs struct {
logger *logrus.Logger
}
func main() {
commonArgs := &commonArgs{logger: logrus.New()}
var verbose, quiet bool
rootCmd := &cobra.Command{
Use: "goality",
PersistentPreRun: func(_ *cobra.Command, _ []string) {
if quiet {
commonArgs.logger.SetOutput(ioutil.Discard)
}
if verbose {
commonArgs.logger.SetLevel(logrus.DebugLevel)
commonArgs.logger.Debugf("Using verbose logging")
}
},
}
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Verbose output.")
rootCmd.PersistentFlags().BoolVarP(&quiet, "quiet", "q", false, "Do not perform any logging.")
rootCmd.AddCommand(
initRunCommand(commonArgs),
)
if err := rootCmd.Execute(); err != nil {
commonArgs.logger.WithError(err).Debugf("Execution failed.")
os.Exit(1)
}
commonArgs.logger.Debug("Execution successful.")
}
type runArgs struct {
*commonArgs
projectPath string
config string
excludePaths []string
linters []string
depth int
paths []string
format printer.FormatType
}
func initRunCommand(commonArgs *commonArgs) *cobra.Command {
cArgs := &runArgs{commonArgs: commonArgs}
var formatValue string
cmd := &cobra.Command{
Use: "run [path]",
Short: "Perform a quality analysis of the specified project.",
Long: `Run an analysis over the directory tree rooted at the specified path. If no path is given this defaults to the current working directory.
Example:
goality run
goality run --config=~/.golangci.yaml --depth 1 ./cmd
goality run src/github.com/me/project
`,
Args: cobra.MaximumNArgs(1),
PreRunE: func(cmd *cobra.Command, args []string) error {
switch formatValue {
case "csv":
cArgs.format = printer.FormatTypeCSV
case "screen":
cArgs.format = printer.FormatTypeScreen
default:
return fmt.Errorf("unknown result output format %q", cArgs.format)
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
args = append(args, ".")
}
cArgs.projectPath = args[0]
return executeRunCommand(cArgs)
},
}
cmd.Flags().StringVarP(&cArgs.config, "config", "c", "", "Path to a golangci-lint configuration file that should be used.")
cmd.Flags().StringSliceVarP(&cArgs.excludePaths, "excludes", "e", nil, "Names of directories that should be skipped.")
cmd.Flags().StringSliceVarP(&cArgs.linters, "linters", "l", nil, "Specific linters to run.")
cmd.Flags().IntVarP(&cArgs.depth, "depth", "d", -1, "Path granularity at which to perform the quality analysis.")
cmd.Flags().StringSliceVarP(&cArgs.paths, "paths", "p", nil, "Specific paths for which to provide aggregate quality analysis results.")
cmd.Flags().StringVarP(&formatValue, "format", "f", "screen", "Format to use when printing the results.")
return cmd
}
func executeRunCommand(args *runArgs) error {
cwd, err := os.Getwd()
if err != nil {
args.logger.WithError(err).Error("Failed to determine the current working directory")
return err
}
if args.config != "" && !filepath.IsAbs(args.config) {
args.config = filepath.Join(cwd, args.config)
}
if !filepath.IsAbs(args.projectPath) {
args.projectPath = filepath.Join(cwd, args.projectPath)
}
for idx := range args.paths {
if filepath.IsAbs(args.paths[idx]) {
relPath, relErr := filepath.Rel(args.projectPath, args.paths[idx])
if relErr != nil {
return relErr
} else if strings.HasPrefix(relPath, "../") {
return fmt.Errorf("specified path %q is outside of the targeted project at %q", args.paths[idx], args.projectPath)
}
args.paths[idx] = relPath
}
}
project, err := report.Parse(
args.logger,
args.projectPath,
report.WithConfig(args.config),
report.WithLinters(args.linters...),
report.WithExcludeDirs(args.excludePaths...),
)
if err != nil {
return err
}
return printer.PrintView(os.Stdout, project.GenerateView(report.WithDepth(args.depth), report.WithPaths(args.paths...)), args.format)
}