Description
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 (e.g., gocritic, go vet, etc.). (https://golangci-lint.run/usage/linters/)
Description of the problem
The path for the output report specified in a configuration file is apparently relative to the current working directory that golangci-lint is invoked from, rather than relative to the configuration file itself. This is a problem if the configuration file is located in a parent directory.
Steps to reproduce
- Create a configuration file at
~/Thumbtack/go/src/github.com/thumbtack/go/.golangci.yml
that includes the following:
output:
format: colored-line-number,junit-xml:reports/junit/lint.xml
- Create a directory at
~/Thumbtack/go/src/github.com/thumbtack/go/reports/junit
that will hold the report output. (The directory creation as a first step is necessary because this has not been implemented: Automatically create output directory for reports #3623) - Change directory to a sub-package, and then run the linter:
% cd ~/Thumbtack/go/src/github.com/thumbtack/go/lib/system
% pwd
/Users/james.johnston/Thumbtack/go/src/github.com/thumbtack/go/lib/system
% golangci-lint --verbose run ./...
Expected behavior
The linter should write a report file at ~/Thumbtack/go/src/github.com/thumbtack/go/reports/junit/lint.xml
because that is the output path specified in the configuration file (relative to the directory containing the configuration file).
Actual behavior
The linter fails with an error, because it tries to write the output in a location relative to the current working directory (lib/system
sub-directory), and does not find a pre-existing output directory there:
INFO [config_reader] Config search paths: [./ /Users/james.johnston/Thumbtack/go/src/github.com/thumbtack/go/lib/system /Users/james.johnston/Thumbtack/go/src/github.com/thumbtack/go/lib /Users/james.johnston/Thumbtack/go/src/github.com/thumbtack/go /Users/james.johnston/Thumbtack/go/src/github.com/thumbtack /Users/james.johnston/Thumbtack/go/src/github.com /Users/james.johnston/Thumbtack/go/src /Users/james.johnston/Thumbtack/go /Users/james.johnston/Thumbtack /Users/james.johnston /Users /]
INFO [config_reader] Used config file ../../.golangci.yml
INFO [lintersdb] Active 16 linters: [bodyclose errcheck errorlint gocritic gosec gosimple govet ineffassign noctx reassign revive scopelint staticcheck stylecheck typecheck unused]
INFO [loader] Go packages loading at mode 575 (imports|types_sizes|compiled_files|deps|files|exports_file|name) took 141.1195ms
WARN [runner] The linter 'scopelint' is deprecated (since v1.39.0) due to: The repository of the linter has been deprecated by the owner. Replaced by exportloopref.
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 1.335042ms
INFO [linters_context/goanalysis] analyzers took 0s with no stages
INFO [runner] Issues before processing: 30, after processing: 0
INFO [runner] Processors filtering stat (out/in): uniq_by_line: 21/24, path_prettifier: 30/30, exclude-rules: 24/28, nolint: 24/24, cgo: 30/30, exclude: 28/28, skip_dirs: 30/30, autogenerated_exclude: 28/30, diff: 0/21, filename_unadjuster: 30/30, skip_files: 30/30, identifier_marker: 28/28
INFO [runner] processing took 250.08712ms with stages: diff: 247.169708ms, nolint: 1.074416ms, exclude-rules: 676.333µs, autogenerated_exclude: 481.041µs, identifier_marker: 369.041µs, path_prettifier: 299.292µs, skip_dirs: 8.041µs, uniq_by_line: 3.375µs, cgo: 1.666µs, filename_unadjuster: 1.25µs, max_same_issues: 1.082µs, sort_results: 416ns, skip_files: 250ns, source_code: 250ns, path_shortener: 250ns, max_per_file_from_linter: 209ns, exclude: 209ns, max_from_linter: 125ns, severity-rules: 84ns, path_prefixer: 82ns
INFO [runner] linters took 705.687375ms with stages: goanalysis_metalinter: 455.4205ms
ERRO Running error: can't create output for reports/junit/lint.xml: open reports/junit/lint.xml: no such file or directory
INFO Memory: 10 samples, avg is 43.7MB, max is 57.3MB
INFO Execution took 856.919584ms
In the above logs, note the following:
- The configuration file used is
../../.golangci.yml
relative to the current working directory. - However, it tries to write output to
reports/junit/lint.xml
-- not../../reports/junit/lint.xml
which would be the path relative to the configuration file.
Thoughts on solving this
At the end of the day, all I want to do is write the JUnit output during CI/CD to a subdirectory relative to the base of our repository / relative to the configuration file, while at the same time allow ordinary developers to at least be able to run golangci-lint from any directory without encountering an error.
Whether that is solved by addressing #3623, providing a way to evaluate the output path relative to the configuration file, or some other maintainable solution is relatively inconsequential to me. It is the combination of both of these issues that presents a problem where it's just not practical to put output files in a subdirectory.
Version of golangci-lint
$ golangci-lint --version
golangci-lint has version 1.51.0 built from 6d3f06c5 on 2023-02-02T08:24:52Z
The problem still exists in master branch:
- At
golangci-lint/pkg/commands/run.go
Lines 414 to 425 in 50901e4
printReports
function. - At
golangci-lint/pkg/commands/run.go
Lines 434 to 435 in 50901e4
createWriter
as-is. - Which at
golangci-lint/pkg/commands/run.go
Lines 462 to 469 in 50901e4
os.OpenFile
as-is. - At no point is the path being adjusted to compensate for the location where the path was actually specified (e.g. the directory containing the configuration file).
Configuration file
Relevant part cited in problem description, above.
Go environment
% go version && go env
go version go1.19.5 darwin/arm64
GO111MODULE=""
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/james.johnston/Library/Caches/go-build"
GOENV="/Users/james.johnston/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/james.johnston/Thumbtack/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/james.johnston/Thumbtack/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.19.5"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/james.johnston/Thumbtack/go/src/github.com/thumbtack/go/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS="-I/usr/local/include"
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-L/usr/local/lib"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/91/w0njycjx075fd3lpnbzl44_h0000gp/T/go-build709362124=/tmp/go-build -gno-record-gcc-switches -fno-common"
Verbose output of running
Relevant verbose output cited in problem description.
Code example or link to a public repository
Enough information should be provided in the problem description to reproduce it.