{"id":13394004,"url":"https://github.com/alecthomas/gometalinter","last_synced_at":"2025-09-28T19:31:53.019Z","repository":{"id":19388823,"uuid":"22629932","full_name":"alecthomas/gometalinter","owner":"alecthomas","description":"DEPRECATED: Use https://github.com/golangci/golangci-lint","archived":true,"fork":false,"pushed_at":"2019-03-07T12:34:43.000Z","size":5762,"stargazers_count":3507,"open_issues_count":0,"forks_count":267,"subscribers_count":61,"default_branch":"master","last_synced_at":"2025-01-16T10:29:05.534Z","etag":null,"topics":["go","gometalinter","linter"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alecthomas.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-08-05T04:11:15.000Z","updated_at":"2025-01-08T10:41:59.000Z","dependencies_parsed_at":"2022-07-27T00:32:02.639Z","dependency_job_id":null,"html_url":"https://github.com/alecthomas/gometalinter","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fgometalinter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fgometalinter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fgometalinter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alecthomas%2Fgometalinter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alecthomas","download_url":"https://codeload.github.com/alecthomas/gometalinter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234440305,"owners_count":18832980,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","gometalinter","linter"],"created_at":"2024-07-30T17:01:05.274Z","updated_at":"2025-09-28T19:31:47.180Z","avatar_url":"https://github.com/alecthomas.png","language":"Go","readme":"# Go Meta Linter\n\n----\n\ngometalinter is **DEPRECATED** and the project will be archived on 2019-04-07. See [#590](https://github.com/alecthomas/gometalinter/issues/590) for discussion.\n\nSwitch to [golangci-lint](https://github.com/golangci/golangci-lint).\n\n----\n\n\n[![Build Status](https://travis-ci.org/alecthomas/gometalinter.svg)](https://travis-ci.org/alecthomas/gometalinter) [![Gitter chat](https://badges.gitter.im/alecthomas.svg)](https://gitter.im/alecthomas/Lobby)\n\n\u003c!-- MarkdownTOC --\u003e\n\n- [Installing](#installing)\n    - [Binary Releases](#binary-releases)\n    - [Homebrew](#homebrew)\n- [Editor integration](#editor-integration)\n- [Supported linters](#supported-linters)\n- [Configuration file](#configuration-file)\n    - [`Format` key](#format-key)\n    - [Format Methods](#format-methods)\n  - [Adding Custom linters](#adding-custom-linters)\n- [Comment directives](#comment-directives)\n- [Quickstart](#quickstart)\n- [FAQ](#faq)\n  - [Exit status](#exit-status)\n  - [What's the best way to use `gometalinter` in CI?](#whats-the-best-way-to-use-gometalinter-in-ci)\n  - [How do I make `gometalinter` work with Go 1.5 vendoring?](#how-do-i-make-gometalinter-work-with-go-15-vendoring)\n  - [Why does `gometalinter --install` install a fork of gocyclo?](#why-does-gometalinter---install-install-a-fork-of-gocyclo)\n  - [Many unexpected errors are being reported](#many-unexpected-errors-are-being-reported)\n  - [Gometalinter is not working](#gometalinter-is-not-working)\n    - [1. Update to the latest build of gometalinter and all linters](#1-update-to-the-latest-build-of-gometalinter-and-all-linters)\n    - [2. Analyse the debug output](#2-analyse-the-debug-output)\n    - [3. Report an issue.](#3-report-an-issue)\n  - [How do I filter issues between two git refs?](#how-do-i-filter-issues-between-two-git-refs)\n- [Checkstyle XML format](#checkstyle-xml-format)\n\n\u003c!-- /MarkdownTOC --\u003e\n\n\nThe number of tools for statically checking Go source for errors and warnings\nis impressive.\n\nThis is a tool that concurrently runs a whole bunch of those linters and\nnormalises their output to a standard format:\n\n    \u003cfile\u003e:\u003cline\u003e:[\u003ccolumn\u003e]: \u003cmessage\u003e (\u003clinter\u003e)\n\neg.\n\n    stutter.go:9::warning: unused global variable unusedGlobal (varcheck)\n    stutter.go:12:6:warning: exported type MyStruct should have comment or be unexported (golint)\n\nIt is intended for use with editor/IDE integration.\n\n## Installing\n\n### Binary Releases\n\nTo install the latest stable release:\n\n    curl -L https://git.io/vp6lP | sh\n\nAlternatively you can install a specific version from the [releases](https://github.com/alecthomas/gometalinter/releases) list.\n\n### Homebrew\n\n```sh\nbrew tap alecthomas/homebrew-tap\nbrew install gometalinter\n```\n\n## Editor integration\n\n- [SublimeLinter plugin](https://github.com/alecthomas/SublimeLinter-contrib-gometalinter).\n- [Atom go-plus package](https://atom.io/packages/go-plus).\n- [Emacs Flycheck checker](https://github.com/favadi/flycheck-gometalinter).\n- [Go for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=lukehoban.Go).\n- [GoLand File Watcher](https://blog.jetbrains.com/go/2017/10/18/gogland-eap-16-file-watcher-tons-of-new-inspections-smarter-navigate-to-test-and-more/).\n- Vim/Neovim\n    - [Neomake](https://github.com/neomake/neomake).\n    - [Syntastic](https://github.com/scrooloose/syntastic/wiki/Go:---gometalinter) `let g:syntastic_go_checkers = ['gometalinter']`.\n    - [ale](https://github.com/w0rp/ale) `let g:ale_linters = {'go': ['gometalinter']}`\n    - [vim-go](https://github.com/fatih/vim-go) with the `:GoMetaLinter` command.\n\n## Supported linters\n\n- [go vet](https://golang.org/cmd/vet/) - Reports potential errors that otherwise compile.\n- [go tool vet --shadow](https://golang.org/cmd/vet/#hdr-Shadowed_variables) - Reports variables that may have been unintentionally shadowed.\n- [gotype](https://golang.org/x/tools/cmd/gotype) - Syntactic and semantic analysis similar to the Go compiler.\n- [gotype -x](https://golang.org/x/tools/cmd/gotype) - Syntactic and semantic analysis in external test packages (similar to the Go compiler).\n- [deadcode](https://github.com/tsenart/deadcode) - Finds unused code.\n- [gocyclo](https://github.com/alecthomas/gocyclo) - Computes the cyclomatic complexity of functions.\n- [golint](https://github.com/golang/lint) - Google's (mostly stylistic) linter.\n- [varcheck](https://github.com/opennota/check) - Find unused global variables and constants.\n- [structcheck](https://github.com/opennota/check) - Find unused struct fields.\n- [maligned](https://github.com/mdempsky/maligned) -  Detect structs that would take less memory if their fields were sorted.\n- [errcheck](https://github.com/kisielk/errcheck) - Check that error return values are used.\n- [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) - Statically detect bugs, both obvious and subtle ones.\n- [dupl](https://github.com/mibk/dupl) - Reports potentially duplicated code.\n- [ineffassign](https://github.com/gordonklaus/ineffassign) - Detect when assignments to *existing* variables are not used.\n- [interfacer](https://github.com/mvdan/interfacer) - Suggest narrower interfaces that can be used.\n- [unconvert](https://github.com/mdempsky/unconvert) - Detect redundant type conversions.\n- [goconst](https://github.com/jgautheron/goconst) - Finds repeated strings that could be replaced by a constant.\n- [gosec](https://github.com/securego/gosec) - Inspects source code for security problems by scanning the Go AST.\n\nDisabled by default (enable with `--enable=\u003clinter\u003e`):\n\n- [testify](https://github.com/stretchr/testify) - Show location of failed testify assertions.\n- [test](http://golang.org/pkg/testing/) - Show location of test failures from the stdlib testing module.\n- [gofmt -s](https://golang.org/cmd/gofmt/) - Checks if the code is properly formatted and could not be further simplified.\n- [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports) - Checks missing or unreferenced package imports.\n- [gochecknoinits](https://4d63.com/gochecknoinits) - Report init functions, to reduce side effects in code.\n- [gochecknoglobals](https://4d63.com/gochecknoglobals) - Report global vars, to reduce side effects in code.\n- [lll](https://github.com/walle/lll) - Report long lines (see `--line-length=N`).\n- [misspell](https://github.com/client9/misspell) - Finds commonly misspelled English words.\n- [nakedret](https://github.com/alexkohler/nakedret) - Finds naked returns.\n- [unparam](https://github.com/mvdan/unparam) - Find unused function parameters.\n- [safesql](https://github.com/stripe/safesql) - Finds potential SQL injection vulnerabilities.\n\nAdditional linters can be added through the command line with `--linter=NAME:COMMAND:PATTERN` (see [below](#details)).\n\n## Configuration file\n\ngometalinter now supports a JSON configuration file called `.gometalinter.json` that can\nbe placed at the root of your project. The configuration file will be automatically loaded\nfrom the working directory or any parent directory and can be overridden by passing\n`--config=\u003cfile\u003e` or ignored with `--no-config`. The format of this file is determined by\nthe `Config` struct in [config.go](https://github.com/alecthomas/gometalinter/blob/master/config.go).\n\nThe configuration file mostly corresponds to command-line flags, with the following exceptions:\n\n- Linters defined in the configuration file will overlay existing definitions, not replace them.\n- \"Enable\" defines the exact set of linters that will be enabled (default\n  linters are disabled). `--help` displays the list of default linters with the exact names\n  you must use.\n\nHere is an example configuration file:\n\n```json\n{\n  \"Enable\": [\"deadcode\", \"unconvert\"]\n}\n```\n\nIf a `.gometalinter.json` file is loaded, individual options can still be overridden by\npassing command-line flags. All flags are parsed in order, meaning configuration passed\nwith the `--config` flag will override any command-line flags passed before and be\noverridden by flags passed after.\n\n\n#### `Format` key\n\nThe default `Format` key places the different fields of an `Issue` into a template. this\ncorresponds to the `--format` option command-line flag.\n\nDefault `Format`:\n```\nFormat: \"{{.Path}}:{{.Line}}:{{if .Col}}{{.Col}}{{end}}:{{.Severity}}: {{.Message}} ({{.Linter}})\"\n```\n\n#### Format Methods\n\n* `{{.Path.Relative}}` - equivalent to `{{.Path}}` which outputs a relative path to the file\n* `{{.Path.Abs}}` - outputs an absolute path to the file\n\n### Adding Custom linters\n\nLinters can be added and customized from the config file using the `Linters` field.\nLinters supports the following fields:\n\n* `Command` - the path to the linter binary and any default arguments\n* `Pattern` - a regular expression used to parse the linter output\n* `IsFast` - if the linter should be run when the `--fast` flag is used\n* `PartitionStrategy` - how paths args should be passed to the linter command:\n  * `directories` - call the linter once with a list of all the directories\n  * `files` - call the linter once with a list of all the files\n  * `packages` - call the linter once with a list of all the package paths\n  * `files-by-package` - call the linter once per package with a list of the\n    files in the package.\n  * `single-directory` - call the linter once per directory\n\nThe config for default linters can be overridden by using the name of the\nlinter.\n\nAdditional linters can be configured via the command line using the format\n`NAME:COMMAND:PATTERN`.\n\nExample:\n\n```\n$ gometalinter --linter='vet:go tool vet -printfuncs=Infof,Debugf,Warningf,Errorf:PATH:LINE:MESSAGE' .\n```\n\n## Comment directives\n\ngometalinter supports suppression of linter messages via comment directives. The\nform of the directive is:\n\n```\n// nolint[: \u003clinter\u003e[, \u003clinter\u003e, ...]]\n```\n\nSuppression works in the following way:\n\n1. Line-level suppression\n\n    A comment directive suppresses any linter messages on that line.\n\n    eg. In this example any messages for `a := 10` will be suppressed and errcheck\n    messages for `defer r.Close()` will also be suppressed.\n\n    ```go\n    a := 10 // nolint\n    a = 2\n    defer r.Close() // nolint: errcheck\n    ```\n\n2. Statement-level suppression\n\n    A comment directive at the same indentation level as a statement it\n    immediately precedes will also suppress any linter messages in that entire\n    statement.\n\n    eg. In this example all messages for `SomeFunc()` will be suppressed.\n\n    ```go\n    // nolint\n    func SomeFunc() {\n    }\n    ```\n\nImplementation details: gometalinter now performs parsing of Go source code,\nto extract linter directives and associate them with line ranges. To avoid\nunnecessary processing, parsing is on-demand: the first time a linter emits a\nmessage for a file, that file is parsed for directives.\n\n## Quickstart\n\nInstall gometalinter (see above).\n\nRun it:\n\n```\n$ cd example\n$ gometalinter ./...\nstutter.go:13::warning: unused struct field MyStruct.Unused (structcheck)\nstutter.go:9::warning: unused global variable unusedGlobal (varcheck)\nstutter.go:12:6:warning: exported type MyStruct should have comment or be unexported (golint)\nstutter.go:16:6:warning: exported type PublicUndocumented should have comment or be unexported (golint)\nstutter.go:8:1:warning: unusedGlobal is unused (deadcode)\nstutter.go:12:1:warning: MyStruct is unused (deadcode)\nstutter.go:16:1:warning: PublicUndocumented is unused (deadcode)\nstutter.go:20:1:warning: duplicateDefer is unused (deadcode)\nstutter.go:21:15:warning: error return value not checked (defer a.Close()) (errcheck)\nstutter.go:22:15:warning: error return value not checked (defer a.Close()) (errcheck)\nstutter.go:27:6:warning: error return value not checked (doit()           // test for errcheck) (errcheck)\nstutter.go:29::error: unreachable code (vet)\nstutter.go:26::error: missing argument for Printf(\"%d\"): format reads arg 1, have only 0 args (vet)\n```\n\nGometalinter also supports the commonly seen `\u003cpath\u003e/...` recursive path\nformat. Note that this can be *very* slow, and you may need to increase the linter `--deadline` to allow linters to complete.\n\n## FAQ\n\n### Exit status\n\ngometalinter sets two bits of the exit status to indicate different issues:\n\n| Bit | Meaning\n|-----|----------\n| 0   | A linter generated an issue.\n| 1   | An underlying error occurred; eg. a linter failed to execute. In this situation a warning will also be displayed.\n\neg. linter only = 1, underlying only = 2, linter + underlying = 3\n\n### What's the best way to use `gometalinter` in CI?\n\nThere are two main problems running in a CI:\n\n1. \u003cs\u003eLinters break, causing `gometalinter --install --update` to error\u003c/s\u003e (this is no longer an issue as all linters are vendored).\n2. `gometalinter` adds a new linter.\n\nI have solved 1 by vendoring the linters.\n\nFor 2, the best option is to disable all linters, then explicitly enable the\nones you want:\n\n    gometalinter --disable-all --enable=errcheck --enable=vet --enable=vetshadow ...\n\n### How do I make `gometalinter` work with Go 1.5 vendoring?\n\n`gometalinter` has a `--vendor` flag that just sets `GO15VENDOREXPERIMENT=1`, however the\nunderlying tools must support it. Ensure that all of the linters are up to date and built with Go 1.5\n(`gometalinter --install --force`) then run `gometalinter --vendor .`. That should be it.\n\n### Why does `gometalinter --install` install a fork of gocyclo?\n\nI forked `gocyclo` because the upstream behaviour is to recursively check all\nsubdirectories even when just a single directory is specified. This made it\nunusably slow when vendoring. The recursive behaviour can be achieved with\ngometalinter by explicitly specifying `\u003cpath\u003e/...`. There is a\n[pull request](https://github.com/fzipp/gocyclo/pull/1) open.\n\n### Many unexpected errors are being reported\n\nIf you see a whole bunch of errors being reported that you wouldn't expect,\nsuch as compile errors, this typically means that something is wrong with your\nGo environment. Try `go install` and fix any issues with your go installation,\nthen try gometalinter again.\n\n### Gometalinter is not working\n\nThat's more of a statement than a question, but okay.\n\nSometimes gometalinter will not report issues that you think it should. There\nare three things to try in that case:\n\n#### 1. Update to the latest build of gometalinter and all linters\n\n    curl -L https://git.io/vp6lP | sh\n\nIf you're lucky, this will fix the problem.\n\n#### 2. Analyse the debug output\n\nIf that doesn't help, the problem may be elsewhere (in no particular order):\n\n1. Upstream linter has changed its output or semantics.\n2. gometalinter is not invoking the tool correctly.\n3. gometalinter regular expression matches are not correct for a linter.\n4. Linter is exceeding the deadline.\n\nTo find out what's going on run in debug mode:\n\n    gometalinter --debug\n\nThis will show all output from the linters and should indicate why it is\nfailing.\n\n#### 3. Report an issue.\n\nFailing all else, if the problem looks like a bug please file an issue and\ninclude the output of `gometalinter --debug`.\n\n### How do I filter issues between two git refs?\n\n[revgrep](https://github.com/bradleyfalzon/revgrep) can be used to filter the output of `gometalinter`\nto show issues on lines that have changed between two git refs, such as unstaged changes, changes in\n`HEAD` vs `master` and between `master` and `origin/master`. See the project's documentation and `-help`\nusage for more information.\n\n```\ngo get -u github.com/bradleyfalzon/revgrep/...\ngometalinter |\u0026 revgrep               # If unstaged changes or untracked files, those issues are shown.\ngometalinter |\u0026 revgrep               # Else show issues in the last commit.\ngometalinter |\u0026 revgrep master        # Show issues between master and HEAD (or any other reference).\ngometalinter |\u0026 revgrep origin/master # Show issues that haven't been pushed.\n```\n\n## Checkstyle XML format\n\n`gometalinter` supports [checkstyle](http://checkstyle.sourceforge.net/)\ncompatible XML output format. It is triggered with `--checkstyle` flag:\n\n\tgometalinter --checkstyle\n\nCheckstyle format can be used to integrate gometalinter with Jenkins CI with the\nhelp of [Checkstyle Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Checkstyle+Plugin).\n","funding_links":[],"categories":["Misc","Go","Code Analysis","Code Checking","Linters","Linters Helper Tools","Static Code Analysis","代码分析","[](https://github.com/golang/go/wiki/CodeTools#all-in-one)All-in-one"],"sub_categories":["Contents","HTTP Load testing","Routers","Go","Misc","Middlewares","路由器"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falecthomas%2Fgometalinter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falecthomas%2Fgometalinter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falecthomas%2Fgometalinter/lists"}