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

[インデックス 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 パッケージが GOROOTGOPATH の設定に関する警告メッセージを出力するのを停止することです。以前のバージョンでは、GOROOT が無効な場合や、GOPATH に重複するエントリがある場合に、log.Printf を使用して警告メッセージが標準エラー出力に表示されていました。

このような警告は、開発者がGoの環境設定を行う際に役立つこともありますが、CI/CD環境やスクリプトからGoのツールを実行する際には、不要な出力となり、ログのノイズを増やす原因となることがあります。また、これらの警告がエラーとして扱われるべきではない状況でも表示されるため、ツールの利用を妨げる可能性がありました。

この変更は、Goのビルドツールがより「静かに」動作し、必要な情報のみを出力するようにするための一般的な傾向の一部と考えられます。これにより、Goツールをプログラム的に利用する際の安定性と予測可能性が向上します。

前提知識の解説

Go言語の環境変数 (GOROOTGOPATH)

  • 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ツールは GOROOTGOPATH を利用して、必要なパッケージのソースコードやコンパイル済みバイナリを探します。パス解決はビルドプロセスの初期段階で行われ、どのパッケージがどこにあるかを特定します。

技術的詳細

このコミットでは、src/pkg/go/build/path.go ファイルから以下の2種類の警告メッセージの出力が削除されています。

  1. 無効な GOROOT の警告: init 関数内で newTree(root) (ここで rootruntime.GOROOT() の値) の呼び出しがエラーを返した場合、以前は log.Printf("invalid GOROOT %q: %v", root, err) というメッセージが出力されていました。この変更により、エラーが発生しても警告は出力されず、単に Path 変数に GOROOT のツリーが追加されないだけになります。

  2. 無効な 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())

コアとなるコードの解説

  1. log パッケージのインポート削除: - "log" の行が削除され、log パッケージへの依存がなくなりました。これは、このファイル内で log.Printf を使用する箇所がすべて削除されることを示唆しています。

  2. HasPkg メソッド内のコメント削除: - // TODO(adg): check object version is consistent のコメントが削除されました。これは直接的な機能変更ではありませんが、関連するTODO項目が不要になったか、別の方法で対処されるようになったことを示しています。

  3. init 関数内の GOROOT 処理の変更: 以前は、newTree(root) がエラーを返した場合に log.Printf("invalid GOROOT %q: %v", root, err) で警告を出力し、それ以外の場合に Path に追加していました。 変更後は、if err == nil という条件になり、エラーが発生した場合は何もせず、警告も出力しません。GOROOT が無効な場合は、単に Path に追加されないだけになります。

  4. 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 パッケージは、GOROOTGOPATH の設定に関する問題が発生した場合でも、警告メッセージを一切出力しなくなりました。これは、Goツールがより静かに動作し、エラーではない情報メッセージを抑制する方針に沿ったものです。

関連リンク

コミットメッセージに https://golang.org/cl/5529055 というGo Change List (CL) へのリンクが記載されていますが、現在のところこのリンクからは関連情報を見つけることができませんでした。これは、非常に古いCLであるため、アーカイブされたか、URL形式が変更された可能性があります。

参考にした情報源リンク

  • コミットの差分情報 (git diff)
  • Go言語の公式ドキュメント (特に GOROOTGOPATH に関する情報)
  • Go言語の log パッケージのドキュメント
  • Go言語のビルドシステムに関する一般的な知識