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

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

このコミットは、Go言語のテストユーティリティである gotest コマンドの動作を改善し、コマンドライン引数としてテスト対象のファイル名を指定できるようにするものです。これにより、ユーザーは特定のテストファイルのみを実行できるようになり、開発の柔軟性と効率が向上します。

コミット

  • コミットハッシュ: 8b8630c6cf95c44d59e415069e40c8845b6627c5
  • Author: Rob Pike r@golang.org
  • Date: Tue Nov 18 14:17:13 2008 -0800

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

https://github.com/golang/go/commit/8b8630c6cf95c44d59e415069e40c8845b6627c5

元コミット内容

allow files to be named on the command line

R=rsc
DELTA=3  (1 added, 1 deleted, 1 changed)
OCL=19485
CL=19485

変更の背景

初期のGo言語開発において、gotest コマンドは現在のディレクトリにある test*.go というパターンに一致するすべてのテストファイルを自動的に検出して実行する設計でした。これはシンプルなケースでは便利ですが、大規模なプロジェクトや特定のテストのみを実行したい場合には不便でした。

例えば、開発者が特定の機能に関連するテストファイルのみを素早く実行してデバッグしたい場合、以前の gotest の動作では、関連のない他のすべてのテストも実行されてしまい、時間とリソースの無駄が生じていました。このコミットは、このようなシナリオに対応するため、gotest コマンドにコマンドライン引数としてファイル名を直接指定する機能を追加し、より柔軟なテスト実行を可能にすることを目的としています。

前提知識の解説

gotest コマンド

gotest は、Go言語の初期のテスト実行ツールです。現在の go test コマンドの前身にあたります。Go言語のテストは、ファイル名が _test.go で終わるファイルに記述され、Test で始まる関数がテスト関数として認識されます。gotest はこれらのテストファイルをコンパイルし、実行するためのスクリプトでした。

シェルスクリプトの基本

このコミットで変更されている gotest はシェルスクリプトで書かれています。変更内容を理解するためには、以下のシェルスクリプトの概念が重要です。

  • set -e: このコマンドは、スクリプト内で実行されるコマンドが失敗(ゼロ以外の終了ステータスを返す)した場合、即座にスクリプトの実行を終了させることを意味します。これにより、エラーが発生した際にスクリプトが予期せぬ動作を続けることを防ぎ、堅牢性が向上します。
  • $(command) (コマンド置換): バッククォート `command` と同じく、command を実行し、その標準出力結果を文字列として現在のコマンドラインに挿入します。例えば、gofiles=$(echo test*.go)test*.go にマッチするファイル名を gofiles 変数に代入します。
  • echo: 引数を標準出力に出力するコマンドです。
  • sed: ストリームエディタ。テキストの変換に使用されます。sed 's/\\.go/.6/g' は、入力文字列中の .go.6 に置換します。これは、Goのコンパイル済みオブジェクトファイルが .6 拡張子を持つことに由来します。
  • シェルパラメータ展開 (${parameter:-word}): これはBashなどのシェルで利用できる強力な機能です。
    • $*: スクリプトに渡されたすべての位置パラメータ(コマンドライン引数)を単一の単語として展開します。例えば、./gotest file1.go file2.go と実行した場合、$*"file1.go file2.go" となります。
    • ${parameter:-word}: parameter が設定されていないか、またはnull(空文字列)の場合に word を展開します。そうでない場合は parameter の値を展開します。
      • このコミットでは gofiles=${*:-$(echo test*.go)} となっています。これは、gotest スクリプトにコマンドライン引数が渡された場合($* が空でない場合)は、その引数を gofiles に設定し、引数が渡されなかった場合($* が空の場合)は、$(echo test*.go) の結果(現在のディレクトリの test*.go ファイルリスト)を gofiles に設定するという意味になります。

技術的詳細

このコミットの核心は、gotest シェルスクリプトにおける gofiles 変数の初期化方法の変更です。

