본문 바로가기

Language/python

python - cyclomatic complexity 모듈 (lizard)

프로그램 언어 별 Cyclomatic complexity, LOC, Parameter Number를 계산해주는 Python 모듈인 lizard를 소개한다.

C/C++ 언어의 경우에도 헤더 파싱을 안하더라도 간결하게 계산할 수 있어 도움이 많이 될듯 하다.



1. 설치


pip install lizard


2. 사용법


lizard [options] [PATH or FILE] [PATH] ...


  • 옵션 없이 실행하면, 해당 폴더를 포함하여 하부 폴더에 있는 소스코드에 대한 분석을 수행한다.
  • -m : Modified CC를 계산함(switch / case 문은 1로 계산함)
  • -X, --xml : 결과를 xml로 저장함.
  • --csv : 결과를 csv로 저장함.
  • -H, --html : 결과를 html로 저장함.

3. 결과 화면

================================================
  NLOC    CCN   token  PARAM  length  location 
------------------------------------------------
      22      1    143      1     103 set_prefs@5-107@.\.vscode\.ropeproject\config.py
       1      1      6      1       2 project_opened@110-111@.\.vscode\.ropeproject\config.py
     125      1   1207      2     126 setupUi@16-141@.\fir\qt4\MainDlg.py
      20      1    423      2      20 retranslateUi@143-162@.\fir\qt4\MainDlg.py
       2      1     12      2       2 __init__@21-22@.\fir\ClocXmlParser.py
       9      2     51      2      17 openXml@24-40@.\fir\ClocXmlParser.py
       5      2     47      3       5 executeCloc@42-46@.\fir\ClocXmlParser.py
      19      4    120      2      29 parseXml@48-76@.\fir\ClocXmlParser.py
      12      1     80      2      12 __init__@36-47@.\fir\FileInfo.py
       6      2     47      1      12 check_file_type@49-60@.\fir\FileInfo.py
       2      1     10      1       7 get_file_ext@62-68@.\fir\FileInfo.py
       2      1     10      1       7 get_file_type@70-76@.\fir\FileInfo.py
      12      3     71      2      21 read_info@78-98@.\fir\FileInfo.py
       2      1     13      1       6 get_checksum@100-105@.\fir\FileInfo.py
       2      1     13      1       6 get_mtime@107-112@.\fir\FileInfo.py
       2      1     13      1       6 get_size@114-119@.\fir\FileInfo.py
       2      1     13      1       7 get_line_count@121-127@.\fir\FileInfo.py
       6      1     46      1      15 read_crc32@129-143@.\fir\FileInfo.py
       7      1     55      1      16 read_sha1@145-160@.\fir\FileInfo.py
       7      1     55      1      16 read_md5@162-177@.\fir\FileInfo.py
       5      1     44      1      13 read_mtime@179-191@.\fir\FileInfo.py
       3      1     26      1      11 read_size@193-203@.\fir\FileInfo.py
       7      2     47      1      17 read_line_count@205-221@.\fir\FileInfo.py
       3      1     18      2       3 __init__@27-29@.\fir\FilesInfoDB.py
       2      1      9      1       2 get_db@31-32@.\fir\FilesInfoDB.py
       2      1     22      3       9 insert@34-42@.\fir\FilesInfoDB.py
      19      4    152      2      34 to_csv@44-77@.\fir\FilesInfoDB.py
      12      4    119      2      22 to_stdout@79-100@.\fir\FilesInfoDB.py
      19      4    122      3      23 __init__@40-62@.\fir\FilesInfoReader.py
       2      1      9      1       2 get_file_info_db@64-65@.\fir\FilesInfoReader.py
       2      1     12      2       2 set_ignore_pattern@67-68@.\fir\FilesInfoReader.py
       2      1      9      1       2 get_path_ignore_pattern@70-71@.\fir\FilesInfoReader.py
       2      1     13      2       8 set_root_path@73-80@.\fir\FilesInfoReader.py
       7      1     51      2      15 start_cloc@82-96@.\fir\FilesInfoReader.py
       4      3     44      2       4 _walk_dir@98-101@.\fir\FilesInfoReader.py
       5      1     53      4      13 iterate@103-115@.\fir\FilesInfoReader.py
      60     12    443      6      71 _iterate_all_files@117-187@.\fir\FilesInfoReader.py
       9      3     62      1      10 _get_total_size@189-198@.\fir\FilesInfoReader.py
       7      3     52      2      16 save@200-215@.\fir\FilesInfoReader.py
       3      1     17      1       3 setUp@28-30@.\test\test_ClocXmlParser.py
       2      1      6      1       2 tearDown@32-33@.\test\test_ClocXmlParser.py
       3      1     21      1       3 test_parseXml_with_data1@35-37@.\test\test_ClocXmlParser.py
       3      1     21      1       3 test_parseXml_with_nofile@39-41@.\test\test_ClocXmlParser.py
       6      1     62      1       6 test_parseXml_normal_data@43-48@.\test\test_ClocXmlParser.py
       5      1     50      1       5 test_parseXml_normal_data_with_korean_path@50-54@.\test\test_ClocXmlParser.py
       2      1      6      1       2 setUp@26-27@.\test\test_FileInfo.py
       2      1      6      1       2 tearDown@29-30@.\test\test_FileInfo.py
       5      1     41      1       5 test_init@32-36@.\test\test_FileInfo.py
       4      1     24      1       4 test_check_file_type_source_code@38-41@.\test\test_FileInfo.py
       4      1     24      1       4 test_check_file_type_no_source_code@43-46@.\test\test_FileInfo.py
       4      1     24      1       4 test_get_file_ext_1@48-51@.\test\test_FileInfo.py
       4      1     24      1       4 test_get_file_ext_2@53-56@.\test\test_FileInfo.py
       6      1     46      1       6 test_read_info_1@58-63@.\test\test_FileInfo.py
       6      1     46      1       6 test_read_info_2@65-70@.\test\test_FileInfo.py
       2      1      6      1       2 setUp@22-23@.\test\test_FilesInfoReader.py
       2      1      6      1       2 tearDown@25-26@.\test\test_FilesInfoReader.py
       9      1     57      1       9 test_iterate@28-36@.\test\test_FilesInfoReader.py
      14      1     59      0      18 print_usage@24-41@.\FilesInfoReaderMain.py
       4      1     31      2       4 __init__@38-41@.\FilesInfoReaderMainGUI.py
       5      1     35      5       5 set_data@43-47@.\FilesInfoReaderMainGUI.py
       6      2     53      1       6 run@49-54@.\FilesInfoReaderMainGUI.py
      47      1    530      2      65 __init__@60-124@.\FilesInfoReaderMainGUI.py
      16      2    171      1      19 close_app@126-144@.\FilesInfoReaderMainGUI.py
       3      1     22      1       3 _load_config@146-148@.\FilesInfoReaderMainGUI.py
       9      2     63      2      14 change_ignore@151-164@.\FilesInfoReaderMainGUI.py
       9      2     63      2      16 change_cloc_use@166-181@.\FilesInfoReaderMainGUI.py
       9      2     63      2      14 change_ext_only@183-196@.\FilesInfoReaderMainGUI.py
       3      1     26      1       7 show_target_folder_dlg@198-204@.\FilesInfoReaderMainGUI.py
       5      2     42      1       9 show_output_file_dlg@206-214@.\FilesInfoReaderMainGUI.py
       3      1     28      1       7 show_cloc_path_dlg@216-222@.\FilesInfoReaderMainGUI.py
      41     10    257      1      58 read_info@224-281@.\FilesInfoReaderMainGUI.py
       4      3     27      1       4 _all_disable@283-286@.\FilesInfoReaderMainGUI.py
       4      3     27      1       4 _all_enable@288-291@.\FilesInfoReaderMainGUI.py
      11      3     67      2      11 _check_worker@293-303@.\FilesInfoReaderMainGUI.py
       2      1     26      2       7 _warning@305-311@.\FilesInfoReaderMainGUI.py
       2      1     26      2       7 _info@313-319@.\FilesInfoReaderMainGUI.py
13 file analyzed.
==============================================================
NLOC    Avg.NLOC  AvgCCN  Avg.token  function_cnt    file
--------------------------------------------------------------
     23      11.5     1.0       74.5         2     .\.vscode\.ropeproject\config.py
    150      72.5     1.0      815.0         2     .\fir\qt4\MainDlg.py
     53       8.8     2.2       57.5         4     .\fir\ClocXmlParser.py
    107       5.1     1.3       36.2        15     .\fir\FileInfo.py
     61       7.6     2.2       64.0         5     .\fir\FilesInfoDB.py
    152      10.8     2.8       79.1        11     .\fir\FilesInfoReader.py
      5       0.0     0.0        0.0         0     .\fir\__init__.py
     46       3.7     1.0       29.5         6     .\test\test_ClocXmlParser.py
     60       4.1     1.0       26.8         9     .\test\test_FileInfo.py
     33       4.3     1.0       23.0         3     .\test\test_FilesInfoReader.py
      0       0.0     0.0        0.0         0     .\test\__init__.py
     83      14.0     1.0       59.0         1     .\FilesInfoReaderMain.py
    222      10.2     2.2       86.5        18     .\FilesInfoReaderMainGUI.py

=============================================================================================
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
------------------------------------------------------------------------------------------
       995       9.3     1.7       76.9       76            0      0.00    0.00



4. 기타


파이썬 모듈로써 활용할 수 있다.

>>> import lizard

>>> i = lizard.analyze_file("../cpputest/tests/AllTests.cpp")

>>> print i.__dict__

{'nloc': 9, 'function_list': [<lizard.FunctionInfo object at 0x10bf7af10>], 'filename': '../cpputest/tests/AllTests.cpp'} >>> print i.function_list[0].__dict__ {'cyclomatic_complexity': 1, 'token_count': 22, 'name': 'main', 'parameter_count': 2, 'nloc': 3, 'long_name': 'main( int ac , const char ** av )', 'start_line': 30}