don't print config parsing info logs twice
This commit is contained in:
parent
a24cc87a06
commit
47440bc2cc
@ -6,10 +6,12 @@ import (
|
|||||||
"github.com/golangci/golangci-lint/pkg/logutils"
|
"github.com/golangci/golangci-lint/pkg/logutils"
|
||||||
"github.com/golangci/golangci-lint/pkg/report"
|
"github.com/golangci/golangci-lint/pkg/report"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Executor struct {
|
type Executor struct {
|
||||||
rootCmd *cobra.Command
|
rootCmd *cobra.Command
|
||||||
|
runCmd *cobra.Command
|
||||||
|
|
||||||
exitCode int
|
exitCode int
|
||||||
version, commit, date string
|
version, commit, date string
|
||||||
@ -27,18 +29,43 @@ func NewExecutor(version, commit, date string) *Executor {
|
|||||||
version: version,
|
version: version,
|
||||||
commit: commit,
|
commit: commit,
|
||||||
date: date,
|
date: date,
|
||||||
|
DBManager: lintersdb.NewManager(),
|
||||||
}
|
}
|
||||||
|
|
||||||
e.log = report.NewLogWrapper(logutils.NewStderrLog(""), &e.reportData)
|
e.log = report.NewLogWrapper(logutils.NewStderrLog(""), &e.reportData)
|
||||||
e.DBManager = lintersdb.NewManager()
|
|
||||||
e.EnabledLintersSet = lintersdb.NewEnabledSet(e.DBManager, &lintersdb.Validator{},
|
|
||||||
e.log.Child("lintersdb"), e.cfg)
|
|
||||||
|
|
||||||
|
// to setup log level early we need to parse config from command line extra time to
|
||||||
|
// find `-v` option
|
||||||
|
commandLineCfg, err := e.getConfigForCommandLine()
|
||||||
|
if err != nil && err != pflag.ErrHelp {
|
||||||
|
e.log.Fatalf("Can't get config for command line: %s", err)
|
||||||
|
}
|
||||||
|
if commandLineCfg != nil {
|
||||||
|
logutils.SetupVerboseLog(e.log, commandLineCfg.Run.IsVerbose)
|
||||||
|
}
|
||||||
|
|
||||||
|
// init of commands must be done before config file reading because
|
||||||
|
// init sets config with the default values of flags
|
||||||
e.initRoot()
|
e.initRoot()
|
||||||
e.initRun()
|
e.initRun()
|
||||||
e.initHelp()
|
e.initHelp()
|
||||||
e.initLinters()
|
e.initLinters()
|
||||||
|
|
||||||
|
// init e.cfg by values from config: flags parse will see these values
|
||||||
|
// like the default ones. It will overwrite them only if the same option
|
||||||
|
// is found in command-line: it's ok, command-line has higher priority.
|
||||||
|
|
||||||
|
r := config.NewFileReader(e.cfg, commandLineCfg, e.log.Child("config_reader"))
|
||||||
|
if err := r.Read(); err != nil {
|
||||||
|
e.log.Fatalf("Can't read config: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slice options must be explicitly set for proper merging of config and command-line options.
|
||||||
|
fixSlicesFlags(e.runCmd.Flags())
|
||||||
|
|
||||||
|
e.EnabledLintersSet = lintersdb.NewEnabledSet(e.DBManager,
|
||||||
|
lintersdb.NewValidator(e.DBManager), e.log.Child("lintersdb"), e.cfg)
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ func IsLinterInConfigsList(name string, linters []linter.Config) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e Executor) executeLinters(cmd *cobra.Command, args []string) {
|
func (e *Executor) executeLinters(cmd *cobra.Command, args []string) {
|
||||||
enabledLCs, err := e.EnabledLintersSet.Get()
|
enabledLCs, err := e.EnabledLintersSet.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Can't get enabled linters: %s", err)
|
log.Fatalf("Can't get enabled linters: %s", err)
|
||||||
|
@ -20,8 +20,6 @@ func (e *Executor) persistentPreRun(cmd *cobra.Command, args []string) {
|
|||||||
|
|
||||||
runtime.GOMAXPROCS(e.cfg.Run.Concurrency)
|
runtime.GOMAXPROCS(e.cfg.Run.Concurrency)
|
||||||
|
|
||||||
logutils.SetupVerboseLog(e.log, e.cfg.Run.IsVerbose)
|
|
||||||
|
|
||||||
if e.cfg.Run.CPUProfilePath != "" {
|
if e.cfg.Run.CPUProfilePath != "" {
|
||||||
f, err := os.Create(e.cfg.Run.CPUProfilePath)
|
f, err := os.Create(e.cfg.Run.CPUProfilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -168,42 +168,48 @@ func (e *Executor) initRunConfiguration(cmd *cobra.Command) {
|
|||||||
fs := cmd.Flags()
|
fs := cmd.Flags()
|
||||||
fs.SortFlags = false // sort them as they are defined here
|
fs.SortFlags = false // sort them as they are defined here
|
||||||
initFlagSet(fs, e.cfg, e.DBManager)
|
initFlagSet(fs, e.cfg, e.DBManager)
|
||||||
|
}
|
||||||
|
|
||||||
// init e.cfg by values from config: flags parse will see these values
|
func (e Executor) getConfigForCommandLine() (*config.Config, error) {
|
||||||
// like the default ones. It will overwrite them only if the same option
|
// We use another pflag.FlagSet here to not set `changed` flag
|
||||||
// is found in command-line: it's ok, command-line has higher priority.
|
// on cmd.Flags() options. Otherwise string slice options will be duplicated.
|
||||||
|
fs := pflag.NewFlagSet("config flag set", pflag.ContinueOnError)
|
||||||
|
|
||||||
r := config.NewFileReader(e.cfg, e.log.Child("config_reader"), func(fs *pflag.FlagSet, cfg *config.Config) {
|
var cfg config.Config
|
||||||
// Don't do `fs.AddFlagSet(cmd.Flags())` because it shares flags representations:
|
// Don't do `fs.AddFlagSet(cmd.Flags())` because it shares flags representations:
|
||||||
// `changed` variable inside string slice vars will be shared.
|
// `changed` variable inside string slice vars will be shared.
|
||||||
// Use another config variable here, not e.cfg, to not
|
// Use another config variable here, not e.cfg, to not
|
||||||
// affect main parsing by this parsing of only config option.
|
// affect main parsing by this parsing of only config option.
|
||||||
initFlagSet(fs, cfg, e.DBManager)
|
initFlagSet(fs, &cfg, e.DBManager)
|
||||||
|
|
||||||
// Parse max options, even force version option: don't want
|
// Parse max options, even force version option: don't want
|
||||||
// to get access to Executor here: it's error-prone to use
|
// to get access to Executor here: it's error-prone to use
|
||||||
// cfg vs e.cfg.
|
// cfg vs e.cfg.
|
||||||
initRootFlagSet(fs, cfg, true)
|
initRootFlagSet(fs, &cfg, true)
|
||||||
})
|
|
||||||
if err := r.Read(); err != nil {
|
fs.Usage = func() {} // otherwise help text will be printed twice
|
||||||
e.log.Fatalf("Can't read config: %s", err)
|
if err := fs.Parse(os.Args); err != nil {
|
||||||
|
if err == pflag.ErrHelp {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slice options must be explicitly set for proper merging of config and command-line options.
|
return nil, fmt.Errorf("can't parse args: %s", err)
|
||||||
fixSlicesFlags(fs)
|
}
|
||||||
|
|
||||||
|
return &cfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Executor) initRun() {
|
func (e *Executor) initRun() {
|
||||||
var runCmd = &cobra.Command{
|
e.runCmd = &cobra.Command{
|
||||||
Use: "run",
|
Use: "run",
|
||||||
Short: welcomeMessage,
|
Short: welcomeMessage,
|
||||||
Run: e.executeRun,
|
Run: e.executeRun,
|
||||||
}
|
}
|
||||||
e.rootCmd.AddCommand(runCmd)
|
e.rootCmd.AddCommand(e.runCmd)
|
||||||
|
|
||||||
runCmd.SetOutput(logutils.StdOut) // use custom output to properly color it in Windows terminals
|
e.runCmd.SetOutput(logutils.StdOut) // use custom output to properly color it in Windows terminals
|
||||||
|
|
||||||
e.initRunConfiguration(runCmd)
|
e.initRunConfiguration(e.runCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fixSlicesFlags(fs *pflag.FlagSet) {
|
func fixSlicesFlags(fs *pflag.FlagSet) {
|
||||||
|
@ -5,26 +5,24 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/golangci/golangci-lint/pkg/fsutils"
|
"github.com/golangci/golangci-lint/pkg/fsutils"
|
||||||
"github.com/golangci/golangci-lint/pkg/logutils"
|
"github.com/golangci/golangci-lint/pkg/logutils"
|
||||||
"github.com/spf13/pflag"
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FlagSetInit func(fs *pflag.FlagSet, cfg *Config)
|
|
||||||
|
|
||||||
type FileReader struct {
|
type FileReader struct {
|
||||||
log logutils.Log
|
log logutils.Log
|
||||||
cfg *Config
|
cfg *Config
|
||||||
flagSetInit FlagSetInit
|
commandLineCfg *Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFileReader(toCfg *Config, log logutils.Log, flagSetInit FlagSetInit) *FileReader {
|
func NewFileReader(toCfg, commandLineCfg *Config, log logutils.Log) *FileReader {
|
||||||
return &FileReader{
|
return &FileReader{
|
||||||
log: log,
|
log: log,
|
||||||
cfg: toCfg,
|
cfg: toCfg,
|
||||||
flagSetInit: flagSetInit,
|
commandLineCfg: commandLineCfg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,9 +31,9 @@ func (r *FileReader) Read() error {
|
|||||||
// 1. to access "config" option here.
|
// 1. to access "config" option here.
|
||||||
// 2. to give config less priority than command line.
|
// 2. to give config less priority than command line.
|
||||||
|
|
||||||
configFile, restArgs, err := r.parseConfigOption()
|
configFile, err := r.parseConfigOption()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == errConfigDisabled || err == pflag.ErrHelp {
|
if err == errConfigDisabled {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +43,7 @@ func (r *FileReader) Read() error {
|
|||||||
if configFile != "" {
|
if configFile != "" {
|
||||||
viper.SetConfigFile(configFile)
|
viper.SetConfigFile(configFile)
|
||||||
} else {
|
} else {
|
||||||
r.setupConfigFileSearch(restArgs)
|
r.setupConfigFileSearch()
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.parseConfig()
|
return r.parseConfig()
|
||||||
@ -108,7 +106,9 @@ func (r *FileReader) validateConfig() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *FileReader) setupConfigFileSearch(args []string) {
|
func getFirstPathArg() string {
|
||||||
|
args := os.Args
|
||||||
|
|
||||||
// skip all args ([golangci-lint, run/linters]) before files/dirs list
|
// skip all args ([golangci-lint, run/linters]) before files/dirs list
|
||||||
for len(args) != 0 {
|
for len(args) != 0 {
|
||||||
if args[0] == "run" {
|
if args[0] == "run" {
|
||||||
@ -121,10 +121,18 @@ func (r *FileReader) setupConfigFileSearch(args []string) {
|
|||||||
|
|
||||||
// find first file/dir arg
|
// find first file/dir arg
|
||||||
firstArg := "./..."
|
firstArg := "./..."
|
||||||
if len(args) != 0 {
|
for _, arg := range args {
|
||||||
firstArg = args[0]
|
if !strings.HasPrefix(arg, "-") {
|
||||||
|
firstArg = arg
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return firstArg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *FileReader) setupConfigFileSearch() {
|
||||||
|
firstArg := getFirstPathArg()
|
||||||
absStartPath, err := filepath.Abs(firstArg)
|
absStartPath, err := filepath.Abs(firstArg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.log.Warnf("Can't make abs path for %q: %s", firstArg, err)
|
r.log.Warnf("Can't make abs path for %q: %s", firstArg, err)
|
||||||
@ -159,34 +167,20 @@ func (r *FileReader) setupConfigFileSearch(args []string) {
|
|||||||
|
|
||||||
var errConfigDisabled = errors.New("config is disabled by --no-config")
|
var errConfigDisabled = errors.New("config is disabled by --no-config")
|
||||||
|
|
||||||
func (r *FileReader) parseConfigOption() (string, []string, error) {
|
func (r *FileReader) parseConfigOption() (string, error) {
|
||||||
// We use another pflag.FlagSet here to not set `changed` flag
|
cfg := r.commandLineCfg
|
||||||
// on cmd.Flags() options. Otherwise string slice options will be duplicated.
|
if cfg == nil {
|
||||||
fs := pflag.NewFlagSet("config flag set", pflag.ContinueOnError)
|
return "", nil
|
||||||
|
|
||||||
var cfg Config
|
|
||||||
r.flagSetInit(fs, &cfg)
|
|
||||||
|
|
||||||
fs.Usage = func() {} // otherwise help text will be printed twice
|
|
||||||
if err := fs.Parse(os.Args); err != nil {
|
|
||||||
if err == pflag.ErrHelp {
|
|
||||||
return "", nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", nil, fmt.Errorf("can't parse args: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// for `-v` to work until running of preRun function
|
|
||||||
logutils.SetupVerboseLog(r.log, cfg.Run.IsVerbose)
|
|
||||||
|
|
||||||
configFile := cfg.Run.Config
|
configFile := cfg.Run.Config
|
||||||
if cfg.Run.NoConfig && configFile != "" {
|
if cfg.Run.NoConfig && configFile != "" {
|
||||||
return "", nil, fmt.Errorf("can't combine option --config and --no-config")
|
return "", fmt.Errorf("can't combine option --config and --no-config")
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Run.NoConfig {
|
if cfg.Run.NoConfig {
|
||||||
return "", nil, errConfigDisabled
|
return "", errConfigDisabled
|
||||||
}
|
}
|
||||||
|
|
||||||
return configFile, fs.Args(), nil
|
return configFile, nil
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,6 @@ func (es EnabledSet) Get() ([]linter.Config, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
es.verbosePrintLintersStatus(resultLinters)
|
es.verbosePrintLintersStatus(resultLinters)
|
||||||
|
|
||||||
return resultLinters, nil
|
return resultLinters, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ func TestGetEnabledLintersSet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
m := NewManager()
|
m := NewManager()
|
||||||
es := NewEnabledSet(m, &Validator{}, nil, nil)
|
es := NewEnabledSet(m, NewValidator(m), nil, nil)
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
t.Run(c.name, func(t *testing.T) {
|
t.Run(c.name, func(t *testing.T) {
|
||||||
defaultLinters := []linter.Config{}
|
defaultLinters := []linter.Config{}
|
||||||
|
@ -11,6 +11,12 @@ type Validator struct {
|
|||||||
m *Manager
|
m *Manager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewValidator(m *Manager) *Validator {
|
||||||
|
return &Validator{
|
||||||
|
m: m,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (v Validator) validateLintersNames(cfg *config.Linters) error {
|
func (v Validator) validateLintersNames(cfg *config.Linters) error {
|
||||||
allNames := append([]string{}, cfg.Enable...)
|
allNames := append([]string{}, cfg.Enable...)
|
||||||
allNames = append(allNames, cfg.Disable...)
|
allNames = append(allNames, cfg.Disable...)
|
||||||
|
@ -89,7 +89,7 @@ func buildTemplateContext() (map[string]interface{}, error) {
|
|||||||
|
|
||||||
func getLintersListMarkdown(enabled bool) string {
|
func getLintersListMarkdown(enabled bool) string {
|
||||||
var neededLcs []linter.Config
|
var neededLcs []linter.Config
|
||||||
lcs := lintersdb.GetAllSupportedLinterConfigs()
|
lcs := lintersdb.NewManager().GetAllSupportedLinterConfigs()
|
||||||
for _, lc := range lcs {
|
for _, lc := range lcs {
|
||||||
if lc.EnabledByDefault == enabled {
|
if lc.EnabledByDefault == enabled {
|
||||||
neededLcs = append(neededLcs, lc)
|
neededLcs = append(neededLcs, lc)
|
||||||
@ -114,7 +114,7 @@ func getLintersListMarkdown(enabled bool) string {
|
|||||||
func getThanksList() string {
|
func getThanksList() string {
|
||||||
var lines []string
|
var lines []string
|
||||||
addedAuthors := map[string]bool{}
|
addedAuthors := map[string]bool{}
|
||||||
for _, lc := range lintersdb.GetAllSupportedLinterConfigs() {
|
for _, lc := range lintersdb.NewManager().GetAllSupportedLinterConfigs() {
|
||||||
if lc.OriginalURL == "" {
|
if lc.OriginalURL == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,8 @@ func inSlice(s []string, v string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getEnabledByDefaultFastLintersExcept(except ...string) []string {
|
func getEnabledByDefaultFastLintersExcept(except ...string) []string {
|
||||||
ebdl := lintersdb.GetAllEnabledByDefaultLinters()
|
m := lintersdb.NewManager()
|
||||||
|
ebdl := m.GetAllEnabledByDefaultLinters()
|
||||||
ret := []string{}
|
ret := []string{}
|
||||||
for _, linter := range ebdl {
|
for _, linter := range ebdl {
|
||||||
if linter.DoesFullImport {
|
if linter.DoesFullImport {
|
||||||
@ -186,7 +187,7 @@ func getEnabledByDefaultFastLintersExcept(except ...string) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getAllFastLintersWith(with ...string) []string {
|
func getAllFastLintersWith(with ...string) []string {
|
||||||
linters := lintersdb.GetAllSupportedLinterConfigs()
|
linters := lintersdb.NewManager().GetAllSupportedLinterConfigs()
|
||||||
ret := append([]string{}, with...)
|
ret := append([]string{}, with...)
|
||||||
for _, linter := range linters {
|
for _, linter := range linters {
|
||||||
if linter.DoesFullImport {
|
if linter.DoesFullImport {
|
||||||
@ -199,7 +200,7 @@ func getAllFastLintersWith(with ...string) []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getEnabledByDefaultLinters() []string {
|
func getEnabledByDefaultLinters() []string {
|
||||||
ebdl := lintersdb.GetAllEnabledByDefaultLinters()
|
ebdl := lintersdb.NewManager().GetAllEnabledByDefaultLinters()
|
||||||
ret := []string{}
|
ret := []string{}
|
||||||
for _, linter := range ebdl {
|
for _, linter := range ebdl {
|
||||||
ret = append(ret, linter.Linter.Name())
|
ret = append(ret, linter.Linter.Name())
|
||||||
@ -209,7 +210,7 @@ func getEnabledByDefaultLinters() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getEnabledByDefaultFastLintersWith(with ...string) []string {
|
func getEnabledByDefaultFastLintersWith(with ...string) []string {
|
||||||
ebdl := lintersdb.GetAllEnabledByDefaultLinters()
|
ebdl := lintersdb.NewManager().GetAllEnabledByDefaultLinters()
|
||||||
ret := append([]string{}, with...)
|
ret := append([]string{}, with...)
|
||||||
for _, linter := range ebdl {
|
for _, linter := range ebdl {
|
||||||
if linter.DoesFullImport {
|
if linter.DoesFullImport {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user