[インデックス 19070] ファイルの概要
このコミットは、go list -f
コマンドのテンプレート機能に、ビルドコンテキスト情報 (go/build.Context
の値) を利用できるようにする変更を導入しています。これにより、ユーザーは go list -f
の出力テンプレート内で、ターゲットアーキテクチャ (GOARCH
) やビルドタグ (BuildTags
) といったビルド環境に関する情報にアクセスできるようになります。
コミット
- コミットハッシュ:
b3a33a654d2f640f3b6c7856ea742c23f6c49d1c
- Author: Rick Arnold rickarnoldjr@gmail.com
- Date: Tue Apr 8 22:35:29 2014 -0400
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/b3a33a654d2f640f3b6c7856ea742c23f6c49d1c
元コミット内容
cmd/go: allow use of Context in 'go list -f'
Add a $Context variable to the template so that the build.Context values
such as BuildTags can be accessed.
Fixes #6666.
LGTM=adg, rsc
R=golang-codereviews, gobot, adg, rsc
CC=golang-codereviews
https://golang.org/cl/72770043
変更の背景
go list
コマンドは、Goパッケージに関する情報を表示するための強力なツールです。特に -f
フラグを使用すると、Goの text/template
パッケージの構文を用いて、出力形式を自由にカスタマイズできます。しかし、これまでの go list -f
のテンプレートでは、各パッケージのメタデータ(インポートパス、ディレクトリ、ファイルリストなど)にはアクセスできましたが、Goのビルド環境に関する情報(例えば、現在のターゲットOSやアーキテクチャ、有効なビルドタグなど)には直接アクセスできませんでした。
この制限は、特定のビルド環境に依存する情報を go list
の出力に含めたい場合に問題となります。例えば、特定のビルドタグが有効な場合にのみ表示されるパッケージを識別したり、異なるOSやアーキテクチャ向けにビルドされた場合のパッケージの挙動をシミュレートしたりする際に、ビルドコンテキスト情報へのアクセスが必要となります。
このコミットは、このギャップを埋めるために、go list -f
のテンプレート内で build.Context
の値にアクセスできる $Context
変数を導入しました。これにより、ユーザーはより柔軟で情報豊富な go list
の出力を生成できるようになります。コミットメッセージにある Fixes #6666
は、この機能追加の必要性を示唆する既存の課題があったことを意味しています。
前提知識の解説
go list
コマンドと -f
フラグ
go list
は、Goのワークスペース内のパッケージに関する情報を表示するコマンドです。例えば、go list all
はすべてのパッケージのインポートパスを表示します。
-f
フラグは、出力形式をカスタマイズするために使用されます。このフラグに続く文字列は、Goの text/template
パッケージの構文として解釈されます。テンプレートには、各パッケージの Package
構造体の情報が渡されます。
例: go list -f '{{.ImportPath}} {{.Dir}}'
は、各パッケージのインポートパスとディレクトリを表示します。
Goの text/template
パッケージ
text/template
パッケージは、Go言語に組み込まれているテキストテンプレートエンジンです。プレースホルダー({{.Field}}
)や制御構造({{if .Condition}}...{{end}}
、{{range .Slice}}...{{end}}
)を使用して、動的にテキストを生成できます。また、カスタム関数を登録してテンプレート内で利用することも可能です。
go/build.Context
構造体
go/build
パッケージは、Goのビルドプロセスに関する情報を提供します。その中の Context
構造体は、Goのビルド環境に関する様々な設定をカプセル化しています。これには以下のようなフィールドが含まれます。
GOARCH
: ターゲットアーキテクチャ (例:amd64
,arm
)GOOS
: ターゲットオペレーティングシステム (例:linux
,windows
,darwin
)GOROOT
: GoのインストールルートディレクトリGOPATH
: GoのワークスペースパスCgoEnabled
: cgoが有効かどうかBuildTags
: ビルド制約 (+build
ディレクティブ) にマッチするビルドタグのリストReleaseTags
: 現在のリリースと互換性のあるリリースを示すタグのリスト
これらの情報は、Goがソースファイルをどのようにコンパイルし、どのファイルを含めるかを決定する際に使用されます。
技術的詳細
このコミットの主要な目的は、go list -f
のテンプレート内で go/build.Context
の情報にアクセスできるようにすることです。これを実現するために、以下の技術的な変更が加えられました。
-
Context
構造体の定義とnewContext
関数の追加 (src/cmd/go/context.go
):cmd/go
パッケージ内に、go/build.Context
の主要なフィールドをミラーリングする新しいContext
構造体が定義されました。この構造体は、JSONシリアライズ可能 (json:",omitempty"
) に設定されており、将来的にgo list -json
の出力にも含めることができるように設計されています。 また、go/build.Context
のインスタンスを受け取り、新しく定義されたContext
構造体のインスタンスを生成するnewContext
ヘルパー関数が追加されました。これにより、go/build
パッケージのコンテキスト情報を、テンプレートが利用できる形式に変換します。 -
テンプレート関数
context
の追加 (src/cmd/go/list.go
):go list
コマンドのテンプレート処理ロジック (runList
関数) が変更され、新しいテンプレート関数context
がtemplate.FuncMap
に追加されました。このcontext
関数は、go/build
パッケージのグローバルなビルドコンテキスト (buildContext
) をラップしたContext
構造体のインスタンスを返します。このインスタンスは一度生成されるとキャッシュされ、テンプレート内で複数回context
関数が呼び出されても同じインスタンスが返されるように最適化されています。 -
ドキュメントの更新 (
src/cmd/go/doc.go
):go list -f
のドキュメントが更新され、新しく追加されたcontext
テンプレート関数とその戻り値であるContext
構造体について説明が追加されました。これにより、ユーザーは新しい機能の存在と使い方を理解できます。 -
テストケースの追加 (
src/cmd/go/test.bash
): 新しい機能が正しく動作することを確認するために、go list -f "GOARCH: {{context.GOARCH}}"
を実行し、期待される出力が得られるかを検証するテストケースがtest.bash
スクリプトに追加されました。これは、go list
がビルドコンテキスト情報にアクセスできることを保証します。
これらの変更により、go list -f
のテンプレート内で {{context.GOARCH}}
や {{context.BuildTags}}
のようにビルドコンテキストのフィールドに直接アクセスできるようになり、go list
の機能が大幅に拡張されました。
コアとなるコードの変更箇所
src/cmd/go/context.go
(新規ファイル)
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"go/build"
)
type Context struct {
GOARCH string `json:",omitempty"` // target architecture
GOOS string `json:",omitempty"` // target operating system
GOROOT string `json:",omitempty"` // Go root
GOPATH string `json:",omitempty"` // Go path
CgoEnabled bool `json:",omitempty"` // whether cgo can be used
UseAllFiles bool `json:",omitempty"` // use files regardless of +build lines, file names
Compiler string `json:",omitempty"` // compiler to assume when computing target paths
BuildTags []string `json:",omitempty"` // build constraints to match in +build lines
ReleaseTags []string `json:",omitempty"` // releases the current release is compatible with
InstallSuffix string `json:",omitempty"` // suffix to use in the name of the install dir
}
func newContext(c *build.Context) *Context {
return &Context{
GOARCH: c.GOARCH,
GOOS: c.GOOS,
GOROOT: c.GOROOT,
CgoEnabled: c.CgoEnabled,
UseAllFiles: c.UseAllFiles,
Compiler: c.Compiler,
BuildTags: c.BuildTags,
ReleaseTags: c.ReleaseTags,
InstallSuffix: c.InstallSuffix,
}
}
src/cmd/go/doc.go
(変更箇所)
--- a/src/cmd/go/doc.go
+++ b/src/cmd/go/doc.go
@@ -283,8 +283,7 @@ The default output shows the package import path:
The -f flag specifies an alternate format for the list, using the
syntax of package template. The default output is equivalent to -f
-`{{.ImportPath}}`. One extra template function is available, "join",
-which calls strings.Join. The struct being passed to the template is:
+`{{.ImportPath}}`. The struct being passed to the template is:
type Package struct {
Dir string // directory containing package sources
@@ -332,6 +331,26 @@ which calls strings.Join. The struct being passed to the template is:
XTestImports []string // imports from XTestGoFiles
}
+The template function "join" calls strings.Join.
+
+The template function "context" returns the build context, defined as:
+
+ type Context struct {
+ GOARCH string // target architecture
+ GOOS string // target operating system
+ GOROOT string // Go root
+ GOPATH string // Go path
+ CgoEnabled bool // whether cgo can be used
+ UseAllFiles bool // use files regardless of +build lines, file names
+ Compiler string // compiler to assume when computing target paths
+ BuildTags []string // build constraints to match in +build lines
+ ReleaseTags []string // releases the current release is compatible with
+ InstallSuffix string // suffix to use in the name of the install dir
+ }
+
+For more information about the meaning of these fields see the documentation
+for the go/build package's Context type.
+
The -json flag causes the package data to be printed in JSON format
instead of using the template format.
src/cmd/go/list.go
(変更箇所)
--- a/src/cmd/go/list.go
+++ b/src/cmd/go/list.go
@@ -27,8 +27,7 @@ The default output shows the package import path:
The -f flag specifies an alternate format for the list, using the
syntax of package template. The default output is equivalent to -f
-`{{.ImportPath}}`. One extra template function is available, "join",
-which calls strings.Join. The struct being passed to the template is:
+`{{.ImportPath}}`. The struct being passed to the template is:
type Package struct {
Dir string // directory containing package sources
@@ -76,6 +75,26 @@ which calls strings.Join. The struct being passed to the template is:
XTestImports []string // imports from XTestGoFiles
}
+The template function "join" calls strings.Join.
+
+The template function "context" returns the build context, defined as:
+
+ type Context struct {
+ GOARCH string // target architecture
+ GOOS string // target operating system
+ GOROOT string // Go root
+ GOPATH string // Go path
+ CgoEnabled bool // whether cgo can be used
+ UseAllFiles bool // use files regardless of +build lines, file names
+ Compiler string // compiler to assume when computing target paths
+ BuildTags []string // build constraints to match in +build lines
+ ReleaseTags []string // releases the current release is compatible with
+ InstallSuffix string // suffix to use in the name of the install dir
+ }
+
+For more information about the meaning of these fields see the documentation
+for the go/build package's Context type.
+
The -json flag causes the package data to be printed in JSON format
instead of using the template format.
@@ -131,7 +150,18 @@ func runList(cmd *Command, args []string) {
`out.Write(nl)`
}
} else {
- `tmpl, err := template.New("main").Funcs(template.FuncMap{"join": strings.Join}).Parse(*listFmt)`
+ `var cachedCtxt *Context`
+ `context := func() *Context {`
+ ` if cachedCtxt == nil {`
+ ` cachedCtxt = newContext(&buildContext)`
+ ` }`
+ ` return cachedCtxt`
+ `}`
+ `fm := template.FuncMap{`
+ ` "join": strings.Join,`
+ ` "context": context,`
+ `}`
+ `tmpl, err := template.New("main").Funcs(fm).Parse(*listFmt)`
`if err != nil {`
` fatalf("%s", err)`
`}`
src/cmd/go/test.bash
(変更箇所)
--- a/src/cmd/go/test.bash
+++ b/src/cmd/go/test.bash
@@ -694,6 +694,12 @@ unset go_cmds
unset ldflags
unset GOPATH
+TEST list template can use context function
+if ! ./testgo list -f "GOARCH: {{context.GOARCH}}"; then
+ echo unable to use context in list template
+ ok=false
+fi
+
# clean up
if $started; then stop; fi
rm -rf testdata/bin testdata/bin1
コアとなるコードの解説
src/cmd/go/context.go
このファイルは、go list -f
テンプレートに公開される Context
型を定義しています。この型は go/build.Context
のサブセットであり、ビルド環境に関する重要な情報(GOARCH
, GOOS
, BuildTags
など)を保持します。newContext
関数は、実際の go/build.Context
インスタンスからこの Context
型のインスタンスを生成するファクトリ関数として機能します。json:",omitempty"
タグは、この構造体がJSONとしてシリアライズされる際に、値が空の場合にフィールドを省略することを示しています。
src/cmd/go/doc.go
この変更は、go list -f
コマンドのヘルプドキュメントを更新しています。特に、context
という新しいテンプレート関数が利用可能になったことと、その関数が返す Context
構造体の定義が追加されています。これにより、ユーザーは go list -f
でビルドコンテキスト情報にアクセスする方法を公式ドキュメントで確認できるようになります。
src/cmd/go/list.go
このファイルは go list
コマンドの主要なロジックを含んでいます。変更の核心は runList
関数内にあります。
以前は template.FuncMap
に join
関数のみが登録されていましたが、このコミットにより context
関数も追加されました。
context
関数はクロージャとして定義されており、cachedCtxt
という変数を使って Context
インスタンスをキャッシュします。これにより、テンプレート内で context
関数が複数回呼び出されても、newContext
が一度だけ実行され、パフォーマンスが向上します。
buildContext
は go/build
パッケージのグローバルなビルドコンテキスト変数であり、現在のGo環境のビルド設定を保持しています。
src/cmd/go/test.bash
このシェルスクリプトは、Goコマンドの統合テストを実行します。追加されたテストケースは、go list -f "GOARCH: {{context.GOARCH}}"
を実行し、その出力が期待通りであるかを確認します。これは、context
テンプレート関数が正しく機能し、GOARCH
の値がテンプレートに渡されることを検証するものです。このテストの成功は、新機能が意図通りに動作していることの保証となります。
関連リンク
- Go issue #6666: https://github.com/golang/go/issues/6666 (このコミットが修正した課題)
- Go Code Review 72770043: https://golang.org/cl/72770043 (このコミットのコードレビューページ)
参考にした情報源リンク
- Go Command Documentation:
go help list
(Goのgo list
コマンドに関する公式ドキュメント) text/template
package documentation: https://pkg.go.dev/text/template (Goのテキストテンプレートパッケージに関する公式ドキュメント)go/build
package documentation: https://pkg.go.dev/go/build (Goのビルドパッケージに関する公式ドキュメント)- Web search for "go list -f template context"
- Web search for "go/build.Context struct fields"
I have generated the detailed explanation in Markdown format, following all the specified instructions and including all the required sections. I have used the commit data and the web search results to provide comprehensive explanations for each section.
I will now output this to standard output.# [インデックス 19070] ファイルの概要
このコミットは、`go list -f` コマンドのテンプレート機能に、ビルドコンテキスト情報 (`go/build.Context` の値) を利用できるようにする変更を導入しています。これにより、ユーザーは `go list -f` の出力テンプレート内で、ターゲットアーキテクチャ (`GOARCH`) やビルドタグ (`BuildTags`) といったビルド環境に関する情報にアクセスできるようになります。
## コミット
- **コミットハッシュ**: `b3a33a654d2f640f3b6c7856ea742c23f6c49d1c`
- **Author**: Rick Arnold <rickarnoldjr@gmail.com>
- **Date**: Tue Apr 8 22:35:29 2014 -0400
## GitHub上でのコミットページへのリンク
[https://github.com/golang/go/commit/b3a33a654d2f640f3b6c7856ea742c23f6c49d1c](https://github.com/golang.com/go/commit/b3a33a654d2f640f3b6c7856ea742c23f6c49d1c)
## 元コミット内容
cmd/go: allow use of Context in 'go list -f'
Add a $Context variable to the template so that the build.Context values such as BuildTags can be accessed.
Fixes #6666.
LGTM=adg, rsc R=golang-codereviews, gobot, adg, rsc CC=golang-codereviews https://golang.org/cl/72770043
## 変更の背景
`go list` コマンドは、Goパッケージに関する情報を表示するための強力なツールです。特に `-f` フラグを使用すると、Goの `text/template` パッケージの構文を用いて、出力形式を自由にカスタマイズできます。しかし、これまでの `go list -f` のテンプレートでは、各パッケージのメタデータ(インポートパス、ディレクトリ、ファイルリストなど)にはアクセスできましたが、Goのビルド環境に関する情報(例えば、現在のターゲットOSやアーキテクチャ、有効なビルドタグなど)には直接アクセスできませんでした。
この制限は、特定のビルド環境に依存する情報を `go list` の出力に含めたい場合に問題となります。例えば、特定のビルドタグが有効な場合にのみ表示されるパッケージを識別したり、異なるOSやアーキテクチャ向けにビルドされた場合のパッケージの挙動をシミュレートしたりする際に、ビルドコンテキスト情報へのアクセスが必要となります。
このコミットは、このギャップを埋めるために、`go list -f` のテンプレート内で `build.Context` の値にアクセスできる `$Context` 変数を導入しました。これにより、ユーザーはより柔軟で情報豊富な `go list` の出力を生成できるようになります。コミットメッセージにある `Fixes #6666` は、この機能追加の必要性を示唆する既存の課題があったことを意味しています。
## 前提知識の解説
### `go list` コマンドと `-f` フラグ
`go list` は、Goのワークスペース内のパッケージに関する情報を表示するコマンドです。例えば、`go list all` はすべてのパッケージのインポートパスを表示します。
`-f` フラグは、出力形式をカスタマイズするために使用されます。このフラグに続く文字列は、Goの `text/template` パッケージの構文として解釈されます。テンプレートには、各パッケージの `Package` 構造体の情報が渡されます。
例: `go list -f '{{.ImportPath}} {{.Dir}}'` は、各パッケージのインポートパスとディレクトリを表示します。
### Goの `text/template` パッケージ
`text/template` パッケージは、Go言語に組み込まれているテキストテンプレートエンジンです。プレースホルダー(`{{.Field}}`)や制御構造(`{{if .Condition}}...{{end}}`、`{{range .Slice}}...{{end}}`)を使用して、動的にテキストを生成できます。また、カスタム関数を登録してテンプレート内で利用することも可能です。
### `go/build.Context` 構造体
`go/build` パッケージは、Goのビルドプロセスに関する情報を提供します。その中の `Context` 構造体は、Goのビルド環境に関する様々な設定をカプセル化しています。これには以下のようなフィールドが含まれます。
* `GOARCH`: ターゲットアーキテクチャ (例: `amd64`, `arm`)
* `GOOS`: ターゲットオペレーティングシステム (例: `linux`, `windows`, `darwin`)
* `GOROOT`: Goのインストールルートディレクトリ
* `GOPATH`: Goのワークスペースパス
* `CgoEnabled`: cgoが有効かどうか
* `BuildTags`: ビルド制約 (`+build` ディレクティブ) にマッチするビルドタグのリスト
* `ReleaseTags`: 現在のリリースと互換性のあるリリースを示すタグのリスト
これらの情報は、Goがソースファイルをどのようにコンパイルし、どのファイルを含めるかを決定する際に使用されます。
## 技術的詳細
このコミットの主要な目的は、`go list -f` のテンプレート内で `go/build.Context` の情報にアクセスできるようにすることです。これを実現するために、以下の技術的な変更が加えられました。
1. **`Context` 構造体の定義と `newContext` 関数の追加 (`src/cmd/go/context.go`)**:
`cmd/go` パッケージ内に、`go/build.Context` の主要なフィールドをミラーリングする新しい `Context` 構造体が定義されました。この構造体は、JSONシリアライズ可能 (`json:",omitempty"`) に設定されており、将来的に `go list -json` の出力にも含めることができるように設計されています。
また、`go/build.Context` のインスタンスを受け取り、新しく定義された `Context` 構造体のインスタンスを生成する `newContext` ヘルパー関数が追加されました。これにより、`go/build` パッケージのコンテキスト情報を、テンプレートが利用できる形式に変換します。
2. **テンプレート関数 `context` の追加 (`src/cmd/go/list.go`)**:
`go list` コマンドのテンプレート処理ロジック (`runList` 関数) が変更され、新しいテンプレート関数 `context` が `template.FuncMap` に追加されました。この `context` 関数は、`go/build` パッケージのグローバルなビルドコンテキスト (`buildContext`) をラップした `Context` 構造体のインスタンスを返します。このインスタンスは一度生成されるとキャッシュされ、テンプレート内で複数回 `context` 関数が呼び出されても同じインスタンスが返されるように最適化されています。
3. **ドキュメントの更新 (`src/cmd/go/doc.go`)**:
`go list -f` のドキュメントが更新され、新しく追加された `context` テンプレート関数とその戻り値である `Context` 構造体について説明が追加されました。これにより、ユーザーは新しい機能の存在と使い方を理解できます。
4. **テストケースの追加 (`src/cmd/go/test.bash`)**:
新しい機能が正しく動作することを確認するために、`go list -f "GOARCH: {{context.GOARCH}}"` を実行し、期待される出力が得られるかを検証するテストケースが `test.bash` スクリプトに追加されました。これは、`go list` がビルドコンテキスト情報にアクセスできることを保証します。
これらの変更により、`go list -f` のテンプレート内で `{{context.GOARCH}}` や `{{context.BuildTags}}` のようにビルドコンテキストのフィールドに直接アクセスできるようになり、`go list` の機能が大幅に拡張されました。
## コアとなるコードの変更箇所
### `src/cmd/go/context.go` (新規ファイル)
```go
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"go/build"
)
type Context struct {
GOARCH string `json:",omitempty"` // target architecture
GOOS string `json:",omitempty"` // target operating system
GOROOT string `json:",omitempty"` // Go root
GOPATH string `json:",omitempty"` // Go path
CgoEnabled bool `json:",omitempty"` // whether cgo can be used
UseAllFiles bool `json:",omitempty"` // use files regardless of +build lines, file names
Compiler string `json:",omitempty"` // compiler to assume when computing target paths
BuildTags []string `json:",omitempty"` // build constraints to match in +build lines
ReleaseTags []string `json:",omitempty"` // releases the current release is compatible with
InstallSuffix string `json:",omitempty"` // suffix to use in the name of the install dir
}
func newContext(c *build.Context) *Context {
return &Context{
GOARCH: c.GOARCH,
GOOS: c.GOOS,
GOROOT: c.GOROOT,
CgoEnabled: c.CgoEnabled,
UseAllFiles: c.UseAllFiles,
Compiler: c.Compiler,
BuildTags: c.BuildTags,
ReleaseTags: c.ReleaseTags,
InstallSuffix: c.InstallSuffix,
}
}
src/cmd/go/doc.go
(変更箇所)
--- a/src/cmd/go/doc.go
+++ b/src/cmd/go/doc.go
@@ -283,8 +283,7 @@ The default output shows the package import path:
The -f flag specifies an alternate format for the list, using the
syntax of package template. The default output is equivalent to -f
-`{{.ImportPath}}`. One extra template function is available, "join",
-which calls strings.Join. The struct being passed to the template is:
+`{{.ImportPath}}`. The struct being passed to the template is:
type Package struct {
Dir string // directory containing package sources
@@ -332,6 +331,26 @@ which calls strings.Join. The struct being passed to the template is:
XTestImports []string // imports from XTestGoFiles
}
+The template function "join" calls strings.Join.
+
+The template function "context" returns the build context, defined as:
+
+ type Context struct {
+ GOARCH string // target architecture
+ GOOS string // target operating system
+ GOROOT string // Go root
+ GOPATH string // Go path
+ CgoEnabled bool // whether cgo can be used
+ UseAllFiles bool // use files regardless of +build lines, file names
+ Compiler string // compiler to assume when computing target paths
+ BuildTags []string // build constraints to match in +build lines
+ ReleaseTags []string // releases the current release is compatible with
+ InstallSuffix string // suffix to use in the name of the install dir
+ }
+
+For more information about the meaning of these fields see the documentation
+for the go/build package's Context type.
+
The -json flag causes the package data to be printed in JSON format
instead of using the template format.
src/cmd/go/list.go
(変更箇所)
--- a/src/cmd/go/list.go
+++ b/src/cmd/go/list.go
@@ -27,8 +27,7 @@ The default output shows the package import path:
The -f flag specifies an alternate format for the list, using the
syntax of package template. The default output is equivalent to -f
-`{{.ImportPath}}`. One extra template function is available, "join",
-which calls strings.Join. The struct being passed to the template is:
+`{{.ImportPath}}`. The struct being passed to the template is:
type Package struct {
Dir string // directory containing package sources
@@ -76,6 +75,26 @@ which calls strings.Join. The struct being passed to the template is:
XTestImports []string // imports from XTestGoFiles
}
+The template function "join" calls strings.Join.
+
+The template function "context" returns the build context, defined as:
+
+ type Context struct {
+ GOARCH string // target architecture
+ GOOS string // target operating system
+ GOROOT string // Go root
+ GOPATH string // Go path
+ CgoEnabled bool // whether cgo can be used
+ UseAllFiles bool // use files regardless of +build lines, file names
+ Compiler string // compiler to assume when computing target paths
+ BuildTags []string // build constraints to match in +build lines
+ ReleaseTags []string // releases the current release is compatible with
+ InstallSuffix string // suffix to use in the name of the install dir
+ }
+
+For more information about the meaning of these fields see the documentation
+for the go/build package's Context type.
+
The -json flag causes the package data to be printed in JSON format
instead of using the template format.
@@ -131,7 +150,18 @@ func runList(cmd *Command, args []string) {
`out.Write(nl)`
}
} else {
- `tmpl, err := template.New("main").Funcs(template.FuncMap{"join": strings.Join}).Parse(*listFmt)`
+ `var cachedCtxt *Context`
+ `context := func() *Context {`
+ ` if cachedCtxt == nil {`
+ ` cachedCtxt = newContext(&buildContext)`
+ ` }`
+ ` return cachedCtxt`
+ `}`
+ `fm := template.FuncMap{`
+ ` "join": strings.Join,`
+ ` "context": context,`
+ `}`
+ `tmpl, err := template.New("main").Funcs(fm).Parse(*listFmt)`
`if err != nil {`
` fatalf("%s", err)`
`}`
src/cmd/go/test.bash
(変更箇所)
--- a/src/cmd/go/test.bash
+++ b/src/cmd/go/test.bash
@@ -694,6 +694,12 @@ unset go_cmds
unset ldflags
unset GOPATH
+TEST list template can use context function
+if ! ./testgo list -f "GOARCH: {{context.GOARCH}}"; then
+ echo unable to use context in list template
+ ok=false
+fi
+
# clean up
if $started; then stop; fi
rm -rf testdata/bin testdata/bin1
コアとなるコードの解説
src/cmd/go/context.go
このファイルは、go list -f
テンプレートに公開される Context
型を定義しています。この型は go/build.Context
のサブセットであり、ビルド環境に関する重要な情報(GOARCH
, GOOS
, BuildTags
など)を保持します。newContext
関数は、実際の go/build.Context
インスタンスからこの Context
型のインスタンスを生成するファクトリ関数として機能します。json:",omitempty"
タグは、この構造体がJSONとしてシリアライズされる際に、値が空の場合にフィールドを省略することを示しています。
src/cmd/go/doc.go
この変更は、go list -f
コマンドのヘルプドキュメントを更新しています。特に、context
という新しいテンプレート関数が利用可能になったことと、その関数が返す Context
構造体の定義が追加されています。これにより、ユーザーは go list -f
でビルドコンテキスト情報にアクセスする方法を公式ドキュメントで確認できるようになります。
src/cmd/go/list.go
このファイルは go list
コマンドの主要なロジックを含んでいます。変更の核心は runList
関数内にあります。
以前は template.FuncMap
に join
関数のみが登録されていましたが、このコミットにより context
関数も追加されました。
context
関数はクロージャとして定義されており、cachedCtxt
という変数を使って Context
インスタンスをキャッシュします。これにより、テンプレート内で context
関数が複数回呼び出されても、newContext
が一度だけ実行され、パフォーマンスが向上します。
buildContext
は go/build
パッケージのグローバルなビルドコンテキスト変数であり、現在のGo環境のビルド設定を保持しています。
src/cmd/go/test.bash
このシェルスクリプトは、Goコマンドの統合テストを実行します。追加されたテストケースは、go list -f "GOARCH: {{context.GOARCH}}"
を実行し、その出力が期待通りであるかを確認します。これは、context
テンプレート関数が正しく機能し、GOARCH
の値がテンプレートに渡されることを検証するものです。このテストの成功は、新機能が意図通りに動作していることの保証となります。
関連リンク
- Go issue #6666: https://github.com/golang/go/issues/6666 (このコミットが修正した課題)
- Go Code Review 72770043: https://golang.org/cl/72770043 (このコミットのコードレビューページ)
参考にした情報源リンク
- Go Command Documentation:
go help list
(Goのgo list
コマンドに関する公式ドキュメント) text/template
package documentation: https://pkg.go.dev/text/template (Goのテキストテンプレートパッケージに関する公式ドキュメント)go/build
package documentation: https://pkg.go.dev/go/build (Goのビルドパッケージに関する公式ドキュメント)- Web search for "go list -f template context"
- Web search for "go/build.Context struct fields"