[インデックス 11319] ファイルの概要
このコミットは、Go言語のビルドシステムにおけるパス解決ロジックを扱う src/pkg/go/build/path.go ファイルに対する変更です。このファイルは、Goのソースコードがどこに存在し、どのようにパッケージが解決されるかを決定する上で中心的な役割を担っています。具体的には、GOROOT (Goのインストールディレクトリ) と GOPATH (ユーザーのワークスペースディレクトリ) の設定を読み込み、それらのパスを管理する機能を提供します。
コミット
go/build: すべての警告を抑制
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/191873981af38f04e57a41815c36daad3724afd6
元コミット内容
commit 191873981af38f04e57a41815c36daad3724afd6
Author: Andrew Gerrand <adg@golang.org>
Date: Mon Jan 23 09:26:46 2012 +1100
go/build: silence all warnings
R=rsc
CC=golang-dev
https://golang.org/cl/5529055
変更の背景
このコミットの主な目的は、go/build パッケージが GOROOT や GOPATH の設定に関する警告メッセージを出力するのを停止することです。以前のバージョンでは、GOROOT が無効な場合や、GOPATH に重複するエントリがある場合に、log.Printf を使用して警告メッセージが標準エラー出力に表示されていました。
このような警告は、開発者がGoの環境設定を行う際に役立つこともありますが、CI/CD環境やスクリプトからGoのツールを実行する際には、不要な出力となり、ログのノイズを増やす原因となることがあります。また、これらの警告がエラーとして扱われるべきではない状況でも表示されるため、ツールの利用を妨げる可能性がありました。
この変更は、Goのビルドツールがより「静かに」動作し、必要な情報のみを出力するようにするための一般的な傾向の一部と考えられます。これにより、Goツールをプログラム的に利用する際の安定性と予測可能性が向上します。
前提知識の解説
Go言語の環境変数 (GOROOT と GOPATH)
GOROOT: GoのSDKがインストールされているディレクトリを指します。Goの標準ライブラリやツール群は、このディレクトリ以下に配置されています。Goのビルドツールは、GOROOTを参照して標準パッケージを見つけます。GOPATH: Goのワークスペースディレクトリを指します。Go 1.11以降のGo Modulesの導入によりその重要性は薄れましたが、このコミットが作成された2012年当時は、ユーザーが開発するGoのプロジェクトやサードパーティのライブラリを配置する場所として非常に重要でした。GOPATHは複数のパスをコロン (:) またはセミコロン (;) で区切って指定でき、Goツールはこれらのパスを順に検索してパッケージを見つけます。各GOPATHエントリは、src(ソースコード)、pkg(コンパイル済みパッケージ)、bin(実行可能ファイル) のサブディレクトリを持つことが期待されていました。
log パッケージ
Goの標準ライブラリに含まれる log パッケージは、シンプルなロギング機能を提供します。log.Printf 関数は、指定されたフォーマット文字列と引数を使用してメッセージをフォーマットし、デフォルトでは標準エラー出力 (stderr) に出力します。これは、デバッグ情報や警告、エラーメッセージを表示するためによく使用されます。
Goのビルドプロセス
Goのビルドプロセスは、ソースコードをコンパイルして実行可能ファイルやライブラリを生成する一連のステップです。このプロセスでは、Goツールは GOROOT と GOPATH を利用して、必要なパッケージのソースコードやコンパイル済みバイナリを探します。パス解決はビルドプロセスの初期段階で行われ、どのパッケージがどこにあるかを特定します。
技術的詳細
このコミットでは、src/pkg/go/build/path.go ファイルから以下の2種類の警告メッセージの出力が削除されています。
-
無効な
GOROOTの警告:init関数内でnewTree(root)(ここでrootはruntime.GOROOT()の値) の呼び出しがエラーを返した場合、以前はlog.Printf("invalid GOROOT %q: %v", root, err)というメッセージが出力されていました。この変更により、エラーが発生しても警告は出力されず、単にPath変数にGOROOTのツリーが追加されないだけになります。 -
無効な
GOPATHエントリおよび重複するGOPATHエントリの警告:os.Getenv("GOPATH")から取得した各パスに対してnewTree(p)を呼び出した際にエラーが発生した場合、以前はlog.Printf("invalid GOPATH %q: %v", p, err)というメッセージが出力されていました。この変更により、エラーが発生しても警告は出力されず、単にその無効なGOPATHエントリがスキップされるだけになります。 さらに、GOPATHエントリがGOROOTと同じパスを指している場合や、GOPATH内で重複するエントリがある場合に、それぞれlog.Printf("GOPATH is the same as GOROOT: %q", t.Path)またはlog.Printf("duplicate GOPATH entry: %q", t.Path)という警告が出力されていました。これらの重複チェックとそれに関連する警告出力も完全に削除されました。
これらの変更は、Goのビルドツールが環境設定の問題に対してより寛容になり、警告を出す代わりに単に問題のあるパスを無視するように動作することを意味します。これにより、スクリプトや自動化された環境でのGoツールの利用がよりスムーズになります。
コアとなるコードの変更箇所
--- a/src/pkg/go/build/path.go
+++ b/src/pkg/go/build/path.go
@@ -7,7 +7,6 @@ package build
import (
"errors"
"fmt"
- "log"
"os"
"path/filepath"
"runtime"
@@ -81,7 +80,6 @@ func (t *Tree) HasPkg(pkg string) bool {
return false
}
return !fi.IsDir()
- // TODO(adg): check object version is consistent
}
var (
@@ -150,38 +148,20 @@ var (
func init() {
root := runtime.GOROOT()
t, err := newTree(root)
- if err != nil {
- log.Printf("invalid GOROOT %q: %v", root, err)
- } else {
+ if err == nil {
t.Goroot = true
Path = []*Tree{t}
}
-Loop:
for _, p := range filepath.SplitList(os.Getenv("GOPATH")) {
if p == "" {
continue
}
t, err := newTree(p)
if err != nil {
-\t\t\tlog.Printf("invalid GOPATH %q: %v", p, err)
continue
}
-\t\t// Check for dupes.
-\t\t// TODO(alexbrainman): make this correct under windows (case insensitive).
-\t\tfor _, t2 := range Path {
-\t\t\tif t2.Path != t.Path {
-\t\t\t\tcontinue
-\t\t\t}\n-\t\t\tif t2.Goroot {\n-\t\t\t\tlog.Printf("GOPATH is the same as GOROOT: %q", t.Path)\n-\t\t\t} else {\n-\t\t\t\tlog.Printf("duplicate GOPATH entry: %q", t.Path)\n-\t\t\t}\n-\t\t\tcontinue Loop\n-\t\t}\n-\n Path = append(Path, t)
gcImportArgs = append(gcImportArgs, "-I", t.PkgDir())
ldImportArgs = append(ldImportArgs, "-L", t.PkgDir())
コアとなるコードの解説
-
logパッケージのインポート削除:- "log"の行が削除され、logパッケージへの依存がなくなりました。これは、このファイル内でlog.Printfを使用する箇所がすべて削除されることを示唆しています。 -
HasPkgメソッド内のコメント削除:- // TODO(adg): check object version is consistentのコメントが削除されました。これは直接的な機能変更ではありませんが、関連するTODO項目が不要になったか、別の方法で対処されるようになったことを示しています。 -
init関数内のGOROOT処理の変更: 以前は、newTree(root)がエラーを返した場合にlog.Printf("invalid GOROOT %q: %v", root, err)で警告を出力し、それ以外の場合にPathに追加していました。 変更後は、if err == nilという条件になり、エラーが発生した場合は何もせず、警告も出力しません。GOROOTが無効な場合は、単にPathに追加されないだけになります。 -
init関数内のGOPATH処理の変更:- 無効な
GOPATHエントリの警告削除:newTree(p)がエラーを返した場合にlog.Printf("invalid GOPATH %q: %v", p, err)で警告を出力していた部分が削除されました。エラーが発生した場合はcontinueで次のGOPATHエントリの処理に移るだけになります。 - 重複チェックと関連警告の削除:
GOPATHエントリの重複をチェックし、GOROOTとの重複やGOPATH内での重複に対して警告を出力していたfor _, t2 := range Path { ... }ブロック全体が削除されました。これにより、重複するGOPATHエントリがあっても警告は出力されず、Goツールは単にそれらをPathに追加し続けます。
- 無効な
これらの変更により、go/build パッケージは、GOROOT や GOPATH の設定に関する問題が発生した場合でも、警告メッセージを一切出力しなくなりました。これは、Goツールがより静かに動作し、エラーではない情報メッセージを抑制する方針に沿ったものです。
関連リンク
コミットメッセージに https://golang.org/cl/5529055 というGo Change List (CL) へのリンクが記載されていますが、現在のところこのリンクからは関連情報を見つけることができませんでした。これは、非常に古いCLであるため、アーカイブされたか、URL形式が変更された可能性があります。
参考にした情報源リンク
- コミットの差分情報 (
git diff) - Go言語の公式ドキュメント (特に
GOROOTとGOPATHに関する情報) - Go言語の
logパッケージのドキュメント - Go言語のビルドシステムに関する一般的な知識