[インデックス 15179] ファイルの概要
このコミットは、Go言語のコマンドラインツール go test
の挙動に関するドキュメントと実装の変更を扱っています。具体的には、go test
が認識しないフラグ(オプション)をコマンドラインで指定する際の正しい位置について、ユーザーに明確な指示を与えるための修正です。
コミット
commit 482f3e8481465bccefea2a0093e5fbeefb30bb29
Author: Robert Daniel Kortschak <dan.kortschak@adelaide.edu.au>
Date: Fri Feb 8 16:00:59 2013 -0500
cmd/go: indicate that flags unrecognized by 'go test' must follow package specification
R=rsc, minux.ma
CC=golang-dev
https://golang.org/cl/7300063
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/482f3e8481465bccefea2a0093e5fbeefb30bb29
元コミット内容
cmd/go: indicate that flags unrecognized by 'go test' must follow package specification
このコミットメッセージは、go test
コマンドが認識しないフラグは、パッケージ指定の後に配置する必要があることを示す、という変更の意図を簡潔に述べています。
変更の背景
Go言語の go test
コマンドは、テストの実行、ベンチマーク、プロファイリングなど、Goプロジェクトのテストに関連する多岐にわたる機能を提供します。このコマンドは、Goツールチェーンの一部として、特定のフラグ(例: -v
で詳細出力、-bench
でベンチマーク実行)を認識し、それに応じて動作を変更します。
しかし、go test
コマンド自体が認識しないフラグを、テストバイナリ(go test
がコンパイルして実行するテストプログラム)に渡したい場合があります。例えば、テストバイナリが独自のコマンドライン引数を処理するように設計されている場合などです。
このコミットが作成された背景には、ユーザーが go test
コマンドに、go test
自身が処理すべきフラグと、テストバイナリに渡すべきフラグを混同して指定してしまうという問題があったと考えられます。Goのコマンドライン引数処理の慣習として、コマンド自身が処理する引数と、そのコマンドが起動するサブプロセスに渡す引数を区別するために、--
のようなセパレータを使用したり、引数の順序に特定のルールを設けたりすることが一般的です。
このコミットは、go test
が認識しないフラグをテストバイナリに正しく渡すための明確なルールを導入し、ユーザーの混乱を避けることを目的としています。具体的には、「go test
が認識しないフラグは、パッケージ指定の後に配置しなければならない」というルールを明文化し、ドキュメントとコードコメントに追加することで、ユーザーが意図した通りにテストを実行できるように改善しています。
前提知識の解説
Go言語の go test
コマンド
go test
は、Go言語の標準的なテストツールです。Goのソースコード内に記述されたテスト関数(TestXxx
、BenchmarkXxx
、ExampleXxx
など)を検出し、それらをコンパイルしてテストバイナリを生成し、実行します。
go test
コマンドは、以下のような一般的な形式で実行されます。
go test [flags] [packages]
[flags]
:go test
コマンド自身が解釈するフラグです。例:-v
: 詳細なテスト結果を出力します。-run <regexp>
: 指定された正規表現にマッチするテストのみを実行します。-bench <regexp>
: 指定された正規表現にマッチするベンチマークのみを実行します。-cpu <list>
: 指定されたGOMAXPROCS値でテストを実行します。-cover
: カバレッジ情報を収集します。
[packages]
: テストを実行するパッケージを指定します。例:./...
(カレントディレクトリ以下の全パッケージ)、./my/package
。
コマンドライン引数のパース
多くのコマンドラインツールでは、引数のパース(解析)に特定の規則があります。特に、コマンド自身が処理する引数と、そのコマンドが起動する別のプログラムに渡す引数を区別するメカニズムが重要になります。
一般的な慣習として、以下のようなパターンがあります。
--
セパレータ: 一部のコマンドでは、--
を使用して、それ以降の引数をサブコマンドや別のプログラムに渡すことを示します。例:git commit -m "message" -- -s
(ここで-s
はgit commit
ではなく、エディタに渡される)。- 引数の順序: 引数の種類によって、コマンドライン上での出現順序が厳密に定められている場合があります。例えば、コマンド自身のフラグはコマンド名の直後に、ファイルパスやサブプログラムへの引数はその後に続く、といった規則です。
このコミットは、go test
における後者の「引数の順序」に関するルールを明確にしています。go test
が認識しないフラグは、go test
コマンド自身が処理するのではなく、コンパイルされたテストバイナリに渡されます。このとき、それらの「認識されないフラグ」は、パッケージ指定の後に置かれる必要がある、というルールです。
例えば、go test -v ./my/package -myflag value
のように指定した場合、-v
は go test
が処理し、-myflag value
は my/package
のテストバイナリに渡されることになります。もし -myflag value
がパッケージ指定の前に置かれた場合、go test
はそれを自身のフラグとして解釈しようとし、認識できないためにエラーとなるか、意図しない挙動を引き起こす可能性があります。
技術的詳細
このコミットの技術的な詳細は、主にGoツールチェーンの cmd/go
パッケージにおける go test
コマンドの引数パースロジックと、そのドキュメント化に焦点を当てています。
go test
コマンドは、内部的に flag
パッケージを使用して自身のフラグを解析します。しかし、go test
は単に自身のフラグを処理するだけでなく、テストバイナリに渡すべきフラグも適切に分離して処理する必要があります。
コミットメッセージにある「Flags not recognized by 'go test' must be placed after any specified packages.
」という指示は、go test
のコマンドライン引数処理の内部的な仕組みに基づいています。
go test
は、まず自身のフラグ(例:-v
,-run
)を解析します。- 次に、パッケージ指定(例:
./...
,github.com/foo/bar
)を解析します。 - パッケージ指定の後に続く引数で、かつ
go test
自身が認識しないフラグは、テストバイナリに渡すための引数として扱われます。
この順序が重要であり、もし認識されないフラグがパッケージ指定の前に置かれると、go test
はそれを自身のフラグとして解釈しようとし、結果として「不明なフラグ」エラーを発生させるか、あるいは誤ってパッケージ名の一部として解釈してしまう可能性があります。
このコミットは、この挙動をユーザーに明確に伝えるために、src/cmd/go/doc.go
(Goコマンドのヘルプドキュメント)と src/cmd/go/test.go
(go test
コマンドの実装ファイル内のコメント)の両方に同じ注意書きを追加しています。これにより、ユーザーは go help test
コマンドを実行した際や、ソースコードを読んだ際に、この重要なルールを理解できるようになります。
これは、Goツールチェーンのユーザーエクスペリエンスを向上させるための、小さなしかし重要なドキュメントとコードの整合性に関する改善です。
コアとなるコードの変更箇所
このコミットによる変更は、以下の2つのファイルに限定されています。
src/cmd/go/doc.go
src/cmd/go/test.go
それぞれのファイルで、全く同じ行が追加されています。
--- a/src/cmd/go/doc.go
+++ b/src/cmd/go/doc.go
@@ -766,6 +766,8 @@ will compile the test binary and then run it as
The test flags that generate profiles also leave the test binary in pkg.test
for use when analyzing the profiles.
+Flags not recognized by 'go test' must be placed after any specified packages.
+
Description of testing functions
--- a/src/cmd/go/test.go
+++ b/src/cmd/go/test.go
@@ -167,6 +167,8 @@ will compile the test binary and then run it as
The test flags that generate profiles also leave the test binary in pkg.test
for use when analyzing the profiles.
+\n+Flags not recognized by 'go test' must be placed after any specified packages.
`,
}
コアとなるコードの解説
追加された行は以下の通りです。
Flags not recognized by 'go test' must be placed after any specified packages.
この行は、go test
コマンドのドキュメントと、go test
コマンドの内部的な説明コメントの両方に追加されました。
src/cmd/go/doc.go
: このファイルは、go help
コマンドで表示されるGoコマンド全体のドキュメントを生成するためのソースです。このファイルにこの行を追加することで、ユーザーがgo help test
を実行した際に、この重要な情報が直接表示されるようになります。これは、ユーザーがコマンドライン引数の正しい使い方を理解するための主要な情報源となります。src/cmd/go/test.go
: このファイルはgo test
コマンドの実際のロジックを実装しています。このファイル内のコメントにこの行を追加することは、主に開発者向けです。go test
のコードを将来的に変更する開発者が、コマンドライン引数のパースに関するこの重要な規則を認識し、それに従ってコードを維持・変更するための注意喚起となります。
この変更は、コードの機能的な挙動を変更するものではなく、既存の挙動に関するドキュメントと内部コメントを改善し、ユーザーと開発者の両方にとっての明確性を高めることを目的としています。これにより、go test
コマンドの使い方がより明確になり、誤った引数指定による混乱やエラーが減少することが期待されます。
関連リンク
- Go言語公式ドキュメント: https://golang.org/doc/
go test
コマンドのドキュメント(現在のバージョン): https://golang.org/cmd/go/#hdr-Test_packages- Go言語の
flag
パッケージ: https://golang.org/pkg/flag/
参考にした情報源リンク
- Go言語のソースコードリポジトリ: https://github.com/golang/go
- Go言語のコードレビューシステム (Gerrit): https://go-review.googlesource.com/
- このコミットのGerritチェンジリスト: https://golang.org/cl/7300063 (コミットメッセージに記載されているリンク)
- 一般的なコマンドライン引数パースの慣習に関する知識