Help us understand the problem. What is going on with this article?

サイクロマティック複雑度の計測ツール「lizard」のセットアップ&使い方

More than 1 year has passed since last update.

「lizard」とは?

コマンドラインのサイクロマティック複雑度(以下、CCN)計測ツールです。
OSSなのでフリーで使えます。

CCNについては別記事で説明しているので、そちらをご参照ください。

環境

  • OS:macOS High Sierra 10.13.1
  • Python:3.6.1
  • pip:9.0.1
  • lizard:1.14.10
  • jinja2:2.10

セットアップ

Python環境の構築

lizardはPython製なので、Pythonのインストールが必要です。
Python環境の構築についてはこちらの記事をご参照ください。

私は以下のようなPython環境を作成しました。

$ pyenv virtualenv 3.6.1 CCNAnalyzer

lizardのインストール

pipでインストールします。

$ pip install lizard
Collecting lizard
  Using cached https://files.pythonhosted.org/packages/25/78/4fad2f578ce5b42f9f635a27f81d1332183e9f14b506a158e298ec759f03/lizard-1.14.10-py2.py3-none-any.whl
Installing collected packages: lizard
Successfully installed lizard-1.14.10
You are using pip version 9.0.1, however version 10.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

pipが古いと怒られましたが、無事にインストールできました。

操作方法

標準出力

今回はSwiftLintのソースをお借りして、CCNを計測してみます。

-l オプションの値は言語に応じて変更してください。

# プロジェクトのルートフォルダへ移動する
$ cd SwiftLint/Source/swiftlint/

# CCNを計測する
$ lizard -l swift
================================================
  NLOC    CCN   token  PARAM  length  location
------------------------------------------------
       8      3     38      2       8 report@12-19@./Extensions/Reporter+CommandLine.swift
       4      2     39      2       4 reporterFrom@22-25@./Extensions/Reporter+CommandLine.swift
      34      6    238      0      36 scriptInputFiles@16-51@./Extensions/Configuration+CommandLine.swift
       1      1     14      1       1 autoreleasepool@54-54@./Extensions/Configuration+CommandLine.swift
      55      8    400      8      55 visitLintableFiles@59-113@./Extensions/Configuration+CommandLine.swift
      17      6    136      5      17 getFiles@115-131@./Extensions/Configuration+CommandLine.swift
       7      2     74      1       7 init@135-141@./Extensions/Configuration+CommandLine.swift
       6      1     80      3       6 visitLintableFiles@143-148@./Extensions/Configuration+CommandLine.swift
       6      2     68      1       6 init@152-157@./Extensions/Configuration+CommandLine.swift
       4      1     34      1       4 init@161-164@./Extensions/Configuration+CommandLine.swift
      14      3     79      1      15 print@19-33@./Commands/RulesCommand.swift
      16      5    138      1      20 run@39-58@./Commands/RulesCommand.swift
      17      7    107      2      21 ruleList@60-80@./Commands/RulesCommand.swift
       8      2     73      1       8 create@90-97@./Commands/RulesCommand.swift
      12      1     88      1      12 evaluate@99-110@./Commands/RulesCommand.swift
      40      6    275      2      40 init@116-155@./Commands/RulesCommand.swift
       9      1     51      0       9 currentWidth@159-167@./Commands/RulesCommand.swift
      48      8    392      1      48 run@20-67@./Commands/LintCommand.swift
       9      3     50      2       9 successOrExit@69-77@./Commands/LintCommand.swift
       9      2     51      3       9 printStatus@79-87@./Commands/LintCommand.swift
       6      1     51      2       6 isWarningThresholdBroken@89-94@./Commands/LintCommand.swift
      13      1     65      1      13 createThresholdViolation@96-108@./Commands/LintCommand.swift
      15      3     78      2      15 applyLeniency@110-124@./Commands/LintCommand.swift
       5      1    185      1       5 create@142-146@./Commands/LintCommand.swift
      24      1    225      1      25 evaluate@148-172@./Commands/LintCommand.swift
       4      1     43      1       4 run@17-20@./Commands/VersionCommand.swift
      25      6    206      1      26 run@17-42@./Commands/AutoCorrectCommand.swift
       5      1    125      1       5 create@56-60@./Commands/AutoCorrectCommand.swift
      17      1    143      1      18 evaluate@62-79@./Commands/AutoCorrectCommand.swift
      13      3     90      1      15 run@17-31@./Commands/GenerateDocsCommand.swift
       3      1     20      1       3 create@37-39@./Commands/GenerateDocsCommand.swift
       6      1     47      1       6 evaluate@41-46@./Commands/GenerateDocsCommand.swift
       3      1     13      1       3 init@21-23@./Helpers/Benchmark.swift
       3      1     27      2       3 record@25-27@./Helpers/Benchmark.swift
       3      1     30      2       3 record@29-31@./Helpers/Benchmark.swift
      14      2    153      0      15 save@33-47@./Helpers/Benchmark.swift
       5      1     28      1       5 pathOption@12-16@./Helpers/CommonOptions.swift
       6      1     30      1       6 quietOption@27-32@./Helpers/CommonOptions.swift
