Skip to content

gocritic: invalid ruleguard rules do not cause a warning or error #4421

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

Closed
5 tasks done
autarch opened this issue Feb 27, 2024 · 8 comments
Closed
5 tasks done

gocritic: invalid ruleguard rules do not cause a warning or error #4421

autarch opened this issue Feb 27, 2024 · 8 comments
Labels
dependencies Relates to an upstream dependency question Further information is requested

Comments

@autarch
Copy link

autarch commented Feb 27, 2024

Welcome

Description of the problem

If a ruleguard rule is invalid (but syntactically correct), it seems like golangci-lint does not error out. Here's an example rule:

func SomeRule(m dsl.Matcher) {
	m.Match("$foo").
		Where(m["foo"].Text.Matches("x")).
		Where(m["foo"].Text.Matches("y")).
		Report("x and y")
}

If this is run against ruleguard directly, it will complain: ruleguard: load rules: parse rules file: irconv error: ./gorules/rule.go:7: Where() can't be repeated

However, if run via golangci-lint run, there is no error and the process exits 0.

Note that this is not the same as #1565, which is about syntax errors in the rules. In this case, the rules are valid Go but the use of the dsl API is not valid.

Version of golangci-lint

$ golangci-lint --version
golangci-lint has version 1.56.2 built with go1.22.0 from 58a724a0 on 2024-02-15T18:01:51Z

Configuration

linters:
  disable-all: true
  enable:
    - gocritic

  gocritic:
    enabled-checks:
      - ruleguard
    settings:
      ruleguard:
        rules: "${configDir}/gorules/*.go"

Go environment

$ go version && go env
go version go1.20.10 linux/amd64
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/autarch/.cache/go-build"
GOENV="/home/autarch/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/autarch/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/autarch/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.20.10"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/autarch/tmp/rg/go.mod"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build548721329=/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/autarch/tmp/rg /home/autarch/tmp /home/autarch /home /] 
INFO [config_reader] Used config file .golangci.yml 
INFO [lintersdb] Active 1 linters: [gocritic]     
INFO [loader] Go packages loading at mode 575 (imports|name|types_sizes|compiled_files|deps|exports_file|files) took 103.777308ms 
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 106.514µs 
INFO [linters_context/goanalysis] analyzers took 5.572402ms with top 10 stages: gocritic: 5.567661ms, typecheck: 4.741µs 
INFO [runner] processing took 2.921µs with stages: max_from_linter: 570ns, nolint: 347ns, max_same_issues: 307ns, cgo: 239ns, identifier_marker: 237ns, skip_dirs: 163ns, autogenerated_exclude: 163ns, skip_files: 120ns, exclude-rules: 106ns, source_code: 105ns, fixer: 105ns, path_prettifier: 103ns, filename_unadjuster: 102ns, path_shortener: 36ns, severity-rules: 33ns, exclude: 32ns, diff: 31ns, sort_results: 31ns, max_per_file_from_linter: 31ns, uniq_by_line: 30ns, path_prefixer: 30ns 
INFO [runner] linters took 177.609003ms with stages: goanalysis_metalinter: 177.583661ms 
INFO File cache stats: 0 entries of total size 0B 
INFO Memory: 4 samples, avg is 47.3MB, max is 66.1MB 
INFO Execution took 285.113086ms                  

A minimal reproducible example or link to a public repository

https://github.com/autarch/golangci-lint-ruleguard-issue

Validation

  • Yes, I've included all information above (version, config, etc.).
@autarch autarch added the bug Something isn't working label Feb 27, 2024
@ldez
Copy link
Member

ldez commented Feb 27, 2024

Hello, you comparing with which version of ruleguard/go-critic?

@ldez ldez added the dependencies Relates to an upstream dependency label Feb 27, 2024
@ldez
Copy link
Member

ldez commented Feb 27, 2024

It's because your configuration is invalid:

linters:
  disable-all: true
  enable:
    - gocritic

linters-settings: ## <-- this line is missing inside your configuration
  gocritic:
    enabled-checks:
      - ruleguard
    settings:
      ruleguard:
        rules: "${configDir}/gorules/*.go"

With linters-settings::

