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

[インデックス 12778] ファイルの概要

このコミットは、Go言語のビルドツールである cmd/dist におけるGoバージョンの検出ロジックの修正に関するものです。具体的には、goversion 文字列が "go." で始まるかどうかを判定する際に、末尾のドットが不要なケース(例: "go1")を正しく扱えるように変更されています。これにより、リリースビルドにおける特定のファイルの存在チェックが適切に行われるようになります。

コミット

commit 901ee5c1513f56c292072eedcdfb3b0218f6d1fe
Author: Russ Cox <rsc@golang.org>
Date:   Tue Mar 27 00:17:35 2012 -0400

    cmd/dist: fix detection of go1 version

    R=golang-dev, r
    CC=golang-dev
    https://golang.org/cl/5924044

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/901ee5c1513f56c292072eedcdfb3b0218f6d1fe

元コミット内容

cmd/dist: fix detection of go1 version

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/5924044

変更の背景

Go言語のビルドシステム cmd/dist は、Goのソースコードからコンパイラ、ツール、標準ライブラリなどをビルドするために使用されます。このシステムは、ビルド対象のGoのバージョンに応じて異なる振る舞いをすることがあります。特に、リリースビルド(release. で始まるバージョンや go で始まるバージョン)の場合、特定のファイルやディレクトリが存在しないことを確認するロジックが含まれています。

このコミットが行われた2012年3月は、Go 1のリリースが間近に迫っていた時期です。Go 1はGo言語にとって最初の安定版リリースであり、そのバージョン文字列の形式は go1 となることが想定されていました。しかし、既存のバージョン検出ロジックでは、goversion が "go." で始まる場合にのみリリースバージョンと判断していました。このため、goversion が "go1" のように末尾にドットがない場合に、正しくリリースバージョンとして認識されず、リリースビルドに必要なチェックがスキップされてしまう問題が発生していました。

この問題は、リリースビルドの整合性を損なう可能性があり、unreleased (未リリース) とされるべきファイルが誤って存在してしまうことを防ぐために修正が必要でした。

前提知識の解説

  • cmd/dist: Go言語のソースコードからGoツールチェイン全体をビルドするためのコマンドラインツールです。Goのビルドプロセスの中核を担い、コンパイラ、リンカ、アセンブラ、標準ライブラリなどを構築します。
  • goversion: Goのバージョン文字列を表す変数です。例えば、go1go1.0.1release.r60.3 などがあります。この文字列は、ビルド時にGoのバージョンを識別するために使用されます。
  • hasprefix 関数: C言語で実装された文字列操作関数で、ある文字列が特定のプレフィックス(接頭辞)で始まるかどうかを判定します。Go言語の標準ライブラリにも同様の strings.HasPrefix 関数が存在しますが、これは cmd/dist がC言語で書かれているため、C言語の関数が使用されています。
  • リリースビルドの整合性チェック: Goのリリースビルドでは、安定性と予測可能性を保証するために、特定の開発中のファイルや一時的なファイルが最終的なリリースパッケージに含まれていないことを確認する仕組みがあります。unreleased という概念は、リリース版には含まれるべきではないファイルやディレクトリを指します。

技術的詳細

このコミットの技術的な核心は、src/cmd/dist/build.c ファイル内の setup 関数における goversion のチェックロジックの変更です。

元のコードでは、goversion がリリースバージョンであるかどうかを判断するために、以下の条件を使用していました。

if(hasprefix(goversion, "release.") || hasprefix(goversion, "go.")) {

この条件は、goversion が "release." で始まるか、または "go." で始まる場合に真となります。しかし、Go 1のバージョン文字列が "go1" のように末尾にドットを含まない場合、hasprefix(goversion, "go.")false を返してしまい、結果として go1 がリリースバージョンとして正しく認識されませんでした。

このコミットでは、この条件が以下のように修正されました。

if(hasprefix(goversion, "release.") || hasprefix(goversion, "go")) {

変更点は hasprefix(goversion, "go.")hasprefix(goversion, "go") になった点です。これにより、goversion が "go" で始まる文字列であれば、その後にドットが続くかどうかに関わらず、リリースバージョンとして認識されるようになります。例えば、"go1"、"go1.0.1"、"go.weekly" など、"go" で始まるすべてのバージョンがこの条件に合致するようになります。

この修正により、go1 のようなバージョン文字列も正しくリリースビルドとして扱われ、unreleased なファイルが存在しないことのチェックが適切に実行されるようになります。これは、Go 1の安定版リリースに向けた重要な修正であり、ビルドプロセスの堅牢性を高めるものです。

コアとなるコードの変更箇所

変更は src/cmd/dist/build.c ファイルの1箇所のみです。

--- a/src/cmd/dist/build.c
+++ b/src/cmd/dist/build.c
@@ -362,7 +362,7 @@ setup(void)\n  	}\n  \n  	// For release, make sure excluded things are excluded.\n- \tif(hasprefix(goversion, "release.") || hasprefix(goversion, "go.")) {\n+ \tif(hasprefix(goversion, "release.") || hasprefix(goversion, "go")) {\n  \t\tfor(i=0; i<nelem(unreleased); i++)\n  \t\t\tif(isdir(bpathf(&b, "%s/%s", goroot, unreleased[i])))\n  \t\t\t\tfatal("%s should not exist in release build", bstr(&b));

コアとなるコードの解説

変更された行は、setup 関数内でリリースビルドの検出を行う条件分岐です。

元のコード: if(hasprefix(goversion, "release.") || hasprefix(goversion, "go.")) { これは、goversion が "release." で始まるか、または "go." で始まる場合に、リリースビルドと判断していました。

修正後のコード: if(hasprefix(goversion, "release.") || hasprefix(goversion, "go")) { この修正により、goversion が "release." で始まるか、または "go" で始まる場合に、リリースビルドと判断するようになりました。

この変更の直接的な影響は、go1 のようなバージョン文字列が hasprefix(goversion, "go") の条件に合致するようになり、その結果、unreleased なファイルが存在しないことを確認するループが実行されるようになることです。このループは、unreleased 配列に定義されたパス(例えば、開発中にのみ存在する一時ファイルやテストファイルなど)が goroot 以下に存在しないことを確認し、もし存在すれば fatal エラーを発生させてビルドを停止させます。これにより、リリースビルドのクリーンさが保証されます。

関連リンク

参考にした情報源リンク