mirror of
https://github.com/mgechev/revive.git
synced 2025-01-18 03:21:24 +02:00
3421eaecf0
* refactor: fix thelper issues test/utils_test.go:19:6 thelper test helper function should start from t.Helper() test/utils_test.go:42:6 thelper test helper function should start from t.Helper() test/utils_test.go:63:6 thelper test helper function should start from t.Helper() test/utils_test.go:146:6 thelper test helper function should start from t.Helper() * refactor: fix govet issues rule/error_strings.go:50:21 govet printf: non-constant format string in call to fmt.Errorf * refactor: fix gosimple issue rule/bare_return.go:52:9 gosimple S1016: should convert w (type lintBareReturnRule) to bareReturnFinder instead of using struct literal * refactor: fix errorlint issues lint/filefilter.go:70:86 errorlint non-wrapping format verb for fmt.Errorf. Use `%w` to format errors lint/filefilter.go:113:104 errorlint non-wrapping format verb for fmt.Errorf. Use `%w` to format errors lint/filefilter.go:125:89 errorlint non-wrapping format verb for fmt.Errorf. Use `%w` to format errors lint/linter.go:166:72 errorlint non-wrapping format verb for fmt.Errorf. Use `%w` to format errors lint/linter.go:171:73 errorlint non-wrapping format verb for fmt.Errorf. Use `%w` to format errors config/config.go:174:57 errorlint non-wrapping format verb for fmt.Errorf. Use `%w` to format errors config/config.go:179:64 errorlint non-wrapping format verb for fmt.Errorf. Use `%w` to format errors * refactor: fix revive issue about comment spacing cli/main.go:31:2 revive comment-spacings: no space between comment delimiter and comment text * refactor: fix revive issue about unused-receiver revivelib/core_test.go:77:7 revive unused-receiver: method receiver 'r' is not referenced in method's body, consider removing or renaming it as _ revivelib/core_test.go:81:7 revive unused-receiver: method receiver 'r' is not referenced in method's body, consider removing or renaming it as _ rule/context_as_argument.go:76:7 revive unused-receiver: method receiver 'r' is not referenced in method's body, consider removing or renaming it as _ rule/var_naming.go:73:7 revive unused-receiver: method receiver 'r' is not referenced in method's body, consider removing or renaming it as _ rule/modifies_value_receiver.go:59:7 revive unused-receiver: method receiver 'r' is not referenced in method's body, consider removing or renaming it as _ rule/filename_format.go:43:7 revive unused-receiver: method receiver 'r' is not referenced in method's body, consider removing or renaming it as _ * refactor: fix revive issues about unused-parameter revivelib/core_test.go:81:24 revive unused-parameter: parameter 'file' seems to be unused, consider removing or renaming it as _ revivelib/core_test.go:81:41 revive unused-parameter: parameter 'arguments' seems to be unused, consider removing or renaming it as _ * refactor: fix gocritic issues about commentedOutCode test/utils_test.go:119:5 gocritic commentedOutCode: may want to remove commented-out code rule/unreachable_code.go:65:3 gocritic commentedOutCode: may want to remove commented-out code
207 lines
4.7 KiB
Go
207 lines
4.7 KiB
Go
// Package cli implements the revive command line application.
|
|
package cli
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime/debug"
|
|
"strings"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/mgechev/revive/config"
|
|
"github.com/mgechev/revive/revivelib"
|
|
"github.com/mitchellh/go-homedir"
|
|
"github.com/spf13/afero"
|
|
)
|
|
|
|
const (
|
|
defaultVersion = "dev"
|
|
defaultCommit = "none"
|
|
defaultDate = "unknown"
|
|
defaultBuilder = "unknown"
|
|
)
|
|
|
|
var (
|
|
version = defaultVersion
|
|
commit = defaultCommit
|
|
date = defaultDate
|
|
builtBy = defaultBuilder
|
|
// AppFs is used to operations related with user config files
|
|
AppFs = afero.NewOsFs()
|
|
)
|
|
|
|
func fail(err string) {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// RunRevive runs the CLI for revive.
|
|
func RunRevive(extraRules ...revivelib.ExtraRule) {
|
|
// move parsing flags outside of init() otherwise tests dont works properly
|
|
// more info: https://github.com/golang/go/issues/46869#issuecomment-865695953
|
|
initConfig()
|
|
|
|
if versionFlag {
|
|
fmt.Print(getVersion(builtBy, date, commit, version))
|
|
os.Exit(0)
|
|
}
|
|
|
|
conf, err := config.GetConfig(configPath)
|
|
if err != nil {
|
|
fail(err.Error())
|
|
}
|
|
|
|
revive, err := revivelib.New(
|
|
conf,
|
|
setExitStatus,
|
|
maxOpenFiles,
|
|
extraRules...,
|
|
)
|
|
if err != nil {
|
|
fail(err.Error())
|
|
}
|
|
|
|
files := flag.Args()
|
|
packages := []*revivelib.LintPattern{}
|
|
|
|
for _, file := range files {
|
|
packages = append(packages, revivelib.Include(file))
|
|
}
|
|
|
|
for _, file := range excludePatterns {
|
|
packages = append(packages, revivelib.Exclude(file))
|
|
}
|
|
|
|
failures, err := revive.Lint(packages...)
|
|
if err != nil {
|
|
fail(err.Error())
|
|
}
|
|
|
|
output, exitCode, err := revive.Format(formatterName, failures)
|
|
if err != nil {
|
|
fail(err.Error())
|
|
}
|
|
|
|
if output != "" {
|
|
fmt.Println(output)
|
|
}
|
|
|
|
os.Exit(exitCode)
|
|
}
|
|
|
|
var (
|
|
configPath string
|
|
excludePatterns revivelib.ArrayFlags
|
|
formatterName string
|
|
versionFlag bool
|
|
setExitStatus bool
|
|
maxOpenFiles int
|
|
)
|
|
|
|
var originalUsage = flag.Usage
|
|
|
|
func getLogo() string {
|
|
return color.YellowString(` _ __ _____ _(_)__ _____
|
|
| '__/ _ \ \ / / \ \ / / _ \
|
|
| | | __/\ V /| |\ V / __/
|
|
|_| \___| \_/ |_| \_/ \___|`)
|
|
}
|
|
|
|
func getCall() string {
|
|
return color.MagentaString("revive -config c.toml -formatter friendly -exclude a.go -exclude b.go ./...")
|
|
}
|
|
|
|
func getBanner() string {
|
|
return fmt.Sprintf(`
|
|
%s
|
|
|
|
Example:
|
|
%s
|
|
`, getLogo(), getCall())
|
|
}
|
|
|
|
func buildDefaultConfigPath() string {
|
|
var result string
|
|
var homeDirFile string
|
|
configFileName := "revive.toml"
|
|
configDirFile := filepath.Join(os.Getenv("XDG_CONFIG_HOME"), configFileName)
|
|
|
|
if homeDir, err := homedir.Dir(); err == nil {
|
|
homeDirFile = filepath.Join(homeDir, configFileName)
|
|
}
|
|
|
|
switch {
|
|
case fileExist(configDirFile):
|
|
result = configDirFile
|
|
case fileExist(homeDirFile):
|
|
result = homeDirFile
|
|
default:
|
|
result = ""
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func initConfig() {
|
|
// Force colorizing for no TTY environments
|
|
if os.Getenv("REVIVE_FORCE_COLOR") == "1" {
|
|
color.NoColor = false
|
|
}
|
|
|
|
flag.Usage = func() {
|
|
fmt.Println(getBanner())
|
|
originalUsage()
|
|
}
|
|
|
|
// command line help strings
|
|
const (
|
|
configUsage = "path to the configuration TOML file, defaults to $XDG_CONFIG_HOME/revive.toml or $HOME/revive.toml, if present (i.e. -config myconf.toml)"
|
|
excludeUsage = "list of globs which specify files to be excluded (i.e. -exclude foo/...)"
|
|
formatterUsage = "formatter to be used for the output (i.e. -formatter stylish)"
|
|
versionUsage = "get revive version"
|
|
exitStatusUsage = "set exit status to 1 if any issues are found, overwrites errorCode and warningCode in config"
|
|
maxOpenFilesUsage = "maximum number of open files at the same time"
|
|
)
|
|
|
|
defaultConfigPath := buildDefaultConfigPath()
|
|
|
|
flag.StringVar(&configPath, "config", defaultConfigPath, configUsage)
|
|
flag.Var(&excludePatterns, "exclude", excludeUsage)
|
|
flag.StringVar(&formatterName, "formatter", "", formatterUsage)
|
|
flag.BoolVar(&versionFlag, "version", false, versionUsage)
|
|
flag.BoolVar(&setExitStatus, "set_exit_status", false, exitStatusUsage)
|
|
flag.IntVar(&maxOpenFiles, "max_open_files", 0, maxOpenFilesUsage)
|
|
flag.Parse()
|
|
}
|
|
|
|
// getVersion returns build info (version, commit, date and builtBy)
|
|
func getVersion(builtBy, date, commit, version string) string {
|
|
var buildInfo string
|
|
if date != defaultDate && builtBy != defaultBuilder {
|
|
buildInfo = fmt.Sprintf("Built\t\t%s by %s\n", date, builtBy)
|
|
}
|
|
|
|
if commit != defaultCommit {
|
|
buildInfo = fmt.Sprintf("Commit:\t\t%s\n%s", commit, buildInfo)
|
|
}
|
|
|
|
if version == defaultVersion {
|
|
bi, ok := debug.ReadBuildInfo()
|
|
if ok {
|
|
version = strings.TrimPrefix(bi.Main.Version, "v")
|
|
if len(buildInfo) == 0 {
|
|
return fmt.Sprintf("version %s\n", version)
|
|
}
|
|
}
|
|
}
|
|
|
|
return fmt.Sprintf("Version:\t%s\n%s", version, buildInfo)
|
|
}
|
|
|
|
func fileExist(path string) bool {
|
|
_, err := AppFs.Stat(path)
|
|
return err == nil
|
|
}
|