せめてリポジトリの各ディレクトリの概要説明だけでも欲しい思ったので dirmap というツールを作ってみた

既存の開発に参加するときや、0->1の開発をしているとき、いつも「せめてリポジトリの各ディレクトリの概要説明だけでも欲しい」と思っていました。

既存のプロジェクトに参加するときは「プロジェクトの理解をする側」、0->1のプロジェクトで開発をしているときは「説明をする側の立場」で、です。

Ruby on Railsのような基本のディレクトリレイアウト決まっていてもそのプロジェクトの独自性がでてきますし、Goのようにスタンダードなレイアウトがないのであればなおさら初見ではわかりません。

「じゃあREADME.mdにでも書いておけばいい」というのはその通りです。

ただ、概要説明であっても一度書いたら終わりではなく、更新は必要になります。特に0->1のプロジェクトの初期ではディレクトリレイアウトすら途中で変わるということはままあります。

(ここらへんは「継続的ドキュメンテーション」として私の興味のある分野です。私のSpeaker Deckのドキュメント系の発表は大体が継続的ドキュメンテーションにつながっています)

そこで、できるだけ簡単に各ディレクトリの概要説明を実現するために dirmap というツールを作ってみました。

github.com

dirmap

dirmapはディレクトリを再帰的に走査して各ディレクトリの「概要を説明していそうな箇所の文字列」を取得し「各ディレクトリの概要説明=ディレクトリマップ」を生成するツールです。

たとえば dirmap のリポジトリルートで dirmap generate を実行すると以下のような tree に近い出力を得ることができます。

$ dirmap generate
.
├── .github/
│   └── workflows/
├── cmd/ ... Commands.
├── config/ ... Configuration file.
├── matcher/ ... Implementation to find the string that will be the overview from the code or Markdown.
├── output/ ... Output format of the directory map.
├── scanner/ ... Implementation of scanning the target directory and its overview from the file system based on the configuration.
├── scripts/ ... scripts for Dockerfile.
└── version/ ... Version.

この Commands.scripts for Dockerfile. のような概要っぽい文字列はどこから取得しているかというと、「そのディレクトリにあるMarkdownファイルの見出しではない最初のパラグラフ」や「そのディレクトリにあるGoのソースコードに書かれているgodocのpackages Overviewにあたる部分」などです。

このように「そのディレクトリにあるファイルからそのディレクトリの説明となる文章を抽出すれば、各ディレクトリの概要説明の管理も最小限になるだろう」という算段です。

「概要っぽい文字列」の取得ルールは設定ファイルを渡すことで変更も可能です。built-inな markdown markdownHeading godoc 以外にも正規表現マッチもサポートしています。

設定ファイルは dirmap init で生成可能です。書かれている設定は dirmap のデフォルト設定(設定ファイルなしの場合の挙動と同じ)になります。

$ dirmap init
Create .dirmap.yml
# $ cat .dirmap.yml
targets:
- file: .dirmap.md
  matcher: markdown
- file: README.md
  matcher: markdown
- file: doc.go
  matcher: godoc
- file: "*.go"
  matcher: godoc

ディレクトリの概要は targets: に指定した走査条件に最初にマッチした文字列になります。

dirmap generate で出力できるフォーマットは今の所「treeライクなASCIIの出力」と「Markdown(GFM)のテーブル形式」の2つです(以下はテーブル形式)。

$ dirmap generate -t table
| Directory | Overview |
| --- | --- |
| .github/ |  |
| .github/workflows/ |  |
| cmd/ | Commands. ( [ref](cmd/doc.go) ) |
| config/ | Configuration file ( [ref](config/config.go) ) |
| matcher/ | Implementation to find the string that will be the overview from the code or Markdown. ( [ref](matcher/matcher.go) ) |
| output/ | Output format of the directory map ( [ref](output/output.go) ) |
| scanner/ | Implementation of scanning the target directory and its overview from the file system based on the configuration. ( [ref](scanner/scanner.go) ) |
| scripts/ | Scripts for Dockerfile ( [ref](scripts/.dirmap.md) ) |
| version/ | Version ( [ref](version/version.go) ) |

とりあえずdirmapを使って各ディレクトリの概要説明をいれつつ、新しくプロジェクトに入るメンバーのために開発者用ドキュメントをメンテナンスしてみようと思います。

Goのプロジェクトならgodocのpackage overviewの箇所だけ書いておけばいいだけなので楽です(他の言語も良いドキュメントフォーマットが存在するなら対応したいと思っています。ぜひ教えてください)。

これだけで開発開始までのオーバーヘッドが大幅に減るとは思ってはいませんが、継続的ドキュメンテーションの1つとして試してみようと思います。