[インデックス 12233] ファイルの概要
このコミットは、Go言語のドキュメンテーションツールであるgodoc
の表示挙動に関する改善です。具体的には、godoc
が「フラットディレクトリモード」で動作している際に、Goパッケージファイルを含まないディレクトリを表示しないようにする変更が加えられました。これにより、ユーザーインターフェースの視認性が向上し、不要な情報が排除されます。
コミット
commit ab169c6e3f3acfdf9e9176968825d398820f40f1
Author: Robert Griesemer <gri@golang.org>
Date: Mon Feb 27 11:18:00 2012 -0800
godoc: don't show directories w/o packages in flat dir mode
The main change is simple: Both the Directory and DirEntry
struct have an extra field 'HasPkg' indicating whether the
directory contains any package files. The remaining changes
are more comments and adjustments to the template files.
Fixes #3121.
R=golang-dev, bradfitz, sameer
CC=golang-dev
https://golang.org/cl/5699072
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/ab169c6e3f3acfdf9e9176968825d398820f40f1
元コミット内容
godoc
: フラットディレクトリモードでパッケージのないディレクトリを表示しない。
主な変更はシンプルです。Directory
とDirEntry
の両方の構造体に、ディレクトリがパッケージファイルを含んでいるかどうかを示す追加フィールドHasPkg
が追加されました。残りの変更は、コメントの追加とテンプレートファイルの調整です。
Issue #3121 を修正します。
変更の背景
godoc
はGo言語のソースコードからドキュメンテーションを生成し、Webインターフェースを通じて提供するツールです。このツールには、パッケージのリストを階層的に表示する通常のモードと、すべてのパッケージをフラットなリストとして表示する「フラットディレクトリモード」(URLに?m=flat
を追加することで有効化)があります。
以前のgodoc
のフラットディレクトリモードでは、Goパッケージファイル(.go
ファイル)を含まないディレクトリであっても、ディレクトリ構造の一部として表示されていました。これは、特に大規模なプロジェクトや、Goパッケージ以外のファイル(例えば、ドキュメント、テストデータ、ビルドスクリプトなど)のみを含むディレクトリが多い場合に、表示が煩雑になり、ユーザーが目的のパッケージを見つけにくくなるという問題がありました。
この問題は、GoのIssueトラッカーで「Issue #3121: godoc: in flat mode, don't display empty parent directories」として報告されていました。このコミットは、このユーザーエクスペリエンスの課題を解決し、godoc
のフラットディレクトリモードの有用性を高めることを目的としています。
前提知識の解説
godoc
: Go言語の公式ドキュメンテーションツール。Goのソースコードからコメントや宣言を解析し、HTML形式などでドキュメントを生成します。また、HTTPサーバーとして動作し、ブラウザからドキュメントを閲覧することも可能です。- フラットディレクトリモード (
?m=flat
):godoc
のWebインターフェースで、URLに?m=flat
クエリパラメータを追加することで有効になる表示モードです。このモードでは、パッケージの階層構造を無視し、すべてのパッケージをそのフルパスでフラットなリストとして表示します。 - Goパッケージ: Go言語のコードはパッケージにまとめられます。通常、一つのディレクトリが一つのパッケージに対応し、そのディレクトリ内の
.go
ファイルがそのパッケージの一部となります。 - HTMLテンプレート (
text/template
パッケージ): Go言語には、HTMLやテキストを動的に生成するためのテンプレートエンジンが標準で提供されています。godoc
のWebインターフェースも、これらのテンプレートファイル(例:package.html
,package.txt
)を使用して動的にコンテンツを生成しています。 - 構造体 (
struct
): Go言語におけるユーザー定義型の一つで、異なる型のフィールド(プロパティ)をまとめることができます。このコミットでは、Directory
とDirEntry
という構造体が変更されています。Directory
: ディレクトリツリーのノードを表す構造体で、サブディレクトリやパッケージ情報を含みます。DirEntry
: ディレクトリリストのエントリを表す構造体で、ディレクトリのパス、名前、概要などを保持します。
技術的詳細
この変更の核心は、ディレクトリがGoパッケージファイルを含んでいるかどうかを識別するための新しいフィールドHasPkg
を導入することです。
HasPkg
フィールドの追加:src/cmd/godoc/dirtrees.go
内のDirectory
構造体とDirEntry
構造体にHasPkg bool
フィールドが追加されました。このフィールドは、そのディレクトリが少なくとも1つのGoパッケージファイル(.go
ファイル)を含んでいる場合にtrue
となります。
HasPkg
の計算:src/cmd/godoc/dirtrees.go
内のnewDirTree
関数(ディレクトリツリーを構築する関数)において、ディレクトリ内のファイルをスキャンする際に、Goファイルが見つかった場合にhasPkgFiles
という内部変数をtrue
に設定し、最終的にDirectory
構造体のHasPkg
フィールドにその値を割り当てます。
- テンプレートの条件分岐:
lib/godoc/package.html
とlib/godoc/package.txt
というHTML/テキストテンプレートファイルが修正されました。これらのテンプレートでは、{{if $.DirFlat}}
(フラットディレクトリモードの場合)という条件分岐の中に、さらに{{if .HasPkg}}
という条件を追加しています。- これにより、フラットディレクトリモードでパッケージリストを生成する際に、
HasPkg
がtrue
のDirEntry
(つまり、Goパッケージを含むディレクトリ)のみが表示されるようになります。HasPkg
がfalse
のディレクトリはスキップされ、表示されません。
- 親ディレクトリへのリンクの表示制御:
package.html
では、フラットディレクトリモードの場合に「..」(親ディレクトリへのリンク)が表示されないようにする変更も含まれています。これは、フラットモードでは階層構造が意味を持たないため、不要なナビゲーション要素を排除するためです。
この変更により、godoc
はフラットディレクトリモードでよりクリーンで関連性の高いパッケージリストを提供できるようになりました。
コアとなるコードの変更箇所
src/cmd/godoc/dirtrees.go
Directory
構造体とDirEntry
構造体にHasPkg
フィールドが追加されました。
newDirTree
関数内で、ディレクトリがGoパッケージファイルを含むかどうかの判定ロジックが追加され、その結果がDirectory
構造体のHasPkg
フィールドに設定されます。
DirEntry
の生成時にも、対応するDirectory
のHasPkg
値がコピーされるようになりました。
// Directory struct definition
type Directory struct {
Depth int
Path string // directory path; includes Name
Name string // directory name
HasPkg bool // true if the directory contains at least one package
Synopsis string // package documentation, if any
Dirs []*Directory // subdirectories
}
// DirEntry struct definition
type DirEntry struct {
Depth int // >= 0
Height int // = DirList.MaxHeight - Depth, > 0
Path string // directory path; includes Name, relative to DirList root
Name string // directory name
HasPkg bool // true if the directory contains at least one package
Synopsis string // package documentation, if any
}
// Inside newDirTree function, where Directory is created:
// ...
return &Directory{
Depth: depth,
Path: path,
Name: name,
HasPkg: hasPkgFiles, // This line is new/modified
Synopsis: synopsis,
Dirs: dirs,
}
// ...
// Inside listing function, where DirEntry is created:
// ...
p.Path = path
p.Name = d.Name
p.HasPkg = d.HasPkg // This line is new/modified
p.Synopsis = d.Synopsis
// ...
lib/godoc/package.html
フラットディレクトリモード ($.DirFlat
) の場合に、HasPkg
がtrue
のディレクトリのみを表示するように条件が追加されました。また、親ディレクトリへのリンク (..
) の表示もフラットモードでは抑制されます。
<!-- Original: -->
<!--
<tr>
<td><a href="..">..</a></td>
</tr>
-->
<!-- New: -->
{{if not $.DirFlat}}
<tr>
<td><a href="..">..</a></td>
</tr>
{{end}}
<!-- Original: -->
<!--
{{range .List}}
<tr>
<td>
{{if $.DirFlat}}
<a href="{{html .Path}}">{{html .Path}}</a>
{{else}}
{{repeat ` ` .Depth}}<a href="{{html .Path}}">{{html .Name}}</a>
{{end}}
</td>
<td> </td>
<td style="width: auto">{{html .Synopsis}}</td>
</tr>
{{end}}
-->
<!-- New: -->
{{range .List}}
{{if $.DirFlat}}
{{if .HasPkg}}
<tr>
<td><a href="{{html .Path}}">{{html .Path}}</a></td>
<td> </td>
<td style="width: auto">{{html .Synopsis}}</td>
</tr>
{{end}}
{{else}}
<tr>
<td>{{repeat ` ` .Depth}}<a href=\"{{html .Path}}\">{{html .Name}}</a></td>
<td> </td>
<td style="width: auto">{{html .Synopsis}}</td>
</tr>
{{end}}
{{end}}
lib/godoc/package.txt
テキスト形式のパッケージリストでも、フラットディレクトリモード ($.DirFlat
) の場合にHasPkg
がtrue
のディレクトリのみを表示するように条件が追加されました。
<!-- Original: -->
<!--
{{if $.DirFlat}}{{range .List}}
{{.Path}}{{end}}
-->
<!-- New: -->
{{if $.DirFlat}}{{range .List}}{{if .HasPkg}}
{{.Path}}{{end}}{{end}}
コアとなるコードの解説
このコミットの主要な変更は、godoc
がディレクトリ情報を扱う方法に新しいセマンティクスを追加した点です。
- データ構造の拡張:
Directory
とDirEntry
という、ディレクトリのメタデータを保持するGoの構造体にHasPkg
というブーリアン型のフィールドが追加されました。これは、そのディレクトリがGoのパッケージファイル(.go
拡張子を持つファイル)を一つでも含んでいるかどうかを示すフラグです。 - 情報収集ロジックの追加:
src/cmd/godoc/dirtrees.go
内のnewDirTree
関数は、ファイルシステムを走査してディレクトリツリーを構築する役割を担っています。この関数内で、各ディレクトリを処理する際に、そのディレクトリ内にGoファイルが存在するかどうかをチェックし、その結果を新しく追加されたHasPkg
フィールドに設定するように変更されました。これにより、ディレクトリが「空の」ディレクトリ(Goパッケージの観点から見て)であるかどうかの情報が、ツリー構築時に正確に記録されるようになります。 - プレゼンテーションロジックの変更:
lib/godoc/package.html
とlib/godoc/package.txt
は、godoc
のWebインターフェースでパッケージリストを表示するためのテンプレートファイルです。これらのテンプレートはGoのtext/template
パッケージの構文を使用しており、データ(この場合はDirectory
やDirEntry
のリスト)を元に動的にHTMLやテキストを生成します。- 変更点として、フラットディレクトリモード (
$.DirFlat
がtrue
の場合) でパッケージリストをレンダリングする際に、{{if .HasPkg}}
という条件文が追加されました。これは、「もし現在のDirEntry
がGoパッケージを含んでいるならば、そのエントリを表示する」という意味になります。 - この条件により、
HasPkg
がfalse
のディレクトリ(つまり、Goパッケージを含まないディレクトリ)は、フラットディレクトリモードでは完全にスキップされ、ユーザーインターフェースに表示されなくなります。 - また、フラットモードでは階層構造の概念がなくなるため、親ディレクトリへのリンク (
..
) も不要となり、package.html
からその表示が抑制されました。
- 変更点として、フラットディレクトリモード (
これらの変更により、godoc
のフラットディレクトリモードは、Goパッケージを含むディレクトリのみをリストアップするようになり、ユーザーはより関連性の高い情報に集中できるようになりました。これは、特に多数のディレクトリが存在する大規模なGoプロジェクトにおいて、ドキュメンテーションのナビゲーションを大幅に改善するものです。
関連リンク
- Go Issue #3121: https://github.com/golang/go/issues/3121
- Go Code Review: https://golang.org/cl/5699072
参考にした情報源リンク
godoc
tool: https://pkg.go.dev/golang.org/x/tools/cmd/godoc- Go
text/template
package: https://pkg.go.dev/text/template - Go
os
package (for file system operations): https://pkg.go.dev/os - Go
token
package (for Go source code parsing): https://pkg.go.dev/go/token - Go
parser
package (for Go source code parsing): https://pkg.go.dev/go/parser