[インデックス 12583] ファイルの概要
このコミットは、Go言語のコマンドラインツール go の挙動に関する変更を元に戻すものです。具体的には、以前のコミット CL 5754088 (ハッシュ cae9a7c0db06) によって導入された $GOBIN 環境変数の扱いに関する変更をアンドゥしています。このアンドゥの理由は「broke builders」(ビルドシステムを壊した)とされており、以前の変更が予期せぬ問題を引き起こしたため、その変更を撤回する目的で行われました。
コミット
commit bf09a8c9708104c2f2b172d3a2e5ef80198d5256
Author: Russ Cox <rsc@golang.org>
Date: Mon Mar 12 17:03:29 2012 -0400
undo CL 5754088 / cae9a7c0db06
broke builders
««« original CL description
cmd/go: respect $GOBIN always
Before, we only consulted $GOBIN for source code
found in $GOROOT, but that's confusing to explain
and less useful. The new behavior lets users set
GOBIN=$HOME/bin and have all go-compiled binaries
installed there.
Fixes #3269.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5754088
»»»
TBR=bradfitz
CC=golang-dev
https://golang.org/cl/5794065
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/bf09a8c9708104c2f2b172d3a2e5ef80198d5256
元コミット内容
このコミットがアンドゥしている元のコミット CL 5754088 の内容は以下の通りです。
コミットメッセージ(元のCLより):
cmd/go: respect $GOBIN always
Before, we only consulted $GOBIN for source code
found in $GOROOT, but that's confusing to explain
and less useful. The new behavior lets users set
GOBIN=$HOME/bin and have all go-compiled binaries
installed there.
Fixes #3269.
この元のコミットは、go install コマンドがバイナリをインストールする際に $GOBIN 環境変数を常に尊重するように変更することを意図していました。それ以前は、$GOBIN は $GOROOT 内で見つかったソースコードに対してのみ考慮されており、それ以外の場所(例えば $GOPATH)にあるプロジェクトのバイナリは $GOBIN にインストールされませんでした。この制限はユーザーにとって混乱を招き、利便性が低いと判断されたため、$GOBIN を常に適用することで、ユーザーが指定した単一のディレクトリにすべてのGoコンパイル済みバイナリをインストールできるようにすることが目的でした。これにより、$HOME/bin のような共通のバイナリディレクトリにGoの実行ファイルを一元管理できるようになることが期待されていました。
変更の背景
このコミット bf09a8c9708104c2f2b172d3a2e5ef80198d5256 は、以前のコミット cae9a7c0db06 (CL 5754088) を元に戻すために作成されました。元のコミットは $GOBIN の挙動を変更し、go install が常に $GOBIN を尊重するようにしました。しかし、この変更は「broke builders」(ビルドシステムを壊した)と明記されており、Goプロジェクトの自動ビルドシステムやテストスイートにおいて、予期せぬエラーや互換性の問題を引き起こしたと考えられます。
Goプロジェクトでは、安定性と後方互換性が非常に重視されます。新しい機能や挙動の変更が既存のシステムやワークフローに悪影響を与える場合、迅速にその変更を元に戻すことが一般的なプラクティスです。このコミットは、元の変更がGoのビルドインフラストラクチャに深刻な問題を引き起こしたため、その影響を最小限に抑えるための緊急措置として行われたものと推測されます。
前提知識の解説
このコミットを理解するためには、Go言語の以下の基本的な概念と環境変数について知っておく必要があります。
-
GOROOT:- Goのインストールディレクトリを指す環境変数です。Goの標準ライブラリ、ツール、ドキュメントなどが含まれています。
goコマンドは、このパスを基にGoの実行に必要なファイルを探索します。
-
GOPATH:- Go 1.11以前のGoプロジェクトのワークスペースを定義する環境変数です。Goのソースコード、パッケージ、コンパイル済みバイナリが配置される場所を指定します。
- 通常、複数のパスを設定でき、
src(ソースコード),pkg(コンパイル済みパッケージ),bin(コンパイル済みバイナリ) のサブディレクトリを持ちます。 - Go 1.11以降のGo Modulesの導入により、
GOPATHの役割は大きく変わりましたが、このコミットが作成された2012年当時はGo開発の主要なワークスペースモデルでした。
-
GOBIN:go installコマンドによってコンパイルされた実行可能バイナリがインストールされるディレクトリを指定する環境変数です。GOBINが設定されていない場合、バイナリは通常$GOPATH/bin(または$GOROOT/bin、Goのバージョンやコンテキストによる) にインストールされます。- このコミットの核心は、
go installが$GOBINを「いつ」「どのように」尊重するかという点にあります。
-
go installコマンド:- Goのソースコードをコンパイルし、その結果生成された実行可能バイナリ(
mainパッケージの場合)やパッケージアーカイブ(ライブラリの場合)を適切な場所にインストールするコマンドです。 - 実行可能バイナリは
$GOBINまたは$GOPATH/binに、パッケージアーカイブは$GOPATH/pkgにインストールされます。
- Goのソースコードをコンパイルし、その結果生成された実行可能バイナリ(
-
GoのビルドシステムとCI/CD:
- Goプロジェクトのような大規模なオープンソースプロジェクトでは、継続的インテグレーション(CI)システムが導入されており、コミットごとに自動的にコードのビルド、テスト、リンティングなどが行われます。
- 「broke builders」という表現は、このCIシステムが、元のコミットによって導入された変更のために正常に動作しなくなったことを意味します。これは、ビルドエラー、テストの失敗、または予期せぬ挙動の発生を示唆しています。
技術的詳細
このコミットは、go install コマンドがバイナリのインストール先を決定するロジックを元に戻すものです。元のコミット CL 5754088 は、$GOBIN が設定されている場合、$GOROOT 内のパッケージだけでなく、すべてのGoパッケージに対してそのパスを優先的に使用するように変更しました。
具体的には、元の変更では src/cmd/go/build.go 内の gobin 変数の初期化方法が変更され、os.Getenv("GOBIN") を直接使用するようになりました。これにより、GOBIN が設定されていれば、go install は常にそのパスをインストール先として使用するようになりました。また、Package 構造体の target フィールドの扱いも変更され、GOBIN の値に基づいて実行ファイルの出力パスが決定されるようになりました。
しかし、このアンドゥコミットでは、gobin 変数の初期化を defaultGobin() 関数を介して行うように戻しています。defaultGobin() 関数は、$GOBIN が設定されていない場合に $GOROOT/bin をデフォルト値として返すロジックを含んでいます。これにより、$GOBIN が設定されていない場合や、特定の条件下では、以前の挙動($GOROOT/bin へのインストール)が維持されるようになります。
また、doc/install-source.html、src/cmd/go/doc.go、src/cmd/go/help.go、src/cmd/go/pkg.go のドキュメントやコード内のコメントも、$GOBIN が常に尊重されるという記述を削除し、元の挙動($GOROOT 内のソースコードに限定される可能性)に戻しています。特に src/cmd/go/pkg.go では、bp.BinDir = gobin の行が削除されており、build.Package の BinDir フィールドに $GOBIN の値を無条件に設定する挙動が取り消されています。
このアンドゥは、元の変更がGoのビルドシステムや既存のユーザーワークフローに予期せぬ影響を与えたことを示唆しています。例えば、$GOBIN が設定されていない環境でのビルドが壊れた、あるいは特定のパッケージのインストールパスが期待と異なる挙動を示したなどが考えられます。
コアとなるコードの変更箇所
このコミットによる主要なコード変更は以下のファイルに集中しています。
-
src/cmd/go/build.go:gobin変数の初期化方法が変更されました。- 変更前:
gobin = os.Getenv("GOBIN") - 変更後:
gobin = defaultGobin()
- 変更前:
defaultGobin()関数が追加されました。この関数は$GOBINが設定されていればその値を返し、そうでなければ$GOROOT/binを返します。goFilesPackage関数内で、pkg.targetおよびpkg.Targetの設定ロジックが元に戻されました。特に、gobinの値に基づいてpkg.targetを設定する部分が削除されています。action関数内で、p.local && (!a.link || p.target == "")の条件がp.localに簡略化され、ローカルパッケージのビルドモードの決定ロジックが元に戻されました。
-
doc/install-source.html:$GOBINの説明から、「IfGOBINis set, thego commandinstalls all commands there.」という記述が削除されました。これにより、$GOBINが常にすべてのコマンドのインストール先となるわけではないという元の説明に戻されました。
-
src/cmd/go/doc.goおよびsrc/cmd/go/help.go:go installのインストールパスに関する説明から、「If the GOBIN environment variable is set, commands are installed to the directory it names instead of DIR/bin.」という記述が削除されました。これも$GOBINの普遍的な適用を否定する変更です。
-
src/cmd/go/pkg.go:Package.load関数内で、if gobin != "" { bp.BinDir = gobin }という行が削除されました。これにより、build.PackageのBinDirフィールドに$GOBINの値を無条件に設定する挙動が取り消されました。loadPackage関数内で、bp.BinDir = gobinという行が追加されました。これは、GOROOT内のパッケージに対しては$GOBINを適用するという、元の挙動の一部を維持するための変更と考えられます。
コアとなるコードの解説
このコミットの核心は、src/cmd/go/build.go における gobin 変数の初期化と、go install がバイナリの出力パスを決定するロジックの変更です。
元のコミット CL 5754088 では、gobin 変数を単に os.Getenv("GOBIN") で初期化していました。これは、$GOBIN が設定されていれば、その値が常に go install のデフォルトのインストール先として使用されることを意味します。しかし、このアンドゥコミットでは、gobin の初期化を defaultGobin() 関数に委ねることで、より複雑なロジックを導入しています。
// src/cmd/go/build.go (変更後)
var (
gobin = defaultGobin() // ここが変更点
goroot = filepath.Clean(runtime.GOROOT())
gorootSrcPkg = filepath.Join(goroot, "src/pkg")
gorootPkg = filepath.Join(goroot, "pkg")
gorootSrc = filepath.Join(goroot, "src")
)
func defaultGobin() string {
if s := os.Getenv("GOBIN"); s != "" {
return s
}
return filepath.Join(goroot, "bin")
}
defaultGobin() 関数は、$GOBIN 環境変数が設定されている場合はその値を返しますが、設定されていない場合は $GOROOT/bin を返します。これは、$GOBIN が設定されていない場合に、Goの標準ツールやライブラリのバイナリが $GOROOT/bin にインストールされるという、Goの初期の挙動を維持するためのものです。
また、src/cmd/go/pkg.go の Package.load 関数から bp.BinDir = gobin の行が削除されたことも重要です。これは、go install がパッケージをロードする際に、build.Package 構造体の BinDir フィールドに $GOBIN の値を無条件に設定するのをやめたことを意味します。これにより、$GOBIN の適用範囲が限定され、特定の条件下でのみ有効になるように戻されました。
これらの変更は、$GOBIN が常にすべてのGoバイナリのインストール先となるという単純なモデルから、$GOBIN が設定されていない場合や、$GOROOT 内のパッケージなど、特定のコンテキストでは異なるデフォルトパスが使用されるという、より複雑な(しかし当時のGoの設計思想に合致する)モデルに戻すことを目的としています。
関連リンク
- Go Issue #3269: https://github.com/golang/go/issues/3269 (このコミットがアンドゥした元の変更が修正しようとした問題)
- 元の変更リスト (CL 5754088): https://golang.org/cl/5754088
- このアンドゥ変更リスト (CL 5794065): https://golang.org/cl/5794065
参考にした情報源リンク
- Go言語の公式ドキュメント (当時のバージョンに基づく
$GOBIN,$GOPATH,$GOROOTの説明) - Go言語のソースコードリポジトリ (特に
src/cmd/goディレクトリ内のファイル) - Go言語のIssueトラッカー (GitHub Issues)
- Go言語のChange List (CL) システム (Gerrit)
- Go言語の環境変数に関する一般的な解説記事やブログポスト (当時の情報に注意)
[インデックス 12583] ファイルの概要
このコミットは、Go言語のコマンドラインツール go の挙動に関する変更を元に戻すものです。具体的には、以前のコミット CL 5754088 (ハッシュ cae9a7c0db06) によって導入された $GOBIN 環境変数の扱いに関する変更をアンドゥしています。このアンドゥの理由は「broke builders」(ビルドシステムを壊した)とされており、以前の変更が予期せぬ問題を引き起こしたため、その変更を撤回する目的で行われました。
コミット
commit bf09a8c9708104c2f2b172d3a2e5ef80198d5256
Author: Russ Cox <rsc@golang.org>
Date: Mon Mar 12 17:03:29 2012 -0400
undo CL 5754088 / cae9a7c0db06
broke builders
««« original CL description
cmd/go: respect $GOBIN always
Before, we only consulted $GOBIN for source code
found in $GOROOT, but that's confusing to explain
and less useful. The new behavior lets users set
GOBIN=$HOME/bin and have all go-compiled binaries
installed there.
Fixes #3269.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5754088
»»»
TBR=bradfitz
CC=golang-dev
https://golang.org/cl/5794065
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/bf09a8c9708104c2f2b172d3a2e5ef80198d5256
元コミット内容
このコミットがアンドゥしている元のコミット CL 5754088 の内容は以下の通りです。
コミットメッセージ(元のCLより):
cmd/go: respect $GOBIN always
Before, we only consulted $GOBIN for source code
found in $GOROOT, but that's confusing to explain
and less useful. The new behavior lets users set
GOBIN=$HOME/bin and have all go-compiled binaries
installed there.
Fixes #3269.
この元のコミットは、go install コマンドがバイナリをインストールする際に $GOBIN 環境変数を常に尊重するように変更することを意図していました。それ以前は、$GOBIN は $GOROOT 内で見つかったソースコードに対してのみ考慮されており、それ以外の場所(例えば $GOPATH)にあるプロジェクトのバイナリは $GOBIN にインストールされませんでした。この制限はユーザーにとって混乱を招き、利便性が低いと判断されたため、$GOBIN を常に適用することで、ユーザーが指定した単一のディレクトリにすべてのGoコンパイル済みバイナリをインストールできるようにすることが目的でした。これにより、$HOME/bin のような共通のバイナリディレクトリにGoの実行ファイルを一元管理できるようになることが期待されていました。
変更の背景
このコミット bf09a8c9708104c2f2b172d3a2e5ef80198d5256 は、以前のコミット cae9a7c0db06 (CL 5754088) を元に戻すために作成されました。元のコミットは $GOBIN の挙動を変更し、go install が常に $GOBIN を尊重するようにしました。しかし、この変更は「broke builders」(ビルドシステムを壊した)と明記されており、Goプロジェクトの自動ビルドシステムやテストスイートにおいて、予期せぬエラーや互換性の問題を引き起こしたと考えられます。
Goプロジェクトでは、安定性と後方互換性が非常に重視されます。新しい機能や挙動の変更が既存のシステムやワークフローに悪影響を与える場合、迅速にその変更を元に戻すことが一般的なプラクティスです。このコミットは、元の変更がGoのビルドインフラストラクチャに深刻な問題を引き起こしたため、その影響を最小限に抑えるための緊急措置として行われたものと推測されます。
前提知識の解説
このコミットを理解するためには、Go言語の以下の基本的な概念と環境変数について知っておく必要があります。
-
GOROOT:- Goのインストールディレクトリを指す環境変数です。Goの標準ライブラリ、ツール、ドキュメントなどが含まれています。
goコマンドは、このパスを基にGoの実行に必要なファイルを探索します。
-
GOPATH:- Go 1.11以前のGoプロジェクトのワークスペースを定義する環境変数です。Goのソースコード、パッケージ、コンパイル済みバイナリが配置される場所を指定します。
- 通常、複数のパスを設定でき、
src(ソースコード),pkg(コンパイル済みパッケージ),bin(コンパイル済みバイナリ) のサブディレクトリを持ちます。 - Go 1.11以降のGo Modulesの導入により、
GOPATHの役割は大きく変わりましたが、このコミットが作成された2012年当時はGo開発の主要なワークスペースモデルでした。
-
GOBIN:go installコマンドによってコンパイルされた実行可能バイナリがインストールされるディレクトリを指定する環境変数です。GOBINが設定されていない場合、バイナリは通常$GOPATH/bin(または$GOROOT/bin、Goのバージョンやコンテキストによる) にインストールされます。- このコミットの核心は、
go installが$GOBINを「いつ」「どのように」尊重するかという点にあります。
-
go installコマンド:- Goのソースコードをコンパイルし、その結果生成された実行可能バイナリ(
mainパッケージの場合)やパッケージアーカイブ(ライブラリの場合)を適切な場所にインストールするコマンドです。 - 実行可能バイナリは
$GOBINまたは$GOPATH/binに、パッケージアーカイブは$GOPATH/pkgにインストールされます。
- Goのソースコードをコンパイルし、その結果生成された実行可能バイナリ(
-
GoのビルドシステムとCI/CD:
- Goプロジェクトのような大規模なオープンソースプロジェクトでは、継続的インテグレーション(CI)システムが導入されており、コミットごとに自動的にコードのビルド、テスト、リンティングなどが行われます。
- 「broke builders」という表現は、このCIシステムが、元のコミットによって導入された変更のために正常に動作しなくなったことを意味します。これは、ビルドエラー、テストの失敗、または予期せぬ挙動の発生を示唆しています。
技術的詳細
このコミットは、go install コマンドがバイナリのインストール先を決定するロジックを元に戻すものです。元のコミット CL 5754088 は、$GOBIN が設定されている場合、$GOROOT 内のパッケージだけでなく、すべてのGoパッケージに対してそのパスを優先的に使用するように変更しました。
具体的には、元の変更では src/cmd/go/build.go 内の gobin 変数の初期化方法が変更され、os.Getenv("GOBIN") を直接使用するようになりました。これにより、GOBIN が設定されていれば、go install は常にそのパスをインストール先として使用するようになりました。また、Package 構造体の target フィールドの扱いも変更され、GOBIN の値に基づいて実行ファイルの出力パスが決定されるようになりました。
しかし、このアンドゥコミットでは、gobin 変数の初期化を defaultGobin() 関数を介して行うように戻しています。defaultGobin() 関数は、$GOBIN が設定されていない場合に $GOROOT/bin をデフォルト値として返すロジックを含んでいます。これにより、$GOBIN が設定されていない場合や、特定の条件下では、以前の挙動($GOROOT/bin へのインストール)が維持されるようになります。
また、doc/install-source.html、src/cmd/go/doc.go、src/cmd/go/help.go、src/cmd/go/pkg.go のドキュメントやコード内のコメントも、$GOBIN が常に尊重されるという記述を削除し、元の挙動($GOROOT 内のソースコードに限定される可能性)に戻しています。特に src/cmd/go/pkg.go では、bp.BinDir = gobin の行が削除されており、build.Package の BinDir フィールドに $GOBIN の値を無条件に設定する挙動が取り消されています。
このアンドゥは、元の変更がGoのビルドシステムや既存のユーザーワークフローに予期せぬ影響を与えたことを示唆しています。例えば、$GOBIN が設定されていない環境でのビルドが壊れた、あるいは特定のパッケージのインストールパスが期待と異なる挙動を示したなどが考えられます。
コアとなるコードの変更箇所
このコミットによる主要なコード変更は以下のファイルに集中しています。
-
src/cmd/go/build.go:gobin変数の初期化方法が変更されました。- 変更前:
gobin = os.Getenv("GOBIN") - 変更後:
gobin = defaultGobin()
- 変更前:
defaultGobin()関数が追加されました。この関数は$GOBINが設定されていればその値を返し、そうでなければ$GOROOT/binを返します。goFilesPackage関数内で、pkg.targetおよびpkg.Targetの設定ロジックが元に戻されました。特に、gobinの値に基づいてpkg.targetを設定する部分が削除されています。action関数内で、p.local && (!a.link || p.target == "")の条件がp.localに簡略化され、ローカルパッケージのビルドモードの決定ロジックが元に戻されました。
-
doc/install-source.html:$GOBINの説明から、「IfGOBINis set, thego commandinstalls all commands there.」という記述が削除されました。これにより、$GOBINが常にすべてのコマンドのインストール先となるわけではないという元の説明に戻されました。
-
src/cmd/go/doc.goおよびsrc/cmd/go/help.go:go installのインストールパスに関する説明から、「If the GOBIN environment variable is set, commands are installed to the directory it names instead of DIR/bin.」という記述が削除されました。これも$GOBINの普遍的な適用を否定する変更です。
-
src/cmd/go/pkg.go:Package.load関数内で、if gobin != "" { bp.BinDir = gobin }という行が削除されました。これにより、build.PackageのBinDirフィールドに$GOBINの値を無条件に設定する挙動が取り消されました。loadPackage関数内で、bp.BinDir = gobinという行が追加されました。これは、GOROOT内のパッケージに対しては$GOBINを適用するという、元の挙動の一部を維持するための変更と考えられます。
コアとなるコードの解説
このコミットの核心は、src/cmd/go/build.go における gobin 変数の初期化と、go install がバイナリの出力パスを決定するロジックの変更です。
元のコミット CL 5754088 では、gobin 変数を単に os.Getenv("GOBIN") で初期化していました。これは、$GOBIN が設定されていれば、その値が常に go install のデフォルトのインストール先として使用されることを意味します。しかし、このアンドゥコミットでは、gobin の初期化を defaultGobin() 関数に委ねることで、より複雑なロジックを導入しています。
// src/cmd/go/build.go (変更後)
var (
gobin = defaultGobin() // ここが変更点
goroot = filepath.Clean(runtime.GOROOT())
gorootSrcPkg = filepath.Join(goroot, "src/pkg")
gorootPkg = filepath.Join(goroot, "pkg")
gorootSrc = filepath.Join(goroot, "src")
)
func defaultGobin() string {
if s := os.Getenv("GOBIN"); s != "" {
return s
}
return filepath.Join(goroot, "bin")
}
defaultGobin() 関数は、$GOBIN 環境変数が設定されている場合はその値を返しますが、設定されていない場合は $GOROOT/bin を返します。これは、$GOBIN が設定されていない場合に、Goの標準ツールやライブラリのバイナリが $GOROOT/bin にインストールされるという、Goの初期の挙動を維持するためのものです。
また、src/cmd/go/pkg.go の Package.load 関数から bp.BinDir = gobin の行が削除されたことも重要です。これは、go install がパッケージをロードする際に、build.Package 構造体の BinDir フィールドに $GOBIN の値を無条件に設定するのをやめたことを意味します。これにより、$GOBIN の適用範囲が限定され、特定の条件下でのみ有効になるように戻されました。
これらの変更は、$GOBIN が常にすべてのGoバイナリのインストール先となるという単純なモデルから、$GOBIN が設定されていない場合や、$GOROOT 内のパッケージなど、特定のコンテキストでは異なるデフォルトパスが使用されるという、より複雑な(しかし当時のGoの設計思想に合致する)モデルに戻すことを目的としています。
関連リンク
- Go Issue #3269: https://github.com/golang/go/issues/3269 (このコミットがアンドゥした元の変更が修正しようとした問題)
- 元の変更リスト (CL 5754088): https://golang.org/cl/5754088
- このアンドゥ変更リスト (CL 5794065): https://golang.org/cl/5794065
参考にした情報源リンク
- Go言語の公式ドキュメント (当時のバージョンに基づく
$GOBIN,$GOPATH,$GOROOTの説明) - Go言語のソースコードリポジトリ (特に
src/cmd/goディレクトリ内のファイル) - Go言語のIssueトラッカー (GitHub Issues)
- Go言語のChange List (CL) システム (Gerrit)
- Go言語の環境変数に関する一般的な解説記事やブログポスト (当時の情報に注意)