🤖

コマンド紹介シリーズ:scc

に公開

コマンド紹介シリーズ記念すべき第10回目は、sccというコマンドを紹介します。どのような種類のファイルがどれくらいの行数で記述されているかなどを取得できるコマンドとなっています。

なお、第9回は以下になりますので、ぜひご興味があればご覧ください。

https://zenn.dev/akasan/articles/facccc0169d83b

sccとは?

sccとは公式GitHubによると、

A tool similar to cloc, sloccount and tokei. For counting the lines of code, blank lines, comment lines, and physical lines of source code in many programming languages.
Goal is to be the fastest code counter possible, but also perform COCOMO calculation like sloccount, estimate code complexity similar to cyclomatic complexity calculators and produce unique lines of code or DRYness metrics. In short one tool to rule them all.

ということで、まとめると以下になります。

  • cloc、sloccount、tokeiに似たツールであり、様々なプログラミング言語のコード行数、空行数、コメント行数、そしてソースコードの物理行数をカウント
  • 目標は最速のコードカウンターを実現することであり、sloccountのようなCOCOMO計算、循環的複雑度計算ツールのようなコード複雑度の推定、そして一意のコード行数やDRY度メトリクスの生成も行う。これら全てを1つのツールで実現できるツール

要は、どのようなファイルがあってどれくらいの規模かんで実装されているかを計算してくれるツールであるということです。

https://github.com/boyter/scc

実際に使ってみる

インストール

インストール方法は以下のリンクにまとまっています。

https://github.com/boyter/scc?tab=readme-ov-file#install

私はmacbookを使っているので、以下のコマンドでインストールできます。

brew install scc

ファイル構成の取得

今回はsccのGitレポジトリをcloneし、sccのプロジェクトについて結果をみてみようと思います。以下の手続きを実行することで、sccプロジェクトに対してsccコマンドを適用できます。

git clone git@github.com:boyter/scc.git
scc scc

実行すると、記事執筆時点では以下のような結果になりました。

