Refactor nolintlint handling: Enforce directive and linter list formatting #4543
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The rationale for this PR is to enforce the formatting of the spacing in the nolint directive via the nolintlint linter. The syntax of a Go directive should roughly conform to the following format: ^[a-z]+:[a-z]+. For nolint directive comments that have leading whitespace, the nolintlint linter currently gives a warning of the form “directive
// nolint: lll // ignore line length warningsshould be written without leading space as//nolint: lll // ignore line length warnings", when it should actually suggest//nolint:lll // ignore line length warnings(with no space between nolint: and lll) instead. Broadly, this PR makes the nolintlint warnings more strictly conform to the syntax of a Go directive and avoids providing inaccurate suggestions such as the aforementioned. This should reduce confusion for developers and should make it easier to conform to the requirements of go fmt as of go1.19.Change list:
directiveWithOptionalLeadingSpacefield - leading spaces in the directive are no longer allowed as of go1.19, so the directive will now always be//nolint. It cannot be any directive other thannolint(e.g.,go:generate) due to the guarantee provided by matching the comment against thecommentPatternregular expression in theRunfunction. Therefore, we can just hardcode//nolintas the directive. (The directive, as the term is generally used in Go, could be something like//nolint:lllor//nolint:allwith a colon and specific linter(s) afternolint, but thedirectiveWithOptionalLeadingSpacevariable would not currently include the optional colon and anything following it, so for the purposes of this field, the directive will always be//nolint).fullDirectivePatternto disallow spaces in the linter list. The updated regular expression also disallows spaces at the beginning of the string in order to avoid providing an error message that could potentially contain an inaccurate suggestion for how to update thenolintdirective, as would have previously been done by theNotMachineissue. The regular expression continues to allow empty explanation comments because they will be caught by theNoExplanationissue if theNeedsExplanationflag is set.BaseIssuestruct, since it should not be used outside nolintlint.go.NeedsMachineOnlyand remove all references in code.NotMachineissue, since it has been superseded by theParserError, which gives a more accurate error message (specifically, it does not provide a suggestion for how to update thenolintdirective that could potentially still have spaces in the linter list, but rather a more generic suggestion of the format of a well-formednolintcomment).NoExplanationdetails to provide a generic directive template rather than a specific suggestion; update unit tests accordingly. Similar to the previous bullet point, this avoids inadvertently providing an inaccurate error message.//nolint:gocriticcomments.NotMachineissue to reflect that they now result in theParseErrorissue instead.directiveWithOptionalLeadingSpacevalues not equal to//nolintor// nolint(namely,directiveWithOptionalLeadingSpacevalues containing additional characters after the directive, such as//nolint / description).