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

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

このコミットは、Go言語のディストリビューションからcmd/apiツールを削除することを目的としています。cmd/apiはGo開発者がGo 1 APIの互換性保証を破ることを防ぐための内部ツールであり、エンドユーザーには有用性がなく、また標準ライブラリ以外では動作しないという制約がありました。将来的にgo.toolsリポジトリのgo/typesに依存する新しい実装が予定されているため、バイナリ配布物からこのツールを除外する変更が行われました。

コミット

  • コミットハッシュ: b8b48abe0fbd3ce6a1f8332da8ad6b8885a3aa1d
  • Author: Brad Fitzpatrick bradfitz@golang.org
  • Date: Fri Aug 2 10:19:52 2013 -0700

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

https://github.com/golang/go/commit/b8b48abe0fbd3ce6a1f8332da8ad6b8885a3aa1d

元コミット内容

misc/dist: don't ship cmd/api

cmd/api is a tool to prevent the Go developers from breaking
the Go 1 API promise. It has no utility to end users and
doesn't run on arbitrary packages (it's always been full of
hacks for its bespoke type checker to work on the standard
library)

Robert's in-progress rewrite depends on the go.tools repo for
go/types, so we won't be able to ship this tool later
anyway. Just remove it from binary distributions.

A future change to run.bash can conditionally build & run
cmd/api, perhaps automatically fetching go/types if
necessary. I assume people don't want to vendor go/types into
a private gopath just for cmd/api.

I will need help with run.bat.

R=golang-dev, adg, dsymonds, rsc
CC=golang-dev
https://golang.org/cl/12316043

変更の背景

この変更の主な背景は、cmd/apiツールの性質と、Go言語の将来的な開発計画にあります。

  1. エンドユーザーへの無用性: cmd/apiは、Go言語のコア開発者がGo 1のAPI互換性保証を維持するために使用する内部ツールでした。これは、Goの標準ライブラリのAPIがGo 1リリース以降、後方互換性を損なわないように変更されていないかをチェックする目的で使われていました。そのため、一般のエンドユーザーがGoアプリケーションを開発する上でこのツールを使用する機会はほとんどなく、バイナリディストリビューションに含める必要性が低いと判断されました。

  2. 技術的制約と将来の展望: cmd/apiは、独自の型チェッカーを内蔵しており、これが標準ライブラリに特化したハックに満ちていたため、任意のパッケージに対しては動作しませんでした。Robert Griesemer氏によるcmd/apiの書き換えが進行中であり、その新しい実装はgo.toolsリポジトリ内のgo/typesパッケージに依存することが計画されていました。go.toolsはGoの公式ツール群を開発するためのリポジトリであり、go/typesはGoの型システムを扱うためのパッケージです。この依存関係の変更により、cmd/apiをGoのメインディストリビューションに含めることが難しくなるため、バイナリ配布物から削除する決定が下されました。

  3. 開発ワークフローの最適化: 将来的には、run.bashスクリプト(Goのビルドとテストを実行するスクリプト)が条件付きでcmd/apiをビルド・実行し、必要に応じてgo/typesを自動的にフェッチするような仕組みが検討されていました。これにより、開発者がcmd/apiを使用するためにgo/typesを個人のGOPATHにベンダーする必要がなくなるという利点があります。

これらの理由から、cmd/apiをGoのバイナリディストリビューションから除外し、よりクリーンで効率的な開発環境を構築することが目指されました。

前提知識の解説

このコミットを理解するためには、以下の概念について知っておく必要があります。

  1. Go 1 API Promise (Go 1 互換性保証): Go言語は、バージョン1.0のリリース以降、厳格な後方互換性ポリシーを維持しています。これは「Go 1 API Promise」として知られ、Go 1.xのリリースでは、Go 1.0で書かれたプログラムが将来のGo 1.xバージョンでもコンパイルされ、動作し続けることを保証するというものです。この互換性保証は、Goが広く採用される上で非常に重要な要素であり、開発者が安心してGoのバージョンアップを行える基盤となっています。cmd/apiツールは、このGo 1 API Promiseが破られていないかを自動的にチェックするためにGo開発チームが使用していた内部ツールでした。

  2. cmd/apiツール: Goのソースコードリポジトリ内に存在した内部ツールで、Goの標準ライブラリのAPI定義を解析し、Go 1 API Promiseに違反する変更がないかを検出する役割を担っていました。例えば、既存の公開関数から引数が削除されたり、型定義が変更されたりすると、このツールがそれを検出し、互換性違反として報告していました。しかし、このツールはGoのビルドプロセスの一部として配布されるものではなく、Go開発者向けの特殊なツールでした。

  3. go.toolsリポジトリ: golang.org/x/toolsとして知られるGoの公式ツール群を開発するためのリポジトリです。Goのメインリポジトリ(golang/go)とは別に管理されており、go vetgoimportsgoplsなどの様々な開発支援ツールが含まれています。これらのツールはGoのリリースサイクルとは独立して開発・更新されることが多く、Goのメインディストリビューションには通常含まれません。

  4. go/typesパッケージ: golang.org/x/tools/go/typesに存在するパッケージで、Goの型システムをプログラム的に扱うための機能を提供します。Goのソースコードを解析し、型情報を抽出したり、型チェックを行ったりするために使用されます。コンパイラやリンター、IDEなどのツールがGoのコードを理解し、分析するために不可欠なコンポーネントです。cmd/apiの新しい実装がこのパッケージに依存するということは、より汎用的で堅牢な型解析機能を利用するようになることを意味します。

  5. misc/dist/bindist.go: Goのバイナリディストリビューションを構築する際に、配布物から除外すべきファイルやディレクトリを指定するGoのソースファイルです。このファイルにリストされたパスは、最終的なGoのリリースパッケージには含まれません。

  6. src/run.bash: Goのソースツリーのルートにあるシェルスクリプトで、Goのビルド、テスト、およびその他の開発関連タスクを実行するために使用されます。GoのCI/CDパイプラインや開発者のローカル環境で頻繁に実行されるスクリプトです。

技術的詳細

このコミットは、Goのビルドおよび配布プロセスからcmd/apiツールを削除するための具体的な変更を含んでいます。

  1. misc/dist/bindist.goの変更: misc/dist/bindist.goファイルは、Goのバイナリディストリビューションを作成する際に、配布物から除外されるべきファイルやディレクトリのリストを定義しています。このコミットでは、preBuildCleanFilesという文字列スライスに"src/cmd/api"が追加されました。これにより、Goのリリースビルドが作成される前に、src/cmd/apiディレクトリがクリーンアップ(削除)されるようになります。結果として、cmd/apiツールはGoの公式バイナリディストリビューションには含まれなくなります。

  2. src/run.bashの変更: src/run.bashスクリプトは、Goのソースツリーのビルドとテストを実行する主要なスクリプトです。以前は、このスクリプト内でGoのAPI互換性チェックのためにgo tool apiコマンドが無条件に実行されていました。 このコミットでは、go tool apiの実行部分がif [ -d "$GOROOT/src/cmd/api" ]という条件文で囲まれました。この条件文は、$GOROOT/src/cmd/apiディレクトリが存在する場合にのみ、API互換性チェックを実行するように変更します。 misc/dist/bindist.goの変更により、バイナリディストリビューションではsrc/cmd/apiが削除されるため、この条件文によってgo tool apiの実行がスキップされるようになります。これにより、エンドユーザーがダウンロードするGoのバイナリパッケージにはcmd/apiが含まれず、またそのAPIチェックも実行されなくなります。 ただし、Goのソースコードからビルドする開発環境など、src/cmd/apiが存在する場合には、引き続きAPI互換性チェックが実行されることになります。これは、Go開発者がAPI互換性を維持するための内部的なチェック機構としては残しつつ、一般配布物からは除外するという意図を反映しています。

この変更は、Goのビルドシステムと配布メカニズムに直接影響を与え、cmd/apiの存在をGoの公式リリースから切り離すための重要なステップです。

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

diff --git a/misc/dist/bindist.go b/misc/dist/bindist.go
index 754bd280c2..f56a88dc6b 100644
--- a/misc/dist/bindist.go
+++ b/misc/dist/bindist.go
@@ -50,6 +50,7 @@ const (
 var preBuildCleanFiles = []string{
 	"lib/codereview",
 	"misc/dashboard/godashboard",
+	"src/cmd/api",
 	"src/cmd/cov",
 	"src/cmd/prof",
 	"src/pkg/exp",
diff --git a/src/run.bash b/src/run.bash
index 83ef65bf0b..e5f2c384bb 100755
--- a/src/run.bash
+++ b/src/run.bash
@@ -176,9 +176,12 @@ unset GOMAXPROCS
 time go run run.go || exit 1
 ) || exit $?\n
-echo
-echo '# Checking API compatibility.'
-go tool api -c $GOROOT/api/go1.txt,$GOROOT/api/go1.1.txt -next $GOROOT/api/next.txt -except $GOROOT/api/except.txt
+if [ -d "$GOROOT/src/cmd/api" ]
+then
+\techo
+\techo '# Checking API compatibility.'
+\tgo tool api -c $GOROOT/api/go1.txt,$GOROOT/api/go1.1.txt -next $GOROOT/api/next.txt -except $GOROOT/api/except.txt
+fi
 
 echo
 echo ALL TESTS PASSED

コアとなるコードの解説

misc/dist/bindist.go の変更

  • 変更前: preBuildCleanFilesという文字列スライスには、Goのバイナリディストリビューションを構築する際に削除されるべきファイルやディレクトリのパスがリストされていました。このリストにはsrc/cmd/apiは含まれていませんでした。
  • 変更後: preBuildCleanFilesスライスに"src/cmd/api"が追加されました。
  • 解説: この変更により、Goの公式バイナリディストリビューションが作成される前処理として、src/cmd/apiディレクトリとその内容が完全に削除されるようになります。これにより、cmd/apiツールがエンドユーザー向けのGoリリースパッケージに含まれることがなくなります。これは、cmd/apiが内部ツールであり、エンドユーザーには不要であるという判断に基づいています。

src/run.bash の変更

  • 変更前: src/run.bashスクリプトの後半部分で、API互換性チェックのためにgo tool apiコマンドが無条件に実行されていました。このコマンドは、Go 1 APIの互換性を検証するために、特定のAPI定義ファイル(go1.txt, go1.1.txt, next.txt, except.txt)を参照していました。
  • 変更後: go tool apiコマンドの実行部分が、if [ -d "$GOROOT/src/cmd/api" ]という条件文で囲まれました。
    • [ -d "$GOROOT/src/cmd/api" ]は、$GOROOT/src/cmd/apiというパスがディレクトリとして存在するかどうかをチェックするシェルスクリプトの条件式です。
    • この条件が真(ディレクトリが存在する)の場合にのみ、echoコマンドでメッセージを表示し、その後にgo tool apiコマンドが実行されます。
  • 解説: この変更は、cmd/apiツールがバイナリディストリビューションから削除された場合でも、run.bashスクリプトがエラーなく実行されるようにするためのものです。
    • Goの公式リリースバイナリを使用する場合、misc/dist/bindist.goの変更によりsrc/cmd/apiは存在しないため、このif条件は偽となり、go tool apiコマンドは実行されません。
    • しかし、Goのソースコードから直接ビルドを行う開発環境など、src/cmd/apiが存在する場合には、引き続きAPI互換性チェックが実行されます。これにより、Go開発者はAPIの互換性違反を継続的にチェックできる一方で、エンドユーザーは不要なツールを含まない軽量なディストリビューションを利用できるようになります。

これらの変更は連携して機能し、cmd/apiをGoの公式配布物から除外しつつ、Go開発者が必要に応じてその機能を利用できる柔軟性を維持しています。

関連リンク

参考にした情報源リンク