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

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

このコミットは、Go言語のAPIチェッカーツールである cmd/api の挙動に関する変更です。具体的には、過去にAPIに含まれていたが、その後削除され api/except.txt に記載されている機能について、標準出力にその情報を出力しないように修正しています。これにより、ツールの出力から不要なノイズが削減され、よりクリーンな情報のみが表示されるようになります。

コミット

commit 2184282308566ad6fd445ea55ab755019e360d77
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date:   Tue May 14 09:43:56 2013 -0700

    cmd/api: don't print out except.txt removed features to stdout

    It's just noise. They've already been acknowledged in except.txt.

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

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

https://github.com/golang/go/commit/2184282308566ad6fd445ea55ab755019e360d77

元コミット内容

cmd/api: don't print out except.txt removed features to stdout

このコミットの目的は、cmd/api ツールが except.txt に記載されている削除済みのAPI機能について、標準出力に情報を表示しないようにすることです。コミットメッセージには「It's just noise. They've already been acknowledged in except.txt.」(それは単なるノイズだ。それらはすでに except.txt で認識されている。)とあり、冗長な出力を排除することが意図されています。

変更の背景

Go言語のAPIは、バージョンアップに伴い変更されることがあります。特に、一度公開されたAPIの一部が、設計上の理由や互換性の問題などにより削除されるケースも存在します。Goプロジェクトでは、このようなAPIの変更を追跡し、互換性を維持するための仕組みが導入されています。

cmd/api ツールは、GoのAPI定義を比較し、変更点を検出するために使用されます。このツールは、Goのリリースごとに定義されるAPIの「スナップショット」ファイル(例: go1.txt)と、現在のAPIを比較することで、APIの追加、削除、変更を特定します。

しかし、過去にAPIから削除された機能は api/except.txt というファイルにリストアップされ、その削除が「認識済み」であることを示しています。このコミット以前は、cmd/api ツールがAPIの比較を行う際に、except.txt に記載されている削除済み機能についても、その存在を標準出力に報告していました。これは、すでに except.txt で明示的に扱われている情報であるため、ツールの利用者にとっては冗長な「ノイズ」となっていました。

このコミットは、この冗長な出力を排除し、cmd/api の出力をより意味のある情報に絞り込むことを目的としています。これにより、開発者はAPIの変更点をより効率的に把握できるようになります。

前提知識の解説

このコミットを理解するためには、以下のGo言語開発における概念とツールに関する知識が必要です。

  • Go APIの安定性: Go言語は、後方互換性を非常に重視しています。特に、Go 1以降のリリースでは、既存のプログラムが新しいGoバージョンで動作し続けるように、APIの安定性が保証されています。しかし、ごく稀に、重大な問題や設計上の改善のためにAPIが変更または削除されることがあります。
  • cmd/api ツール:
    • Goの標準ライブラリに含まれるAPIの定義をチェックするための内部ツールです。
    • Goのリリースごとに、その時点での公開APIのリストが api/go1.txt のようなファイルに保存されます。
    • cmd/api は、現在のGoソースコードからAPIを抽出し、これらの「スナップショット」ファイルと比較することで、APIの変更を検出します。
    • これにより、GoチームはAPIの互換性を維持し、意図しないAPIの変更を防ぐことができます。
  • api/except.txt:
    • Goプロジェクトの api ディレクトリに存在するテキストファイルです。
    • このファイルには、過去にGoの公開APIに含まれていたが、その後削除されたり、特定の理由で互換性チェックから除外されたりするAPI要素がリストされています。
    • except.txt に記載されているAPI要素は、その変更がGoチームによって「認識済み」であり、意図的なものであることを示します。したがって、cmd/api がこれらの要素を検出しても、通常のエラーや警告としては扱われません。
  • go1.txt:
    • Go 1のリリース時に定義された公開APIのリストを含むファイルです。
    • Goの互換性保証の基準となる重要なファイルの一つです。
    • cmd/api は、このファイルやその後のリリースごとのAPI定義ファイルと比較することで、APIの変更を追跡します。
  • 標準出力 (stdout): プログラムが結果や情報を出力するデフォルトの場所です。通常、ターミナルやコンソールに表示されます。

技術的詳細

このコミットの技術的な変更は、cmd/api ツールの中核部分であるAPI比較ロジックにあります。

src/cmd/api/goapi.go ファイル内の compareAPI 関数は、GoのAPIを比較する主要なロジックを担っています。この関数は、features (現在のAPI)、required (期待されるAPI、例: go1.txt から読み込まれたもの)、optionalexception (例外リスト、except.txt から読み込まれたもの) といった複数のAPIリストを受け取ります。

