[インデックス 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
の説明から、「IfGOBIN
is set, thego command
installs 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
の説明から、「IfGOBIN
is set, thego command
installs 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言語の環境変数に関する一般的な解説記事やブログポスト (当時の情報に注意)