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

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

このコミットは、Go言語のツールである cmd/api の動作に関する修正です。具体的には、cmd/api ツールが正常終了(終了ステータスが0)した場合でも、その出力(標準出力)が表示されるように変更されました。これにより、APIの追加など、next.txt に記録されるべき変更が正しく確認できるようになります。

コミット

9a9e541c4db86bb1c590b0f4657929dde4312e2b

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

https://github.com/golang/go/commit/9a9e541c4db86bb1c590b0f4657929dde4312e2b

元コミット内容

cmd/api: show output of api tool even if exit status is 0

We weren't seeing additions. (stuff to put in next.txt)

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/12678043

変更の背景

cmd/api ツールは、Go言語の標準ライブラリのAPI互換性をチェックするために使用されます。このツールは、既存のAPIに対する変更(追加、削除、変更)を検出し、その結果を標準出力に出力します。特に、新しいAPIの追加は next.txt というファイルに記録されるべき重要な情報です。

しかし、このコミットが行われる前は、cmd/api ツールがエラーなく正常に実行された場合(つまり、終了ステータスが0の場合)、その出力が標準出力に表示されないという問題がありました。これは、APIの追加など、ツールが検出した重要な情報がユーザーに伝わらないことを意味します。コミットメッセージにある「We weren't seeing additions. (stuff to put in next.txt)」という記述は、この問題が特にAPIの追加(next.txt に記録されるべき内容)の確認を妨げていたことを明確に示しています。

この変更は、開発者がAPIの変更を正確に把握し、next.txt の更新を適切に行えるようにするために不可欠でした。

前提知識の解説

  • cmd/api ツール: Go言語のソースコードリポジトリに含まれる内部ツールの一つです。その主な目的は、Goの標準ライブラリのAPIの互換性をチェックすることです。Go言語は後方互換性を非常に重視しており、既存のAPIに対する破壊的な変更は厳しく管理されています。cmd/api は、Goのリリースプロセスにおいて、APIの変更が意図した通りであるか、または互換性を損ねていないかを検証するために利用されます。このツールは、GoのAPI定義ファイル(例: api/go1.txt)と現在のソースコードを比較し、差異を報告します。
  • next.txt: Go言語の標準ライブラリにおいて、次のメジャーリリースで追加される予定のAPIを記述するためのファイルです。GoのAPI互換性ポリシーでは、既存のAPIを削除したり変更したりすることは原則として許可されていませんが、新しいAPIを追加することは可能です。next.txt は、これらの新しいAPIを文書化し、将来のリリースで正式に公開される前にレビューするためのメカニズムとして機能します。cmd/api ツールは、この next.txt の内容と実際のAPIの差異もチェックします。
  • 終了ステータス (Exit Status): プログラムやコマンドが実行を終了した際に、オペレーティングシステムに返す数値です。慣例として、終了ステータスが 0 の場合は正常終了、0 以外の値はエラーや異常終了を示します。シェルスクリプトなどでは、この終了ステータスをチェックして、後続の処理を分岐させることがよくあります。
  • 標準出力 (Standard Output, stdout): プログラムが通常の結果や情報を出力するために使用する出力ストリームです。多くのCLIツールは、処理結果やメッセージを標準出力に表示します。

技術的詳細

このコミットの技術的な問題は、cmd/api ツールが exec.Command を使用してAPIチェッカーを実行し、その結果を bytes.Buffer にキャプチャしていたにもかかわらず、そのキャプチャした内容を無条件に標準出力に表示していなかった点にあります。

元のコードでは、exec.Command の実行結果として errnil (エラーなし) でない場合にのみ、エラーメッセージと共にキャプチャした出力 out を表示していました。これは、エラーが発生した場合にデバッグ情報として出力を表示する一般的なパターンです。しかし、cmd/api の場合、エラーがない場合でも、APIの追加などの情報が out に含まれている可能性がありました。

このコミットは、このロジックを変更し、exec.Command の実行が成功したかどうかにかかわらず、キャプチャした out の内容を fmt.Print(string(out)) を使って標準出力に書き出すようにしました。これにより、ツールが正常に動作し、APIの変更を検出した場合でも、その情報がユーザーに可視化されるようになりました。

この修正は、cmd/api ツールのユーザーエクスペリエンスを向上させ、APIの変更管理プロセスにおける重要な情報を見落とすリスクを排除しました。

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

--- a/src/cmd/api/run.go
+++ b/src/cmd/api/run.go
@@ -57,6 +57,7 @@ func main() {
 	if err != nil {
 		log.Fatalf("Error running API checker: %v\n%s", err, out)
 	}
+	fmt.Print(string(out))
 }

 // file expands s to $GOROOT/api/s.txt.

コアとなるコードの解説

変更は src/cmd/api/run.go ファイルの main 関数内で行われています。

元のコードでは、APIチェッカーの実行結果を err 変数でチェックしていました。

	if err != nil {
		log.Fatalf("Error running API checker: %v\n%s", err, out)
	}

この if ブロックは、errnil でない(つまり、APIチェッカーの実行中にエラーが発生した)場合にのみ実行され、エラーメッセージとキャプチャされた出力 out を表示してプログラムを終了していました。

このコミットによって追加された行は以下の通りです。

	fmt.Print(string(out))

この行は、if err != nil ブロックの直後、つまりAPIチェッカーの実行がエラーなく完了した場合(errnil の場合)に実行されます。outexec.Command の標準出力と標準エラー出力をキャプチャしたバイトスライスであり、string(out) で文字列に変換され、fmt.Print によって標準出力に書き出されます。

このシンプルな追加により、cmd/api ツールは、APIの追加やその他の変更が検出され、それがエラーとして扱われなかった場合でも、その詳細をユーザーに報告できるようになりました。これにより、開発者は cmd/api の出力を常に確認し、next.txt の更新などの必要なアクションを適切に実行できるようになります。

関連リンク

参考にした情報源リンク

  • Go言語のソースコード (src/cmd/api/run.go の変更前後の内容)
  • Go言語のAPI互換性に関するドキュメント (一般的な知識として)
  • exec.Command および fmt.Print のGo言語標準ライブラリのドキュメント (一般的な知識として)