───────────────────────────────────────────────────────────────────────────────
Language                 Files     Lines   Blanks  Comments     Code Complexity
───────────────────────────────────────────────────────────────────────────────
Go                          30     22718     1439       440    20839       1369
Java                        24      3913      798       651     2464        547
Python                      16       659       99        80      480         98
JavaScript                  12       225        4        26      195         53
Markdown                    10      1569      359         0     1210          0
YAML                         7       376       65        61      250          0
CSS                          5        24        0        19        5          0
License                      3        10        4         0        6          0
Makefile                     3         3        0         0        3          0
Plain Text                   3        33        7         0       26          0
Shell                        3      1467      168        82     1217        113
C#                           2       623       83       130      410         45
C++                          2        29        1         2       26          4
Clipper                      2        56       12        19       25          0
Dockerfile                   2        15        3         0       12          0
JSON                         2      8173        1         0     8172          0
JavaServer Pages             2         1        0         0        1          0
Lua                          2        53       13         3       37          9
PHP                          2         1        0         0        1          0
Perl                         2        10        1         2        7          2
Powershell                   2       240       35       159       46          8
TypeScript                   2        20        0        18        2          0
AWK                          1        28        4         1       23          4
Alchemist                    1        20        0         0       20         55
Alloy                        1        50        6        40        4          0
Arturo                       1       417       66        89      262         20
BASH                         1         1        0         0        1          0
Bicep                        1        50        8         5       37          4
Bitbucket Pipeline           1        23        1         0       22          0
Boo                          1         1        0         0        1          0
Bosque                       1       179       32         8      139          1
C                            1         0        0         0        0          0
C Header                     1       235        1        67      167         14
C Shell                      1         1        0         0        1          0
CMake                        1        28        4         1       23          4
Cairo                        1        28        3         0       25          4
Cangjie                      1        27        5         2       20          2
Cap'n Proto                  1        27        5         1       21          0
Chapel                       1        14        0         2       12          0
Circom                       1        34        4         7       23          2
Clojure                      1         1        0         0        1          0
CloudFormation (JSO…         1       407        0         0      407          0
CloudFormation (YAM…         1       150       16         1      133         19
Coq                          1       168       18         9      141          5
Cuda                         1        43        8         7       28          3
DM                           1        21        2         7       12          4
DOT                          1        12        0         5        7          0
Docker ignore                1         3        0         1        2          0
Elm                          1         6        1         0        5          1
Extensible Styleshe…         1         0        0         0        0          0
F#                           1         3        0         0        3          1
FSL                          1       151       36         1      114         33
FXML                         1         9        1         0        8          0
Factor                       1        23        4         1       18          2
Flow9                        1        21        3         6       12          5
Freemarker Template          1         0        0         0        0          0
Futhark                      1        29        3        10       16          2
Gemfile                      1         1        0         0        1          0
Gherkin Specificati…         1         0        0         0        0          0
Go Template                  1        62        1         0       61          0
GraphQL                      1     61602     9958     36881    14763       1533
HAML                         1        14        3         1       10          0
HTML                         1       308        0         0      308          0
Hare                         1        39        8         1       30          7
INI                          1        10        1         2        7          0
JSONC                        1         9        0         6        3          0
Jsonnet                      1        40        6         5       29          3
Korn Shell                   1         1        0         0        1          0
LALRPOP                      1        36        7         3       26          0
LLVM IR                      1         5        0         1        4          0
Luau                         1        16        2         1       13          4
Luna                         1        23        5         1       17          0
MATLAB                       1       471       55        67      349         54
Macromedia eXtensib…         1         0        0         0        0          0
Monkey C                     1        74       12         0       62         12
Nushell                      1        22        2         2       18          2
Objective C                  1       896      150        66      680         57
OpenQASM                     1        89       10        21       58         14
Pkl                          1        39        7        21       11          0
Q#                           1        31        6         2       23          5
R                            1        12        3         1        8          2
Racket                       1       107       14         2       91         33
Rakefile                     1         1        0         0        1          0
Report Definition L…         1         0        0         0        0          0
Sieve                        1       192       14        14      164         47
Slang                        1        15        2         5        8          0
Slint                        1        72        5         2       65          9
Snakemake                    1        67       13        10       44          0
Teal                         1        15        0         6        9          2
Templ                        1         9        1         0        8          1
Terraform                    1        31        7         6       18         21
Textile                      1         9        2         6        1          0
TypeSpec                     1        19        4         0       15          0
Typst                        1        16        4         3        9          0
V                            1        73        8        30       35          3
Vala                         1        20        1         1       18          0
Varnish Configurati…         1         0        0         0        0          0
Verilog                      1        79        7        21       51          2
Web Services Descri…         1         1        0         0        1          0
Windows Resource-De…         1        51        6         6       39          0
Wren                         1       188       26        37      125          8
XML Schema                   1         1        0         0        1          0
Yarn                         1        30        4         0       26          5
Zig                          1        13        1         0       12          2
ZoKrates                     1        16        2         5        9          2
Zsh                          1         1        0         0        1          0
nuspec                       1        22        0         0       22          0
wenyan                       1        12        0         1       11          0
───────────────────────────────────────────────────────────────────────────────
Total                      224    107288    13680     39200    54408       4261
───────────────────────────────────────────────────────────────────────────────
Estimated Cost to Develop (organic) $1,794,904
Estimated Schedule Effort (organic) 17.18 months
Estimated People Required (organic) 9.28
───────────────────────────────────────────────────────────────────────────────
Processed 3223184 bytes, 3.223 megabytes (SI)
───────────────────────────────────────────────────────────────────────────────

結果を見ると、goのファイルが最も多く30ファイルあり、コードの総行数は20000行を超えているということです。

出力結果の見方

先ほどの例で出力されていた結果にはいくつかの項目がありましたが、それぞれが意味することは以下になります。

  • Language: 利用されている言語
  • Files: ファイル数
  • Lines: 行数
  • Blanks: 空行の数
  • Comments: コメント行数
  • Code: Lines-Blanks-Comments
  • Complexity:複雑度(後述)
  • Estimated Cost to Develop: COCOMOで計算された開発コスト
  • Estimated Schedule Effort: COCOMOで計算された開発期間
  • Estimated People Required: COCOMOで計算された必要な開発者数

なお、COCOMOとはWikipediaによると、ソフトウェア開発の工数、開発期間の見積もり手法の1つであり、開発言語に査収されない計算方法であるとのことです。

https://ja.wikipedia.org/wiki/COCOMO

複雑度の計算について

公式ページの内容を元に、以下に要約をまとめます。

  • 複雑度の推定値は、実際には同じ言語のファイル間でのみ比較できる数値であり、重み付けをせずに言語を直接比較するために使用すべきではない。理由としては、コード内の分岐文やループ文を探し、そのファイルのカウンターをインクリメントすることで計算されるため
  • 言語によってはループの代わりに再帰を使用しているため、複雑度のカウントが低くなることがある
  • 同じ言語で書かれたプロジェクト間の推定、またはプロジェクト内で最も複雑なファイルを見つけるのに役立つ(scc --by-file -s 複雑度

なお、具体的な計算方法については以下のWikipediaを参照とのことです。

https://en.wikipedia.org/wiki/Cyclomatic_complexity

先ほど記載したscc --by-fileというオプションをつけて実行すると、言語ごとにまとめられるのではなく個々のファイルに対して計算結果を表示できます。例えばsccレポジトリで標準出力の20行分を確認すると以下のように個別のファイルについて集計結果が確認できます。

scc scc --by-file | head -20
───────────────────────────────────────────────────────────────────────────────
Language                 Files     Lines   Blanks  Comments     Code Complexity
───────────────────────────────────────────────────────────────────────────────
Go                          30     22718     1439       440    20839       1369
───────────────────────────────────────────────────────────────────────────────
~er/scc/processor/constants.go     13250        1         2    13247          0
~scc/processor/workers_test.go      1586      296        33     1257        287
~r/scc/processor/formatters.go      1459      201        31     1227        152
~/processor/formatters_test.go      1415      146         3     1266        118
~yter/scc/processor/workers.go       834      124        95      615        205
~er/scc/processor/processor.go       624      132       103      389         79
~github.com/boyter/scc/main.go       459       12         8      439         17
~boyter/scc/cmd/badges/main.go       431       70        17      344         65
~cc/processor/detector_test.go       420       94         3      323        109
~ocessor/workers_tokei_test.go       249       37         2      210         40
~ter/scc/processor/detector.go       226       41        33      152         54
~er/scc/processor/file_test.go       213       50         1      162         37
~or/workers_regression_test.go       212       42         5      165         42
~yter/scc/processor/structs.go       202       21        18      163         17
~r/scc/cmd/badges/main_test.go       199        6         0      193         10

先ほどの結果の通りgo全体の結果は変わらず、個別のスクリプトについて集計結果が取得できていることがわかります。

オプションについて

sccでは様々なオプションが提供されていますが、その中で個人的に使うコマンドについて紹介します。

  • --by-file: 個別のスクリプトについて結果を表示させる(先ほどの例)
  • -m,--character: 1行あたりの最大文字数と平均文字数を計算する
scc scc -m | head -20

# 結果
───────────────────────────────────────────────────────────────────────────────
Language                 Files     Lines   Blanks  Comments     Code Complexity
───────────────────────────────────────────────────────────────────────────────
Go                          30     22718     1439       440    20839       1369
MaxLine / MeanLine        1189        18
-------------------------------------------------------------------------------
Java                        24      3913      798       651     2464        547
MaxLine / MeanLine         112        31
-------------------------------------------------------------------------------
Python                      16       659       99        80      480         98
MaxLine / MeanLine        1051        27
-------------------------------------------------------------------------------
JavaScript                  12       225        4        26      195         53
MaxLine / MeanLine      390864      3480
-------------------------------------------------------------------------------
Markdown                    10      1569      359         0     1210          0
MaxLine / MeanLine         446        42
-------------------------------------------------------------------------------
YAML                         7       376       65        61      250          0
MaxLine / MeanLine         143        30
  • --cocomo-project-type: COCOMOモデルタイプの変更(選択肢:organic, semi-detached, embedded, custom,1,1,1,1, デフォルトはorganic)
scc scc --cocomo-project-type organic | tail -10

# 結果
wenyan                       1        12        0         1       11          0
───────────────────────────────────────────────────────────────────────────────
Total                      224    107288    13680     39200    54408       4261
───────────────────────────────────────────────────────────────────────────────
Estimated Cost to Develop (organic) $1,794,904
Estimated Schedule Effort (organic) 17.18 months
Estimated People Required (organic) 9.28
───────────────────────────────────────────────────────────────────────────────
Processed 3223184 bytes, 3.223 megabytes (SI)
───────────────────────────────────────────────────────────────────────────────

#######################################
scc scc --cocomo-project-type semi-detached | tail -10

# 結果
wenyan                       1        12        0         1       11          0
───────────────────────────────────────────────────────────────────────────────
Total                      224    107288    13680     39200    54408       4261
───────────────────────────────────────────────────────────────────────────────
Estimated Cost to Develop (semi-detached) $2,967,888
Estimated Schedule Effort (semi-detached) 17.59 months
Estimated People Required (semi-detached) 14.99
───────────────────────────────────────────────────────────────────────────────
Processed 3223184 bytes, 3.223 megabytes (SI)
───────────────────────────────────────────────────────────────────────────────
  • -p, --percent: パーセンテージも表示する
scc scc -p | head -20

# 結果
───────────────────────────────────────────────────────────────────────────────
Language                 Files     Lines   Blanks  Comments     Code Complexity
───────────────────────────────────────────────────────────────────────────────
Go                          30     22718     1439       440    20839       1369
Percentage               13.4%     21.2%    10.5%      1.1%    38.3%      32.1%
-------------------------------------------------------------------------------
Java                        24      3913      798       651     2464        547
Percentage               10.7%      3.6%     5.8%      1.7%     4.5%      12.8%
-------------------------------------------------------------------------------
Python                      16       659       99        80      480         98
Percentage                7.1%      0.6%     0.7%      0.2%     0.9%       2.3%
-------------------------------------------------------------------------------
JavaScript                  12       225        4        26      195         53
Percentage                5.4%      0.2%     0.0%      0.1%     0.4%       1.2%
-------------------------------------------------------------------------------
Markdown                    10      1569      359         0     1210          0
Percentage                4.5%      1.5%     2.6%      0.0%     2.2%       0.0%
-------------------------------------------------------------------------------
YAML                         7       376       65        61      250          0
Percentage                3.1%      0.4%     0.5%      0.2%     0.5%       0.0%
  • --binary: バイナリファイルの検出を無効

まとめ

今回はプロジェクトのファイル構成から様々な情報を自動計測してくれるsccについて紹介しました。レポジトリの規模間であったりどのようなコストがかかっているかの見積もりなどができるツールであるため、ぜひ自分の携わっているレポジトリに対して使ってみてはいかがでしょうか!

Discussion