Digger なるツールについて

みなさん、DMD を自前でビルドしてますよね。
# What's Digger?
[Digger](https://github.com/CyberShadow/Digger) とは CyberShadow さんが開発している、DMD をビルドするためのツールです。もちろん D 言語製です。
## DMD をビルドするツール
単にその時点で最新の DMD をビルドしたいのであれば、[公式 wiki のガイド](http://wiki.dlang.org/Building_DMD)に従ってコマンドを打っていけばできるはずです。しかしながら、ある時点でのバージョンや未マージの pull request を適用したバージョンが欲しくても git になじみがない自分にはおっくうだったりします。
そんなときでも 1 コマンドでサクッとビルドできてしまうのがこのツールです。
また、同梱の `digger-web` というツールはフロントエンドがウェブブラウザであり、よさげな pull request や誰かがフォークしたものをポチポチと選ぶことができるので手軽です。
## 犯人捜しツール
もう 1 つの側面として、エンバグしたコミットを見つけ出す機能があります。これは `git bisect` を使った機能であるらしく、バグっていないコミットとバグっているコミットを指定し、その間からどこでバグったかをひたすらビルドとテストを繰り返すことで原因となるコミットを二分探索的に特定するもののようです。逆に、どこで正常になったのかを探すこともできます。
# 使い方
## 入手
Windows 版のバージョン 1.0 のバイナリが[リリースページ](https://github.com/CyberShadow/Digger/releases)で公開されていますが、それ以外の環境では自前でビルドする必要があります。また、このリリース版は若干古いので Windows な人も自らビルドすればいいと思います。`git` と `rdmd` があれば README のとおりにすれば可能です。
執筆時点で最新の DMD 2.066.1 ではコンパイルエラーになるようで、対応策も出ていますが、そのうち直るかもしれません。

* [Digger-web no longer compiles on 2.066.1 · Issue #10 · CyberShadow/Digger](https://github.com/CyberShadow/Digger/issues/10)

自分は 32 ビット Windows 版の 2.067.0-b1 を使いました。ライブラリが見つからないとリンカが言ってきますが、スルー推奨です。
## DMD をビルドしてみる
以下、Windows での話です。他の環境では適当に読み替えてください。また、コマンドラインツールの `digger` を使うことにします。
### ビルド
まずは `digger.ini` という設定ファイルを用意する必要があります。`digger.ini.sample` を参考に編集し、`digger` のあるディレクトリに置いておきます。とりあえず作業ディレクトリだけ変更したかったので次のようにしてみました。

```ini:digger.ini
workDir = d:\d\digger_tmp

[environment]
```

あとは

```console:console_input
$ digger build
```

で GitHub の `master` から最新のソースを持ってきて、DMD, druntime, Phobos, rdmd とビルドしてくれます。なお、初回はビルドに必要なツールを自動でダウンロードし、作業ディレクトリに展開するようです。
無事に終われば最終的に

```console:console_output
digger: Build successful.

Add d:\d\digger_tmp\result\bin to your PATH to start using it.
```

のように表示されるはずです。
どの時点での DMD が欲しいかは、このコマンドのオプションとして指定するわけですが、例によって README にさまざまな例があるのでそちらをどうぞ。
### リビルド
ビルド後、ソースファイルは作業ディレクトリ内の `repo` に置かれています。そこのソースを編集した上でビルドしたい場合は

```console:console_input
$ digger rebuild
```

とする必要があります。`$ digger build` ではソースがリモートの物で上書きされ、悲しいことになります。
リビルド機能はバージョン 1.0 には搭載されていないので注意してください。
### 単体テストなど
DMD のビルドでは単体テスト一式を走らせるのが儀礼ですが、残念ながらその機能は未搭載のようなので、[公式 wiki のガイド](http://wiki.dlang.org/Building_DMD)のように手作業で行う必要があります。
ドキュメント生成や他のツールのビルド機能もないようなので、これも手作業でどうぞ。
## bisect してみる
### 準備
`bisect.ini` を用意します。同様に `bisect.ini.sample` を元に作りましょう。
今回は `std.range` に `enumerate` ができたタイミングを発見してみます。事実として、2014/09/20 に[その pull request](https://github.com/D-Programming-Language/phobos/pull/1866) がマージされています。
では、次のような `bisect.ini` を `digger` と同じディレクトリに用意します。

```ini:bisect.ini
bad  = @ 2014-09-19
good = @ 2014-09-21

reverse = true

tester = dmd -main -o- d:\d\digger_tmp\tester.d

[build]
model = 32
debugDMD = false

[environment]
```

`reverse = true` を指定したので、テスト失敗状態からテスト成功状態になったコミットを探すモードになりました。そのため、`good` よりも `bad` が古くなるように指定しています。テスト結果は `tester` で指定したコマンドの終了ステータスで判断されます。
今回はコンパイルエラーが出るか出ないかというテストを行うので、作業ディレクトリの `d:\d\digger_tmp` に次のようなテスト用のファイルを作ります。

```d:tester.d
import std.range : enumerate;
```

コンパイルが成功し、`dmd` が `0` を返せばテスト成功です。
### 実行
次のコマンドを実行します。

```console:console_input
$ digger bisect bisect.ini
```

すると、ひたすらビルドとテストが行われ、最終的にターゲットが捕獲されるはずです。

```console:console_output
a46170ff9647111d45f5743139b95db19e9274f1 is the first bad commit
commit a46170ff9647111d45f5743139b95db19e9274f1
Author: Михаил Страшун <registrations@dicebot.lv>
Date:   Sat Sep 20 16:14:02 2014 +0400

    phobos: Merge pull request #1866 from JakobOvrum/enumerate
    
    https://github.com/D-Programming-Language/phobos/pull/1866
    
    Add std.range.enumerate

:160000 160000 cbdbf52cac4d408acf09a4e69d48d64ba795dc0c 2ad0698308c788c55ee0f2be30725d80c144f76f M	phobos
bisect run success
```

# 最後に
最先端の D 言語を先取りしたい方々、コンパイラや標準ライブラリに手を加えたい方々には便利なツールではないでしょうか。