[インデックス 13630] ファイルの概要
このコミットは、Go言語のコマンドラインツールcmd/go
におけるgo test -i
コマンドの挙動を修正するものです。具体的には、相対パスで指定されたテストパッケージの依存関係を処理する際に、ローカルインポートではないパスのみを対象とするように変更が加えられています。これにより、go test -i ./...
のようなコマンド実行時に、ローカルのテストデータディレクトリなどが誤ってインストール対象に含まれてしまう問題を解決しています。
変更されたファイルは以下の2つです。
src/cmd/go/test.bash
:go test -i
コマンドの相対パスでのテストケースを追加しています。src/cmd/go/test.go
:go test -i
コマンドの内部ロジックを修正し、ローカルインポートではないパスのみを依存関係として追加するように変更しています。
コミット
commit 34976b985a9e2d29c594daa2dfa4dd21ee4c4bf1
Author: Francisco Souza <franciscossouza@gmail.com>
Date: Wed Aug 15 07:32:49 2012 -0700
cmd/go: skipping relative paths on go test -i ./...
Fixes #3896.
R=rsc, rogpeppe, r
CC=golang-dev
https://golang.org/cl/6457075
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/34976b985a9e2d29c594daa2dfa4dd21ee4c4bf1
元コミット内容
diff --git a/src/cmd/go/test.bash b/src/cmd/go/test.bash
index fe186d4bbc..587bcfc1f9 100755
--- a/src/cmd/go/test.bash
+++ b/src/cmd/go/test.bash
@@ -76,6 +76,12 @@ if ! ./testgo test ./testdata/testimport; then
\tok=false
fi
+# Test installation with relative imports.
+if ! ./testgo test -i ./testdata/testimport; then
+ echo "go test -i ./testdata/testimport failed"
+ ok=false
+fi
+
# Test tests with relative imports in packages synthesized
# from Go files named on the command line.
if ! ./testgo test ./testdata/testimport/*.go; then
diff --git a/src/cmd/go/test.go b/src/cmd/go/test.go
index 5f40bd64c0..cd9b411e9d 100644
--- a/src/cmd/go/test.go
+++ b/src/cmd/go/test.go
@@ -276,7 +276,9 @@ func runTest(cmd *Command, args []string) {
\tall := []string{}
\tfor path := range deps {\n-\t\t\tall = append(all, path)\n+\t\t\tif !build.IsLocalImport(path) {\n+\t\t\t\tall = append(all, path)\n+\t\t\t}\n \t\t}\n \t\tsort.Strings(all)\n
変更の背景
この変更は、Go言語のIssue #3896「cmd/go: go test -i doesn't work if there are no Go files in the current directory.」を修正するために行われました。
元の問題は、go test -i
コマンドが、カレントディレクトリにGoファイルが存在しない場合に正しく機能しないというものでした。特に、go test -i ./...
のように相対パスとワイルドカードを組み合わせて使用した場合、テスト対象ではないローカルのディレクトリ(例えばテストデータが置かれたtestdata
ディレクトリなど)が誤って依存関係として認識され、インストール対象に含まれてしまうことがありました。これは、go test -i
がテストパッケージとその依存関係をインストールしようとする際に、相対パスで指定されたディレクトリを適切にフィルタリングできていなかったためです。
このコミットは、go test -i
がテストパッケージの依存関係を収集する際に、ローカルインポート(相対パスで指定されたパッケージ)をスキップすることで、この問題を解決しています。これにより、go test -i
が意図しないディレクトリをインストールしようとすることを防ぎ、コマンドの正確な挙動を保証します。
前提知識の解説
go test -i
コマンド
go test
コマンドはGo言語のテストを実行するための主要なツールです。-i
フラグは「install」を意味し、テストを実行する前にテストパッケージとその依存関係をインストールすることを指示します。これにより、テストの実行環境がクリーンな状態に保たれ、依存関係の解決が確実に行われることが期待されます。通常、go test
はテストを実行するだけで依存関係のインストールは行いませんが、-i
フラグを使用することで、テストの実行前に必要なパッケージがビルドされ、GOPATHのpkg
ディレクトリにインストールされます。
相対パスとパッケージのインポート
Go言語では、パッケージのインポートパスは通常、GOPATHまたはGo Modulesのルートからの絶対パスで指定されます(例: github.com/user/repo/package
)。しかし、同じモジュール内やローカルのファイルシステム上にあるパッケージを参照する際には、相対パスを使用することも可能です(例: ./subpackage
)。
build.IsLocalImport(path)
Go言語のgo/build
パッケージには、パッケージのインポートパスがローカルインポートであるかどうかを判定するためのIsLocalImport
関数が存在します。この関数は、与えられたパスが.
や..
で始まる相対パスである場合にtrue
を返します。この関数は、Goツールがパッケージの依存関係を解析し、ビルドやテストの際に適切な処理を行うために利用されます。
技術的詳細
このコミットの技術的な核心は、go test -i
コマンドがテストパッケージの依存関係を収集するロジックにbuild.IsLocalImport
関数を導入した点にあります。
go test -i
は、テスト対象のパッケージが依存するすべてのパッケージを特定し、それらをインストールしようとします。この「すべてのパッケージ」には、標準ライブラリのパッケージ、サードパーティのパッケージ、そして同じプロジェクト内の他のローカルパッケージが含まれます。
問題は、./...
のようなワイルドカードを含む相対パスが指定された場合、testdata
のようなテストデータが格納されているディレクトリもパッケージとして認識され、そのパスが依存関係のリストdeps
に含まれてしまうことでした。testdata
ディレクトリは通常、Goのソースファイルを含まないため、パッケージとしてビルド・インストールされるべきではありません。しかし、相対パスとして認識されるため、従来のロジックではこれをフィルタリングできませんでした。
この修正では、deps
マップから取得した各path
に対してbuild.IsLocalImport(path)
を呼び出し、その結果がfalse
(つまり、ローカルインポートではない)の場合にのみ、そのパスをall
スライスに追加するように変更しました。これにより、./testdata/testimport
のようなローカルの相対パスはインストール対象から除外され、go test -i
が意図しないディレクトリを処理しようとする問題が解決されました。
test.bash
の変更は、この修正が正しく機能することを確認するためのテストケースの追加です。go test -i ./testdata/testimport
というコマンドを実行し、それが成功することを確認しています。これは、修正によってローカルのテストデータディレクトリが正しくスキップされることを検証するものです。
コアとなるコードの変更箇所
src/cmd/go/test.bash
--- a/src/cmd/go/test.bash
+++ b/src/cmd/go/test.bash
@@ -76,6 +76,12 @@ if ! ./testgo test ./testdata/testimport; then
\tok=false
fi
+# Test installation with relative imports.
+if ! ./testgo test -i ./testdata/testimport; then
+ echo "go test -i ./testdata/testimport failed"
+ ok=false
+fi
+
# Test tests with relative imports in packages synthesized
# from Go files named on the command line.
if ! ./testgo test ./testdata/testimport/*.go; then
src/cmd/go/test.go
--- a/src/cmd/go/test.go
+++ b/src/cmd/go/test.go
@@ -276,7 +276,9 @@ func runTest(cmd *Command, args []string) {
\tall := []string{}
\tfor path := range deps {\n-\t\t\tall = append(all, path)\n+\t\t\tif !build.IsLocalImport(path) {\n+\t\t\t\tall = append(all, path)\n+\t\t\t}\n \t\t}\n \t\tsort.Strings(all)\n
コアとなるコードの解説
src/cmd/go/test.bash
の変更
このファイルは、go
コマンドのテストスクリプトです。追加された部分は、go test -i
コマンドが相対パスで指定されたテストデータディレクトリに対して正しく動作するかどうかを検証するための新しいテストケースです。
+if ! ./testgo test -i ./testdata/testimport; then
+ echo "go test -i ./testdata/testimport failed"
+ ok=false
+fi
このコードは、./testgo test -i ./testdata/testimport
というコマンドを実行しています。./testdata/testimport
は、Goのパッケージとしては無効な、単なるテストデータが格納されたディレクトリを想定しています。修正前は、このコマンドがエラーになったり、意図しない動作をしたりする可能性がありました。修正後は、go test -i
がこの相対パスをローカルインポートとして認識し、インストール対象からスキップするため、コマンドはエラーなく(または期待されるエラーで)終了するはずです。このテストケースの追加により、修正が意図通りに機能していることが自動的に検証されます。
src/cmd/go/test.go
の変更
このファイルは、go test
コマンドの主要なロジックを実装しています。変更された部分は、テストパッケージの依存関係を収集するループ内です。
all := []string{}
for path := range deps {
- all = append(all, path)
+ if !build.IsLocalImport(path) {
+ all = append(all, path)
+ }
}
sort.Strings(all)
元のコードでは、deps
マップ(テストパッケージの依存関係のパスがキーとして格納されている)から取得したすべてのpath
を無条件にall
スライスに追加していました。このall
スライスは、その後、インストール対象のパッケージリストとして使用されます。
修正後のコードでは、all = append(all, path)
の行がif !build.IsLocalImport(path) { all = append(all, path) }
という条件文で囲まれています。
build.IsLocalImport(path)
: この関数は、path
が.
や..
で始まる相対パスである場合にtrue
を返します。!build.IsLocalImport(path)
: この条件は、「path
がローカルインポートではない場合」を意味します。
したがって、この変更により、deps
に含まれるパスのうち、ローカルインポートではない(つまり、GOPATHやGo Modulesのルートからの絶対パスで指定されるような)パッケージのみがall
スライスに追加されるようになりました。これにより、./testdata/testimport
のようなローカルの相対パスは、go test -i
のインストール対象から除外され、問題が解決されます。
関連リンク
- Go Issue #3896: https://github.com/golang/go/issues/3896
- Go CL 6457075: https://golang.org/cl/6457075
参考にした情報源リンク
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFEusaC48YCUW7-hpxQlqYCv3Oq3jcx3pwAxIYfKR21QZqT91TJ2_DgLa2JH93coJt6LlCII6jwl-qcDw7kgX4IAnNUwXMbSXRjY4nqOWSZwwhbsO0wr3eV0kbg2cNgY7OxgA==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHXlLU7IyCJkgq7_pWWV9jSnhkq2kAOVX7Zb1mJjaYvf_b3AN9cb_Krx7MC-1JXno13IflIxFJAQn2woBQyatZMsRjKYAw4XbBHbmtkrF3MbJmeiylO-Q--PdK7uK7KfHI=