[インデックス 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
参考にした情報源リンク
godoctool: https://pkg.go.dev/golang.org/x/tools/cmd/godoc- Go
text/templatepackage: https://pkg.go.dev/text/template - Go
ospackage (for file system operations): https://pkg.go.dev/os - Go
tokenpackage (for Go source code parsing): https://pkg.go.dev/go/token - Go
parserpackage (for Go source code parsing): https://pkg.go.dev/go/parser