コード行数計測ツール「cloc」を使ってgitリポジトリのコード行数を解析する

`git diff`コマンドでも各ファイルの追加行数と削除行数を取得することはできますが、 **より詳細に論理LOCを計測する** ためにはコード行数計測ツール「cloc」がオススメです。

`git diff`コマンドについて知りたい方はこちらの記事もご覧ください。  
[git diffの--ignoreオプションにおけるスペース、タブ、改行の扱いを理解する - Qiita](https://qiita.com/toe/items/8a056b87c9e481e07e57)

**確認した動作環境**
OS: macOS Sierra 10.12.5

# 「cloc（Count Lines of Code）」とは

「cloc」は様々な言語のコード行数を **「空行数」、「コメント行数」、「論理LOC」** に分類して計測してくれるオープンソースのツールです。コミット間の差分比較では **「修正行」、「追加行」、「削除行」** に分類して計測することができます。

**ライセンス** : GNU General Public License, v2

--------------------------------------------------------------------------------

[GitHub - AlDanial/cloc: cloc counts blank lines, comment lines, and physical lines of source code in many programming languages.](https://github.com/AlDanial/cloc)<br>
[CLOC -- Count Lines of Code](http://cloc.sourceforge.net/#Languages)

# clocをインストールする

以下のコマンドを入力します。

```
$ brew install cloc
```

たったこれだけのコマンドでインストールは完了です。それでは早速clocを使ってみましょう。

# リポジトリ全体のコード行数を計測する

本稿では参考として[skeeto/sample-java-project: Example Ant-based Java project](https://github.com/skeeto/sample-java-project)のリポジトリをクローンします。

```
$ git clone https://github.com/skeeto/sample-java-project.git
```

以下のコマンドを入力すると **言語別** にコード行数が出力されます。

```
$ cloc path/to/directory
```

本稿の例では以下のように出力されます。

```
$ cloc sample-java-project
      12 text files.
      12 unique files.                              
       4 files ignored.

github.com/AlDanial/cloc v 1.74  T=0.09 s (99.8 files/s, 7683.5 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Ant                              1             22              9            197
XML                              4             52             79            159
Java                             3             16             34             73
Markdown                         1             10              0             42
-------------------------------------------------------------------------------
SUM:                             9            100            122            471
-------------------------------------------------------------------------------
```

## 各項目の定義について

各項目の定義は以下の通りです。

項目      | 説明
------- | --------------------------------------------------------
files   | ファイル数
blank   | 空行数
comment | コメント行数（ファイルの拡張子から言語を判断し、 **言語別に定義されたフィルター** に従って行数を算出する）
code    | 論理LOC（物理LOCから空行数とコメント行数を除いた行数）

**物理LOC = blank + comment + code** の関係が成り立ちます。

--------------------------------------------------------------------------------

[How it Works | CLOC -- Count Lines of Code](http://cloc.sourceforge.net/#How_it_works)

## デフォルトで定義されていない拡張子について

clocでは **「.properties」などのデフォルトで定義されていない拡張子のファイルはカウントされずに無視されてしまいます。**

[Recognized Languages | CLOC -- Count Lines of Code](http://cloc.sourceforge.net/#Languages)からデフォルトで定義されている拡張子を確認することができます。もしデフォルトで定義されていない拡張子について計測したい場合は、定義ファイルを作成する必要があります。

# コミットの差分コード行数を言語別に計測する

以下は **コミットの差分** を比較し、 **言語別** に差分のあるコード行数を出力するコマンドです。

`<set1>`と`<set2>`には変更前後のコミットのハッシュを入力します。

```
$ cloc --diff <set1> <set2>
```

本稿の例では最初のコミットと最新のコミットを比較することとします。

以下のコマンドを入力してリポジトリの最初のコミット・ハッシュを取得します。

```
$ git rev-list --max-parents=0 HEAD
059a26260610ee2878e4929ec3adcc880b43c313
```

以下のコマンドを入力して差分を比較します。

```
$ cloc --diff 059a26260610ee2878e4929ec3adcc880b43c313 HEAD
       3 text files.
      12 text files.
       3 files ignored.                             

github.com/AlDanial/cloc v 1.74  T=0.22 s (4.6 files/s, 4.6 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Ant
 same                            0              0              0             24
 modified                        1              0              1             25
 added                           0             14              8            148
 removed                         0              0              0              1
Markdown
 same                            0              0              0              0
 modified                        0              0              0              0
 added                           1             10              0             42
 removed                         0              0              0              0
Java
 same                            0              0              0              9
 modified                        2              0              0             14
 added                           1              9             34             50
 removed                         0              0              0              0
XML
 same                            0              0              0              0
 modified                        0              0              0              0
 added                           4             52             79            159
 removed                         0              0              0              0
-------------------------------------------------------------------------------
SUM:
 same                            0              0              0             33
 modified                        3              0              1             39
 added                           6             85            121            399
 removed                         0              0              0              1
-------------------------------------------------------------------------------
```

それぞれの項目は以下の意味を示します。

項目       | 意味
-------- | ---------
same     | 変更のなかった行数
modified | 修正された行数
added    | 追加された行数
removed  | 削除された行数

# コミットの差分コード行数をファイル毎に計測し、CSV形式で出力する

clocでは上述の出力結果を **CSV形式** で出力することもできます。

```
$ cloc --diff --by-file --csv 059a262  HEAD
       3 text files.
      12 text files.
       3 files ignored.                             

File, == blank, != blank, + blank, - blank, == comment, != comment, + comment, - comment, == code, != code, + code, - code, "github.com/AlDanial/cloc v 1.74 T=0.214647054672241 s"
src/sample/java/project/SampleJavaProject.java, 0, 0, 8, 0, 0, 0, 16, 0, 4, 5, 42, 0,
build.xml, 0, 0, 14, 0, 0, 1, 8, 0, 24, 25, 148, 1,
test/sample/java/project/SampleJavaProjectTest.java, 0, 0, 1, 0, 0, 0, 15, 0, 5, 9, 7, 0,
checkstyle.xml, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 77, 0,
pmd.xml, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 23, 0,
pom.xml, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 31, 0,
src/sample/java/project/package-info.java, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0,
ivy.xml, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 28, 0,
README.md, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 42, 0,
```

上記の出力結果を以下の表にまとめました。

File                                                | == blank | != blank | + blank | - blank | == comment | != comment | + comment | - comment | == code | != code | + code | - code
--------------------------------------------------- | -------- | -------- | ------- | ------- | ---------- | ---------- | --------- | --------- | ------- | ------- | ------ | ------
ivy.xml                                             | 0        | 0        | 3       | 0       | 0          | 0          | 4         | 0         | 0       | 0       | 28     | 0
pmd.xml                                             | 0        | 0        | 1       | 0       | 0          | 0          | 7         | 0         | 0       | 0       | 23     | 0
checkstyle.xml                                      | 0        | 0        | 44      | 0       | 0          | 0          | 68        | 0         | 0       | 0       | 77     | 0
src/sample/java/project/SampleJavaProject.java      | 0        | 0        | 8       | 0       | 0          | 0          | 16        | 0         | 4       | 5       | 42     | 0
src/sample/java/project/package-info.java           | 0        | 0        | 0       | 0       | 0          | 0          | 3         | 0         | 0       | 0       | 1      | 0
pom.xml                                             | 0        | 0        | 4       | 0       | 0          | 0          | 0         | 0         | 0       | 0       | 31     | 0
test/sample/java/project/SampleJavaProjectTest.java | 0        | 0        | 1       | 0       | 0          | 0          | 15        | 0         | 5       | 9       | 7      | 0
build.xml                                           | 0        | 0        | 14      | 0       | 0          | 1          | 8         | 0         | 24      | 25      | 148    | 1
README.md                                           | 0        | 0        | 10      | 0       | 0          | 0          | 0         | 0         | 0       | 0       | 42     | 0

それぞれの記号は以下の意味を示します。

記号 | 意味
--- | ---------
== | 変更のなかった行数
!= | 修正された行数
+  | 追加された行数
-  | 削除された行数

## さいごに

clocは大変便利なツールですが、 **デフォルトで定義されていない拡張子のファイルはカウントされずに無視されてしまう点** が少し残念に思います。

他にもっと便利なツールをご存知の方がいれば是非教えてください！

--------------------------------------------------------------------------------

[![クリエイティブ・コモンズ・ライセンス](https://i.creativecommons.org/l/by/4.0/88x31.png)](http://creativecommons.org/licenses/by/4.0/)<br>
この 作品 は [クリエイティブ・コモンズ 表示 4.0 国際 ライセンス](http://creativecommons.org/licenses/by/4.0/)の下に提供されています。