[インデックス 12698] ファイルの概要
このコミットは、Go言語のビルドシステムにおいて、テスト実行前にGOPATH
環境変数を解除する変更を導入しています。これは、GOROOT
(Goのインストールディレクトリ)がGOPATH
の配下にある場合に、非ローカルパッケージに対するローカルインポートが許可されないというGoのビルドルールにより、一部のテストがビルドに失敗する問題を解決するためのものです。
コミット
commit 23322ab841c2d6192557a9a0cae3ace40bff8c9d
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Wed Mar 21 00:47:27 2012 +0800
build: unset GOPATH before tests
This is because we disallow local import for non-local packages, if
GOROOT happens to be under one of GOPATH, then some tests will fail
to build.
Fixes #3337.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5852043
---
src/run.bash | 2 +++
src/run.bat | 4 ++++
2 files changed, 6 insertions(+)
diff --git a/src/run.bash b/src/run.bash
index 748f6e93f5..41ab37e3c2 100755
--- a/src/run.bash
+++ b/run.bash
@@ -8,6 +8,8 @@ set -e
eval $(go env)
unset CDPATH # in case user has it set
+unset GOPATH # we disallow local import for non-local packages, if $GOROOT happens
+ # to be under $GOPATH, then some tests below will fail
# no core files, please
ulimit -c 0
diff --git a/src/run.bat b/src/run.bat
index 1d5bf60f25..c7a1579728 100644
--- a/src/run.bat
+++ b/src/run.bat
@@ -12,6 +12,10 @@ setlocal
set GOBUILDFAIL=0
+:: we disallow local import for non-local packages, if %GOROOT% happens
+:: to be under %GOPATH%, then some tests below will fail
+set GOPATH=
+
rem TODO avoid rebuild if possible
if x%1==x--no-rebuild goto norebuild
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/23322ab841c2d6192557a9a0cae3ace40bff8c9d
元コミット内容
build: unset GOPATH before tests
This is because we disallow local import for non-local packages, if
GOROOT happens to be under one of GOPATH, then some tests will fail
to build.
Fixes #3337.
変更の背景
この変更の背景には、Go言語のビルドシステムにおける特定の環境設定とパッケージインポートのルールが関係しています。
Go言語では、GOROOT
とGOPATH
という2つの重要な環境変数があります。
GOROOT
: GoのSDK(コンパイラ、ツール、標準ライブラリなど)がインストールされているディレクトリを指します。GOPATH
: Goのワークスペースのルートディレクトリを指します。ここには、ユーザーが開発するGoのソースコード、ダウンロードされたパッケージ、コンパイルされたバイナリなどが格納されます。
Goのビルドルールには、「非ローカルパッケージに対するローカルインポートを許可しない」というものがあります。ここでいう「ローカルインポート」とは、相対パス(例: ./mypackage
)を使ったインポートを指します。一方、「非ローカルパッケージ」とは、標準ライブラリやGOPATH
外のモジュールなど、現在のプロジェクトのソースツリーに直接含まれないパッケージを指します。
問題は、開発環境のセットアップによっては、GOROOT
が誤ってGOPATH
のサブディレクトリとして設定されてしまうケースがあったことです。このような状況下でGoのテストを実行しようとすると、Goのビルドツールは標準ライブラリのパッケージ(これらは非ローカルパッケージと見なされる)を、GOPATH
内の相対パスとして解釈しようとします。しかし、Goのルールでは非ローカルパッケージに対するローカルインポートは許可されていないため、ビルドエラーが発生し、テストが失敗するという事態が生じていました。
このコミットは、この問題を解決するために、テストを実行するスクリプト(run.bash
とrun.bat
)において、テスト開始前に明示的にGOPATH
環境変数を解除することで、GoのビルドツールがGOROOT
内の標準ライブラリを正しく認識し、ビルドエラーを回避するようにしています。コミットメッセージにあるFixes #3337
は、Goの内部的な課題追跡システムにおける特定のバグ報告に対応するものであると考えられます。
前提知識の解説
Goの環境変数: GOROOT
とGOPATH
GOROOT
: Goのインストールパスです。Goのコンパイラ、標準ライブラリ、ツールなどがこのディレクトリに格納されています。通常、ユーザーが手動で設定する必要はありませんが、複数のGoバージョンを切り替える場合などに設定することがあります。GOPATH
: Goのワークスペースのルートパスです。Go 1.11でGo Modulesが導入される以前は、Goのプロジェクトは必ず$GOPATH/src
以下に配置する必要がありました。Go Modules導入後も、go get
でダウンロードされるパッケージや、go install
で生成されるバイナリはGOPATH
配下に格納されます。GOPATH
は複数のパスを設定することも可能で、Goツールはこれらのパスを順に検索します。
Goのパッケージインポートルール
Goのパッケージインポートには、主に以下の2種類があります。
- 絶対パスインポート:
fmt
、net/http
、github.com/user/repo/package
のように、パッケージの完全なインポートパスを指定する方法です。Goツールは、GOROOT
、GOPATH
、またはGo Modulesのキャッシュからこれらのパッケージを探します。 - 相対パスインポート:
./mypackage
、../anotherpackage
のように、現在のファイルからの相対パスでパッケージを指定する方法です。これは、通常、同じモジュール内または同じGOPATH
ワークスペース内のローカルパッケージをインポートする場合にのみ使用されます。
Goのビルドルールでは、非ローカルパッケージ(つまり、現在のモジュールやGOPATH
ワークスペースに属さない外部パッケージや標準ライブラリ)を相対パスでインポートすることは許可されていません。これは、インポートパスの曖昧さをなくし、ビルドの再現性を高めるための重要な制約です。
ビルドとテストのプロセス
Goプロジェクトのビルドやテストは、go build
やgo test
コマンドによって行われます。これらのコマンドは、Goの環境変数(特にGOROOT
とGOPATH
)を参照して、ソースコードの場所、依存関係、およびコンパイル済みバイナリの出力先を決定します。
技術的詳細
このコミットが解決しようとしている問題は、GoのビルドシステムがGOPATH
とGOROOT
の特定の関係性によって誤動作するという、環境設定に起因するものです。
具体的には、もしGOROOT
(例: /usr/local/go
)がGOPATH
(例: /home/user/go
)のサブディレクトリとして設定されてしまった場合(例: /home/user/go/go
のような不適切な設定)、Goのビルドツールは混乱します。Goの標準ライブラリ(fmt
, net/http
など)はGOROOT
内に存在しますが、GOPATH
が設定されていると、GoツールはまずGOPATH
配下でパッケージを探そうとします。
この時、Goのビルドツールは、標準ライブラリのパッケージをGOPATH
内の相対パスとして解釈しようとする可能性があります。例えば、fmt
パッケージをインポートする際に、GOPATH
が設定されていると、Goツールは$GOPATH/src/fmt
のようなパスを探索しようとします。しかし、fmt
は標準ライブラリであり、GOROOT
内に存在するため、これは「非ローカルパッケージ」に該当します。Goのルールでは、非ローカルパッケージを相対パスでインポートすることは許可されていないため、この状況下でビルドエラーが発生します。
このコミットは、テスト実行前にGOPATH
を一時的に解除することで、この問題を回避します。GOPATH
が解除されると、Goツールは標準ライブラリの探索においてGOROOT
を優先的に参照するようになります。これにより、標準ライブラリが非ローカルパッケージとして正しく認識され、相対パスでのインポート試行によるビルドエラーが回避され、テストが正常に実行できるようになります。
この変更は、Goのビルドスクリプト(run.bash
とrun.bat
)に直接行われているため、Goのソースコードをビルド・テストする際の環境設定に影響を与えます。これは、Goの開発者がGo自身のテストを実行する際の安定性を確保するために重要な修正です。
コアとなるコードの変更箇所
diff --git a/src/run.bash b/src/run.bash
index 748f6e93f5..41ab37e3c2 100755
--- a/src/run.bash
+++ b/src/run.bash
@@ -8,6 +8,8 @@ set -e
eval $(go env)
unset CDPATH # in case user has it set
+unset GOPATH # we disallow local import for non-local packages, if $GOROOT happens
+ # to be under $GOPATH, then some tests below will fail
# no core files, please
ulimit -c 0
diff --git a/src/run.bat b/src/run.bat
index 1d5bf60f25..c7a1579728 100644
--- a/src/run.bat
+++ b/src/run.bat
@@ -12,6 +12,10 @@ setlocal
set GOBUILDFAIL=0
+:: we disallow local import for non-local packages, if %GOROOT% happens
+:: to be under %GOPATH%, then some tests below will fail
+set GOPATH=
+
rem TODO avoid rebuild if possible
if x%1==x--no-rebuild goto norebuild
コアとなるコードの解説
このコミットは、Goのビルドおよびテスト実行に使用されるシェルスクリプト(src/run.bash
)とバッチスクリプト(src/run.bat
)に、それぞれ1行の変更とコメントの追加を行っています。
src/run.bash
(Unix/Linux/macOS向けシェルスクリプト)
unset GOPATH # we disallow local import for non-local packages, if $GOROOT happens
# to be under $GOPATH, then some tests below will fail
unset GOPATH
: このコマンドは、現在のシェルセッションからGOPATH
環境変数を解除します。これにより、Goのビルドツールは、テスト実行中にGOPATH
の値を参照しなくなります。- コメント:
GOPATH
を解除する理由が明確に説明されています。「非ローカルパッケージに対するローカルインポートを許可しない」というGoのルールと、GOROOT
がGOPATH
の配下にある場合にテストが失敗する可能性が指摘されています。
src/run.bat
(Windows向けバッチスクリプト)
set GOPATH=
set GOPATH=
: このコマンドは、WindowsのバッチファイルにおいてGOPATH
環境変数を空文字列に設定することで、実質的にGOPATH
を解除します。Unix系のunset
コマンドと同様の効果があります。- コメント: シェルスクリプトと同様に、
GOPATH
を解除する理由が説明されています。
これらの変更により、Goのテストが実行される前にGOPATH
が確実に解除されるため、GOROOT
とGOPATH
の間の潜在的な競合が解消され、テストのビルドが安定して行われるようになります。これは、Goのビルドシステムの堅牢性を高めるための重要な修正です。
関連リンク
- GitHubコミットページ: https://github.com/golang/go/commit/23322ab841c2d6192557a9a0cae3ace40bff8c9d
- Go CL (Code Review): https://golang.org/cl/5852043
参考にした情報源リンク
- Go Modules and GOPATH: https://go.dev/blog/using-go-modules
- Go Environment Variables (GOROOT, GOPATH): https://go.dev/doc/code
- Go Package Paths: https://go.dev/ref/mod#go-mod-file-paths
- Go Modules: https://go.dev/blog/go111module
- Go Modules and GOPATH (GeeksforGeeks): https://www.geeksforgeeks.org/go-modules-and-gopath/
- Understanding GOROOT and GOPATH in Go (Medium): https://medium.com/@go_lang_fan/understanding-goroot-and-gopath-in-go-101-a7b7b7b7b7b7 (Note: This is a placeholder URL, as the exact article from the search results was not directly linkable, but the content was used for general understanding of GOROOT/GOPATH.)
- Go Modules and GOPATH (TutorialsPoint): https://www.tutorialspoint.com/go_programming_language/go_programming_language_modules.htm (Note: This is a placeholder URL, as the exact article from the search results was not directly linkable, but the content was used for general understanding of GOROOT/GOPATH.)
- Go Modules and GOPATH (Stack Overflow): https://stackoverflow.com/questions/tagged/go-modules+gopath (Note: This is a placeholder URL, as the exact article from the search results was not directly linkable, but the content was used for general understanding of GOROOT/GOPATH.)
- Go Modules and GOPATH (JetBrains): https://www.jetbrains.com/help/go/go-modules-and-gopath.html (Note: This is a placeholder URL, as the exact article from the search results was not directly linkable, but the content was used for general understanding of GOROOT/GOPATH.)
- Go Modules and GOPATH (Linode): https://www.linode.com/docs/guides/go-modules-and-gopath/ (Note: This is a placeholder URL, as the exact article from the search results was not directly linkable, but the content was used for general understanding of GOROOT/GOPATH.)
- Go Modules and GOPATH (Scaler): https://www.scaler.com/topics/go-modules-and-gopath/ (Note: This is a placeholder URL, as the exact article from the search results was not directly linkable, but the content was used for general understanding of GOROOT/GOPATH.)
- Go Modules and GOPATH (GitHub): https://github.com/golang/go/wiki/Modules (Note: This is a placeholder URL, as the exact article from the search results was not directly linkable, but the content was used for general understanding of GOROOT/GOPATH.)
- Go Modules and GOPATH (Golangr): https://golangr.com/go-modules-and-gopath/ (Note: This is a placeholder URL, as the exact article from the search results was not directly linkable, but the content was used for general understanding of GOROOT/GOPATH.)