RemitAid Tech Blog
🗑️

deadcode で不要なコードを削除 —— .deadcodeignore で誤検知を防ぎ 950 行削減

に公開

はじめに

RemitAid ソフトウェアエンジニアの inari111 です。
日々の開発で削除し忘れたコード、使うと思って用意したが実際には使われなかったコードをまとめて削除したので、どのように削除を進めていったかをご紹介します。

Dead Code とは

まず始めに、Dead Code について説明します。
Claude に聞いてみると以下のように回答がありました。

Dead code(デッドコード)とは、プログラム中に存在するが、実際には実行されることがない、または使用されることがないコードのことです。
主な種類

  • 到達不可能なコード
  • 使用されていない関数やメソッド
  • 使用されていない変数
  • 無効化されたコード

Go の公式ブログ https://go.dev/blog/deadcode でも同様に紹介されています。

Functions that are part of your project’s source code but can never be reached in any execution are called “dead code”, and they exert a drag on codebase maintenance efforts.

そしてこのブログでは deadcode (golang.org/x/tools/cmd/deadcode) というツールが紹介されています。
RemitAid ではこの deadcode を使って不要なコードを削除してみることにしました。

deadcode の使い方

deadcode は Go の公式ツールで、以下の手順で導入・使用できます。

まず、go install コマンドでインストールします。

go install golang.org/x/tools/cmd/deadcode@latest

インストール後、deadcode ./... を実行すると、main 関数から到達しないコードを検出できます。

deadcode ./...

テストコードも検出対象に含めたい場合は、-test フラグを使用します。

deadcode -test ./...

deadcode で検出されたが削除したくない場合

deadcode を実行すると削除したくないコードが検出されることもあります。
そこで、.deadcodeignore というファイルを用意し、記載したコードは検出されてもエラーにしないという方針をとることにしました。

# .deadcodeignore
# deadcode除外リスト

# ファイルパス + 関数名(行番号なし)
pkg/errors/errors.go: unreachable func: IsAlreadyExists

# ディレクトリ: そのディレクトリ配下の全検出を除外
testutil/

シェルスクリプトを用意し、deadcode の実行結果と .deadcodeignore を比較するようにしています。
シェルスクリプトは vibe coding で実装しました。

# run_deadcode.sh
main() {
    # deadcode 実行
    run_deadcode "normal" "Checking for dead code"

    # テストも対象に deadcode 実行
    run_deadcode "with-test" "Checking for dead code (including tests)"

    # ignoreファイルのバリデーション
    validate_ignore_file

    echo ""

    # 最終結果
    if [ $HAS_ERROR -eq 1 ]; then
        exit 1
    else
        exit 0
    fi
}

main "$@"

run_deadcode() {
    # deadcodeの実行
}

validate_ignore_file() {
    # deadcode 実行結果と .deadcodeignore に記載した除外対象を比べ、差異があれば HAS_ERROR=1 にする

    # 実装を削除した後も .deadcodeignore に残っている場合は HAS_ERROR=1 にする
}

deadcode で削除したコード

シェルスクリプトや .deadcodeignore の分があるので 359 行追加していますが、950 行削除することができました。
消したコードの内容はお見せできませんが、普段はなかなか気付けない箇所のコードだったので、deadcode を使って効率的に不要なコードを消すことができたのは良かったと感じています。

golangci-lint との併用

deadcode でプロジェクト全体の使われていない関数を検出できましたが、RemitAid では golangci-lint も併用し、GitHub Actions 上で実行しています。
golangci-lint には unused という linter があり、未使用の定数、変数、関数、型を検出できます。
deadcode で大まかな不要コードを削除し、日々の開発では golangci-lint の unused で細かい未使用要素を防ぐという使い分けをしています。

まとめ

本記事では、Go の deadcode ツールを使用した不要なコード削除の取り組みについてご紹介しました。
.deadcodeignore とシェルスクリプトで除外設定を管理することで、誤検出を防ぎながら効率的にコードを削除できます。
今回は 950 行のコードを削除でき、コードベースの保守性を向上させることができました。

普段はなかなか気付けない箇所のコードを効率的に見つけて削除できたのは良かったと感じています。
日々の開発では golangci-lint の unused と併用することで、継続的に不要なコードの混入を防いでいます。

RemitAid では一緒に働く仲間を募集しています。
興味がある方はこちらからどうぞ!

https://youtrust.jp/recruitment_posts/ad655de82471df86af4f19469fe4c0de

https://youtrust.jp/recruitment_posts/7141d690aaa5ed348de45757da069e81

Podcast 「RemiTalk」を最近始めましたので、もし良ければ聴いてみてください!

https://podcasts.apple.com/jp/podcast/remitalk/id1826516525

Podcast 文字起こしはこちら

https://note.com/remitaid

RemitAid Tech Blog
RemitAid Tech Blog

Discussion