Skip to content

Commit

Permalink
Add versions, improve deprecation system, improve linters page (#1854)
Browse files Browse the repository at this point in the history
  • Loading branch information
ldez committed Mar 17, 2021
1 parent b6a6faa commit 8db518c
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 39 deletions.
36 changes: 20 additions & 16 deletions docs/src/docs/contributing/new-linters.mdx
Expand Up @@ -9,31 +9,35 @@ from scratch and integrate it into `golangci-lint`.

## How to add a public linter to `golangci-lint`

You need to implement a new linter using `go/analysis` API. We don't accept not `go/analysis` linters.
You need to implement a new linter using `go/analysis` API.
We don't accept not `go/analysis` linters.

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.
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.
- Run `go run ./cmd/golangci-lint/ run --no-config --disable-all --enable=yourlintername ./test/testdata/yourlintername.go`
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/manager.go`](https://github.com/golangci/golangci-lint/blob/master/pkg/lint/lintersdb/manager.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, `nakedret` has
only 1 option: [`max-func-lines`](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml).
to the function `GetAllSupportedLinterConfigs`.
- Add `WithSince("next_version")`, where `next_version` must be replaced by the next minor version. (ex: v1.2.0 if the current version is v1.1.0)
4. Find out what options do you need to configure for the linter.
For example, `nakedret` has only 1 option: [`max-func-lines`](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml).
Choose default values to not being annoying for users of golangci-lint. Add configuration options to:

- [.golangci.example.yml](https://github.com/golangci/golangci-lint/blob/master/.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) - 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/850).
- [.golangci.example.yml](https://github.com/golangci/golangci-lint/blob/master/.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) -
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/pulls?q=is%3Apr+is%3Amerged+label%3A%22linter%3A+new%22).

## How to add a private linter to `golangci-lint`

Some people and organizations may choose to have custom made linters run as a part of `golangci-lint`.
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.

Expand Down
33 changes: 25 additions & 8 deletions pkg/lint/linter/config.go
Expand Up @@ -20,6 +20,12 @@ const (
PresetUnused = "unused" // Related to the detection of unused code.
)

type Deprecation struct {
Since string
Message string
Replacement string
}

type Config struct {
Linter Linter
EnabledByDefault bool
Expand All @@ -29,11 +35,13 @@ type Config struct {
InPresets []string
AlternativeNames []string

OriginalURL string // URL of original (not forked) repo, needed for autogenerated README
CanAutoFix bool
IsSlow bool
DoesChangeTypes bool
DeprecatedMessage string
OriginalURL string // URL of original (not forked) repo, needed for autogenerated README
CanAutoFix bool
IsSlow bool
DoesChangeTypes bool

Since string
Deprecation *Deprecation
}

func (lc *Config) ConsiderSlow() *Config {
Expand Down Expand Up @@ -82,13 +90,22 @@ func (lc *Config) WithChangeTypes() *Config {
return lc
}

func (lc *Config) Deprecated(message string) *Config {
lc.DeprecatedMessage = message
func (lc *Config) WithSince(version string) *Config {
lc.Since = version
return lc
}

func (lc *Config) Deprecated(message, version, replacement string) *Config {
lc.Deprecation = &Deprecation{
Since: version,
Message: message,
Replacement: replacement,
}
return lc
}

func (lc *Config) IsDeprecated() bool {
return lc.DeprecatedMessage != ""
return lc.Deprecation != nil
}

func (lc *Config) AllNames() []string {
Expand Down

0 comments on commit 8db518c

Please sign in to comment.