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

[インデックス 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: フラットディレクトリモードでパッケージのないディレクトリを表示しない。

主な変更はシンプルです。DirectoryDirEntryの両方の構造体に、ディレクトリがパッケージファイルを含んでいるかどうかを示す追加フィールド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言語におけるユーザー定義型の一つで、異なる型のフィールド(プロパティ)をまとめることができます。このコミットでは、DirectoryDirEntryという構造体が変更されています。
    • Directory: ディレクトリツリーのノードを表す構造体で、サブディレクトリやパッケージ情報を含みます。
    • DirEntry: ディレクトリリストのエントリを表す構造体で、ディレクトリのパス、名前、概要などを保持します。

技術的詳細

この変更の核心は、ディレクトリがGoパッケージファイルを含んでいるかどうかを識別するための新しいフィールドHasPkgを導入することです。

  1. HasPkgフィールドの追加:
    • src/cmd/godoc/dirtrees.go内のDirectory構造体とDirEntry構造体にHasPkg boolフィールドが追加されました。このフィールドは、そのディレクトリが少なくとも1つのGoパッケージファイル(.goファイル)を含んでいる場合にtrueとなります。
  2. HasPkgの計算:
    • src/cmd/godoc/dirtrees.go内のnewDirTree関数(ディレクトリツリーを構築する関数)において、ディレクトリ内のファイルをスキャンする際に、Goファイルが見つかった場合にhasPkgFilesという内部変数をtrueに設定し、最終的にDirectory構造体のHasPkgフィールドにその値を割り当てます。
  3. テンプレートの条件分岐:
    • lib/godoc/package.htmllib/godoc/package.txtというHTML/テキストテンプレートファイルが修正されました。これらのテンプレートでは、{{if $.DirFlat}}(フラットディレクトリモードの場合)という条件分岐の中に、さらに{{if .HasPkg}}という条件を追加しています。
    • これにより、フラットディレクトリモードでパッケージリストを生成する際に、HasPkgtrueDirEntry(つまり、Goパッケージを含むディレクトリ)のみが表示されるようになります。HasPkgfalseのディレクトリはスキップされ、表示されません。
  4. 親ディレクトリへのリンクの表示制御:
    • package.htmlでは、フラットディレクトリモードの場合に「..」(親ディレクトリへのリンク)が表示されないようにする変更も含まれています。これは、フラットモードでは階層構造が意味を持たないため、不要なナビゲーション要素を排除するためです。

この変更により、godocはフラットディレクトリモードでよりクリーンで関連性の高いパッケージリストを提供できるようになりました。

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

src/cmd/godoc/dirtrees.go

Directory構造体とDirEntry構造体にHasPkgフィールドが追加されました。 newDirTree関数内で、ディレクトリがGoパッケージファイルを含むかどうかの判定ロジックが追加され、その結果がDirectory構造体のHasPkgフィールドに設定されます。 DirEntryの生成時にも、対応するDirectoryHasPkg値がコピーされるようになりました。

// 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) の場合に、HasPkgtrueのディレクトリのみを表示するように条件が追加されました。また、親ディレクトリへのリンク (..) の表示もフラットモードでは抑制されます。

<!-- 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 `&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;` .Depth}}<a href="{{html .Path}}">{{html .Name}}</a>
		{{end}}
		</td>
		<td>&nbsp;&nbsp;&nbsp;&nbsp;</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>&nbsp;&nbsp;&nbsp;&nbsp;</td>
				<td style="width: auto">{{html .Synopsis}}</td>
				</tr>
			{{end}}
		{{else}}
			<tr>
			<td>{{repeat `&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;` .Depth}}<a href=\"{{html .Path}}\">{{html .Name}}</a></td>
			<td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
			<td style="width: auto">{{html .Synopsis}}</td>
			</tr>
		{{end}}
	{{end}}

lib/godoc/package.txt

テキスト形式のパッケージリストでも、フラットディレクトリモード ($.DirFlat) の場合にHasPkgtrueのディレクトリのみを表示するように条件が追加されました。

<!-- Original: -->
<!--
{{if $.DirFlat}}{{range .List}}
	{{.Path}}{{end}}
-->
<!-- New: -->
{{if $.DirFlat}}{{range .List}}{{if .HasPkg}}
	{{.Path}}{{end}}{{end}}

コアとなるコードの解説

このコミットの主要な変更は、godocがディレクトリ情報を扱う方法に新しいセマンティクスを追加した点です。

  1. データ構造の拡張: DirectoryDirEntryという、ディレクトリのメタデータを保持するGoの構造体にHasPkgというブーリアン型のフィールドが追加されました。これは、そのディレクトリがGoのパッケージファイル(.go拡張子を持つファイル)を一つでも含んでいるかどうかを示すフラグです。
  2. 情報収集ロジックの追加: src/cmd/godoc/dirtrees.go内のnewDirTree関数は、ファイルシステムを走査してディレクトリツリーを構築する役割を担っています。この関数内で、各ディレクトリを処理する際に、そのディレクトリ内にGoファイルが存在するかどうかをチェックし、その結果を新しく追加されたHasPkgフィールドに設定するように変更されました。これにより、ディレクトリが「空の」ディレクトリ(Goパッケージの観点から見て)であるかどうかの情報が、ツリー構築時に正確に記録されるようになります。
  3. プレゼンテーションロジックの変更: lib/godoc/package.htmllib/godoc/package.txtは、godocのWebインターフェースでパッケージリストを表示するためのテンプレートファイルです。これらのテンプレートはGoのtext/templateパッケージの構文を使用しており、データ(この場合はDirectoryDirEntryのリスト)を元に動的にHTMLやテキストを生成します。
    • 変更点として、フラットディレクトリモード ($.DirFlattrueの場合) でパッケージリストをレンダリングする際に、{{if .HasPkg}}という条件文が追加されました。これは、「もし現在のDirEntryがGoパッケージを含んでいるならば、そのエントリを表示する」という意味になります。
    • この条件により、HasPkgfalseのディレクトリ(つまり、Goパッケージを含まないディレクトリ)は、フラットディレクトリモードでは完全にスキップされ、ユーザーインターフェースに表示されなくなります。
    • また、フラットモードでは階層構造の概念がなくなるため、親ディレクトリへのリンク (..) も不要となり、package.htmlからその表示が抑制されました。

これらの変更により、godocのフラットディレクトリモードは、Goパッケージを含むディレクトリのみをリストアップするようになり、ユーザーはより関連性の高い情報に集中できるようになりました。これは、特に多数のディレクトリが存在する大規模なGoプロジェクトにおいて、ドキュメンテーションのナビゲーションを大幅に改善するものです。

関連リンク

参考にした情報源リンク