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

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

このコミットは、Go言語の配布物(バイナリディストリビューション)を生成するスクリプトである misc/dist/bindist.go に関連する変更です。具体的には、Goの公式ツールである go covergo vet を配布物に含めるようにし、go.tools リポジトリの特定のタグを指定するための -tool フラグを追加しています。

コミット

このコミットは、Go言語のバイナリ配布物生成プロセスを改善し、go.tools リポジトリに含まれる重要なツールである covervet を標準配布物に含めるようにしました。これにより、Goユーザーはこれらのツールを別途インストールすることなく利用できるようになります。また、go.tools のバージョン管理をより柔軟に行うための -tool フラグが導入されました。

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

https://github.com/golang/go/commit/73790d407c9271a356eb374006d1b23303229d72

元コミット内容

misc/dist: include cover and vet, add -tool flag to specify go.tools tag

Fixes #6356.

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

変更の背景

この変更の背景には、Go言語の公式ツールである go covergo vet をGoの標準配布物の一部として提供し、ユーザーがより簡単にこれらのツールを利用できるようにするという目的があります。以前は、これらのツールは go.tools リポジトリに存在し、ユーザーは go get コマンドを使って個別にインストールする必要がありました。

コミットメッセージにある Fixes #6356 は、この変更がIssue 6356を解決することを示しています。Issue 6356は「go vetgo cover をGoの配布物に含めるべきか?」という議論に関するもので、最終的に含めるという決定がなされたため、このコミットが作成されました。

また、go.tools リポジトリはGo本体とは独立して開発が進められるため、配布物生成時にどのバージョンの go.tools を使用するかを柔軟に指定できるメカニズムが必要でした。これが -tool フラグの導入理由です。

前提知識の解説

  • go.tools: go.tools は、Go言語の公式ツールやライブラリをまとめたリポジトリです。go vet (静的解析ツール)、go cover (カバレッジツール)、godoc (ドキュメント生成ツール) など、Go開発を支援する多くのツールが含まれています。これらのツールはGo本体とは異なるリリースサイクルを持つことがあります。
  • go get: Goのパッケージや依存関係を取得するためのコマンドです。指定されたリポジトリからソースコードをダウンロードし、GOPATH に配置します。-d フラグを付けると、ダウンロードのみを行い、ビルドやインストールは行いません。
  • go install: Goのパッケージをビルドし、実行可能ファイルを GOBIN (または GOPATH/bin) に、ライブラリファイルを GOPATH/pkg にインストールするコマンドです。
  • go cover: Goプログラムのテストカバレッジを測定するためのツールです。どのコードがテストによって実行されたかを可視化し、テストの網羅性を評価するのに役立ちます。
  • go vet: Goプログラムの潜在的なバグや疑わしい構造を検出するための静的解析ツールです。例えば、フォーマット文字列の誤り、到達不能なコード、ロックの誤用などを検出できます。
  • misc/dist/bindist.go: Go言語のソースコードリポジトリ内の misc/dist ディレクトリにあるGoプログラムです。このプログラムは、Goの公式バイナリ配布物(Windows, macOS, Linuxなどの各OS/アーキテクチャ向けのGo SDK)を生成するプロセスの一部として使用されます。具体的には、Go本体のビルドに加え、go.tools の一部や go-tour などの追加ツールをパッケージングする役割を担っています。
  • Mercurial (hg): Goプロジェクトがかつてバージョン管理システムとして使用していた分散型バージョン管理システムです。このコミットが作成された2013年時点では、GoプロジェクトはまだGitに完全に移行しておらず、Mercurialが主要なVCSでした。hg update コマンドは、指定されたリビジョンやタグに作業コピーを更新するために使用されます。
  • GOROOTGOPATH:
    • GOROOT: GoのSDKがインストールされているルートディレクトリです。Goの標準ライブラリやツールが含まれます。
    • GOPATH: Goのワークスペースディレクトリです。ユーザーが開発するGoプロジェクトのソースコード、ビルドされたバイナリ、ダウンロードされた依存関係などが配置されます。

技術的詳細

このコミットの主要な技術的変更点は以下の通りです。

  1. go.tools の取り込みと -tool フラグの追加:

    • flag.String("tool", defaultToolTag, "go.tools tag to check out") が追加され、go.tools リポジトリのチェックアウトに使用するタグを指定できるようになりました。defaultToolTagtip に設定されており、デフォルトでは go.tools の最新版が使用されます。
    • toolPath 定数として code.google.com/p/go.tools が定義されました。これは go.tools リポジトリのインポートパスです。
  2. covervet の追加:

    • toolPaths という新しい []string スライスが導入され、"code.google.com/p/go.tools/cmd/cover""code.google.com/p/go.tools/cmd/vet" が追加されました。これにより、bindist.go がこれらのツールを配布物に含める対象として認識するようになりました。godoc も引き続きこのリストに含まれています。
  3. godoc() 関数のリファクタリングと tools() への改名:

    • 既存の godoc() 関数が tools() に改名され、その内部ロジックが拡張されました。
    • 新しい tools() 関数は、以下のステップで go.tools の各コマンドを処理します。
      • go get -d: まず、toolPaths にリストされているすべてのツール(cover, godoc, vet)のソースコードをダウンロードしますが、ビルドは行いません (-d フラグ)。これは、後で特定のタグに更新する前にソースコードを取得するためです。
      • hg update: ダウンロード後、go.tools リポジトリのローカルコピー (repoPath) を、-tool フラグで指定されたタグ (*toolTag) に更新します。これにより、配布物に含める go.tools のバージョンを正確に制御できます。
      • go install: 最後に、toolPaths にリストされているすべてのツールを go install コマンドでビルドし、$GOROOT/bin または $GOROOT/pkg/tool にインストールします。これにより、これらのツールがGoのバイナリ配布物に含まれるようになります。
  4. tourPackagestourContent の変更:

    • tourContent から "prog""tour.article" が削除され、代わりに "content" が追加されました。これは、Go Tourのコンテンツ構造の変更に対応するものです。

これらの変更により、Goのバイナリ配布物には go covergo vet が標準で含まれるようになり、配布物生成時に go.tools の特定のバージョンを指定する柔軟性が提供されました。

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