変更前は、gofiles 変数は常に $(echo test*.go) の結果、つまり現在のディレクトリにある test*.go というパターンに一致するすべてのファイル名に設定されていました。これは、gotest が常にディレクトリ内のすべてのテストを実行することを意味していました。

変更後は、gofiles=${*:-$(echo test*.go)} という行に置き換えられました。この変更により、gotest スクリプトが実行される際に、コマンドライン引数が存在するかどうかがチェックされます。

  1. コマンドライン引数が存在する場合: $* が空でないため、gofiles 変数には $* の値、すなわちコマンドラインで指定されたファイル名が設定されます。これにより、ユーザーは gotest file1_test.go file2_test.go のように特定のテストファイルのみを指定して実行できるようになります。
  2. コマンドライン引数が存在しない場合: $* が空であるため、${*:-$(echo test*.go)}:- の後の部分が評価され、gofiles 変数には $(echo test*.go) の結果が設定されます。これは、以前のデフォルトの動作と同じであり、引数なしで gotest を実行した場合には、引き続きディレクトリ内のすべての test*.go ファイルが対象となります。

この変更は、gotest の柔軟性を大幅に向上させ、ユーザーがテスト実行の対象をより細かく制御できるようにしました。

また、echo $ofiles の行が削除されています。これは、おそらくデバッグ目的で一時的に追加されていた出力行であり、機能には影響しないため、クリーンアップの一環として削除されたと考えられます。

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

--- a/src/cmd/gotest/gotest
+++ b/src/cmd/gotest/gotest
@@ -6,13 +6,13 @@
 # Using all the test*.go files in the current directory, write out a file
 # _testmain.go that runs all its tests. Compile everything and run the
 # tests.
+# If files are named on the command line, use them instead of test*.go.
  
 set -e
  
-gofiles=$(echo test*.go)
+gofiles=${*:-$(echo test*.go)}
 ofiles=$(echo $gofiles | sed 's/\.go/.6/g')
 files=$(echo $gofiles | sed 's/\.go//g')
-echo $ofiles
  
 for i in $gofiles
 do

コアとなるコードの解説

  1. # If files are named on the command line, use them instead of test*.go.:

    • これは追加されたコメント行で、このコミットの目的を明確に説明しています。コマンドラインでファイル名が指定された場合、test*.go の代わりにそれらのファイルを使用するという新しい動作を示しています。
  2. -gofiles=$(echo test*.go):

    • 変更前の行です。gofiles 変数に、現在のディレクトリにある test*.go パターンに一致するすべてのファイル名を代入していました。これは、常にすべてのテストファイルが対象となることを意味していました。
  3. +gofiles=${*:-$(echo test*.go)}:

    • 変更後の行です。これがこのコミットの主要な変更点です。
    • ${*:-word} というシェルパラメータ展開を使用しています。
    • $* は、スクリプトに渡されたすべてのコマンドライン引数を表します。
    • この構文により、gotest コマンドに引数が渡された場合(例: gotest my_test.go)、gofiles には my_test.go が設定されます。
    • 引数が渡されなかった場合(例: gotest)、gofiles には $(echo test*.go) の結果、つまり現在のディレクトリのすべての test*.go ファイルが設定されます。
    • これにより、コマンドライン引数によるテスト対象ファイルの選択が可能になりました。
  4. -echo $ofiles:

    • 削除された行です。ofiles 変数(.go.6 に置換したファイル名リスト)の内容を標準出力に出力していました。これはデバッグ目的か、あるいは単に不要な出力であったため、このコミットで削除されました。機能的な影響はありません。

これらの変更により、gotest はより柔軟なテスト実行オプションを提供し、開発者が特定のテストファイルに焦点を当てて作業できるようになりました。

関連リンク

  • Go言語の初期のコミット履歴は、現在のGoプロジェクトの進化を理解する上で貴重な情報源です。
  • go test コマンドの現在のドキュメント: https://pkg.go.dev/cmd/go#hdr-Test_packages (これは現在の go test のドキュメントであり、gotest の直接的なドキュメントではありませんが、その進化を理解する上で参考になります。)

参考にした情報源リンク