Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add gochecksumtype linter #3671

Merged
merged 6 commits into from
Oct 9, 2023
Merged

feat: add gochecksumtype linter #3671

merged 6 commits into from
Oct 9, 2023

Conversation

alecthomas
Copy link
Contributor

@alecthomas alecthomas commented Mar 12, 2023

gochecksumtype is a linter that checks that type switches on "sum types" in Go are exhaustive.

https://github.com/alecthomas/go-check-sumtype

This is based on BurntSushi/go-sumtype, but fixes, modernises and simplifies it.

fixes #402

@CLAassistant
Copy link

CLAassistant commented Mar 12, 2023

CLA assistant check
All committers have signed the CLA.

@ldez
Copy link
Member

ldez commented Mar 12, 2023

In order for a pull request adding a linter to be reviewed, the linter and the PR must follow some requirements.

Pull Request Description

  • It must have a link to the linter repository.
  • It must provide a short description of the linter.

Linter

  • It must not be a duplicate of another linter or a rule of a linter. (the team will help to verify that)
  • It must have a valid license (AGPL is not allowed) and the file must contain the required information by the license, ex: author, year, etc.
  • The linter repository must have a CI and tests.
  • It must use go/analysis.
  • It must have a valid tag, ex: v1.0.0, v0.1.0.
  • It must not contain init().
  • It must not contain panic(), log.fatal(), os.exit(), or similar.
  • It must not have false positives/negatives. (the team will help to verify that)
  • It must have tests inside golangci-lint.

The Linter Tests Inside Golangci-lint

  • They must have at least one std lib import.
  • They must work with T=<name of the linter test file>.go make test_linters. (the team will help to verify that)

.golangci.reference.yml

  • The linter must be added to the list of available linters (alphabetical case-insensitive order).
    • enable and disable options
  • If the linter has a configuration, the exhaustive configuration of the linter must be added (alphabetical case-insensitive order)
    • The values must be different from the default ones.
    • The default values must be defined in a comment.
    • The option must have a short description.

Others Requirements

  • The files (tests and linter) inside golangci-lint must have the same name as the linter.
  • The .golangci.yml of golangci-lint itself must not be edited and the linter must not be added to this file.
  • The linters must be sorted in the alphabetical order (case-insensitive) in the Manager.GetAllSupportedLinterConfigs(...) and .golangci.reference.yml.
  • The load mode (WithLoadMode(...)):
    • if the linter doesn't use types: goanalysis.LoadModeSyntax
    • goanalysis.LoadModeTypesInfo required WithLoadForGoAnalysis() in the Manager.GetAllSupportedLinterConfigs(...)
  • The version in WithSince(...) must be the next minor version (v1.X.0) of golangci-lint.

Recommendations

  • The linter should not use SSA. (currently, SSA does not support generics)
  • The linter repository should have a readme and linting.
  • The linter should be published as a binary. (useful to diagnose bug origins)

The golangci-lint team will edit this comment to check the boxes before and during the review.

If the author of the PR is a member of the golangci-lint team, he should not edit this message.

This checklist does not imply that we will accept the linter.

@ldez ldez added the linter: new Support new linter label Mar 12, 2023
@ldez
Copy link
Member

ldez commented Mar 12, 2023

Hello,

this linter seems really close to exhaustive maybe it can be an improvement of this lnter.
ping @nishanths

@ldez ldez added the feedback required Requires additional feedback label Mar 12, 2023
@alecthomas
Copy link
Contributor Author

As I mentioned, this is just a fork of an existing linter that has been around for quite some time. There was only a minimal amount of work required to bring it up to date.

FWIW I did look at exhaustive and while it is similar it does not have this functionality. Given the choice between simply updating go-sumtype, or reimplementing all of the logic in exhaustive, I chose the former. I can understand if that's not the right choice for golangci-lint, but I personally don't have the time to reimplement this existing functional lexer in an entirely new codebase. If that's the path forward you'd prefer, I'll close this PR.

@ldez
Copy link
Member

ldez commented Mar 12, 2023

I will wait for feedback from @nishanths before taking a decision.

@alecthomas
Copy link
Contributor Author

Ping!

@ldez
Copy link
Member

ldez commented Mar 25, 2023

still waiting for @nishanths feedback