変更前のコードでは、required リストに含まれる機能が features リスト(現在のAPI)には存在せず、かつその機能が exceptionSetexcept.txt に含まれる機能のセット)に存在する場合、つまり「過去に存在したが、現在は削除され、かつ except.txt で認識されている機能」である場合に、fmt.Fprintf(w, "~%s\\n", feature) という行が実行され、その機能名が標準出力に ~ プレフィックス付きで出力されていました。

このコミットでは、この fmt.Fprintf の呼び出しが削除されました。代わりに、その行があった場所にコメントが追加され、このケース(削除され except.txt にある機能)はすでに except.txt で認識されているため、ここで出力する必要はないという説明がされています。

これにより、compareAPI 関数は、except.txt に記載された削除済み機能については、何も出力しなくなります。

テストファイル src/cmd/api/goapi_test.go の変更は、この挙動の変更を反映したものです。TestCompareAPI 関数内のテストケースの一つで、exception: []string{"B"} と設定されたシナリオ(機能 "B" が except.txt にあると仮定)において、期待される出力 out~B\n から "" (空文字列) に変更されています。これは、機能 "B" が削除され except.txt にある場合、もはや出力されないことをテストで確認するための修正です。

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

src/cmd/api/goapi.go

--- a/src/cmd/api/goapi.go
+++ b/src/cmd/api/goapi.go
@@ -231,7 +231,12 @@ func compareAPI(w io.Writer, features, required, optional, exception []string) (
 		case len(features) == 0 || (len(required) > 0 && required[0] < features[0]):
 			feature := take(&required)
 			if exceptionSet[feature] {
-				fmt.Fprintf(w, "~%s\\n", feature)
+				// An "unfortunate" case: the feature was once
+				// included in the API (e.g. go1.txt), but was
+				// subsequently removed. These are already
+				// acknowledged by being in the file
+				// "api/except.txt". No need to print them out
+				// here.
 			} else if featureSet[featureWithoutContext(feature)] {
 				// okay.
 			} else {

src/cmd/api/goapi_test.go

--- a/src/cmd/api/goapi_test.go
+++ b/src/cmd/api/goapi_test.go
@@ -110,7 +110,7 @@ func TestCompareAPI(t *testing.T) {
 			features:  []string{"A", "C"},
 			exception: []string{"B"},
 			ok:        true,
-			out:       "~B\\n",
+			out:       "",
 		},
 		{
 			// http://golang.org/issue/4303

コアとなるコードの解説

src/cmd/api/goapi.go の変更

compareAPI 関数内の if exceptionSet[feature] ブロックが変更されています。 変更前は、exceptionSet に含まれる feature (API要素) が見つかった場合、つまり except.txt に記載されている削除済み機能である場合に、fmt.Fprintf(w, "~%s\\n", feature) を使ってその機能名を ~ プレフィックス付きで出力していました。

変更後は、この fmt.Fprintf の行が削除され、代わりに複数行のコメントが追加されています。このコメントは、このケースが「不幸なケース」(APIに一度含まれたが、その後削除された機能)であり、これらの機能はすでに api/except.txt で認識されているため、ここで出力する必要がないことを説明しています。

この変更により、cmd/api ツールは、except.txt にリストされている削除済みAPI機能については、もはや標準出力に何も報告しなくなります。これは、ツールの出力をより簡潔にし、本当に注意すべきAPIの変更点(例えば、except.txt にない意図しない削除など)に焦点を当てることを可能にします。

src/cmd/api/goapi_test.go の変更

TestCompareAPI 関数内のテストデータ構造 tests の一部が変更されています。 特定のテストケースで、exception: []string{"B"} と設定されています。これは、API機能 "B" が except.txt に記載されていることをシミュレートしています。 変更前は、このテストケースの期待される出力 out~B\n でした。これは、機能 "B" が except.txt にある場合でも、以前の goapi.go のロジックでは ~B が出力されることを期待していたためです。 変更後は、out"" (空文字列) になっています。これは、goapi.go の変更によって、except.txt にある機能はもはや出力されないという新しい挙動をテストで検証するためのものです。このテストの変更は、コードの変更が意図した通りに動作することを確認する上で不可欠です。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント
  • Go言語のGitHubリポジトリのソースコード
  • コミットメッセージと関連するGoのChange-ID (https://golang.org/cl/9392047) を通じたGoのコードレビューシステム (Gerrit) の情報。