mirror of
https://github.com/scratchfoundation/golangci-lint.git
synced 2025-08-13 06:48:43 -04:00
docs: migrate README.md to a website (#1094)
Make a website https://golangci-lint.run for golangci-lint documentation. The website is backed by Gatsby static site generator and deployed into Netlify.
This commit is contained in:
parent
a85e1e1faa
commit
2d4d503a79
35 changed files with 23004 additions and 2153 deletions
.github
.gitignoreCHANGELOG.mdMakefileREADME.mdREADME.tmpl.mddocs
.gitignoreLICENSEgatsby-config.jspackage-lock.jsonpackage.json
src
static
template_data.statescripts/expand_website_templates
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -1,3 +1 @@
|
|||
Thank you for the pull request!
|
||||
|
||||
Please make sure you didn't directly change `README.md`: it should be changed only by changing `README.tmpl.md` and running `make README.md`.
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -13,3 +13,4 @@
|
|||
/tools/svg-term
|
||||
/.vscode/
|
||||
*.test
|
||||
.DS_Store
|
||||
|
|
|
@ -2,13 +2,14 @@ Follow the news and releases on our [twitter](https://twitter.com/golangci) and
|
|||
There is the most valuable changes log:
|
||||
|
||||
### May 2020
|
||||
|
||||
1. Add new linters: `nolintlint`, `goerr113`
|
||||
2. Updated linters: `godot`
|
||||
2. Updated linters: `godot`, `staticcheck`
|
||||
|
||||
### April 2020
|
||||
|
||||
1. Add new linters: `testpackage`, `nestif`, `godot`, `gomodguard`, `asciicheck`
|
||||
2. Add github actions output format
|
||||
2. Add github actions output format
|
||||
3. Update linters: `wsl`, `gomodguard`, `gosec`
|
||||
4. Support `disabled-tags` setting for `gocritic`
|
||||
5. Mitigate OOM and "failed prerequisites"
|
||||
|
@ -63,4 +64,4 @@ There is the most valuable changes log:
|
|||
7. Support `--color` option
|
||||
8. Update x/tools to fix c++ issues
|
||||
9. Include support for log level
|
||||
10. Sort linters list in help commands
|
||||
10. Sort linters list in help commands
|
||||
|
|
21
Makefile
21
Makefile
|
@ -1,8 +1,6 @@
|
|||
.DEFAULT_GOAL = test
|
||||
.PHONY: FORCE
|
||||
|
||||
# enable module support across all go commands.
|
||||
export GO111MODULE = on
|
||||
# enable consistent Go 1.12/1.13 GOPROXY behavior.
|
||||
export GOPROXY = https://proxy.golang.org
|
||||
|
||||
|
@ -42,14 +40,11 @@ test_linters:
|
|||
|
||||
# Maintenance
|
||||
|
||||
generate: README.md assets/demo.svg install.sh assets/github-action-config.json
|
||||
generate: install.sh assets/github-action-config.json
|
||||
.PHONY: generate
|
||||
|
||||
fast_generate: README.md
|
||||
.PHONY: fast_generate
|
||||
|
||||
maintainer-clean: clean
|
||||
rm -rf assets/demo.svg README.md install.sh
|
||||
rm -rf install.sh
|
||||
.PHONY: maintainer-clean
|
||||
|
||||
check_generated:
|
||||
|
@ -58,12 +53,6 @@ check_generated:
|
|||
git diff --exit-code # check no changes
|
||||
.PHONY: check_generated
|
||||
|
||||
fast_check_generated:
|
||||
$(MAKE) --always-make fast_generate
|
||||
git checkout -- go.mod go.sum # can differ between go1.12 and go1.13
|
||||
git diff --exit-code # check no changes
|
||||
.PHONY: fast_check_generated
|
||||
|
||||
release: .goreleaser.yml tools/goreleaser
|
||||
./tools/goreleaser
|
||||
.PHONY: release
|
||||
|
@ -85,22 +74,22 @@ tools/goreleaser: export GOFLAGS = -mod=readonly
|
|||
tools/goreleaser: tools/go.mod tools/go.sum
|
||||
cd tools && go build github.com/goreleaser/goreleaser
|
||||
|
||||
# TODO: migrate to docs/
|
||||
tools/svg-term: tools/package.json tools/package-lock.json
|
||||
cd tools && npm ci
|
||||
ln -sf node_modules/.bin/svg-term $@
|
||||
|
||||
# TODO: migrate to docs/
|
||||
tools/Dracula.itermcolors:
|
||||
curl -fL -o $@ https://raw.githubusercontent.com/dracula/iterm/master/Dracula.itermcolors
|
||||
|
||||
# TODO: migrate to docs/
|
||||
assets/demo.svg: tools/svg-term tools/Dracula.itermcolors
|
||||
./tools/svg-term --cast=183662 --out assets/demo.svg --window --width 110 --height 30 --from 2000 --to 20000 --profile ./tools/Dracula.itermcolors --term iterm2
|
||||
|
||||
install.sh: .goreleaser.yml tools/godownloader
|
||||
./tools/godownloader .goreleaser.yml | sed '/DO NOT EDIT/s/ on [0-9TZ:-]*//' > $@
|
||||
|
||||
README.md: FORCE golangci-lint
|
||||
go run ./scripts/gen_readme/main.go
|
||||
|
||||
assets/github-action-config.json: FORCE golangci-lint
|
||||
go run ./scripts/gen_github_action_config/main.go $@
|
||||
|
||||
|
|
660
README.tmpl.md
660
README.tmpl.md
|
@ -1,660 +0,0 @@
|
|||
# GolangCI-Lint
|
||||
|
||||

|
||||
[](/LICENSE)
|
||||
[](https://github.com/golangci/golangci-lint/releases/latest)
|
||||
[](https://hub.docker.com/r/golangci/golangci-lint)
|
||||
|
||||
GolangCI-Lint is a linters aggregator. It's fast: on average [5 times faster](#performance) than gometalinter.
|
||||
It's [easy to integrate and use](#command-line-options), has [nice output](#quick-start) and has a minimum number of false positives. It supports go modules.
|
||||
|
||||
GolangCI-Lint has [integrations](#editor-integration) with VS Code, GNU Emacs, Sublime Text.
|
||||
|
||||
Follow the news and releases on our [twitter](https://twitter.com/golangci) and our [blog](https://medium.com/golangci).
|
||||
|
||||
Sponsored by [GolangCI.com](https://golangci.com): SaaS service for running linters on GitHub pull requests. Free for Open Source.
|
||||
|
||||
<a href="https://golangci.com/"><img src="assets/go.png" width="250px"></a>
|
||||
|
||||
- [GolangCI-Lint](#golangci-lint)
|
||||
- [Demo](#demo)
|
||||
- [Install](#install)
|
||||
- [Binary](#binary)
|
||||
- [macOS](#macos)
|
||||
- [Docker](#docker)
|
||||
- [Go](#go)
|
||||
- [Trusted By](#trusted-by)
|
||||
- [Quick Start](#quick-start)
|
||||
- [Editor Integration](#editor-integration)
|
||||
- [Shell Completion](#shell-completion)
|
||||
- [macOS](#macos-1)
|
||||
- [Linux](#linux)
|
||||
- [Comparison](#comparison)
|
||||
- [`golangci-lint` vs `gometalinter`](#golangci-lint-vs-gometalinter)
|
||||
- [`golangci-lint` vs Running Linters Manually](#golangci-lint-vs-running-linters-manually)
|
||||
- [Performance](#performance)
|
||||
- [Comparison with gometalinter](#comparison-with-gometalinter)
|
||||
- [Why golangci-lint is faster](#why-golangci-lint-is-faster)
|
||||
- [Memory Usage of Golangci-lint](#memory-usage-of-golangci-lint)
|
||||
- [Internals](#internals)
|
||||
- [Supported Linters](#supported-linters)
|
||||
- [Enabled By Default Linters](#enabled-by-default-linters)
|
||||
- [Disabled By Default Linters (`-E/--enable`)](#disabled-by-default-linters--e--enable)
|
||||
- [Configuration](#configuration)
|
||||
- [Command-Line Options](#command-line-options)
|
||||
- [Config File](#config-file)
|
||||
- [Custom Linters](#custom-linters)
|
||||
- [Create a Copy of `golangci-lint` that Can Run with Plugins](#create-a-copy-of-golangci-lint-that-can-run-with-plugins)
|
||||
- [Configure Your Project for Linting](#configure-your-project-for-linting)
|
||||
- [To Create Your Own Custom Linter](#to-create-your-own-custom-linter)
|
||||
- [False Positives](#false-positives)
|
||||
- [Nolint](#nolint)
|
||||
- [FAQ](#faq)
|
||||
- [Thanks](#thanks)
|
||||
- [Changelog](#changelog)
|
||||
- [Debug](#debug)
|
||||
- [Future Plans](#future-plans)
|
||||
- [Contact Information](#contact-information)
|
||||
- [License Scan](#license-scan)
|
||||
|
||||
## Demo
|
||||
|
||||
<p align="center">
|
||||
<img src="./assets/demo.svg" width="100%">
|
||||
</p>
|
||||
|
||||
Short 1.5 min video demo of analyzing [beego](https://github.com/astaxie/beego).
|
||||
[](https://asciinema.org/a/183662)
|
||||
|
||||
## Install
|
||||
|
||||
### Binary
|
||||
|
||||
Most installations are done for CI (e.g. Travis CI, CircleCI). It's important to have reproducible CI:
|
||||
don't start to fail all builds at the same time. With golangci-lint this can happen if you
|
||||
use deprecated option `--enable-all` and a new linter is added or even without `--enable-all`: when one upstream linter is upgraded.
|
||||
|
||||
It's highly recommended to install a specific version of golangci-lint available on the [releases page](https://github.com/golangci/golangci-lint/releases).
|
||||
|
||||
Here is the recommended way to install golangci-lint {{.LatestVersion}}:
|
||||
|
||||
```bash
|
||||
# binary will be $(go env GOPATH)/bin/golangci-lint
|
||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin {{.LatestVersion}}
|
||||
|
||||
# or install it into ./bin/
|
||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s {{.LatestVersion}}
|
||||
|
||||
# In alpine linux (as it does not come with curl by default)
|
||||
wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s {{.LatestVersion}}
|
||||
|
||||
golangci-lint --version
|
||||
```
|
||||
|
||||
It is advised that you periodically update version of golangci-lint as the project is under active development
|
||||
and is constantly being improved. For any problems with golangci-lint, check out recent [GitHub issues](https://github.com/golangci/golangci-lint/issues) and update if needed.
|
||||
|
||||
### macOS
|
||||
|
||||
You can also install a binary release on macOS using [brew](https://brew.sh/):
|
||||
|
||||
```bash
|
||||
brew install golangci/tap/golangci-lint
|
||||
brew upgrade golangci/tap/golangci-lint
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:{{.LatestVersion}} golangci-lint run -v
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
Go source installations are supported for the two most recent Go releases.
|
||||
|
||||
```bash
|
||||
GO111MODULE=on go get github.com/golangci/golangci-lint/cmd/golangci-lint@{{.LatestVersion}}
|
||||
```
|
||||
|
||||
## Trusted By
|
||||
|
||||
The following companies/products use golangci-lint:
|
||||
|
||||
* [Google](https://github.com/GoogleContainerTools/skaffold)
|
||||
* [Facebook](https://github.com/facebookincubator/fbender)
|
||||
* [Red Hat OpenShift](https://github.com/openshift/telemeter)
|
||||
* [Yahoo](https://github.com/yahoo/yfuzz)
|
||||
* [IBM](https://github.com/ibm-developer/ibm-cloud-env-golang)
|
||||
* [Intuit](https://github.com/intuit)
|
||||
* [Xiaomi](https://github.com/XiaoMi/soar)
|
||||
* [Baidu](https://github.com/baidu/bfe)
|
||||
* [Samsung](https://github.com/samsung-cnct/cluster-api-provider-ssh)
|
||||
* [Arduino](https://github.com/arduino/arduino-cli)
|
||||
* [Eclipse Foundation](https://github.com/eclipse/che-go-jsonrpc)
|
||||
* [WooCart](https://github.com/woocart/gsutil)
|
||||
* [Percona](https://github.com/percona/pmm-managed)
|
||||
* [Serverless](https://github.com/serverless/event-gateway)
|
||||
* [ScyllaDB](https://github.com/scylladb/gocqlx)
|
||||
* [NixOS](https://github.com/NixOS/nixpkgs-channels)
|
||||
* [The New York Times](https://github.com/NYTimes/encoding-wrapper)
|
||||
* [Istio](https://github.com/istio/istio)
|
||||
* [SoundCloud](https://github.com/soundcloud/periskop)
|
||||
* [Mattermost](https://github.com/mattermost/mattermost-server)
|
||||
|
||||
The following great projects use golangci-lint:
|
||||
|
||||
* [alecthomas/participle](https://github.com/alecthomas/participle)
|
||||
* [asobti/kube-monkey](https://github.com/asobti/kube-monkey)
|
||||
* [banzaicloud/pipeline](https://github.com/banzaicloud/pipeline)
|
||||
* [caicloud/cyclone](https://github.com/caicloud/cyclone)
|
||||
* [getantibody/antibody](https://github.com/getantibody/antibody)
|
||||
* [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)
|
||||
* [go-swagger/go-swagger](https://github.com/go-swagger/go-swagger)
|
||||
* [kubeedge/kubeedge](https://github.com/kubeedge/kubeedge)
|
||||
* [kubernetes-sigs/kustomize](https://github.com/kubernetes-sigs/kustomize)
|
||||
* [dunglas/mercure](https://github.com/dunglas/mercure)
|
||||
* [posener/complete](https://github.com/posener/complete)
|
||||
* [segmentio/terraform-docs](https://github.com/segmentio/terraform-docs)
|
||||
* [tsuru/tsuru](https://github.com/tsuru/tsuru)
|
||||
* [twpayne/chezmoi](https://github.com/twpayne/chezmoi)
|
||||
* [virtual-kubelet/virtual-kubelet](https://github.com/virtual-kubelet/virtual-kubelet)
|
||||
* [xenolf/lego](https://github.com/xenolf/lego)
|
||||
* [y0ssar1an/q](https://github.com/y0ssar1an/q)
|
||||
|
||||
## Quick Start
|
||||
|
||||
To run golangci-lint execute:
|
||||
|
||||
```bash
|
||||
golangci-lint run
|
||||
```
|
||||
|
||||
It's an equivalent of executing:
|
||||
|
||||
```bash
|
||||
golangci-lint run ./...
|
||||
```
|
||||
|
||||
You can choose which directories and files to analyze:
|
||||
|
||||
```bash
|
||||
golangci-lint run dir1 dir2/... dir3/file1.go
|
||||
```
|
||||
|
||||
Directories are NOT analyzed recursively. To analyze them recursively append `/...` to their path.
|
||||
|
||||
GolangCI-Lint can be used with zero configuration. By default the following linters are enabled:
|
||||
|
||||
```bash
|
||||
$ golangci-lint help linters
|
||||
{{.LintersCommandOutputEnabledOnly}}
|
||||
```
|
||||
|
||||
and the following linters are disabled by default:
|
||||
|
||||
```bash
|
||||
$ golangci-lint help linters
|
||||
...
|
||||
{{.LintersCommandOutputDisabledOnly}}
|
||||
```
|
||||
|
||||
Pass `-E/--enable` to enable linter and `-D/--disable` to disable:
|
||||
|
||||
```bash
|
||||
golangci-lint run --disable-all -E errcheck
|
||||
```
|
||||
|
||||
## Editor Integration
|
||||
|
||||
1. [Go for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-vscode.Go).
|
||||
Recommended settings for VS Code are:
|
||||
|
||||
```json
|
||||
"go.lintTool":"golangci-lint",
|
||||
"go.lintFlags": [
|
||||
"--fast"
|
||||
]
|
||||
```
|
||||
|
||||
Using it in an editor without `--fast` can freeze your editor.
|
||||
Golangci-lint automatically discovers `.golangci.yml` config for edited file: you don't need to configure it in VS Code settings.
|
||||
2. Sublime Text - [plugin](https://github.com/alecthomas/SublimeLinter-contrib-golang-cilint) for SublimeLinter.
|
||||
3. GoLand
|
||||
* Add [File Watcher](https://www.jetbrains.com/help/go/settings-tools-file-watchers.html) using existing `golangci-lint` template.
|
||||
* If your version of GoLand does not have the `golangci-lint` [File Watcher](https://www.jetbrains.com/help/go/settings-tools-file-watchers.html) template you can configure your own and use arguments `run --disable=typecheck $FileDir$`.
|
||||
4. GNU Emacs
|
||||
* [Spacemacs](https://github.com/syl20bnr/spacemacs/blob/develop/layers/+lang/go/README.org#pre-requisites)
|
||||
* [flycheck checker](https://github.com/weijiangan/flycheck-golangci-lint).
|
||||
5. Vim
|
||||
* [vim-go](https://github.com/fatih/vim-go)
|
||||
* syntastic [merged pull request](https://github.com/vim-syntastic/syntastic/pull/2190) with golangci-lint support
|
||||
* ale [merged pull request](https://github.com/w0rp/ale/pull/1890) with golangci-lint support
|
||||
6. Atom - [go-plus](https://atom.io/packages/go-plus) supports golangci-lint.
|
||||
|
||||
## Shell Completion
|
||||
|
||||
`golangci-lint` can generate bash completion file.
|
||||
|
||||
### macOS
|
||||
|
||||
There are two versions of `bash-completion`, v1 and v2. V1 is for Bash 3.2 (which is the default on macOS), and v2 is for Bash 4.1+. The `golangci-lint` completion script doesn’t work correctly with bash-completion v1 and Bash 3.2. It requires bash-completion v2 and Bash 4.1+. Thus, to be able to correctly use `golangci-lint` completion on macOS, you have to install and use Bash 4.1+ ([instructions](https://itnext.io/upgrading-bash-on-macos-7138bd1066ba)). The following instructions assume that you use Bash 4.1+ (that is, any Bash version of 4.1 or newer).
|
||||
|
||||
Install `bash-completion v2`:
|
||||
|
||||
```bash
|
||||
brew install bash-completion@2
|
||||
echo 'export BASH_COMPLETION_COMPAT_DIR="/usr/local/etc/bash_completion.d"' >>~/.bashrc
|
||||
echo '[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"' >>~/.bashrc
|
||||
exec bash # reload and replace (if it was updated) shell
|
||||
type _init_completion && echo "completion is OK" # verify that bash-completion v2 is correctly installed
|
||||
```
|
||||
|
||||
Add `golangci-lint` bash completion:
|
||||
|
||||
```bash
|
||||
echo 'source <(golangci-lint completion bash)' >>~/.bashrc
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
### Linux
|
||||
|
||||
See [kubectl instructions](https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion) and don't forget to replace `kubectl` with `golangci-lint`.
|
||||
|
||||
## Comparison
|
||||
|
||||
### `golangci-lint` vs `gometalinter`
|
||||
|
||||
GolangCI-Lint was created to fix the following issues with `gometalinter`:
|
||||
|
||||
1. Slow work: `gometalinter` usually works for minutes in average projects.
|
||||
**GolangCI-Lint works [2-7x times faster](#performance)** by [reusing work](#internals).
|
||||
2. Huge memory consumption: parallel linters don't share the same program representation and can consume
|
||||
`n` times more memory (`n` - concurrency). GolangCI-Lint fixes it by sharing representation and **consumes 26% less memory**.
|
||||
3. Doesn't use real bounded concurrency: if you set it to `n` it can take up to `n*n` threads because of
|
||||
forced threads in specific linters. `gometalinter` can't do anything about it because it runs linters as
|
||||
black boxes in forked processes. In GolangCI-Lint we run all linters in one process and completely control
|
||||
them. Configured concurrency will be correctly bounded.
|
||||
This issue is important because you often want to set concurrency to the CPUs count minus one to
|
||||
ensure you **do not freeze your PC** and be able to work on it while analyzing code.
|
||||
4. Lack of nice output. We like how the `gcc` and `clang` compilers format their warnings: **using colors,
|
||||
printing warning lines and showing the position in line**.
|
||||
5. Too many issues. GolangCI-Lint cuts a lot of issues by using default exclude list of common false-positives.
|
||||
By default, it has enabled **smart issues processing**: merge multiple issues for one line, merge issues with the
|
||||
same text or from the same linter. All of these smart processors can be configured by the user.
|
||||
6. Integration into large codebases. A good way to start using linters in a large project is not to fix a plethora
|
||||
of existing issues, but to set up CI and **fix only issues in new commits**. You can use `revgrep` for it, but it's
|
||||
yet another utility to install and configure. With `golangci-lint` it's much easier: `revgrep` is already built into
|
||||
`golangci-lint` and you can use it with one option (`-n, --new` or `--new-from-rev`).
|
||||
7. Installation. With `gometalinter`, you need to run a linters installation step. It's easy to forget this step and
|
||||
end up with stale linters. It also complicates CI setup. GolangCI-Lint requires **no installation of linters**.
|
||||
8. **Yaml or toml config**. Gometalinter's JSON isn't convenient for config files.
|
||||
|
||||
### `golangci-lint` vs Running Linters Manually
|
||||
|
||||
1. It will be much slower because `golangci-lint` runs all linters in parallel and shares 50-80% of linters work.
|
||||
2. It will have less control and more false-positives: some linters can't be properly configured without hacks.
|
||||
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 concurrent linting as a default consuming all cores.
|
||||
Benchmark was run (and measured) automatically, see the code
|
||||
[here](https://github.com/golangci/golangci-lint/blob/master/test/bench/bench_test.go) (`BenchmarkWithGometalinter`).
|
||||
|
||||
We measure peak memory usage (RSS) by tracking of processes RSS every 5 ms.
|
||||
|
||||
### Comparison with gometalinter
|
||||
|
||||
We compare golangci-lint and gometalinter in default mode, but explicitly enable all linters because of small differences in the default configuration.
|
||||
|
||||
```bash
|
||||
$ golangci-lint run --no-config --issues-exit-code=0 --timeout=30m \
|
||||
--disable-all --enable=deadcode --enable=gocyclo --enable=golint --enable=varcheck \
|
||||
--enable=structcheck --enable=maligned --enable=errcheck --enable=dupl --enable=ineffassign \
|
||||
--enable=interfacer --enable=unconvert --enable=goconst --enable=gosec --enable=megacheck
|
||||
$ gometalinter --deadline=30m --vendor --cyclo-over=30 --dupl-threshold=150 \
|
||||
--exclude=<default golangci-lint excludes> --skip=testdata --skip=builtin \
|
||||
--disable-all --enable=deadcode --enable=gocyclo --enable=golint --enable=varcheck \
|
||||
--enable=structcheck --enable=maligned --enable=errcheck --enable=dupl --enable=ineffassign \
|
||||
--enable=interfacer --enable=unconvert --enable=goconst --enable=gosec --enable=megacheck
|
||||
./...
|
||||
```
|
||||
|
||||
| Repository | GolangCI Time | GolangCI Is Faster than Gometalinter | GolangCI Memory | GolangCI eats less memory than Gometalinter |
|
||||
| ---------- | ------------- | ------------------------------------ | --------------- | ------------------------------------------- |
|
||||
| gometalinter repo, 4 kLoC | 6s | **6.4x** | 0.7GB | 33% |
|
||||
| self-repo, 4 kLoC | 12s | **7.5x** | 1.2GB | 41% |
|
||||
| beego, 50 kLoC | 10s | **4.2x** | 1.4GB | 9% |
|
||||
| hugo, 70 kLoC | 15s | **6.1x** | 1.6GB | 44% |
|
||||
| consul, 127 kLoC | 58s | **4x** | 2.7GB | 41% |
|
||||
| terraform, 190 kLoC | 2m13s | **1.6x** | 4.8GB | 0% |
|
||||
| go-ethereum, 250 kLoC | 33s | **5x** | 3.6GB | 0% |
|
||||
| go source (`$GOROOT/src`), 1300 kLoC | 2m45s | **2x** | 4.7GB | 0% |
|
||||
|
||||
**On average golangci-lint is 4.6 times faster** than gometalinter. Maximum difference is in the
|
||||
self-repo: **7.5 times faster**, minimum difference is in terraform source code repo: 1.8 times faster.
|
||||
|
||||
On average golangci-lint consumes 26% less memory.
|
||||
|
||||
### Why golangci-lint is faster
|
||||
|
||||
Golangci-lint directly calls linters (no forking) and reuses 80% of work by parsing program only once.
|
||||
Read [this section](#internals) for details.
|
||||
|
||||
### Memory Usage of Golangci-lint
|
||||
|
||||
A trade-off between memory usage and execution time can be controlled by [`GOGC`](https://golang.org/pkg/runtime/#hdr-Environment_Variables) environment variable.
|
||||
Less `GOGC` values trigger garbage collection more frequently and golangci-lint consumes less memory and more CPU. Below is the trade-off table for running on this repo:
|
||||
|
||||
|`GOGC`|Peak Memory, GB|Executon Time, s|
|
||||
|------|---------------|----------------|
|
||||
|`5` |1.1 |60 |
|
||||
|`10` |1.1 |34 |
|
||||
|`20` |1.3 |25 |
|
||||
|`30` |1.6 |20.2 |
|
||||
|`50` |2.0 |17.1 |
|
||||
|`80` |2.2 |14.1 |
|
||||
|`100` (default)|2.2 |13.8 |
|
||||
|`off` |3.2 |9.3 |
|
||||
|
||||
## Internals
|
||||
|
||||
1. Work sharing
|
||||
The key difference with gometalinter is that golangci-lint shares work between specific linters (golint, govet, ...).
|
||||
We don't fork to call specific linter but use its API.
|
||||
For small and medium projects 50-90% of work between linters can be reused.
|
||||
|
||||
* load `[]*packages.Package` by `go/packages` once
|
||||
|
||||
We load program (parsing all files and type-checking) only once for all linters. For the most of linters
|
||||
it's the most heavy operation: it takes 5 seconds on 8 kLoC repo and 11 seconds on `$GOROOT/src`.
|
||||
* build `ssa.Program` once
|
||||
|
||||
Some linters (megacheck, interfacer, unparam) work on SSA representation.
|
||||
Building of this representation takes 1.5 seconds on 8 kLoC repo and 6 seconds on `$GOROOT/src`.
|
||||
|
||||
* parse source code and build AST once
|
||||
|
||||
Parsing one source file takes 200 us on average. Parsing of all files in `$GOROOT/src` takes 2 seconds.
|
||||
Currently we parse each file more than once because it's not the bottleneck. But we already save a lot of
|
||||
extra parsing. We're planning to parse each file only once.
|
||||
|
||||
* walk files and directories once
|
||||
|
||||
It takes 300-1000 ms for `$GOROOT/src`.
|
||||
2. Smart linters scheduling
|
||||
|
||||
We schedule linters by a special algorithm which takes estimated execution time into account. It allows
|
||||
to save 10-30% of time when one of heavy linters (megacheck etc) is enabled.
|
||||
|
||||
3. Don't fork to run shell commands
|
||||
|
||||
All linters has their version fixed with go modules, they are builtin
|
||||
and you don't need to install them separately.
|
||||
|
||||
## Supported Linters
|
||||
|
||||
To see a list of supported linters and which linters are enabled/disabled:
|
||||
|
||||
```bash
|
||||
golangci-lint help linters
|
||||
```
|
||||
|
||||
### Enabled By Default Linters
|
||||
|
||||
{{.EnabledByDefaultLinters}}
|
||||
|
||||
### Disabled By Default Linters (`-E/--enable`)
|
||||
|
||||
{{.DisabledByDefaultLinters}}
|
||||
|
||||
## Configuration
|
||||
|
||||
The config file has lower priority than command-line options. If the same bool/string/int option is provided on the command-line
|
||||
and in the config file, the option from command-line will be used.
|
||||
Slice options (e.g. list of enabled/disabled linters) are combined from the command-line and config file.
|
||||
|
||||
To see a list of enabled by your configuration linters:
|
||||
|
||||
```bash
|
||||
golangci-lint linters
|
||||
```
|
||||
|
||||
### Command-Line Options
|
||||
|
||||
```bash
|
||||
golangci-lint run -h
|
||||
{{.RunHelpText}}
|
||||
```
|
||||
|
||||
### Config File
|
||||
|
||||
GolangCI-Lint looks for config files in the following paths from the current working directory:
|
||||
|
||||
* `.golangci.yml`
|
||||
* `.golangci.toml`
|
||||
* `.golangci.json`
|
||||
|
||||
GolangCI-Lint also searches for config files in all directories from the directory of the first analyzed path up to the root.
|
||||
To see which config file is being used and where it was sourced from run golangci-lint with `-v` option.
|
||||
|
||||
Config options inside the file are identical to command-line options.
|
||||
You can configure specific linters' options only within the config file (not the command-line).
|
||||
|
||||
There is a [`.golangci.example.yml`](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml) example
|
||||
config file with all supported options, their description and default value:
|
||||
|
||||
```yaml
|
||||
{{.GolangciYamlExample}}
|
||||
```
|
||||
|
||||
It's a [.golangci.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.yml) config file of this repo: we enable more linters
|
||||
than the default and have more strict settings:
|
||||
|
||||
```yaml
|
||||
{{.GolangciYaml}}
|
||||
```
|
||||
|
||||
## Custom Linters
|
||||
Some people and organizations may choose to have custom made linters run as a part of golangci-lint. That functionality
|
||||
is supported through go's plugin library.
|
||||
|
||||
### Create a Copy of `golangci-lint` that Can Run with Plugins
|
||||
In order to use plugins, you'll need a golangci-lint executable that can run them. The normal version of this project
|
||||
is built with the vendors option, which breaks plugins that have overlapping dependencies.
|
||||
|
||||
1. Download [golangci-lint](https://github.com/golangci/golangci-lint) source code
|
||||
2. From the projects root directory, run `make vendor_free_build`
|
||||
3. Copy the `golangci-lint` executable that was created to your path, project, or other location
|
||||
|
||||
### Configure Your Project for Linting
|
||||
If you already have a linter plugin available, you can follow these steps to define it's usage in a projects
|
||||
`.golangci.yml` file. An example linter can be found at [here](https://github.com/golangci/example-plugin-linter). If you're looking for
|
||||
instructions on how to configure your own custom linter, they can be found further down.
|
||||
|
||||
1. If the project you want to lint does not have one already, copy the [.golangci.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.yml) to the root directory.
|
||||
2. Adjust the yaml to appropriate `linters-settings:custom` entries as so:
|
||||
```
|
||||
linters-settings:
|
||||
custom:
|
||||
example:
|
||||
path: /example.so
|
||||
description: The description of the linter
|
||||
original-url: github.com/golangci/example-linter
|
||||
```
|
||||
|
||||
That is all the configuration that is required to run a custom linter in your project. Custom linters are enabled by default,
|
||||
but abide by the same rules as other linters. If the disable all option is specified either on command line or in
|
||||
`.golangci.yml` files `linters:disable-all: true`, custom linters will be disabled; they can be re-enabled by adding them
|
||||
to the `linters:enable` list, or providing the enabled option on the command line, `golangci-lint run -Eexample`.
|
||||
|
||||
### To Create Your Own Custom Linter
|
||||
|
||||
Your linter must implement one or more `golang.org/x/tools/go/analysis.Analyzer` structs.
|
||||
Your project should also use `go.mod`. All versions of libraries that overlap `golangci-lint` (including replaced
|
||||
libraries) MUST be set to the same version as `golangci-lint`. You can see the versions by running `go version -m golangci-lint`.
|
||||
|
||||
You'll also need to create a go file like `plugin/example.go`. This MUST be in the package `main`, and define a
|
||||
variable of name `AnalyzerPlugin`. The `AnalyzerPlugin` instance MUST implement the following interface:
|
||||
```
|
||||
type AnalyzerPlugin interface {
|
||||
GetAnalyzers() []*analysis.Analyzer
|
||||
}
|
||||
```
|
||||
The type of `AnalyzerPlugin` is not important, but is by convention `type analyzerPlugin struct {}`. See
|
||||
[plugin/example.go](https://github.com/golangci/example-plugin-linter/plugin/example.go) for more info.
|
||||
|
||||
To build the plugin, from the root project directory, run `go build -buildmode=plugin plugin/example.go`. This will create a plugin `*.so`
|
||||
file that can be copied into your project or another well known location for usage in golangci-lint.
|
||||
|
||||
## False Positives
|
||||
|
||||
False positives are inevitable, but we did our best to reduce their count. For example, we have a default enabled set of [exclude patterns](#command-line-options). If a false positive occurred you have the following choices:
|
||||
|
||||
1. Exclude issue by text using command-line option `-e` or config option `issues.exclude`. It's helpful when you decided to ignore all issues of this type. Also, you can use `issues.exclude-rules` config option for per-path or per-linter configuration.
|
||||
2. Exclude this one issue by using special comment `//nolint` (see [the section](#nolint) below).
|
||||
3. Exclude issues in path by `run.skip-dirs`, `run.skip-files` or `issues.exclude-rules` config options.
|
||||
|
||||
Please create [GitHub Issues here](https://github.com/golangci/golangci-lint/issues/new) if you find any false positives. We will add it to the default exclude list if it's common or we will fix underlying linter.
|
||||
|
||||
### Nolint
|
||||
|
||||
To exclude issues from all linters use `//nolint`. For example, if it's used inline (not from the beginning of the line) it excludes issues only for this line.
|
||||
|
||||
```go
|
||||
var bad_name int //nolint
|
||||
```
|
||||
|
||||
To exclude issues from specific linters only:
|
||||
|
||||
```go
|
||||
var bad_name int //nolint:golint,unused
|
||||
```
|
||||
|
||||
To exclude issues for the block of code use this directive on the beginning of a line:
|
||||
|
||||
```go
|
||||
//nolint
|
||||
func allIssuesInThisFunctionAreExcluded() *string {
|
||||
// ...
|
||||
}
|
||||
|
||||
//nolint:govet
|
||||
var (
|
||||
a int
|
||||
b int
|
||||
)
|
||||
```
|
||||
|
||||
Also, you can exclude all issues in a file by:
|
||||
|
||||
```go
|
||||
//nolint:unparam
|
||||
package pkg
|
||||
```
|
||||
|
||||
You may add a comment explaining or justifying why `//nolint` is being used on the same line as the flag itself:
|
||||
|
||||
```go
|
||||
//nolint:gocyclo // This legacy function is complex but the team too busy to simplify it
|
||||
func someLegacyFunction() *string {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
You can see more examples of using `//nolint` in [our tests](https://github.com/golangci/golangci-lint/tree/master/pkg/result/processors/testdata) for it.
|
||||
|
||||
Use `//nolint` instead of `// nolint` because machine-readable comments should have no space by Go convention.
|
||||
|
||||
## FAQ
|
||||
|
||||
**How do you add a custom linter?**
|
||||
|
||||
You can integrate it yourself, see this [wiki page](https://github.com/golangci/golangci-lint/wiki/How-to-add-a-custom-linter) with documentation. Or you can create a [GitHub Issue](https://github.com/golangci/golangci-lint/issues/new) and we will integrate when time permits.
|
||||
|
||||
**It's cool to use `golangci-lint` when starting a project, but what about existing projects with large codebase? It will take days to fix all found issues**
|
||||
|
||||
We are sure that every project can easily integrate `golangci-lint`, even the large one. The idea is to not fix all existing issues. Fix only newly added issue: issues in new code. To do this setup CI (or better use [GolangCI](https://golangci.com)) to run `golangci-lint` with option `--new-from-rev=HEAD~1`. Also, take a look at option `--new`, but consider that CI scripts that generate unstaged files will make `--new` only point out issues in those files and not in the last commit. In that regard `--new-from-rev=HEAD~1` is safer.
|
||||
By doing this you won't create new issues in your code and can choose fix existing issues (or not).
|
||||
|
||||
**How to use `golangci-lint` in CI (Continuous Integration)?**
|
||||
|
||||
Run `golangci-lint` in CI and check the exit code. If it's non-zero - fail the build.
|
||||
|
||||
We don't recommend vendoring `golangci-lint` in your repo: you will get troubles updating `golangci-lint`. Please, use recommended way to install with the shell script: it's very fast.
|
||||
|
||||
**Do I need to run `go install`?**
|
||||
|
||||
No, you don't need to do it anymore.
|
||||
|
||||
**Which go versions are supported**
|
||||
Short answer: go 1.12 and newer are officially supported.
|
||||
|
||||
Long answer:
|
||||
|
||||
1. go < 1.9 isn't supported
|
||||
2. go1.9 is officially supported by golangci-lint <= v1.10.2
|
||||
3. go1.10 is officially supported by golangci-lint <= 1.15.0.
|
||||
4. go1.11 is officially supported by golangci-lint <= 1.17.1.
|
||||
5. go1.12+ are officially supported by the latest version of golangci-lint (>= 1.18.0).
|
||||
|
||||
**`golangci-lint` doesn't work**
|
||||
|
||||
1. Please, ensure you are using the latest binary release.
|
||||
2. Run it with `-v` option and check the output.
|
||||
3. If it doesn't help create a [GitHub issue](https://github.com/golangci/golangci-lint/issues/new) with the output from the error and #2 above.
|
||||
|
||||
**Why running with `--fast` is slow on the first run?**
|
||||
Because the first run caches type information. All subsequent runs will be fast.
|
||||
Usually this options is used during development on local machine and compilation was already performed.
|
||||
|
||||
## Thanks
|
||||
|
||||
Thanks to all [contributors](https://github.com/golangci/golangci-lint/graphs/contributors)!
|
||||
Thanks to [alecthomas/gometalinter](https://github.com/alecthomas/gometalinter) for inspiration and amazing work.
|
||||
Thanks to [bradleyfalzon/revgrep](https://github.com/bradleyfalzon/revgrep) for cool diff tool.
|
||||
|
||||
Thanks to developers and authors of used linters:
|
||||
{{.ThanksList}}
|
||||
|
||||
## Changelog
|
||||
|
||||
{{.ChangeLog}}
|
||||
|
||||
## Debug
|
||||
|
||||
You can see a verbose output of linter by using `-v` option.
|
||||
|
||||
If you would like to see more detailed logs you can set environment variable `GL_DEBUG` to debug `golangci-lint`.
|
||||
It's value is a list of debug tags. For example, `GL_DEBUG=loader,gocritic golangci-lint run`.
|
||||
Existing debug tags:
|
||||
|
||||
1. `gocritic` - debug `go-critic` linter;
|
||||
2. `env` - debug `go env` command;
|
||||
3. `loader` - debug packages loading (including `go/packages` internal debugging);
|
||||
4. `autogen_exclude` - debug a filter excluding autogenerated source code;
|
||||
5. `nolint` - debug a filter excluding issues by `//nolint` comments.
|
||||
|
||||
## Future Plans
|
||||
|
||||
1. Upstream all changes of forked linters.
|
||||
2. Make it easy to write own linter/checker: it should take a minimum code, have perfect documentation, debugging and testing tooling.
|
||||
3. Speed up SSA loading: on-disk cache and existing code profiling-optimizing.
|
||||
4. Analyze (don't only filter) only new code: analyze only changed files and dependencies, make incremental analysis, caches.
|
||||
5. Smart new issues detector: don't print existing issues on changed lines.
|
||||
6. Minimize false-positives by fixing linters and improving testing tooling.
|
||||
7. Automatic issues fixing (code rewrite, refactoring) where it's possible.
|
||||
8. Documentation for every issue type.
|
||||
|
||||
## Contact Information
|
||||
|
||||
Slack channel: [#golangci-lint](https://slack.com/share/IS0TDK8RG/TEKQWjTZXxfK9Ta2G5HrnsMY/enQtODg0OTMxNjU0ODY2LWUyMTQ3NDc2MmNlNGU3NTNhYWE0Nzc3MjUyZjkxZWI3YjI5ODMwNDA1NTU3MmM2Yzc5ZjQyYTFkNThlODllN2Y).
|
||||
|
||||
You can contact the [author](https://github.com/jirfag) of GolangCI-Lint
|
||||
by [denis@golangci.com](mailto:denis@golangci.com). Follow the news and releases on our [twitter](https://twitter.com/golangci) and our [blog](https://medium.com/golangci).
|
||||
|
||||
## License Scan
|
||||
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fgolangci%2Fgolangci-lint?ref=badge_large)
|
69
docs/.gitignore
vendored
Normal file
69
docs/.gitignore
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# dotenv environment variable files
|
||||
.env*
|
||||
|
||||
# gatsby files
|
||||
.cache/
|
||||
public
|
||||
|
||||
# Mac files
|
||||
.DS_Store
|
||||
|
||||
# Yarn
|
||||
yarn-error.log
|
||||
.pnp/
|
||||
.pnp.js
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
21
docs/LICENSE
Normal file
21
docs/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 Rocketseat
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
71
docs/gatsby-config.js
Normal file
71
docs/gatsby-config.js
Normal file
|
@ -0,0 +1,71 @@
|
|||
const siteUrl = `https://golangci-lint.run`;
|
||||
|
||||
module.exports = {
|
||||
siteMetadata: {
|
||||
siteTitle: `golangci-lint`,
|
||||
defaultTitle: ``,
|
||||
siteTitleShort: `golangci-lint`,
|
||||
siteDescription: `Fast Go linters runner golangci-lint.`,
|
||||
siteUrl: siteUrl,
|
||||
siteAuthor: `@golangci`,
|
||||
siteImage: `/logo.png`,
|
||||
siteLanguage: `en`,
|
||||
themeColor: `#7159c1`,
|
||||
basePath: `/`,
|
||||
footer: `© ${new Date().getFullYear()}`,
|
||||
},
|
||||
plugins: [
|
||||
`gatsby-alias-imports`,
|
||||
{
|
||||
resolve: `@rocketseat/gatsby-theme-docs`,
|
||||
options: {
|
||||
configPath: `src/config`,
|
||||
docsPath: `src/docs`,
|
||||
githubUrl: `https://github.com/golangci/golangci-lint`,
|
||||
baseDir: `docs`,
|
||||
},
|
||||
},
|
||||
{
|
||||
resolve: `gatsby-plugin-manifest`,
|
||||
options: {
|
||||
name: `golangci-lint website`,
|
||||
short_name: `golangci-lint`,
|
||||
start_url: `/`,
|
||||
background_color: `#ffffff`,
|
||||
display: `standalone`,
|
||||
icon: `static/logo.png`,
|
||||
},
|
||||
},
|
||||
`gatsby-plugin-sitemap`,
|
||||
{
|
||||
resolve: `gatsby-plugin-google-analytics`,
|
||||
options: {
|
||||
trackingId: null, // TODO
|
||||
siteSpeedSampleRate: 100,
|
||||
},
|
||||
},
|
||||
{
|
||||
resolve: `gatsby-plugin-canonical-urls`,
|
||||
options: {
|
||||
siteUrl: siteUrl,
|
||||
},
|
||||
},
|
||||
`gatsby-plugin-offline`,
|
||||
{
|
||||
resolve: "gatsby-plugin-react-svg",
|
||||
options: {
|
||||
rule: {
|
||||
include: /logo\.svg$/,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
resolve: `gatsby-transformer-remark`,
|
||||
options: {
|
||||
plugins: [`gatsby-remark-external-links`],
|
||||
},
|
||||
},
|
||||
`gatsby-plugin-netlify`,
|
||||
`gatsby-plugin-netlify-cache`,
|
||||
],
|
||||
};
|
21815
docs/package-lock.json
generated
Normal file
21815
docs/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
40
docs/package.json
Normal file
40
docs/package.json
Normal file
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"name": "gatsby-starter-rocket-docs",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"description": "Out of the box Gatsby Starter for creating documentation websites easily and quickly. With support for MDX, code highlight, Analytics, SEO and more",
|
||||
"author": "João Pedro Schmitz <oi@joaopedro.cc> (@joaopedro_cc)",
|
||||
"license": "MIT",
|
||||
"starter-name": "gatsby-starter-rocket-docs",
|
||||
"dependencies": {
|
||||
"@rocketseat/gatsby-theme-docs": "^2.1.1",
|
||||
"gatsby": "^2.19.10",
|
||||
"gatsby-alias-imports": "^1.0.4",
|
||||
"gatsby-plugin-canonical-urls": "^2.1.19",
|
||||
"gatsby-plugin-google-analytics": "^2.1.34",
|
||||
"gatsby-plugin-manifest": "^2.2.37",
|
||||
"gatsby-plugin-netlify": "^2.3.2",
|
||||
"gatsby-plugin-netlify-cache": "^1.2.0",
|
||||
"gatsby-plugin-offline": "^3.0.32",
|
||||
"gatsby-plugin-react-svg": "^3.0.0",
|
||||
"gatsby-plugin-sitemap": "^2.2.26",
|
||||
"gatsby-remark-external-links": "0.0.4",
|
||||
"gatsby-transformer-remark": "^2.8.8",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-icons": "^3.10.0"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"keywords": [
|
||||
"gatsby",
|
||||
"rocketseat",
|
||||
"gatsby-starter"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "gatsby build",
|
||||
"start": "gatsby develop",
|
||||
"serve": "gatsby serve",
|
||||
"clean": "gatsby clean"
|
||||
}
|
||||
}
|
91
docs/src/@rocketseat/gatsby-theme-docs/components/Logo.js
Normal file
91
docs/src/@rocketseat/gatsby-theme-docs/components/Logo.js
Normal file
|
@ -0,0 +1,91 @@
|
|||
import React from "react";
|
||||
import { css, keyframes } from "@emotion/core";
|
||||
import GolangciSvg from "./logo.svg";
|
||||
|
||||
const grow = keyframes`
|
||||
0% {
|
||||
transform: scale(0.25);
|
||||
}
|
||||
|
||||
35% {
|
||||
transform: scale(1.0);
|
||||
}
|
||||
|
||||
70% {
|
||||
transform: scale(0.85);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
const moveInDown = keyframes`
|
||||
0% {
|
||||
transform: translate3d(0, -300px, 0);
|
||||
}
|
||||
|
||||
60% {
|
||||
transform: translate3d(0, 13px, 0);
|
||||
}
|
||||
|
||||
80% {
|
||||
transform: translate3d(0, -9px, 0);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translate3d(0, 0, 0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const moveInRightShield = keyframes`
|
||||
0% {
|
||||
transform: translate3d(-100px, 46px, 0);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translate3d(48px, 46px, 0);
|
||||
}
|
||||
|
||||
80% {
|
||||
transform: translate3d(0px, 46px, 0);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translate3d(12px, 46px, 0);
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
const centerAndFade = css`
|
||||
opacity: 0;
|
||||
transform-origin: 50%;
|
||||
`;
|
||||
|
||||
const svgCss = css`
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
padding: 0.5em;
|
||||
&:hover {
|
||||
#logo__go__circle {
|
||||
animation: ${grow} 0.5s ease-out forwards;
|
||||
${centerAndFade};
|
||||
}
|
||||
#logo__go__body {
|
||||
animation: ${moveInDown} 1s ease-out forwards;
|
||||
${centerAndFade};
|
||||
}
|
||||
#logo__go__shield {
|
||||
animation: ${moveInRightShield} 1s ease-out forwards;
|
||||
${centerAndFade};
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const Logo = () => (
|
||||
<GolangciSvg x={0} height="80%" viewBox="0 0 100 100" css={svgCss} />
|
||||
);
|
||||
export default Logo;
|
62
docs/src/@rocketseat/gatsby-theme-docs/components/logo.svg
Normal file
62
docs/src/@rocketseat/gatsby-theme-docs/components/logo.svg
Normal file
|
@ -0,0 +1,62 @@
|
|||
|
||||
<svg width="100px" height="100px" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 48.2 (47327) - http://www.bohemiancoding.com/sketch -->
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<circle id="path-1" cx="50" cy="50" r="50"></circle>
|
||||
<linearGradient x1="48.6208546%" y1="50%" x2="51.1360013%" y2="50%" id="linearGradient-3">
|
||||
<stop stop-color="#97EBF6" offset="0%"></stop>
|
||||
<stop stop-color="#59C1CE" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="go">
|
||||
<g id="logo__go__circle" fill="#17AFC2" fill-rule="nonzero">
|
||||
<circle id="a" cx="50" cy="50" r="50"></circle>
|
||||
</g>
|
||||
<g id="logo__go__body">
|
||||
<mask id="mask-2" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<g id="a"></g>
|
||||
<g id="Group" mask="url(#mask-2)">
|
||||
<g transform="translate(16.000000, 20.000000)">
|
||||
<path d="M0.818,50.893 C0.953,53.683 3.728,52.391 4.988,51.52 C6.181,50.692 6.53,51.38 6.635,49.747 C6.703,48.673 6.827,47.6 6.765,46.522 C4.961,46.358 2.997,46.789 1.517,47.868 C0.755,48.424 -0.675,50.198 0.817,50.893" id="Shape" stroke="#178391" stroke-width="1.5" fill="#97EBF5" fill-rule="nonzero"></path>
|
||||
<path d="M0.818,50.893 C1.056,50.759 2.086,50.217 2.248,49.893" id="Shape" stroke="#178391" stroke-width="1" fill="#C6B198" fill-rule="nonzero"></path>
|
||||
<path d="M7.235,17.676 C-3.405,14.676 4.505,1.096 13.051,6.681 L7.236,17.677 L7.235,17.676 Z M54.51,5.662 C62.933,-0.272 70.544,13.117 60.756,16.485 L54.51,5.662 Z" id="Shape" stroke="#178391" stroke-width="1.5" fill="#97EBF5" fill-rule="nonzero"></path>
|
||||
<path d="M7.68,13.926 C6.275,13.181 5.245,12.169 6.104,10.541 C6.899,9.034 8.376,9.197 9.78,9.941 L7.68,13.927 L7.68,13.926 Z M59.538,12.51 C60.942,11.765 61.972,10.753 61.113,9.124 C60.318,7.616 58.841,7.78 57.437,8.524 L59.537,12.51 L59.538,12.51 Z" id="Shape" stroke="none" fill="#178391" fill-rule="nonzero"></path>
|
||||
<path d="M68.2,50.54 C68.067,53.328 65.29,52.037 64.032,51.166 C62.838,50.338 62.489,51.026 62.384,49.393 C62.316,48.319 62.192,47.246 62.254,46.168 C64.058,46.004 66.022,46.435 67.502,47.514 C68.264,48.07 69.694,49.844 68.202,50.539" id="Shape" stroke="#178391" stroke-width="1.5" fill="#97EBF5" fill-rule="nonzero"></path>
|
||||
<path d="M68.2,50.54 C67.797,50.388 66.524,49.904 66.25,49.538" id="Shape" stroke="#178391" stroke-width="1" fill="#C6B198" fill-rule="nonzero"></path>
|
||||
<path d="M63.011,47.897 C63.624,58.339 64.981,70.403 60.151,80.081 C55.071,90.263 42.376,92.824 31.916,92.449 C23.701,92.154 13.776,89.466 9.14,81.936 C3.7,73.102 6.274,59.968 6.67,50.138 C7.137,38.495 3.525,26.818 7.338,15.424 C11.294,3.604 21.962,0.934 33.443,0.024 C44.096,0.024 54.083,1.551 59.288,11.818 C63.96,23.325 62.298,35.734 63.011,47.897 Z" id="Shape" stroke="#178391" stroke-width="1.5" fill="#97EBF6" fill-rule="nonzero"></path>
|
||||
<path d="M35.324,16.367 C37.237,27.52 55.41,24.572 52.8,13.323 C50.46,3.236 34.688,6.028 35.324,16.367 Z M13.606,18.17 C16.086,27.88 31.582,25.395 30.998,15.655 C30.298,3.99 11.236,6.241 13.606,18.171 L13.606,18.17 Z M37.517,30.75 C37.525,32.2 37.845,33.83 37.572,35.37 C37.202,36.07 36.479,36.145 35.855,36.428 C34.992,36.292 34.265,35.723 33.92,34.914 C33.7,33.154 34.003,31.448 34.06,29.687 L37.517,30.751 L37.517,30.75 Z" id="Shape" stroke="#178391" stroke-width="1" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
<g id="Group" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="translate(15.580000, 13.684000)">
|
||||
<ellipse id="Oval" fill="#178391" fill-rule="nonzero" cx="2.704" cy="2.904" rx="2.617" ry="2.843"></ellipse>
|
||||
<ellipse id="Oval" fill="#FFFFFF" fill-rule="nonzero" cx="3.895" cy="3.546" rx="1" ry="1"></ellipse>
|
||||
</g>
|
||||
<g id="Group" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" transform="translate(37.560000, 12.976000)">
|
||||
<ellipse id="Oval" fill="#178391" fill-rule="nonzero" cx="2.748" cy="2.904" rx="2.573" ry="2.843"></ellipse>
|
||||
<ellipse id="Oval" fill="#FFFFFF" fill-rule="nonzero" cx="3.918" cy="3.546" rx="1" ry="1"></ellipse>
|
||||
</g>
|
||||
<path d="M30.038,30.593 C28.898,33.369 30.675,38.919 33.773,34.825 C33.551,33.065 33.856,31.36 33.911,29.598 L30.039,30.593 L30.038,30.593 Z" id="Shape" stroke="#178391" stroke-width="1" fill="#FFFFFF" fill-rule="nonzero"></path>
|
||||
<path d="M30.43,25.247 C28.3,25.429 26.56,27.967 27.668,29.975 C29.133,32.635 32.404,29.74 34.441,30.011 C36.786,30.061 38.707,32.499 40.591,30.453 C42.684,28.178 39.688,25.961 37.347,24.971 L30.43,25.248 L30.43,25.247 Z" id="Shape" stroke="#178391" stroke-width="1.2" fill="#97EBF5" fill-rule="nonzero"></path>
|
||||
<path d="M30.16,25.136 C30.004,21.438 37.033,20.976 37.863,24.071 C38.691,27.161 30.507,27.878 30.161,25.137 C29.886,22.947 30.161,25.137 30.161,25.137 L30.16,25.136 Z" id="Shape" stroke="none" fill="#168391" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="logo__go__shield" transform="translate(12.000000, 46.000000)" stroke="#036D7A">
|
||||
<path d="M29,3.7420034 L29,32.8111955 L14.4442385,45 L0,32.8111955 L0,3.73968608 C0.452286685,3.75887778 0.910586619,3.76869038 1.37394334,3.76869038 C7.17954221,3.76869038 12.1912918,2.22824223 14.5278808,1.18988708e-11 C16.8644697,2.22824223 21.8762193,3.76869038 27.6818182,3.76869038 C28.1261432,3.76869038 28.5658182,3.75966731 29,3.7420034 Z" id="Combined-Shape" fill="url(#linearGradient-3)" stroke-linecap="square"></path>
|
||||
<g id="bug" transform="translate(6.000000, 13.000000)">
|
||||
<polyline id="Line-4" stroke-linecap="square" transform="translate(2.769231, 14.153846) scale(-1, 1) translate(-2.769231, -14.153846) " points="1.38461538 12.3076923 3.34243128 13.483874 4.15384615 16"></polyline>
|
||||
<polyline id="Line-4" stroke-linecap="square" points="12.4615385 12.3076923 14.4193544 13.483874 15.2307692 16"></polyline>
|
||||
<polyline id="Line-2" stroke-linecap="square" points="13.8461538 8.61538462 16.3555308 8.61538462 18 11.0769231"></polyline>
|
||||
<ellipse id="Oval-2" cx="8.30769231" cy="8" rx="4.15384615" ry="8"></ellipse>
|
||||
<polyline id="Line-2" stroke-linecap="square" transform="translate(2.076923, 9.846154) scale(-1, 1) translate(-2.076923, -9.846154) " points="3.55271368e-15 8.61538462 2.50937698 8.61538462 4.15384615 11.0769231"></polyline>
|
||||
<polyline id="Line-3" stroke-linecap="square" points="12.4615385 3.69230769 15.4320542 2.9391728 16.6153846 1.23076923"></polyline>
|
||||
<polyline id="Line-3" stroke-linecap="square" transform="translate(2.076923, 2.461538) scale(-1, 1) translate(-2.076923, -2.461538) " points="0 3.69230769 2.97051577 2.9391728 4.15384615 1.23076923"></polyline>
|
||||
<path d="M6.04771997,1.23076923 C6.63033385,1.67380534 7.42794975,1.94692839 8.30769231,1.94692839 C9.18743487,1.94692839 9.98505076,1.67380534 10.5676646,1.23076923 C11.7076091,2.66247502 12.4615385,5.1458636 12.4615385,7.96967337 C12.4615385,12.4047003 10.6017982,16 8.30769231,16 C6.01358642,16 4.15384615,12.4047003 4.15384615,7.96967337 C4.15384615,5.1458636 4.90777549,2.66247502 6.04771997,1.23076923 Z" id="Combined-Shape"></path>
|
||||
<path d="M8.30769231,2.94505495 L8.30769231,15.5164835" id="Line-6" stroke-linecap="square"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After (image error) Size: 8 KiB |
34
docs/src/config/sidebar.yml
Normal file
34
docs/src/config/sidebar.yml
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Sidebar navigation
|
||||
|
||||
- label: "Introduction"
|
||||
link: "/"
|
||||
- label: Usage
|
||||
items:
|
||||
- label: "Install"
|
||||
link: "/usage/install/"
|
||||
- label: "Quick Start"
|
||||
link: "/usage/quick-start/"
|
||||
- label: "Integrations"
|
||||
link: "/usage/integrations/"
|
||||
- label: "Linters"
|
||||
link: "/usage/linters/"
|
||||
- label: "Configuration"
|
||||
link: "/usage/configuration/"
|
||||
- label: "False Positives"
|
||||
link: "/usage/false-positives/"
|
||||
- label: "FAQ"
|
||||
link: "/usage/faq/"
|
||||
- label: "Performance"
|
||||
link: "/usage/performance/"
|
||||
- label: "Debug"
|
||||
link: "/usage/debug/"
|
||||
- label: Product
|
||||
items:
|
||||
- label: "Roadmap"
|
||||
link: "/product/roadmap/"
|
||||
- label: "GitHub"
|
||||
link: "https://github.com/golangci/golangci-lint"
|
||||
- label: "Trusted By"
|
||||
link: "/product/trusted-by/"
|
||||
- label: "Comparison"
|
||||
link: "/product/comparison/"
|
43
docs/src/docs/index.mdx
Normal file
43
docs/src/docs/index.mdx
Normal file
|
@ -0,0 +1,43 @@
|
|||
---
|
||||
title: Introduction
|
||||
---
|
||||
|
||||
import { FaTwitter, FaSlack } from "react-icons/fa";
|
||||
import { IconContainer } from "lib/icons";
|
||||
|
||||

|
||||
[](/LICENSE)
|
||||
[](https://github.com/golangci/golangci-lint/releases/latest)
|
||||
[](https://hub.docker.com/r/golangci/golangci-lint)
|
||||
[](https://somsubhra.com/github-release-stats/?username=golangci&repository=golangci-lint)
|
||||
|
||||
`golangci-lint` is a linters aggregator.
|
||||
|
||||
Join our slack <IconContainer color="#1DA1F2"><FaSlack /></IconContainer> channel by [joining Gophers workspace](https://invite.slack.golangbridge.org/)
|
||||
and then [joining](https://gophers.slack.com/archives/CS0TBRKPC) channel [`#golangci-lint`](https://gophers.slack.com/archives/CS0TBRKPC).
|
||||
|
||||
Follow the news and releases on our twitter <IconContainer color="#1DA1F2"><FaTwitter /></IconContainer> [`@golangci`](https://twitter.com/golangci).
|
||||
|
||||
## Features
|
||||
|
||||
- ⚡ [Very fast](/usage/performance): runs linters in parallel, reuses Go build cache and caches analysis results.
|
||||
- ⚙️ Yaml-based [configuration](/usage/configuration).
|
||||
- 🖥 [integrations](/usage/integrations) with VS Code, GNU Emacs, Sublime Text.
|
||||
- 🥇 [48 linters](/usage/linters) included, no need to install them.
|
||||
- 📈 Minimum number of [false positives](/usage/false-positives) because of tuned default settings.
|
||||
- 🔥nice output with colors, source code lines and marked `identifiers`.
|
||||
|
||||
[Get started now!](/usage/install)
|
||||
|
||||
## Demo
|
||||
|
||||

|
||||
|
||||
Short 1.5 min video demo of analyzing [beego](https://github.com/astaxie/beego).
|
||||
[](https://asciinema.org/a/183662)
|
||||
|
||||
[Get started now!](/usage/install)
|
||||
|
||||
## License Scan
|
||||
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fgolangci%2Fgolangci-lint?ref=badge_large)
|
78
docs/src/docs/product/comparison.mdx
Normal file
78
docs/src/docs/product/comparison.mdx
Normal file
|
@ -0,0 +1,78 @@
|
|||
---
|
||||
title: Comparison
|
||||
---
|
||||
|
||||
## `golangci-lint` vs `gometalinter`
|
||||
|
||||
GolangCI-Lint was created to fix the following issues with `gometalinter`:
|
||||
|
||||
1. Slow work: `gometalinter` usually works for minutes in average projects.
|
||||
**GolangCI-Lint works [2-7x times faster](/usage/performance)** by reusing work.
|
||||
2. Huge memory consumption: parallel linters don't share the same program representation and can consume
|
||||
`n` times more memory (`n` - concurrency). GolangCI-Lint fixes it by sharing representation and **consumes 26% less memory**.
|
||||
3. Doesn't use real bounded concurrency: if you set it to `n` it can take up to `n*n` threads because of
|
||||
forced threads in specific linters. `gometalinter` can't do anything about it because it runs linters as
|
||||
black boxes in forked processes. In GolangCI-Lint we run all linters in one process and completely control
|
||||
them. Configured concurrency will be correctly bounded.
|
||||
This issue is important because you often want to set concurrency to the CPUs count minus one to
|
||||
ensure you **do not freeze your PC** and be able to work on it while analyzing code.
|
||||
4. Lack of nice output. We like how the `gcc` and `clang` compilers format their warnings: **using colors,
|
||||
printing warning lines and showing the position in line**.
|
||||
5. Too many issues. GolangCI-Lint cuts a lot of issues by using default exclude list of common false-positives.
|
||||
By default, it has enabled **smart issues processing**: merge multiple issues for one line, merge issues with the
|
||||
same text or from the same linter. All of these smart processors can be configured by the user.
|
||||
6. Integration into large codebases. A good way to start using linters in a large project is not to fix a plethora
|
||||
of existing issues, but to set up CI and **fix only issues in new commits**. You can use `revgrep` for it, but it's
|
||||
yet another utility to install and configure. With `golangci-lint` it's much easier: `revgrep` is already built into
|
||||
`golangci-lint` and you can use it with one option (`-n, --new` or `--new-from-rev`).
|
||||
7. Installation. With `gometalinter`, you need to run a linters installation step. It's easy to forget this step and
|
||||
end up with stale linters. It also complicates CI setup. GolangCI-Lint requires **no installation of linters**.
|
||||
8. **Yaml or toml config**. Gometalinter's JSON isn't convenient for config files.
|
||||
|
||||
## `golangci-lint` vs Running Linters Manually
|
||||
|
||||
1. It will be much slower because `golangci-lint` runs all linters in parallel and shares 50-80% of linters work.
|
||||
2. It will have less control and more false-positives: some linters can't be properly configured without hacks.
|
||||
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 concurrent linting as a default consuming all cores.
|
||||
Benchmark was run (and measured) automatically, see the code
|
||||
[here](https://github.com/golangci/golangci-lint/blob/master/test/bench/bench_test.go) (`BenchmarkWithGometalinter`).
|
||||
|
||||
We measure peak memory usage (RSS) by tracking of processes RSS every 5 ms.
|
||||
|
||||
### Comparison with gometalinter
|
||||
|
||||
We compare golangci-lint and gometalinter in default mode, but explicitly enable all linters because of small differences in the default configuration.
|
||||
|
||||
```bash
|
||||
$ golangci-lint run --no-config --issues-exit-code=0 --timeout=30m \
|
||||
--disable-all --enable=deadcode --enable=gocyclo --enable=golint --enable=varcheck \
|
||||
--enable=structcheck --enable=maligned --enable=errcheck --enable=dupl --enable=ineffassign \
|
||||
--enable=interfacer --enable=unconvert --enable=goconst --enable=gosec --enable=megacheck
|
||||
$ gometalinter --deadline=30m --vendor --cyclo-over=30 --dupl-threshold=150 \
|
||||
--exclude=<default golangci-lint excludes> --skip=testdata --skip=builtin \
|
||||
--disable-all --enable=deadcode --enable=gocyclo --enable=golint --enable=varcheck \
|
||||
--enable=structcheck --enable=maligned --enable=errcheck --enable=dupl --enable=ineffassign \
|
||||
--enable=interfacer --enable=unconvert --enable=goconst --enable=gosec --enable=megacheck
|
||||
./...
|
||||
```
|
||||
|
||||
| Repository | GolangCI Time | GolangCI Is Faster than Gometalinter | GolangCI Memory | GolangCI eats less memory than Gometalinter |
|
||||
| ------------------------------------ | ------------- | ------------------------------------ | --------------- | ------------------------------------------- |
|
||||
| gometalinter repo, 4 kLoC | 6s | **6.4x** | 0.7GB | 33% |
|
||||
| self-repo, 4 kLoC | 12s | **7.5x** | 1.2GB | 41% |
|
||||
| beego, 50 kLoC | 10s | **4.2x** | 1.4GB | 9% |
|
||||
| hugo, 70 kLoC | 15s | **6.1x** | 1.6GB | 44% |
|
||||
| consul, 127 kLoC | 58s | **4x** | 2.7GB | 41% |
|
||||
| terraform, 190 kLoC | 2m13s | **1.6x** | 4.8GB | 0% |
|
||||
| go-ethereum, 250 kLoC | 33s | **5x** | 3.6GB | 0% |
|
||||
| go source (`$GOROOT/src`), 1300 kLoC | 2m45s | **2x** | 4.7GB | 0% |
|
||||
|
||||
**On average golangci-lint is 4.6 times faster** than gometalinter. Maximum difference is in the
|
||||
self-repo: **7.5 times faster**, minimum difference is in terraform source code repo: 1.8 times faster.
|
||||
|
||||
On average golangci-lint consumes 26% less memory.
|
39
docs/src/docs/product/roadmap.mdx
Normal file
39
docs/src/docs/product/roadmap.mdx
Normal file
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
title: Roadmap
|
||||
---
|
||||
|
||||
## 💡 Feature Requests
|
||||
|
||||
Please file an issue to suggest new features. Vote on feature requests by adding a 👍. This helps maintainers prioritize what to work on.
|
||||
|
||||
[See Feature Requests](https://github.com/golangci/golangci-lint/issues?utf8=✓&q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc+label%3Aenhancement)
|
||||
|
||||
## 🐛 Bugs
|
||||
|
||||
Please file an issue for bugs, missing documentation, or unexpected behavior.
|
||||
|
||||
[See Bugs](https://github.com/golangci/golangci-lint/issues?utf8=✓&q=is%3Aissue+is%3Aopen+label%3A%22bug%22+sort%3Acreated-desc)
|
||||
|
||||
## Thanks
|
||||
|
||||
Thanks to all [contributors](https://github.com/golangci/golangci-lint/graphs/contributors)!
|
||||
Thanks to [alecthomas/gometalinter](https://github.com/alecthomas/gometalinter) for inspiration and amazing work.
|
||||
Thanks to [bradleyfalzon/revgrep](https://github.com/bradleyfalzon/revgrep) for cool diff tool.
|
||||
|
||||
Thanks to developers and authors of used linters:
|
||||
{.ThanksList}
|
||||
|
||||
## Changelog
|
||||
|
||||
{.ChangeLog}
|
||||
|
||||
## Future Plans
|
||||
|
||||
1. Upstream all changes of forked linters.
|
||||
2. Make it easy to write own linter/checker: it should take a minimum code, have perfect documentation, debugging and testing tooling.
|
||||
3. Speed up SSA loading: on-disk cache and existing code profiling-optimizing.
|
||||
4. Analyze (don't only filter) only new code: analyze only changed files and dependencies, make incremental analysis, caches.
|
||||
5. Smart new issues detector: don't print existing issues on changed lines.
|
||||
6. Minimize false-positives by fixing linters and improving testing tooling.
|
||||
7. Automatic issues fixing (code rewrite, refactoring) where it's possible.
|
||||
8. Documentation for every issue type.
|
27
docs/src/docs/product/trusted-by.mdx
Normal file
27
docs/src/docs/product/trusted-by.mdx
Normal file
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
title: Trusted By
|
||||
---
|
||||
|
||||
The following companies/products use `golangci-lint`:
|
||||
|
||||
- [AWS](https://github.com/aws/aws-xray-sdk-go)
|
||||
- [Facebook](https://github.com/facebookincubator/fbender)
|
||||
- [Google](https://github.com/GoogleContainerTools/skaffold)
|
||||
- [Netflix](https://github.com/Netflix/titus-executor)
|
||||
- [Arduino](https://github.com/arduino/arduino-cli)
|
||||
- [Baidu](https://github.com/baidu/bfe)
|
||||
- [Eclipse Foundation](https://github.com/eclipse/che-go-jsonrpc)
|
||||
- [IBM](https://github.com/ibm-developer/ibm-cloud-env-golang)
|
||||
- [Istio](https://github.com/istio/istio)
|
||||
- [Percona](https://github.com/percona/pmm-managed)
|
||||
- [Red Hat OpenShift](https://github.com/openshift/telemeter)
|
||||
- [Samsung](https://github.com/samsung-cnct/cluster-api-provider-ssh)
|
||||
- [Serverless](https://github.com/serverless/event-gateway)
|
||||
- [ScyllaDB](https://github.com/scylladb/gocqlx)
|
||||
- [SoundCloud](https://github.com/soundcloud/periskop)
|
||||
- [The New York Times](https://github.com/NYTimes/encoding-wrapper)
|
||||
- [WooCart](https://github.com/woocart/gsutil)
|
||||
- [Xiaomi](https://github.com/XiaoMi/soar)
|
||||
- [Yahoo](https://github.com/yahoo/yfuzz)
|
||||
|
||||
And thousands of other great companies use `golangci-lint` too.
|
48
docs/src/docs/usage/configuration.mdx
Normal file
48
docs/src/docs/usage/configuration.mdx
Normal file
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
title: Configuration
|
||||
---
|
||||
|
||||
The config file has lower priority than command-line options. If the same bool/string/int option is provided on the command-line
|
||||
and in the config file, the option from command-line will be used.
|
||||
Slice options (e.g. list of enabled/disabled linters) are combined from the command-line and config file.
|
||||
|
||||
To see a list of enabled by your configuration linters:
|
||||
|
||||
```bash
|
||||
golangci-lint linters
|
||||
```
|
||||
|
||||
## Command-Line Options
|
||||
|
||||
```bash
|
||||
golangci-lint run -h
|
||||
{.RunHelpText}
|
||||
```
|
||||
|
||||
## Config File
|
||||
|
||||
GolangCI-Lint looks for config files in the following paths from the current working directory:
|
||||
|
||||
- `.golangci.yml`
|
||||
- `.golangci.toml`
|
||||
- `.golangci.json`
|
||||
|
||||
GolangCI-Lint also searches for config files in all directories from the directory of the first analyzed path up to the root.
|
||||
To see which config file is being used and where it was sourced from run golangci-lint with `-v` option.
|
||||
|
||||
Config options inside the file are identical to command-line options.
|
||||
You can configure specific linters' options only within the config file (not the command-line).
|
||||
|
||||
There is a [`.golangci.example.yml`](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml) example
|
||||
config file with all supported options, their description and default value:
|
||||
|
||||
```yaml
|
||||
{ .GolangciYamlExample }
|
||||
```
|
||||
|
||||
It's a [.golangci.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.yml) config file of this repo: we enable more linters
|
||||
than the default and have more strict settings:
|
||||
|
||||
```yaml
|
||||
{ .GolangciYaml }
|
||||
```
|
15
docs/src/docs/usage/debug.mdx
Normal file
15
docs/src/docs/usage/debug.mdx
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
title: Debugging
|
||||
---
|
||||
|
||||
You can see a verbose output of linter by using `-v` option.
|
||||
|
||||
If you would like to see more detailed logs you can set environment variable `GL_DEBUG` to debug `golangci-lint`.
|
||||
It's value is a list of debug tags. For example, `GL_DEBUG=loader,gocritic golangci-lint run`.
|
||||
Existing debug tags:
|
||||
|
||||
1. `gocritic` - debug `go-critic` linter;
|
||||
2. `env` - debug `go env` command;
|
||||
3. `loader` - debug packages loading (including `go/packages` internal debugging);
|
||||
4. `autogen_exclude` - debug a filter excluding autogenerated source code;
|
||||
5. `nolint` - debug a filter excluding issues by `//nolint` comments.
|
60
docs/src/docs/usage/false-positives.mdx
Normal file
60
docs/src/docs/usage/false-positives.mdx
Normal file
|
@ -0,0 +1,60 @@
|
|||
---
|
||||
title: False Positives
|
||||
---
|
||||
|
||||
False positives are inevitable, but we did our best to reduce their count. For example, we have a default enabled set of [exclude patterns](/usage/configuration#command-line-options). If a false positive occurred you have the following choices:
|
||||
|
||||
1. Exclude issue by text using command-line option `-e` or config option `issues.exclude`. It's helpful when you decided to ignore all issues of this type. Also, you can use `issues.exclude-rules` config option for per-path or per-linter configuration.
|
||||
2. Exclude this one issue by using special comment `//nolint` (see [the section](#nolint) below).
|
||||
3. Exclude issues in path by `run.skip-dirs`, `run.skip-files` or `issues.exclude-rules` config options.
|
||||
|
||||
Please create [GitHub Issues here](https://github.com/golangci/golangci-lint/issues/new) if you find any false positives. We will add it to the default exclude list if it's common or we will fix underlying linter.
|
||||
|
||||
## Nolint
|
||||
|
||||
To exclude issues from all linters use `//nolint`. For example, if it's used inline (not from the beginning of the line) it excludes issues only for this line.
|
||||
|
||||
```go
|
||||
var bad_name int //nolint
|
||||
```
|
||||
|
||||
To exclude issues from specific linters only:
|
||||
|
||||
```go
|
||||
var bad_name int //nolint:golint,unused
|
||||
```
|
||||
|
||||
To exclude issues for the block of code use this directive on the beginning of a line:
|
||||
|
||||
```go
|
||||
//nolint
|
||||
func allIssuesInThisFunctionAreExcluded() *string {
|
||||
// ...
|
||||
}
|
||||
|
||||
//nolint:govet
|
||||
var (
|
||||
a int
|
||||
b int
|
||||
)
|
||||
```
|
||||
|
||||
Also, you can exclude all issues in a file by:
|
||||
|
||||
```go
|
||||
//nolint:unparam
|
||||
package pkg
|
||||
```
|
||||
|
||||
You may add a comment explaining or justifying why `//nolint` is being used on the same line as the flag itself:
|
||||
|
||||
```go
|
||||
//nolint:gocyclo // This legacy function is complex but the team too busy to simplify it
|
||||
func someLegacyFunction() *string {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
You can see more examples of using `//nolint` in [our tests](https://github.com/golangci/golangci-lint/tree/master/pkg/result/processors/testdata) for it.
|
||||
|
||||
Use `//nolint` instead of `// nolint` because machine-readable comments should have no space by Go convention.
|
46
docs/src/docs/usage/faq.mdx
Normal file
46
docs/src/docs/usage/faq.mdx
Normal file
|
@ -0,0 +1,46 @@
|
|||
---
|
||||
title: FAQ
|
||||
---
|
||||
|
||||
## How do you add a custom linter?
|
||||
|
||||
You can integrate it yourself, see this [manual](/usage/linters#how-to-add-a-linter-to-golangci-lint-).
|
||||
Or you can create a [GitHub Issue](https://github.com/golangci/golangci-lint/issues/new) and we will integrate when time permits.
|
||||
|
||||
## It's cool to use `golangci-lint` when starting a project, but what about existing projects with large codebase? It will take days to fix all found issues
|
||||
|
||||
We are sure that every project can easily integrate `golangci-lint`, even the large one. The idea is to not fix all existing issues. Fix only newly added issue: issues in new code. To do this setup CI (or better use [GolangCI](https://golangci.com)) to run `golangci-lint` with option `--new-from-rev=HEAD~1`. Also, take a look at option `--new`, but consider that CI scripts that generate unstaged files will make `--new` only point out issues in those files and not in the last commit. In that regard `--new-from-rev=HEAD~1` is safer.
|
||||
By doing this you won't create new issues in your code and can choose fix existing issues (or not).
|
||||
|
||||
## How to use `golangci-lint` in CI (Continuous Integration)?
|
||||
|
||||
Run `golangci-lint` in CI and check the exit code. If it's non-zero - fail the build.
|
||||
|
||||
We don't recommend vendoring `golangci-lint` in your repo: you will get troubles updating `golangci-lint`. Please, use recommended way to install with the shell script: it's very fast.
|
||||
|
||||
## Do I need to run `go install`?
|
||||
|
||||
No, you don't need to do it anymore.
|
||||
|
||||
## Which go versions are supported
|
||||
|
||||
Short answer: Go 1.12 and newer are officially supported.
|
||||
|
||||
Long answer:
|
||||
|
||||
1. go < 1.9 isn't supported
|
||||
2. go1.9 is officially supported by golangci-lint <= v1.10.2
|
||||
3. go1.10 is officially supported by golangci-lint <= 1.15.0.
|
||||
4. go1.11 is officially supported by golangci-lint <= 1.17.1.
|
||||
5. go1.12+ are officially supported by the latest version of golangci-lint (>= 1.18.0).
|
||||
|
||||
## `golangci-lint` doesn't work
|
||||
|
||||
1. Please, ensure you are using the latest binary release.
|
||||
2. Run it with `-v` option and check the output.
|
||||
3. If it doesn't help create a [GitHub issue](https://github.com/golangci/golangci-lint/issues/new) with the output from the error and #2 above.
|
||||
|
||||
## Why running with `--fast` is slow on the first run?
|
||||
|
||||
Because the first run caches type information. All subsequent runs will be fast.
|
||||
Usually this options is used during development on local machine and compilation was already performed.
|
56
docs/src/docs/usage/install.mdx
Normal file
56
docs/src/docs/usage/install.mdx
Normal file
|
@ -0,0 +1,56 @@
|
|||
---
|
||||
title: "Install"
|
||||
---
|
||||
|
||||
## Binary
|
||||
|
||||
Most installations are done for CI (e.g. Travis CI, CircleCI). It's important to have reproducible CI:
|
||||
don't start to fail all builds at the same time. With golangci-lint this can happen if you
|
||||
use deprecated option `--enable-all` and a new linter is added or even without `--enable-all`: when one upstream linter is upgraded.
|
||||
|
||||
It's highly recommended to install a specific version of golangci-lint available on the [releases page](https://github.com/golangci/golangci-lint/releases).
|
||||
|
||||
Here is the recommended way to install golangci-lint {.LatestVersion}:
|
||||
|
||||
```bash
|
||||
# binary will be $(go env GOPATH)/bin/golangci-lint
|
||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin {.LatestVersion}
|
||||
|
||||
# or install it into ./bin/
|
||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s {.LatestVersion}
|
||||
|
||||
# In alpine linux (as it does not come with curl by default)
|
||||
wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s {.LatestVersion}
|
||||
|
||||
golangci-lint --version
|
||||
```
|
||||
|
||||
It is advised that you periodically update version of golangci-lint as the project is under active development
|
||||
and is constantly being improved. For any problems with golangci-lint, check out recent [GitHub issues](https://github.com/golangci/golangci-lint/issues) and update if needed.
|
||||
|
||||
## macOS
|
||||
|
||||
You can also install a binary release on macOS using [brew](https://brew.sh/):
|
||||
|
||||
```bash
|
||||
brew install golangci/tap/golangci-lint
|
||||
brew upgrade golangci/tap/golangci-lint
|
||||
```
|
||||
|
||||
## Docker
|
||||
|
||||
```bash
|
||||
docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:{.LatestVersion} golangci-lint run -v
|
||||
```
|
||||
|
||||
## Go
|
||||
|
||||
Go source installations are supported for the two most recent Go releases.
|
||||
|
||||
```bash
|
||||
go get github.com/golangci/golangci-lint/cmd/golangci-lint@{.LatestVersion}
|
||||
```
|
||||
|
||||
## Next
|
||||
|
||||
[Quick Start: how to use `golangci-lint`](/usage/quick-start).
|
60
docs/src/docs/usage/integrations.mdx
Normal file
60
docs/src/docs/usage/integrations.mdx
Normal file
|
@ -0,0 +1,60 @@
|
|||
---
|
||||
title: Integrations
|
||||
---
|
||||
|
||||
## Editor Integration
|
||||
|
||||
1. [Go for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=ms-vscode.Go).
|
||||
Recommended settings for VS Code are:
|
||||
|
||||
```json
|
||||
"go.lintTool":"golangci-lint",
|
||||
"go.lintFlags": [
|
||||
"--fast"
|
||||
]
|
||||
```
|
||||
|
||||
Using it in an editor without `--fast` can freeze your editor.
|
||||
Golangci-lint automatically discovers `.golangci.yml` config for edited file: you don't need to configure it in VS Code settings.
|
||||
|
||||
2. Sublime Text - [plugin](https://github.com/alecthomas/SublimeLinter-contrib-golang-cilint) for SublimeLinter.
|
||||
3. GoLand
|
||||
- Add [File Watcher](https://www.jetbrains.com/help/go/settings-tools-file-watchers.html) using existing `golangci-lint` template.
|
||||
- If your version of GoLand does not have the `golangci-lint` [File Watcher](https://www.jetbrains.com/help/go/settings-tools-file-watchers.html) template you can configure your own and use arguments `run --disable=typecheck $FileDir$`.
|
||||
4. GNU Emacs
|
||||
- [Spacemacs](https://github.com/syl20bnr/spacemacs/blob/develop/layers/+lang/go/README.org#pre-requisites)
|
||||
- [flycheck checker](https://github.com/weijiangan/flycheck-golangci-lint).
|
||||
5. Vim
|
||||
- [vim-go](https://github.com/fatih/vim-go)
|
||||
- syntastic [merged pull request](https://github.com/vim-syntastic/syntastic/pull/2190) with golangci-lint support
|
||||
- ale [merged pull request](https://github.com/w0rp/ale/pull/1890) with golangci-lint support
|
||||
6. Atom - [go-plus](https://atom.io/packages/go-plus) supports golangci-lint.
|
||||
|
||||
## Shell Completion
|
||||
|
||||
`golangci-lint` can generate bash completion file.
|
||||
|
||||
### macOS
|
||||
|
||||
There are two versions of `bash-completion`, v1 and v2. V1 is for Bash 3.2 (which is the default on macOS), and v2 is for Bash 4.1+. The `golangci-lint` completion script doesn’t work correctly with bash-completion v1 and Bash 3.2. It requires bash-completion v2 and Bash 4.1+. Thus, to be able to correctly use `golangci-lint` completion on macOS, you have to install and use Bash 4.1+ ([instructions](https://itnext.io/upgrading-bash-on-macos-7138bd1066ba)). The following instructions assume that you use Bash 4.1+ (that is, any Bash version of 4.1 or newer).
|
||||
|
||||
Install `bash-completion v2`:
|
||||
|
||||
```bash
|
||||
brew install bash-completion@2
|
||||
echo 'export BASH_COMPLETION_COMPAT_DIR="/usr/local/etc/bash_completion.d"' >>~/.bashrc
|
||||
echo '[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"' >>~/.bashrc
|
||||
exec bash # reload and replace (if it was updated) shell
|
||||
type _init_completion && echo "completion is OK" # verify that bash-completion v2 is correctly installed
|
||||
```
|
||||
|
||||
Add `golangci-lint` bash completion:
|
||||
|
||||
```bash
|
||||
echo 'source <(golangci-lint completion bash)' >>~/.bashrc
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
### Linux
|
||||
|
||||
See [kubectl instructions](https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion) and don't forget to replace `kubectl` with `golangci-lint`.
|
81
docs/src/docs/usage/linters.mdx
Normal file
81
docs/src/docs/usage/linters.mdx
Normal file
|
@ -0,0 +1,81 @@
|
|||
---
|
||||
title: Linters
|
||||
---
|
||||
|
||||
To see a list of supported linters and which linters are enabled/disabled:
|
||||
|
||||
```bash
|
||||
golangci-lint help linters
|
||||
```
|
||||
|
||||
## Enabled By Default Linters
|
||||
|
||||
{.EnabledByDefaultLinters}
|
||||
|
||||
## Disabled By Default Linters (`-E/--enable`)
|
||||
|
||||
{.DisabledByDefaultLinters}
|
||||
|
||||
## How to add a linter to `golangci-lint`
|
||||
|
||||
You need to implement a new linter using `go/analysis` API. After that:
|
||||
|
||||
1. Implement functional tests for the linter: add one file into directory [`test/testdata`](https://github.com/golangci/golangci-lint/tree/master/test/testdata). Run `T=yourlintername.go make test_linters` to ensure that test fails.
|
||||
2. Add a new file `pkg/golinters/{yourlintername}.go`. Look at other linters in this directory. Implement linter integration and check that test passes.
|
||||
3. Add the new struct for the linter (which you've implemented in `pkg/golinters/{yourlintername}.go`) to the list of all supported linters in [`pkg/lint/lintersdb/lintersdb.go`](https://github.com/golangci/golangci-lint/blob/master/pkg/lint/lintersdb/lintersdb.go) to the function `GetAllSupportedLinterConfigs`. Enable it by default only if you are sure.
|
||||
4. Find out what options do you need to configure for the linter. For example, `govet` has only 1 option: [`check-shadowing`](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml#L20). Choose default values to not being annoying for users of golangci-lint. Add configuration options to:
|
||||
|
||||
- [.golangci.example.yml](.golangci.example.yml) - the example of a configuration file. You can also add them to [.golangci.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.yml) if you think that this project needs not default values.
|
||||
- [config struct](https://github.com/golangci/golangci-lint/blob/master/pkg/config/config.go#L61) - don't forget about `mapstructure` tag for proper configuration files parsing by [pflag](https://github.com/spf13/pflag).
|
||||
|
||||
5. Take a look at the example of [Pull Request with new linter support](https://github.com/golangci/golangci-lint/pull/135).
|
||||
|
||||
## How to add a private linter
|
||||
|
||||
Some people and organizations may choose to have custom made linters run as a part of `golangci-lint`.
|
||||
Typically, these linters can't be open-sourced or too specific.
|
||||
Such linters can be added through Go's plugin library.
|
||||
|
||||
### Configure a Plugin
|
||||
|
||||
If you already have a linter plugin available, you can follow these steps to define it's usage in a projects
|
||||
`.golangci.yml` file. An example linter can be found at [here](https://github.com/golangci/example-plugin-linter). If you're looking for
|
||||
instructions on how to configure your own custom linter, they can be found further down.
|
||||
|
||||
1. If the project you want to lint does not have one already, copy the [.golangci.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.yml) to the root directory.
|
||||
2. Adjust the yaml to appropriate `linters-settings:custom` entries as so:
|
||||
|
||||
```yaml
|
||||
linters-settings:
|
||||
custom:
|
||||
example:
|
||||
path: /example.so
|
||||
description: The description of the linter
|
||||
original-url: github.com/golangci/example-linter
|
||||
```
|
||||
|
||||
That is all the configuration that is required to run a custom linter in your project. Custom linters are enabled by default,
|
||||
but abide by the same rules as other linters. If the disable all option is specified either on command line or in
|
||||
`.golangci.yml` files `linters:disable-all: true`, custom linters will be disabled; they can be re-enabled by adding them
|
||||
to the `linters:enable` list, or providing the enabled option on the command line, `golangci-lint run -Eexample`.
|
||||
|
||||
### Create a Plugin
|
||||
|
||||
Your linter must implement one or more `golang.org/x/tools/go/analysis.Analyzer` structs.
|
||||
Your project should also use `go.mod`. All versions of libraries that overlap `golangci-lint` (including replaced
|
||||
libraries) MUST be set to the same version as `golangci-lint`. You can see the versions by running `go version -m golangci-lint`.
|
||||
|
||||
You'll also need to create a go file like `plugin/example.go`. This MUST be in the package `main`, and define a
|
||||
variable of name `AnalyzerPlugin`. The `AnalyzerPlugin` instance MUST implement the following interface:
|
||||
|
||||
```go
|
||||
type AnalyzerPlugin interface {
|
||||
GetAnalyzers() []*analysis.Analyzer
|
||||
}
|
||||
```
|
||||
|
||||
The type of `AnalyzerPlugin` is not important, but is by convention `type analyzerPlugin struct {}`. See
|
||||
[plugin/example.go](https://github.com/golangci/example-plugin-linter/plugin/example.go) for more info.
|
||||
|
||||
To build the plugin, from the root project directory, run `go build -buildmode=plugin plugin/example.go`. This will create a plugin `*.so`
|
||||
file that can be copied into your project or another well known location for usage in golangci-lint.
|
56
docs/src/docs/usage/performance.mdx
Normal file
56
docs/src/docs/usage/performance.mdx
Normal file
|
@ -0,0 +1,56 @@
|
|||
---
|
||||
title: Performance
|
||||
---
|
||||
|
||||
## Memory Usage
|
||||
|
||||
A trade-off between memory usage and execution time can be controlled by [`GOGC`](https://golang.org/pkg/runtime/#hdr-Environment_Variables) environment variable.
|
||||
Less `GOGC` values trigger garbage collection more frequently and golangci-lint consumes less memory and more CPU. Below is the trade-off table for running on this repo:
|
||||
|
||||
| `GOGC` | Peak Memory, GB | Executon Time, s |
|
||||
| --------------- | --------------- | ---------------- |
|
||||
| `5` | 1.1 | 60 |
|
||||
| `10` | 1.1 | 34 |
|
||||
| `20` | 1.3 | 25 |
|
||||
| `30` | 1.6 | 20.2 |
|
||||
| `50` | 2.0 | 17.1 |
|
||||
| `80` | 2.2 | 14.1 |
|
||||
| `100` (default) | 2.2 | 13.8 |
|
||||
| `off` | 3.2 | 9.3 |
|
||||
|
||||
## Why `golangci-lint` is so fast
|
||||
|
||||
1. Work sharing
|
||||
The key difference with gometalinter is that golangci-lint shares work between specific linters (golint, govet, ...).
|
||||
We don't fork to call specific linter but use its API.
|
||||
For small and medium projects 50-90% of work between linters can be reused.
|
||||
|
||||
- load `[]*packages.Package` by `go/packages` once
|
||||
|
||||
We load program (parsing all files and type-checking) only once for all linters. For the most of linters
|
||||
it's the most heavy operation: it takes 5 seconds on 8 kLoC repo and 11 seconds on `$GOROOT/src`.
|
||||
|
||||
- build `ssa.Program` once
|
||||
|
||||
Some linters (megacheck, interfacer, unparam) work on SSA representation.
|
||||
Building of this representation takes 1.5 seconds on 8 kLoC repo and 6 seconds on `$GOROOT/src`.
|
||||
|
||||
- parse source code and build AST once
|
||||
|
||||
Parsing one source file takes 200 us on average. Parsing of all files in `$GOROOT/src` takes 2 seconds.
|
||||
Currently we parse each file more than once because it's not the bottleneck. But we already save a lot of
|
||||
extra parsing. We're planning to parse each file only once.
|
||||
|
||||
- walk files and directories once
|
||||
|
||||
It takes 300-1000 ms for `$GOROOT/src`.
|
||||
|
||||
2. Smart linters scheduling
|
||||
|
||||
We schedule linters by a special algorithm which takes estimated execution time into account. It allows
|
||||
to save 10-30% of time when one of heavy linters (megacheck etc) is enabled.
|
||||
|
||||
3. Don't fork to run shell commands
|
||||
|
||||
All linters has their version fixed with go modules, they are builtin
|
||||
and you don't need to install them separately.
|
44
docs/src/docs/usage/quick-start.mdx
Normal file
44
docs/src/docs/usage/quick-start.mdx
Normal file
|
@ -0,0 +1,44 @@
|
|||
---
|
||||
title: Quick Start
|
||||
---
|
||||
|
||||
To run golangci-lint execute:
|
||||
|
||||
```bash
|
||||
golangci-lint run
|
||||
```
|
||||
|
||||
It's an equivalent of executing:
|
||||
|
||||
```bash
|
||||
golangci-lint run ./...
|
||||
```
|
||||
|
||||
You can choose which directories and files to analyze:
|
||||
|
||||
```bash
|
||||
golangci-lint run dir1 dir2/... dir3/file1.go
|
||||
```
|
||||
|
||||
Directories are NOT analyzed recursively. To analyze them recursively append `/...` to their path.
|
||||
|
||||
GolangCI-Lint can be used with zero configuration. By default the following linters are enabled:
|
||||
|
||||
```bash
|
||||
$ golangci-lint help linters
|
||||
{.LintersCommandOutputEnabledOnly}
|
||||
```
|
||||
|
||||
and the following linters are disabled by default:
|
||||
|
||||
```bash
|
||||
$ golangci-lint help linters
|
||||
...
|
||||
{.LintersCommandOutputDisabledOnly}
|
||||
```
|
||||
|
||||
Pass `-E/--enable` to enable linter and `-D/--disable` to disable:
|
||||
|
||||
```bash
|
||||
golangci-lint run --disable-all -E errcheck
|
||||
```
|
16
docs/src/lib/icons.js
Normal file
16
docs/src/lib/icons.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
/** @jsx jsx */
|
||||
import { css, jsx } from "@emotion/core";
|
||||
|
||||
export const IconContainer = ({ color, children }) => (
|
||||
<span
|
||||
css={css`
|
||||
svg {
|
||||
color: ${color};
|
||||
text-align: center;
|
||||
vertical-align: -0.125em;
|
||||
}
|
||||
`}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
);
|
18
docs/src/pages/404.js
Normal file
18
docs/src/pages/404.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
import React from "react";
|
||||
import { Link } from "gatsby";
|
||||
|
||||
import Layout from "@rocketseat/gatsby-theme-docs/src/components/Layout";
|
||||
import SEO from "@rocketseat/gatsby-theme-docs/src/components/SEO";
|
||||
|
||||
export default function NotFound() {
|
||||
return (
|
||||
<Layout title="Page not found!">
|
||||
<SEO title="404: Not found" />
|
||||
<p>You just hit a route that doesn't exist... the sadness.</p>
|
||||
<p>
|
||||
If you'd like to go back to homepage, <Link to="/">click here</Link>
|
||||
.
|
||||
</p>
|
||||
</Layout>
|
||||
);
|
||||
}
|
BIN
docs/static/banner.png
vendored
Normal file
BIN
docs/static/banner.png
vendored
Normal file
Binary file not shown.
After ![]() (image error) Size: 38 KiB |
0
assets/demo.svg → docs/static/demo.svg
vendored
0
assets/demo.svg → docs/static/demo.svg
vendored
Before (image error) Size: 178 KiB After (image error) Size: 178 KiB |
BIN
docs/static/logo-400.png
vendored
Normal file
BIN
docs/static/logo-400.png
vendored
Normal file
Binary file not shown.
After ![]() (image error) Size: 94 KiB |
BIN
docs/static/logo.png
vendored
Normal file
BIN
docs/static/logo.png
vendored
Normal file
Binary file not shown.
After ![]() (image error) Size: 167 KiB |
2
docs/template_data.state
Executable file
2
docs/template_data.state
Executable file
|
@ -0,0 +1,2 @@
|
|||
This file stores hash of website templates to trigger Netlify rebuild when something changes, e.g. new linter is added.
|
||||
cdd4fe0f14771f7f1e196c11aa59a2c3fc61565beba07b81a9826692fcc822ae
|
|
@ -2,44 +2,125 @@ package main
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/golangci/golangci-lint/internal/renameio"
|
||||
|
||||
"github.com/golangci/golangci-lint/pkg/lint/linter"
|
||||
"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
|
||||
)
|
||||
|
||||
func main() {
|
||||
const (
|
||||
tmplPath = "README.tmpl.md"
|
||||
outPath = "README.md"
|
||||
)
|
||||
var stateFilePath = filepath.Join("docs", "template_data.state")
|
||||
|
||||
if err := genReadme(tmplPath, outPath); err != nil {
|
||||
log.Fatalf("failed: %s", err)
|
||||
func main() {
|
||||
var onlyWriteState bool
|
||||
flag.BoolVar(&onlyWriteState, "only-state", false, fmt.Sprintf("Only write hash of state to %s and exit", stateFilePath))
|
||||
flag.Parse()
|
||||
|
||||
replacements, err := buildTemplateContext()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to build template context: %s", err)
|
||||
}
|
||||
log.Printf("Successfully generated %s", outPath)
|
||||
|
||||
if err = updateStateFile(replacements); err != nil {
|
||||
log.Fatalf("Failed to update state file: %s", err)
|
||||
}
|
||||
|
||||
if onlyWriteState {
|
||||
return
|
||||
}
|
||||
|
||||
if err := rewriteDocs(replacements); err != nil {
|
||||
log.Fatalf("Failed to rewrite docs: %s", err)
|
||||
}
|
||||
log.Printf("Successfully expanded templates")
|
||||
}
|
||||
|
||||
func genReadme(tmplPath, outPath string) error {
|
||||
ctx, err := buildTemplateContext()
|
||||
func updateStateFile(replacements map[string]string) error {
|
||||
replBytes, err := json.Marshal(replacements)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to json marshal replacements: %w", err)
|
||||
}
|
||||
|
||||
out, err := os.Create(outPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
h := sha256.New()
|
||||
h.Write(replBytes) //nolint:errcheck
|
||||
|
||||
tmpl := template.Must(template.ParseFiles(tmplPath))
|
||||
return tmpl.Execute(out, ctx)
|
||||
var contentBuf bytes.Buffer
|
||||
contentBuf.WriteString("This file stores hash of website templates to trigger " +
|
||||
"Netlify rebuild when something changes, e.g. new linter is added.\n")
|
||||
contentBuf.WriteString(hex.EncodeToString(h.Sum(nil)))
|
||||
|
||||
return renameio.WriteFile(stateFilePath, contentBuf.Bytes(), os.ModePerm)
|
||||
}
|
||||
|
||||
func rewriteDocs(replacements map[string]string) error {
|
||||
madeReplacements := map[string]bool{}
|
||||
err := filepath.Walk(filepath.Join("docs", "src", "docs"),
|
||||
func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
return processDoc(path, replacements, madeReplacements)
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to walk dir: %w", err)
|
||||
}
|
||||
|
||||
if len(madeReplacements) != len(replacements) {
|
||||
for key := range replacements {
|
||||
if !madeReplacements[key] {
|
||||
log.Printf("Replacement %q wasn't performed", key)
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("%d replacements weren't performed", len(replacements)-len(madeReplacements))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func processDoc(path string, replacements map[string]string, madeReplacements map[string]bool) error {
|
||||
contentBytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read %s: %w", path, err)
|
||||
}
|
||||
|
||||
content := string(contentBytes)
|
||||
hasReplacements := false
|
||||
for key, replacement := range replacements {
|
||||
nextContent := content
|
||||
nextContent = strings.ReplaceAll(nextContent, fmt.Sprintf("{.%s}", key), replacement)
|
||||
|
||||
// Yaml formatter in mdx code section makes extra spaces, need to match them too.
|
||||
nextContent = strings.ReplaceAll(nextContent, fmt.Sprintf("{ .%s }", key), replacement)
|
||||
|
||||
if nextContent != content {
|
||||
hasReplacements = true
|
||||
madeReplacements[key] = true
|
||||
content = nextContent
|
||||
}
|
||||
}
|
||||
if !hasReplacements {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("Expanded template in %s, saving it", path)
|
||||
if err = renameio.WriteFile(path, []byte(content), os.ModePerm); err != nil {
|
||||
return fmt.Errorf("failed to write changes to file %s: %w", path, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getLatestVersion() (string, error) {
|
||||
|
@ -56,7 +137,7 @@ func getLatestVersion() (string, error) {
|
|||
return string(lines[0]), nil
|
||||
}
|
||||
|
||||
func buildTemplateContext() (map[string]interface{}, error) {
|
||||
func buildTemplateContext() (map[string]string, error) {
|
||||
golangciYaml, err := ioutil.ReadFile(".golangci.yml")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't read .golangci.yml: %s", err)
|
||||
|
@ -98,7 +179,7 @@ func buildTemplateContext() (map[string]interface{}, error) {
|
|||
return nil, fmt.Errorf("failed to get latest version: %s", err)
|
||||
}
|
||||
|
||||
return map[string]interface{}{
|
||||
return map[string]string{
|
||||
"GolangciYaml": strings.TrimSpace(string(golangciYaml)),
|
||||
"GolangciYamlExample": strings.TrimSpace(string(golangciYamlExample)),
|
||||
"LintersCommandOutputEnabledOnly": string(lintersOutParts[0]),
|
Loading…
Add table
Add a link
Reference in a new issue