@ldez ldez self-requested a review March 30, 2023 20:04
@ldez
Copy link
Member

ldez commented Apr 14, 2023

I think we have waited enough time, so we will accept your linter.

@alecthomas Can you take a look at the checklist? #3671 (comment)

@ldez
Copy link
Member

ldez commented Apr 16, 2023

Since I added one sts import in the test case, the test fails:

$ T=gochecksumtype.go make test_linters         
GL_TEST_RUN=1 go test -v ./test -count 1 -run TestSourcesFromTestdata/gochecksumtype.go
=== RUN   TestSourcesFromTestdata
    linters_test.go:21: testdata/*.go
=== RUN   TestSourcesFromTestdata/gochecksumtype.go
=== PAUSE TestSourcesFromTestdata/gochecksumtype.go
=== CONT  TestSourcesFromTestdata/gochecksumtype.go
level=info msg="[test] ran [/home/ldez/sources/go/src/github.com/golangci/golangci-lint/golangci-lint run --internal-cmd-test --no-config --allow-parallel-runners --disable-all --out-format=json --max-same-issues=100 -Egochecksumtype gochecksumtype.go] in 213.428115ms"
    analysis.go:66: gochecksumtype.go:26: no diagnostic was reported matching `exhaustiveness check failed for sum type.*SumType.*missing cases for Two`
level=info msg="[test] ran [/home/ldez/sources/go/src/github.com/golangci/golangci-lint/golangci-lint run --internal-cmd-test --no-config --allow-parallel-runners --disable-all --out-format=json --max-same-issues=100 -Etypecheck -Egochecksumtype gochecksumtype.go] in 240.006321ms"
    analysis.go:66: gochecksumtype.go:26: no diagnostic was reported matching `exhaustiveness check failed for sum type.*SumType.*missing cases for Two`
--- FAIL: TestSourcesFromTestdata (2.04s)
    --- FAIL: TestSourcesFromTestdata/gochecksumtype.go (0.45s)
=== RUN   TestSourcesFromTestdataSubDir
--- PASS: TestSourcesFromTestdataSubDir (0.00s)
FAIL
FAIL    github.com/golangci/golangci-lint/test  2.528s
FAIL
make: *** [Makefile:48: test_linters] Error 1

@ldez
Copy link
Member

ldez commented Apr 16, 2023

I move the logger and the test works, maybe there is something that I don't understand.

@gnuletik
Copy link
Contributor

gnuletik commented Jun 6, 2023

Hi ! Thanks for this PR ! I was looking for a similar feature! Is there anything blocking here?

@ldez
Copy link
Member

ldez commented Jun 6, 2023

If you can explain why this change produces a different behavior.

@gnuletik
Copy link
Contributor

gnuletik commented Jun 6, 2023

@ldez thanks for the fast feedback!

It seems that this behavior is intended by the linter's author.

https://github.com/alecthomas/go-check-sumtype/blob/803c965876eec8ffc4d0f26a65af8fa4d2520423/check.go#L64-L65

This behavior comes from upstream:

https://github.com/alecthomas/go-check-sumtype/blob/803c965876eec8ffc4d0f26a65af8fa4d2520423/check.go#L64-L65

NB: The comment is not exact because it seems that the linter only check if the default case is only containing a panic.

@ldez ldez removed the feedback required Requires additional feedback label Jun 6, 2023
@ldez ldez added the enhancement New feature or improvement label Jul 31, 2023
@golangci golangci deleted a comment from Antonboom Oct 1, 2023
alecthomas and others added 6 commits October 9, 2023 17:18
`gochecksumtype` is a linter that checks that type switches on "sum
types" in Go are exhaustive.

https://github.com/alecthomas/go-check-sumtype

This is based on BurntSushi/go-sumtype, but fixes, modernises and
simplifies it.
@ldez ldez merged commit 69d6cc9 into golangci:master Oct 9, 2023
11 checks passed
}

var unknownError error
errors := gochecksumtype.Run([]*packages.Package{pkg})
Copy link
Contributor

@maratori maratori Oct 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation doesn't allow declaring a sum type in package A and checking a type switch in package B. That's because each package is checked separately.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe to open separate issue?
I feel like this comment will get lost

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or improvement linter: new Support new linter
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add go-sumtype
6 participants