[インデックス 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言語のビルドシステムに関する一般的な知識