go/packages 荒訳

公開:2020/10/15
更新:2020/10/15
3 min読了の目安(約2700字TECH技術記事

https://pkg.go.dev/golang.org/x/tools/go/packages (通称 go/packages) のOverviewの荒訳です。

概要

packagesパッケージはGoのパッケージを検証及び解析のために読み込みます。

Load関数はパターンのリストを入力として取り、そのパターンにマッチした個別のパッケージに対応したPackage構造体のリストを返します。LoadModeは読み込むパッケージ情報の詳細度を制御します。

Loadはパターンのほとんどを下回りのビルドツールにそのまま渡しますが、すべてのパターンは"query="プレフィクスを持ち、queryの部分は[a-z]の文字からなる空白ではない文字列で、予約されクエリのオペレーターとして解釈されます。

現在のところ"file""pattern"の2つのクエリオペレーターがサポートされています。

"file=path/to/file.go"というクエリはそのパッケージおよびpath/to/file.goというファイルを含む複数のパッケージマッチします。例えば"file=~/go/src/fmt/print.go""fmt""fmt [fmt.test]"パッケージを返すでしょう。

"pattern=string"というクエリは下回りのビルドツールに文字列"string"をそのまま渡します。ほとんどの場合これは必要ないですが、アプリケーションはLoad("pattern=" + x)'='を含むxがクエリオペレータとして解釈されないことを確実にするためのエスケープ機構として利用できます。

他のすべてのクエリオペレーターは将来のために予約されており、現在のLoadはそれらに対してエラーを報告します。

Package構造体はパッケージについての以下の基本的な情報を提供します。

  • ID - パッケージのユニーク識別子(戻り値の中でユニーク)
  • GoFiles - パッケージ内のGoのソースファイルの名前
  • Imports - import文字列からそれが指定するパッケージへのマップ
  • Types - パッケージがexportするsymbolの型情報
  • Syntax - パッケージのソースコードのparse済みsyntaxツリー
  • TypeInfo - パッケージのソースツリーの完全な型チェックの結果

(詳しくは以下のPackage型の説明を参照)

例えば以下のコードはbytes, unicode, unicode/utf16及びunicode/utf8の4つの標準ライブラリのパッケージに対応するPackageを返します。

Load(nil, "bytes", "unicode...")

1つのパターンが複数のパッケージにマッチしうること、そして1つのパッケージが複数のパターンにマッチしうることに留意してください。すなわちどのパッケージがどのパターンにマッチしたかを特定することは不可能ということです。

Load関数は第1引数にConfigのポインタを渡すことで動作を変更できます。nilを渡すことは空のConfigを渡すことと同義で、それは最小限の情報を集めるLoadFilesモードでLoadを実行します。詳しくはConfig型の説明を参照してください。

先述した通り、Config.Modeは読んだパッケージの情報の詳細度を制御します。詳しくはLoadModeの説明を参照してください。

多くのツールは彼らの未解釈なコマンドライン引数(フラグを除く)をローダーに引き渡すべきです。それによりローダーが下回りとなるビルドシステムの流儀に従ってそれらを解釈できます。この関数の典型的な使用方法は以下の例を参照してください。

以下はコマンドラインで指定したパッケージのソースからパッケージ情報を読み込むデモンストレーションの例です。

package main

import (
	"flag"
	"fmt"
	"golang.org/x/tools/go/packages"
	"os"
)

func main() {
	flag.Parse()

	// Many tools pass their command-line arguments (after any flags)
	// uninterpreted to packages.Load so that it can interpret them
	// according to the conventions of the underlying build system.
	cfg := &packages.Config{Mode: packages.NeedFiles | packages.NeedSyntax}
	pkgs, err := packages.Load(cfg, flag.Args()...)
	if err != nil {
		fmt.Fprintf(os.Stderr, "load: %v\n", err)
		os.Exit(1)
	}
	if packages.PrintErrors(pkgs) > 0 {
		os.Exit(1)
	}

	// Print the names of the source files
	// for each package listed on the command line.
	for _, pkg := range pkgs {
		fmt.Println(pkg.ID, pkg.GoFiles)
	}
}

(訳者注) 翻訳は以上になります。残りの詳細は https://pkg.go.dev/golang.org/x/tools/go/packages#pkg-examples を参照してください。