【Docker×cloc】空行・コメントを除外して正確な修正行数をサクッと測定！

## はじめに

ソースコードの修正量を測る際、「実際に動くコードの行数（空行やコメントを除いた行数）」を知りたいことはありませんか？
手作業で数えるのは非現実的ですが、ツールを使えば簡単にカウントできます。

本記事では、Docker上で「cloc」を実行し、Gitのブランチ間のファイルごとの修正行数を取得する方法を説明します。

ちなみに筆者のPCでは、ローカル環境（Windows）に直接clocをインストールすると

- 「unzipコマンドが無い」と怒られる
- 「プロセスはファイルにアクセスできません。別のプロセスが使用中です。」の謎エラーが起きる

の問題が起きて、cloc は動きませんでした。

Docker上でclocを実行すると、このような環境起因の問題が起きることも無く、ローカル環境も汚さずに済みます。

### この記事でわかる・できること

- Dockerを利用して、ローカル環境を汚さずに行数カウントできる
- 異なるブランチ間で増減したコード行数を簡単に比較できる

### この記事の対象者

- 自チームのコードの修正行数をカウントしたい開発者
- コードの変更規模を定量的に評価したい品質チェック担当者

### 動作環境

- OS：Windows
- Docker（動作確認済みのバージョン: 27.5.1）
- Git
- コマンドプロンプト

## 1. 必要なツールの準備

clocのDockerイメージをpullするだけです。
コマンドプロンプトなどのCLIで下記のコマンドを実行してください。

```
docker pull aldanial/cloc
```

## 2. Docker上のcloc実行方法

まずは、試しにclocのバージョンを表示してみましょう。

```
docker run --rm aldanial/cloc --version
```

このコマンドを実行して、バージョンが

```
2.02
```

のように表示されれば成功です。

※「docker run」に「--rm」のオプションを付けると、実行完了時にコンテナが自動的に削除されます。


## 3. Gitのブランチ間のファイルごとの修正行数取得

ここからが本題です。
Gitのブランチ間の修正行数をファイル単位で取得する方法を紹介します。
※この章ではコマンドを1つずつ紹介していますが、次の章ではコマンドを一括実行する方法も紹介します。

### (1)修正前のコミットID取得

後でclocのコマンド引数に使用するため、修正前のコミットIDを控えておく。

### (2)修正後のブランチに切り替え

clocのコマンド引数で```HEAD```を使用するため、修正後のブランチに切り替えておく。

### (3)修正したファイルのパス一覧出力

下記のGitコマンドで、修正したファイルのパスの一覧をファイル出力します。
※コマンド実行前にカレントディレクトリをGitリポジトリのチェックアウト先のルートフォルダにしてください。

```
git diff {修正前のブランチ} {修正後のブランチ} --name-only > filelist.txt
```

もし、修正行数を取得したくないファイル（自分の所管外のファイルなど）がある場合、```filelist.txt```から行を削除しておいてください。

### (4)修正行数取得

下記のコマンドを実行します。
（コマンドの意味は後述）

```
docker run --rm -v %CD%:/workspace -w /workspace aldanial/cloc --diff --by-file --csv --list-file=filelist.txt {修正前のコミットID} HEAD > diff.csv
```

成功すると下記のような内容のCSVファイル（diff.csv）が出力されます。
このCSVを解析すると空行・コメントを除外した修正行数が確認できます。
（CSVの各項目の意味についても後述）

```
File, == blank, != blank, + blank, - blank, == comment, != comment, + comment, - comment, == code, != code, + code, - code, "github.com/AlDanial/cloc v 2.02 T=3.52096199989319 s"
NewMachineguns.md, 0, 0, 6, 0, 0, 0, 0, 0, 388, 8, 54, 0, 
Tegataners.md, 0, 0, 142, 0, 0, 0, 316, 0, 0, 0, 494, 0, 
```

### コマンド解説

| オプション                        | 説明 |
|----------------------------------|------------------------------------------------------------|
| `-v %CD%:/workspace`            | ホストのカレントディレクトリ（`%CD%`）をコンテナ内の `/workspace` にマウントする。これにより、ホストのファイルをコンテナ内で利用可能にする。 |
| `-w /workspace`                 | コンテナ内の作業ディレクトリを `/workspace` に設定する。 |
| `--diff`                        | コードの差分を計測（指定した 2 つのバージョンの違いを分析）。 |
| `--by-file`                     | ファイルごとの変更行数を表示。 |
| `--csv`                         | 出力を CSV 形式にする。 |
| `--list-file=filelist.txt`      | `filelist.txt` に記載されたファイルの変更のみを分析。 |
| `{修正前のコミットID} HEAD`      | Git の 2 つのコミットを指定して、差分を解析する。 |
| `{修正前のコミットID}`          | 過去のコミットを指定。 |
| `HEAD`                          | 現在の最新コミットを指定。 |

### CSVの各項目解説

| 項目              | 意味 |
|-------------------|--------------------------------|
| **File**         | 対象のファイル名（パス） |
| **== blank**     | 変更されなかった空行の数 |
| **!= blank**     | 編集された空行の数（内容が変わった空行） |
| **+ blank**      | 新しく追加された空行の数 |
| **- blank**      | 削除された空行の数 |
| **== comment**   | 変更されなかったコメント行の数 |
| **!= comment**   | 編集されたコメント行の数（内容が変わったコメント行） |
| **+ comment**    | 新しく追加されたコメント行の数 |
| **- comment**    | 削除されたコメント行の数 |
| **== code**      | 変更されなかったコード行の数 |
| **!= code**      | 編集されたコード行の数（内容が変わったコード行） |
| **+ code**       | 新しく追加されたコード行の数 |
| **- code**       | 削除されたコード行の数 |
| **"github.com/AlDanial/cloc v X.XX T=Y.YYYY s"** | `cloc` のバージョン情報と処理時間（秒） |

## 4. コマンド一括実行

コマンドプロンプトで下記のコマンドを実行することで、一撃で修正行数のCSVを取得することが可能です。

※最初の{修正前のブランチ}、{修正後のブランチ}は、比較対象のブランチに書き替えてください。

※コマンド実行前にカレントディレクトリをGitリポジトリのチェックアウト先のルートフォルダにしてください。

```
set old_branch={修正前のブランチ}
set new_branch={修正後のブランチ}

rem (1)修正前のコミットID取得
git checkout %old_branch%
for /f %i in ('git rev-parse HEAD') do set old_commit=%i

rem (2)修正後のブランチに切り替え
git checkout %new_branch%

rem (3)修正したファイルのパス一覧出力
git diff %old_branch% %new_branch% --name-only > filelist.txt

rem (4)修正行数取得
docker run --rm -v %CD%:/workspace -w /workspace aldanial/cloc --diff --by-file --csv --list-file=filelist.txt %old_commit% HEAD > diff.csv
```

## **5. まとめ**

本記事では、Docker上でclocを使って、Gitのブランチ間で変更されたコードの行数を簡単に計測する方法を紹介しました。ローカル環境にclocをインストールすることなく、コンテナで手軽に行数をカウントできるので、環境依存の問題を気にせずに運用できます。

もしこの記事を参考にして、Dockerでclocを使った作業がうまくいったなら、ぜひチームでも共有してみてください。あらゆる開発者にとって、役立つツールとなるはずです。