Skip to content

Commit

Permalink
"//nolint:nit" directive support
Browse files Browse the repository at this point in the history
It allows skipping a whole file that includes the following line:

//nolint:nit

This is useful for allowing some tools to properly work, for example
go-swagger, to generate code not using grouped types.
  • Loading branch information
MarioCarrion committed Oct 15, 2019
1 parent bfd7790 commit 9b9f871
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 14 deletions.
17 changes: 15 additions & 2 deletions break_comments.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,33 @@ type (
index int
comments []int
generatedFile bool
nolintNit bool
}
)

const (
breakComment = "//-"
generatedFile = `^// Code generated .* DO NOT EDIT\.$`
nitLinter = "^//nolint:nit$"
)

// NewBreakComments returns all the valid break-like comments.
func NewBreakComments(fset *token.FileSet, comments []*ast.CommentGroup) *BreakComments {
r := BreakComments{}

re, _ := regexp.Compile(generatedFile)
regen, _ := regexp.Compile(generatedFile)
renit, _ := regexp.Compile(nitLinter)

for _, c := range comments {
for _, c1 := range c.List {
if re.MatchString(c1.Text) {
if regen.MatchString(c1.Text) {
r.generatedFile = true
}

if renit.MatchString(c1.Text) {
r.nolintNit = true
}

if strings.HasPrefix(c1.Text, breakComment) {
position := fset.PositionFor(c1.Pos(), false)
if position.Column == 1 || position.Column == 2 { // left most either nested or not nested group declarations
Expand All @@ -51,6 +58,12 @@ func (c *BreakComments) HasGeneratedCode() bool {
return c.generatedFile
}

// HasNoLintNit indicates whether the current file contains a "do not lint nit"
// expression.
func (c *BreakComments) HasNoLintNit() bool {
return c.nolintNit
}

// Moves current line cursor to the received line.
func (c *BreakComments) MoveTo(line int) {
if c.index >= len(c.comments) {
Expand Down
37 changes: 25 additions & 12 deletions break_comments_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,31 @@ import (
)

func TestBreakComments(t *testing.T) {
type expected struct {
result []int
generatedCode bool
noLintNit bool
}

tests := [...]struct {
name string
filename string
expected []int
expectedCodegenerated bool
name string
filename string
expected expected
}{
{
"OK",
"break_comments1.go",
[]int{8, 13, 19},
false,
expected{result: []int{8, 13, 19}},
},
{
"OK: code generated",
"break_comments2.go",
nil,
true,
expected{generatedCode: true},
},
{
"OK: nolint nit",
"break_comments3.go",
expected{noLintNit: true},
},
}

Expand All @@ -36,7 +44,7 @@ func TestBreakComments(t *testing.T) {
var actual []int

bc := nit.NewBreakComments(fset, f.Comments)
for _, v := range tt.expected {
for _, v := range tt.expected.result {
bc.MoveTo(v)
v = bc.Next()
if v == -1 {
Expand All @@ -45,11 +53,16 @@ func TestBreakComments(t *testing.T) {
actual = append(actual, v)
}

if !cmp.Equal(tt.expected, actual) {
if !cmp.Equal(tt.expected.result, actual) {
ts.Errorf("expected values do not match: %s", cmp.Diff(tt.expected, actual))
}
if tt.expectedCodegenerated != bc.HasGeneratedCode() {
ts.Errorf("expected %t, got %t", tt.expectedCodegenerated, bc.HasGeneratedCode())

if tt.expected.generatedCode != bc.HasGeneratedCode() {
ts.Errorf("expected %t, got %t", tt.expected.generatedCode, bc.HasGeneratedCode())
}

if tt.expected.noLintNit != bc.HasNoLintNit() {
ts.Errorf("expected %t, got %t", tt.expected.noLintNit, bc.HasNoLintNit())
}
})
}
Expand Down
2 changes: 2 additions & 0 deletions cmd/nit/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func main() {

localPkg := flag.String("pkg", "", "local package")
skipGenerated := flag.Bool("skip-generated", false, "skip generated files")
nolint := flag.Bool("nolint", false, "enable nolint directive")
includeTests := flag.Bool("include-tests", false, "include test files")
showVersion := flag.Bool("version", false, "prints current version information")

Expand Down Expand Up @@ -57,6 +58,7 @@ func main() {
v := nit.Nitpicker{
LocalPath: *localPkg,
SkipGeneratedFile: *skipGenerated,
NoLint: *nolint,
}

if err := v.Validate(f); err != nil {
Expand Down
5 changes: 5 additions & 0 deletions nitpicking.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type (
Nitpicker struct {
LocalPath string
SkipGeneratedFile bool
NoLint bool
//-
fset *token.FileSet
fsm *FileSectionMachine
Expand All @@ -37,6 +38,10 @@ func (v *Nitpicker) Validate(filename string) error {
return nil
}

if v.comments.HasNoLintNit() && v.NoLint {
return nil
}

for _, s := range f.Decls {
if err := v.validateToken(s); err != nil {
return err
Expand Down
9 changes: 9 additions & 0 deletions testdata/break_comments3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package testdata

func NewBreakCommentType3() {}

//nolint:nit

type BreakCommentType3_1 int

//-

0 comments on commit 9b9f871

Please sign in to comment.