golangci-lint: Golang 快速 lint 工具

发布时间: 更新时间: 总字数:1242 阅读时间:3m 作者:IP:上海 网址

golangci-lint 支持并行运行 lint、缓存、YAML 配置,且支持与主流集成开发环境集成,并包含一百多个 lint 程序

介绍

  • 非常快:并行运行筛选器,重用 Go 构建缓存并缓存分析结果
  • 基于 YAML 的配置
  • 与 VS Code、Sublime Text、GoLand、GNU Emacs、Vim 和 GitHub Actions 集成
  • 内置大量 linters,无需安装
  • 内置默认设置,误报率最低
  • 带有颜色、源代码行和标记标识符的漂亮输出

安装

# bin
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.59.1

golangci-lint --version

# mac
brew install golangci-lint
brew upgrade golangci-lint

# Linux
直接到 https://github.com/golangci/golangci-lint/releases 下载二进制包

# go
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.59.1

# Docker
docker run -t --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.59.1 golangci-lint run -v

help

golangci-lint --help ...

vscode 集成配置

  • 推荐 settings
"go.lintTool": "golangci-lint",
"go.lintFlags": [
  "--fast"
]

常用命令

golangci-lint run
# disable all, enable errcheck
golangci-lint run --disable-all -E errcheck

golangci-lint help linters

配置

  • 参考
  • 默认加载以下名字的配置文件
.golangci.yml
.golangci.yaml
.golangci.toml
.golangci.json

排除代码检查

var bad_name int //nolint
var bad_name int //nolint:golint,unused

//nolint
func allIssuesInThisFunctionAreExcluded() *string {
  // ...
}

//nolint:govet
var (
  a int
  b int
)

# 整个文件生效
//nolint:unparam
package pkg

示例一

.golangci.yaml ...

示例二

.golangci.yaml ...

示例三

.golangci.yaml ...

示例四

.golangci.yaml ...

与其他工具集成

Makefile

ifeq (,$(shell go env GOBIN))
GOBIN=$(shell go env GOPATH)/bin
else
GOBIN=$(shell go env GOBIN)
endif

.PHONY: go/deps
go/deps:
	go mod tidy

# renovate: datasource=go depName=mvdan.cc/gofumpt
GOFUMPT_VERSION := v0.6.0
gofumpt:
ifeq (, $(shell command -v gofumpt >/dev/null))
	go install mvdan.cc/gofumpt@$(GOFUMPT_VERSION)
GOFUMPT=$(GOBIN)/gofumpt
else
GOFUMPT=$(shell command -v gofumpt)
endif

# Rather than running this over and over we recommend running gofumpt on save with your editor.
# Check https://github.com/mvdan/gofumpt#installation for instructions.
.PHONY: go/fmt
go/fmt: gofumpt
	$(GOFUMPT) -l -w $(shell go list -f {{.Dir}} ./... | grep -v gen/proto)

.PHONY: go/lint
go/lint:
	golangci-lint run
.PHONY: go/test
go/test:
	go test $(SANITIZERS) -tags assert -v `go list ./...`

.PHONY: go/bench
go/bench:
	mkdir -pm 777 tmp/
	go test $(SANITIZERS) -run=. -bench=. -benchtime=1x -v `go list ./...` # run benchmark with one iteration to make sure they work

GOLANGCI_LINT_VERSION := v1.59.1
golangci-lint:
ifeq (, $(shell command -v golangci-lint >/dev/null))
	go install github.com/golangci/golangci-lint/cmd/golangci-lint@${GOLANGCI_LINT_VERSION}
endif

# or
.PHONY: go/lint
go/lint: golangci-lint
	golangci-lint run --fix
  # go mod tidy
	# golangci-lint run --fix --verbose --concurrency 4 --timeout 5m --enable goimports

github actions

name: golangci-lint
on:
  push:
    tags:
      - v*
    branches:
    - main
    - release-*
  pull_request:
    branches:
    - main
    - release-*
  merge_group:
    branches:
    - main

jobs:
  lint:
    name: Go Lint
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7

      - name: Set up Go
        uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
        with:
          go-version-file: .go-version
          cache: false

      ...

      - name: Install dependencies
        run: make go/deps

      - name: Build
        run: make go/build

      - name: Format
        run: make go/fmt && git diff --exit-code # ':!ui/packages/app/web/build'

      - name: Lint
        run: make go/lint

扩展

gofumpt

gofumptgofmt 的基础上添加了一系列更加严格的格式化规则,并保证对 gofmt 的兼容

  • 安装
go install mvdan.cc/gofumpt@latest
  • vscode 中集成 gofumpt 配置
  "go.useLanguageServer": true,
  "gopls": {
    "formatting.gofumpt": true,
  }

F&Q

could use tagged switch on xxx QF1003

建议将一连串的 if/else if 语句转换为带标签(Tagged Switch) 的 switch 语句,因为它发现这些条件都在对同一个变量进行比较。

本文总阅读量 次 本站总访问量 次 本站总访客数