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

golangci-lint -> gocritic -> ruleguard fails with no indication #2190

Closed
4 tasks done
thockin opened this issue Aug 19, 2021 · 11 comments
Closed
4 tasks done

golangci-lint -> gocritic -> ruleguard fails with no indication #2190

thockin opened this issue Aug 19, 2021 · 11 comments
Assignees
Labels
bug Something isn't working

Comments

@thockin
Copy link

thockin commented Aug 19, 2021

Welcome

  • Yes, I'm using a binary release within 2 latest major releases. Only such installations are supported.
  • Yes, I've searched similar issues on GitHub and didn't find any.
  • Yes, I've included all information below (version, config, etc).
  • Yes, I've tried with the standalone linter if available. (https://golangci-lint.run/usage/linters/)

Description of the problem

It seems that ruleguard demands github.com/quasilyte/go-ruleguard/dsl be available locally but when it's not, there's no error from golangci-lint. Running gocritic itself tells me:

$ gocritic
panic: load embedded ruleguard rules: typechecker error: rules/rules.go:4:2: could not import github.com/quasilyte/go-ruleguard/dsl (can't find import: "github.com/quasilyte/go-ruleguard/dsl")

golangci-lint (either by hand or run under docker) says nothing at all, making me BELIEVE my rules all pass.

Version of golangci-lint

$ golangci-lint --version
golangci-lint has version v1.41.1 built from (unknown, mod sum: "h1:KH28pTSqRu6DTXIAANl1sPXNCmqg4VEH21z6G9Wj4SM=") on (unknown)

Configuration file

$ cat .golangci.yml
run:
  timeout: 30m
  skip-files:
    - "^zz_generated.*"

issues:
  max-same-issues: 0

linters:
  disable-all: true
  enable: # please keep this alphabetized
    - deadcode
    - gocritic
    - ineffassign
    - staticcheck
    - unused
    - varcheck
linters-settings: # please keep this alphabetized
  gocritic:
    enabled-checks:
      - ruleguard
    settings:
      ruleguard:
        rules: "ruleguard_rules.go"
  staticcheck:
    go: "1.16"
    checks: [ "all" ]
  unused:
    go: "1.16"

Go environment

$ go version && go env
go version go1.16 linux/amd64
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/thockin/.cache/go-build"
GOENV="/home/thockin/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/thockin/src/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/thockin/src/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/thockin/src/go/src/k8s.io/kubernetes/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2389944306=/tmp/go-build -gno-record-gcc-switches"

Verbose output of running

$ golangci-lint cache clean
$ golangci-lint run -v
INFO [config_reader] Config search paths: [./ /home/thockin/src/go/src/k8s.io/kubernetes /home/thockin/src/go/src/k8s.io /home/thockin/src/go/src /home/thockin/src/go /home/thockin/src /home/thockin /home /] 
INFO [config_reader] Used config file .golangci.yaml 
INFO [lintersdb] Active 6 linters: [deadcode gocritic ineffassign staticcheck unused varcheck] 
INFO [loader] Go packages loading at mode 575 (compiled_files|exports_file|name|types_sizes|deps|files|imports) took 393.318901ms 
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 7.458204ms 
INFO [linters context/goanalysis] analyzers took 0s with no stages 
INFO [runner] processing took 3.273µs with stages: max_same_issues: 750ns, skip_dirs: 348ns, nolint: 275ns, filename_unadjuster: 218ns, max_from_linter: 210ns, skip_files: 206ns, cgo: 147ns, path_prettifier: 139ns, diff: 137ns, exclude: 135ns, uniq_by_line: 129ns, autogenerated_exclude: 128ns, identifier_marker: 127ns, source_code: 57ns, exclude-rules: 48ns, path_shortener: 46ns, max_per_file_from_linter: 44ns, path_prefixer: 43ns, sort_results: 43ns, severity-rules: 43ns 
INFO [runner] linters took 137.727999ms with stages: goanalysis_metalinter: 137.685261ms 
INFO File cache stats: 0 entries of total size 0B 
INFO Memory: 7 samples, avg is 71.9MB, max is 72.1MB 
INFO Execution took 543.696902ms                  

Code example or link to a public repository

// add your code here
@thockin thockin added the bug Something isn't working label Aug 19, 2021
@boring-cyborg
Copy link

boring-cyborg bot commented Aug 19, 2021

Hey, thank you for opening your first Issue ! 🙂 If you would like to contribute we have a guide for contributors.

@ldez
Copy link
Member

ldez commented Aug 19, 2021

hello,
could you provide a reproducible example?

@thockin
Copy link
Author

thockin commented Aug 20, 2021

Check out k8s.io/kubernetes.

$ cat > .golangci.yaml << EOF
run:
  timeout: 30m
  skip-files:
    - "^zz_generated.*"

issues:
  max-same-issues: 0

linters:
  disable-all: true
  enable:
    - gocritic
linters-settings: # please keep this alphabetized
  gocritic:
    enabled-checks:
      - ruleguard
    settings:
      ruleguard:
        rules: "ruleguard_rules.go"
EOF

$ cat > rules.go << EOF
package gorules

import "github.com/quasilyte/go-ruleguard/dsl"

func netParseIP(m dsl.Matcher) {
	m.Match(`net.ParseIP($_)`).Report("prefer utilnet.ParseIPSloppy()")
}
EOF

$ golangci-lint run -v
INFO [config_reader] Config search paths: [./ /home/thockin/src/go/src/k8s.io/kubernetes /home/thockin/src/go/src/k8s.io /home/thockin/src/go/src /home/thockin/src/go /home/thockin/src /home/thockin /home /] 
INFO [config_reader] Used config file .golangci.yaml 
INFO [lintersdb] Active 1 linters: [gocritic]     
INFO [loader] Go packages loading at mode 575 (compiled_files|files|name|types_sizes|deps|exports_file|imports) took 59.476790173s 
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 352.107499ms 
INFO [linters context/goanalysis] analyzers took 1m46.65046061s with top 10 stages: gocritic: 1m46.65046061s 
INFO [runner] processing took 2.975µs with stages: max_same_issues: 589ns, skip_dirs: 325ns, nolint: 240ns, cgo: 236ns, filename_unadjuster: 211ns, skip_files: 196ns, max_from_linter: 179ns, identifier_marker: 125ns, uniq_by_line: 123ns, exclude: 122ns, diff: 120ns, autogenerated_exclude: 118ns, path_prettifier: 113ns, max_per_file_from_linter: 44ns, source_code: 43ns, exclude-rules: 41ns, path_shortener: 39ns, sort_results: 38ns, path_prefixer: 37ns, severity-rules: 36ns 
INFO [runner] linters took 21.235547543s with stages: gocritic: 21.235502731s 
INFO File cache stats: 0 entries of total size 0B 
INFO Memory: 812 samples, avg is 348.1MB, max is 1204.4MB 
INFO Execution took 1m21.077419655s

$ gocritic check -v -enable ruleguard -@ruleguard.rules rules.go
panic: load embedded ruleguard rules: typechecker error: rules/rules.go:4:2: could not import github.com/quasilyte/go-ruleguard/dsl (can't find import: "github.com/quasilyte/go-ruleguard/dsl")

goroutine 1 [running]:
github.com/go-critic/go-critic/checkers.init.10()
	/home/thockin/src/go/pkg/mod/github.com/go-critic/go-critic@v0.5.7/checkers/checkers.go:55 +0x611

If I force github.com/quasilyte/go-ruleguard/dsl to be vendored (which is a PITA, to be sure) then it works. It took us far too long to figure this out because golangci-lint doesn't complain at all.

@thockin
Copy link
Author

thockin commented Aug 21, 2021

More simply, point the ruleguard config in .golangci.yaml to a non-existent file and watch it not fail.

$ cat .golangci.yaml
run:
linters:
  disable-all: true
  enable:
    - gocritic
linters-settings:
  gocritic:
    enabled-checks:
      - ruleguard
    settings:
      ruleguard:
        rules: "no-such-file.go"
$ ls -l no-such-file.go
ls: cannot access 'no-such-file.go': No such file or directory
$ golangci-lint run -v ./pkg/proxy/...
INFO [config_reader] Config search paths: [./ /home/thockin/src/go/src/k8s.io/kubernetes/pkg/proxy /home/thockin/src/go/src/k8s.io/kubernetes/pkg /home/thockin/src/go/src/k8s.io/kubernetes /home/thockin/src/go/src/k8s.io /home/thockin/src/go/src /home/thockin/src/go /home/thockin/src /home/thockin /home /] 
INFO [config_reader] Used config file .golangci.yaml 
INFO [lintersdb] Active 1 linters: [gocritic]     
INFO [loader] Go packages loading at mode 575 (types_sizes|imports|name|exports_file|files|compiled_files|deps) took 558.241437ms 
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 16.775999ms 
INFO [linters context/goanalysis] analyzers took 0s with no stages 
INFO [runner] processing took 3.096µs with stages: max_same_issues: 508ns, skip_dirs: 303ns, nolint: 253ns, cgo: 251ns, max_from_linter: 240ns, skip_files: 228ns, filename_unadjuster: 228ns, autogenerated_exclude: 140ns, diff: 132ns, exclude: 129ns, path_prettifier: 129ns, uniq_by_line: 121ns, identifier_marker: 108ns, source_code: 52ns, path_shortener: 50ns, exclude-rules: 50ns, sort_results: 49ns, max_per_file_from_linter: 42ns, severity-rules: 42ns, path_prefixer: 41ns 
INFO [runner] linters took 117.817765ms with stages: gocritic: 117.779537ms 
INFO File cache stats: 0 entries of total size 0B 
INFO Memory: 8 samples, avg is 79.9MB, max is 138.3MB 
INFO Execution took 697.971514ms                  
$ echo $?
0

@thockin
Copy link
Author

thockin commented Oct 22, 2021

Coming back to this, I have set up a trivial demonstration of the problem(s): https://github.com/thockin/ruleguard-multi-modules

There are errors in both subdir/file.go and submod/file.go.

$ golangci-lint run
subdir/file.go:6:2: ruleguard: prefer mynet.ParseIPSloppy() (gocritic)
	net.ParseIP("foobar")
	^

but

$ golangci-lint run ./submod/
ERRO [linters context] typechecking error: main module (example.com/root) does not contain package example.com/root/submod

I know this is a problem with Go's own handling of multi-repo. Try the usual workaround:

$ cd submod/; golangci-lint run; cd - >/dev/null

No output.

$ cd submod/; golangci-lint -v  run; cd - >/dev/null
INFO [config_reader] Config search paths: [./ /home/thockin/src/go/src/github.com/thockin/ruleguard-multi-modules/submod /home/thockin/src/go/src/github.com/thockin/ruleguard-multi-modules /home/thockin/src/go/src/github.com/thockin /home/thockin/src/go/src/github.com /home/thockin/src/go/src /home/thockin/src/go /home/thockin/src /home/thockin /home /] 
INFO [config_reader] Used config file ../.golangci.yaml 
INFO [lintersdb] Active 1 linters: [gocritic]     
INFO [loader] Go packages loading at mode 575 (compiled_files|files|name|deps|exports_file|imports|types_sizes) took 70.889764ms 
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 94.267µs 
INFO [linters context/goanalysis] analyzers took 0s with no stages 
INFO [runner] processing took 3.34µs with stages: max_same_issues: 551ns, nolint: 523ns, skip_dirs: 257ns, cgo: 241ns, skip_files: 217ns, max_from_linter: 217ns, filename_unadjuster: 212ns, diff: 143ns, path_prettifier: 135ns, identifier_marker: 131ns, uniq_by_line: 130ns, autogenerated_exclude: 129ns, exclude: 124ns, max_per_file_from_linter: 53ns, path_shortener: 51ns, source_code: 50ns, sort_results: 49ns, severity-rules: 44ns, exclude-rules: 42ns, path_prefixer: 41ns 
INFO [runner] linters took 16.305039ms with stages: gocritic: 16.238387ms 
INFO File cache stats: 0 entries of total size 0B 
INFO Memory: 2 samples, avg is 71.7MB, max is 71.8MB 
INFO Execution took 92.837517ms                   

It found the golangi-lint config in the parent dir, but not the rules file. But it didn't complain in any way, making me thing it actually passed, when it didn't.

@sebastien-rosset
Copy link
Contributor

sebastien-rosset commented Oct 23, 2021

Is this reproducible with the master branch of golangci-lint? PR #2041 was merged into master, it has has go-critic 0.6.1 (from 0.5.6) and ruleguard 0.3.13 (from 0.3.4).

@ldez
Copy link
Member

ldez commented Oct 23, 2021

I tested the 2 use cases and the problem are fixed by #2041

$ ./golangci-lint run
WARN [runner] Can't run linter gocritic: gocritic: ruleguard init error: no file matching 'no-such-file.go' 
$ ./golangci-lint run
subdir/file.go:6:2: ruleguard: prefer mynet.ParseIPSloppy() (gocritic)
	net.ParseIP("foobar")
	^

@ldez ldez closed this as completed Oct 23, 2021
@thockin
Copy link
Author

thockin commented Oct 23, 2021

Excellent news! Can we get a new tag on this repo?

Thanks.

@thockin
Copy link
Author

thockin commented Nov 8, 2021

confirmed thanks!

@Charlie17Li
Copy link

@thockin Excuse me, how can you fix the problem that executes golangci-lint run in the main mod and will show the error

$ golangci-lint run ./submod/
ERRO [linters context] typechecking error: main module (example.com/root) does not contain package example.com/root/submod

I add the golnagci-lint plugin in Goland, and every time I save the go file, it will show the above the error

thx :)

@thockin
Copy link
Author

thockin commented Dec 16, 2022

cd submod; golangci-lint run .

or use go workspaces

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants