ファイル数、コード行数をサクッと調べる方法

## はじめに

本記事は [with Advent Calendar 2021](https://qiita.com/advent-calendar/2021/with) 15日目の記事です。

こんにちは [with](https://with.is/welcome) でAndroid エンジニアをしている石田です。

突然ですがコードを書いていてふと、ソースコードの総ファイル数や総行数などをカウントしたくなる時はありませんか...？ 本記事ではこういう時に便利なコマンドとその使用例を紹介します。

## コマンド

前提としてノイズになる  `.gitignore` で指定されている ファイル/ディレクトリ を除外してカウントしてくれるコマンドが必要です。また、できるだけ使い方がシンプルで覚えやすいものがよさそうです。本記事では `cloc` `fd` `ag` `wc` の4つのコマンドを使用します。インストール方法等については参照先のURLをご覧ください。


| コマンド | URL | 説明 |
| - | - | - |
| cloc | [https://github.com/AlDanial/cloc](https://github.com/AlDanial/cloc) | ソースコードの行数をカウントすることに特化したコマンドです。 |
| fd | [https://github.com/sharkdp/fd](https://github.com/sharkdp/fd) | ファイルを検索できる find コマンドを使いやすくしたコマンドです。 |
| ag | https://github.com/ggreer/the_silver_searcher | コードを検索できる ack コマンドより高速に動作するコマンドです。
| wc | https://www.freebsd.org/cgi/man.cgi?query=wc | 文字数や行数をカウントできる標準のLinuxコマンドです。 |

## 使用例

### ソースコードの総ファイル数や総行数をカウントしたい

`cloc` コマンドを使います。ポイントは`--vcs=git` オプションを設定することで、このオプションにより `.gitignore` を考慮してカウントしてくれます。

実行するとこんな感じの結果が得られます。`files` がファイル数、 `code` が行数です。

```shell
❯ cloc . --vcs=git                                             
     549 text files.
     525 unique files.                                          
      72 files ignored.

github.com/AlDanial/cloc v 1.90  T=1.21 s (429.9 files/s, 21029.7 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Kotlin                         343           2316           1278          16631
XML                            151            451             29           3054
Gradle                          17             81              7            840
Markdown                         3             87              0            305
Bourne Shell                     1             21             22            129
DOS Batch                        1             23              2             59
YAML                             2              0              0             53
ProGuard                         1              0              0              1
-------------------------------------------------------------------------------
SUM:                           519           2979           1338          21072
-------------------------------------------------------------------------------
```

### 特定の言語のみをカウントしたい

**【clocを使う方法】**

 `-include-ext=<拡張子>` オプションを追加します。実行するとこんな感じの結果が得られます。


```shell
❯ cloc . --vcs=git --include-ext=xml
     549 text files.
     525 unique files.                                          
     440 files ignored.

github.com/AlDanial/cloc v 1.90  T=1.15 s (131.4 files/s, 3074.5 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
XML                            151            451             29           3054
-------------------------------------------------------------------------------
SUM:                           151            451             29           3054
-------------------------------------------------------------------------------
```

**【fdを使う方法】**

カウント対象をもう少し厳密に絞りたい場合には `fd` コマンドも覚えておくと便利です。

`fd` コマンドはデフォルトで `.gitignore` を考慮してくれます。`-e <拡張子>` オプションで特定の拡張子に絞り込めます。また、`-p <パターン>` オプションでフルパスがパターンにマッチするものに絞り込めます。

例えば Android のプロジェクトで `layout` ディレクトリ配下のXMLだけをカウントしたい場合はこんな感じでカウントできます。

```bash
❯ fd -e xml -p layout | wc
      76      76    4797
```

### 特定文字列を含むファイル数をカウントしたい

**[負債を Redash で可視化する](https://qiita.com/maxfie1d/items/383490621a77fc24692e)** の記事でも例として取りあげた RxJava が何個のファイルで使われているかを計測してみます。

`ag`コマンドを使います。 `-c` オプションでファイル名とマッチしたカウントだけを表示するようにしています。簡単すぎてちょっとあっけないですが、ちゃんとカウントできています。

```bash
❯ ag -c "import io.reactivex" | wc  
      92      92   10366
```

## まとめ

- `cloc` `fd` `ag` `wc` コマンドを使ってソースコードの様々な数値をカウントをする方法を紹介しました。
- これらのコマンドを組み合わせることでちょっとした計測を簡単に実現できるので覚えておいて損はないと思います 👍