[インデックス 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
にコピーされる)を読み込んでいました。しかし、この方式にはいくつかの問題がありました。
- デプロイの複雑さ:
godoc
バイナリだけでなく、関連するテンプレートファイルも一緒にデプロイする必要がありました。これにより、配布やインストールのプロセスが複雑になります。 - 実行時の依存性:
godoc
が正しく機能するためには、テンプレートファイルが特定のパスに存在している必要がありました。ファイルが見つからない場合、godoc
はエラーになる可能性がありました。実際に、2013年8月頃には、godoc
がテンプレートを見つけられないという問題が報告されていました(GitHub Issue #6010)。 - 一貫性の欠如: 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つのステップを実行していました。
go get
コマンドでgodoc
パッケージ(golang.org/x/tools/cmd/godoc
に相当)を取得し、$GOROOT/bin
にバイナリをインストールします。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のツールがよりポータブルで、依存関係が少ない設計へと進化していることを示しています。
関連リンク
- https://golang.org/cl/12751047 (このコミットに対応するGoのコードレビューシステム上のチェンジリスト)
参考にした情報源リンク
- Go Issue #6010: cmd/godoc: godoc fails to find templates
- Stack Overflow: How to embed static files in Go in 2013
- Go 1.16
embed
package documentation (直接このコミットの時点での情報ではないが、Goにおけるアセット埋め込みの標準的な方法として参考)