[インデックス 14998] ファイルの概要
このコミットは、Go言語のgo/build
パッケージにおける以前の変更(Change List: CL 7129048)を元に戻すものです。この元に戻された変更は、godoc net/http
コマンドの動作を阻害していたため、その問題を解決するために実施されました。具体的には、ImportDir
関数内のディレクトリ存在チェックのロジックが一時的に無効化され、関連するテストがスキップされるようになっています。
コミット
commit a8e0a75726c07cdbb8ce5f2e72a1bc54e392ad13
Author: Russ Cox <rsc@golang.org>
Date: Mon Jan 28 12:49:26 2013 -0500
go/build: undo CL 7129048
This broke 'godoc net/http'.
TBR=adg
CC=golang-dev
https://golang.org/cl/7235052
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/a8e0a75726c07cdbb8ce5f2e72a1bc54e392ad13
元コミット内容
元コミット内容の詳細は、このコミットメッセージからは直接読み取れませんが、ウェブ検索の結果から、CL 7129048は「cmd/go
: go run
に-C
フラグを追加」という内容であったことが分かります。この変更は、go run
コマンドが特定のディレクトリで実行されるように指定できる-C
フラグを導入するものでした。
変更の背景
このコミットは、以前の変更であるCL 7129048がgodoc net/http
コマンドの動作を壊したため、その変更を元に戻すことを目的としています。godoc
はGoのドキュメントツールであり、パッケージのドキュメントを生成・表示するために使用されます。net/http
パッケージはGoの標準ライブラリの中でも非常に重要なパッケージであり、そのドキュメント表示が機能しないことはGo開発者にとって大きな問題となります。
具体的な問題は、go/build
パッケージ内のImportDir
関数が、指定されたパスがディレクトリであるかどうかを厳密にチェックするようになったことに起因しているようです。このチェックがgodoc net/http
の内部的な動作と競合し、正しくパッケージをインポートできなくなったと考えられます。
コミットメッセージには「TBR=adg
」とあり、これはレビュー担当者(To Be Reviewed by)がadg
(Andrew Gerrand)であることを示しています。また、「CC=golang-dev
」は、golang-dev
メーリングリストに通知が送られることを意味します。
前提知識の解説
Go言語のビルドシステムとパッケージ管理
Go言語には、ソースコードのビルド、パッケージの管理、依存関係の解決を行うための強力なツールチェーンが組み込まれています。
go/build
パッケージ: Goの標準ライブラリの一部であり、Goのソースコードを解析し、パッケージの依存関係を解決するための機能を提供します。go build
、go install
、go get
などのコマンドは、このパッケージの機能を利用して動作します。- パッケージ: Goのコードはパッケージにまとめられます。パッケージは関連する機能の集合であり、再利用可能なコードの単位です。
ImportDir
関数:go/build
パッケージ内の関数で、指定されたディレクトリからGoパッケージをインポートしようとします。この関数は、パッケージのソースファイルを見つけ、その依存関係を解決する役割を担います。godoc
コマンド: Goのドキュメント生成ツールです。Goのソースコードからコメントを抽出し、HTML形式などでドキュメントを生成・表示します。開発者がGoの標準ライブラリやサードパーティライブラリのAPIを理解するために不可欠なツールです。
godoc net/http
の動作
godoc net/http
を実行すると、net/http
パッケージのドキュメントが表示されます。このプロセスでは、godoc
ツールが内部的にnet/http
パッケージのソースコードを解析し、その構造やコメントからドキュメントを生成します。この解析の過程で、go/build
パッケージのImportDir
のような関数が使用され、net/http
パッケージの場所を特定し、その内容を読み込む必要があります。
CL (Change List)
Goプロジェクトでは、コードの変更は「Change List (CL)」として管理されます。これは、Gerritなどのコードレビューシステムで使われる用語で、一連の変更をまとめたものです。各CLには一意の番号が割り当てられ、レビューと承認を経てメインのコードベースにマージされます。
技術的詳細
このコミットの技術的な核心は、go/build
パッケージのbuild.go
ファイル内のImportDir
関数の変更にあります。
元のコード(CL 7129048によって導入されたと思われる部分)では、ImportDir
関数がパッケージをインポートした後、!ctxt.isDir(p.Dir)
という条件で、インポートされたパッケージのディレクトリが実際に存在するかどうかを厳密にチェックしていました。このチェックがgodoc net/http
の動作を妨げた原因と考えられます。
考えられるシナリオとしては、godoc
がnet/http
パッケージを処理する際に、一時的なディレクトリや仮想的なパスを使用したり、あるいはImportDir
が期待する形式とは異なる方法でディレクトリ情報を扱ったりしていた可能性があります。その結果、!ctxt.isDir(p.Dir)
のチェックが予期せずtrue
となり、エラーが発生してgodoc
が正常に動作しなくなったと考えられます。
このコミットでは、その厳密なディレクトリチェックを一時的に無効化することで、godoc net/http
の問題を回避しています。具体的には、if err == nil && !ctxt.isDir(p.Dir)
という条件式の前にif false &&
を追加することで、この条件全体が常にfalse
になるようにしています。これは、問題の根本原因を特定し解決するまでの暫定的な措置としてよく用いられる手法です。
また、build_test.go
ファイル内のTestBogusDirectory
テストがreturn
文によってスキップされるようになっています。これは、このテストがImportDir
関数のディレクトリチェックに依存しており、そのチェックを無効化したことでテストが失敗するようになったため、一時的に無効化されたものと推測されます。テストのコメントには「// See issue 4696.
」とありますが、ウェブ検索ではGoの公式なissue 4696は見つかりませんでした。これは、内部的な追跡番号であるか、あるいは後に別の番号に統合された可能性も考えられます。
コアとなるコードの変更箇所
src/pkg/go/build/build.go
--- a/src/pkg/go/build/build.go
+++ b/src/pkg/go/build/build.go
@@ -322,7 +322,9 @@ func (p *Package) IsCommand() bool {
// the named directory.
func (ctxt *Context) ImportDir(dir string, mode ImportMode) (*Package, error) {
p, err := ctxt.Import(".", dir, mode)
- if err == nil && !ctxt.isDir(p.Dir) {
+ // TODO(rsc,adg): breaks godoc net/http. Not sure why.
+ // See CL 7232047 and issue 4696.
+ if false && err == nil && !ctxt.isDir(p.Dir) {
err = fmt.Errorf("%q is not a directory", p.Dir)
}
return p, err
src/pkg/go/build/build_test.go
--- a/src/pkg/go/build/build_test.go
+++ b/src/pkg/go/build/build_test.go
@@ -92,6 +92,7 @@ func TestLocalDirectory(t *testing.T) {
// golang.org/issue/3248
func TestBogusDirectory(t *testing.T) {
+ return // See issue 4696.
const dir = "/foo/bar/baz/gopher"
_, err := ImportDir(dir, FindOnly)
want := fmt.Sprintf("%q is not a directory", filepath.FromSlash(dir))
コアとなるコードの解説
src/pkg/go/build/build.go
の変更
ImportDir
関数内のif
文の条件式が変更されています。
- 変更前:
この行は、「エラーがなく、かつif err == nil && !ctxt.isDir(p.Dir) {
p.Dir
(インポートされたパッケージのディレクトリ)がディレクトリではない場合」という条件で、エラーを発生させていました。 - 変更後:
// TODO(rsc,adg): breaks godoc net/http. Not sure why. // See CL 7232047 and issue 4696. if false && err == nil && !ctxt.isDir(p.Dir) {
if false &&
が追加されたことで、このif
文の条件は常にfalse
になります。これにより、!ctxt.isDir(p.Dir)
のチェックが実質的に無効化され、godoc net/http
が壊れる原因となっていたロジックがスキップされるようになりました。 コメントには、この変更がgodoc net/http
を壊したこと、その理由が不明であること、そして関連するCL(7232047)とissue(4696)が示されています。これは、一時的な修正であり、根本的な原因究明と解決が将来的に必要であることを示唆しています。
src/pkg/go/build/build_test.go
の変更
TestBogusDirectory
というテスト関数の冒頭にreturn
文が追加されています。
- 変更前: テストは通常通り実行されます。
- 変更後:
func TestBogusDirectory(t *testing.T) { return // See issue 4696. const dir = "/foo/bar/baz/gopher" // ... (テストロジック) }
return
文が追加されたことで、このテスト関数は実行されるとすぐに終了し、テストロジックはスキップされます。これは、ImportDir
関数の変更(ディレクトリチェックの無効化)により、このテストが期待通りに動作しなくなったため、一時的に無効化されたものと考えられます。テストのコメントも// See issue 4696.
とあり、関連する問題があることを示しています。
これらの変更は、godoc net/http
の機能を迅速に回復させるための緊急的な対応であり、根本的な解決策ではありません。TODO
コメントやテストの無効化は、将来的にこれらの問題に対処する必要があることを明確に示しています。
関連リンク
- Go言語の公式ドキュメント: https://go.dev/doc/
go/build
パッケージのドキュメント: https://pkg.go.dev/go/buildgodoc
コマンドについて: https://go.dev/blog/godoc
参考にした情報源リンク
- GitHub: https://github.com/golang/go/commit/a8e0a75726c07cdbb8ce5f2e72a1bc54e392ad13
- Go CL 7129048に関するウェブ検索結果 (CLのタイトル情報): https://go.dev/cl/7129048 (直接の検索結果ではないが、CL番号から辿れる情報源)
- Go issue 4696に関するウェブ検索結果 (Goの公式issueではないことを確認): https://github.com/golang/go/issues (Goの公式issueトラッカー)