사이클로매틱 복잡도 측정 툴 "lizard"설정 및 사용법

"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

  • 설정



    파이썬 환경 구축



    lizard는 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
    메소드의 인수의 수

    길이
    -
    NLOC에서 빈 줄을 제외한 행 수

    location
    -
    {메소드 이름}@{시작행}-{종료행}@{파일 경로}


    모든 파일과 모든 파일에 대한 출력도 거의 같습니다.

    출력 결과의 견해를 알 수 있었던 곳에서 유석의 SwiftLint입니다. CCN이 모든 방법으로 한 자리에 맞습니다.

    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 만 출력되는 것 같습니다.



    SwiftLint는 우수하기 때문에 출력되지 않았지만 CCN이 임계값(기본값이면 15)을 초과하면 [Cyclomatic complexity] 열의 배경색이 녹색에서 빨간색으로 바뀝니다.

    참고 링크


  • ‎terryyin/lizard: A simple code complexity analyser without caring about the C/C++ header files or Java imports, supports most of the popular languages.
  • Objective-C의 순환 복잡도 측정 - Qiita
  • lizard에서 McCabe의 순환 복잡도 측정 - Qiita
  • 좋은 웹페이지 즐겨찾기