10 file analyzed.
==============================================================
NLOC    Avg.NLOC  AvgCCN  Avg.token  function_cnt    file
--------------------------------------------------------------
     15       6.0     2.5       38.5         2     ./Extensions/Reporter+CommandLine.swift
    140      16.2     3.4      130.5         8     ./Extensions/Configuration+CommandLine.swift
    139      16.6     3.6      115.9         7     ./Commands/RulesCommand.swift
    153      16.1     2.5      137.1         8     ./Commands/LintCommand.swift
     11       4.0     1.0       43.0         1     ./Commands/VersionCommand.swift
     64      15.7     2.7      158.0         3     ./Commands/AutoCorrectCommand.swift
     32       7.3     1.7       52.3         3     ./Commands/GenerateDocsCommand.swift
     44       5.8     1.2       55.8         4     ./Helpers/Benchmark.swift
     20       5.5     1.0       29.0         2     ./Helpers/CommonOptions.swift
     17       0.0     0.0        0.0         0     ./main.swift

=============================================================================================
No thresholds exceeded (cyclomatic_complexity > 15 or length > 1000 or parameter_count > 100)
==========================================================================================
Total nloc   Avg.NLOC  AvgCCN  Avg.token   Fun Cnt  Warning cnt   Fun Rt   nloc Rt
------------------------------------------------------------------------------------------
       635      13.0     2.6      104.8       38            0      0.00    0.00

メソッドごとのCCN→ファイルごとのCCN平均→全ファイルのCCN平均 の順で出力されます。

「メソッドごとのCCN」について、各列の意味は以下の通りです。

説明
NLOC Number Line Of Code コードの行数(コメントを除く)
CCN Cyclomatic Complexity Number サイクロマティック複雑度
token -
PARAM PARAMeter メソッドの引数の数
length - NLOCから空行を除いた行数
location - {メソッド名}@{開始行}-{終了行}@{ファイルパス}

ファイルごとや全ファイルについての出力もほぼ同様です。

出力結果の見方がわかったところで流石のSwiftLintです。CCNが全メソッドで1桁に収まっています。

CSV出力

標準出力だと使いづらいので lizard --help でオプションを確認したところ、他にも様々な形式で出力できることがわかりました。

--csvオプションを付けることで、CSV形式で出力されます。
Python環境が構築されていることですし、pandasやmatplotlibを使ってグラフ化するのもよさそうです。

# 出力結果をCSVファイルへ出力する
$ lizard -l swift --csv > ~/Desktop/SwiftLint_CCN.csv

出力結果

CSVの場合はメソッドごとのCCNのみ出力されるようです。
ヘッダー(1行目)は出力されなかったので、公式のGitHubなどを参考にして付けました。

SwiftLint_CCN.csv
nloc,ccn,token_count,parameter_count,length,location,filepath,method_name,method_long_name,start_line,end_line
8,3,38,2,7,"report@12-19@./Extensions/Reporter+CommandLine.swift","./Extensions/Reporter+CommandLine.swift","report","report violations : [ StyleViolation ] , realtimeCondition : Bool",12,19
4,2,39,2,3,"reporterFrom@22-25@./Extensions/Reporter+CommandLine.swift","./Extensions/Reporter+CommandLine.swift","reporterFrom","reporterFrom options : LintOptions , configuration : Configuration",22,25
34,6,238,0,35,"scriptInputFiles@16-51@./Extensions/Configuration+CommandLine.swift","./Extensions/Configuration+CommandLine.swift","scriptInputFiles","scriptInputFiles",16,51
…
6,1,30,1,5,"quietOption@27-32@./Helpers/CommonOptions.swift","./Helpers/CommonOptions.swift","quietOption","quietOption action : String",27,32

HTML出力

--html オプションを付けることで、HTML形式で出力されます。

# 出力結果をHTMLで出力する
$ lizard -l swift --html > ~/Desktop/SwiftLint_CCN.html
HTML Output depends on jinja2. `pip install jinja2` first

出力に失敗しました。
HTML形式で出力する場合、jinja2というツールも必要とのことです。

lizardと同じくpipでインストールします。

$ pip install jinja2

これで再度コマンドを実行するとHTMLで出力されます。

出力結果

標準出力やCSVよりグラフィカルで見やすいです。

CSVと同様、メソッドごとのCCNのみ出力されるようです。

スクリーンショット 2018-04-22 18.03.53.png

SwiftLintは優秀なので出力されませんでしたが、CCNがしきい値(デフォルトだと15)を超えると[Cyclomatic complexity]列の背景色が緑から赤に変わります。

参考リンク

uhooi
iOSアプリ開発とSwiftが好きです✨ 趣味:テニス、アナログゲーム
https://theuhooi.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away