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

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

このコミットは、Goコマンドラインツールにおけるビルドフラグの扱いを統一することを目的としています。特に、go clean および go list コマンドが、他のビルド関連コマンド(go build, go install, go run, go test)と同様に共通のビルドフラグを受け入れるように変更されました。これにより、Goツールのコマンドラインインターフェースの一貫性が向上し、ユーザーエクスペリエンスが改善されています。

コミット

commit 0f52fdbf7ba599702643660b46ce94f4925856b0
Author: Russ Cox <rsc@golang.org>
Date:   Fri May 9 16:32:38 2014 -0400

    cmd/go: accept build flags in clean and list
    
    list has been adding them one at a time haphazardly
    (race and tags were there and documented; compiler
    was there and undocumented).
    
    clean -i needs -compiler in order to clean the
    installed targets for alternate compilers.
    
    Fixes #7302.
    
    While we're here, tweak the language in the 'go get' docs
    about build flags.
    
    Fixes #7807.
    
    LGTM=iant
    R=golang-codereviews, iant
    CC=golang-codereviews
    https://golang.org/cl/99130043

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

https://github.com/golang/go/commit/0f52fdbf7ba599702643660b46ce94f4925856b0

元コミット内容

cmd/go: accept build flags in clean and list

list コマンドはこれまで、ビルドフラグを場当たり的に追加していました(-race-tags は文書化されていましたが、-compiler は文書化されていませんでした)。

clean -i は、代替コンパイラ用にインストールされたターゲットをクリーンアップするために -compiler を必要とします。

Issue #7302 を修正します。

ついでに、go get のドキュメントにおけるビルドフラグに関する記述を修正します。

Issue #7807 を修正します。

変更の背景

この変更の背景には、Goコマンドラインツールの一貫性と使いやすさの向上が挙げられます。

  1. ビルドフラグの一貫性の欠如: 以前は、go buildgo installgo rungo test といった主要なビルド関連コマンドは共通のビルドフラグ(例: -a, -n, -x, -tags, -race, -compiler など)をサポートしていましたが、go cleango list といった他のコマンドでは、これらのフラグのサポートが不完全であったり、場当たり的に実装されていたりしました。特に go list では、-race-tags はサポートされていましたが、-compiler はサポートされておらず、その挙動も一貫していませんでした。
  2. go clean -i の機能不足: go clean -i は、インストールされたパッケージのクリーンアップを行うためのフラグですが、代替コンパイラ(例えば、クロスコンパイル環境など)でビルドされたターゲットを正確にクリーンアップするためには、どのコンパイラが使用されたかを指定する -compiler フラグの情報が必要でした。しかし、go clean コマンドがこのフラグを適切に受け入れないため、このシナリオでのクリーンアップが困難でした。
  3. ドキュメントの不正確さ: go get コマンドのドキュメントには、ビルドフラグに関する記述がありましたが、その表現が曖昧であったり、最新の挙動を反映していなかったりする部分がありました。
  4. Issue #7302 と #7807 の解決: このコミットは、具体的にGoのIssueトラッカーで報告されていた2つの問題、#7302 と #7807 を修正することを目的としています。これらのIssueは、ビルドフラグの不整合やドキュメントの不備に関連するものでした。

これらの問題を解決することで、Go開発者はより予測可能で一貫性のある方法でGoツールを使用できるようになり、特に複雑なビルド環境やクリーンアップ作業において、その利便性が向上しました。

前提知識の解説

このコミットを理解するためには、以下のGoコマンドラインツールの概念とフラグに関する知識が役立ちます。

  1. Goコマンドラインツール: Go言語には、ソースコードのビルド、テスト、依存関係の管理などを行うための強力なコマンドラインツールセットが付属しています。主要なコマンドには go build, go install, go run, go test, go get, go clean, go list などがあります。
  2. ビルドフラグ (Build Flags): これらのコマンドの多くは、ビルドプロセスやその他の操作の挙動を制御するための「ビルドフラグ」を受け入れます。これらは通常、go help build コマンドで確認できる共通のフラグ群です。
    • -a: 既に最新であるパッケージであっても、強制的に再ビルドします。
    • -n: コマンドを実行せずに、実行されるコマンドを表示します(ドライラン)。
    • -x: 実行されるコマンドを表示し、実際に実行します(詳細なトレース)。
    • -tags 'tag list': ビルドタグを指定します。これにより、特定のビルドタグが有効な場合にのみコンパイルされるコードブロック(// +build tag ディレクティブで指定)を制御できます。例えば、go build -tags 'debug' とすると、debug タグが有効になります。
    • -race: 競合検出器を有効にしてビルドします。これにより、並行処理におけるデータ競合の検出が可能になります。
    • -compiler name: 使用するコンパイラを指定します。通常は gc (Goコンパイラ) ですが、gccgo などの代替コンパイラを使用する場合に指定します。
  3. go clean コマンド: Goプロジェクトのビルドによって生成されたオブジェクトファイルやキャッシュファイルを削除し、クリーンな状態に戻すためのコマンドです。
    • -i: インストールされたパッケージのアーカイブファイルも削除します。
    • -r: 依存関係にあるパッケージのオブジェクトファイルも再帰的に削除します。
  4. go list コマンド: 指定されたパッケージに関する情報を表示するコマンドです。パッケージのインポートパス、依存関係、ビルド情報などをJSON形式やカスタムフォーマットで出力できます。
  5. go get コマンド: リモートリポジトリからGoパッケージをダウンロードし、インストールするためのコマンドです。依存関係の解決にも使用されます。
  6. go help build: Goコマンドラインツールにおけるビルドフラグに関する詳細な説明を表示するコマンドです。このコマンドは、共通のビルドフラグとその意味を理解するための主要な情報源となります。
  7. Issueトラッカー (Issue Tracker): Goプロジェクトでは、バグ報告や機能要望を管理するためにIssueトラッカー(GitHub Issuesなど)を使用しています。コミットメッセージに Fixes #XXXX とある場合、それはそのコミットが特定のIssueを解決したことを意味します。

これらの概念を理解することで、このコミットがGoツールのどの部分に影響を与え、どのような問題を解決しようとしているのかを深く把握することができます。

技術的詳細

このコミットの技術的な核心は、Goコマンドラインツールにおけるビルドフラグの処理ロジックを中央集権化し、再利用性を高めることにあります。具体的には、以下の点が変更されています。

  1. addBuildFlags 関数の適用範囲の拡大:

    • src/cmd/go/build.go に定義されている addBuildFlags 関数は、元々 go build および go install コマンドに共通のビルドフラグを追加するために使用されていました。
    • このコミットでは、この関数のコメントと内部ロジックが更新され、go clean, go get, go list, go run, go test コマンドもこの共通のビルドフラグセットを利用するように変更されました。これにより、各コマンドが個別にビルドフラグを定義・解析する必要がなくなり、コードの重複が削減され、一貫性が保証されます。
  2. go clean コマンドのフラグ処理の統合:

    • 以前の go clean コマンドは、-n (ドライラン) や -x (コマンド表示) といったフラグを独自に定義し、cleanNcleanX といった専用の変数で管理していました。
    • このコミットでは、これらのフラグの定義が go cleaninit 関数から削除され、代わりに addBuildFlags(cmdClean) が呼び出されるようになりました。これにより、cleanNcleanX の代わりに、共通のビルドフラグ変数である buildNbuildX が使用されるようになります。
    • clean 関数内のロジックも、cleanN || cleanX から buildN || buildX へと変更され、共通のビルドフラグ変数に依存するようになりました。
    • これにより、go clean-tags-compiler といった他のビルドフラグも透過的に受け入れ、特に clean -i が代替コンパイラでビルドされたターゲットをクリーンアップする際に -compiler フラグを適切に利用できるようになります。
  3. go list コマンドのフラグ処理の統合と簡素化:

    • go list コマンドは、これまで -race, -tags, -compiler といったビルド関連のフラグを個別に定義していました。特に -compiler は文書化されていませんでした。
    • このコミットでは、cmdList.Flag.Var を用いたこれらのフラグの個別定義が削除され、addBuildFlags(cmdList) が呼び出されるようになりました。
    • これにより、go list は共通のビルドフラグセットを継承し、-race フラグの処理ロジック(if *listRace { buildRace = true })も不要になりました。これは、buildRace が既に共通のビルドコンテキストの一部として管理されるためです。
  4. ドキュメントの更新:

    • src/cmd/go/doc.go および src/cmd/go/get.gosrc/cmd/go/list.go のドキュメントが更新され、go clean, go list, go get コマンドがビルドフラグを受け入れること、そしてビルドフラグの詳細については go help build を参照するように明記されました。これにより、ユーザーは一貫したドキュメントを参照できるようになります。

これらの変更により、Goコマンドラインツールの内部構造はよりモジュール化され、保守性が向上しました。また、ユーザーにとっては、どのGoコマンドでも同じビルドフラグが期待通りに機能するという、より予測可能なインターフェースが提供されることになります。

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

このコミットにおける主要なコード変更は、以下のファイルに集中しています。

  1. src/cmd/go/build.go:

    • addBuildFlags 関数のコメントが更新され、この関数が build, clean, get, install, list, run, test の各コマンドに共通のビルドフラグを追加することが明記されました。
  2. src/cmd/go/clean.go:

    • cmdCleanUsageLineclean [-i] [-r] [-n] [-x] [packages] から clean [-i] [-r] [-n] [-x] [build flags] [packages] に変更され、ビルドフラグを受け入れることが示されました。
    • cleanN, cleanX といった個別のフラグ変数の宣言が削除されました。
    • init 関数内で addBuildFlags(cmdClean) が呼び出されるようになりました。
    • clean 関数内のフラグ参照が cleanNcleanX から buildNbuildX に変更されました。
  3. src/cmd/go/doc.go:

    • go build, go clean, go listUsage セクションが更新され、ビルドフラグの受け入れが反映されました。
    • 特に go list の説明から、-tags-race フラグに関する具体的な記述が削除され、代わりに「ビルドフラグの詳細については go help build を参照してください」という一般的な記述に置き換えられました。
  4. src/cmd/go/get.go:

    • go get コマンドのドキュメントにおいて、ビルドフラグに関する記述が簡素化され、「go help build を参照してください」という指示に統一されました。
  5. src/cmd/go/list.go:

    • cmdListUsageLinelist [-e] [-race] [-f format] [-json] [-tags 'tag list'] [packages] から list [-e] [-f format] [-json] [build flags] [packages] に変更され、ビルドフラグを受け入れることが示されました。
    • cmdList.Flag.Var を用いた compiler, tags の個別フラグ定義が削除されました。
    • init 関数内で addBuildFlags(cmdList) が呼び出されるようになりました。
    • listRace 変数と、それに基づいて buildRace を設定するロジックが削除されました。

これらの変更は、Goコマンドラインツールのフラグ処理ロジックを中央集権化し、一貫性を高めるためのものです。

コアとなるコードの解説

このコミットのコアとなる変更は、Goコマンドラインツールにおけるビルドフラグの処理を共通化する addBuildFlags 関数の利用拡大と、それに伴う各コマンドのフラグ処理ロジックの簡素化です。

src/cmd/go/build.go の変更: このファイルでは、addBuildFlags 関数の役割が明確化されています。以前は buildinstall コマンドに共通のフラグを追加するものでしたが、このコミットにより、clean, get, list, run, test コマンドも対象となることがコメントで明記されました。これは、この関数がGoコマンドラインツール全体のビルドフラグ管理の中心となることを示しています。

// addBuildFlags adds the flags common to the build, clean, get,
// install, list, run, and test commands.
func addBuildFlags(cmd *Command) {
	// NOTE: If you add flags here, also add them to testflag.go.
	cmd.Flag.BoolVar(&buildA, "a", false, "")
	// ... (他の共通ビルドフラグの定義)
}

この関数は、*Command 型の引数 cmd を受け取り、その Flag フィールド(flag.FlagSet のインスタンス)に共通のビルドフラグ(-a, -n, -x, -tags, -race, -compiler など)を登録します。これにより、各コマンドは自身の init 関数内で addBuildFlags(cmdX) を呼び出すだけで、これらの共通フラグを自動的にサポートできるようになります。

src/cmd/go/clean.go の変更: go clean コマンドは、これまで -n-x フラグを独自に管理していました。

変更前:

var cleanN bool // clean -n flag
var cleanX bool // clean -x flag

func init() {
	// ...
	cmdClean.Flag.BoolVar(&cleanN, "n", false, "")
	cmdClean.Flag.BoolVar(&cleanX, "x", false, "")
}

func clean(p *Package) {
	if cleanN || cleanX {
		// ...
	}
	// ...
}

変更後:

// var cleanN bool // clean -n flag (削除)
// var cleanX bool // clean -x flag (削除)

func init() {
	// break init cycle
	cmdClean.Run = runClean

	cmdClean.Flag.BoolVar(&cleanI, "i", false, "")
	cmdClean.Flag.BoolVar(&cleanR, "r", false, "")
	// -n and -x are important enough to be
	// mentioned explicitly in the docs but they
	// are part of the build flags.
	addBuildFlags(cmdClean) // ここで共通ビルドフラグを追加
}

func clean(p *Package) {
	if buildN || buildX { // 共通の buildN, buildX を参照
		// ...
	}
	// ...
}

この変更により、cleanNcleanX は不要となり、addBuildFlags によって登録される共通の buildNbuildX 変数が使用されるようになりました。これにより、go clean-tags-compiler といった他のビルドフラグも自動的に受け入れるようになります。特に clean -i が代替コンパイラでビルドされたターゲットをクリーンアップする際に -compiler フラグを適切に利用できるようになる点が重要です。

src/cmd/go/list.go の変更: go list コマンドも同様に、これまで -compiler, -tags, -race フラグを個別に管理していました。

変更前:

func init() {
	cmdList.Run = runList // break init cycle
	cmdList.Flag.Var(buildCompiler{}, "compiler", "")
	cmdList.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
}

var listRace = cmdList.Flag.Bool("race", false, "")

func runList(cmd *Command, args []string) {
	// ...
	if *listRace {
		buildRace = true
	}
	// ...
}

変更後:

func init() {
	cmdList.Run = runList // break init cycle
	// cmdList.Flag.Var(buildCompiler{}, "compiler", "") (削除)
	// cmdList.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "") (削除)
	addBuildFlags(cmdList) // ここで共通ビルドフラグを追加
}

// var listRace = cmdList.Flag.Bool("race", false, "") (削除)

func runList(cmd *Command, args []string) {
	// ...
	// if *listRace { buildRace = true } (削除)
	// buildRace は addBuildFlags によって適切に設定される
	// ...
}

この変更により、go listaddBuildFlags を通じて共通のビルドフラグセットを継承し、個別のフラグ定義やそれに基づくロジックが不要になりました。これにより、go list のコードが簡素化され、他のGoコマンドとの一貫性が向上しました。

これらの変更は、Goコマンドラインツールの設計原則である「シンプルさ」と「一貫性」を追求したものであり、将来的な機能拡張や保守を容易にする基盤を築いています。

関連リンク

参考にした情報源リンク

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

このコミットは、Goコマンドラインツールにおけるビルドフラグの扱いを統一することを目的としています。特に、`go clean` および `go list` コマンドが、他のビルド関連コマンド(`go build`, `go install`, `go run`, `go test`)と同様に共通のビルドフラグを受け入れるように変更されました。これにより、Goツールのコマンドラインインターフェースの一貫性が向上し、ユーザーエクスペリエンスが改善されています。

## コミット

commit 0f52fdbf7ba599702643660b46ce94f4925856b0 Author: Russ Cox rsc@golang.org Date: Fri May 9 16:32:38 2014 -0400

cmd/go: accept build flags in clean and list

list has been adding them one at a time haphazardly
(race and tags were there and documented; compiler
was there and undocumented).

clean -i needs -compiler in order to clean the
installed targets for alternate compilers.

Fixes #7302.

While we're here, tweak the language in the 'go get' docs
about build flags.

Fixes #7807.

LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews
https://golang.org/cl/99130043

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

[https://github.com/golang/go/commit/0f52fdbf7ba599702643660b46ce94f4925856b0](https://github.com/golang/go/commit/0f52fdbf7ba599702643660b46ce94f4925856b0)

## 元コミット内容

`cmd/go: accept build flags in clean and list`

`list` コマンドはこれまで、ビルドフラグを場当たり的に追加していました(`-race` と `-tags` は文書化されていましたが、`-compiler` は文書化されていませんでした)。

`clean -i` は、代替コンパイラ用にインストールされたターゲットをクリーンアップするために `-compiler` を必要とします。

Issue #7302 を修正します。

ついでに、`go get` のドキュメントにおけるビルドフラグに関する記述を修正します。

Issue #7807 を修正します。

## 変更の背景

この変更の背景には、Goコマンドラインツールの一貫性と使いやすさの向上が挙げられます。

1.  **ビルドフラグの一貫性の欠如**: 以前は、`go build`、`go install`、`go run`、`go test` といった主要なビルド関連コマンドは共通のビルドフラグ(例: `-a`, `-n`, `-x`, `-tags`, `-race`, `-compiler` など)をサポートしていましたが、`go clean` や `go list` といった他のコマンドでは、これらのフラグのサポートが不完全であったり、場当たり的に実装されていたりしました。特に `go list` では、`-race` や `-tags` はサポートされていましたが、`-compiler` はサポートされておらず、その挙動も一貫していませんでした。
2.  **`go clean -i` の機能不足**: `go clean -i` は、インストールされたパッケージのクリーンアップを行うためのフラグですが、代替コンパイラ(例えば、クロスコンパイル環境など)でビルドされたターゲットを正確にクリーンアップするためには、どのコンパイラが使用されたかを指定する `-compiler` フラグの情報が必要でした。しかし、`go clean` コマンドがこのフラグを適切に受け入れないため、このシナリオでのクリーンアップが困難でした。
3.  **ドキュメントの不正確さ**: `go get` コマンドのドキュメントには、ビルドフラグに関する記述がありましたが、その表現が曖昧であったり、最新の挙動を反映していなかったりする部分がありました。
4.  **Issue #7302 と #7807 の解決**: このコミットは、具体的にGoのIssueトラッカーで報告されていた2つの問題、#7302 と #7807 を修正することを目的としています。これらのIssueは、ビルドフラグの不整合やドキュメントの不備に関連するものでした。

これらの問題を解決することで、Go開発者はより予測可能で一貫性のある方法でGoツールを使用できるようになり、特に複雑なビルド環境やクリーンアップ作業において、その利便性が向上しました。

## 前提知識の解説

このコミットを理解するためには、以下のGoコマンドラインツールの概念とフラグに関する知識が役立ちます。

1.  **Goコマンドラインツール**: Go言語には、ソースコードのビルド、テスト、依存関係の管理などを行うための強力なコマンドラインツールセットが付属しています。主要なコマンドには `go build`, `go install`, `go run`, `go test`, `go get`, `go clean`, `go list` などがあります。
2.  **ビルドフラグ (Build Flags)**: これらのコマンドの多くは、ビルドプロセスやその他の操作の挙動を制御するための「ビルドフラグ」を受け入れます。これらは通常、`go help build` コマンドで確認できる共通のフラグ群です。
    *   **`-a`**: 既に最新であるパッケージであっても、強制的に再ビルドします。
    *   **`-n`**: コマンドを実行せずに、実行されるコマンドを表示します(ドライラン)。
    *   **`-x`**: 実行されるコマンドを表示し、実際に実行します(詳細なトレース)。
    *   **`-tags 'tag list'`**: ビルドタグを指定します。これにより、特定のビルドタグが有効な場合にのみコンパイルされるコードブロック(`// +build tag` ディレクティブで指定)を制御できます。例えば、`go build -tags 'debug'` とすると、`debug` タグが有効になります。
    *   **`-race`**: 競合検出器を有効にしてビルドします。これにより、並行処理におけるデータ競合の検出が可能になります。
    *   **`-compiler name`**: 使用するコンパイラを指定します。通常は `gc` (Goコンパイラ) ですが、`gccgo` などの代替コンパイラを使用する場合に指定します。
3.  **`go clean` コマンド**: Goプロジェクトのビルドによって生成されたオブジェクトファイルやキャッシュファイルを削除し、クリーンな状態に戻すためのコマンドです。
    *   **`-i`**: インストールされたパッケージのアーカイブファイルも削除します。
    *   **`-r`**: 依存関係にあるパッケージのオブジェクトファイルも再帰的に削除します。
4.  **`go list` コマンド**: 指定されたパッケージに関する情報を表示するコマンドです。パッケージのインポートパス、依存関係、ビルド情報などをJSON形式やカスタムフォーマットで出力できます。
5.  **`go get` コマンド**: リモートリポジトリからGoパッケージをダウンロードし、インストールするためのコマンドです。依存関係の解決にも使用されます。
6.  **`go help build`**: Goコマンドラインツールにおけるビルドフラグに関する詳細な説明を表示するコマンドです。このコマンドは、共通のビルドフラグとその意味を理解するための主要な情報源となります。
7.  **Issueトラッカー (Issue Tracker)**: Goプロジェクトでは、バグ報告や機能要望を管理するためにIssueトラッカー(GitHub Issuesなど)を使用しています。コミットメッセージに `Fixes #XXXX` とある場合、それはそのコミットが特定のIssueを解決したことを意味します。

これらの概念を理解することで、このコミットがGoツールのどの部分に影響を与え、どのような問題を解決しようとしているのかを深く把握することができます。

## 技術的詳細

このコミットの技術的な核心は、Goコマンドラインツールにおけるビルドフラグの処理ロジックを中央集権化し、再利用性を高めることにあります。具体的には、以下の点が変更されています。

1.  **`addBuildFlags` 関数の適用範囲の拡大**:
    *   `src/cmd/go/build.go` に定義されている `addBuildFlags` 関数は、元々 `go build` および `go install` コマンドに共通のビルドフラグを追加するために使用されていました。
    *   このコミットでは、この関数のコメントと内部ロジックが更新され、`go clean`, `go get`, `go list`, `go run`, `go test` コマンドもこの共通のビルドフラグセットを利用するように変更されました。これにより、各コマンドが個別にビルドフラグを定義・解析する必要がなくなり、コードの重複が削減され、一貫性が保証されます。

2.  **`go clean` コマンドのフラグ処理の統合**:
    *   以前の `go clean` コマンドは、`-n` (ドライラン) や `-x` (コマンド表示) といったフラグを独自に定義し、`cleanN` や `cleanX` といった専用の変数で管理していました。
    *   このコミットでは、これらのフラグの定義が `go clean` の `init` 関数から削除され、代わりに `addBuildFlags(cmdClean)` が呼び出されるようになりました。これにより、`cleanN` や `cleanX` の代わりに、共通のビルドフラグ変数である `buildN` や `buildX` が使用されるようになります。
    *   `clean` 関数内のロジックも、`cleanN || cleanX` から `buildN || buildX` へと変更され、共通のビルドフラグ変数に依存するようになりました。
    *   これにより、`go clean` は `-tags` や `-compiler` といった他のビルドフラグも透過的に受け入れ、特に `clean -i` が代替コンパイラでビルドされたターゲットをクリーンアップする際に `-compiler` フラグを適切に利用できるようになります。

3.  **`go list` コマンドのフラグ処理の統合と簡素化**:
    *   `go list` コマンドは、これまで `-race`, `-tags`, `-compiler` といったビルド関連のフラグを個別に定義していました。特に `-compiler` は文書化されていませんでした。
    *   このコミットでは、`cmdList.Flag.Var` を用いたこれらのフラグの個別定義が削除され、`addBuildFlags(cmdList)` が呼び出されるようになりました。
    *   これにより、`go list` は共通のビルドフラグセットを継承し、`-race` フラグの処理ロジック(`if *listRace { buildRace = true }`)も不要になりました。これは、`buildRace` が既に共通のビルドコンテキストの一部として管理されるためです。

4.  **ドキュメントの更新**:
    *   `src/cmd/go/doc.go` および `src/cmd/go/get.go`、`src/cmd/go/list.go` のドキュメントが更新され、`go clean`, `go list`, `go get` コマンドがビルドフラグを受け入れること、そしてビルドフラグの詳細については `go help build` を参照するように明記されました。これにより、ユーザーは一貫したドキュメントを参照できるようになります。

これらの変更により、Goコマンドラインツールの内部構造はよりモジュール化され、保守性が向上しました。また、ユーザーにとっては、どのGoコマンドでも同じビルドフラグが期待通りに機能するという、より予測可能なインターフェースが提供されることになります。

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

このコミットにおける主要なコード変更は、以下のファイルに集中しています。

1.  **`src/cmd/go/build.go`**:
    *   `addBuildFlags` 関数のコメントが更新され、この関数が `build`, `clean`, `get`, `install`, `list`, `run`, `test` の各コマンドに共通のビルドフラグを追加することが明記されました。

2.  **`src/cmd/go/clean.go`**:
    *   `cmdClean` の `UsageLine` が `clean [-i] [-r] [-n] [-x] [packages]` から `clean [-i] [-r] [-n] [-x] [build flags] [packages]` に変更され、ビルドフラグを受け入れることが示されました。
    *   `cleanN`, `cleanX` といった個別のフラグ変数の宣言が削除されました。
    *   `init` 関数内で `addBuildFlags(cmdClean)` が呼び出されるようになりました。
    *   `clean` 関数内のフラグ参照が `cleanN` や `cleanX` から `buildN` や `buildX` に変更されました。

3.  **`src/cmd/go/doc.go`**:
    *   `go build`, `go clean`, `go list` の `Usage` セクションが更新され、ビルドフラグの受け入れが反映されました。
    *   特に `go list` の説明から、`-tags` と `-race` フラグに関する具体的な記述が削除され、代わりに「ビルドフラグの詳細については `go help build` を参照してください」という一般的な記述に置き換えられました。

4.  **`src/cmd/go/get.go`**:
    *   `go get` コマンドのドキュメントにおいて、ビルドフラグに関する記述が簡素化され、「`go help build` を参照してください」という指示に統一されました。

5.  **`src/cmd/go/list.go`**:
    *   `cmdList` の `UsageLine` が `list [-e] [-race] [-f format] [-json] [-tags 'tag list'] [packages]` から `list [-e] [-f format] [-json] [build flags] [packages]` に変更され、ビルドフラグを受け入れることが示されました。
    *   `cmdList.Flag.Var` を用いた `compiler`, `tags` の個別フラグ定義が削除されました。
    *   `init` 関数内で `addBuildFlags(cmdList)` が呼び出されるようになりました。
    *   `listRace` 変数と、それに基づいて `buildRace` を設定するロジックが削除されました。

これらの変更は、Goコマンドラインツールのフラグ処理ロジックを中央集権化し、一貫性を高めるためのものです。

## コアとなるコードの解説

このコミットのコアとなる変更は、Goコマンドラインツールにおけるビルドフラグの処理を共通化する `addBuildFlags` 関数の利用拡大と、それに伴う各コマンドのフラグ処理ロジックの簡素化です。

**`src/cmd/go/build.go` の変更**:
このファイルでは、`addBuildFlags` 関数の役割が明確化されています。以前は `build` と `install` コマンドに共通のフラグを追加するものでしたが、このコミットにより、`clean`, `get`, `list`, `run`, `test` コマンドも対象となることがコメントで明記されました。これは、この関数がGoコマンドラインツール全体のビルドフラグ管理の中心となることを示しています。

```go
// addBuildFlags adds the flags common to the build, clean, get,
// install, list, run, and test commands.
func addBuildFlags(cmd *Command) {
	// NOTE: If you add flags here, also add them to testflag.go.
	cmd.Flag.BoolVar(&buildA, "a", false, "")
	// ... (他の共通ビルドフラグの定義)
}

この関数は、*Command 型の引数 cmd を受け取り、その Flag フィールド(flag.FlagSet のインスタンス)に共通のビルドフラグ(-a, -n, -x, -tags, -race, -compiler など)を登録します。これにより、各コマンドは自身の init 関数内で addBuildFlags(cmdX) を呼び出すだけで、これらの共通フラグを自動的にサポートできるようになります。

src/cmd/go/clean.go の変更: go clean コマンドは、これまで -n-x フラグを独自に管理していました。

変更前:

var cleanN bool // clean -n flag
var cleanX bool // clean -x flag

func init() {
	// ...
	cmdClean.Flag.BoolVar(&cleanN, "n", false, "")
	cmdClean.Flag.BoolVar(&cleanX, "x", false, "")
}

func clean(p *Package) {
	if cleanN || cleanX {
		// ...
	}
	// ...
}

変更後:

// var cleanN bool // clean -n flag (削除)
// var cleanX bool // clean -x flag (削除)

func init() {
	// break init cycle
	cmdClean.Run = runClean

	cmdClean.Flag.BoolVar(&cleanI, "i", false, "")
	cmdClean.Flag.BoolVar(&cleanR, "r", false, "")
	// -n and -x are important enough to be
	// mentioned explicitly in the docs but they
	// are part of the build flags.
	addBuildFlags(cmdClean) // ここで共通ビルドフラグを追加
}

func clean(p *Package) {
	if buildN || buildX { // 共通の buildN, buildX を参照
		// ...
	}
	// ...
}

この変更により、cleanNcleanX は不要となり、addBuildFlags によって登録される共通の buildNbuildX 変数が使用されるようになりました。これにより、go clean-tags-compiler といった他のビルドフラグも自動的に受け入れるようになります。特に clean -i が代替コンパイラでビルドされたターゲットをクリーンアップする際に -compiler フラグを適切に利用できるようになる点が重要です。

src/cmd/go/list.go の変更: go list コマンドも同様に、これまで -compiler, -tags, -race フラグを個別に管理していました。

変更前:

func init() {
	cmdList.Run = runList // break init cycle
	cmdList.Flag.Var(buildCompiler{}, "compiler", "")
	cmdList.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
}

var listRace = cmdList.Flag.Bool("race", false, "")

func runList(cmd *Command, args []string) {
	// ...
	if *listRace {
		buildRace = true
	}
	// ...
}

変更後:

func init() {
	cmdList.Run = runList // break init cycle
	// cmdList.Flag.Var(buildCompiler{}, "compiler", "") (削除)
	// cmdList.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "") (削除)
	addBuildFlags(cmdList) // ここで共通ビルドフラグを追加
}

// var listRace = cmdList.Flag.Bool("race", false, "") (削除)

func runList(cmd *Command, args []string) {
	// ...
	// if *listRace { buildRace = true } (削除)
	// buildRace は addBuildFlags によって適切に設定される
	// ...
}

この変更により、go listaddBuildFlags を通じて共通のビルドフラグセットを継承し、個別のフラグ定義やそれに基づくロジックが不要になりました。これにより、go list のコードが簡素化され、他のGoコマンドとの一貫性が向上しました。

これらの変更は、Goコマンドラインツールの設計原則である「シンプルさ」と「一貫性」を追求したものであり、将来的な機能拡張や保守を容易にする基盤を築いています。

関連リンク

参考にした情報源リンク

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

このコミットは、Goコマンドラインツールにおけるビルドフラグの扱いを統一することを目的としています。特に、`go clean` および `go list` コマンドが、他のビルド関連コマンド(`go build`, `go install`, `go run`, `go test`)と同様に共通のビルドフラグを受け入れるように変更されました。これにより、Goツールのコマンドラインインターフェースの一貫性が向上し、ユーザーエクスペリエンスが改善されています。

## コミット

commit 0f52fdbf7ba599702643660b46ce94f4925856b0 Author: Russ Cox rsc@golang.org Date: Fri May 9 16:32:38 2014 -0400

cmd/go: accept build flags in clean and list

list has been adding them one at a time haphazardly
(race and tags were there and documented; compiler
was there and undocumented).

clean -i needs -compiler in order to clean the
installed targets for alternate compilers.

Fixes #7302.

While we're here, tweak the language in the 'go get' docs
about build flags.

Fixes #7807.

LGTM=iant
R=golang-codereviews, iant
CC=golang-codereviews
https://golang.org/cl/99130043

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

[https://github.com/golang/go/commit/0f52fdbf7ba599702643660b46ce94f4925856b0](https://github.com/golang/go/commit/0f52fdbf7ba599702643660b46ce94f4925856b0)

## 元コミット内容

`cmd/go: accept build flags in clean and list`

`list` コマンドはこれまで、ビルドフラグを場当たり的に追加していました(`-race` と `-tags` は文書化されていましたが、`-compiler` は文書化されていませんでした)。

`clean -i` は、代替コンパイラ用にインストールされたターゲットをクリーンアップするために `-compiler` を必要とします。

Issue #7302 を修正します。

ついでに、`go get` のドキュメントにおけるビルドフラグに関する記述を修正します。

Issue #7807 を修正します。

## 変更の背景

この変更の背景には、Goコマンドラインツールの一貫性と使いやすさの向上が挙げられます。

1.  **ビルドフラグの一貫性の欠如**: 以前は、`go build`、`go install`、`go run`、`go test` といった主要なビルド関連コマンドは共通のビルドフラグ(例: `-a`, `-n`, `-x`, `-tags`, `-race`, `-compiler` など)をサポートしていましたが、`go clean` や `go list` といった他のコマンドでは、これらのフラグのサポートが不完全であったり、場当たり的に実装されていたりしました。特に `go list` では、`-race` や `-tags` はサポートされていましたが、`-compiler` はサポートされておらず、その挙動も一貫していませんでした。
2.  **`go clean -i` の機能不足**: `go clean -i` は、インストールされたパッケージのクリーンアップを行うためのフラグですが、代替コンパイラ(例えば、クロスコンパイル環境など)でビルドされたターゲットを正確にクリーンアップするためには、どのコンパイラが使用されたかを指定する `-compiler` フラグの情報が必要でした。しかし、`go clean` コマンドがこのフラグを適切に受け入れないため、このシナリオでのクリーンアップが困難でした。
3.  **ドキュメントの不正確さ**: `go get` コマンドのドキュメントには、ビルドフラグに関する記述がありましたが、その表現が曖昧であったり、最新の挙動を反映していなかったりする部分がありました。
4.  **Issue #7302 と #7807 の解決**: このコミットは、具体的にGoのIssueトラッカーで報告されていた2つの問題、#7302 と #7807 を修正することを目的としています。これらのIssueは、ビルドフラグの不整合やドキュメントの不備に関連するものでした。

これらの問題を解決することで、Go開発者はより予測可能で一貫性のある方法でGoツールを使用できるようになり、特に複雑なビルド環境やクリーンアップ作業において、その利便性が向上します。

## 前提知識の解説

このコミットを理解するためには、以下のGoコマンドラインツールの概念とフラグに関する知識が役立ちます。

1.  **Goコマンドラインツール**: Go言語には、ソースコードのビルド、テスト、依存関係の管理などを行うための強力なコマンドラインツールセットが付属しています。主要なコマンドには `go build`, `go install`, `go run`, `go test`, `go get`, `go clean`, `go list` などがあります。
2.  **ビルドフラグ (Build Flags)**: これらのコマンドの多くは、ビルドプロセスやその他の操作の挙動を制御するための「ビルドフラグ」を受け入れます。これらは通常、`go help build` コマンドで確認できる共通のフラグ群です。
    *   **`-a`**: 既に最新であるパッケージであっても、強制的に再ビルドします。
    *   **`-n`**: コマンドを実行せずに、実行されるコマンドを表示します(ドライラン)。
    *   **`-x`**: 実行されるコマンドを表示し、実際に実行します(詳細なトレース)。
    *   **`-tags 'tag list'`**: ビルドタグを指定します。これにより、特定のビルドタグが有効な場合にのみコンパイルされるコードブロック(`// +build tag` ディレクティブで指定)を制御できます。例えば、`go build -tags 'debug'` とすると、`debug` タグが有効になります。
    *   **`-race`**: 競合検出器を有効にしてビルドします。これにより、並行処理におけるデータ競合の検出が可能になります。
    *   **`-compiler name`**: 使用するコンパイラを指定します。通常は `gc` (Goコンパイラ) ですが、`gccgo` などの代替コンパイラを使用する場合に指定します。
3.  **`go clean` コマンド**: Goプロジェクトのビルドによって生成されたオブジェクトファイルやキャッシュファイルを削除し、クリーンな状態に戻すためのコマンドです。
    *   **`-i`**: インストールされたパッケージのアーカイブファイルも削除します。
    *   **`-r`**: 依存関係にあるパッケージのオブジェクトファイルも再帰的に削除します。
4.  **`go list` コマンド**: 指定されたパッケージに関する情報を表示するコマンドです。パッケージのインポートパス、依存関係、ビルド情報などをJSON形式やカスタムフォーマットで出力できます。
5.  **`go get` コマンド**: リモートリポジトリからGoパッケージをダウンロードし、インストールするためのコマンドです。依存関係の解決にも使用されます。
6.  **`go help build`**: Goコマンドラインツールにおけるビルドフラグに関する詳細な説明を表示するコマンドです。このコマンドは、共通のビルドフラグとその意味を理解するための主要な情報源となります。
7.  **Issueトラッカー (Issue Tracker)**: Goプロジェクトでは、バグ報告や機能要望を管理するためにIssueトラッカー(GitHub Issuesなど)を使用しています。コミットメッセージに `Fixes #XXXX` とある場合、それはそのコミットが特定のIssueを解決したことを意味します。

これらの概念を理解することで、このコミットがGoツールのどの部分に影響を与え、どのような問題を解決しようとしているのかを深く把握することができます。

## 技術的詳細

このコミットの技術的な核心は、Goコマンドラインツールにおけるビルドフラグの処理ロジックを中央集権化し、再利用性を高めることにあります。具体的には、以下の点が変更されています。

1.  **`addBuildFlags` 関数の適用範囲の拡大**:
    *   `src/cmd/go/build.go` に定義されている `addBuildFlags` 関数は、元々 `go build` および `go install` コマンドに共通のビルドフラグを追加するために使用されていました。
    *   このコミットでは、この関数のコメントと内部ロジックが更新され、`go clean`, `go get`, `go list`, `go run`, `go test` コマンドもこの共通のビルドフラグセットを利用するように変更されました。これにより、各コマンドが個別にビルドフラグを定義・解析する必要がなくなり、コードの重複が削減され、一貫性が保証されます。

2.  **`go clean` コマンドのフラグ処理の統合**:
    *   以前の `go clean` コマンドは、`-n` (ドライラン) や `-x` (コマンド表示) といったフラグを独自に定義し、`cleanN` や `cleanX` といった専用の変数で管理していました。
    *   このコミットでは、これらのフラグの定義が `go clean` の `init` 関数から削除され、代わりに `addBuildFlags(cmdClean)` が呼び出されるようになりました。これにより、`cleanN` や `cleanX` の代わりに、共通のビルドフラグ変数である `buildN` や `buildX` が使用されるようになります。
    *   `clean` 関数内のロジックも、`cleanN || cleanX` から `buildN || buildX` へと変更され、共通のビルドフラグ変数に依存するようになりました。
    *   これにより、`go clean` は `-tags` や `-compiler` といった他のビルドフラグも透過的に受け入れ、特に `clean -i` が代替コンパイラでビルドされたターゲットをクリーンアップする際に `-compiler` フラグを適切に利用できるようになります。

3.  **`go list` コマンドのフラグ処理の統合と簡素化**:
    *   `go list` コマンドは、これまで `-race`, `-tags`, `-compiler` といったビルド関連のフラグを個別に定義していました。特に `-compiler` は文書化されていませんでした。
    *   このコミットでは、`cmdList.Flag.Var` を用いたこれらのフラグの個別定義が削除され、代わりに `addBuildFlags(cmdList)` が呼び出されるようになりました。
    *   これにより、`go list` は共通のビルドフラグセットを継承し、`-race` フラグの処理ロジック(`if *listRace { buildRace = true }`)も不要になりました。これは、`buildRace` が既に共通のビルドコンテキストの一部として管理されるためです。

4.  **ドキュメントの更新**:
    *   `src/cmd/go/doc.go` および `src/cmd/go/get.go`、`src/cmd/go/list.go` のドキュメントが更新され、`go clean`, `go list`, `go get` コマンドがビルドフラグを受け入れること、そしてビルドフラグの詳細については `go help build` を参照するように明記されました。これにより、ユーザーは一貫したドキュメントを参照できるようになります。

これらの変更により、Goコマンドラインツールの内部構造はよりモジュール化され、保守性が向上しました。また、ユーザーにとっては、どのGoコマンドでも同じビルドフラグが期待通りに機能するという、より予測可能なインターフェースが提供されることになります。

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

このコミットにおける主要なコード変更は、以下のファイルに集中しています。

1.  **`src/cmd/go/build.go`**:
    *   `addBuildFlags` 関数のコメントが更新され、この関数が `build`, `clean`, `get`, `install`, `list`, `run`, `test` の各コマンドに共通のビルドフラグを追加することが明記されました。

2.  **`src/cmd/go/clean.go`**:
    *   `cmdClean` の `UsageLine` が `clean [-i] [-r] [-n] [-x] [packages]` から `clean [-i] [-r] [-n] [-x] [build flags] [packages]` に変更され、ビルドフラグを受け入れることが示されました。
    *   `cleanN`, `cleanX` といった個別のフラグ変数の宣言が削除されました。
    *   `init` 関数内で `addBuildFlags(cmdClean)` が呼び出されるようになりました。
    *   `clean` 関数内のフラグ参照が `cleanN` や `cleanX` から `buildN` や `buildX` に変更されました。

3.  **`src/cmd/go/doc.go`**:
    *   `go build`, `go clean`, `go list` の `Usage` セクションが更新され、ビルドフラグの受け入れが反映されました。
    *   特に `go list` の説明から、`-tags` と `-race` フラグに関する具体的な記述が削除され、代わりに「ビルドフラグの詳細については `go help build` を参照してください」という一般的な記述に置き換えられました。

4.  **`src/cmd/go/get.go`**:
    *   `go get` コマンドのドキュメントにおいて、ビルドフラグに関する記述が簡素化され、「`go help build` を参照してください」という指示に統一されました。

5.  **`src/cmd/go/list.go`**:
    *   `cmdList` の `UsageLine` が `list [-e] [-race] [-f format] [-json] [-tags 'tag list'] [packages]` から `list [-e] [-f format] [-json] [build flags] [packages]` に変更され、ビルドフラグを受け入れることが示されました。
    *   `cmdList.Flag.Var` を用いた `compiler`, `tags` の個別フラグ定義が削除されました。
    *   `init` 関数内で `addBuildFlags(cmdList)` が呼び出されるようになりました。
    *   `listRace` 変数と、それに基づいて `buildRace` を設定するロジックが削除されました。

これらの変更は、Goコマンドラインツールのフラグ処理ロジックを中央集権化し、一貫性を高めるためのものです。

## コアとなるコードの解説

このコミットのコアとなる変更は、Goコマンドラインツールにおけるビルドフラグの処理を共通化する `addBuildFlags` 関数の利用拡大と、それに伴う各コマンドのフラグ処理ロジックの簡素化です。

**`src/cmd/go/build.go` の変更**:
このファイルでは、`addBuildFlags` 関数の役割が明確化されています。以前は `build` と `install` コマンドに共通のフラグを追加するものでしたが、このコミットにより、`clean`, `get`, `list`, `run`, `test` コマンドも対象となることがコメントで明記されました。これは、この関数がGoコマンドラインツール全体のビルドフラグ管理の中心となることを示しています。

```go
// addBuildFlags adds the flags common to the build, clean, get,
// install, list, run, and test commands.
func addBuildFlags(cmd *Command) {
	// NOTE: If you add flags here, also add them to testflag.go.
	cmd.Flag.BoolVar(&buildA, "a", false, "")
	// ... (他の共通ビルドフラグの定義)
}

この関数は、*Command 型の引数 cmd を受け取り、その Flag フィールド(flag.FlagSet のインスタンス)に共通のビルドフラグ(-a, -n, -x, -tags, -race, -compiler など)を登録します。これにより、各コマンドは自身の init 関数内で addBuildFlags(cmdX) を呼び出すだけで、これらの共通フラグを自動的にサポートできるようになります。

src/cmd/go/clean.go の変更: go clean コマンドは、これまで -n-x フラグを独自に管理していました。

変更前:

var cleanN bool // clean -n flag
var cleanX bool // clean -x flag

func init() {
	// ...
	cmdClean.Flag.BoolVar(&cleanN, "n", false, "")
	cmdClean.Flag.BoolVar(&cleanX, "x", false, "")
}

func clean(p *Package) {
	if cleanN || cleanX {
		// ...
	}
	// ...
}

変更後:

// var cleanN bool // clean -n flag (削除)
// var cleanX bool // clean -x flag (削除)

func init() {
	// break init cycle
	cmdClean.Run = runClean

	cmdClean.Flag.BoolVar(&cleanI, "i", false, "")
	cmdClean.Flag.BoolVar(&cleanR, "r", false, "")
	// -n and -x are important enough to be
	// mentioned explicitly in the docs but they
	// are part of the build flags.
	addBuildFlags(cmdClean) // ここで共通ビルドフラグを追加
}

func clean(p *Package) {
	if buildN || buildX { // 共通の buildN, buildX を参照
		// ...
	}
	// ...
}

この変更により、cleanNcleanX は不要となり、addBuildFlags によって登録される共通の buildNbuildX 変数が使用されるようになりました。これにより、go clean-tags-compiler といった他のビルドフラグも自動的に受け入れるようになります。特に clean -i が代替コンパイラでビルドされたターゲットをクリーンアップする際に -compiler フラグを適切に利用できるようになる点が重要です。

src/cmd/go/list.go の変更: go list コマンドも同様に、これまで -compiler, -tags, -race フラグを個別に管理していました。

変更前:

func init() {
	cmdList.Run = runList // break init cycle
	cmdList.Flag.Var(buildCompiler{}, "compiler", "")
	cmdList.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
}

var listRace = cmdList.Flag.Bool("race", false, "")

func runList(cmd *Command, args []string) {
	// ...
	if *listRace {
		buildRace = true
	}
	// ...
}

変更後:

func init() {
	cmdList.Run = runList // break init cycle
	// cmdList.Flag.Var(buildCompiler{}, "compiler", "") (削除)
	// cmdList.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "") (削除)
	addBuildFlags(cmdList) // ここで共通ビルドフラグを追加
}

// var listRace = cmdList.Flag.Bool("race", false, "") (削除)

func runList(cmd *Command, args []string) {
	// ...
	// if *listRace { buildRace = true } (削除)
	// buildRace は addBuildFlags によって適切に設定される
	// ...
}

この変更により、go listaddBuildFlags を通じて共通のビルドフラグセットを継承し、個別のフラグ定義やそれに基づくロジックが不要になりました。これにより、go list のコードが簡素化され、他のGoコマンドとの一貫性が向上しました。

これらの変更は、Goコマンドラインツールの設計原則である「シンプルさ」と「一貫性」を追求したものであり、将来的な機能拡張や保守を容易にする基盤を築いています。

関連リンク

参考にした情報源リンク