Using linters improves readability by highlighting problems before they are executed, and it helps with the standardization of your codebase. A good linter has configuration settings that help to lessen warnings for rules you don’t care about, making code easier to comprehend, modify, and maintain.
In this article, we’ll be learning more about linting through these topics:
golint has been the most widely used linter for Go over the years. Unfortunately, it is now officially deprecated and archived. The issue with golint is that it doesn’t offer any configuration options and always applies all the rules, which leads to warnings for rules you don’t care about. In this article, we’ll use the revive package as well as exploring alternative go linting packages.
Conversely, revive is a fast, configurable, extensible, adaptable, and beautiful linter for Go. It serves as golint’s drop-in replacement.
Here’s how revive is different from golint:
- Allows us to enable or disable rules using a configuration file
- Allows us to configure the linting rules with a TOML file
- Is two times faster running the same rules as golint
- Provides functionality for disabling a specific rule or the entire linter for a file or a range of lines (golint allows this only for generated files)
- Optional type checking. Most rules in golint do not require type checking. If you disable them in the config file, revive will run over six times faster than golint
- Provides multiple formatters that let us customize the output
- Allows us to customize the return code for the entire linter or based on the failure of only some rules
- Everyone can extend it easily with custom rules or formatters
- revive provides more rules compared to golint
Setting up a project with revive
Open a terminal and create a project folder. Navigate to the project folder and run the following command to start a new project:
go mod init project
Navigate to your Go project and run the following command to install the revive linter package:
go install github.com/mgechev/[email protected]
main.go file and add the following code snippet to the
package main import ( "fmt" ) func main() PrintName("Emmanuel") PrintAge(23) func PrintName(name string) fmt.Println(name) func PrintAge(age int) fmt.Println(age)
Now, run the
revive command on the project terminal and you should get the following report:
main.go:11:1: exported function PrintName should have comment or be unexported main.go:15:1: exported function PrintAge should have comment or be unexported
In Go, the first letter of an exported function is usually an uppercase. A properly documented codebase requires that exported functions be commented with a brief overview of the function’s purpose, so everyone can understand what it does. Now we can see how the revive package helps us write well-documented code.
More great articles from LogRocket:
Now, let’s add some comments to these functions:
... // This function uses the fmt.Println function to print a string. func PrintName(name string) fmt.Println(name) // This function uses the fmt.Println function to print a number. func PrintAge(age int) fmt.Println(age)
Execute the revive command and you should have the following report:
main.go:12:1: comment on exported function PrintName should be of the form "PrintName ..." main.go:17:1: comment on exported function PrintAge should be of the form "PrintAge ..."
Revive tells us that our comment should begin with the name of our exported functions for a properly documented codebase.
Let’s change our comments to the following:
... // PrintName uses the fmt.Println function to print a string. func PrintName(name string) fmt.Println(name) // PrintAge uses the fmt.Println function to print a number. func PrintAge(age int) fmt.Println(age)
With this, execute the revive command and you should have no report.
Suppressing linting errors with revive
Sometimes, it’s necessary to disable specific linting issues that appear in a file or package. Both comments and exclusion rules in the configuration file can be used to do this. Let’s examine each strategy in turn.
The comments strategy comes in handy when you want to disable warnings for a certain section of code but still want to apply the rule to other parts of the project.
Here is how to disable specific linting issues using comments:
package main import ( "fmt" ) func main() PrintName("Emmanuel") // revive:disable:exported func PrintName(name string) fmt.Println(name)
The syntax for this is
revive, followed by a colon, then
disable. If desired, add another colon followed by the name of a linter rule.
Setting up configurations for linters
This is one amazing feature of the revive linter package that address the major challenge with the popular
golint linter package.
Let’s see how to configure the revive linter package to disable some linting rules in order to reduce unnecessary warnings.
Add a file named
revive.toml to the project folder with the default
ignoreGeneratedHeader = false severity = "warning" confidence = 0.8 errorCode = 0 warningCode = 0 [rule.blank-imports] [rule.context-as-argument] [rule.context-keys-type] [rule.dot-imports] [rule.error-return] [rule.error-strings] [rule.error-naming] [rule.exported] [rule.if-return] [rule.increment-decrement] [rule.var-naming] [rule.var-declaration] [rule.package-comments] [rule.range] [rule.receiver-naming] [rule.time-naming] [rule.unexported-return] [rule.indent-error-flow] [rule.errorf] [rule.empty-block] [rule.superfluous-else] [rule.unused-parameter] [rule.unreachable-code] [rule.redefines-builtin-id]
Now, remove all comments and run the following command to use the linter with the configuration file:
revive -config revive.toml
To disable any of these rules, you can either remove them or add
# before the specified rule as follows:
Setting up linting in code editors
Some code editors support linting code automatically; Visual Studio Code is one of them.
Let’s see how to set up the revive linter in Visual Studio Code.
Open VS Code and install the
go extension for VS Code. Then, select the File tab > Preferences > Settings and add
go.lint to the search field and select revive in the Go: Lint Tool section.
The default Go linter for Visual Studio Code is
go vet command
In contrast to linters, the go vet command identifies code that compiles but probably won’t perform as intended.
Let’s consider a common self assignment bug in our Golang code. Update
main.go file as follows:
package main import ( "fmt" ) func main() PrintName("Emmanuel") // revive:disable:exported func PrintName(name string) name = name fmt.Println(name)
The above code will compile even with this bug. Executing the revive linter command won’t report any issue concerning this bug. This is where the
go vet command comes in handy.
go vet command and you should have the following result instead:
$ go vet # sample .\main.go:10:2: self-assignment of name to name
Alternative packages for linting in Go
If revive isn’t your preference, here is a list of Go linters that have been built and maintained by the community.
golangci-lint is a fast Go linters runner. It integrates with every major IDE, employs caching, enables YAML configuration, executes linters in parallel, and comes with a large number of linters.
staticcheck is a cutting-edge Go programming language linter. It employs static analysis to identify bugs and performance problems, provide simplifications, and enforce style guidelines.
Go takes documentation seriously because the easier it is for developers to produce good documentation, the better for everyone.
In this article, we’ve explored linting in Golang, my preferred linting package, and alternative packages for linting in Go. I hope you’ll like working with revive!
LogRocket: Full visibility into your web and mobile apps
LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
Try it for free.