[インデックス 17667] ファイルの概要
このコミットは、Go言語のツールチェインの一部である cmd/api
コマンドの動作変更に関するものです。具体的には、APIチェックの実行条件が変更され、hg
(Mercurial) がシステムに存在するかどうかでAPIチェックの実行を判断するようになりました。
コミット
- コミットハッシュ:
afda774e95c103e7a4ecf61b945c8e5a166514ab
- Author: Brad Fitzpatrick bradfitz@golang.org
- Date: Sun Sep 22 08:01:17 2013 +0100
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/afda774e95c103e7a4ecf61b945c8e5a166514ab
元コミット内容
cmd/api: always do API check if hg is available
Fixes #6124
R=golang-dev, minux.ma
CC=golang-dev
https://golang.org/cl/13500046
変更の背景
このコミットの背景には、cmd/api
コマンドのAPIチェックの実行条件に関する課題がありました。以前の cmd/api
は、APIチェックを実行するかどうかを isGoDeveloper
という変数と forceAPICheck()
関数に依存していました。
isGoDeveloper
はhg pq
コマンドの実行結果に基づいて、現在の環境がGo開発者の環境であるかどうかを判断していました。hg pq
はMercurialのpatch queue機能に関連するコマンドで、GoのリポジトリがMercurialで管理されていた当時、開発環境の識別に使われていたと考えられます。forceAPICheck()
はGO_FORCE_API_CHECK
という環境変数が設定されているかどうかをチェックしていました。これは主にビルドシステム(builders
)がAPIチェックを強制するために使用されていました。
この設計では、hg
が利用できない環境や、GO_FORCE_API_CHECK
が設定されていない環境では、APIチェックがスキップされる可能性がありました。コミットメッセージの "always do API check if hg is available" (hgが利用可能であれば常にAPIチェックを行う) という記述から、APIチェックがより一貫して実行されるようにすることが目的であったと推測されます。特に、GO_FORCE_API_CHECK
環境変数に依存するのではなく、hg
の存在のみで判断することで、APIチェックのロジックを簡素化し、より予測可能な動作を目指したと考えられます。
Fixes #6124
とありますが、Goの公式Issue Trackerで #6124 を検索しても直接関連する情報は見つかりませんでした。これは、非常に古いIssueであるか、または内部的なIssue番号である可能性があります。しかし、コミットメッセージから、APIチェックの実行条件に関する問題がこの変更によって解決されたことは明らかです。
前提知識の解説
cmd/api
cmd/api
はGo言語のツールチェインの一部であり、Goの標準ライブラリのAPIが変更されていないことを確認するためのツールです。Go言語では、後方互換性が非常に重視されており、既存のAPIを変更することは原則として避けるべきとされています。cmd/api
は、Goのリリース間でAPIの互換性が維持されているかを自動的にチェックするために使用されます。これにより、Goのバージョンアップによって既存のコードが動作しなくなるという問題を未然に防ぐことができます。
hg
(Mercurial)
hg
はMercurialという分散型バージョン管理システムのコマンドラインツールです。Gitと同様に、ソースコードの変更履歴を管理するために使用されます。Go言語のプロジェクトは、初期にはMercurialで管理されていましたが、後にGitに移行しました。このコミットが2013年のものであることから、当時はまだMercurialがGoプロジェクトの主要なバージョン管理システムとして使われていたことがわかります。
GOROOT
GOROOT
はGo言語のインストールディレクトリを示す環境変数です。Goのコンパイラ、標準ライブラリ、ツールなどがこのディレクトリに配置されます。cmd/api
のようなGoツールは、GOROOT
を参照して必要なファイルやライブラリを見つけます。
os/exec
パッケージ
Go言語の標準ライブラリである os/exec
パッケージは、外部コマンドを実行するための機能を提供します。このコミットでは、exec.Command
や exec.LookPath
といった関数が使用されています。
exec.Command(name string, arg ...string)
: 指定されたコマンドと引数を持つCmd
構造体を返します。exec.LookPath(file string)
: 指定された実行可能ファイルがシステムのPATH環境変数内でどこにあるかを検索します。ファイルが見つからない場合はエラーを返します。
技術的詳細
このコミットの主要な変更点は、src/cmd/api/run.go
ファイルにおけるAPIチェックの実行条件のロジックです。
変更前:
isGoDeveloper := exec.Command("hg", "pq").Run() == nil
if !isGoDeveloper && !forceAPICheck() {
fmt.Println("Skipping cmd/api checks; hg codereview extension not available and GO_FORCE_API_CHECK not set")
return
}
変更前は、以下の2つの条件を組み合わせてAPIチェックのスキップを判断していました。
isGoDeveloper
:hg pq
コマンドがエラーなく実行できるかどうかで、Go開発環境であるかを判断していました。forceAPICheck()
:GO_FORCE_API_CHECK
環境変数がtrue
に設定されているかどうかをチェックしていました。
もし isGoDeveloper
が false
であり、かつ GO_FORCE_API_CHECK
が設定されていない場合、APIチェックはスキップされていました。
変更後:
_, err := exec.LookPath("hg")
if err != nil {
fmt.Println("Skipping cmd/api checks; hg not available")
return
}
変更後は、exec.LookPath("hg")
を使用して、システムに hg
コマンドが存在するかどうかだけをチェックするようになりました。exec.LookPath
は、指定された実行可能ファイルがシステムのPATH環境変数内に存在するかどうかを確認します。もし hg
が見つからない場合(err != nil
)、APIチェックはスキップされます。
また、forceAPICheck()
関数自体も削除されました。
-// GO_FORCE_API_CHECK is set by builders.
-func forceAPICheck() bool {
- v, _ := strconv.ParseBool(os.Getenv("GO_FORCE_API_CHECK"))
- return v
-}
この変更により、APIチェックの実行条件が大幅に簡素化され、GO_FORCE_API_CHECK
環境変数に依存しなくなりました。hg
がシステムにインストールされていれば、常にAPIチェックが実行されるという明確な動作になりました。これは、ビルドシステムや開発環境において、APIチェックの実行をより確実にすることを意図していると考えられます。
コアとなるコードの変更箇所
--- a/src/cmd/api/run.go
+++ b/src/cmd/api/run.go
@@ -21,7 +21,6 @@ import (
"os/exec"
"os/user"
"path/filepath"
-\t"strconv"
"strings"
)
@@ -38,9 +37,9 @@ func main() {
if goroot == "" {
log.Fatal("No $GOROOT set.")
}
-\tisGoDeveloper := exec.Command("hg", "pq").Run() == nil
-\tif !isGoDeveloper && !forceAPICheck() {
-\t\tfmt.Println("Skipping cmd/api checks; hg codereview extension not available and GO_FORCE_API_CHECK not set")
+\t_, err := exec.LookPath("hg")
+\tif err != nil {
+\t\tfmt.Println("Skipping cmd/api checks; hg not available")
return
}
@@ -88,12 +87,6 @@ func file(s ...string) string {
return filepath.Join(goroot, "api", s[0]+".txt")
}
-// GO_FORCE_API_CHECK is set by builders.
-func forceAPICheck() bool {
-\tv, _ := strconv.ParseBool(os.Getenv("GO_FORCE_API_CHECK"))
-\treturn v
-}
-\n // prepGoPath returns a GOPATH for the "go" tool to compile the API tool with.
// It tries to re-use a go.tools checkout from a previous run if possible,
// else it hg clones it.
コアとなるコードの解説
上記のdiffは、src/cmd/api/run.go
ファイルにおける変更を示しています。
-
import "strconv"
の削除:- 変更前は
forceAPICheck()
関数内で環境変数GO_FORCE_API_CHECK
の文字列値をブール値に変換するためにstrconv.ParseBool
を使用していました。 forceAPICheck()
関数が削除されたため、strconv
パッケージも不要となり、インポートリストから削除されました。これはクリーンアップの一環です。
- 変更前は
-
APIチェック条件の変更:
- 削除された行:
この部分では、まずisGoDeveloper := exec.Command("hg", "pq").Run() == nil if !isGoDeveloper && !forceAPICheck() { fmt.Println("Skipping cmd/api checks; hg codereview extension not available and GO_FORCE_API_CHECK not set")
hg pq
コマンドを実行してisGoDeveloper
を設定し、その後にisGoDeveloper
とforceAPICheck()
の両方がfalse
の場合にAPIチェックをスキップしていました。 - 追加された行:
この新しいロジックでは、_, err := exec.LookPath("hg") if err != nil { fmt.Println("Skipping cmd/api checks; hg not available")
exec.LookPath("hg")
を呼び出して、システムPATHにhg
コマンドが存在するかどうかを確認します。err
がnil
でない場合(つまりhg
が見つからない場合)、APIチェックはスキップされます。これにより、APIチェックの実行条件が「hg
が利用可能であること」という単一の条件に簡素化されました。
- 削除された行:
-
forceAPICheck()
関数の削除:- ファイルの下部にあった
forceAPICheck()
関数全体が削除されました。この関数はGO_FORCE_API_CHECK
環境変数をチェックする役割を担っていましたが、新しいロジックでは不要になったため削除されました。
- ファイルの下部にあった
これらの変更により、cmd/api
は GO_FORCE_API_CHECK
環境変数に依存することなく、hg
コマンドの存在のみでAPIチェックの実行を判断するようになりました。これにより、APIチェックのロジックがよりシンプルで直接的になり、hg
がインストールされている環境であれば常にAPIチェックが実行されるという、より堅牢な動作が実現されました。
関連リンク
- GitHub上のコミットページ: https://github.com/golang/go/commit/afda774e95c103e7a4ecf61b945c8e5a166514ab
- Go CL (Change List): https://golang.org/cl/13500046
参考にした情報源リンク
- Go言語の公式ドキュメント (os/execパッケージ): https://pkg.go.dev/os/exec
- Mercurial (hg) 公式サイト: https://www.mercurial-scm.org/
- Go言語の環境変数 (GOROOT): https://go.dev/doc/install
- Go言語のAPI互換性に関するポリシー (Go 1 Compatibility Promise): https://go.dev/doc/go1compat
strconv
パッケージ: https://pkg.go.dev/strconv