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

Add ability to ignore faillint problems #11

Merged
merged 12 commits into from
Mar 14, 2020
Merged

Add ability to ignore faillint problems #11

merged 12 commits into from
Mar 14, 2020

Conversation

nnutter
Copy link
Contributor

@nnutter nnutter commented Mar 7, 2020

Linter directive is based on staticcheck.

For: #6

For example,

```go
//lint:file-ignore faillint This file should be ignored by faillint.
Copy link
Owner

Choose a reason for hiding this comment

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

Does it have to be on top of the package keyword or does it not matter where we put this line? I think mentioning this in the readme is important to make it clear.

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 test coverage and update docs accordingly. I believe postfix comment will work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Postfix did not work as it was but it has been updated so that it does.

return false
}

func commentHasIgnoreDirective(c *ast.Comment) bool {
Copy link
Owner

Choose a reason for hiding this comment

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

Better name: hasLineIgnore. But I'm not sure we need this function at all. I think it's better if we just inline them. There is now too much indirections and we jump quite around.

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 think the indirection and jumping around has been addressed; there are now only three new functions.

return false
}

func commentGroupsHaveIgnoreDirective(gs []*ast.CommentGroup) bool {
Copy link
Owner

Choose a reason for hiding this comment

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

commentsIgnored I think is a shorter name, let's use that.

}
}
return false
}
Copy link
Owner

Choose a reason for hiding this comment

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

I think both fileIsIgnored and usageIsIgnored can be combined into a single funtion, such as:

func IsIgnored(cm *ast.CommentGroup, option string) bool {
 	if cm == nil {
 		return false
 	}
 	for _, comment := range cm.List {
 		cmd, args := parseDirective(comment.Text)
 		if cmd == option && len(args) > 0 && args[0] == "faillint" {
 			return true
 		}
 	}
 	return false
 }

and then use it like:

isIgnored(file.Doc, "file-ignore)

or

isIgnored(spec.Doc, "ignore")

This also means we can get rid of commentHasIgnoreDirective

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As I switched to this style I felt like the function should not have ignore in the name because it could technically be more broad and because it stuttered. I did shorten the names but because of this deviated from your suggestions. Please, of course, let me know what you think of the names once you see it in its new form.

@fatih
Copy link
Owner

fatih commented Mar 8, 2020

Thank you @nnutter. Added add some initial comments so you can go over them.

@fatih
Copy link
Owner

fatih commented Mar 8, 2020

Also now that I think, I wonder if we should use faillint:ignore reason and faillint:file-ignore rason syntax. I'm not sure using statichecks's syntax make sense. People would assume it belongs to staticcheck even if it's not.

Linter directive is based on staticcheck.
README.md Outdated

#### File-based linter directives

File-based linter directives can be applied to ignore `faillint` problems in a whole file. The format is,
Copy link
Owner

Choose a reason for hiding this comment

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

Can you add a comment that the ignore directive has to be before the package keyword? Or is there any other case that would also work?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added clarification; in 3986017. If you want it anywhere in the file that can be done but it's probably better to keep it limited to the package docs.

const (
ignore = "ignore"
fileignore = "file-ignore"
)
Copy link
Owner

Choose a reason for hiding this comment

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

Can you move them to the top of the file? Also I think documenting them and naming them in a more descriptive way would be better. Such as: ignoreKeyE and fileIgnoreKey

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored now; in 08c1050.

README.md Outdated
### Ignoring problems

If you want to ignore a problem reported by `faillint` you can add a linter directive.
The format of a directive is based on the format other linters, such as `staticcheck`, use and there are two types: line-based and file-based.
Copy link
Owner

Choose a reason for hiding this comment

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

I think this line is not applicable anymore and can be removed.

Copy link
Contributor Author

@nnutter nnutter Mar 9, 2020

Choose a reason for hiding this comment

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

Removed now; in 1c0756d.

s = strings.TrimPrefix(s, "//faillint:")
fields := strings.Split(s, " ")
return fields[0]
}
Copy link
Owner

Choose a reason for hiding this comment

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

I think we should check for the reason as well. And reason should be MUST have. Most of the time people add these lines and later if someone reads it they don't have an idea why it's added. Hence we should make sure it's required. I think staticcheck does also require reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Checked now; in c11afeb.

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 also added a check for out-of-place file-ignore options; in 01ca523.

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 both cases adding a test was not possible in the current framework because adding a // want comment negates the test conditions. I wanted to check with you before trying anything else. Do you want to create a ResultType and return something from run()? Maybe a struct with a slice of analysis.Diagnostic? If so do you want all the existing tests converted to use that? Of course, any other ideas? Maybe I'm overlooking something simple?

Manual testing,

$ go run . -paths errors ./faillint/testdata/src/n 
/Users/nnutter/src/github.com/nnutter/faillint/faillint/testdata/src/n/n.go:4:2: missing reason on faillint directive
exit status 3
                                                                                                                                                      (master)faillint 17:44:59 1
[1181] github.com/nnutter/faillint $ go run . -paths errors ./faillint/testdata/src/o
/Users/nnutter/src/github.com/nnutter/faillint/faillint/testdata/src/o/o.go:4:2: file-ignore option on faillint directive must be in package docs
/Users/nnutter/src/github.com/nnutter/faillint/faillint/testdata/src/o/o.go:5:2: package "errors" shouldn't be imported
exit status 3

Copy link
Owner

Choose a reason for hiding this comment

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

I think we should have a TestParseDirective that tests the parseDirective function. And then you can check for various parse directives and I think that would be sufficient for our needs.

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 merged our two ideas together. =)

Copy link
Owner

Choose a reason for hiding this comment

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

Thanks, this is much better 👍

@nnutter nnutter requested a review from fatih March 9, 2020 23:03
@dominikh
Copy link

Also now that I think, I wonder if we should use faillint:ignore reason and faillint:file-ignore rason syntax. I'm not sure using statichecks's syntax make sense. People would assume it belongs to staticcheck even if it's not.

FWIW, I designed staticcheck's syntax in the hope that other projects would adopt it, too. It's why staticcheck doesn't flag unknown check names in directives, and why I chose a prefix as generic as lint:, as opposed to, say, sc:.

Copy link
Owner

@fatih fatih left a comment

Choose a reason for hiding this comment

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

@nnutter thanks a lot for all the work. This looks great right now, I added couple of comments for further improvements. I know this took longer than anticipated, but once merged it'll be maintained as long as this project is active, so I want to make sure things are right from the beginning

One last second, after talking to @dominikh, seems like using //lint, just like staticcheck, would be better in the long term. I know you did initially and I hope it's not a big issue changing it.

Once we wrap it all, we're good to go.

README.md Outdated
//faillint:file-ignore reason
```