diff --git a/misc/dist/bindist.go b/misc/dist/bindist.go
index ea716ffd6b..c01274d71a 100644
--- a/misc/dist/bindist.go
+++ b/misc/dist/bindist.go
@@ -30,6 +30,7 @@ import (

 var (
 	tag             = flag.String("tag", "release", "mercurial tag to check out")
+	toolTag         = flag.String("tool", defaultToolTag, "go.tools tag to check out")
 	repo            = flag.String("repo", "https://code.google.com/p/go", "repo URL")
 	verbose         = flag.Bool("v", false, "verbose output")
 	upload          = flag.Bool("upload", true, "upload resulting files to Google Code")
@@ -42,11 +43,21 @@ var (
 )

 const (
-	uploadURL = "https://go.googlecode.com/files"
-	godocPath = "code.google.com/p/go.tools/cmd/godoc"
-	tourPath  = "code.google.com/p/go-tour"
+	uploadURL      = "https://go.googlecode.com/files"
+	tourPath       = "code.google.com/p/go-tour"
+	toolPath       = "code.google.com/p/go.tools"
+	defaultToolTag = "tip" // TOOD(adg): set this once Go 1.2 settles
 )

+// Import paths for tool commands.
+// These must be the command that cmd/go knows to install to $GOROOT/bin
+// or $GOROOT/pkg/tool.
+var toolPaths = []string{
+	"code.google.com/p/go.tools/cmd/cover",
+	"code.google.com/p/go.tools/cmd/godoc",
+	"code.google.com/p/go.tools/cmd/vet",
+}
+
 var preBuildCleanFiles = []string{
 	"lib/codereview",
 	"misc/dashboard/godashboard",
@@ -75,12 +86,11 @@ var tourPackages = []string{
 }

 var tourContent = []string{
+	"content",
 	"js",
-	"prog",
 	"solutions",
 	"static",
 	"template",
-	"tour.article",
 }

 // The os-arches that support the race toolchain.
@@ -227,7 +237,7 @@ func (b *Build) Do() error {
 		if err != nil {
 			return err
 		}
-		err = b.godoc()
+		err = b.tools()
 		if err != nil {
 			return err
 		}
@@ -413,7 +423,7 @@ func (b *Build) Do() error {
 	return err
 }

-func (b *Build) godoc() error {
+func (b *Build) tools() error {
 	defer func() {
 		// Clean work files from GOPATH directory.
 		for _, d := range []string{"bin", "pkg", "src"} {
@@ -421,9 +431,23 @@ func (b *Build) godoc() error {
 		}
 	}()

-	// go get the godoc package.
-	// The go tool knows to install to $GOROOT/bin.
-	_, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"), "get", godocPath)
+	// Fetch the tool packages (without building/installing).
+	args := append([]string{"get", "-d"}, toolPaths...)
+	_, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"), args...)
+	if err != nil {
+		return err
+	}
+
+	// Update the repo to the revision specified by -tool.
+	repoPath := filepath.Join(b.gopath, "src", filepath.FromSlash(toolPath))
+	_, err = b.run(repoPath, "hg", "update", *toolTag)
+	if err != nil {
+		return err
+	}
+
+	// Install tools.
+	args = append([]string{"install"}, toolPaths...)
+	_, err = b.run(b.gopath, filepath.Join(b.root, "bin", "go"), args...)
 	return err
 }

コアとなるコードの解説

このコミットの核となる変更は、bindist.go 内の tools() 関数(旧 godoc())と、新しく導入された toolPaths 変数に集約されます。

  • toolPaths 変数:

    var toolPaths = []string{
    	"code.google.com/p/go.tools/cmd/cover",
    	"code.google.com/p/go.tools/cmd/godoc",
    	"code.google.com/p/go.tools/cmd/vet",
    }
    

    このスライスは、Goの配布物に含める go.tools のコマンドのインポートパスを定義しています。以前は godocPath という単一の定数で godoc のパスのみが指定されていましたが、この変更により covervet が追加され、複数のツールを一元的に管理できるようになりました。

  • tools() 関数:

    func (b *Build) tools() error {
    	defer func() {
    		// Clean work files from GOPATH directory.
    		for _, d := range []string{"bin", "pkg", "src"} {
    			os.RemoveAll(filepath.Join(b.gopath, d))
    		}
    	}()
    
    	// Fetch the tool packages (without building/installing).
    	args := append([]string{"get", "-d"}, toolPaths...)
    	_, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"), args...)
    	if err != nil {
    		return err
    	}
    
    	// Update the repo to the revision specified by -tool.
    	repoPath := filepath.Join(b.gopath, "src", filepath.FromSlash(toolPath))
    	_, err = b.run(repoPath, "hg", "update", *toolTag)
    	if err != nil {
    		return err
    	}
    
    	// Install tools.
    	args = append([]string{"install"}, toolPaths...)
    	_, err = b.run(b.gopath, filepath.Join(b.root, "bin", "go"), args...)
    	return err
    }
    

    この関数は、Goの配布物生成プロセスにおいて go.tools の各コマンドをビルドし、インストールする役割を担います。

    1. go get -d: toolPaths に指定されたすべてのツールのソースコードを、ビルドせずにダウンロードします。これは、後続の hg update コマンドで特定のバージョンに切り替えるための準備です。
    2. hg update: ダウンロードされた go.tools リポジトリのローカルコピーを、コマンドラインで -tool フラグによって指定されたタグ(またはデフォルトの tip)に更新します。これにより、配布物に含める go.tools のバージョンを正確に指定できます。
    3. go install: 最後に、更新されたバージョンの go.tools の各コマンドをビルドし、Goの標準ツールディレクトリにインストールします。これにより、これらのツールがGoのバイナリ配布物の一部として提供されるようになります。

この一連の処理により、go covergo vet がGoの標準配布物に組み込まれ、ユーザーはGoをインストールするだけでこれらの重要な開発ツールを利用できるようになりました。

関連リンク

参考にした情報源リンク

  • Go言語公式ドキュメント: go get コマンド, go install コマンド, go vet, go cover
  • Go言語のソースコードリポジトリ (misc/dist/bindist.go の周辺コード)
  • Mercurial (hg) のドキュメント (特に hg update コマンドについて)
  • GoプロジェクトのIssueトラッカー (Issue 6356の議論内容)