diff --git a/.goreleaser.yml b/.goreleaser.yml index 2590808..dd75ac9 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -16,12 +16,3 @@ archives: - format_overrides: - goos: windows format: zip - -brews: - - tap: - owner: tmzane - name: homebrew-tap - token: '{{ .Env.HOMEBREW_TAP_TOKEN }}' - homepage: https://github.com/tmzane/musttag - description: A Go linter that enforces field tags in (un)marshaled structs - license: MPL-2.0 diff --git a/README.md b/README.md index 621c7a9..54c2744 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # musttag -[![checks](https://github.com/tmzane/musttag/actions/workflows/checks.yml/badge.svg)](https://github.com/tmzane/musttag/actions/workflows/checks.yml) -[![pkg.go.dev](https://pkg.go.dev/badge/go.tmz.dev/musttag.svg)](https://pkg.go.dev/go.tmz.dev/musttag) -[![goreportcard](https://goreportcard.com/badge/go.tmz.dev/musttag)](https://goreportcard.com/report/go.tmz.dev/musttag) -[![codecov](https://codecov.io/gh/tmzane/musttag/branch/main/graph/badge.svg)](https://codecov.io/gh/tmzane/musttag) +[![checks](https://github.com/go-simpler/musttag/actions/workflows/checks.yml/badge.svg)](https://github.com/go-simpler/musttag/actions/workflows/checks.yml) +[![pkg.go.dev](https://pkg.go.dev/badge/go-simpler.org/musttag.svg)](https://pkg.go.dev/go-simpler.org/musttag) +[![goreportcard](https://goreportcard.com/badge/go-simpler.org/musttag)](https://goreportcard.com/report/go-simpler.org/musttag) +[![codecov](https://codecov.io/gh/go-simpler/musttag/branch/main/graph/badge.svg)](https://codecov.io/gh/go-simpler/musttag) -A Go linter that enforces field tags in (un)marshaled structs +A Go linter that enforces field tags in (un)marshaled structs. ## 📌 About @@ -14,13 +14,13 @@ A Go linter that enforces field tags in (un)marshaled structs ```go // BAD: var user struct { - Name string + Name string } data, err := json.Marshal(user) // GOOD: var user struct { - Name string `json:"name"` + Name string `json:"name"` } data, err := json.Marshal(user) ``` @@ -36,18 +36,18 @@ The rational from [Uber Style Guide][1]: The following packages are supported out of the box: -* [`encoding/json`][2] -* [`encoding/xml`][3] -* [`gopkg.in/yaml.v3`][4] -* [`github.com/BurntSushi/toml`][5] -* [`github.com/mitchellh/mapstructure`][6] -* [`github.com/jmoiron/sqlx`][7] +* [encoding/json][2] +* [encoding/xml][3] +* [gopkg.in/yaml.v3][4] +* [github.com/BurntSushi/toml][5] +* [github.com/mitchellh/mapstructure][6] +* [github.com/jmoiron/sqlx][7] In addition, any [custom package](#custom-packages) can be added to the list. -## 📋 Usage +## 📦 Install -`musttag` is already integrated into `golangci-lint`, and this is the recommended way to use it. +`musttag` is integrated into [`golangci-lint`][8], and this is the recommended way to use it. To enable the linter, add the following lines to `.golangci.yml`: @@ -57,39 +57,33 @@ linters: - musttag ``` -If you'd rather prefer to use `musttag` standalone, you can install it via `brew`... - -```shell -brew install tmzane/tap/musttag -``` +Alternatively, you can download a prebuilt binary from the [Releases][9] page to use `musttag` standalone. -...or download a prebuilt binary from the [Releases][9] page. +## 📋 Usage -Then run it either directly or as a `go vet` tool: +Run `golangci-lint` with `musttag` enabled. +See the list of [available options][10] to configure the linter. -```shell -go vet -vettool=$(which musttag) ./... -``` +When using `sloglint` standalone, pass the options as flags. ### Custom packages -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 `hclsimple.DecodeFile` function from [`github.com/hashicorp/hcl`][8]: +To report a custom function, you need to add its description to `.golangci.yml`. +The following is an example of adding support for [`hclsimple.Decode`][11]: ```yaml linters-settings: musttag: functions: # The full name of the function, including the package. - - name: github.com/hashicorp/hcl/v2/hclsimple.DecodeFile + - name: github.com/hashicorp/hcl/v2/hclsimple.Decode # The struct tag whose presence should be ensured. tag: hcl # The position of the argument to check. arg-pos: 2 ``` -The same can be done via the `-fn=name:tag:arg-pos` flag when using `musttag` standalone: +The same can be done via the `-fn=` flag when using `musttag` standalone: ```shell musttag -fn="github.com/hashicorp/hcl/v2/hclsimple.DecodeFile:hcl:2" ./... @@ -98,9 +92,11 @@ musttag -fn="github.com/hashicorp/hcl/v2/hclsimple.DecodeFile:hcl:2" ./... [1]: https://github.com/uber-go/guide/blob/master/style.md#use-field-tags-in-marshaled-structs [2]: https://pkg.go.dev/encoding/json [3]: https://pkg.go.dev/encoding/xml -[4]: https://github.com/go-yaml/yaml -[5]: https://github.com/BurntSushi/toml -[6]: https://github.com/mitchellh/mapstructure -[7]: https://github.com/jmoiron/sqlx -[8]: https://github.com/hashicorp/hcl -[9]: https://github.com/tmzane/musttag/releases +[4]: https://pkg.go.dev/gopkg.in/yaml.v3 +[5]: https://pkg.go.dev/github.com/BurntSushi/toml +[6]: https://pkg.go.dev/github.com/mitchellh/mapstructure +[7]: https://pkg.go.dev/github.com/jmoiron/sqlx +[8]: https://golangci-lint.run +[9]: https://github.com/go-simpler/musttag/releases +[10]: https://golangci-lint.run/usage/linters/#musttag +[11]: https://pkg.go.dev/github.com/hashicorp/hcl/v2/hclsimple#Decode diff --git a/builtins.go b/builtins.go index c5e0b52..3305513 100644 --- a/builtins.go +++ b/builtins.go @@ -54,7 +54,7 @@ var builtins = []Func{ ifaceWhitelist: []string{"encoding/xml.Unmarshaler", "encoding.TextUnmarshaler"}, }, - // https://github.com/go-yaml/yaml + // https://pkg.go.dev/gopkg.in/yaml.v3 { Name: "gopkg.in/yaml.v3.Marshal", Tag: "yaml", ArgPos: 0, ifaceWhitelist: []string{"gopkg.in/yaml.v3.Marshaler"}, @@ -72,7 +72,7 @@ var builtins = []Func{ ifaceWhitelist: []string{"gopkg.in/yaml.v3.Unmarshaler"}, }, - // https://github.com/BurntSushi/toml + // https://pkg.go.dev/github.com/BurntSushi/toml { Name: "github.com/BurntSushi/toml.Unmarshal", Tag: "toml", ArgPos: 1, ifaceWhitelist: []string{"github.com/BurntSushi/toml.Unmarshaler", "encoding.TextUnmarshaler"}, @@ -98,13 +98,13 @@ var builtins = []Func{ ifaceWhitelist: []string{"github.com/BurntSushi/toml.Unmarshaler", "encoding.TextUnmarshaler"}, }, - // https://github.com/mitchellh/mapstructure + // https://pkg.go.dev/github.com/mitchellh/mapstructure {Name: "github.com/mitchellh/mapstructure.Decode", Tag: "mapstructure", ArgPos: 1}, {Name: "github.com/mitchellh/mapstructure.DecodeMetadata", Tag: "mapstructure", ArgPos: 1}, {Name: "github.com/mitchellh/mapstructure.WeakDecode", Tag: "mapstructure", ArgPos: 1}, {Name: "github.com/mitchellh/mapstructure.WeakDecodeMetadata", Tag: "mapstructure", ArgPos: 1}, - // https://github.com/jmoiron/sqlx + // https://pkg.go.dev/github.com/jmoiron/sqlx {Name: "github.com/jmoiron/sqlx.Get", Tag: "db", ArgPos: 1}, {Name: "github.com/jmoiron/sqlx.GetContext", Tag: "db", ArgPos: 2}, {Name: "github.com/jmoiron/sqlx.Select", Tag: "db", ArgPos: 1}, diff --git a/cmd/musttag/main.go b/cmd/musttag/main.go index d742c4b..5843349 100644 --- a/cmd/musttag/main.go +++ b/cmd/musttag/main.go @@ -6,7 +6,7 @@ import ( "os" "runtime" - "go.tmz.dev/musttag" + "go-simpler.org/musttag" "golang.org/x/tools/go/analysis/singlechecker" ) diff --git a/go.mod b/go.mod index 14aee94..2b2c38c 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module go.tmz.dev/musttag +module go-simpler.org/musttag go 1.20 diff --git a/musttag.go b/musttag.go index 1c2b3c0..ebcf91c 100644 --- a/musttag.go +++ b/musttag.go @@ -105,7 +105,7 @@ func run(pass *analysis.Pass, mainModule string, funcs map[string]Func) (_ any, } if len(call.Args) <= fn.ArgPos { - err = fmt.Errorf("Func.ArgPos cannot be %d: %s accepts only %d argument(s)", fn.ArgPos, fn.Name, len(call.Args)) + err = fmt.Errorf("musttag: Func.ArgPos cannot be %d: %s accepts only %d argument(s)", fn.ArgPos, fn.Name, len(call.Args)) return } diff --git a/musttag_test.go b/musttag_test.go index 76f1a1c..1f57fbd 100644 --- a/musttag_test.go +++ b/musttag_test.go @@ -29,7 +29,7 @@ func TestAnalyzer(t *testing.T) { Func{Name: "encoding/json.Marshal", Tag: "json", ArgPos: 10}, ) err := analysistest.Run(nopT{}, testdata, analyzer, "tests")[0].Err - assert.Equal[E](t, err.Error(), "Func.ArgPos cannot be 10: encoding/json.Marshal accepts only 1 argument(s)") + assert.Equal[E](t, err.Error(), "musttag: Func.ArgPos cannot be 10: encoding/json.Marshal accepts only 1 argument(s)") }) } diff --git a/utils.go b/utils.go index 1aafd27..1a13f96 100644 --- a/utils.go +++ b/utils.go @@ -30,17 +30,20 @@ func getMainModule() (string, error) { // based on golang.org/x/tools/imports.VendorlessPath func cutVendor(path string) string { var prefix string + switch { case strings.HasPrefix(path, "(*"): prefix, path = "(*", path[len("(*"):] case strings.HasPrefix(path, "("): prefix, path = "(", path[len("("):] } + if i := strings.LastIndex(path, "/vendor/"); i >= 0 { return prefix + path[i+len("/vendor/"):] } if strings.HasPrefix(path, "vendor/") { return prefix + path[len("vendor/"):] } + return prefix + path }