$ git clone [email protected]:autarch/golangci-lint-ruleguard-issue.git
Cloning into 'golangci-lint-ruleguard-issue'...
remote: Enumerating objects: 11, done.
remote: Counting objects: 100% (11/11), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 11 (delta 0), reused 8 (delta 0), pack-reused 0
Receiving objects: 100% (11/11), done.
$ cd golangci-lint-ruleguard-issue 
$ vim .golangci.yml
$ go mod tidy
$ golangci-lint run                                                 
gorules/rule.go:1:1: ruleguard: execution error: used Run() with an empty rule set; forgot to call Load() first? (gocritic)
package gorules
^
main.go:1:1: ruleguard: execution error: used Run() with an empty rule set; forgot to call Load() first? (gocritic)
package main
^

Don't forget to clean to cache: golangci-lint cache clean
As rule files are not handled by golangci-lint itself, the changes on those files don't invalid the golangci-lint cache.

@ldez ldez added question Further information is requested and removed bug Something isn't working labels Feb 27, 2024
@Antonboom
Copy link
Contributor

Don't forget to clean to cache: golangci-lint cache clean

@ldez, hi
Maybe to add it to gocritic.settings.ruleguard comment?

@autarch
Copy link
Author

autarch commented Feb 29, 2024

Hello, you comparing with which version of ruleguard/go-critic?

I used the standalone ruleguard binary. Here's its "version" output:

$> ruleguard --V=full
/home/autarch/go/bin/ruleguard version devel comments-go-here buildID=debb54a207f33e4b3ebfee437ca250721178942d302e743b70b27f492ca7f5ba

I installed it with go install -v github.com/quasilyte/go-ruleguard/cmd/ruleguard@latest, which I think explains the lack of a version number.

@ldez
Copy link
Member

ldez commented Feb 29, 2024

This is not the same version as golangci-lint:

github.com/quasilyte/go-ruleguard v0.4.0 // indirect

The latest version of ruleguard is v0.4.2, I don't know the difference.

As you can see in the go.mod golangci-lint doesn't use ruleguard directly, we use go-critic.

can you try with go-critic?

@ldez
Copy link
Member

ldez commented Feb 29, 2024

I tried with go-critic:

$ gocritic check -enable ruleguard [email protected] gorules/rule.go main.go 
ruleguard init error, skip gorules/rule.go: irconv error: gorules/rule.go:7: Where() can't be repeated
./main.go:1:1: ruleguard: execution error: used Run() with an empty rule set; forgot to call Load() first?

@ldez
Copy link
Member

ldez commented Feb 29, 2024

The first line is a log:
https://github.com/go-critic/go-critic/blob/3b3645b54a7fb6b2b9fb6c10ef76ad601457003f/checkers/ruleguard_checker.go#L232-L238

The second line is a report.

golangci-lint doesn't allow linters to log, it just displays the report.

This is what I see in my test: #4421 (comment)

@ldez
Copy link
Member

ldez commented Feb 29, 2024

It's a log, and it uses the global std logger (no wrapper, no dedicated instance, etc.) so we cannot catch it.

But you can use the failOn

linters:
  disable-all: true
  enable:
    - gocritic

linters-settings:
  gocritic:
    enabled-checks:
      - ruleguard
    settings:
      ruleguard:
        rules: "${configDir}/gorules/rule.go"
        failOn: dsl

You will have this error:

$ golangci-lint run                                                                            
WARN [runner] Can't run linter goanalysis_metalinter: gocritic: ruleguard init error: irconv error: /home/ldez/sources/go/src/github.com/golangci/sandbox/gorules/rule.go:7: Where() can't be repeated 
ERRO Running error: can't run linter goanalysis_metalinter
gocritic: ruleguard init error: irconv error: /home/ldez/sources/go/src/github.com/golangci/sandbox/gorules/rule.go:7: Where() can't be repeated 

https://golangci-lint.run/usage/linters/#gocritic

@ldez ldez changed the title Invalid ruleguard rules do not cause a warning or error gocritic: invalid ruleguard rules do not cause a warning or error Feb 29, 2024
@ldez ldez closed this as completed Feb 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies Relates to an upstream dependency question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants