diff --git a/DEPS.bzl b/DEPS.bzl index f1e7920961fc9..65f9d5b4b657c 100644 --- a/DEPS.bzl +++ b/DEPS.bzl @@ -927,6 +927,14 @@ def go_deps(): sum = "h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=", version = "v0.0.4", ) + go_repository( + name = "com_github_golangci_gofmt", + build_file_proto_mode = "disable", + importpath = "github.com/golangci/gofmt", + sum = "h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks=", + version = "v0.0.0-20190930125516-244bba706f1a", + ) + go_repository( name = "com_github_golangci_prealloc", build_file_proto_mode = "disable", diff --git a/br/pkg/errors/BUILD.bazel b/br/pkg/errors/BUILD.bazel index d07b0c723102a..fd6f45603d35c 100644 --- a/br/pkg/errors/BUILD.bazel +++ b/br/pkg/errors/BUILD.bazel @@ -1,4 +1,4 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "errors", @@ -7,3 +7,13 @@ go_library( visibility = ["//visibility:public"], deps = ["@com_github_pingcap_errors//:errors"], ) + +go_test( + name = "errors_test", + srcs = ["errors_test.go"], + deps = [ + ":errors", + "@com_github_pingcap_errors//:errors", + "@com_github_stretchr_testify//require", + ], +) diff --git a/br/pkg/pdutil/BUILD.bazel b/br/pkg/pdutil/BUILD.bazel index f2e997d3d833c..128b4b6b31cda 100644 --- a/br/pkg/pdutil/BUILD.bazel +++ b/br/pkg/pdutil/BUILD.bazel @@ -17,6 +17,7 @@ go_library( "//util/codec", "@com_github_coreos_go_semver//semver", "@com_github_docker_go_units//:go-units", + "@com_github_google_uuid//:uuid", "@com_github_opentracing_opentracing_go//:opentracing-go", "@com_github_pingcap_errors//:errors", "@com_github_pingcap_failpoint//:failpoint", diff --git a/build/BUILD.bazel b/build/BUILD.bazel index 4264907bb1fb9..6957be918b42b 100644 --- a/build/BUILD.bazel +++ b/build/BUILD.bazel @@ -83,6 +83,7 @@ nogo( "@org_golang_x_tools//go/analysis/passes/unusedresult:go_default_library", "//build/linter/durationcheck:durationcheck", "//build/linter/exportloopref:exportloopref", + "//build/linter/gofmt:gofmt", "//build/linter/ineffassign:ineffassign", "//build/linter/prealloc:prealloc", ] + staticcheck_analyzers(STATICHECK_ANALYZERS), diff --git a/build/linter/gofmt/BUILD.bazel b/build/linter/gofmt/BUILD.bazel new file mode 100644 index 0000000000000..c21e7e7e9fe40 --- /dev/null +++ b/build/linter/gofmt/BUILD.bazel @@ -0,0 +1,12 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "gofmt", + srcs = ["analyzer.go"], + importpath = "github.com/pingcap/tidb/build/linter/gofmt", + visibility = ["//visibility:public"], + deps = [ + "@com_github_golangci_gofmt//gofmt", + "@org_golang_x_tools//go/analysis", + ], +) diff --git a/build/linter/gofmt/analyzer.go b/build/linter/gofmt/analyzer.go new file mode 100644 index 0000000000000..05c266b0bbe20 --- /dev/null +++ b/build/linter/gofmt/analyzer.go @@ -0,0 +1,65 @@ +// Copyright 2022 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gofmt + +import ( + "fmt" + "strings" + + "github.com/golangci/gofmt/gofmt" + "golang.org/x/tools/go/analysis" +) + +// Analyzer is the analyzer struct of gofmt. +var Analyzer = &analysis.Analyzer{ + Name: "gofmt", + Doc: "gofmt checks whether code was gofmt-ed" + + "this tool runs with -s option to check for code simplification", + Run: run, +} + +var needSimplify bool + +func init() { + Analyzer.Flags.BoolVar(&needSimplify, "need-simplify", true, "run gofmt with -s for code simplification") +} + +func run(pass *analysis.Pass) (any, error) { + fileNames := make([]string, 0, 10) + for _, f := range pass.Files { + pos := pass.Fset.PositionFor(f.Pos(), false) + if pos.Filename != "" && !strings.HasSuffix(pos.Filename, "failpoint_binding__.go") { + fileNames = append(fileNames, pos.Filename) + } + } + + for _, f := range fileNames { + diff, err := gofmt.Run(f, needSimplify) + if err != nil { + return nil, fmt.Errorf("could not run gofmt: %w (%s)", err, f) + } + + if diff == nil { + continue + } + + pass.Report(analysis.Diagnostic{ + Pos: 1, + Message: fmt.Sprintf("\n%s", diff), + }) + } + + return nil, nil +} diff --git a/build/nogo_config.json b/build/nogo_config.json index d0d99435f146b..cefdb5fe4aa11 100644 --- a/build/nogo_config.json +++ b/build/nogo_config.json @@ -104,6 +104,16 @@ ".*_generated\\.go$": "ignore generated code" } }, + "gofmt": { + "exclude_files": { + "/external/": "no need to vet third party code", + ".*_generated\\.go$": "ignore generated code", + "/cgo/": "ignore cgo code", + "/rules_go_work-*": "ignore generated code", + ".*test_/testmain\\.go$": "ignore generated code", + ".*failpoint_binding__.go$": "ignore generated code" + } + }, "httpresponse": { "exclude_files": { "/external/": "no need to vet third party code", diff --git a/go.mod b/go.mod index 351a6ea1817cf..9ad9135be4085 100644 --- a/go.mod +++ b/go.mod @@ -98,6 +98,7 @@ require ( require ( github.com/aliyun/alibaba-cloud-sdk-go v1.61.1581 github.com/charithe/durationcheck v0.0.9 + github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 github.com/kyoh86/exportloopref v0.1.8 honnef.co/go/tools v0.0.1-2020.1.4 diff --git a/go.sum b/go.sum index 5bc93febdf2ab..2dcc2c3e4cfeb 100644 --- a/go.sum +++ b/go.sum @@ -343,6 +343,8 @@ github.com/golang/snappy v0.0.2-0.20190904063534-ff6b7dc882cf/go.mod h1:/XxbfmMg github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21 h1:leSNB7iYzLYSSx3J/s5sVf4Drkc68W2wm4Ixh/mr0us= github.com/golangci/prealloc v0.0.0-20180630174525-215b22d4de21/go.mod h1:tf5+bzsHdTM0bsB7+8mt0GUMvjCgwLpTapNZHU8AajI= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=