golintergolangci-lint

golangci-lint results differ for the exact same file


I have a fork of the Polygon Edge software, developed in Go v1.20. The project uses golangci-lint in its GitHub Actions workflows. I enabled golangci-lint but first ran it manually on both the original and forked projects to compare results.

In the original project, no errors were found. However, in the forked project, numerous errors appeared—even for identical files, which is quite unusual. Here is the code from one of the files in question:

//nolint:forcetypeassert
package evm

import (
...
)


...

func opExp(c *state) {
    x := c.pop()
    y := c.top()

    var gas uint64
    if c.config.EIP158 {
        gas = 50
    } else {
        gas = 10
    }

    gasCost := uint64((y.BitLen()+7)/8) * gas
    if !c.consumeGas(gasCost) {
        return
    }

    z := acquireBig().Set(one)

    // https://www.programminglogic.com/fast-exponentiation-algorithms/
    for _, d := range y.Bits() {
        for i := 0; i < _W; i++ {
            if d&1 == 1 {
                toU256(z.Mul(z, x))
            }

            d >>= 1

            toU256(x.Mul(x, x))
        }
    }

    y.Set(z)
    releaseBig(z)
}

func opAddMod(c *state) {
    a := c.pop()
    b := c.pop()
    z := c.top()

    if z.Sign() == 0 {
        // division by zero
        z.Set(zero)
    } else {
        a = a.Add(a, b)
        z = z.Mod(a, z)
        toU256(z)
    }
}

func opMulMod(c *state) {
    a := c.pop()
    b := c.pop()
    z := c.top()

    if z.Sign() == 0 {
        // division by zero
        z.Set(zero)
    } else {
        a = a.Mul(a, b)
        z = z.Mod(a, z)
        toU256(z)
    }
}

func opAnd(c *state) {
    a := c.pop()
    b := c.top()

    b.And(a, b)
}

func opOr(c *state) {
    a := c.pop()
    b := c.top()

    b.Or(a, b)
}

func opXor(c *state) {
    a := c.pop()
    b := c.top()

    b.Xor(a, b)
}

var opByteMask = big.NewInt(255)

func opByte(c *state) {
    x := c.pop()
    y := c.top()

    indx := x.Int64()
    if indx > 31 {
        y.Set(zero)
    } else {
                sh := (31 - indx) * 8
line,220:       y.Rsh(y, uint(sh))
                y.And(y, opByteMask)
    }
}

func opNot(c *state) {
    a := c.top()

    a.Not(a)
    toU256(a)
}

...

I ran the following command: golangci-lint run --out-format=github-actions --timeout 10m --verbose

The results are as follows:

