PR

Go言語(Golang)golangci-lintの使い方|おすすめformatter・lintの設定方法

2. 基礎

こんにちは。Tomoyuki(@tomoyuki65)です。

Go言語(Golang)には標準のformatter(go fmt)やlint(go vet)が使えるようになっていますが、実務では他にも定番のライブラリがよく使われたりします。

その際に各種定番ライブラリをまとめて使えるようにする「統合Lintツール」として、「golangci-lint」というのがあり、これを使うと便利です。

この記事では、そんなgolangci-lintの使い方についてご紹介します。

 

Go言語(Golang)golangci-lintの使い方|おすすめformatter・lintの設定方法

まずはDockerで開発環境を構築するため、以下のコマンドを実行して各種ファイルを作成します。

$ mkdir go-golangci-lint && cd go-golangci-lint
$ mkdir src && touch src/main.go
$ touch Dockerfile compose.yml

 

次に作成したファイルをそれぞれ以下のように記述します。

・「Dockerfile」

FROM golang:1.26-alpine3.23

# インストール可能なパッケージ一覧の更新
RUN apk update && \
    apk upgrade && \
    # パッケージのインストール(--no-cacheでキャッシュ削除)
    apk add --no-cache \
            curl

WORKDIR /go/src

COPY ./src .

# go.modがあれば依存関係をインストール
RUN if [ -f ./go.mod ]; then \
      go install; \
    fi

# 開発用のライブラリをインストール
RUN curl -sSfL https://golangci-lint.run/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.12.2

EXPOSE 8080

※今回はGoのバージョン「1.26」、golangci-lintのバージョンは「v2.12.2」を使います。またgolangci-lintのインストールにはcurlコマンドが必要です。

 

・「compose.yml」

services:
  go-dev:
    container_name: go-script
    build:
      context: .
      dockerfile: ./Dockerfile
    volumes:
      - ./src:/go/src
    ports:
      - "8080:8080"
    tty: true
    stdin_open: true

 

・「src/main.go」

package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello World !!")
}

 

次に以下のコマンドを実行し、Dockerコンテナのビルドを行います。

$ docker compose build --no-cache

 

次に以下のコマンドを実行し、goの初期化を行います。

$ docker compose run --rm go-dev go mod init go-golangci-lint

 

次に以下のコマンドを実行し、スクリプトを実行して試します。

$ docker compose run --rm go-dev go run main.go

 

コマンド実行後、「Hello World !!」が出力されればOKです。

 

golangci-lintの設定

次にgolangci-lintの設定をするため、以下のコマンドを実行して設定用のファイルを作成します。

$ touch src/.golangci.yml

 

次に作成したファイルを以下のように記述します。

・「src/.golangci.yml」

version: "2"

run:
  # タイムアウト設定
  timeout: 5m

formatters:
  # 実行するformatterを指定
  enable:
    - gofumpt
    - goimports

linters:
  # デフォルト設定を全てOFF
  default: none
  # 実行するlintを指定
  enable:
    - govet
    - staticcheck
    - gosec

※最小構成で試します。

・gofumpt:gofmtより厳しめのコードフォーマッタ
・goimports:import整理 + 不足import自動追加
・govet:Go標準の静的コード解析
・staticcheck:高性能静的コード解析
・gosec:セキュリティ問題を検出する静的コード解析

 

golangci-lintを試す

次にフォーマット修正や静的コード解析でのエラーを試すため、ファイル「src/main.go」を以下のように修正します。

package main

import (
"fmt"
)

func main() {
x := []int{1, 2, 3}
for _, v := range x {
fmt.Sprintf("%d", v)
}
}

 

次に以下のコマンドを実行し、エラーが出ることを確認します。

$ docker compose run --rm go-dev golangci-lint run ./...

※詳細を確認したい場合はオプション「-v」を付けて実行して下さい。

 

実行後、以下のようにエラーが表示されればOKです。

 

次に以下のコマンドを実行し、フォーマット修正を行います。

