Top Related Projects
Fast linters runner for Go
🔥 ~6x faster, stricter, configurable, extensible, and beautiful drop-in replacement for golint
Staticcheck - The advanced Go linter
Go security checker
errcheck checks that you checked errors.
Quick Overview
Gometalinter is a tool that concurrently runs a collection of Go linters and normalizes their output. It's designed to be fast, easy to use, and customizable, allowing developers to maintain code quality and consistency across Go projects.
Pros
- Runs multiple linters concurrently, significantly reducing overall execution time
- Provides a unified output format for all linters, making it easier to parse and integrate with various tools
- Highly customizable, allowing users to enable/disable specific linters and set custom configurations
- Supports vendored dependencies and can be easily integrated into CI/CD pipelines
Cons
- The project is no longer actively maintained (as of 2019)
- Some linters may have conflicting rules or produce false positives
- Can be resource-intensive when running on large codebases
- Initial setup and configuration may be complex for beginners
Getting Started
To install gometalinter, run:
go get -u github.com/alecthomas/gometalinter
gometalinter --install
To run gometalinter on your project:
gometalinter ./...
To customize the linters and their settings, create a configuration file named .gometalinter.json
in your project root:
{
"Enable": ["vet", "golint", "gocyclo"],
"Deadline": "2m",
"Sort": ["linter", "severity", "path", "line"],
"Exclude": ["vendor"]
}
Then run gometalinter with the config file:
gometalinter --config=.gometalinter.json ./...
Competitor Comparisons
Fast linters runner for Go
Pros of golangci-lint
- Significantly faster execution time, especially for large codebases
- Supports running multiple linters concurrently
- Provides more customization options and configuration flexibility
Cons of golangci-lint
- May have a steeper learning curve due to more complex configuration
- Some users report occasional false positives or inconsistent results
Code Comparison
gometalinter configuration:
linters:
enable:
- gofmt
- golint
- vet
golangci-lint configuration:
linters:
enable:
- gofmt
- golint
- govet
fast: true
Both tools allow for similar linter configurations, but golangci-lint offers more advanced options like the fast
setting for improved performance.
golangci-lint generally provides a more modern and actively maintained solution for Go code linting, with better performance and a wider range of features. However, gometalinter may still be preferred by some users for its simplicity and established track record. The choice between the two often depends on project requirements and personal preferences.
🔥 ~6x faster, stricter, configurable, extensible, and beautiful drop-in replacement for golint
Pros of Revive
- Faster execution due to concurrent linting and better resource management
- More customizable with a flexible rule configuration system
- Actively maintained and regularly updated
Cons of Revive
- Fewer built-in linters compared to Gometalinter
- May require more initial setup and configuration
- Less widespread adoption in the Go community
Code Comparison
Revive configuration example:
ignoreGeneratedHeader = false
severity = "warning"
confidence = 0.8
errorCode = 1
warningCode = 0
[rule.blank-imports]
[rule.context-as-argument]
[rule.context-keys-type]
[rule.dot-imports]
[rule.error-return]
Gometalinter configuration example:
linters:
enable:
- deadcode
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- typecheck
- unused
disable:
- dupl
- gocyclo
- golint
Both tools offer configuration options, but Revive's approach is more granular and flexible, allowing for fine-tuned control over individual rules.
Staticcheck - The advanced Go linter
Pros of go-tools
- More focused on static analysis tools specifically for Go
- Regularly updated and maintained
- Provides a comprehensive set of individual analyzers
Cons of go-tools
- Requires more setup and configuration compared to gometalinter
- Less integrated out-of-the-box experience
- May have a steeper learning curve for beginners
Code Comparison
gometalinter:
package main
import (
"github.com/alecthomas/gometalinter"
)
func main() {
gometalinter.Install()
gometalinter.Run()
}
go-tools:
package main
import (
"golang.org/x/tools/go/analysis/multichecker"
"honnef.co/go/tools/staticcheck"
)
func main() {
multichecker.Main(
staticcheck.Analyzers...,
)
}
The code comparison shows that gometalinter provides a more straightforward setup, while go-tools requires more specific configuration but offers greater flexibility in choosing and combining analyzers.
Go security checker
Pros of gosec
- Focused specifically on security-related issues in Go code
- Faster execution time for security-specific checks
- Integrates well with CI/CD pipelines for security scanning
Cons of gosec
- Limited to security-related checks, lacking broader code quality analysis
- Fewer customization options compared to gometalinter
- May require additional tools for comprehensive code analysis
Code Comparison
gosec:
package main
import (
"github.com/securego/gosec/v2"
"github.com/securego/gosec/v2/rules"
)
func main() {
analyzer := gosec.NewAnalyzer(rules.NewRuleSet(), nil)
// ... (usage continues)
}
gometalinter:
package main
import (
"github.com/alecthomas/gometalinter"
)
func main() {
m := gometalinter.NewLinter()
m.Install()
// ... (usage continues)
errcheck checks that you checked errors.
Pros of errcheck
- Focused specifically on error checking, providing in-depth analysis
- Lightweight and fast, with minimal setup required
- Can be easily integrated into existing workflows or CI/CD pipelines
Cons of errcheck
- Limited scope compared to gometalinter's comprehensive linting capabilities
- Doesn't offer the same level of customization and configuration options
- Lacks the ability to run multiple linters concurrently
Code Comparison
errcheck:
err := someFunction()
if err != nil {
return err
}
gometalinter:
// gometalinter runs multiple linters, including errcheck
// No specific code example, as it's a meta-linter
Summary
errcheck is a specialized tool focusing solely on error checking in Go code. It's lightweight and easy to use but lacks the comprehensive linting capabilities of gometalinter. gometalinter, on the other hand, offers a wider range of linting options and can run multiple linters concurrently, including errcheck. While errcheck is excellent for projects that prioritize error handling, gometalinter provides a more holistic approach to code quality analysis.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Go Meta Linter
gometalinter is DEPRECATED and the project will be archived on 2019-04-07. See #590 for discussion.
Switch to golangci-lint.
- Installing
- Editor integration
- Supported linters
- Configuration file
- Comment directives
- Quickstart
- FAQ
- Checkstyle XML format
The number of tools for statically checking Go source for errors and warnings is impressive.
This is a tool that concurrently runs a whole bunch of those linters and normalises their output to a standard format:
<file>:<line>:[<column>]: <message> (<linter>)
eg.
stutter.go:9::warning: unused global variable unusedGlobal (varcheck)
stutter.go:12:6:warning: exported type MyStruct should have comment or be unexported (golint)
It is intended for use with editor/IDE integration.
Installing
Binary Releases
To install the latest stable release:
curl -L https://git.io/vp6lP | sh
Alternatively you can install a specific version from the releases list.
Homebrew
brew tap alecthomas/homebrew-tap
brew install gometalinter
Editor integration
- SublimeLinter plugin.
- Atom go-plus package.
- Emacs Flycheck checker.
- Go for Visual Studio Code.
- GoLand File Watcher.
- Vim/Neovim
Supported linters
- go vet - Reports potential errors that otherwise compile.
- go tool vet --shadow - Reports variables that may have been unintentionally shadowed.
- gotype - Syntactic and semantic analysis similar to the Go compiler.
- gotype -x - Syntactic and semantic analysis in external test packages (similar to the Go compiler).
- deadcode - Finds unused code.
- gocyclo - Computes the cyclomatic complexity of functions.
- golint - Google's (mostly stylistic) linter.
- varcheck - Find unused global variables and constants.
- structcheck - Find unused struct fields.
- maligned - Detect structs that would take less memory if their fields were sorted.
- errcheck - Check that error return values are used.
- staticcheck - Statically detect bugs, both obvious and subtle ones.
- dupl - Reports potentially duplicated code.
- ineffassign - Detect when assignments to existing variables are not used.
- interfacer - Suggest narrower interfaces that can be used.
- unconvert - Detect redundant type conversions.
- goconst - Finds repeated strings that could be replaced by a constant.
- gosec - Inspects source code for security problems by scanning the Go AST.
Disabled by default (enable with --enable=<linter>
):
- testify - Show location of failed testify assertions.
- test - Show location of test failures from the stdlib testing module.
- gofmt -s - Checks if the code is properly formatted and could not be further simplified.
- goimports - Checks missing or unreferenced package imports.
- gochecknoinits - Report init functions, to reduce side effects in code.
- gochecknoglobals - Report global vars, to reduce side effects in code.
- lll - Report long lines (see
--line-length=N
). - misspell - Finds commonly misspelled English words.
- nakedret - Finds naked returns.
- unparam - Find unused function parameters.
- safesql - Finds potential SQL injection vulnerabilities.
Additional linters can be added through the command line with --linter=NAME:COMMAND:PATTERN
(see below).
Configuration file
gometalinter now supports a JSON configuration file called .gometalinter.json
that can
be placed at the root of your project. The configuration file will be automatically loaded
from the working directory or any parent directory and can be overridden by passing
--config=<file>
or ignored with --no-config
. The format of this file is determined by
the Config
struct in config.go.
The configuration file mostly corresponds to command-line flags, with the following exceptions:
- Linters defined in the configuration file will overlay existing definitions, not replace them.
- "Enable" defines the exact set of linters that will be enabled (default
linters are disabled).
--help
displays the list of default linters with the exact names you must use.
Here is an example configuration file:
{
"Enable": ["deadcode", "unconvert"]
}
If a .gometalinter.json
file is loaded, individual options can still be overridden by
passing command-line flags. All flags are parsed in order, meaning configuration passed
with the --config
flag will override any command-line flags passed before and be
overridden by flags passed after.
Format
key
The default Format
key places the different fields of an Issue
into a template. this
corresponds to the --format
option command-line flag.
Default Format
:
Format: "{{.Path}}:{{.Line}}:{{if .Col}}{{.Col}}{{end}}:{{.Severity}}: {{.Message}} ({{.Linter}})"
Format Methods
{{.Path.Relative}}
- equivalent to{{.Path}}
which outputs a relative path to the file{{.Path.Abs}}
- outputs an absolute path to the file
Adding Custom linters
Linters can be added and customized from the config file using the Linters
field.
Linters supports the following fields:
Command
- the path to the linter binary and any default argumentsPattern
- a regular expression used to parse the linter outputIsFast
- if the linter should be run when the--fast
flag is usedPartitionStrategy
- how paths args should be passed to the linter command:directories
- call the linter once with a list of all the directoriesfiles
- call the linter once with a list of all the filespackages
- call the linter once with a list of all the package pathsfiles-by-package
- call the linter once per package with a list of the files in the package.single-directory
- call the linter once per directory
The config for default linters can be overridden by using the name of the linter.
Additional linters can be configured via the command line using the format
NAME:COMMAND:PATTERN
.
Example:
$ gometalinter --linter='vet:go tool vet -printfuncs=Infof,Debugf,Warningf,Errorf:PATH:LINE:MESSAGE' .
Comment directives
gometalinter supports suppression of linter messages via comment directives. The form of the directive is:
// nolint[: <linter>[, <linter>, ...]]
Suppression works in the following way:
-
Line-level suppression
A comment directive suppresses any linter messages on that line.
eg. In this example any messages for
a := 10
will be suppressed and errcheck messages fordefer r.Close()
will also be suppressed.a := 10 // nolint a = 2 defer r.Close() // nolint: errcheck
-
Statement-level suppression
A comment directive at the same indentation level as a statement it immediately precedes will also suppress any linter messages in that entire statement.
eg. In this example all messages for
SomeFunc()
will be suppressed.// nolint func SomeFunc() { }
Implementation details: gometalinter now performs parsing of Go source code, to extract linter directives and associate them with line ranges. To avoid unnecessary processing, parsing is on-demand: the first time a linter emits a message for a file, that file is parsed for directives.
Quickstart
Install gometalinter (see above).
Run it:
$ cd example
$ gometalinter ./...
stutter.go:13::warning: unused struct field MyStruct.Unused (structcheck)
stutter.go:9::warning: unused global variable unusedGlobal (varcheck)
stutter.go:12:6:warning: exported type MyStruct should have comment or be unexported (golint)
stutter.go:16:6:warning: exported type PublicUndocumented should have comment or be unexported (golint)
stutter.go:8:1:warning: unusedGlobal is unused (deadcode)
stutter.go:12:1:warning: MyStruct is unused (deadcode)
stutter.go:16:1:warning: PublicUndocumented is unused (deadcode)
stutter.go:20:1:warning: duplicateDefer is unused (deadcode)
stutter.go:21:15:warning: error return value not checked (defer a.Close()) (errcheck)
stutter.go:22:15:warning: error return value not checked (defer a.Close()) (errcheck)
stutter.go:27:6:warning: error return value not checked (doit() // test for errcheck) (errcheck)
stutter.go:29::error: unreachable code (vet)
stutter.go:26::error: missing argument for Printf("%d"): format reads arg 1, have only 0 args (vet)
Gometalinter also supports the commonly seen <path>/...
recursive path
format. Note that this can be very slow, and you may need to increase the linter --deadline
to allow linters to complete.
FAQ
Exit status
gometalinter sets two bits of the exit status to indicate different issues:
Bit | Meaning |
---|---|
0 | A linter generated an issue. |
1 | An underlying error occurred; eg. a linter failed to execute. In this situation a warning will also be displayed. |
eg. linter only = 1, underlying only = 2, linter + underlying = 3
What's the best way to use gometalinter
in CI?
There are two main problems running in a CI:
Linters break, causing(this is no longer an issue as all linters are vendored).gometalinter --install --update
to errorgometalinter
adds a new linter.
I have solved 1 by vendoring the linters.
For 2, the best option is to disable all linters, then explicitly enable the ones you want:
gometalinter --disable-all --enable=errcheck --enable=vet --enable=vetshadow ...
How do I make gometalinter
work with Go 1.5 vendoring?
gometalinter
has a --vendor
flag that just sets GO15VENDOREXPERIMENT=1
, however the
underlying tools must support it. Ensure that all of the linters are up to date and built with Go 1.5
(gometalinter --install --force
) then run gometalinter --vendor .
. That should be it.
Why does gometalinter --install
install a fork of gocyclo?
I forked gocyclo
because the upstream behaviour is to recursively check all
subdirectories even when just a single directory is specified. This made it
unusably slow when vendoring. The recursive behaviour can be achieved with
gometalinter by explicitly specifying <path>/...
. There is a
pull request open.
Many unexpected errors are being reported
If you see a whole bunch of errors being reported that you wouldn't expect,
such as compile errors, this typically means that something is wrong with your
Go environment. Try go install
and fix any issues with your go installation,
then try gometalinter again.
Gometalinter is not working
That's more of a statement than a question, but okay.
Sometimes gometalinter will not report issues that you think it should. There are three things to try in that case:
1. Update to the latest build of gometalinter and all linters
curl -L https://git.io/vp6lP | sh
If you're lucky, this will fix the problem.
2. Analyse the debug output
If that doesn't help, the problem may be elsewhere (in no particular order):
- Upstream linter has changed its output or semantics.
- gometalinter is not invoking the tool correctly.
- gometalinter regular expression matches are not correct for a linter.
- Linter is exceeding the deadline.
To find out what's going on run in debug mode:
gometalinter --debug
This will show all output from the linters and should indicate why it is failing.
3. Report an issue.
Failing all else, if the problem looks like a bug please file an issue and
include the output of gometalinter --debug
.
How do I filter issues between two git refs?
revgrep can be used to filter the output of gometalinter
to show issues on lines that have changed between two git refs, such as unstaged changes, changes in
HEAD
vs master
and between master
and origin/master
. See the project's documentation and -help
usage for more information.
go get -u github.com/bradleyfalzon/revgrep/...
gometalinter |& revgrep # If unstaged changes or untracked files, those issues are shown.
gometalinter |& revgrep # Else show issues in the last commit.
gometalinter |& revgrep master # Show issues between master and HEAD (or any other reference).
gometalinter |& revgrep origin/master # Show issues that haven't been pushed.
Checkstyle XML format
gometalinter
supports checkstyle
compatible XML output format. It is triggered with --checkstyle
flag:
gometalinter --checkstyle
Checkstyle format can be used to integrate gometalinter with Jenkins CI with the help of Checkstyle Plugin.
Top Related Projects
Fast linters runner for Go
🔥 ~6x faster, stricter, configurable, extensible, and beautiful drop-in replacement for golint
Staticcheck - The advanced Go linter
Go security checker
errcheck checks that you checked errors.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot