generate command line options section of README
This commit is contained in:
parent
4df5df2ab7
commit
9133ef4271
@ -10,7 +10,6 @@ output:
|
|||||||
format: colored-line-number
|
format: colored-line-number
|
||||||
print-issued-lines: true
|
print-issued-lines: true
|
||||||
print-linter-name: true
|
print-linter-name: true
|
||||||
print-welcome: true
|
|
||||||
|
|
||||||
linters-settings:
|
linters-settings:
|
||||||
errcheck:
|
errcheck:
|
||||||
|
@ -20,7 +20,3 @@ linters:
|
|||||||
enable-all: true
|
enable-all: true
|
||||||
disable:
|
disable:
|
||||||
- maligned
|
- maligned
|
||||||
|
|
||||||
issues:
|
|
||||||
exclude:
|
|
||||||
- should have a package comment
|
|
||||||
|
1
Makefile
1
Makefile
@ -2,7 +2,6 @@ test:
|
|||||||
go install ./cmd/...
|
go install ./cmd/...
|
||||||
golangci-lint run -v
|
golangci-lint run -v
|
||||||
golangci-lint run --fast --no-config -v
|
golangci-lint run --fast --no-config -v
|
||||||
golangci-lint run --fast --no-config -v
|
|
||||||
golangci-lint run --no-config -v
|
golangci-lint run --no-config -v
|
||||||
golangci-lint run --fast --no-config -v ./test/testdata/typecheck.go
|
golangci-lint run --fast --no-config -v ./test/testdata/typecheck.go
|
||||||
go test -v -race ./...
|
go test -v -race ./...
|
||||||
|
170
README.md
170
README.md
@ -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.
|
3. It will take more time because of different usages and need of tracking of versions of `n` linters.
|
||||||
|
|
||||||
# Performance
|
# 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.
|
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
|
# Supported Linters
|
||||||
To see a list of supported linters and which linters are enabled/disabled by default execute a command
|
To see a list of supported linters and which linters are enabled/disabled by default execute a command
|
||||||
```bash
|
```
|
||||||
golangci-lint linters
|
golangci-lint linters
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -204,99 +207,77 @@ golangci-lint linters
|
|||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
## Command-Line Options
|
## Command-Line Options
|
||||||
Run next command to see their description and defaults.
|
```
|
||||||
```bash
|
|
||||||
golangci-lint run -h
|
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
|
## Configuration File
|
||||||
GolangCI-Lint looks for next config paths in the current directory:
|
GolangCI-Lint looks for next config paths in the current directory:
|
||||||
- `.golangci.yml`
|
- `.golangci.yml`
|
||||||
@ -330,11 +311,6 @@ linters:
|
|||||||
enable-all: true
|
enable-all: true
|
||||||
disable:
|
disable:
|
||||||
- maligned
|
- maligned
|
||||||
|
|
||||||
issues:
|
|
||||||
exclude:
|
|
||||||
- should have a package comment
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
# False Positives
|
# False Positives
|
||||||
|
@ -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.
|
3. It will take more time because of different usages and need of tracking of versions of `n` linters.
|
||||||
|
|
||||||
# Performance
|
# 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.
|
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
|
# Supported Linters
|
||||||
To see a list of supported linters and which linters are enabled/disabled by default execute a command
|
To see a list of supported linters and which linters are enabled/disabled by default execute a command
|
||||||
```bash
|
```
|
||||||
golangci-lint linters
|
golangci-lint linters
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -162,99 +165,11 @@ golangci-lint linters
|
|||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
## Command-Line Options
|
## Command-Line Options
|
||||||
Run next command to see their description and defaults.
|
```
|
||||||
```bash
|
|
||||||
golangci-lint run -h
|
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
|
## Configuration File
|
||||||
GolangCI-Lint looks for next config paths in the current directory:
|
GolangCI-Lint looks for next config paths in the current directory:
|
||||||
- `.golangci.yml`
|
- `.golangci.yml`
|
||||||
|
@ -56,6 +56,14 @@ func (e *Executor) persistentPreRun(cmd *cobra.Command, args []string) {
|
|||||||
os.Exit(e.exitCode)
|
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() {
|
func (e *Executor) initRoot() {
|
||||||
rootCmd := &cobra.Command{
|
rootCmd := &cobra.Command{
|
||||||
Use: "golangci-lint",
|
Use: "golangci-lint",
|
||||||
@ -69,11 +77,13 @@ func (e *Executor) initRoot() {
|
|||||||
PersistentPreRun: e.persistentPostRun,
|
PersistentPreRun: e.persistentPostRun,
|
||||||
PersistentPostRun: e.persistentPreRun,
|
PersistentPostRun: e.persistentPreRun,
|
||||||
}
|
}
|
||||||
rootCmd.PersistentFlags().BoolVarP(&e.cfg.Run.IsVerbose, "verbose", "v", false, "verbose output")
|
rootCmd.PersistentFlags().BoolVarP(&e.cfg.Run.IsVerbose, "verbose", "v", false, wh("verbose output"))
|
||||||
rootCmd.PersistentFlags().StringVar(&e.cfg.Run.CPUProfilePath, "cpu-profile-path", "", "Path to CPU profile output file")
|
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", "", "Path to memory 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", runtime.NumCPU(), "Concurrency (default NumCPU)")
|
rootCmd.PersistentFlags().IntVarP(&e.cfg.Run.Concurrency, "concurrency", "j", getDefaultConcurrency(), wh("Concurrency (default NumCPU)"))
|
||||||
rootCmd.PersistentFlags().BoolVar(&e.cfg.Run.PrintVersion, "version", false, "Print version")
|
if e.commit != "" {
|
||||||
|
rootCmd.PersistentFlags().BoolVar(&e.cfg.Run.PrintVersion, "version", false, wh("Print version"))
|
||||||
|
}
|
||||||
|
|
||||||
e.rootCmd = rootCmd
|
e.rootCmd = rootCmd
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
"github.com/golangci/golangci-lint/pkg/config"
|
"github.com/golangci/golangci-lint/pkg/config"
|
||||||
"github.com/golangci/golangci-lint/pkg/lint"
|
"github.com/golangci/golangci-lint/pkg/lint"
|
||||||
"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
|
"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
|
||||||
@ -29,92 +30,131 @@ const (
|
|||||||
exitCodeIfTimeout = 4
|
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() {
|
func (e *Executor) initRun() {
|
||||||
var runCmd = &cobra.Command{
|
var runCmd = &cobra.Command{
|
||||||
Use: "run",
|
Use: "run",
|
||||||
Short: "Run linters",
|
Short: welcomeMessage,
|
||||||
Run: e.executeRun,
|
Run: e.executeRun,
|
||||||
}
|
}
|
||||||
e.rootCmd.AddCommand(runCmd)
|
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
|
// Output config
|
||||||
oc := &e.cfg.Output
|
oc := &e.cfg.Output
|
||||||
runCmd.Flags().StringVar(&oc.Format, "out-format",
|
runCmd.Flags().StringVar(&oc.Format, "out-format",
|
||||||
config.OutFormatColoredLineNumber,
|
config.OutFormatColoredLineNumber,
|
||||||
fmt.Sprintf("Format of output: %s", strings.Join(config.OutFormats, "|")))
|
wh(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.PrintIssuedLine, "print-issued-lines", true, wh("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.PrintLinterName, "print-linter-name", true, wh("Print linter name in issue line"))
|
||||||
runCmd.Flags().BoolVar(&oc.PrintWelcomeMessage, "print-welcome", false, "Print welcome message")
|
runCmd.Flags().BoolVar(&oc.PrintWelcomeMessage, "print-welcome", false, wh("Print welcome message"))
|
||||||
|
hideFlag("print-welcome") // no longer used
|
||||||
|
|
||||||
// Run config
|
// Run config
|
||||||
rc := &e.cfg.Run
|
rc := &e.cfg.Run
|
||||||
runCmd.Flags().IntVar(&rc.ExitCodeIfIssuesFound, "issues-exit-code",
|
runCmd.Flags().IntVar(&rc.ExitCodeIfIssuesFound, "issues-exit-code",
|
||||||
1, "Exit code when issues were found")
|
1, wh("Exit code when issues were found"))
|
||||||
runCmd.Flags().StringSliceVar(&rc.BuildTags, "build-tags", []string{}, "Build tags (not all linters support them)")
|
runCmd.Flags().StringSliceVar(&rc.BuildTags, "build-tags", []string{}, wh("Build tags (not all linters support them)"))
|
||||||
runCmd.Flags().DurationVar(&rc.Deadline, "deadline", time.Minute, "Deadline for total work")
|
runCmd.Flags().DurationVar(&rc.Deadline, "deadline", time.Minute, wh("Deadline for total work"))
|
||||||
runCmd.Flags().BoolVar(&rc.AnalyzeTests, "tests", false, "Analyze tests (*_test.go)")
|
runCmd.Flags().BoolVar(&rc.AnalyzeTests, "tests", false, wh("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().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", "", "Read config from file path `PATH`")
|
runCmd.Flags().StringVarP(&rc.Config, "config", "c", "", wh("Read config from file path `PATH`"))
|
||||||
runCmd.Flags().BoolVar(&rc.NoConfig, "no-config", false, "Don't read config")
|
runCmd.Flags().BoolVar(&rc.NoConfig, "no-config", false, wh("Don't read config"))
|
||||||
|
|
||||||
// Linters settings config
|
// Linters settings config
|
||||||
lsc := &e.cfg.LintersSettings
|
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")
|
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()")
|
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")
|
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")
|
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")
|
runCmd.Flags().BoolVar(&lsc.Gofmt.Simplify, "gofmt.simplify", true, "Gofmt: simplify code")
|
||||||
|
hideFlag("gofmt.simplify")
|
||||||
|
|
||||||
runCmd.Flags().IntVar(&lsc.Gocyclo.MinComplexity, "gocyclo.min-complexity",
|
runCmd.Flags().IntVar(&lsc.Gocyclo.MinComplexity, "gocyclo.min-complexity",
|
||||||
30, "Minimal complexity of function to report it")
|
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")
|
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",
|
runCmd.Flags().IntVar(&lsc.Dupl.Threshold, "dupl.threshold",
|
||||||
150, "Dupl: Minimal threshold to detect copy-paste")
|
150, "Dupl: Minimal threshold to detect copy-paste")
|
||||||
|
hideFlag("dupl.threshold")
|
||||||
|
|
||||||
runCmd.Flags().IntVar(&lsc.Goconst.MinStringLen, "goconst.min-len",
|
runCmd.Flags().IntVar(&lsc.Goconst.MinStringLen, "goconst.min-len",
|
||||||
3, "Goconst: minimum constant string length")
|
3, "Goconst: minimum constant string length")
|
||||||
|
hideFlag("goconst.min-len")
|
||||||
runCmd.Flags().IntVar(&lsc.Goconst.MinOccurrencesCount, "goconst.min-occurrences",
|
runCmd.Flags().IntVar(&lsc.Goconst.MinOccurrencesCount, "goconst.min-occurrences",
|
||||||
3, "Goconst: minimum occurrences of constant string count to trigger issue")
|
3, "Goconst: minimum occurrences of constant string count to trigger issue")
|
||||||
|
hideFlag("goconst.min-occurrences")
|
||||||
|
|
||||||
// (@dixonwille) These flag is only used for testing purposes.
|
// (@dixonwille) These flag is only used for testing purposes.
|
||||||
runCmd.Flags().StringSliceVar(&lsc.Depguard.Packages, "depguard.packages", nil,
|
runCmd.Flags().StringSliceVar(&lsc.Depguard.Packages, "depguard.packages", nil,
|
||||||
"Depguard: packages to add to the list")
|
"Depguard: packages to add to the list")
|
||||||
if err := runCmd.Flags().MarkHidden("depguard.packages"); err != nil {
|
hideFlag("depguard.packages")
|
||||||
panic(err) //Considering The only time this is called is if name does not exist
|
|
||||||
}
|
|
||||||
runCmd.Flags().BoolVar(&lsc.Depguard.IncludeGoRoot, "depguard.include-go-root", false,
|
runCmd.Flags().BoolVar(&lsc.Depguard.IncludeGoRoot, "depguard.include-go-root", false,
|
||||||
"Depguard: check list against standard lib")
|
"Depguard: check list against standard lib")
|
||||||
if err := runCmd.Flags().MarkHidden("depguard.include-go-root"); err != nil {
|
hideFlag("depguard.include-go-root")
|
||||||
panic(err) //Considering The only time this is called is if name does not exist
|
|
||||||
}
|
|
||||||
|
|
||||||
// Linters config
|
// Linters config
|
||||||
lc := &e.cfg.Linters
|
lc := &e.cfg.Linters
|
||||||
runCmd.Flags().StringSliceVarP(&lc.Enable, "enable", "E", []string{}, "Enable specific linter")
|
runCmd.Flags().StringSliceVarP(&lc.Enable, "enable", "E", []string{}, wh("Enable specific linter"))
|
||||||
runCmd.Flags().StringSliceVarP(&lc.Disable, "disable", "D", []string{}, "Disable specific linter")
|
runCmd.Flags().StringSliceVarP(&lc.Disable, "disable", "D", []string{}, wh("Disable specific linter"))
|
||||||
runCmd.Flags().BoolVar(&lc.EnableAll, "enable-all", false, "Enable all linters")
|
runCmd.Flags().BoolVar(&lc.EnableAll, "enable-all", false, wh("Enable all linters"))
|
||||||
runCmd.Flags().BoolVar(&lc.DisableAll, "disable-all", false, "Disable all linters")
|
runCmd.Flags().BoolVar(&lc.DisableAll, "disable-all", false, wh("Disable all linters"))
|
||||||
runCmd.Flags().StringSliceVarP(&lc.Presets, "presets", "p", []string{},
|
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(), "|")))
|
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, "Run only fast linters from enabled linters set")
|
runCmd.Flags().BoolVar(&lc.Fast, "fast", false, wh("Run only fast linters from enabled linters set"))
|
||||||
|
|
||||||
// Issues config
|
// Issues config
|
||||||
ic := &e.cfg.Issues
|
ic := &e.cfg.Issues
|
||||||
runCmd.Flags().StringSliceVarP(&ic.ExcludePatterns, "exclude", "e", []string{}, "Exclude issue by regexp")
|
runCmd.Flags().StringSliceVarP(&ic.ExcludePatterns, "exclude", "e", []string{}, wh("Exclude issue by regexp"))
|
||||||
runCmd.Flags().BoolVar(&ic.UseDefaultExcludes, "exclude-use-default", true,
|
runCmd.Flags().BoolVar(&ic.UseDefaultExcludes, "exclude-use-default", true, getDefaultExcludeHelp())
|
||||||
fmt.Sprintf("Use or not use default excludes: (%s)", strings.Join(config.DefaultExcludePatterns, "|")))
|
|
||||||
|
|
||||||
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.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, "Maximum count of issues with the same text. 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().BoolVarP(&ic.Diff, "new", "n", false,
|
||||||
runCmd.Flags().StringVar(&ic.DiffFromRevision, "new-from-rev", "", "Show only new issues created after git revision `REV`")
|
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.DiffPatchFilePath, "new-from-patch", "", "Show only new issues created in git patch with file path `PATH`")
|
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)
|
e.parseConfig(runCmd)
|
||||||
}
|
}
|
||||||
@ -134,7 +174,7 @@ func (e *Executor) runAnalysis(ctx context.Context, args []string) (<-chan resul
|
|||||||
|
|
||||||
excludePatterns := e.cfg.Issues.ExcludePatterns
|
excludePatterns := e.cfg.Issues.ExcludePatterns
|
||||||
if e.cfg.Issues.UseDefaultExcludes {
|
if e.cfg.Issues.UseDefaultExcludes {
|
||||||
excludePatterns = append(excludePatterns, config.DefaultExcludePatterns...)
|
excludePatterns = append(excludePatterns, config.GetDefaultExcludePatternsStrings()...)
|
||||||
}
|
}
|
||||||
var excludeTotalPattern string
|
var excludeTotalPattern string
|
||||||
if len(excludePatterns) != 0 {
|
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) {
|
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
|
needTrackResources := e.cfg.Run.IsVerbose || e.cfg.Run.PrintResourcesUsage
|
||||||
trackResourcesEndCh := make(chan struct{})
|
trackResourcesEndCh := make(chan struct{})
|
||||||
defer func() { // XXX: this defer must be before ctx.cancel defer
|
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)
|
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 {
|
if err := e.runAndPrint(ctx, args); err != nil {
|
||||||
logrus.Warnf("running error: %s", err)
|
logrus.Warnf("running error: %s", err)
|
||||||
if e.exitCode == 0 {
|
if e.exitCode == 0 {
|
||||||
|
@ -14,29 +14,72 @@ const (
|
|||||||
|
|
||||||
var OutFormats = []string{OutFormatColoredLineNumber, OutFormatLineNumber, OutFormatJSON}
|
var OutFormats = []string{OutFormatColoredLineNumber, OutFormatLineNumber, OutFormatJSON}
|
||||||
|
|
||||||
var DefaultExcludePatterns = []string{
|
type ExcludePattern struct {
|
||||||
// errcheck
|
Pattern string
|
||||||
"Error return value of .((os\\.)?std(out|err)\\..*|.*Close|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked",
|
Linter string
|
||||||
|
Why string
|
||||||
|
}
|
||||||
|
|
||||||
// golint
|
var DefaultExcludePatterns = []ExcludePattern{
|
||||||
"should have comment",
|
{
|
||||||
"comment on exported method",
|
Pattern: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked",
|
||||||
"func name will be used as test\\.Test.* by other packages, and that stutters; consider calling this",
|
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
|
func GetDefaultExcludePatternsStrings() []string {
|
||||||
"G103:", // Use of unsafe calls should be audited
|
var ret []string
|
||||||
"G104:", // disable what errcheck does: it reports on Close etc
|
for _, p := range DefaultExcludePatterns {
|
||||||
"G204:", // Subprocess launching should be audited: too lot false positives
|
ret = append(ret, p.Pattern)
|
||||||
"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)`
|
|
||||||
|
|
||||||
// govet
|
return ret
|
||||||
"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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Run struct {
|
type Run struct {
|
||||||
|
@ -59,6 +59,17 @@ func buildTemplateContext() (map[string]interface{}, error) {
|
|||||||
|
|
||||||
lintersOutParts := bytes.Split(lintersOut, []byte("\n\n"))
|
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{}{
|
return map[string]interface{}{
|
||||||
"GolangciYaml": string(golangciYaml),
|
"GolangciYaml": string(golangciYaml),
|
||||||
"LintersCommandOutputEnabledOnly": string(lintersOutParts[0]),
|
"LintersCommandOutputEnabledOnly": string(lintersOutParts[0]),
|
||||||
@ -66,6 +77,7 @@ func buildTemplateContext() (map[string]interface{}, error) {
|
|||||||
"EnabledByDefaultLinters": getLintersListMarkdown(true),
|
"EnabledByDefaultLinters": getLintersListMarkdown(true),
|
||||||
"DisabledByDefaultLinters": getLintersListMarkdown(false),
|
"DisabledByDefaultLinters": getLintersListMarkdown(false),
|
||||||
"ThanksList": getThanksList(),
|
"ThanksList": getThanksList(),
|
||||||
|
"RunHelpText": string(shortHelp),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ func getGometalinterCommonArgs() []string {
|
|||||||
"--vendor",
|
"--vendor",
|
||||||
"--cyclo-over=30",
|
"--cyclo-over=30",
|
||||||
"--dupl-threshold=150",
|
"--dupl-threshold=150",
|
||||||
"--exclude", fmt.Sprintf("(%s)", strings.Join(config.DefaultExcludePatterns, "|")),
|
"--exclude", fmt.Sprintf("(%s)", strings.Join(config.GetDefaultExcludePatternsStrings(), "|")),
|
||||||
"--disable-all",
|
"--disable-all",
|
||||||
"--enable=vet",
|
"--enable=vet",
|
||||||
"--enable=vetshadow",
|
"--enable=vetshadow",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user