$ docker compose run --rm go-dev golangci-lint fmt ./...

 

実行後、ファイル「src/main.go」のフォーマットが以下のように修正されればOKです。

 

次に再度以下のコマンドを実行し、結果を確認します。

$ docker compose run --rm go-dev golangci-lint run ./...

 

実行後、以下のようにフォーマットのエラーが解消すればOKです。

 

次にファイル「src/main.go」を以下のように修正します。

package main

import (
    "fmt"
)

func main() {
    x := []int{1, 2, 3}
    for _, v := range x {
        fmt.Printf("%d\n", v)
    }
}

 

次に再度以下のコマンドを実行し、結果を確認します。

$ docker compose run --rm go-dev golangci-lint run ./...

 

実行後、以下のように静的コード解析のエラーが解消すればOKです。

 

最後に以下のコマンドを実行し、スクリプトを試します。

$ docker compose run --rm go-dev go run main.go

 

実行後、以下のように表示されればOKです。

 

利用可能なformatterやlintを確認する方法

以下のコマンドを実行し、利用可能なformatterやlintを確認することが可能です。

 

・利用可能なformatterを確認

$ docker compose run --rm go-dev golangci-lint formatters

 

実行結果例

※Enabled by your configuration formattersにあるのが有効なもので、Disabled by your configuration formattersにあるのが無効になっているものです。

 

・利用可能なlintを確認

$ docker compose run --rm go-dev golangci-lint linters

 

実行結果例

※Enabled by your configuration lintersにあるのが有効なもので、Disabled by your configuration lintersにあるのが無効になっているものです。

 

その他の利用可能なformatter一覧

formatter名 説明
gci import順序やグループを整理する formatter
gofmt Go標準のコード整形を行う
golines 長い行を自動で折り返して整形する
swaggo swaggo コメント形式を整形・検証する

 

その他の利用可能なlint一覧

lint名 説明
arangolint ArangoDB client のベストプラクティスを検証する
asasalint []any の誤った variadic 渡しを検出する
asciicheck 非ASCII識別子を検出する
bidichk 危険なUnicode文字列を検出する
bodyclose HTTPレスポンスの Close 忘れを検出する
canonicalheader HTTPヘッダー名を正規形式に統一する
clickhouselint ClickHouse driver の誤用を検出する
containedctx struct内の context.Context 保持を検出する
contextcheck context.Context の伝播漏れを検出する
copyloopvar loop変数コピーの事故を検出する
cyclop 循環複雑度をチェックする
decorder 宣言順序をチェックする
depguard 禁止 package import を制御する
dogsled blank identifier 多用を検出する
dupl 重複コードを検出する
dupword 重複単語を検出する
durationcheck duration の誤演算を検出する
embeddedstructfieldcheck embedded field 配置をチェックする
err113 error handling の規約違反を検出する
errcheck error戻り値の未確認を検出する
errchkjson json encode/decode 問題を検出する
errname error命名規則を検証する
errorlint error wrapping 問題を検出する
exhaustive switch網羅漏れを検出する
exhaustruct struct初期化漏れを検出する
exptostd x/exp から stdlib 置換可能箇所を検出する
fatcontext 不要な context ネストを検出する
forbidigo 禁止 identifier を検出する
forcetypeassert panicしうる型アサーションを検出する
funcorder 関数順序をチェックする
funlen 長すぎる関数を検出する
ginkgolinter ginkgo/gomega の misuse を検出する
gocheckcompilerdirectives //go: directive の不正を検出する
gochecknoglobals グローバル変数使用を検出する
gochecknoinits init関数使用を検出する
gochecksumtype sum type の exhaustiveness を検証する
gocognit 認知的複雑度をチェックする
goconst 定数化可能な重複文字列を検出する
gocritic バグ・性能・スタイル問題を広く検出する
gocyclo 循環複雑度を測定する
godoclint GoDocコメント規約を検証する
godot コメント末尾ピリオドを検証する
godox TODO/FIXME コメントを検出する
goheader ファイルヘッダーを検証する
gomoddirectives go.mod directive を検証する
gomodguard_v2 依存 module 制限を行う
goprintffuncname printf系関数命名を検証する
gosmopolitan i18n/l10n anti-pattern を検出する
grouper 式グループ化を分析する
iface interface乱用を検出する
importas import alias を統一する
inamedparam interface の unnamed parameter を検出する
ineffassign 無意味な代入を検出する
interfacebloat 巨大interfaceを検出する
intrange integer range 化可能な loop を検出する
iotamixing iota混在 const を検出する
ireturn interface返却乱用を検出する
lll 長すぎる行を検出する
loggercheck logger key/value ミスを検出する
maintidx 保守性指数を測定する
makezero slice初期化ミスを検出する
mirror bytes/string mirror misuse を検出する
misspell 英単語スペルミスを検出する
mnd マジックナンバーを検出する
modernize modern Go 書き方を提案する
musttag struct tag 漏れを検出する
nakedret 長い naked return を検出する
nestif 深い if ネストを検出する
nilerr err確認後の nil返却バグを検出する
nilnesserr 異常な nil error 判定を検出する
nilnil nil,nil の曖昧返却を検出する
nlreturn return前空行を統一する
noctx context.Context 未使用を検出する
noinlineerr inline error handling を禁止する
nolintlint nolint misuse を検出する
nonamedreturns named return を禁止する
nosprintfhostport Sprintf host:port misuse を検出する
paralleltest t.Parallel() 忘れを検出する
perfsprint fmt.Sprintf の低速利用を検出する
prealloc slice事前確保漏れを検出する
predeclared 組み込み識別子 shadowing を検出する
promlinter Prometheus metrics 命名を検証する
protogetter proto getter 未使用を検出する
reassign package変数再代入を検出する
recvcheck receiver type 一貫性を検証する
revive Goスタイル・品質を広くチェックする
rowserrcheck rows.Err() 未確認を検出する
sloglint log/slog の使い方を統一する
spancheck OpenTelemetry span misuse を検出する
sqlclosecheck DB Rows/Stmt の Close漏れを検出する
tagalign struct tag 整列を行う
tagliatelle struct tag 命名規則を検証する
testableexamples Example test 実行可能性を検証する
testifylint testify misuse を検出する
testpackage 別 package test を強制する
thelper t.Helper() 忘れを検出する
tparallel 誤った t.Parallel() 使用を検出する
unconvert 不要な型変換を検出する
unparam 未使用引数を検出する
unqueryvet SELECT * 使用を検出する
unused 未使用コードを検出する
usestdlibvars 標準ライブラリ定数利用を推奨する
usetesting testing package misuse を検出する
varnamelen 変数名長さをチェックする
wastedassign 無駄な代入を検出する
whitespace 不要空行を整理する
wrapcheck 外部 error wrapping 漏れを検出する
wsl_v5 空行スタイルを統一する
zerologlint zerolog misuse を検出する
gomodguard 依存 module 制限を行う(deprecated)
wsl 空行スタイルを統一する(deprecated)

※数が多いですが、基本的には上記で試した最小構成でも十分なので、もし追加したいものがあれば別途確認して少しずつ導入するようにして下さい。

 

スポンサーリンク

最後に

今回はgolangci-lintの使い方についてご紹介しました。

私も今まで「go fmt」や「staticcheck」を個別に使っていましたが、次からはgolangci-lintに統一していこうと思います。

Go言語のformatterやlintを利用する際におすすめのライブラリなので、よければぜひ参考にしてみて下さい。

 

この記事を書いた人
Tomoyuki

SE→ブロガーを経て、現在はSoftware Engineer(Web/Gopher)をしています!

Tomoyukiをフォローする
2. 基礎
スポンサーリンク
Tomoyukiをフォローする

コメント

タイトルとURLをコピーしました