This must be placed in the `package` docs and, conventionally, these comments should be placed near the top of the file.
Copy link
Owner

Choose a reason for hiding this comment

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

I think people might get confused on what package docs means here. Maybe writing it simpler would be better, such as This must be placed above the package keyword, near the top of the file. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Problem was it did have to be attached to the package comment/docs. However, I agree that's confusing and probably not really correct/ideal. I'll loosen it to search all comments in the file and then the phrase can be, "This may be placed anywhere in the file but conventionally it should be placed at or near the top of the file."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 868a3ea.

s = strings.TrimPrefix(s, "//faillint:")
fields := strings.Split(s, " ")
return fields[0]
}
Copy link
Owner

Choose a reason for hiding this comment

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

Thanks, this is much better 👍

out: false,
message: fmt.Sprintf(unexpectedFileIgnoreTemplate, "file-ignore"),
},
},
Copy link
Owner

Choose a reason for hiding this comment

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

I think it would be nice to have also cases with reason and are valid so we can see it works for those as well. Right now seems like we only check for failures but not for successes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We were covering success in the "integration tests" but it's trivial to add valid cases here and I will do so.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 33d8aa8.

@nnutter nnutter requested a review from fatih March 13, 2020 01:06
@nnutter
Copy link
Contributor Author

nnutter commented Mar 13, 2020

One last second, after talking to @dominikh, seems like using //lint, just like staticcheck, would be better in the long term. I know you did initially and I hope it's not a big issue changing it.

Done in 1151d6a.

@nnutter
Copy link
Contributor Author

nnutter commented Mar 13, 2020

I know this took longer than anticipated, but once merged it'll be maintained as long as this project is active, so I want to make sure things are right from the beginning

I totally understand. From my perspective I appreciate your response time and that we are getting an iteration done something like every 24 hours.

@fatih fatih merged commit 3992f98 into fatih:master Mar 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants