🐁

golangci-lintにコードフォーマットのためのコマンドが追加された

2025/03/25に公開

数日前にgolangci-lint v2がリリースされました。

https://ldez.github.io/blog/2025/03/23/golangci-lint-v2/

golangci-lint v2ではコードをフォーマットするためのgolangci-lint fmtコマンドが追加されました。

次のコマンドを実行することでプロジェクトの全てのGoファイルをフォーマットできます。

golangci-lint fmt

次のように指定したディレクトリやファイルだけを対象とすることもできます。

# `cmd`ディレクトリ以下のGoファイルを再帰的にフォーマット
golangci-lint fmt cmd/...
# `main.go`をフォーマット
golangci-lint fmt main.go

golangci-lint fmtgofmtgoimportsなどのコードフォーマッタを組み合わせてコードをフォーマットします。
使用するフォーマッタは設定ファイルかコマンドのオプションで設定できます。

https://golangci-lint.run/usage/configuration/#formatters-configuration

例えば、次のように設定したときはgofmtgoimportsがコードフォーマッタとして使用されます。

.golangci.toml
version = "2"

[formatters]
enable = ["gofmt", "goimports"]

現時点では次のコードフォーマッタが利用できます。

利用可能なコードフォーマッタはgolangci-lint help formattersまたはgolangci-lint formattersでも確認できます。

$ golangci-lint help formatters
Disabled by default formatters:
gci: Checks if code and import statements are formatted, with additional rules.
gofmt: Checks if the code is formatted according to 'gofmt' command.
gofumpt: Checks if code and import statements are formatted, with additional rules.
goimports: Checks if the code and import statements are formatted according to the 'goimports' command.
golines: Checks if code is formatted, and fixes long lines.
$ golangci-lint formatters
Enabled by your configuration formatters:
gofmt: Checks if the code is formatted according to 'gofmt' command.
goimports: Checks if the code and import statements are formatted according to the 'goimports' command.

Disabled by your configuration formatters:
gci: Checks if code and import statements are formatted, with additional rules.
gofumpt: Checks if code and import statements are formatted, with additional rules.
golines: Checks if code is formatted, and fixes long lines.

formattersで指定したコードフォーマッタはgolangci-lint runを実行するときに自動的にlinterとして使用されます。
つまり、golangci-lint v1でこれらのコードフォーマッタを有効にしたときと同じように動作します。

いずれのフォーマッタも有効にしていないときは標準的なGoのスタイルが使用されます。

次のコードはフォーマット前のコードです。

main.go
package main

import (
        "github.com/zeebo/blake3"
        "fmt"
)

func main(){
        data := []byte("Hello, world!")
        sum:=blake3.Sum256(data)
        fmt.Printf("%x\n", sum)
}

これを上記の設定と同じくgofmtgoimportsを有効にしてgolangci-lint fmtを実行すると次のようにフォーマットされます。

main.go
package main

import (
        "fmt"

        "github.com/zeebo/blake3"
)

func main() {
        data := []byte("Hello, world!")
        sum := blake3.Sum256(data)
        fmt.Printf("%x\n", sum)
}

フォーマット前とフォーマット後の差分はgolangci-lint fmt --diffを実行すると見ることができます。

diff b3sum/main.go.orig b3sum/main.go
--- b3sum/main.go.orig
+++ b3sum/main.go
@@ -1,12 +1,13 @@
 package main

 import (
-       "github.com/zeebo/blake3"
        "fmt"
+
+       "github.com/zeebo/blake3"
 )

-func main(){
+func main() {
        data := []byte("Hello, world!")
-       sum:=blake3.Sum256(data)
+       sum := blake3.Sum256(data)
        fmt.Printf("%x\n", sum)
 }

コードがフォーマットされているかはgolangci-lint runを実行すると確認できます。

フォーマット前:

$ golangci-lint run
        "github.com/zeebo/blake3"
^
1 issues:
* gofmt: 1

フォーマット後:

$ golangci-lint run
0 issues.

終了コードに基づいてフォーマット済みかを確認する場合、golangci-lint fmt --diffgolangci-lint runもフォーマット前のときは非ゼロを返し、フォーマット後のときはゼロを返すのでこれが利用できます。
ただし、golangci-lint runはフォーマット済みでも他のlinterがエラーを返すときは非ゼロを返します。

参考文献

GitHubで編集を提案

Discussion