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

fix: consider path prefix when matching path patterns #3571

Merged
merged 2 commits into from
Mar 17, 2023

Conversation

pohly
Copy link
Contributor

@pohly pohly commented Feb 6, 2023

Problem

When someone invokes golangci-lint in a sub-directory, they can set the path prefix to make the output look like the invocation had been done in the root.
But this prefix was ignored when checking path patterns of exclude, severity, and skip files/dirs entries, so those with matching for directories only worked when golangci-lint was always invoked in the same directory.

Solution

The underlying problem is that the rules from the configuration get checked before updating the path associated with the issues in the path fixer.
To make the prefix work, it now gets passed down into processors and added there to the issue path before checking against the path pattern.

For exclude and severity rules, this could have been done through a separate parameter, but bundling it in a new fsutils helper struct made the change a bit smaller.

@boring-cyborg
Copy link

boring-cyborg bot commented Feb 6, 2023

Hey, thank you for opening your first Pull Request !

@CLAassistant
Copy link

CLAassistant commented Feb 6, 2023

CLA assistant check
All committers have signed the CLA.

@@ -83,7 +83,7 @@ func NewRunner(cfg *config.Config, log logutils.Log, goenv *goutil.Env, es *lint
processors.NewIdentifierMarker(),

getExcludeProcessor(&cfg.Issues),
getExcludeRulesProcessor(&cfg.Issues, log, lineCache),
getExcludeRulesProcessor(&cfg.Issues, log, cfg.Output.PathPrefix, lineCache),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like path prefix and line cache get passed through different functions together. To minimize changes I had originally made "path prefix" a field in the line cache (or rather, the file cache, with an accessor in the line cache).

That didn't work because the caches got created before parsing the configuration. I would have had to add a SetPathPrefix to add that later, which didn't feel right.

Do you have any preference?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the end I went for an approach where line cache and path prefix get combined. This keeps the number of parameters that need to be passed through the same.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if r.isEmpty() {
return false
}
if r.text != nil && !r.text.MatchString(issue.Text) {
return false
}
if r.path != nil && !r.path.MatchString(issue.FilePath()) {
if r.path != nil && !r.path.MatchString(path.Join(pathPrefix, issue.FilePath())) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If pathPrefix is empty, pathPrefix will ignore it. But the result is "cleaned" - I am not sure whether that is potentially harmful (performance, Windows separator?).

If "path prefix" was an attribute in lineCache, then a LineCache.WithPathPrefix(p string) method could be added to do the extension of the path in a consistent way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

path.Join is correct. The path prefixer does the same. To handle Windows, the path regex gets mangled to match the separator used by the platform.

@@ -37,7 +37,7 @@ func TestExcludeRulesMultiple(t *testing.T) {
Linters: []string{"lll"},
},
},
}, lineCache, nil)
}, "" /* path prefix */, lineCache, nil)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add unit tests once I know how this is supposed to be handled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added them.

@pohly pohly changed the title WIP: consider path prefix when matching exclude rules RFC: consider path prefix when matching exclude rules Feb 6, 2023
@ldez ldez changed the title RFC: consider path prefix when matching exclude rules Consider path prefix when matching exclude rules Feb 6, 2023
@ldez ldez marked this pull request as draft February 6, 2023 21:49
@ldez ldez added the area: config Related to .golangci.yml and/or cli options label Feb 6, 2023
@pohly pohly marked this pull request as ready for review February 8, 2023 20:33
@pohly pohly changed the title Consider path prefix when matching exclude rules Consider path prefix when matching exclude and severity rules Feb 8, 2023
@pohly pohly changed the title Consider path prefix when matching exclude and severity rules Consider path prefix when matching path patterns Feb 9, 2023
@pohly
Copy link
Contributor Author

pohly commented Feb 9, 2023

@ldez: I also looked at skip-files and skip-dirs. Both had the same problem, so I extended the PR to also fix those.

I think this is ready for review now.

@pohly
Copy link
Contributor Author

pohly commented Feb 9, 2023

