0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ENTの自動生成コードに対してgolangci-lintのエラーが出てしまう問題

Last updated at Posted at 2025-08-08

記事の概要

個人開発中、golangci-lint v1系で ent の自動生成コードに構文エラー扱いが出るv2.3.0 へ上げたら解消という現象が起きました。その問題について、原因から解決まで順序だててまとめた技術メモです。


ざっくり内容

  • 問題点: Go 1.24.x + ent v0.14.4 のプロジェクトで、golangci-lint v1.64.2 を回すと ent の生成コードに対して構文エラーが出る。
  • 直接原因: v1系にバンドルされた解析器/アナライザ(staticcheck/gosimple/govet など)のバージョンやビルド Go バージョンが、プロジェクト側(Go 1.24.x)に追随しておらず、新しい構文やコード生成パターンに追いつけていなかった。
  • 解決策: golangci-lintv2.3.0 に上げ、設定ファイルを v2 形式へ移行。これにより解析スタックが更新され、ent 生成コードの誤判定が解消。加えて v2 での書式(formatters)・設定キー変更に対応した。
  • 根拠ドキュメント: v2 への移行ガイドと新設定モデル(version: 2、formatter の導入、goimports の位置づけ変更など)を参照。 (golangci-lint)

環境

  • Go: 1.24.x

  • ent: v0.14.4

  • golangci-lint:

    • 以前: v1.64.2(コンテナ側)。ローカルでは v1.62.0 など古いものも混在
    • 以後: v2.3.0(コンテナ/ローカル共に統一)

何が起きていたのか

現れた症状(例)

  • ent の ent/ 配下の自動生成コード(Code generated by entc... DO NOT EDIT. などのヘッダ付き)で構文エラー扱いパーサの失敗が起きる。

  • あるいは golangci-lint 本体が 「ビルドに使われた Go が対象より古い」 と怒られる:

    the Go language version used to build golangci-lint is lower than the targeted Go version
    このチェックは v1系の段階から導入されており、バイナリが古い Go でビルドされていると失敗します。 (GitHub)

背景となる原因

  • golangci-lint複数のアナライザstaticcheck/gosimple/govet など)を同梱しており、それらがビルドされた Go のバージョンアナライザ自身の対応範囲に依存します。
  • プロジェクト側が新しめの Go(1.24.x)、かつ ent の生成コードが最新の構文/パターン(ジェネリクスのエッジケースや build tag、unsafe の使い方等)を含んでいる場合、古いアナライザがパースできずに壊れる/誤爆することがあります。
  • v2 系では golangci-lint 本体・同梱アナライザ群・設定体系が大きく更新され、新しい Go に対する互換性や挙動が改善されています(設定モデル刷新、フォーマッタ分離など)。 (golangci-lint)

解決までの流れ

1) golangci-lint を v2 へアップグレード

  • Homebrew(ローカル):

    brew upgrade golangci-lint
    golangci-lint version   # バージョン表示で v2.3.0 を確認
    
  • Go ツールチェインで明示ピン留め:

    go install github.com/golangci/golangci-lint/cmd/golangci-lint@v2.3.0
    
  • Dockerfile(開発用コンテナ):

    # 旧: v1.64.2
    # RUN go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.2
    
    # 新: v2.3.0
    RUN go install github.com/golangci/golangci-lint/cmd/golangci-lint@v2.3.0
    
  • プロジェクトがターゲットとする Go バージョン(go.mod の go directive)以上の Go でビルドされた golangci-lint を使うこと。古いバイナリだと前述のエラーが出ます。 (GitHub)

2) 設定ファイルを v2 形式に移行

v2 では 設定モデルが変わりました。代表的な変更点:

  • 必須: ルートに version: 2 を書く
  • goimports は linter ではなく “formatter” に移動(linters.enable から外して formatters.enable に入れる)
  • 旧キーが非互換: output.formatsoutput.format など
  • govet.check-shadowing のようなdeprecated 設定は整理(shadow は独立 linter)

公式の Migration GuideConfiguration(v2) ドキュメントが全体像です。 (golangci-lint)
また Formatters の概念/一覧(goimports を含む)は専用ページにまとまっています。 (golangci-lint)

既存の v1 設定から自動変換したい場合は golangci-lint migrate が用意されています(ただしコメントは落ちます)。 (golangci-lint)

v2 用の最小サンプル(今回のケースに合わせた例)

version: 2

run:
  timeout: 5m

issues:
  # 生成物/モックを丸ごと外す(正規表現はリポジトリルート相対)
  exclude-dirs:
    - ^ent($|/)           # ent 生成コード
    - ^src/mocks($|/)     # mockery 生成コード
  # 一時的に特定ファイルを外す場合
  exclude-files:
    - ^src/infrastructure/app_client\.go$

linters-settings:
  gocyclo:
    min-complexity: 15
  govet: {} # 個別設定不要なら空でOK

linters:
  enable:
    - errcheck
    - govet
    - ineffassign
    - staticcheck
    - gocyclo
    # - revive   # 必要に応じて

# ← v2 から導入: フォーマッタは linters とは別セクション
formatters:
  enable:
    - goimports
  goimports:
    local-prefixes: word_app/backend

output:
  format: colored-line-number
  sort-results: true
  • 以前の設定のまま v2 を起動すると、unsupported version of the configurationgoimports is a formatter などのエラーが出ます。これは 設定モデルの変更が原因なので、上記のように version: 2 を宣言し、goimports を formatters へ移動するなど、移行作業が必要となります。 (golangci-lint)

3) 除外設定の “効かない” を潰す

  • exclude-dirsリポジトリルートからの正規表現でマッチします。
    ent, src/mocks などは ^ent($|/), ^src/mocks($|/) のように先頭・末尾を意識した正規表現にすると安定します。
  • それでも個別に出る場合は issues.exclude-rules で “ファイルパス + 対象 linter + メッセージ” をピンポイントで抑制できます(テスト用途の自動生成 Mock に対してのみ staticcheck を外す等)。
issues:
  exclude-dirs:
    - ^ent($|/)
    - ^src/mocks($|/)
  exclude-rules:
    - path: ^src/mocks/
      linters:
        - staticcheck
        - errcheck
        - revive
      text: ".*"    # 生成 Mock は全面除外(必要最小限に)

なお、golangci-lint は 生成コード(ヘッダに “Code generated by … DO NOT EDIT.”) を自動判定してスキップする機構も持っています(generated_file_filter)。ただしすべての生成物を網羅できるわけではないため、ディレクトリ除外を併用するのが実務的です。


v2 へ上げたらなぜ直ったのか(メカニズム)

  1. バンドルされたアナライザ/パーサの更新
    v2 系では、staticcheck をはじめとする解析器が刷新・統合され、新しい Go バージョンやエッジな構文に対する互換性が上がっています。ent 生成コードで起きていたパース失敗/誤検知が解消しました。 (golangci-lint)
  2. ツール自体のビルド Go バージョン整合
    「golangci-lint をビルドした Go バージョン < プロジェクトのターゲット Go」だと実行時に弾かれるチェックもあり、ここが揃うことで解析系が正しく動作します。 (GitHub)
  3. 設定モデルの整理
    goimportslinter ではなく formatter として扱うなど、v2 の設計に合わせて設定を整理したことで、設定起因のエラーが消滅。本質的なコード解析に集中できる状態になりました。 (golangci-lint)

付録: よく出たエラーと対処メモ

  • unsupported version of the configuration
    version: 2 を設定ファイルの先頭に追加。設定キーも v2 に合わせて見直す。 (golangci-lint)
  • goimports is a formatter
    linters.enable から goimports を外し、formatters.enable に移動。 (golangci-lint)
  • the Go language version used to build golangci-lint is lower than the targeted Go version
    golangci-lint バイナリを更新(Homebrew / go install @v2.3.0 / Docker)。プロジェクトの Go と整合させる。 (GitHub)
  • モック/生成コードが除外されない
    exclude-dirs正規表現をリポジトリルート相対で見直し(^src/mocks($|/) 等)。必要に応じて exclude-rules で個別無効化。

まとめ

  • 症状は「v1 系の解析スタックが、Go 1.24 + ent の生成コードに追随できず壊れる/誤爆する」こと。
  • 解決は「golangci-lint を v2(今回は v2.3.0)へ上げ、設定を v2 仕様に移行」。
  • これで ent 生成コードでの構文エラー相当が消え、lint が安定稼働するようになりました。
  • v2 は 設定体系も変わっているため、version: 2formatter(goimports)の導入deprecated 設定の除去を忘れずに。 (golangci-lint)

参考リンク

  • Migration Guide (v2) – 移行の全体像、migrate コマンド、非互換点一覧
    (golangci-lint)
  • Configuration (v2) – 新しい設定モデル(version: 2 など)
    (golangci-lint)
  • Formattersgoimports を含むフォーマッタの説明
    (golangci-lint)
  • Changelog – v2 の主な変更(解析器刷新・統合等)
    (golangci-lint)
  • Go バージョン整合のチェック(ビルド Go が古いと失敗)
    (GitHub)
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?