GoDoc に関するまとめ

GoDoc について調べた内容のまとめです。Go のソースコードでは、コメントを正しい箇所に記述しておくことで、ドキュメントを自動生成できる仕組みがあります。また、言語サーバーとして gopls を利用する IDE であれば、画面上にコメントを表示してくれるようになります。

環境

  • Ubuntu 20.04.4 LTS(WSL2)
  • Go 1.19.1
  • golang.org/x/pkgsite/cmd/pkgsite v0.0.0-20220930220314-86a174403451

サンプルのコード

サンプルコード用のディレクトリを用意して、go module の初期化。

$ mkdir sample
$ cd sample
$ go mod init private.com/private/sample

ファイル構造

.
├── cmd
│   └── book
│       └── main.go
├── go.mod
└── pkg
    └── book
        └── book.go

./cmd/book/main.go

package main

import (
    "fmt"

    "private.com/private/sample/pkg/book"
)

func main() {
    x := book.NewBook("さようなら、ギャングたち", "高橋源一郎")
    y := book.NewBook("風の歌を聴け", "村上春樹")
    fmt.Println(x.Title())
    fmt.Println(y.Title())
}

./pkg/book/book.go

// Sample commnet.
//
// Link to [site].
//
// list
//   - A
//   - B
//
// code block
//
//  $ go run .
//
// [site]: https://example.com/hear
package book

// Type commnet.
type Book struct {
    title  string
    author string
}

// Function commnet.
//
// Initialize new book instance.
func NewBook(title, author string) *Book {
    return &Book{
        title:  title,
        author: author,
    }
}

// Book's mehod commnet.
//
// Return the title of the Book's instance.
func (b *Book) Title() string {
    // BUG(who): 2022/10/01 こんなバグがあったよ
    return b.title
}

実行してみる。

$ go run ./cmd/book/
さようなら、ギャングたち
風の歌を聴け

コメント記述方法

コメントの記述方法は、上記ファイル ./pkg/book/book.go を参照。宣言している packageシンボル (シンボルとは A symbol is a top-level const, func, type, or var. を言うそうです。)の1行上に、ドキュメントとして扱いたいコメントを記述します。

より詳細には、下記の公式資料が詳しいです。前半部分に、各シンボル毎に記載する情報の指針が提示されており、後半部分に、具体的なコメント記述方法のシンタックスが記載されています。

Go Doc Comments

ドキュメント表示方法

記述したコメントを、ドキュメントとして表示してみます。

コマンドラインツール go doc

Go の標準コマンドラインツールである go doc を利用すると、コマンドを実行したターミナル上にドキュメントを表示してくれます。

Go モジュールのルートディレクトリ上で、表示したいパッケージを指定して go doc コマンドを実行します。

$ go doc private.com/private/sample/pkg/book
package book // import "private.com/private/sample/pkg/book"

Sample commnet.

Link to site.

list
  - A
  - B

code block

    $ go run .

[site]: https://example.com/hear

type Book struct{ ... }
    func NewBook(title, author string) *Book

BUG: 2022/10/01 こんなバグがあったよ

シンボルを細かく指定して実行すると、表示する範囲を絞ることができます。

$ go doc private.com/private/sample/pkg/book.Book
package book // import "private.com/private/sample/pkg/book"

type Book struct {
        // Has unexported fields.
}
    Type commnet.

func NewBook(title, author string) *Book
func (b *Book) Title() string
$ go doc private.com/private/sample/pkg/book.Book.Title
package book // import "private.com/private/sample/pkg/book"

func (b *Book) Title() string
    Book's mehod commnet.

    Return the title of the Book's instance.

その他の表示オプションは、下記を参照。

go doc

pkg.go.dev スタイルの WEB サーバーをローカルで起動してくれる pkgsite

準標準パッケージである golang.org/x/pkgsite/cmd/pkgsite を利用すると、pkg.go.dev スタイルの WEB サーバーをローカル上で起動してくれます。

pkgsite

パッケージのインストール。

$ go install golang.org/x/pkgsite/cmd/pkgsite@latest

Go モジュールのルートディレクトリ上で、pkgsite コマンドを実行すると、WEB サーバーが起動します。

$ ~/go/bin/pkgsite
2022/10/01 12:50:34 Info: Listening on addr http://localhost:8080

ブラウザで http://localhost:8080/(module path名) にアクセスします。今回の例では http://localhost:8080/private.com/private/sample という URL です。

確認したいパッケージのリンクをたどると、ドキュメントが表示されています。

module path の名前について

pkgsite でローカルのソースコードを表示する場合、module path の名前に気をつける必要がありました。

今回の例では private.com/private/sample という module path 名としていますが、これは https://pkg.go.dev/ サイトへ公開用の命名規則に則った module path 名となります。( private.com なんてサイトはないですが。。。)

以下は moudle path についての公式解説ですが、

A module path should describe both what the module does and where to find it. Typically, a module path consists of a repository root path, a directory within the repository (usually empty), and a major version suffix (only for major version 2 or higher).

The repository root path is the portion of the module path that corresponds to the root directory of the version control repository where the module is developed. Most modules are defined in their repository’s root directory, so this is usually the entire path. For example, golang.org/x/net is the repository root path for the module of the same name. See Finding a repository for a module path for information on how the go command locates a repository using HTTP requests derived from a module path.

module-path

例えば、1つの Go module を1つの git リポジトリで管理する場合、GitHub でのリポジトリ URL は https://github.com/(GitHubのアカウント名)/(リポジトリ名) となるので、Go module path の名前は github.com/(GitHubのアカウント名)/(リポジトリ名) とする必要があります。この module path 名から派生した HTTP リクエストを利用して、Go コマンドは対象パッケージのあるリポジトリを見つけてきたり、https://pkg.go.dev/ サイトは反映/公開の処理をしている、らしいです。

https://pkg.go.dev/ サイトに公開するつもりのないモジュールであれば、上記の module path 名の規則に従う必要はないのですが、pkgsite コマンドを利用する場合には、module path 名を規則に揃えておく必要がありました。例えば module path を private という名前でつくると、ローカル上の pkg.go.dev サーバーが起動した際、パッケージのファイルを見つけてくれませんでした。良い解決方法を探したのでが見つからず、とりあえずこの方法で回避しています。