INFO golangci-lint has version v1.61.0 built with go1.23.2 from (unknown, modified: ?, mod sum: "h1:VvbOLaRVWmyxCnUIMTbf1kDsaJbTzH20FAMXTAlQGu8=") on (unknown) 
INFO [config_reader] Config search paths: [./ /Users/vitomirpavlov/work/forks/polygon-edge /Users/vitomirpavlov/work/forks
/Users/vitomirpavlov/work/projects/project-node
/Users/vitomirpavlov/work/projects /Users/vitomirpavlov/work/projects /Users/vitomirpavlov /Users /] 
INFO [config_reader] Used config file .golangci.yml 
WARN [config_reader] The configuration option `run.skip-dirs` is deprecated, please use `issues.exclude-dirs`. 
WARN [config_reader] The output format `github-actions` is deprecated, please use `colored-line-number` 
INFO [lintersdb] Active 27 linters: [dogsled dupl errcheck errname errorlint forcetypeassert goconst gocritic godox gofmt goimports gosec importas lll makezero misspell nlreturn nolintlint prealloc predeclared stylecheck thelper tparallel unconvert wastedassign whitespace wsl] 
INFO [loader] Go packages loading at mode 575 (compiled_files|exports_file|files|imports|deps|name|types_sizes) took 7.44611625s 
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 44.592417ms 
INFO [linters_context] importas settings found, but no aliases listed. List aliases under alias: key. 
INFO [linters_context/goanalysis] analyzers took 0s with no stages 
INFO [runner/skip_dirs] Skipped 9 issues from dir tests by pattern tests 
INFO [runner/skip_dirs] Skipped 5 issues from dir helper/tests by pattern tests 
INFO [runner] Issues before processing: 2771, after processing: 0 
INFO [runner] Processors filtering stat (in/out): invalid_issue: 2771/2771, path_prettifier: 2771/2771, skip_dirs: 2771/2757, exclude-rules: 1756/845, uniq_by_line: 497/484, autogenerated_exclude: 2757/1756, identifier_marker: 1756/1756, exclude: 1756/1756, nolint: 845/497, diff: 484/0, cgo: 2771/2771, filename_unadjuster: 2771/2771, skip_files: 2771/2771 
INFO [runner] processing took 449.635086ms with stages: diff: 311.677791ms, nolint: 74.901458ms, identifier_marker: 21.505708ms, exclude-rules: 20.301417ms, path_prettifier: 9.993584ms, autogenerated_exclude: 9.421166ms, skip_dirs: 1.468625ms, cgo: 125.5µs, invalid_issue: 100.75µs, uniq_by_line: 87.291µs, filename_unadjuster: 48.876µs, max_same_issues: 1.168µs, fixer: 291ns, exclude: 250ns, source_code: 209ns, sort_results: 209ns, max_per_file_from_linter: 208ns, skip_files: 167ns, path_shortener: 167ns, max_from_linter: 126ns, path_prefixer: 84ns, severity-rules: 41ns 
INFO [runner] linters took 1.501898458s with stages: goanalysis_metalinter: 1.052092375s 
INFO File cache stats: 0 entries of total size 0B 
INFO Memory: 92 samples, avg is 37.5MB, max is 96.1MB 
INFO Execution took 9.001672292s
INFO golangci-lint has version v1.61.0 built with go1.23.2 from (unknown, modified: ?, mod sum: "h1:VvbOLaRVWmyxCnUIMTbf1kDsaJbTzH20FAMXTAlQGu8=") on (unknown) 
INFO [config_reader] Config search paths: [./ /Users/vitomirpavlov/work/projects/project-node /Users/vitomirpavlov/work/projects /Users/vitomirpavlov/work/ /Users/vitomirpavlov/work /Users/vitomirpavlov /Users /] 
INFO [config_reader] Used config file .golangci.yml 
WARN [config_reader] The output format `github-actions` is deprecated, please use `colored-line-number` 
INFO [lintersdb] Active 27 linters: [dogsled dupl errcheck errname errorlint forcetypeassert goconst gocritic godox gofmt goimports gosec importas lll makezero misspell nlreturn nolintlint prealloc predeclared stylecheck thelper tparallel unconvert wastedassign whitespace wsl] 
INFO [loader] Go packages loading at mode 575 (deps|files|types_sizes|compiled_files|imports|name|exports_file) took 3.602814584s 
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 41.664167ms 
INFO [linters_context] importas settings found, but no aliases listed. List aliases under alias: key. 
INFO [linters_context/goanalysis] analyzers took 0s with no stages 
WARN [runner] Can't process result by diff processor: can't prepare diff by revgrep: could not read git repo: error executing "git diff --color=never --no-ext-diff --relative origin/develop --": exit status 128: fatal: bad revision 'origin/develop' 
INFO [runner/skip_dirs] Skipped 5 issues from dir helper/tests by pattern tests 
INFO [runner/skip_dirs] Skipped 10 issues from dir tests by pattern tests 
INFO [runner/max_same_issues] 43/46 issues with text "G115: integer overflow conversion int -> uint64" were hidden, use --max-same-issues 
INFO [runner/max_same_issues] 23/26 issues with text "G115: integer overflow conversion int64 -> uint64" were hidden, use --max-same-issues 
INFO [runner/max_same_issues] 20/23 issues with text "G115: integer overflow conversion uint64 -> int64" were hidden, use --max-same-issues 
INFO [runner/max_same_issues] 14/17 issues with text "assignments should only be cuddled with other assignments" were hidden, use --max-same-issues 
INFO [runner/max_same_issues] 12/15 issues with text "only one cuddle assignment allowed before if statement" were hidden, use --max-same-issues 
INFO [runner/max_same_issues] 12/15 issues with text "G115: integer overflow conversion uint64 -> int" were hidden, use --max-same-issues 
INFO [runner/max_same_issues] 8/11 issues with text "expressions should not be cuddled with blocks" were hidden, use --max-same-issues 
INFO [runner/max_same_issues] 7/10 issues with text "ifElseChain: rewrite if-else to switch statement" were hidden, use --max-same-issues 
INFO [runner/max_same_issues] 6/9 issues with text "commentFormatting: put a space between `//` and comment text" were hidden, use --max-same-issues 
INFO [runner/max_same_issues] 6/9 issues with text "type assertion must be checked" were hidden, use --max-same-issues 
INFO [runner/max_same_issues] 2/5 issues with text "if statements should only be cuddled with assignments" were hidden, use --max-same-issues 
INFO [runner/max_same_issues] 1/4 issues with text "unslice: could simplify buf[:] to buf" were hidden, use --max-same-issues 
INFO [runner/max_same_issues] 1/4 issues with text "G115: integer overflow conversion int -> uint8" were hidden, use --max-same-issues 
INFO [runner] Issues before processing: 2613, after processing: 103 
INFO [runner] Processors filtering stat (in/out): max_same_issues: 258/103, max_from_linter: 103/103, source_code: 103/103, path_shortener: 103/103, path_prefixer: 103/103, invalid_issue: 2613/2613, identifier_marker: 1634/1634, max_per_file_from_linter: 258/258, uniq_by_line: 271/258, cgo: 2613/2613, filename_unadjuster: 2613/2613, exclude-rules: 1634/531, severity-rules: 103/103, fixer: 103/103, sort_results: 103/103, path_prettifier: 2613/2613, autogenerated_exclude: 2598/1634, nolint: 531/271, skip_files: 2613/2613, skip_dirs: 2613/2598, exclude: 1634/1634 
INFO [runner] processing took 497.365834ms with stages: diff: 379.893458ms, nolint: 46.737834ms, path_prettifier: 22.076375ms, identifier_marker: 20.3875ms, exclude-rules: 15.325542ms, autogenerated_exclude: 9.250959ms, source_code: 1.650209ms, skip_dirs: 1.501666ms, max_same_issues: 184.542µs, invalid_issue: 97.792µs, cgo: 97.751µs, uniq_by_line: 47.666µs, filename_unadjuster: 47.542µs, max_from_linter: 29.083µs, max_per_file_from_linter: 22.167µs, path_shortener: 12.667µs, skip_files: 2.125µs, fixer: 333ns, exclude: 291ns, sort_results: 167ns, severity-rules: 83ns, path_prefixer: 82ns 
INFO [runner] linters took 1.363894625s with stages: goanalysis_metalinter: 866.168459ms 
...
::high file=helper/staking/staking.go,line=198,col=31::G115: integer overflow conversion int -> uint64 (gosec)
::error file=state/runtime/evm/instructions.go,line=1257,col=3::assignOp: replace `availableGas = availableGas - availableGas/64` with `availableGas -= availableGas/64` (gocritic)
::error file=state/runtime/evm/instructions.go,line=1016,col=2::assignOp: replace `size = size - 1` with `size--` (gocritic)
::error file=state/runtime/evm/instructions.go,line=468,col=2::ifElseChain: rewrite if-else to switch statement (gocritic)
::error file=state/runtime/evm/instructions.go,line=508,col=3::ifElseChain: rewrite if-else to switch statement (gocritic)
::error file=state/runtime/evm/instructions.go,line=521,col=3::ifElseChain: rewrite if-else to switch statement (gocritic)
::high file=state/runtime/evm/instructions.go,line=220,col=16::G115: integer overflow conversion int64 -> uint (gosec)
::high file=state/runtime/evm/instructions.go,line=315,col=14::G115: integer overflow conversion uint -> int (gosec)
::high file=state/runtime/evm/instructions.go,line=611,col=28::G115: integer overflow conversion int64 -> uint64 (gosec)
::high file=state/runtime/evm/instructions.go,line=956,col=13::G115: integer overflow conversion uint64 -> int (gosec)
::high file=state/runtime/evm/instructions.go,line=968,col=14::G115: integer overflow conversion uint64 -> int (gosec)
::high file=state/runtime/evm/state.go,line=330,col=50::G115: integer overflow conversion uint64 -> int (gosec)
::error file=state/runtime/evm/instructions.go,line=631,col=6::function min has same name as predeclared identifier (predeclared)
...
INFO File cache stats: 45 entries of total size 343.1KiB 
INFO Memory: 52 samples, avg is 42.3MB, max is 100.6MB 
INFO Execution took 5.018112166s   

The version of the linter is: golangci-lint has version v1.61.0 built with go1.23.2 from (unknown, modified: ?, mod sum: "h1:VvbOLaRVWmyxCnUIMTbf1kDsaJbTzH20FAMXTAlQGu8=") on (unknown)

I have tried to clean the cache, checked versions, and anything that came up to my mind, but nothing worked out.


Solution

  • You have clearly a different configurations, one has run.skip-dirs, the other doesn't. Also, you seem have something like:

    issues:
      new-from-rev: "origin/develop"
    

    in your configuration which appears to be a branch missing in the fork - this could explain the different outputs. Please provide a minimal, reproducible example we can check out and analyze when you require a more precise explanation.