In case someone wonders: the reason why the directory has to be changed in the Kubernetes repo is that staging/src/k8s.io/* are all separate modules, so golangci-lint ./staging/src/k8s.io/... wouldn't work. But we want to maintain a single golangci.yaml for all modules with path matches for certain directories, hence this PR...

When someone invokes golangci-lint in a sub-directory, they can set the path
prefix to make the output look like the invocation had been done in the
root. But this prefix was ignored when checking path patterns of exclude,
severity, and skip files/dirs entries, so those with matching for directories
only worked when golangci-lint was always invoked in the same directory.

The underlying problem is that the rules from the configuration get checked
before updating the path associated with the issues in the path fixer. To make
the prefix work, it now gets passed down into processors and added there to the
issue path before checking against the path pattern.

For exclude and severity rules, this could have been done through a separate
parameter, but bundling it in a new fsutils helper struct made the change a bit
smaller.
@pohly
Copy link
Contributor Author

pohly commented Feb 26, 2023

The path prefixer test failed on Windows because I was using "path.Join", not "path/filepath.Join" as before. This change should fix that:

diff --git a/pkg/fsutils/files.go b/pkg/fsutils/files.go
index 542af531..3d369a23 100644
--- a/pkg/fsutils/files.go
+++ b/pkg/fsutils/files.go
@@ -1,6 +1,6 @@
 package fsutils
 
-import "path"
+import "path/filepath"
 
 // Files combines different operations related to handling file paths and
 // content.
@@ -32,5 +32,5 @@ func WithPathPrefix(pathPrefix, relativePath string) string {
        if pathPrefix == "" {
                return relativePath
        }
-       return path.Join(pathPrefix, relativePath)
+       return filepath.Join(pathPrefix, relativePath)
 }

Copy link
Member

@ldez ldez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think your approach can be extended to the Fixer processor, can try to fix the Fixer?

docs/src/docs/usage/false-positives.mdx Outdated Show resolved Hide resolved
pkg/fsutils/files.go Outdated Show resolved Hide resolved
pkg/fsutils/files.go Outdated Show resolved Hide resolved
pkg/fsutils/files.go Outdated Show resolved Hide resolved
pkg/lint/runner.go Outdated Show resolved Hide resolved
@ldez ldez added the feedback required Requires additional feedback label Mar 15, 2023
Co-authored-by: Ludovic Fernandez <ldez@users.noreply.github.com>
@pohly
Copy link
Contributor Author

pohly commented Mar 16, 2023

I think your approach can be extended to the Fixer processor, can try to fix the Fixer?

The problem with the fixer processor seems to be that it runs after the path prefixer (#3626).

That leads to the inverse problem of what I am solving here: the fixer sees the path with prefix which doesn't match the correct path relative to the current working directory, whereas severity and exclude processors (before this PR) see the path without the prefix when they need it with prefix.

The fix for the fixer in the PR above is to strip the prefix again. That doesn't seem ideal. Perhaps a simpler solution is to move the path prefixing and sorting out of the normal set of processors and do that after fixing?

Either way, such a fix doesn't need to be in this PR.

Thanks for the comment fixes, I included all of them in this commit - I prefer to keep the commit history clean. Let me know if you prefer it otherwise and I can restore them as a separate commit.

@ldez
Copy link
Member

ldez commented Mar 16, 2023

Thanks for the comment fixes, I included all of them in this commit - I prefer to keep the commit history clean. Let me know if you prefer it otherwise and I can restore them as a separate commit.

I prefer to have fixes as commits, it's easier to follow the review.

@pohly
Copy link
Contributor Author

pohly commented Mar 16, 2023

Okay, I added the second commit with the comment changes.

BTW, should I also rebase each time I do a push to avoid having to merge with master?

@pohly
Copy link
Contributor Author

pohly commented Mar 16, 2023

I prepared a separate PR with my idea of fixing the fixer. It's unrelated to the changes in this PR, but there will be a slight merge conflict.

I can also add those other changes here, if you prefer a single PR.

@ldez ldez removed the feedback required Requires additional feedback label Mar 16, 2023
Copy link
Member

@ldez ldez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LTGM

@ldez ldez added bug Something isn't working and removed enhancement New feature or improvement labels Mar 17, 2023
@ldez ldez changed the title Consider path prefix when matching path patterns fix: consider path prefix when matching path patterns Mar 17, 2023
@ldez ldez merged commit b40a544 into golangci:master Mar 17, 2023
SeigeC pushed a commit to SeigeC/golangci-lint that referenced this pull request Apr 4, 2023
yoheiueda added a commit to yoheiueda/cloud-api-adaptor that referenced this pull request Apr 20, 2023
This patch enables the golangci-lint checks for csi-wrapper.

The version of golangci-lint is bumped to v1.52.2, since the old
version has a bug when processing the --prefix-path option, which
is necessary to run the lint tool in sub modules.

golangci/golangci-lint#3571

Signed-off-by: Yohei Ueda <yohei@jp.ibm.com>
huoqifeng pushed a commit to confidential-containers/cloud-api-adaptor that referenced this pull request Apr 24, 2023
This patch enables the golangci-lint checks for csi-wrapper.

The version of golangci-lint is bumped to v1.52.2, since the old
version has a bug when processing the --prefix-path option, which
is necessary to run the lint tool in sub modules.

golangci/golangci-lint#3571

Signed-off-by: Yohei Ueda <yohei@jp.ibm.com>
bpradipt pushed a commit to bpradipt/cloud-api-adaptor that referenced this pull request Aug 12, 2023
This patch enables the golangci-lint checks for csi-wrapper.

The version of golangci-lint is bumped to v1.52.2, since the old
version has a bug when processing the --prefix-path option, which
is necessary to run the lint tool in sub modules.

golangci/golangci-lint#3571

Signed-off-by: Yohei Ueda <yohei@jp.ibm.com>
wainersm pushed a commit to wainersm/cc-cloud-api-adaptor that referenced this pull request Sep 5, 2023
This patch enables the golangci-lint checks for csi-wrapper.

The version of golangci-lint is bumped to v1.52.2, since the old
version has a bug when processing the --prefix-path option, which
is necessary to run the lint tool in sub modules.

golangci/golangci-lint#3571

Signed-off-by: Yohei Ueda <yohei@jp.ibm.com>
@ldez ldez added this to the v1.52 milestone Mar 6, 2024
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 bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants