Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 10455] ファイルの概要

このコミットは、Go言語プロジェクトのコードレビューシステムにおけるgofmtチェックの適用範囲を拡張するものです。具体的には、src/ディレクトリ内のファイルだけでなく、test/ディレクトリ(ただしtest/bench/を除く)以外のすべての.goファイルに対してgofmtによるフォーマットチェックが実行されるように変更されました。これにより、ドキュメントディレクトリ(doc/)内のGoコードなど、これまでチェック対象外だったファイルもフォーマットの統一性が保たれるようになります。

コミット

commit 28cead8b6c342126d2c2277303ba0a8bde4e7bfe
Author: David Crawshaw <david.crawshaw@zentus.com>
Date:   Fri Nov 18 12:42:30 2011 -0800

    codereview: gofmt check for non-src/ files
    
    Gives other projects the benefit of the gofmt presubmit.
    Results in minor changes in the doc/ directory:
            find doc -name \*.go -exec gofmt -d {} \;
    
    R=rsc, gri
    CC=golang-dev
    https://golang.org/cl/5158042

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/28cead8b6c342126d2c2277303ba0a8bde4e7bfe

元コミット内容

codereview: gofmt check for non-src/ files

このコミットは、gofmtによるプリコミットチェックをsrc/以外のファイルにも適用するように変更します。これにより、他のプロジェクトもgofmtプリコミットの恩恵を受けることができます。結果として、doc/ディレクトリ内のファイルに軽微な変更が生じました。

変更の背景

Go言語プロジェクトでは、コードの可読性と一貫性を保つためにgofmtというツールが広く利用されています。gofmtはGoのソースコードを標準的なスタイルに自動的にフォーマットするツールです。コミット以前は、このgofmtによるフォーマットチェックが、主にGoの主要なソースコードが配置されているsrc/ディレクトリ内のファイルと、ベンチマークコードが配置されているtest/bench/ディレクトリ内のファイルに限定されていました。

しかし、Goプロジェクトのリポジトリには、doc/ディレクトリ内のGo言語のサンプルコードや、その他のユーティリティスクリプトなど、src/test/bench/以外にも.go拡張子を持つファイルが存在します。これらのファイルがgofmtのチェック対象外であると、プロジェクト全体でのコードフォーマットの一貫性が損なわれる可能性がありました。

このコミットの背景には、プロジェクト全体でコードの品質と一貫性を向上させたいという意図があります。gofmtの適用範囲を広げることで、Go言語のコードが含まれるすべてのファイルが、Goコミュニティで推奨される標準的なフォーマットに従うことが保証され、結果としてコードベース全体の保守性が向上します。コミットメッセージにある「Gives other projects the benefit of the gofmt presubmit.」という記述は、Goプロジェクト内の様々なサブプロジェクトやドキュメント内のコードも、この自動フォーマットチェックの恩恵を受けることを示唆しています。

前提知識の解説

  • gofmt: gofmtはGo言語のソースコードを自動的にフォーマットするツールです。Go言語の公式ツールチェインの一部として提供されており、インデント、スペース、改行などのスタイルを統一します。これにより、Goコードの可読性が向上し、開発者間のスタイルに関する議論を減らすことができます。Goコミュニティでは、gofmtによってフォーマットされたコードが標準とされています。
  • プリコミットチェック (Presubmit Check): ソフトウェア開発において、コードがバージョン管理システム(例: Git)にコミットされる前に自動的に実行される一連のテストやチェックのことです。これには、コードのコンパイル、単体テストの実行、リンティング(コードスタイルのチェック)、フォーマットチェックなどが含まれます。プリコミットチェックの目的は、不具合やスタイル違反がメインのコードベースに混入するのを防ぎ、コードの品質を維持することです。
  • Go言語のディレクトリ構造: Go言語のプロジェクトでは、慣習的に特定のディレクトリ構造が用いられます。
    • src/: 主にGoのソースコードが配置されるディレクトリです。
    • test/: テストコードが配置されるディレクトリです。
    • test/bench/: ベンチマークテストのコードが配置されるディレクトリです。
    • doc/: ドキュメントやサンプルコードが配置されるディレクトリです。
  • codereview.py: Goプロジェクトのコードレビューシステムで使用されるPythonスクリプトの一部です。このスクリプトは、コードレビュープロセスの一環として、提出された変更セット(チェンジリスト)に対して様々な自動チェックを実行します。これには、gofmtによるフォーマットチェックも含まれます。

技術的詳細

このコミットの技術的な核心は、lib/codereview/codereview.pyファイル内のCheckGofmt関数のファイルフィルタリングロジックの変更にあります。

変更前は、CheckGofmt関数は以下の条件で.goファイルをフィルタリングしていました。 files = [f for f in files if (f.startswith('src/') or f.startswith('test/bench/')) and f.endswith('.go')] このロジックは、「ファイルパスがsrc/で始まる」または「ファイルパスがtest/bench/で始まる」.goファイルのみをgofmtのチェック対象としていました。つまり、Goの主要なソースコードとベンチマークコードに限定されていたわけです。

変更後のロジックは以下の通りです。 files = [f for f in files if (not f.startswith('test/') or f.startswith('test/bench/')) and f.endswith('.go')] この新しいロジックは、より広範なファイルを対象とします。具体的には、以下の条件を満たす.goファイルがチェック対象となります。

  1. ファイルパスが.goで終わる。
  2. ファイルパスがtest/で始まらない(ただし、test/bench/で始まる場合は例外的に含める)。

この変更により、test/ディレクトリ直下や、test/内の他のサブディレクトリにあるGoファイルは引き続きgofmtのチェック対象外となりますが、src/doc/、その他のルートディレクトリ直下にあるGoファイルなど、test/ディレクトリに属さないすべてのGoファイルがgofmtのチェック対象に含まれるようになりました。

このフィルタリングロジックの変更は、Goプロジェクト全体のコード品質と一貫性を向上させるための重要なステップです。gofmtの適用範囲を広げることで、Go言語のコードが含まれるすべてのファイルが、Goコミュニティで推奨される標準的なフォーマットに従うことが保証され、結果としてコードベース全体の保守性が向上します。

コアとなるコードの変更箇所

--- a/lib/codereview/codereview.py
+++ b/lib/codereview/codereview.py
@@ -895,7 +895,7 @@ def CheckFormat(ui, repo, files, just_warn=False):\
 
 # Check that gofmt run on the list of files does not change them
 def CheckGofmt(ui, repo, files, just_warn):\
-	files = [f for f in files if (f.startswith('src/') or f.startswith('test/bench/')) and f.endswith('.go')]\
+	files = [f for f in files if (not f.startswith('test/') or f.startswith('test/bench/')) and f.endswith('.go')]\
 	if not files:\
 		return\
 	cwd = os.getcwd()\

コアとなるコードの解説

変更はlib/codereview/codereview.pyファイル内のCheckGofmt関数にあります。この関数は、コードレビューのプリコミット段階でgofmtがGoファイルに変更を加えないことを確認する役割を担っています。

変更された行は、gofmtを適用する対象となるファイルをフィルタリングするリスト内包表記です。

  • 変更前: files = [f for f in files if (f.startswith('src/') or f.startswith('test/bench/')) and f.endswith('.go')] この行は、渡されたファイルリストfilesの中から、以下の条件をすべて満たすファイルのみを抽出していました。

    1. ファイル名が.goで終わる。
    2. ファイルパスがsrc/で始まる、またはtest/bench/で始まる。 これにより、gofmtのチェックはGoの主要なソースコードとベンチマークコードに限定されていました。
  • 変更後: files = [f for f in files if (not f.startswith('test/') or f.startswith('test/bench/')) and f.endswith('.go')] この行は、ファイルフィルタリングのロジックを拡張しています。新しい条件は以下の通りです。

    1. ファイル名が.goで終わる。
    2. ファイルパスがtest/で始まらない、またはtest/bench/で始まる。 このロジックは、「test/ディレクトリに属さないすべての.goファイル」と、「test/bench/ディレクトリに属する.goファイル」を対象とします。これにより、doc/ディレクトリ内のGoファイルなど、これまでgofmtのチェック対象外だったファイルも含まれるようになり、プロジェクト全体でのフォーマットの一貫性が強化されます。

この変更は、Goプロジェクトのコードベース全体にわたるコード品質と保守性の向上に貢献します。

関連リンク

  • Go言語公式サイト: https://go.dev/
  • gofmtに関する公式ドキュメント: gofmtはGoのツールチェインの一部であり、通常はGoの公式ドキュメントやgo help gofmtコマンドで詳細を確認できます。

参考にした情報源リンク