-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
feat: add godoclint linter #6062
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
base: main
Are you sure you want to change the base?
Conversation
Hey, thank you for opening your first Pull Request ! |
6e96c39
to
46d3307
Compare
In order for a pull request adding a linter to be reviewed, the linter and the PR must follow some requirements.
Pull Request Description
Linter
The Linter Tests Inside Golangci-lint
|
The linter description claims to follow Go recommendations from this page, but several rules are not those recommendations (ex, line length). The linter applies the rules to non-exposed elements, but those elements are not a part of the godoc render (ex, a non-exported constant doesn't need to have a doc beginning with its own name), and so they don't need to follow the same rules as exposed elements.
This can be seen as false positives, IMO, this will be the main criterion for users to not use this linter. Even the examples of "good" from the linter README don't pass the rules of the linter:
|
Thanks for taking the time reviewing the linter, @ldez! 🙏 Let me first provide a categorised table of the rules so that I can refer to them later:
By default, the linter only applies the Basic rules. They're low-effort because they don't require user to add more godocs. Rather, they just check if the existing godocs match the recommended formatting. The Strict rules are costly to enable. Although they're recommended by Go Doc Comments, but the linter do not apply them by default, because it will be too much, and in some cases unnecessary. So, that's up to the user to enable them based on their situation. And finally the Extra rules which are not part of the blog post, are additional rules to help improve godocs. They're not breaking/opposing the recommended rules. These are also not enabled by default. Now, back to your points:
True.
Good point, and that was one of my initial challenges. Note that godocs are not only used with the renderer or on That said, I think I'm open to exclude unexported symbols from the default behaviour, of course, in favour of a configuration parameter to enable the rule for them. Please let me know your thoughts.
Makes sense, and thanks for the feedback. I'll update those examples to avoid confusion for the reader. |
I think it should be an option of |
Note: golangci-lint will not follow your configuration naming style with |
Makes sense. I'll push the changes for this and README good/bad examples, and will then rebase the PR.
Just to be clear, you saying this format is not acceptable, right? linters:
settings:
godoclint:
options:
max-len/length: 127 And if yes, how about using dashes like this? linters:
settings:
godoclint:
options:
max-len-length: 127 Or even dots? linters:
settings:
godoclint:
options:
max-len.length: 127 Any particular recommendation? |
linters:
settings:
godoclint:
options:
max-len:
length: 127 |
I'll push the changes for this as well. |
Signed-off-by: Babak K. Shandiz <[email protected]>
Signed-off-by: Babak K. Shandiz <[email protected]>
Signed-off-by: Babak K. Shandiz <[email protected]>
Signed-off-by: Babak K. Shandiz <[email protected]>
Signed-off-by: Babak K. Shandiz <[email protected]>
Signed-off-by: Babak K. Shandiz <[email protected]>
46d3307
to
49eddf5
Compare
I made the following changes and published v0.6.1 of the linter:
And here are the changes I (force) pushed to this PR branch:
|
b6d29e1
to
ededae2
Compare
ededae2
to
8c6788a
Compare
As an improvement of the linter, I think some messages can be more precise. ex: // Foo is a thing.
type Bar struct {} Current message:
Maybe something like that:
|
Good point, and I like the nicer message. I'll make a release for it and rebase this PR. Thanks for the feedback. 🙏 |
Please don't rebase.
|
From my experience, when users don't understand a report:
Report messages are as critical as good defaults for the adoption of a linter. I recommend reviewing the report messages to ensure they are easily understandable by Go newcomers and non-native English speakers. example:
This is confusing because the problem is related to a line inside the godoc and not the godoc by itself. |
Valuable insight, @ldez! With that I'll review the report messages and will come back with a new release. I was leaning toward short messages, but the cost of losing adoption due to this is a real thing that I would never have thought. Thanks again! ✌️ |
Finally someone did it! Related to |
It doesn't verify links, but it verifies that links are used. |
@ldez is right. But checking for valid links is on my list of todos. |
Signed-off-by: Babak K. Shandiz <[email protected]>
I just pushed the changes to issue messages. You can see godoc-lint/godoc-lint#33 for an overvall look. |
I don't have the answers, but I wonder if a godoc starting with https://go.dev/doc/comment#deprecations
// My constants.
const (
A = "A"
B = "B"
C = "C"
// Deprecated: use A instead.
D = "D"
) Same thing on notes (at least on non-exported symbols): // TODO(user1): refactor to use standard library context
// BUG(user2): not cleaned up
var ctx context.Context This is not blocking from the POV of golangci-lint, this is only some questions. |
The Anyway, definitely both use cases are on my list, and yeah, they're not seem like blockers. |
Maybe you can create one or several issues to expose what is on your list. |
Good point. I'll create one issue for each for now to cover the ideas so far. |
The new message of // Foo is a thing.
type Bar struct {} start-with-name:
pattern: "GODOC %"
I think the message is right in 99% of cases, but the problem is maybe the option |
I found the previous problem, because I dug a bit more about I wanted to quickly hack around the topic by modifying the pattern |
I think I already have a fix for the Regarding the pattern thing, I think I can modify the report message to be different based on the configured pattern. I'll push a commit when I'm done with the fix. Probably tomorrow. |
I think the |
A pattern is needed, because as of the godoc reference godocs should start with a complete senetence, which is okay to start with an article, for example. But I'm not sure there's a point in making the pattern configurable. 🤔 |
This PR adds
godoclint
to available linters (godoc-lint/godoc-lint
).Godoc-Lint is a little opinionated linter for Go documentation practice.
About the linter
Godoc-Lint is a linter for godocs, applying the rules set by the Go team in Go Doc Comments blog post. I made Godoc-Lint as a small/encapsulated linter to enforce best practices around godocs. There might be other linters that support some of the Godoc-Lint rules, but I couldn't find one single linter encompassing them all. The linter is rather new, but is already used in a few projects, including
googleapis/librarian
,googleapis/google-cloud-rust
, and a few others, where it's being used outside of the golang-lint suite. That's why I decided it makes sense for the linter to be integrated with golangci-lint as the current industry standard. More about the linter and its rules can be found in the repo'sREADME.md
file.Integration
I made sure the linter satisfies all technical criteria on the checklist (e.g. no panics, CI tests, etc). The current latest version,
v0.5.0
has been released for this purpose. Note thatos.Exit
has been used a couple of times in thecmd/main
package of the linter. That package is the CLI binary entrypoint and is not reachable through the integration with golangci-lint.Regarding the tests, there are exhaustive tests in the linter's repo, which seemed too much to be duplicated in here in golangci-lint. Instead I added a minimal set of test cases to assert certain aspects of the integration (e.g. default config behaviour, or configuration mapping). However, I couldn't find a decent, already implemented way of package-wide testing. There's this specific rule, named
single-pkg-doc
, that needs to check all files in a Go package to make sure only one of thepackage
statements has godoc, if any. That specific rule is not covered by the tests in this PR.Also, as pointed out in the checklist, the test files include an stdlib import. I'm not sure if it's the same reason, but during early days of developing the linter I noticed
go/analysis
iterates over all imported packages, and therefore I had to make the linter automatically exclude those packages to ensure it stays within the codebase.Regarding the default configuration, the linter has a sensible set of defaults that makes it usable out of the box while bringing value.