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

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

このコミットは、Go言語のコマンドラインツール go の内部構造、特に go list コマンドが利用する Package 型の定義を同期させ、そのドキュメントを更新するものです。go list は、Goパッケージに関する詳細情報を表示するための重要なコマンドであり、その出力形式は Package 型の構造に密接に関連しています。

コミット

commit eb5db57d1aa3dbff48693af0673746c232da875e
Author: Russ Cox <rsc@golang.org>
Date:   Mon Mar 5 14:41:30 2012 -0500

    cmd/go: sync type Package and go list doc

    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/5730061

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

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

元コミット内容

cmd/go: sync type Package and go list doc

このコミットメッセージは、go コマンドの Package 型の定義と、go list コマンドのドキュメントを同期させることを目的としていることを示しています。これは、Package 型の構造が変更された際に、その変更が go list の出力形式に正しく反映されるようにするためのメンテナンス作業です。

変更の背景

Go言語のツールチェインは継続的に進化しており、特に go コマンドはGoプロジェクトのビルド、テスト、管理において中心的な役割を担っています。go list コマンドは、開発者がGoパッケージの依存関係、ソースファイル、ビルド情報などをプログラム的に取得するための強力な手段を提供します。このコマンドの出力は、内部的には Package という構造体によって表現されます。

このコミットが行われた2012年3月は、Go言語がまだ比較的新しく、活発に開発が進められていた時期です。GoのビルドシステムやCgo(GoとC言語の相互運用機能)に関する機能が追加・改善される中で、Package 型の定義もそれに合わせて更新する必要がありました。

具体的には、以下の点が変更の背景にあると考えられます。

  1. Cgo関連情報の追加: CgoはGoプログラムからC言語のコードを呼び出すための機能です。Cgoを使用するパッケージのビルドには、Cコンパイラやリンカに対する特定のフラグ(CFLAGS, LDFLAGS)や、pkg-config の情報が必要になります。これらの情報を Package 型に含めることで、go list がCgo関連のビルド設定も報告できるようになり、ツールやIDEがより正確なビルド情報を取得できるようになります。
  2. テスト関連情報の詳細化: Goのテストフレームワークは、パッケージ内部のテスト (_test.go ファイル) と、外部テスト (_test.go ファイルで _test サフィックスを持つパッケージ) を区別します。これらのテストファイルがインポートするパッケージの情報 (TestImports, XTestImports) を Package 型に含めることで、テストの依存関係をより詳細に分析できるようになります。
  3. 構造体の整理: Package 型のフィールドの順序が変更されています。これは、関連するフィールドをまとめることで、コードの可読性やメンテナンス性を向上させるための一般的なリファクタリングです。また、IncompleteError といったエラー関連のフィールドが、他のエラー情報と共にまとめられています。
  4. ドキュメントとの同期: go list コマンドのヘルプメッセージやドキュメントは、Package 型の定義と一致している必要があります。型定義が変更された場合、その変更をドキュメントにも反映させることで、ユーザーが go list の出力形式を正しく理解できるようにします。

これらの変更は、go コマンドが提供するパッケージ情報の粒度と正確性を向上させ、Goエコシステムにおけるツール開発を支援することを目的としています。

前提知識の解説

このコミットを理解するためには、以下のGo言語および関連ツールの基本的な知識が必要です。

  1. Go言語のパッケージシステム: Go言語はパッケージという単位でコードを管理します。各パッケージは、関連するGoソースファイルの集合であり、import パスによって識別されます。
  2. go コマンド: Go言語の公式ツールチェインの中心となるコマンドです。コードのビルド、テスト、インストール、フォーマット、依存関係の管理など、多岐にわたる機能を提供します。
  3. go list コマンド: go list は、指定されたGoパッケージに関する詳細情報を表示するコマンドです。デフォルトではパッケージのインポートパスを出力しますが、-json フラグを使用すると、パッケージの構造をJSON形式で出力できます。このJSON出力のスキーマは、Goの内部で定義されている Package 構造体に対応しています。
    • 例: go list -json <package_path>
  4. Package 構造体: go コマンドの内部で、Goパッケージのメタデータを表現するために使用されるGo言語の構造体です。この構造体には、パッケージ名、インポートパス、ソースファイルのリスト、依存関係、ドキュメント文字列など、パッケージに関するあらゆる情報が含まれます。go list -json の出力はこの構造体のJSON表現です。
  5. Cgo: Go言語とC言語のコードを相互運用するためのGoの機能です。Cgoを使用すると、Goプログラムから既存のCライブラリを呼び出したり、CのコードをGoプログラムに組み込んだりできます。Cgoを使用する際には、Cコンパイラやリンカに渡す追加のフラグが必要になることがあります。
    • CgoFiles: Cgoディレクティブを含むGoソースファイル。
    • CgoCFLAGS: Cコンパイラに渡すフラグ。
    • CgoLDFLAGS: リンカに渡すフラグ。
    • CgoPkgConfig: pkg-config を使用してライブラリ情報を取得するための名前。
  6. テストファイルの種類: Goのテストファイルには主に2種類あります。
    • 内部テストファイル: パッケージと同じディレクトリにあり、パッケージ名と同じ _test.go サフィックスを持つファイルです。これらはパッケージの一部としてコンパイルされ、パッケージの内部関数や変数にアクセスできます。
    • 外部テストファイル: パッケージと同じディレクトリにあり、_test.go サフィックスを持ち、かつパッケージ名が _test で終わるファイルです(例: mypackage_test)。これらは独立したパッケージとしてコンパイルされ、テスト対象のパッケージを通常のユーザーと同じようにインポートしてテストします。これにより、パッケージのエクスポートされたAPIのみをテストできます。
  7. json タグ: Go言語の構造体フィールドに付与されるタグの一つで、JSONエンコーディング/デコーディング時のフィールド名を指定したり、omitempty オプションで値がゼロ値の場合にJSON出力から省略したりするために使用されます。

技術的詳細

このコミットの主要な変更点は、src/cmd/go/list.gosrc/cmd/go/pkg.go の両方で定義されている Package 構造体の同期と拡張です。

src/cmd/go/list.gogo list コマンドのドキュメントの一部として Package 構造体の定義をコメント形式で含んでおり、src/cmd/go/pkg.go は実際に go コマンドが内部で使用する Package 構造体のGo言語の定義を含んでいます。これら二つの定義は常に一致している必要があります。

変更された Package 構造体のフィールドは以下の通りです。

追加されたフィールド

  • Target string: パッケージのインストールパスを示します。これは、go install コマンドによってビルドされたバイナリやアーカイブがどこに配置されるかを示します。
  • Goroot bool: このパッケージがGoのインストールディレクトリ(GOROOT)内にあるかどうかを示すブール値です。標準ライブラリのパッケージは通常 GOROOT 内にあります。
  • Standard bool: このパッケージがGoの標準ライブラリの一部であるかどうかを示すブール値です。Goroottrue であっても、必ずしも Standardtrue とは限りません(例: GOROOT 内のツールなど)。
  • Root string: このパッケージを含むGoのルートディレクトリまたはGoパスディレクトリを示します。これは、GOROOT または GOPATH のいずれかのルートパスになります。
  • Cgo関連のフィールド:
    • CgoCFLAGS []string: Cgoディレクティブで指定されたCコンパイラへのフラグのリスト。
    • CgoLDFLAGS []string: Cgoディレクティブで指定されたリンカへのフラグのリスト。
    • CgoPkgConfig []string: Cgoディレクティブで指定された pkg-config の名前のリスト。
  • テスト関連のインポート情報:
    • TestImports []string: パッケージ内部のテストファイル (_test.go) がインポートするパッケージのパスのリスト。
    • XTestImports []string: 外部テストファイル (_test.go_test サフィックスを持つパッケージ) がインポートするパッケージのパスのリスト。

変更されたフィールドの順序と配置

  • 既存のフィールド (Dir, ImportPath, Name, Doc など) の順序が変更され、関連する情報がより論理的にグループ化されています。
  • エラー情報 (Incomplete, Error, DepsErrors) が、Package 構造体の末尾近くにまとめられています。
  • ソースファイル関連のフィールド (GoFiles, CgoFiles, CFiles, HFiles, SFiles) もグループ化されています。

json タグの調整

