-
Notifications
You must be signed in to change notification settings - Fork 8
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
per-file patterns #22
Conversation
forbidigo/forbidigo.go
Outdated
for i := 0; i < numTexts; i++ { | ||
texts = append(texts, filename+":"+texts[i]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for i := 0; i < numTexts; i++ { | |
texts = append(texts, filename+":"+texts[i]) | |
for _, text := range texts { | |
texts = append(texts, filename+":"+text) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was unsure whether slices can be modified while iterating over them and still haven't found a definitive statement about that.
But as it seems to work and you suggested it, I'll trust that it is safe and change the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did miss that bit but per https://go.dev/ref/spec, "The range expression x is evaluated once before beginning the loop."
428f3b9
to
b2cc495
Compare
b2cc495
to
4c5afbf
Compare
277a389
to
c542378
Compare
c542378
to
771b37d
Compare
771b37d
to
267f111
Compare
From #21 (comment): I've also been trying to put off #22 because I don't find regex as the conducive to filename matching as glob syntax. A pattern something like this seems most readable to me:
|
955f9fd
to
91bdf14
Compare
e83d37b
to
aecce62
Compare
File globing can be used to enable or disable certain rules based on the file that is being analyzed.
aecce62
to
65d2830
Compare
I've rebased to get get rid of the commits from PR #21 . |
@ashanbrown: do you want me to start the review process for the golangci-lint update now by creating a preliminary PR for it? Before that PR can get merged, it would be good to tag forbidigo and then use that tagged release in golangci-lint. But perhaps folks over there have feedback that we should consider before a formal release. |
How would you feel about inverting the sense of the check to be inclusion and just calling the matcher |
I'm also trying to figure out if we need the package prefix at all. Why wouldn't the package always just by the top-level package? I think this is what golangci-lint assumes as well. At https://golangci-lint.run/usage/configuration/, the example for the "skip-files" control is:
|
I'd favor holding off on the golangci-lint review until we get this MR merged. I'd prefer not to cause noise in there until we are ready. |
I started with that, but then explaining the field became a bit weird: the default (empty list = enabled) is the opposite of what the list means when it has entries. I can try again with that. The example you gave with
The same configuration might be used for multiple different packages. We do that in Kubernetes, which currently consists of a |
I see the issue regarding an empty list. I had been thinking that the So that would look something like:
As it stands we're looking at:
and
Just feeling these things out. Regarding the kubernetes example, would you argue the skip-files should work the same way for golangci-lint (i.e. it should include the package name)? Once we allow a "**" glob matcher, would that match package names too? It feels unusual to have the glob matcher matching parts of package names. |
That won't work, currently the entire file name must be matched. So that would have to be A single string with comma-separation may indeed be simpler. We can also do both (split string at comma, store list directly).
It would be more useful, yes.
The package name in |
I just got bitten (again!) by a gotcha in the globbing library: We are already using regular expressions for the pattern. Does it really make sense to use globbing for the file path? Regular expressions may be better understood and thus predictable. |
WIP PR using the feature in Kubernetes: kubernetes/kubernetes#109728 |
But that could be just me. |
Ok, thanks for experimenting with this. Using regexp to match the behavior of |
(The name |
Stepping back a moment, I'm still trying to understand why per-file matching should have a skip/ignore behavior. https://golangci-lint.run/usage/false-positives/ has a whole system for skipping false positives. Can you remind me why it isn't sufficient? I think the reason that I had suggested using globs was that it was better at describing inclusion. In particular, I had envisioned some syntax like |
The same could be said about moving the golangci.yml file around. But golangcli-lint normalizes paths so that they are relative to the directory of the config file before matching, so one has to change all paths inside the config when moving the config. One can argue both ways. The problem in forbidigo is that there's no concept of "config directory", so it cannot do the same as golangci-lint. It could use "current directory", but that then prevents invoking golangci-lint in different directories (currently supported).
In Kubernetes, I want to forbid certain patterns in If I had to use the Instead of matching specific patterns, I could exclude all issues by forbidgo. But then I still need to list all the non-test directories. Adding nolint directories all over the code base is a non-starter, too. |
We could use relative to "config directory" (when running in golangci-lint) with "current directory" as fallback (when not). But I need to check whether the "config directory" is available. |
|
Suppose the |
Per https://golangci-lint.run/usage/configuration/, golangci-lint seems to have some concept of where the root is. I can't find the documentation that suggests rules are relative to the config file location though. Absent other information, I'd expect rules to be relative to the current directory in which we run the linter. I still don't quite see why the configuration needs of this particular linter are different than any other linter. For every linter in golangci-lint, exceptions still need to be documented in every section. I think the claim is that we often have sets of rules that we want to apply to particular directories. Even for sets of rules, we'll be repeating the I'm just brainstorming here but here are a couple of alternatives we could consider to
I'm not sure there's harm in adding a |
I also think that it is not documented, but I know from experience that it is not the current directory. That makes sense because it is possible to invoke golangci-lint anywhere in the source tree and it will then walk up to find the configuration file. That wouldn't work if the paths in that configuration file were relative to the current directory.
Correct. Usage of a certain function may be fine in some parts of a program and forbidden elsewhere. This is different from coding conventions and best practices.
That is a valid point.
Yes. To me, defining the scope of the rule as part of the rule seems more logical and easier to review.
That may be viable. I'll experiment with that. |
Using Here's how I solved that:
But that is something that could be solved by enhancing golangci-lint - the only problem is that the only reaction I got for my proposal on Slack was a -1. The other problem is that Kubernetes currently has to invoke golangci-lint in sub-directories (multi-module repo) and paths don't work as I thought: what I said about "relative to config" was wrong, it just looked like that because the wrapper script in Kubernetes uses Let's close this PR and come back to it only if really needed, i.e. there's too much push-back against the solution above and nothing else gets accepted either. |
Thanks for testing out the comment-based approach @pohly. I'll keep an eye on golangci/golangci-lint#3571 and see how that goes. |
Including the
<package>:<file>
prefix as alternative text that gets matchedagainst makes it possible to write patterns that only match when that prefix is
as intended.
This builds on top of #21 which must be merged first.