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

[インデックス 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() 関数に依存していました。

  • isGoDeveloperhg 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.Commandexec.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チェックのスキップを判断していました。

  1. isGoDeveloper: hg pq コマンドがエラーなく実行できるかどうかで、Go開発環境であるかを判断していました。
  2. forceAPICheck(): GO_FORCE_API_CHECK 環境変数が true に設定されているかどうかをチェックしていました。

もし isGoDeveloperfalse であり、かつ 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 ファイルにおける変更を示しています。

  1. import "strconv" の削除:

    • 変更前は forceAPICheck() 関数内で環境変数 GO_FORCE_API_CHECK の文字列値をブール値に変換するために strconv.ParseBool を使用していました。
    • forceAPICheck() 関数が削除されたため、strconv パッケージも不要となり、インポートリストから削除されました。これはクリーンアップの一環です。
  2. 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 を設定し、その後に isGoDeveloperforceAPICheck() の両方が false の場合にAPIチェックをスキップしていました。
    • 追加された行:
      _, err := exec.LookPath("hg")
      if err != nil {
      	fmt.Println("Skipping cmd/api checks; hg not available")
      
      この新しいロジックでは、exec.LookPath("hg") を呼び出して、システムPATHに hg コマンドが存在するかどうかを確認します。errnil でない場合(つまり hg が見つからない場合)、APIチェックはスキップされます。これにより、APIチェックの実行条件が「hg が利用可能であること」という単一の条件に簡素化されました。
  3. forceAPICheck() 関数の削除:

    • ファイルの下部にあった forceAPICheck() 関数全体が削除されました。この関数は GO_FORCE_API_CHECK 環境変数をチェックする役割を担っていましたが、新しいロジックでは不要になったため削除されました。

これらの変更により、cmd/apiGO_FORCE_API_CHECK 環境変数に依存することなく、hg コマンドの存在のみでAPIチェックの実行を判断するようになりました。これにより、APIチェックのロジックがよりシンプルで直接的になり、hg がインストールされている環境であれば常にAPIチェックが実行されるという、より堅牢な動作が実現されました。

関連リンク

参考にした情報源リンク