src/cmd/go/pkg.go では、Package 構造体のフィールドに付与されている json:",omitempty" タグが調整されています。これは、JSON出力時にフィールドが空の場合にそのフィールドを省略するためのものです。フィールドの追加や順序変更に伴い、これらのタグも適切に再配置されています。

これらの変更により、go list コマンドは、Goパッケージに関するより包括的で詳細な情報を提供できるようになり、特にCgoを使用するプロジェクトや、テストの依存関係を分析するツールにとって有用なデータを提供します。

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

このコミットでは、主に以下の2つのファイルが変更されています。

  1. src/cmd/go/list.go: go list コマンドのドキュメント内で、Package 構造体の説明が更新されています。これは、go list の出力形式を説明するためのコメントブロックであり、実際のGoコードではありませんが、ユーザーが go list -json の出力を理解するための重要な情報源です。

    --- a/src/cmd/go/list.go
    +++ b/src/cmd/go/list.go
    @@ -30,30 +30,41 @@ is equivalent to -f '{{.ImportPath}}'.  The struct
     being passed to the template is:
    
         type Package struct {
    +        Dir        string // directory containing package sources
    +        ImportPath string // import path of package in dir
             Name       string // package name
             Doc        string // package documentation string
    -        ImportPath string // import path of package in dir
    -        Dir        string // directory containing package sources
    -        Version    string // version of installed package (TODO)
    +        Target     string // install path
    +        Goroot     bool   // is this package in the Go root?
    +        Standard   bool   // is this package part of the standard Go library?
             Stale      bool   // would 'go install' do anything for this package?
    +        Root       string // Go root or Go path dir containing this package
    
             // Source files
    -        GoFiles      []string // .go source files (excluding CgoFiles, TestGoFiles, and XTestGoFiles)
    -        TestGoFiles  []string // _test.go source files internal to the package they are testing
    -        XTestGoFiles []string // _test.go source files external to the package they are testing
    -        CFiles       []string // .c source files
    -        HFiles       []string // .h source files
    -        SFiles       []string // .s source files
    -        CgoFiles     []string // .go sources files that import "C"
    +        GoFiles  []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
    +        CgoFiles []string // .go sources files that import "C"
    +        CFiles   []string // .c source files
    +        HFiles   []string // .h source files
    +        SFiles   []string // .s source files
    +
    +        // Cgo directives
    +        CgoCFLAGS    []string // cgo: flags for C compiler
    +        CgoLDFLAGS   []string // cgo: flags for linker
    +        CgoPkgConfig []string // cgo: pkg-config names
    
             // Dependency information
             Imports []string // import paths used by this package
             Deps    []string // all (recursively) imported dependencies
    -        
    +
             // Error information
             Incomplete bool            // this package or a dependency has an error
    -        Error *PackageError        // error loading package
    +        Error      *PackageError   // error loading package
             DepsErrors []*PackageError // errors loading dependencies
    +\
    +        TestGoFiles  []string // _test.go files in package
    +        TestImports  []string // imports from TestGoFiles
    +        XTestGoFiles []string // _test.go files outside package
    +        XTestImports []string // imports from XTestGoFiles
         }\n
     The -json flag causes the package data to be printed in JSON format
    
  2. src/cmd/go/pkg.go: go コマンドが内部で利用する Package 構造体の実際のGo言語の定義が変更されています。このファイルは、go list の出力だけでなく、go コマンドの他の部分でもパッケージ情報を扱う際に参照されます。

    --- a/src/cmd/go/pkg.go
    +++ b/src/cmd/go/pkg.go
    @@ -24,21 +24,18 @@ type Package struct {
     	// Note: These fields are part of the go command's public API.
     	// See list.go.  It is okay to add fields, but not to change or
     	// remove existing ones.  Keep in sync with list.go
    -\tDir        string        `json:",omitempty"` // directory containing package sources
    -\tImportPath string        `json:",omitempty"` // import path of package in dir
    -\tName       string        `json:",omitempty"` // package name
    -\tDoc        string        `json:",omitempty"` // package documentation string
    -\tTarget     string        `json:",omitempty"` // install path
    -\tGoroot     bool          `json:",omitempty"` // is this package found in the Go root?
    -\tStandard   bool          `json:",omitempty"` // is this package part of the standard Go library?
    -\tStale      bool          `json:",omitempty"` // would 'go install' do anything for this package?
    -\tIncomplete bool          `json:",omitempty"` // was there an error loading this package or dependencies?
    -\tError      *PackageError `json:",omitempty"` // error loading this package (not dependencies)
    -\n-\tRoot string `json:",omitempty"` // root dir of tree this package belongs to
    +\tDir        string `json:",omitempty"` // directory containing package sources
    +\tImportPath string `json:",omitempty"` // import path of package in dir
    +\tName       string `json:",omitempty"` // package name
    +\tDoc        string `json:",omitempty"` // package documentation string
    +\tTarget     string `json:",omitempty"` // install path
    +\tGoroot     bool   `json:",omitempty"` // is this package found in the Go root?
    +\tStandard   bool   `json:",omitempty"` // is this package part of the standard Go library?
    +\tStale      bool   `json:",omitempty"` // would 'go install' do anything for this package?
    +\tRoot       string `json:",omitempty"` // Go root or Go path dir containing this package
    
     	// Source files
    -\tGoFiles  []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles XTestGoFiles)\n
    +\tGoFiles  []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
     	CgoFiles []string `json:",omitempty"` // .go sources files that import "C"
     	CFiles   []string `json:",omitempty"` // .c source files
     	HFiles   []string `json:",omitempty"` // .h source files
    @@ -50,8 +47,12 @@ type Package struct {\n     	CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names
    
     	// Dependency information
    -\tImports    []string        `json:",omitempty"` // import paths used by this package
    -\tDeps       []string        `json:",omitempty"` // all (recursively) imported dependencies
    +\tImports []string `json:",omitempty"` // import paths used by this package
    +\tDeps    []string `json:",omitempty"` // all (recursively) imported dependencies
    +\
    +\t// Error information
    +\tIncomplete bool            `json:",omitempty"` // was there an error loading this package or dependencies?
    +\tError      *PackageError   `json:",omitempty"` // error loading this package (not dependencies)
     	DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies
    
     	// Test information
    

コアとなるコードの解説

このコミットの核心は、Package 構造体の定義を拡張し、そのフィールドの順序を整理することにあります。

  1. フィールドの追加:

    • Target, Goroot, Standard, Root といったフィールドが追加され、パッケージのインストールパス、Goルート内にあるか、標準ライブラリであるか、およびパッケージのルートディレクトリに関する情報が提供されるようになりました。これにより、go list の出力がより詳細になり、パッケージの性質をプログラム的に判断しやすくなります。
    • Cgo関連のビルドフラグ (CgoCFLAGS, CgoLDFLAGS, CgoPkgConfig) が追加されました。これは、Cgoを使用するGoパッケージのビルドプロセスをより正確に記述するために不可欠です。これらの情報は、Cgoのビルド設定を解析するツールにとって非常に価値があります。
    • テストファイルのインポート情報 (TestImports, XTestImports) が追加されました。これにより、Goのテストの依存関係を詳細に分析できるようになり、テストカバレッジツールやIDEがよりインテリジェントな機能を提供できるようになります。
  2. フィールドの再配置:

    • DirImportPath が構造体の先頭に移動されました。これらはパッケージの基本的な識別情報であり、アクセス頻度が高いと予想されるため、先頭に配置することで可読性が向上します。
    • ソースファイル、Cgoディレクティブ、依存関係、エラー情報、テスト情報といった関連するフィールドがそれぞれグループ化されています。これにより、構造体の定義が論理的に整理され、理解しやすくなっています。
  3. json タグの維持: src/cmd/go/pkg.goPackage 構造体では、各フィールドに json:",omitempty" タグが引き続き付与されています。これは、go list -json コマンドでJSON形式で出力される際に、値がGoのゼロ値(文字列の場合は空文字列、スライスの場合はnilなど)であるフィールドがJSON出力から省略されることを意味します。これにより、JSON出力が冗長になるのを防ぎ、必要な情報のみが提供されます。

これらの変更は、go コマンドがGoパッケージに関するよりリッチなメタデータを提供できるようにするための重要なステップであり、Goエコシステムにおけるツール開発の基盤を強化するものです。

関連リンク

参考にした情報源リンク