generate command line options section of README

This commit is contained in:
golangci 2018-06-02 15:32:40 +03:00
parent 4df5df2ab7
commit 9133ef4271
10 changed files with 245 additions and 262 deletions

View File

@ -10,7 +10,6 @@ output:
format: colored-line-number
print-issued-lines: true
print-linter-name: true
print-welcome: true
linters-settings:
errcheck:

View File

@ -19,8 +19,4 @@ linters-settings:
linters:
enable-all: true
disable:
- maligned
issues:
exclude:
- should have a package comment
- maligned

View File

@ -2,7 +2,6 @@ test:
go install ./cmd/...
golangci-lint run -v
golangci-lint run --fast --no-config -v
golangci-lint run --fast --no-config -v
golangci-lint run --no-config -v
golangci-lint run --fast --no-config -v ./test/testdata/typecheck.go
go test -v -race ./...

170
README.md
View File

@ -134,7 +134,10 @@ This issue is important because often you'd like to set concurrency to CPUs coun
3. It will take more time because of different usages and need of tracking of versions of `n` linters.
# Performance
Benchmarks were executed on MacBook Pro (Retina, 13-inch, Late 2013), 2,4 GHz Intel Core i5, 8 GB 1600 MHz DDR3. It has 4 cores and concurrency for linters was default: number of cores. Benchmark runs and measures timings automatically, it's code is [here](https://github.com/golangci/golangci-lint/blob/master/test/bench.go) (`BenchmarkWithGometalinter`).
Benchmarks were executed on MacBook Pro (Retina, 13-inch, Late 2013), 2,4 GHz Intel Core i5, 8 GB 1600 MHz DDR3.
It has 4 cores and concurrency for linters was default: number of cores.
Benchmark runs and measures timings automatically, it's code is
[here](https://github.com/golangci/golangci-lint/blob/master/test/bench_test.go) (`BenchmarkWithGometalinter`).
We measure peak memory usage (RSS) by tracking of processes RSS every 5 ms.
@ -172,7 +175,7 @@ On average golangci-lint consumes 1.35 times less memory.
# Supported Linters
To see a list of supported linters and which linters are enabled/disabled by default execute a command
```bash
```
golangci-lint linters
```
@ -204,99 +207,77 @@ golangci-lint linters
# Configuration
## Command-Line Options
Run next command to see their description and defaults.
```bash
```
golangci-lint run -h
Usage:
golangci-lint run [flags]
Flags:
--out-format string Format of output: colored-line-number|line-number|json (default "colored-line-number")
--print-issued-lines Print lines of code with issue (default true)
--print-linter-name Print linter name in issue line (default true)
--issues-exit-code int Exit code when issues were found (default 1)
--build-tags strings Build tags (not all linters support them)
--deadline duration Deadline for total work (default 1m0s)
--tests Analyze tests (*_test.go)
--print-resources-usage Print avg and max memory usage of golangci-lint and total time
-c, --config PATH Read config from file path PATH
--no-config Don't read config
-E, --enable strings Enable specific linter
-D, --disable strings Disable specific linter
--enable-all Enable all linters
--disable-all Disable all linters
-p, --presets strings Enable presets (bugs|unused|format|style|complexity|performance) of linters. Run 'golangci-lint linters' to see them. This option implies option --disable-all
--fast Run only fast linters from enabled linters set
-e, --exclude strings Exclude issue by regexp
--exclude-use-default Use or not use default excludes:
# errcheck: Almost all programs ignore errors on these functions and in most cases it's ok
- Error return value of .((os\.)?std(out|err)\..*|.*Close|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked
# golint: Annoying issue about not having a comment. The rare codebase has such comments
- (should have comment|comment on exported method|should have a package comment)
# golint: False positive when tests are defined in package 'test'
- func name will be used as test\.Test.* by other packages, and that stutters; consider calling this
# gas: Too many false-positives on 'unsafe' usage
- Use of unsafe calls should be audited
# gas: Too many false-positives for parametrized shell calls
- Subprocess launch(ed with variable|ing should be audited)
# gas: Duplicated errcheck checks
- G104
# gas: Too many issues in popular repos
- (Expect directory permissions to be 0750 or less|Expect file permissions to be 0600 or less)
# gas: False positive is triggered by 'src, err := ioutil.ReadFile(filename)'
- Potential file inclusion via variable
# govet: Common false positives
- (possible misuse of unsafe.Pointer|should have signature)
# megacheck: Developers tend to write in C-style with an explicit 'break' in a 'switch', so it's ok to ignore
- ineffective break statement. Did you mean to break out of the outer loop
(default true)
--max-issues-per-linter int Maximum issues count per one linter. Set to 0 to disable (default 50)
--max-same-issues int Maximum count of issues with the same text. Set to 0 to disable (default 3)
-n, --new Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.
It's a super-useful option for integration of golangci-lint into existing large codebase.
It's not practical to fix all existing issues at the moment of integration: much better don't allow issues in new code
--new-from-rev REV Show only new issues created after git revision REV
--new-from-patch PATH Show only new issues created in git patch with file path PATH
-h, --help help for run
Global Flags:
-j, --concurrency int Concurrency (default NumCPU) (default 8)
--cpu-profile-path string Path to CPU profile output file
--mem-profile-path string Path to memory profile output file
-v, --verbose verbose output
```
### Run Options
- `-c, --config` - path to [config file](#configuration-file) if you don't like using default config path `.golangci.(yml|toml|json)`.
- `-j, --concurrency` - the number of threads used. By default, it's a number of CPUs. Unlike `gometalinter`, it's an honest value, since we do not fork linter processes.
- `--build-tags` - build tags to take into account.
- `--issues-exit-code` - exit code if issues were found. The default is `1`.
- `--deadline` - timeout for running golangci-lint, `1m` by default.
- `--tests` - analyze `*_test.go` files. It's `false` by default.
- `-v, --verbose` - enable verbose output. Use this options to see which linters were enabled, to see timings of steps and another helpful information.
- `--print-resources-usage` - print memory usage and total time elapsed.
### Linters
- `-E, --enable` - enable specific linter. You can pass option multiple times or use a comma:
```bash
golangci-lint run --disable-all -E golint -E govet -E errcheck
golangci-lint run --disable-all --enable golint,govet,errcheck
```
- `-D, --disable` - disable specific linter. Similar to enabling option.
- `--enable-all` - enable all supported linters.
- `--disable-all` - disable all supported linters.
- `-p, --presets` - enable specific presets. To list all presets run
```bash
$ golangci-lint linters
...
Linters presets:
bugs: govet, errcheck, staticcheck, gas, megacheck
unused: unused, structcheck, varcheck, ineffassign, deadcode, megacheck
format: gofmt, goimports
style: golint, gosimple, interfacer, unconvert, dupl, goconst, megacheck, depguard
complexity: gocyclo
performance: maligned
```
Usage example:
```bash
$ golangci-lint run -v --disable-all -p bugs,style,complexity,format
INFO[0000] Active linters: [govet goconst gocyclo gofmt gas dupl goimports megacheck interfacer unconvert errcheck golint]
```
- `--fast` - run only fast linters from the enabled set of linters. To find out which linters are fast run `golangci-lint linters`.
### Linters Options
- `--errcheck.check-type-assertions` - errcheck: check for ignored type assertion results. Disabled by default.
- `--errcheck.check-blank` - errcheck: check for errors assigned to blank identifier: `_ = errFunc()`. Disabled by default
- `--govet.check-shadowing` - govet: check for shadowed variables. Disabled by default.
- `--golint.min-confidence` - golint: minimum confidence of a problem to print it. The default is `0.8`.
- `--gofmt.simplify` - gofmt: simplify code (`gofmt -s`), enabled by default.
- `--gocyclo.min-complexity` - gocyclo: a minimal complexity of function to report it. The default is `30` (it's very high limit).
- `--maligned.suggest-new` - Maligned: print suggested more optimal struct fields ordering. Disabled by default. Example:
```
crypto/tls/ticket.go:20: struct of size 64 bytes could be of size 56 bytes:
struct{
masterSecret []byte,
certificates [][]byte,
vers uint16,
cipherSuite uint16,
usedOldKey bool,
}
```
- `--dupl.threshold` - dupl: Minimal threshold to detect copy-paste, `150` by default.
- `--goconst.min-len` - goconst: minimum constant string length, `3` by default.
- `--goconst.min-occurrences` - goconst: minimum occurences of constant string count to trigger issue. Default is `3`.
### Issues Options
- `-n, --new` - show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed. It's a super-useful option for integration `golangci-lint` into existing large codebase. It's not practical to fix all existing issues at the moment of integration: much better don't allow issues in new code. Disabled by default.
- `--new-from-rev` - show only new issues created after specified git revision.
- `--new-from-patch` - show only new issues created in git patch with the specified file path.
- `-e, --exclude` - exclude issue by regexp on issue text.
- `--exclude-use-default` - use or not use default excludes. We tested our linter on large codebases and marked common false positives. By default we ignore common false positives by next regexps:
- `Error return value of .((os\.)?std(out|err)\..*|.*Close|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked` - ercheck: almost all programs ignore errors on these functions and in most cases it's ok.
- `(should have comment|comment on exported method)` - golint: annoying issues about not having a comment. The rare codebase has such comments.
- `G103:` - gas: `Use of unsafe calls should be audited`
- `G104:` - gas: `disable what errcheck does: it reports on Close etc`
- `G204:` - gas: `Subprocess launching should be audited: too lot false - positives`
- `G301:` - gas: `Expect directory permissions to be 0750 or less`
- `G302:` - gas: `Expect file permissions to be 0600 or less`
- `G304:` - gas: ``Potential file inclusion via variable: `src, err := ioutil.ReadFile(filename)`.``
- `(possible misuse of unsafe.Pointer|should have signature)` - common false positives by govet.
- `ineffective break statement. Did you mean to break out of the outer loop` - megacheck: developers tend to write in C-style with an explicit `break` in a switch, so it's ok to ignore.
Use option `--exclude-use-default=false` to disable these default exclude regexps.
- `--max-issues-per-linter` - maximum issues count per one linter. Set to `0` to disable. The default value is `50` to not being annoying.
- `--max-same-issues` - maximum count of issues with the same text. Set to 0 to disable. The default value is `3` to not being annoying.
### Output Options
- `--out-format` - format of output: `colored-line-number|line-number|json`, default is `colored-line-number`.
- `--print-issued-lines` - print line of source code where the issue occurred. Enabled by default.
- `--print-linter-name` - print linter name in issue line. Enabled by default.
- `--print-welcome` - print welcome message. Enabled by default.
## Configuration File
GolangCI-Lint looks for next config paths in the current directory:
- `.golangci.yml`
@ -330,11 +311,6 @@ linters:
enable-all: true
disable:
- maligned
issues:
exclude:
- should have a package comment
```
# False Positives

View File

@ -112,7 +112,10 @@ This issue is important because often you'd like to set concurrency to CPUs coun
3. It will take more time because of different usages and need of tracking of versions of `n` linters.
# Performance
Benchmarks were executed on MacBook Pro (Retina, 13-inch, Late 2013), 2,4 GHz Intel Core i5, 8 GB 1600 MHz DDR3. It has 4 cores and concurrency for linters was default: number of cores. Benchmark runs and measures timings automatically, it's code is [here](https://github.com/golangci/golangci-lint/blob/master/test/bench.go) (`BenchmarkWithGometalinter`).
Benchmarks were executed on MacBook Pro (Retina, 13-inch, Late 2013), 2,4 GHz Intel Core i5, 8 GB 1600 MHz DDR3.
It has 4 cores and concurrency for linters was default: number of cores.
Benchmark runs and measures timings automatically, it's code is
[here](https://github.com/golangci/golangci-lint/blob/master/test/bench_test.go) (`BenchmarkWithGometalinter`).
We measure peak memory usage (RSS) by tracking of processes RSS every 5 ms.
@ -150,7 +153,7 @@ On average golangci-lint consumes 1.35 times less memory.
# Supported Linters
To see a list of supported linters and which linters are enabled/disabled by default execute a command
```bash
```
golangci-lint linters
```
@ -162,99 +165,11 @@ golangci-lint linters
# Configuration
## Command-Line Options
Run next command to see their description and defaults.
```bash
```
golangci-lint run -h
{{.RunHelpText}}
```
### Run Options
- `-c, --config` - path to [config file](#configuration-file) if you don't like using default config path `.golangci.(yml|toml|json)`.
- `-j, --concurrency` - the number of threads used. By default, it's a number of CPUs. Unlike `gometalinter`, it's an honest value, since we do not fork linter processes.
- `--build-tags` - build tags to take into account.
- `--issues-exit-code` - exit code if issues were found. The default is `1`.
- `--deadline` - timeout for running golangci-lint, `1m` by default.
- `--tests` - analyze `*_test.go` files. It's `false` by default.
- `-v, --verbose` - enable verbose output. Use this options to see which linters were enabled, to see timings of steps and another helpful information.
- `--print-resources-usage` - print memory usage and total time elapsed.
### Linters
- `-E, --enable` - enable specific linter. You can pass option multiple times or use a comma:
```bash
golangci-lint run --disable-all -E golint -E govet -E errcheck
golangci-lint run --disable-all --enable golint,govet,errcheck
```
- `-D, --disable` - disable specific linter. Similar to enabling option.
- `--enable-all` - enable all supported linters.
- `--disable-all` - disable all supported linters.
- `-p, --presets` - enable specific presets. To list all presets run
```bash
$ golangci-lint linters
...
Linters presets:
bugs: govet, errcheck, staticcheck, gas, megacheck
unused: unused, structcheck, varcheck, ineffassign, deadcode, megacheck
format: gofmt, goimports
style: golint, gosimple, interfacer, unconvert, dupl, goconst, megacheck, depguard
complexity: gocyclo
performance: maligned
```
Usage example:
```bash
$ golangci-lint run -v --disable-all -p bugs,style,complexity,format
INFO[0000] Active linters: [govet goconst gocyclo gofmt gas dupl goimports megacheck interfacer unconvert errcheck golint]
```
- `--fast` - run only fast linters from the enabled set of linters. To find out which linters are fast run `golangci-lint linters`.
### Linters Options
- `--errcheck.check-type-assertions` - errcheck: check for ignored type assertion results. Disabled by default.
- `--errcheck.check-blank` - errcheck: check for errors assigned to blank identifier: `_ = errFunc()`. Disabled by default
- `--govet.check-shadowing` - govet: check for shadowed variables. Disabled by default.
- `--golint.min-confidence` - golint: minimum confidence of a problem to print it. The default is `0.8`.
- `--gofmt.simplify` - gofmt: simplify code (`gofmt -s`), enabled by default.
- `--gocyclo.min-complexity` - gocyclo: a minimal complexity of function to report it. The default is `30` (it's very high limit).
- `--maligned.suggest-new` - Maligned: print suggested more optimal struct fields ordering. Disabled by default. Example:
```
crypto/tls/ticket.go:20: struct of size 64 bytes could be of size 56 bytes:
struct{
masterSecret []byte,
certificates [][]byte,
vers uint16,
cipherSuite uint16,
usedOldKey bool,
}
```
- `--dupl.threshold` - dupl: Minimal threshold to detect copy-paste, `150` by default.
- `--goconst.min-len` - goconst: minimum constant string length, `3` by default.
- `--goconst.min-occurrences` - goconst: minimum occurences of constant string count to trigger issue. Default is `3`.
### Issues Options
- `-n, --new` - show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed. It's a super-useful option for integration `golangci-lint` into existing large codebase. It's not practical to fix all existing issues at the moment of integration: much better don't allow issues in new code. Disabled by default.
- `--new-from-rev` - show only new issues created after specified git revision.
- `--new-from-patch` - show only new issues created in git patch with the specified file path.
- `-e, --exclude` - exclude issue by regexp on issue text.
- `--exclude-use-default` - use or not use default excludes. We tested our linter on large codebases and marked common false positives. By default we ignore common false positives by next regexps:
- `Error return value of .((os\.)?std(out|err)\..*|.*Close|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked` - ercheck: almost all programs ignore errors on these functions and in most cases it's ok.
- `(should have comment|comment on exported method)` - golint: annoying issues about not having a comment. The rare codebase has such comments.
- `G103:` - gas: `Use of unsafe calls should be audited`
- `G104:` - gas: `disable what errcheck does: it reports on Close etc`
- `G204:` - gas: `Subprocess launching should be audited: too lot false - positives`
- `G301:` - gas: `Expect directory permissions to be 0750 or less`
- `G302:` - gas: `Expect file permissions to be 0600 or less`
- `G304:` - gas: ``Potential file inclusion via variable: `src, err := ioutil.ReadFile(filename)`.``
- `(possible misuse of unsafe.Pointer|should have signature)` - common false positives by govet.
- `ineffective break statement. Did you mean to break out of the outer loop` - megacheck: developers tend to write in C-style with an explicit `break` in a switch, so it's ok to ignore.
Use option `--exclude-use-default=false` to disable these default exclude regexps.
- `--max-issues-per-linter` - maximum issues count per one linter. Set to `0` to disable. The default value is `50` to not being annoying.
- `--max-same-issues` - maximum count of issues with the same text. Set to 0 to disable. The default value is `3` to not being annoying.
### Output Options
- `--out-format` - format of output: `colored-line-number|line-number|json`, default is `colored-line-number`.
- `--print-issued-lines` - print line of source code where the issue occurred. Enabled by default.
- `--print-linter-name` - print linter name in issue line. Enabled by default.
- `--print-welcome` - print welcome message. Enabled by default.
## Configuration File
GolangCI-Lint looks for next config paths in the current directory:
- `.golangci.yml`

View File

@ -56,6 +56,14 @@ func (e *Executor) persistentPreRun(cmd *cobra.Command, args []string) {
os.Exit(e.exitCode)
}
func getDefaultConcurrency() int {
if os.Getenv("HELP_RUN") == "1" {
return 8 // to make stable concurrency for README help generating builds
}
return runtime.NumCPU()
}
func (e *Executor) initRoot() {
rootCmd := &cobra.Command{
Use: "golangci-lint",
@ -69,11 +77,13 @@ func (e *Executor) initRoot() {
PersistentPreRun: e.persistentPostRun,
PersistentPostRun: e.persistentPreRun,
}
rootCmd.PersistentFlags().BoolVarP(&e.cfg.Run.IsVerbose, "verbose", "v", false, "verbose output")
rootCmd.PersistentFlags().StringVar(&e.cfg.Run.CPUProfilePath, "cpu-profile-path", "", "Path to CPU profile output file")
rootCmd.PersistentFlags().StringVar(&e.cfg.Run.MemProfilePath, "mem-profile-path", "", "Path to memory profile output file")
rootCmd.PersistentFlags().IntVarP(&e.cfg.Run.Concurrency, "concurrency", "j", runtime.NumCPU(), "Concurrency (default NumCPU)")
rootCmd.PersistentFlags().BoolVar(&e.cfg.Run.PrintVersion, "version", false, "Print version")
rootCmd.PersistentFlags().BoolVarP(&e.cfg.Run.IsVerbose, "verbose", "v", false, wh("verbose output"))
rootCmd.PersistentFlags().StringVar(&e.cfg.Run.CPUProfilePath, "cpu-profile-path", "", wh("Path to CPU profile output file"))
rootCmd.PersistentFlags().StringVar(&e.cfg.Run.MemProfilePath, "mem-profile-path", "", wh("Path to memory profile output file"))
rootCmd.PersistentFlags().IntVarP(&e.cfg.Run.Concurrency, "concurrency", "j", getDefaultConcurrency(), wh("Concurrency (default NumCPU)"))
if e.commit != "" {
rootCmd.PersistentFlags().BoolVar(&e.cfg.Run.PrintVersion, "version", false, wh("Print version"))
}
e.rootCmd = rootCmd
}

View File

@ -12,6 +12,7 @@ import (
"strings"
"time"
"github.com/fatih/color"
"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/lint"
"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
@ -29,92 +30,131 @@ const (
exitCodeIfTimeout = 4
)
func getDefaultExcludeHelp() string {
parts := []string{"Use or not use default excludes:"}
for _, ep := range config.DefaultExcludePatterns {
parts = append(parts, fmt.Sprintf(" # %s: %s", ep.Linter, ep.Why))
parts = append(parts, fmt.Sprintf(" - %s", color.YellowString(ep.Pattern)))
parts = append(parts, "")
}
return strings.Join(parts, "\n")
}
const welcomeMessage = "Run this tool in cloud on every github pull request in https://golangci.com for free (public repos)"
func wh(text string) string {
return color.GreenString(text)
}
func (e *Executor) initRun() {
var runCmd = &cobra.Command{
Use: "run",
Short: "Run linters",
Short: welcomeMessage,
Run: e.executeRun,
}
e.rootCmd.AddCommand(runCmd)
runCmd.SetOutput(printers.StdOut) // use custom output to properly color it in Windows terminals
runCmd.Flags().SortFlags = false // sort them as they are defined here
hideFlag := func(name string) {
if err := runCmd.Flags().MarkHidden(name); err != nil {
panic(err)
}
}
// Output config
oc := &e.cfg.Output
runCmd.Flags().StringVar(&oc.Format, "out-format",
config.OutFormatColoredLineNumber,
fmt.Sprintf("Format of output: %s", strings.Join(config.OutFormats, "|")))
runCmd.Flags().BoolVar(&oc.PrintIssuedLine, "print-issued-lines", true, "Print lines of code with issue")
runCmd.Flags().BoolVar(&oc.PrintLinterName, "print-linter-name", true, "Print linter name in issue line")
runCmd.Flags().BoolVar(&oc.PrintWelcomeMessage, "print-welcome", false, "Print welcome message")
wh(fmt.Sprintf("Format of output: %s", strings.Join(config.OutFormats, "|"))))
runCmd.Flags().BoolVar(&oc.PrintIssuedLine, "print-issued-lines", true, wh("Print lines of code with issue"))
runCmd.Flags().BoolVar(&oc.PrintLinterName, "print-linter-name", true, wh("Print linter name in issue line"))
runCmd.Flags().BoolVar(&oc.PrintWelcomeMessage, "print-welcome", false, wh("Print welcome message"))
hideFlag("print-welcome") // no longer used
// Run config
rc := &e.cfg.Run
runCmd.Flags().IntVar(&rc.ExitCodeIfIssuesFound, "issues-exit-code",
1, "Exit code when issues were found")
runCmd.Flags().StringSliceVar(&rc.BuildTags, "build-tags", []string{}, "Build tags (not all linters support them)")
runCmd.Flags().DurationVar(&rc.Deadline, "deadline", time.Minute, "Deadline for total work")
runCmd.Flags().BoolVar(&rc.AnalyzeTests, "tests", false, "Analyze tests (*_test.go)")
runCmd.Flags().BoolVar(&rc.PrintResourcesUsage, "print-resources-usage", false, "Print avg and max memory usage of golangci-lint and total time")
runCmd.Flags().StringVarP(&rc.Config, "config", "c", "", "Read config from file path `PATH`")
runCmd.Flags().BoolVar(&rc.NoConfig, "no-config", false, "Don't read config")
1, wh("Exit code when issues were found"))
runCmd.Flags().StringSliceVar(&rc.BuildTags, "build-tags", []string{}, wh("Build tags (not all linters support them)"))
runCmd.Flags().DurationVar(&rc.Deadline, "deadline", time.Minute, wh("Deadline for total work"))
runCmd.Flags().BoolVar(&rc.AnalyzeTests, "tests", false, wh("Analyze tests (*_test.go)"))
runCmd.Flags().BoolVar(&rc.PrintResourcesUsage, "print-resources-usage", false, wh("Print avg and max memory usage of golangci-lint and total time"))
runCmd.Flags().StringVarP(&rc.Config, "config", "c", "", wh("Read config from file path `PATH`"))
runCmd.Flags().BoolVar(&rc.NoConfig, "no-config", false, wh("Don't read config"))
// Linters settings config
lsc := &e.cfg.LintersSettings
// Hide all linters settings flags: they were initially visible,
// but when number of linters started to grow it became ovious that
// we can't fill 90% of flags by linters settings: common flags became hard to find.
// New linters settings should be done only through config file.
runCmd.Flags().BoolVar(&lsc.Errcheck.CheckTypeAssertions, "errcheck.check-type-assertions", false, "Errcheck: check for ignored type assertion results")
hideFlag("errcheck.check-type-assertions")
runCmd.Flags().BoolVar(&lsc.Errcheck.CheckAssignToBlank, "errcheck.check-blank", false, "Errcheck: check for errors assigned to blank identifier: _ = errFunc()")
hideFlag("errcheck.check-blank")
runCmd.Flags().BoolVar(&lsc.Govet.CheckShadowing, "govet.check-shadowing", false, "Govet: check for shadowed variables")
hideFlag("govet.check-shadowing")
runCmd.Flags().Float64Var(&lsc.Golint.MinConfidence, "golint.min-confidence", 0.8, "Golint: minimum confidence of a problem to print it")
hideFlag("golint.min-confidence")
runCmd.Flags().BoolVar(&lsc.Gofmt.Simplify, "gofmt.simplify", true, "Gofmt: simplify code")
hideFlag("gofmt.simplify")
runCmd.Flags().IntVar(&lsc.Gocyclo.MinComplexity, "gocyclo.min-complexity",
30, "Minimal complexity of function to report it")
hideFlag("gocyclo.min-complexity")
runCmd.Flags().BoolVar(&lsc.Maligned.SuggestNewOrder, "maligned.suggest-new", false, "Maligned: print suggested more optimal struct fields ordering")
hideFlag("maligned.suggest-new")
runCmd.Flags().IntVar(&lsc.Dupl.Threshold, "dupl.threshold",
150, "Dupl: Minimal threshold to detect copy-paste")
hideFlag("dupl.threshold")
runCmd.Flags().IntVar(&lsc.Goconst.MinStringLen, "goconst.min-len",
3, "Goconst: minimum constant string length")
hideFlag("goconst.min-len")
runCmd.Flags().IntVar(&lsc.Goconst.MinOccurrencesCount, "goconst.min-occurrences",
3, "Goconst: minimum occurrences of constant string count to trigger issue")
hideFlag("goconst.min-occurrences")
// (@dixonwille) These flag is only used for testing purposes.
runCmd.Flags().StringSliceVar(&lsc.Depguard.Packages, "depguard.packages", nil,
"Depguard: packages to add to the list")
if err := runCmd.Flags().MarkHidden("depguard.packages"); err != nil {
panic(err) //Considering The only time this is called is if name does not exist
}
hideFlag("depguard.packages")
runCmd.Flags().BoolVar(&lsc.Depguard.IncludeGoRoot, "depguard.include-go-root", false,
"Depguard: check list against standard lib")
if err := runCmd.Flags().MarkHidden("depguard.include-go-root"); err != nil {
panic(err) //Considering The only time this is called is if name does not exist
}
hideFlag("depguard.include-go-root")
// Linters config
lc := &e.cfg.Linters
runCmd.Flags().StringSliceVarP(&lc.Enable, "enable", "E", []string{}, "Enable specific linter")
runCmd.Flags().StringSliceVarP(&lc.Disable, "disable", "D", []string{}, "Disable specific linter")
runCmd.Flags().BoolVar(&lc.EnableAll, "enable-all", false, "Enable all linters")
runCmd.Flags().BoolVar(&lc.DisableAll, "disable-all", false, "Disable all linters")
runCmd.Flags().StringSliceVarP(&lc.Enable, "enable", "E", []string{}, wh("Enable specific linter"))
runCmd.Flags().StringSliceVarP(&lc.Disable, "disable", "D", []string{}, wh("Disable specific linter"))
runCmd.Flags().BoolVar(&lc.EnableAll, "enable-all", false, wh("Enable all linters"))
runCmd.Flags().BoolVar(&lc.DisableAll, "disable-all", false, wh("Disable all linters"))
runCmd.Flags().StringSliceVarP(&lc.Presets, "presets", "p", []string{},
fmt.Sprintf("Enable presets (%s) of linters. Run 'golangci-lint linters' to see them. This option implies option --disable-all", strings.Join(lintersdb.AllPresets(), "|")))
runCmd.Flags().BoolVar(&lc.Fast, "fast", false, "Run only fast linters from enabled linters set")
wh(fmt.Sprintf("Enable presets (%s) of linters. Run 'golangci-lint linters' to see them. This option implies option --disable-all", strings.Join(lintersdb.AllPresets(), "|"))))
runCmd.Flags().BoolVar(&lc.Fast, "fast", false, wh("Run only fast linters from enabled linters set"))
// Issues config
ic := &e.cfg.Issues
runCmd.Flags().StringSliceVarP(&ic.ExcludePatterns, "exclude", "e", []string{}, "Exclude issue by regexp")
runCmd.Flags().BoolVar(&ic.UseDefaultExcludes, "exclude-use-default", true,
fmt.Sprintf("Use or not use default excludes: (%s)", strings.Join(config.DefaultExcludePatterns, "|")))
runCmd.Flags().StringSliceVarP(&ic.ExcludePatterns, "exclude", "e", []string{}, wh("Exclude issue by regexp"))
runCmd.Flags().BoolVar(&ic.UseDefaultExcludes, "exclude-use-default", true, getDefaultExcludeHelp())
runCmd.Flags().IntVar(&ic.MaxIssuesPerLinter, "max-issues-per-linter", 50, "Maximum issues count per one linter. Set to 0 to disable")
runCmd.Flags().IntVar(&ic.MaxSameIssues, "max-same-issues", 3, "Maximum count of issues with the same text. Set to 0 to disable")
runCmd.Flags().IntVar(&ic.MaxIssuesPerLinter, "max-issues-per-linter", 50, wh("Maximum issues count per one linter. Set to 0 to disable"))
runCmd.Flags().IntVar(&ic.MaxSameIssues, "max-same-issues", 3, wh("Maximum count of issues with the same text. Set to 0 to disable"))
runCmd.Flags().BoolVarP(&ic.Diff, "new", "n", false, "Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed")
runCmd.Flags().StringVar(&ic.DiffFromRevision, "new-from-rev", "", "Show only new issues created after git revision `REV`")
runCmd.Flags().StringVar(&ic.DiffPatchFilePath, "new-from-patch", "", "Show only new issues created in git patch with file path `PATH`")
runCmd.Flags().BoolVarP(&ic.Diff, "new", "n", false,
wh("Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.\nIt's a super-useful option for integration of golangci-lint into existing large codebase.\nIt's not practical to fix all existing issues at the moment of integration: much better don't allow issues in new code"))
runCmd.Flags().StringVar(&ic.DiffFromRevision, "new-from-rev", "", wh("Show only new issues created after git revision `REV`"))
runCmd.Flags().StringVar(&ic.DiffPatchFilePath, "new-from-patch", "", wh("Show only new issues created in git patch with file path `PATH`"))
e.parseConfig(runCmd)
}
@ -134,7 +174,7 @@ func (e *Executor) runAnalysis(ctx context.Context, args []string) (<-chan resul
excludePatterns := e.cfg.Issues.ExcludePatterns
if e.cfg.Issues.UseDefaultExcludes {
excludePatterns = append(excludePatterns, config.DefaultExcludePatterns...)
excludePatterns = append(excludePatterns, config.GetDefaultExcludePatternsStrings()...)
}
var excludeTotalPattern string
if len(excludePatterns) != 0 {
@ -207,9 +247,6 @@ func (e *Executor) runAndPrint(ctx context.Context, args []string) error {
}
func (e *Executor) executeRun(cmd *cobra.Command, args []string) {
logrus.Infof("Concurrency: %d, machine cpus count: %d",
e.cfg.Run.Concurrency, runtime.NumCPU())
needTrackResources := e.cfg.Run.IsVerbose || e.cfg.Run.PrintResourcesUsage
trackResourcesEndCh := make(chan struct{})
defer func() { // XXX: this defer must be before ctx.cancel defer
@ -225,10 +262,6 @@ func (e *Executor) executeRun(cmd *cobra.Command, args []string) {
go watchResources(ctx, trackResourcesEndCh)
}
if e.cfg.Output.PrintWelcomeMessage {
fmt.Fprintln(printers.StdOut, "Run this tool in cloud on every github pull request in https://golangci.com for free (public repos)")
}
if err := e.runAndPrint(ctx, args); err != nil {
logrus.Warnf("running error: %s", err)
if e.exitCode == 0 {

View File

@ -14,29 +14,72 @@ const (
var OutFormats = []string{OutFormatColoredLineNumber, OutFormatLineNumber, OutFormatJSON}
var DefaultExcludePatterns = []string{
// errcheck
"Error return value of .((os\\.)?std(out|err)\\..*|.*Close|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked",
type ExcludePattern struct {
Pattern string
Linter string
Why string
}
// golint
"should have comment",
"comment on exported method",
"func name will be used as test\\.Test.* by other packages, and that stutters; consider calling this",
var DefaultExcludePatterns = []ExcludePattern{
{
Pattern: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked",
Linter: "errcheck",
Why: "Almost all programs ignore errors on these functions and in most cases it's ok",
},
{
Pattern: "(should have comment|comment on exported method|should have a package comment)",
Linter: "golint",
Why: "Annoying issue about not having a comment. The rare codebase has such comments",
},
{
Pattern: "func name will be used as test\\.Test.* by other packages, and that stutters; consider calling this",
Linter: "golint",
Why: "False positive when tests are defined in package 'test'",
},
{
Pattern: "Use of unsafe calls should be audited",
Linter: "gas",
Why: "Too many false-positives on 'unsafe' usage",
},
{
Pattern: "Subprocess launch(ed with variable|ing should be audited)",
Linter: "gas",
Why: "Too many false-positives for parametrized shell calls",
},
{
Pattern: "G104",
Linter: "gas",
Why: "Duplicated errcheck checks",
},
{
Pattern: "(Expect directory permissions to be 0750 or less|Expect file permissions to be 0600 or less)",
Linter: "gas",
Why: "Too many issues in popular repos",
},
{
Pattern: "Potential file inclusion via variable",
Linter: "gas",
Why: "False positive is triggered by 'src, err := ioutil.ReadFile(filename)'",
},
{
Pattern: "(possible misuse of unsafe.Pointer|should have signature)",
Linter: "govet",
Why: "Common false positives",
},
{
Pattern: "ineffective break statement. Did you mean to break out of the outer loop",
Linter: "megacheck",
Why: "Developers tend to write in C-style with an explicit 'break' in a 'switch', so it's ok to ignore",
},
}
// gas
"G103:", // Use of unsafe calls should be audited
"G104:", // disable what errcheck does: it reports on Close etc
"G204:", // Subprocess launching should be audited: too lot false positives
"G301:", // Expect directory permissions to be 0750 or less
"G302:", // Expect file permissions to be 0600 or less
"G304:", // Potential file inclusion via variable: `src, err := ioutil.ReadFile(filename)`
func GetDefaultExcludePatternsStrings() []string {
var ret []string
for _, p := range DefaultExcludePatterns {
ret = append(ret, p.Pattern)
}
// govet
"possible misuse of unsafe.Pointer",
"should have signature",
// megacheck
"ineffective break statement. Did you mean to break out of the outer loop", // developers tend to write in C-style with break in switch
return ret
}
type Run struct {

View File

@ -59,6 +59,17 @@ func buildTemplateContext() (map[string]interface{}, error) {
lintersOutParts := bytes.Split(lintersOut, []byte("\n\n"))
helpCmd := exec.Command("golangci-lint", "run", "-h")
helpCmd.Env = append(helpCmd.Env, os.Environ()...)
helpCmd.Env = append(helpCmd.Env, "HELP_RUN=1") // make default concurrency stable: don't depend on machine CPU number
help, err := helpCmd.Output()
if err != nil {
return nil, fmt.Errorf("can't run help cmd: %s", err)
}
helpLines := bytes.Split(help, []byte("\n"))
shortHelp := bytes.Join(helpLines[2:], []byte("\n"))
return map[string]interface{}{
"GolangciYaml": string(golangciYaml),
"LintersCommandOutputEnabledOnly": string(lintersOutParts[0]),
@ -66,6 +77,7 @@ func buildTemplateContext() (map[string]interface{}, error) {
"EnabledByDefaultLinters": getLintersListMarkdown(true),
"DisabledByDefaultLinters": getLintersListMarkdown(false),
"ThanksList": getThanksList(),
"RunHelpText": string(shortHelp),
}, nil
}

View File

@ -74,7 +74,7 @@ func getGometalinterCommonArgs() []string {
"--vendor",
"--cyclo-over=30",
"--dupl-threshold=150",
"--exclude", fmt.Sprintf("(%s)", strings.Join(config.DefaultExcludePatterns, "|")),
"--exclude", fmt.Sprintf("(%s)", strings.Join(config.GetDefaultExcludePatternsStrings(), "|")),
"--disable-all",
"--enable=vet",
"--enable=vetshadow",