コマンド紹介シリーズ:scc
コマンド紹介シリーズ記念すべき第10回目は、scc
というコマンドを紹介します。どのような種類のファイルがどれくらいの行数で記述されているかなどを取得できるコマンドとなっています。
なお、第9回は以下になりますので、ぜひご興味があればご覧ください。
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つのツールで実現できるツール
要は、どのようなファイルがあってどれくらいの規模かんで実装されているかを計算してくれるツールであるということです。
実際に使ってみる
インストール
インストール方法は以下のリンクにまとまっています。
私は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つであり、開発言語に査収されない計算方法であるとのことです。
複雑度の計算について
公式ページの内容を元に、以下に要約をまとめます。
- 複雑度の推定値は、実際には同じ言語のファイル間でのみ比較できる数値であり、重み付けをせずに言語を直接比較するために使用すべきではない。理由としては、コード内の分岐文やループ文を探し、そのファイルのカウンターをインクリメントすることで計算されるため
- 言語によってはループの代わりに再帰を使用しているため、複雑度のカウントが低くなることがある
- 同じ言語で書かれたプロジェクト間の推定、またはプロジェクト内で最も複雑なファイルを見つけるのに役立つ(
scc --by-file -s 複雑度
)
なお、具体的な計算方法については以下のWikipediaを参照とのことです。
先ほど記載した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