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

Output report paths specified in the configuration file should be relative to that configuration file #3656

Closed
4 tasks done
james-johnston-thumbtack opened this issue Mar 4, 2023 · 0 comments · Fixed by #5363
Labels
area: config Related to .golangci.yml and/or cli options area: output Related to issue output enhancement New feature or improvement

Comments

@james-johnston-thumbtack

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

  1. 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
  1. 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)
  2. 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:

  1. At
    formats := strings.Split(e.cfg.Output.Format, ",")
    for _, format := range formats {
    out := strings.SplitN(format, ":", 2)
    if len(out) < 2 {
    out = append(out, "")
    }
    err := e.printReports(ctx, issues, out[1], out[0])
    if err != nil {
    return err
    }
    }
    we can see that the output path is passed as-is as a parameter to the printReports function.
  2. At
    func (e *Executor) printReports(ctx context.Context, issues []result.Issue, path, format string) error {
    w, shouldClose, err := e.createWriter(path)
    we see that it is then passed to createWriter as-is.
  3. Which at
    func (e *Executor) createWriter(path string) (io.Writer, bool, error) {
    if path == "" || path == "stdout" {
    return logutils.StdOut, false, nil
    }
    if path == "stderr" {
    return logutils.StdErr, false, nil
    }
    f, err := os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, defaultFileMode)
    we can see it is then passed to os.OpenFile as-is.
  4. 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.

@james-johnston-thumbtack james-johnston-thumbtack added the bug Something isn't working label Mar 4, 2023
@ldez ldez added enhancement New feature or improvement proposal area: config Related to .golangci.yml and/or cli options area: output Related to issue output and removed bug Something isn't working enhancement New feature or improvement labels Mar 4, 2023
misha-ridge added a commit to misha-ridge/golangci-lint-langserver that referenced this issue Mar 23, 2023
golangci-lint has issues running in subdirectories of the project,
e.g. golangci/golangci-lint#3656, golangci/golangci-lint#3717, so
running it from the directory where configuration file is located
is the only option for some projects.

Make it work as an option, because not every project triggers this
problem in golangci-lint, so for these projects overhead of
looking up directory of config file and adjusting the paths after
is not needed.
misha-ridge added a commit to misha-ridge/golangci-lint-langserver that referenced this issue Mar 23, 2023
golangci-lint has issues running in subdirectories of the project,
e.g. golangci/golangci-lint#3656, golangci/golangci-lint#3717, so
running it from the directory where configuration file is located
is the only option for some projects.

Make it work as an option, because not every project triggers this
problem in golangci-lint, so for these projects overhead of
looking up directory of config file and adjusting the paths after
is not needed.
@ldez ldez added breaking enhancement New feature or improvement and removed proposal labels Mar 3, 2024
@ldez ldez removed the breaking label Jan 31, 2025
@ldez ldez closed this as completed in #5363 Feb 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: config Related to .golangci.yml and/or cli options area: output Related to issue output enhancement New feature or improvement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants