A Go linter that enforces field tags in (un)marshaled structs
musttag
checks that exported fields of a struct passed to a Marshal
-like function are annotated with the relevant tag:
// BAD:
var user struct {
Name string
}
data, err := json.Marshal(user)
// GOOD:
var user struct {
Name string `json:"name"`
}
data, err := json.Marshal(user)
The rational from Uber Style Guide:
The serialized form of the structure is a contract between different systems. Changes to the structure of the serialized form, including field names, break this contract. Specifying field names inside tags makes the contract explicit, and it guards against accidentally breaking the contract by refactoring or renaming fields.
The following packages are supported out of the box:
encoding/json
encoding/xml
gopkg.in/yaml.v3
github.com/BurntSushi/toml
github.com/mitchellh/mapstructure
In addition, any custom package can be added to the list.
musttag
is already integrated into golangci-lint
, and this is the recommended way to use it.
To enable the linter, add the following lines to .golangci.yml
:
linters:
enable:
- mustttag
If you'd rather prefer to use musttag
standalone, you can install it via brew
...
brew install junk1tm/tap/musttag
...or download a prebuilt binary from the Releases page.
Then run it either directly or as a go vet
tool:
go vet -vettool=$(which musttag) ./...
To enable reporting a custom function, you need to add its description to .golangci.yml
.
The following is an example of adding support for the sqlx.Get
function from github.com/jmoiron/sqlx
:
linters-settings:
musttag:
functions:
# The full name of the function, including the package.
- name: github.com/jmoiron/sqlx.Get
# The struct tag whose presence should be ensured.
tag: db
# The position of the argument to check.
arg-pos: 1
The same can be done via the -fn=name:tag:arg-pos
flag when using musttag
standalone:
musttag -fn="github.com/jmoiron/sqlx.Get:db:1" ./...