Skip to content

Commit 815d131

Browse files
committed
docs: add changelog, rewrite internal section, add trusted by section
1 parent 35f9d8e commit 815d131

File tree

3 files changed

+229
-61
lines changed

3 files changed

+229
-61
lines changed

README.md

Lines changed: 114 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# GolangCI-Lint
22
[![Build Status](https://travis-ci.com/golangci/golangci-lint.svg?branch=master)](https://travis-ci.com/golangci/golangci-lint)
33

4-
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.
4+
GolangCI-Lint is a linters aggregator. It's fast: on average [5 times faster](#performance) than gometalinter.
5+
It's [easy to integrate and use](#command-line-options), has [nice output](#quick-start) and has a minimum number of false positives.
56

67
GolangCI-Lint has [integrations](#editor-integration) with VS Code, GNU Emacs, Sublime Text.
78

@@ -15,13 +16,15 @@ Sponsored by [GolangCI.com](https://golangci.com): SaaS service for running lint
1516
* [Editor Integration](#editor-integration)
1617
* [Comparison](#comparison)
1718
* [Performance](#performance)
19+
* [Internals](#internals)
20+
* [Trusted By](#trusted-by)
1821
* [Supported Linters](#supported-linters)
1922
* [Configuration](#configuration)
2023
* [False Positives](#false-positives)
21-
* [Internals](#internals)
2224
* [FAQ](#faq)
2325
* [Thanks](#thanks)
2426
* [Future Plans](#future-plans)
27+
* [Changelog](#changelog)
2528
* [Contact Information](#contact-information)
2629

2730
# Demo
@@ -138,19 +141,34 @@ $ golangci-lint run --disable-all -E errcheck
138141
- Configure [File Watcher](https://www.jetbrains.com/help/go/settings-tools-file-watchers.html) with arguments `run --print-issued-lines=false $FileDir$`.
139142
- Predefined File Watcher will be added in [issue](https://youtrack.jetbrains.com/issue/GO-4574).
140143
4. GNU Emacs - [flycheck checker](https://github.com/weijiangan/flycheck-golangci-lint).
141-
5. Vim - [issue](https://github.com/fatih/vim-go/issues/1841) for vim-go.
144+
5. Vim
145+
- vim-go open [issue](https://github.com/fatih/vim-go/issues/1841)
146+
- syntastic [merged pull request](https://github.com/vim-syntastic/syntastic/pull/2190) with golangci-lint support
142147

143148
# Comparison
144149
## `golangci-lint` vs `gometalinter`
145150
GolangCI-Lint was created to fix the following issues with `gometalinter`:
146-
1. Slow work: `gometalinter` usually works for minutes in average projects. **GolangCI-Lint works [2-7x times faster](#performance)** by [reusing work](#internals).
147-
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 1.35x less memory**.
148-
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.
149-
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.
150-
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**.
151-
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.
152-
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`).
153-
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**.
151+
1. Slow work: `gometalinter` usually works for minutes in average projects.
152+
**GolangCI-Lint works [2-7x times faster](#performance)** by [reusing work](#internals).
153+
2. Huge memory consumption: parallel linters don't share the same program representation and can consume
154+
`n` times more memory (`n` - concurrency). GolangCI-Lint fixes it by sharing representation and **consumes 1.35x less memory**.
155+
3. Doesn't use real bounded concurrency: if you set it to `n` it can take up to `n*n` threads because of
156+
forced threads in specific linters. `gometalinter` can't do anything about it because it runs linters as
157+
black boxes in forked processes. In GolangCI-Lint we run all linters in one process and completely control
158+
them. Configured concurrency will be correctly bounded.
159+
This issue is important because you often want to set concurrency to the CPUs count minus one to
160+
ensure you **do not freeze your PC** and be able to work on it while analyzing code.
161+
4. Lack of nice output. We like how the `gcc` and `clang` compilers format their warnings: **using colors,
162+
printing warning lines and showing the position in line**.
163+
5. Too many issues. GolangCI-Lint cuts a lot of issues by using default exclude list of common false-positives.
164+
By default, it has enabled **smart issues processing**: merge multiple issues for one line, merge issues with the
165+
same text or from the same linter. All of these smart processors can be configured by the user.
166+
6. Integration into large codebases. A good way to start using linters in a large project is not to fix a plethora
167+
of existing issues, but to set up CI and **fix only issues in new commits**. You can use `revgrep` for it, but it's
168+
yet another utility to install and configure. With `golangci-lint` it's much easier: `revgrep` is already built into
169+
`golangci-lint` and you can use it with one option (`-n, --new` or `--new-from-rev`).
170+
7. Installation. With `gometalinter`, you need to run a linters installation step. It's easy to forget this step and
171+
end up with stale linters. It also complicates CI setup. GolangCI-Lint requires **no installation of linters**.
154172
8. **Yaml or toml config**. Gometalinter's JSON isn't convenient for config files.
155173

156174
## `golangci-lint` vs Running Linters Manually
@@ -190,14 +208,76 @@ $ gometalinter --deadline=30m --vendor --cyclo-over=30 --dupl-threshold=150 \
190208
| consul, 127 kLoC | 58s | **4x** | 2.7GB | 1.7x |
191209
| terraform, 190 kLoC | 2m13s | **1.6x** | 4.8GB | 1x |
192210
| go-ethereum, 250 kLoC | 33s | **5x** | 3.6GB | 1x |
193-
| go source, 1300 kLoC | 2m45s | **2x** | 4.7GB | 1x |
211+
| go source (`$GOROOT/src`), 1300 kLoC | 2m45s | **2x** | 4.7GB | 1x |
194212

195213

196214
**On average golangci-lint is 4.6 times faster** than gometalinter. Maximum difference is in the
197215
self-repo: **7.5 times faster**, minimum difference is in terraform source code repo: 1.8 times faster.
198216

199217
On average golangci-lint consumes 1.35 times less memory.
200218

219+
## Why golangci-lint is faster
220+
221+
Golangci-lint directly calls linters (no forking) and reuses 80% of work by parsing program only once.
222+
Read [this section](#internals) for details.
223+
224+
# Internals
225+
226+
1. Work sharing
227+
The key difference with gometalinter is that golangci-lint shares work between specific linters (golint, govet, ...).
228+
We don't fork to call specific linter but use its API.
229+
For small and medium projects 50-90% of work between linters can be reused.
230+
* load `loader.Program` once
231+
232+
We load program (parsing all files and type-checking) only once for all linters. For the most of linters
233+
it's the most heavy operation: it takes 5 seconds on 8 kLoC repo and 11 seconds on `$GOROOT/src`.
234+
* build `ssa.Program` once
235+
236+
Some linters (megacheck, interfacer, unparam) work on SSA representation.
237+
Building of this representation takes 1.5 seconds on 8 kLoC repo and 6 seconds on `$GOROOT/src`.
238+
`SSA` representation is used from a [fork of go-tools](https://github.com/dominikh/go-tools), not the official one.
239+
240+
* parse source code and build AST once
241+
242+
Parsing one source file takes 200 us on average. Parsing of all files in `$GOROOT/src` takes 2 seconds.
243+
Currently we parse each file more than once because it's not the bottleneck. But we already save a lot of
244+
extra parsing. We're planning to parse each file only once.
245+
246+
* walk files and directories once
247+
248+
It takes 300-1000 ms for `$GOROOT/src`.
249+
2. Smart linters scheduling
250+
251+
We schedule linters by a special algorithm which takes estimated execution time into account. It allows
252+
to save 10-30% of time when one of heavy linters (megacheck etc) is enabled.
253+
254+
3. Improved program loading
255+
256+
We smartly use setting `TypeCheckFuncBodies` in `loader.Config` to build `loader.Program`.
257+
If there are no linters requiring SSA enabled we can load dependencies of analyzed code much faster
258+
by not analyzing their functions: we analyze only file-level declarations. It makes program loading
259+
10-30% faster in such cases.
260+
4. Don't fork to run shell commands
261+
262+
All linters are vendored in the `/vendor` folder: their version is fixed, they are builtin
263+
and you don't need to install them separately.
264+
265+
# Trusted By
266+
267+
The following great projects use golangci-lint:
268+
269+
* [GoogleContainerTools/skaffold](https://github.com/GoogleContainerTools/skaffold/blob/master/hack/linter.sh#L24) - Easy and Repeatable Kubernetes Development
270+
* [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser/blob/master/Makefile#L47) - Deliver Go binaries as fast and easily as possible
271+
* [goreleaser/nfpm](https://github.com/goreleaser/nfpm/blob/master/Makefile#L43) - NFPM is Not FPM - a simple deb and rpm packager written in Go
272+
* [goreleaser/godownloader](https://github.com/goreleaser/godownloader/blob/master/Makefile#L37) - Download Go binaries as fast and easily as possible
273+
* [asobti/kube-monkey](https://github.com/asobti/kube-monkey/blob/master/Makefile#L12) - An implementation of Netflix's Chaos Monkey for Kubernetes clusters
274+
* [nutanix/terraform-provider-nutanix](https://github.com/nutanix/terraform-provider-nutanix/blob/develop/.golangci.yml) - Terraform Nutanix Provider
275+
* [getantibody/antibody](https://github.com/getantibody/antibody/blob/master/Makefile#L32) - The fastest shell plugin manager
276+
* [Aptomi/aptomi](https://github.com/Aptomi/aptomi/blob/master/.golangci.yml) - Application delivery engine for k8s
277+
* [status-im/status-go](https://github.com/status-im/status-go/blob/develop/.golangci.yml) - The Status module that consumes go-ethereum
278+
* [ovrclk/akash](https://github.com/ovrclk/akash/blob/master/.golangci.yaml) - Blockchain-powered decentralized compute platform
279+
280+
201281
# Supported Linters
202282
To see a list of supported linters and which linters are enabled/disabled:
203283
```
@@ -558,24 +638,6 @@ func f() {
558638

559639
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.
560640

561-
# Internals
562-
The key difference with gometalinter is that golangci-lint shares work between specific linters (golint, govet, ...).
563-
For small and medium projects 50-80% of work between linters can be reused.
564-
Now we share `loader.Program` and `SSA` representation building. `SSA` representation is used from
565-
a [fork of go-tools](https://github.com/dominikh/go-tools), not the official one. Also, we are going to
566-
reuse `AST` parsing and traversal.
567-
568-
We don't fork to call specific linter but use its API. We forked GitHub repos of almost all linters
569-
to make API. It also allows us to be more performant and control actual count of used threads.
570-
571-
All linters are vendored in the `/vendor` folder: their version is fixed, they are builtin
572-
and you don't need to install them separately.
573-
574-
We use chains for issues and independent processors to post-process them: exclude issues by limits,
575-
nolint comment, diff, regexps; prettify paths, etc.
576-
577-
We use `cobra` for command-line options.
578-
579641
# FAQ
580642
**How do you add a custom linter?**
581643

@@ -655,6 +717,28 @@ Thanks to developers and authors of used linters:
655717
9. Automatic issues fixing (code rewrite, refactoring) where it's possible.
656718
10. Documentation for every issue type.
657719

720+
# Changelog
721+
722+
There is the most valuable changes log:
723+
724+
## June 2018
725+
726+
1. Add support of the next linters:
727+
* unparam
728+
* misspell
729+
* nakedret
730+
* lll
731+
* depguard
732+
2. Smart generated files detector
733+
3. Full `//nolint` support
734+
4. Implement `--skip-files` and `--skip-dirs` options
735+
5. Checkstyle output format support
736+
737+
## May 2018
738+
739+
1. Support GitHub Releases
740+
2. Installation via Homebrew and Docker
741+
658742
# Contact Information
659743
You can contact the [author](https://github.com/jirfag) of GolangCI-Lint
660744
by [denis@golangci.com](mailto:denis@golangci.com).

0 commit comments

Comments
 (0)