[インデックス 15437] ファイルの概要
このコミットは、Go言語の公式ドキュメンテーションツールであるgodoc
において、ソースコード内の特定のコメント(通称「Notes」)の表示方法を改善し、より汎用的な仕組みに移行するものです。具体的には、これまでPackage.Bugs
フィールドで特別に扱われていたBUG
コメントを、より一般的なPackage.Notes
フィールドに統合し、TODO
やSECBUG
といった他の種類のNotesもgodoc
で表示できるように拡張しています。
コミット
commit d6a057c90ed0746ae394efc0345b53f97d781b64
Author: Cosmos Nicolaou <cnicolaou@google.com>
Date: Mon Feb 25 20:34:09 2013 -0800
cmd/godoc: add support for display Notes parsed by pkg/go/doc
pkg/go/doc: move BUG notes from Package.Bugs to the general Package.Notes field.
Removing .Bugs would break existing code so it's left in for now.
R=gri, gri, gary.burd, dsymonds, rsc, kevlar
CC=golang-dev
https://golang.org/cl/7341053
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/d6a057c90ed0746ae394efc0345b53f97d781b64
元コミット内容
cmd/godoc
: pkg/go/doc
によってパースされたNotesの表示をサポート
pkg/go/doc
: BUG
ノートをPackage.Bugs
から一般的なPackage.Notes
フィールドに移動。
.Bugs
を削除すると既存のコードが壊れるため、当面は残しておく。
変更の背景
Go言語のソースコードでは、開発者がコードに関する特定の情報やタスクをコメントとして残す慣習があります。これらは通常、BUG(userid):
、TODO(userid):
、FIXME(userid):
、SECBUG(userid):
といった特定のマーカーで始まります。これらは「Notes」と呼ばれ、コードの改善点、未解決の問題、セキュリティ上の懸念などを開発者に伝えるために使用されます。
このコミット以前は、godoc
ツールはBUG
コメントのみを特別に扱い、pkg/go/doc
パッケージのPackage
構造体内のBugs
フィールドに格納していました。しかし、他の種類のNotes(TODO
、SECBUG
など)はgodoc
の出力に表示されず、開発者がこれらの重要な情報を見落とす可能性がありました。
この変更の背景には、以下の目的があります。
- 汎用性の向上:
BUG
コメントだけでなく、あらゆる種類のNotesをgodoc
で表示できるようにすることで、ドキュメンテーションの網羅性を高める。 - 情報の可視化: 開発者がコードベース全体に散らばる
TODO
やSECBUG
などの重要なNotesを、godoc
を通じて一元的に確認できるようにする。 - コードとドキュメントの一貫性: ソースコード内のNotesが、生成されるドキュメントにも適切に反映されるようにする。
- 将来的な拡張性: 新しい種類のNotesが導入された場合でも、既存のメカニズムを大きく変更することなく対応できるようにする。
Package.Bugs
フィールドは既存のコードとの互換性を保つために残されましたが、将来的にはPackage.Notes
への完全な移行が意図されています。
前提知識の解説
このコミットを理解するためには、以下のGo言語のツールと概念に関する知識が必要です。
-
godoc
:godoc
はGo言語の公式ドキュメンテーションツールです。Goのソースコードからドキュメントを生成し、Webサーバーとして提供したり、コマンドラインで表示したりできます。- Goのパッケージ、関数、型、変数などの定義に付随するコメントを解析し、整形されたドキュメントとして出力します。
- 開発者は
godoc -http=:6060
のように実行することで、ローカルでGoの標準ライブラリや自分のプロジェクトのドキュメントをブラウザで閲覧できます。
-
pkg/go/doc
パッケージ:pkg/go/doc
は、Goのソースコードからドキュメンテーションを抽出・解析するための標準ライブラリパッケージです。godoc
ツールはこのパッケージを利用して、GoのAST(抽象構文木)を解析し、ドキュメンテーションコメントやコード構造からdoc.Package
などの構造体を構築します。doc.Package
構造体は、パッケージ全体のドキュメント、インポートパス、ファイル名、そしてこのコミットで焦点となるNotes
(以前はBugs
)などの情報を含んでいます。
-
GoのコメントにおけるNotes(マーカー):
- Goのソースコードでは、特定の形式のコメントが特別な意味を持つことがあります。これらは通常、
MARKER(userid): comment text
の形式を取ります。 BUG(userid):
: 既知のバグや問題点を示すために使用されます。TODO(userid):
: 将来的に実装すべき機能や改善点を示すために使用されます。FIXME(userid):
: 修正が必要なコード部分を示すために使用されます。SECBUG(userid):
: セキュリティ上の懸念や脆弱性を示すために使用されます。userid
は通常、コメントを追加した開発者のイニシャルやIDです。- これらのNotesは、コードレビューやプロジェクト管理において重要な役割を果たします。
- Goのソースコードでは、特定の形式のコメントが特別な意味を持つことがあります。これらは通常、
-
Goの
text/template
およびhtml/template
パッケージ:- Goの標準ライブラリには、テンプレートエンジンを提供する
text/template
とhtml/template
パッケージがあります。 godoc
はこれらのパッケージを使用して、解析したドキュメントデータをHTMLやプレーンテキスト形式でレンダリングします。- テンプレートファイル(例:
lib/godoc/package.html
)は、Goのテンプレート構文({{.Field}}
,{{range .Slice}}
,{{if .Condition}}
など)を使用して、動的にコンテンツを生成します。 FuncMap
は、テンプレート内で呼び出すことができるカスタム関数を登録するために使用されます。
- Goの標準ライブラリには、テンプレートエンジンを提供する
これらの前提知識を理解することで、コミットがgodoc
の動作、pkg/go/doc
のデータ構造、そしてGoのコメント慣習にどのように影響を与えるかを深く把握できます。
技術的詳細
このコミットの技術的な核心は、pkg/go/doc
パッケージがコメントからNotesを解析する方法と、cmd/godoc
がそれらのNotesをWebページやテキスト出力で表示する方法の変更にあります。
-
pkg/go/doc
におけるNotesの汎用化:- 以前は、
pkg/go/doc.Package
構造体にはBugs []string
というフィールドがあり、BUG
コメントのみがここに収集されていました。 - このコミットでは、
Package
構造体にNotes map[string][]string
という新しいフィールドが追加されました。これは、マーカー(例: "BUG", "TODO", "SECBUG")をキーとし、そのマーカーに属するコメントテキストのリストを値とするマップです。 src/pkg/go/doc/doc.go
では、Bugs
フィールドがDEPRECATED
とマークされ、新しいコードではNotes
を使用するよう促されています。ただし、既存のコードとの互換性のため、Bugs
フィールドは引き続きBUG
コメントで埋められます。src/pkg/go/doc/reader.go
のreadFile
関数内で、コメントを解析してNotesを収集するロジックが変更されました。readNote
関数がコメントからマーカーとテキストを抽出し、その結果をr.notes[marker]
に格納するように統一されました。以前はBUG
マーカーの場合のみr.bugs
にも追加する特殊な処理がありましたが、これが簡素化され、すべてのNotesがr.notes
マップに格納されるようになりました。
- 以前は、
-
cmd/godoc
におけるNotesの表示サポート:src/cmd/godoc/godoc.go
のPageInfo
構造体に、Notes map[string][]string
フィールドが追加されました。これは、pkg/go/doc.Package
から取得したNotesをgodoc
のテンプレートに渡すための中間構造体です。getPageInfo
関数内で、pkg.Notes
から特定のNotes(デフォルトではBUG
)をinfo.Notes
にコピーするロジックが追加されました。これにより、表示したいNotesをフィルタリングできます。src/cmd/godoc/main.go
では、新しいコマンドラインフラグ-notes
が追加されました。これにより、ユーザーはgodoc
がどのNotesマーカー(例:-notes="BUG,TODO,SECBUG"
)を表示するかをカンマ区切りで指定できるようになりました。デフォルトではBUG
のみが表示されます。src/cmd/godoc/godoc.go
には、noteTitle
という新しいテンプレート関数が追加されました。この関数は、Notesマーカー(例: "BUG")を受け取り、それを整形されたタイトル(例: "Bugs")に変換します。これは、HTMLやテキスト出力でNotesのセクション見出しを生成するために使用されます。lib/godoc/package.html
とlib/godoc/package.txt
のテンプレートファイルが更新され、$.Notes
フィールドをイテレートして、各Notesマーカーとその内容を表示するようになりました。これにより、BUG
だけでなく、指定されたすべてのNotesが表示されるようになります。また、noteTitle
関数を使用して見出しが生成されます。
-
テストデータの更新:
src/pkg/go/doc/testdata/a.0.golden
、a.1.golden
、a.2.golden
、template.txt
といったテスト出力ファイルが更新され、新しいNotesの表示形式(例:BUGS
からBUGS .Bugs is now deprecated, please use .Notes instead
、SECBUG
からSECBUGS
、TODO
からTODOS
)を反映しています。これは、godoc
がNotesを複数形で見出しとして表示するようになったことを示しています。
この変更により、godoc
はより柔軟にソースコード内のNotesをドキュメントとして表示できるようになり、開発者にとってコードベースの重要な情報へのアクセスが容易になりました。
コアとなるコードの変更箇所
このコミットにおける主要なコード変更は以下のファイルに集中しています。
-
src/pkg/go/doc/doc.go
:Package
構造体からBugs []string
フィールドが削除され、代わりにNotes map[string][]string
が追加されました。Bugs
フィールドは互換性のために残され、DEPRECATED
コメントが追加されました。
--- a/src/pkg/go/doc/doc.go +++ b/src/pkg/go/doc/doc.go @@ -17,7 +17,10 @@ type Package struct { ImportPath string Imports []string Filenames []string - Bugs []string + // DEPRECATED. For backward compatibility Bugs is still populated, + // but all new code should use Notes instead. + Bugs []string + // Notes such as TODO(userid): or SECURITY(userid): // along the lines of BUG(userid). Any marker with 2 or more upper // case [A-Z] letters is recognised.
-
src/pkg/go/doc/reader.go
:readFile
関数内で、コメントからNotesを収集するロジックが変更されました。以前はBUG
とそれ以外のNotesで処理が分かれていましたが、すべてのNotesがr.notes
マップに格納されるように統一されました。BUG
の場合のみ、互換性のためにr.bugs
にも追加されます。
--- a/src/pkg/go/doc/reader.go +++ b/src/pkg/go/doc/reader.go @@ -487,12 +486,9 @@ func (r *reader) readFile(src *ast.File) { // collect MARKER(...): annotations for _, c := range src.Comments { \tif marker, text := readNote(c); marker != "" { -\t\t\t// Remove r.bugs in a separate CL along with -\t\t\t// any necessary changes to client code. +\t\t\tr.notes[marker] = append(r.notes[marker], text) \t\t\tif marker == "BUG" { \t\t\t\tr.bugs = append(r.bugs, text) -\t\t\t} else { -\t\t\t\tr.notes[marker] = append(r.notes[marker], text) \t\t\t} \t\t} }
-
src/cmd/godoc/godoc.go
:PageInfo
構造体にNotes map[string][]string
フィールドが追加されました。getPageInfo
関数内で、pkg.Notes
から表示対象のNotesをinfo.Notes
に収集するロジックが追加されました。noteTitle
という新しいテンプレートヘルパー関数が追加され、fmap
(テンプレート関数マップ)に登録されました。
--- a/src/cmd/godoc/godoc.go +++ b/src/cmd/godoc/godoc.go @@ -446,6 +446,10 @@ func example_suffixFunc(name string) string { return suffix } +func noteTitle(note string) string { + return strings.Title(strings.ToLower(note)) +} + func splitExampleName(s string) (name, suffix string) { i := strings.LastIndex(s, "_") if 0 <= i && i < len(s)-1 && !startsWithUppercase(s[i+1:]) { @@ -539,6 +543,9 @@ var fmap = template.FuncMap{ "example_text": example_textFunc, "example_name": example_nameFunc, "example_suffix": example_suffixFunc, + + // formatting of Notes + "noteTitle": noteTitle, } func readTemplate(name string) *template.Template { @@ -897,11 +904,12 @@ type PageInfo struct { Err error // error or nil // package info - FSet *token.FileSet // nil if no package documentation - PDoc *doc.Package // nil if no package documentation - Examples []*doc.Example // nil if no example code - PAst *ast.File // nil if no AST with package exports - IsMain bool // true for package main + FSet *token.FileSet // nil if no package documentation + PDoc *doc.Package // nil if no package documentation + Examples []*doc.Example // nil if no example code + Notes map[string][]string // nil if no package Notes + PAst *ast.File // nil if no AST with package exports + IsMain bool // true for package main // directory info Dirs *DirList // nil if no directory information @@ -1082,6 +1090,17 @@ func (h *docServer) getPageInfo(abspath, relpath string, mode PageInfoMode) (inf log.Println("parsing examples:", err) } info.Examples = collectExamples(pkg, files) + + // collect any notes that we want to show + if info.PDoc.Notes != nil { + info.Notes = make(map[string][]string) + for _, m := range notesToShow { + if n := info.PDoc.Notes[m]; n != nil { + info.Notes[m] = n + } + } + } + } else { // show source code // TODO(gri) Consider eliminating export filtering in this mode,
-
src/cmd/godoc/main.go
:-notes
という新しいコマンドラインフラグが追加され、表示するNotesマーカーを指定できるようになりました。
--- a/src/cmd/godoc/main.go +++ b/src/cmd/godoc/main.go @@ -71,6 +71,11 @@ var ( // command-line searches query = flag.Bool("q", false, "arguments are considered search queries") + + // which code 'Notes' to show. + notes = flag.String("notes", "BUG", "comma separated list of Note markers as per pkg:go/doc") + // vector of 'Notes' to show. + notesToShow []string ) func serveError(w http.ResponseWriter, r *http.Request, relpath string, err error) { @@ -157,6 +162,8 @@ func main() { flag.Usage = usage flag.Parse() + notesToShow = strings.Split(*notes, ",") + // Check usage: either server and no args, command line and args, or index creation mode if (*httpAddr != "" || *urlFlag != "") != (flag.NArg() == 0) && !*writeIndex { usage()
-
lib/godoc/package.html
およびlib/godoc/package.txt
:Bugs
フィールドの代わりにNotes
フィールドをイテレートし、noteTitle
関数を使用して見出しを生成するようにテンプレートが変更されました。
--- a/lib/godoc/package.html +++ b/lib/godoc/package.html @@ -70,12 +70,9 @@ <dd> <a href="#{{$tname_html}}.{{$name_html}}">{{node_html .Decl $.FSet}}</a></dd> {{end}} {{end}} - {{if .Bugs}} - <dd><a href="#pkg-bugs">Bugs</a></dd> - {{end}} - {{if .Notes}} - {{range $marker, $item := .Notes}} - <dd><a href="#pkg-{{$marker}}">{{$marker}}</a></dd> + {{if $.Notes}} + {{range $marker, $item := $.Notes}} + <dd><a href="#pkg-note-{{$marker}}">{{noteTitle $marker | html}}s</a></dd> {{end}} {{end}} </dl> @@ -167,15 +164,9 @@ {{comment_html .Doc}} {{end}} - {{with .Bugs}} - <h2 id="pkg-bugs">Bugs</h2> - {{range .}} - {{comment_html .}} - {{end}} - {{end}} - {{with .Notes}} + {{with $.Notes}} {{range $marker, $content := .}} - <h2 id="pkg-{{$marker}}">{{$marker}}</h2> + <h2 id="pkg-note-{{$marker}}">{{noteTitle $marker | html}}s</h2> {{range .}} {{comment_html .}} {{end}}
コアとなるコードの解説
このコミットの主要な変更は、Goのドキュメンテーション生成プロセスにおける「Notes」の扱いを、特定の「Bugs」から汎用的なメカニズムへと進化させた点にあります。
-
pkg/go/doc
の変更 (src/pkg/go/doc/doc.go
,src/pkg/go/doc/reader.go
):Package.Bugs
からPackage.Notes
への移行: 以前はdoc.Package
構造体にBugs []string
というフィールドがあり、BUG
コメントのみがここに格納されていました。このコミットでは、より汎用的なNotes map[string][]string
が導入されました。これは、TODO
、SECBUG
など、任意のマーカーを持つコメントをキーと値のペアで格納できるマップです。- 互換性の維持:
Bugs
フィールドはDEPRECATED
とマークされましたが、既存のコードが壊れないように、BUG
コメントは引き続きBugs
フィールドにも追加されます。これは、段階的な移行を可能にするための重要な設計判断です。 - 解析ロジックの統一:
reader.go
のreadFile
関数内のコメント解析ロジックが簡素化されました。すべてのNotes(BUG
を含む)はまずr.notes
マップに格納されます。その後、BUG
マーカーの場合にのみ、互換性のためにr.bugs
にも追加されるという形になりました。これにより、Notesの収集メカニズムがより一貫性を持つようになりました。
-
cmd/godoc
の変更 (src/cmd/godoc/godoc.go
,src/cmd/godoc/main.go
):PageInfo
構造体の拡張:godoc
がドキュメントをレンダリングする際に使用するPageInfo
構造体に、Notes map[string][]string
フィールドが追加されました。これにより、pkg/go/doc
から取得したNotesデータをテンプレートに渡す準備が整いました。- Notesのフィルタリングと収集:
getPageInfo
関数内で、pkg.Notes
から、コマンドラインで指定された(またはデフォルトの)Notesマーカーに対応するNotesのみをinfo.Notes
に収集するロジックが追加されました。これにより、ユーザーはgodoc
の出力に表示されるNotesの種類を制御できます。 - 新しいコマンドラインフラグ
-notes
:main.go
で導入された-notes
フラグは、ユーザーがgodoc
に表示させたいNotesマーカーをカンマ区切りで指定できるようにします(例:godoc -notes="BUG,TODO"
)。これにより、ドキュメントのカスタマイズ性が向上しました。 noteTitle
テンプレート関数:godoc.go
に追加されたnoteTitle
関数は、Notesマーカー(例: "BUG")を、ドキュメントの見出しに適した形式(例: "Bugs")に変換します。これは、strings.Title(strings.ToLower(note))
というシンプルなロジックで実現されており、汎用的なタイトル生成を可能にしています。この関数はgodoc
のテンプレートエンジンに登録され、HTMLやテキストのレンダリング時に利用されます。
-
テンプレートの変更 (
lib/godoc/package.html
,lib/godoc/package.txt
):- HTMLおよびテキストテンプレートは、
$.Notes
マップをイテレートするように変更されました。これにより、BUG
だけでなく、TODO
やSECBUG
など、すべての指定されたNotesがそれぞれ独立したセクションとして表示されるようになりました。 noteTitle
関数が使用され、各Notesセクションの見出しが動的に生成されます(例:<h2>Bugs</h2>
,<h2>Todos</h2>
)。これにより、ドキュメントの可読性と構造が向上しました。
- HTMLおよびテキストテンプレートは、
これらの変更により、godoc
はGoソースコード内のNotesをより包括的かつ柔軟にドキュメントとして表示できるようになり、開発者がコードベースの重要な情報にアクセスしやすくなりました。
関連リンク
- Go言語公式ドキュメンテーション: https://go.dev/doc/
godoc
コマンドのドキュメンテーション: https://pkg.go.dev/cmd/godocpkg/go/doc
パッケージのドキュメンテーション: https://pkg.go.dev/go/doc- Go Code Review Comments (Notesに関する記述): https://go.dev/wiki/CodeReviewComments#notes
参考にした情報源リンク
- GoのChange List (CL) 7341053: https://golang.org/cl/7341053 (コミットメッセージに記載されている元のCL)
- Go言語のソースコード (GitHub): https://github.com/golang/go
godoc
のNotes表示に関する議論 (Go Issuesなど):godoc: display TODOs, FIXMEs, etc.
(関連するIssueの可能性): https://github.com/golang/go/issues/4000 (このコミットより後の日付だが、同様の議論が以前からあった可能性を示唆)go/doc: add support for TODO/FIXME/BUG comments
(関連するIssueの可能性): https://github.com/golang/go/issues/4001 (同上)
これらのリンクは、コミットの背景、実装の詳細、およびGoコミュニティにおける関連する議論をさらに深く理解するのに役立ちます。