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

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

このコミットは、Go言語のディストリビューションビルドプロセスに関連するファイルである misc/dist/bindist.go に変更を加えています。bindist.go は、Goのバイナリディストリビューションを構築する際に、様々なツールやライブラリを適切に配置するためのロジックを含んでいます。具体的には、godoc ツールに関する処理が修正されています。

コミット

commit b1d64f20f29be25b037e814795ef590ea61af662
Author: Andrew Gerrand <adg@golang.org>
Date:   Fri Aug 16 13:14:13 2013 +1000

    misc/dist: don't copy godoc templates to lib/godoc
    
    They're baked into the godoc binary now.
    
    R=golang-dev, alex.brainman
    CC=golang-dev
    https://golang.org/cl/12751047

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

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

元コミット内容

diff --git a/misc/dist/bindist.go b/misc/dist/bindist.go
index 754bd280c2..5bb3c8be13 100644
--- a/misc/dist/bindist.go
+++ b/misc/dist/bindist.go
@@ -424,15 +424,7 @@ 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)
-	if err != nil {
-		return err
-	}
-
-	// Copy templates from go.tools/cmd/godoc/template to GOROOT/lib/godoc.
-	return cpDir(
-		filepath.Join(b.root, "lib", "godoc"),
-		filepath.Join(b.gopath, "src", filepath.FromSlash(godocPath), "template"),
-	)
+	return err
 }
 
 func (b *Build) tour() error {

変更の背景

このコミットの背景には、godoc ツールがそのHTMLテンプレートファイルをどのように管理するかという変更があります。以前の godoc は、実行時に外部のテンプレートファイル(GOROOT/lib/godoc にコピーされる)を読み込んでいました。しかし、この方式にはいくつかの問題がありました。

  1. デプロイの複雑さ: godoc バイナリだけでなく、関連するテンプレートファイルも一緒にデプロイする必要がありました。これにより、配布やインストールのプロセスが複雑になります。
  2. 実行時の依存性: godoc が正しく機能するためには、テンプレートファイルが特定のパスに存在している必要がありました。ファイルが見つからない場合、godoc はエラーになる可能性がありました。実際に、2013年8月頃には、godoc がテンプレートを見つけられないという問題が報告されていました(GitHub Issue #6010)。
  3. 一貫性の欠如: Goのツールは自己完結型であることが望ましいという設計思想があります。外部ファイルに依存することは、この思想に反する側面がありました。

これらの問題を解決するため、godoc のテンプレートがバイナリ自体に埋め込まれる("baked into")ように変更されました。これにより、godoc は単一のバイナリとして配布・実行できるようになり、外部ファイルへの依存がなくなりました。このコミットは、Goのビルドプロセスにおいて、もはやテンプレートファイルを GOROOT/lib/godoc にコピーする必要がなくなったことを反映しています。

前提知識の解説

Go言語のビルドシステムと GOROOT/GOPATH

Go言語のビルドシステムは、go コマンドを中心としています。

  • GOROOT: GoのSDKがインストールされているディレクトリを指します。標準ライブラリのソースコードや、go コマンド自体を含むツール群がここに配置されます。
  • GOPATH: Goのワークスペースを指します。ユーザーが開発するGoプロジェクトのソースコード、コンパイルされたバイナリ、ダウンロードされたサードパーティのパッケージなどが配置されます。go get コマンドで取得されたパッケージは、通常 $GOPATH/src 以下に配置されます。

godoc ツール

godoc はGo言語の公式ドキュメンテーションツールです。Goのソースコードからコメントやシグネチャを解析し、HTML形式でドキュメントを生成・表示するWebサーバー機能を提供します。開発者は godoc -http=:6060 のように実行することで、ローカルでGoのドキュメントを閲覧できます。

テンプレートの埋め込み(Asset Embedding)

ソフトウェア開発において、HTMLテンプレート、CSSファイル、JavaScriptファイル、画像などの静的アセットをアプリケーションのバイナリに直接含める手法を「アセットの埋め込み」と呼びます。これにより、アプリケーションの配布が単一のファイルで完結し、デプロイが容易になる、実行時のファイルパスの問題が解消される、などのメリットがあります。

Go言語では、Go 1.16で標準ライブラリに embed パッケージが導入されるまでは、アセットをバイナリに埋め込むための標準的なメカニズムはありませんでした。そのため、サードパーティのツール(例: go-bindata)を使用するか、手動でファイルをGoのソースコードに変換する(例: xxd コマンドでバイナリをバイト配列に変換し、Goのソースコードとして埋め込む)といった方法が取られていました。このコミットが行われた2013年時点では、embed パッケージは存在せず、godoc 内部で何らかのカスタムな方法でテンプレートが埋め込まれるように変更されたと考えられます。

技術的詳細

このコミットは、misc/dist/bindist.go 内の (*Build).godoc() メソッドの変更です。このメソッドは、Goのディストリビューションビルドプロセスの一部として godoc ツールをビルドし、配置する役割を担っています。

変更前は、godoc パッケージを go get で取得した後、以下の2つのステップを実行していました。

  1. go get コマンドで godoc パッケージ(golang.org/x/tools/cmd/godoc に相当)を取得し、$GOROOT/bin にバイナリをインストールします。
  2. cpDir 関数を呼び出し、godoc パッケージのソースディレクトリ内にある template ディレクトリ($GOPATH/src/golang.org/x/tools/cmd/godoc/template)から、テンプレートファイルを $GOROOT/lib/godoc へコピーしていました。

このコミットにより、2番目のテンプレートファイルのコピー処理が完全に削除されました。これは、コミットメッセージにある通り「They're baked into the godoc binary now.(それらは今や godoc バイナリに埋め込まれている)」ためです。つまり、godoc バイナリ自体が、実行に必要なすべてのテンプレートデータを含んでいるため、外部からテンプレートファイルをコピーする必要がなくなったのです。

この変更は、Goのビルドシステムにおける godoc の依存関係を簡素化し、godoc の配布と実行をより堅牢にするための重要なステップでした。これにより、godoc は単一の実行ファイルとして機能し、外部のテンプレートファイルが見つからないことによるエラーのリスクがなくなりました。

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

変更は misc/dist/bindist.go ファイルの func (b *Build) godoc() error 関数内で行われています。

具体的には、以下の9行が削除され、1行が追加されています。

削除された行:

	if err != nil {
		return err
	}

	// Copy templates from go.tools/cmd/godoc/template to GOROOT/lib/godoc.
	return cpDir(
		filepath.Join(b.root, "lib", "godoc"),
		filepath.Join(b.gopath, "src", filepath.FromSlash(godocPath), "template"),
	)

追加された行:

	return err

コアとなるコードの解説

変更前のコードでは、go get コマンドの実行後にエラーチェックを行い、エラーがなければ cpDir 関数を呼び出してテンプレートディレクトリをコピーしていました。cpDir 関数は、指定されたソースディレクトリの内容をターゲットディレクトリに再帰的にコピーするユーティリティ関数です。

変更後のコードでは、go get コマンドの実行結果である err をそのまま返しています。これにより、go get が成功した場合には nil が返され、失敗した場合にはそのエラーが伝播されます。テンプレートファイルのコピー処理は完全に削除されており、godoc バイナリが自己完結型になったことを明確に示しています。

この変更は、godoc のビルドとデプロイのプロセスを大幅に簡素化しました。ビルドスクリプトは、godoc バイナリを生成するだけでよくなり、追加のファイルコピー操作は不要になりました。これは、Goのツールがよりポータブルで、依存関係が少ない設計へと進化していることを示しています。

関連リンク

参考にした情報源リンク