cloc是什么

cloc是Count Lines of Code的缩写,根据名字可以看出是一个统计代码量的开源工具。地址点这里

在我们第一次接触一个项目的时候,Cloc能帮助我们回答两个问题:

  • 这个项目有多大?
  • 这个项目用什么写的?

Overview

cloc完全使用Perl语言实现,并且没有任何外部依赖(一些需要使用的外部模块,已经被cloc包含进去了)。因此,cloc的可移植性非常好,只要有Perl v5.6及以上的执行环境即可运行。目前已知cloc可以运行在多种Linux发行版、FreeBSD、NetBSD、OpenBSD、macOS、AIX、HP-UX、Solaris、IRIX、z/OS以及Windows上。

cloc已经可以识别很多种编程语言的源代码行、注释行、空白行。给定两个版本的代码库源码,cloc还能计算出源码行、注释行、空白行的差异。

Quick Start

Install cloc

这里仅以macOS下使用Homebrew安装为例。执行如下命令:

brew install cloc

即可完成安装过程,非常方便。感谢Homebrew。

终端执行cloc -v可以查看cloc用法的简要说明:

➜  ~ cloc -v

                       cloc -- Count Lines of Code

Usage:
    cloc [options] <file(s)/dir(s)/git hash(es)>
        Count physical lines of source code and comments in the given files
        (may be archives such as compressed tarballs or zip files) and/or
        recursively below the given directories or git commit hashes.
        Example:    cloc src/ include/ main.c

    cloc [options] --diff <set1>  <set2>
        Compute differences of physical lines of source code and comments
        between any pairwise combination of directory names, archive
        files or git commit hashes.
        Example:    cloc --diff Python-3.5.tar.xz python-3.6/

cloc --help  shows full documentation on the options.
https://github.com/AlDanial/cloc has numerous examples and more information.
➜  ~

Run cloc

我们就以cloc项目本身为例,使用cloc来统计代码信息。

首先git clone源码工程:

➜  ~ git clone https://github.com/cloudevents/spec.git

然后执行cloc命令:

➜  ~ cloc spec/
      51 text files.
      51 unique files.
       4 files ignored.

github.com/AlDanial/cloc v 1.90  T=0.05 s (965.0 files/s, 163426.5 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
Markdown                        39           1566              0           5483
Bourne Shell                     3            100            158            449
JSON                             2              1              0            191
YAML                             2             14             19             67
Protocol Buffers                 1             12             15             32
make                             1              1              0             21
-------------------------------------------------------------------------------
SUM:                            48           1694            192           6243
-------------------------------------------------------------------------------
➜  ~

可以看到cloc先输出了各类文件数量,然后分析了各类文件的空白行、注释行、代码行数量,最后还给出了汇总值,非常清晰明了。

Why Use cloc

cloc拥有众多优秀的特性,使得它易用、纯粹、可扩展以及可移植:

  1. 只有一个自包含的文件,几乎没有安装过程:下载并执行即可(需要有Perl执行环境)。
  2. 可以从源文件中读取语言注释定义,所以理论上cloc可以和尚不存在的计算机语言一起工作。
  3. 可以按语言或项目分多次运行,并将结果合并输出。
  4. 可以输出各种格式的结果:纯文本、SQL、JSON、XML、YAML、逗号分隔的值列表等。
  5. 可以从压缩文件中统计代码信息(目前支持tar、zip、ear类型)。
  6. 拥用众多的问题排查参数。
  7. 支持文件或目录名中空格与异常字符的处理。
  8. 除了标准Perl之外,没有任何外部依赖。
  9. 可以运行在Linux、FreeBSD、NetBSD、OpenBSD、macOS、AIX、HP-UX、Solaris、IRIX和z/OS等具有Perl 5.6或以上版本的系统上。源码版本可以在Windows上使用ActiveState Perl、Strawberry Perl、Cygwin或MobaXTerm+Perl插件运行。另外,在Windows上还可以运行没有依赖性的Windows二进制文件。

How it Works

简单来说,cloc的执行方式类似SLOCCount:首先创建一个要扫描的文件列表,然后尝试确认文件中是否包含已知的计算机语言源码,最后对完成确认的文件执行对应语言的例程来计算相关行数量。

如果想要了解细节版本,请继续向下看:

  1. 如果输入文件是一个压缩文件(例如.tar.gz或.zip),cloc会创建一个临时目录然后使用系统工具(例如tar、bzip2、unzip等)将压缩文件的内容解压到这个目录中,最后将这个临时目录作为一个扫描的输入源。(该过程在类Unix系统中比在Windows系统中更稳定)
  2. 使用File::Find递归查找输入目录,并组成待扫描的文件列表。这个过程会忽略二进制文件和空文件。
  3. 确保待扫描文件的内容都是不同的(首先通过文件大小比较,然后对相似大小的文件用Digest::MD5做MD5比较)。相同内容的文件按字符顺序排序,只保留第一个文件做扫描,其余相似文件会排除在待扫描文件列表与最终输出结果之外。(使用–skip-uniqueness参数可以关闭文件内容检测,并强制将所有文件都包括在输出结果中。)
  4. cloc根据待扫描文件的扩展名做分类,并匹配到相关的计算机语言(cloc支持的计算机语言与扩展,可以通过–show-lang和–show-ext参数查看)。为匹配到的文件会被排除在待扫描文件列表之外。对于没有扩展名的文件,cloc会读取文件第一行判断是否shell脚本(以#!开头)。如果是shell脚本,该文件就被归入脚本语言。如果待扫描文件即没有扩展名也不是脚本语言,也会被排除在待扫描文件列表之外。
  5. 到此,待扫描文件列表中都是可识别源码的文件了。对每个文件,cloc会执行如下操作:
    • 把整个文件内容读到内存中。
    • 统计所有行数(= L_original)。
    • 移除所有空行,再统计一遍(= L_non_blank)。
    • 查找对应计算机语言的注释过滤器(例如C++有两个注释过滤器:一个处理//开头的注释;另一个处理/*和*/包含的注释)。然后依次使用过滤器来删除注释行,得到剩余的源代码行数(= L_code)。
    • 最后统计该文件的相关信息:空白行数 = L_original - L_non_blank;注释行数 = L_non_blank - L_code;源代码行数 = L_code。

Recognized Languages

使用–show-lang参数,可以查看cloc目前已支持的计算机语言。

prompt> cloc --show-lang

ABAP                       (abap)
ActionScript               (as)
Ada                        (ada, adb, ads, pad)
ADSO/IDSM                  (adso)
Agda                       (agda, lagda)
AMPLE                      (ample, dofile, startup)
Ant                        (build.xml, build.xml)
ANTLR Grammar              (g, g4)
Apex Class                 (cls)
Apex Trigger               (trigger)
APL                        (apl, apla, aplc, aplf, apli, apln, aplo, dyalog, dyapp, mipage)
Arduino Sketch             (ino, pde)
AsciiDoc                   (adoc, asciidoc)
ASP                        (asa, ashx, asp, axd)
ASP.NET                    (asax, ascx, asmx, aspx, master, sitemap, webinfo)
AspectJ                    (aj)
Assembly                   (a51, asm, nasm, S, s)
AutoHotkey                 (ahk, ahkl)
awk                        (auk, awk, gawk, mawk, nawk)
Bazel                      (BUILD)
BizTalk Orchestration      (odx)
BizTalk Pipeline           (btp)
Blade                      (blade, blade.php)
Bourne Again Shell         (bash)
Bourne Shell               (sh)
BrightScript               (brs)
builder                    (xml.builder)
C                          (c, cats, ec, idc, pgc)
C Shell                    (csh, tcsh)
C#                         (cs)
C# Designer                (designer.cs)
C++                        (C, c++, cc, CPP, cpp, cxx, h++, inl, ipp, pcc, tcc, tpp)
...

An Example

cloc不仅功能强大,而且非常易用。和shell脚本结合后,可以大大提升我们的效率。下面举一个网络上找到的例子——如何快速分析一个GitHub上的项目:

#!/usr/bin/env bash
git clone --depth 1 "$1" temp-linecount-repo &&
  printf "('temp-linecount-repo' will be deleted automatically)\n\n\n" &&
  cloc temp-linecount-repo &&
  rm -rf temp-linecount-repo

将以上内容保存,并命名为github_cloc.sh。执行该脚本并分析cloc项目:

➜  Utils ./github_cloc.sh https://github.com/AlDanial/cloc.git
Cloning into 'temp-linecount-repo'...
remote: Enumerating objects: 821, done.
remote: Counting objects: 100% (821/821), done.
remote: Compressing objects: 100% (555/555), done.
remote: Total 821 (delta 165), reused 729 (delta 140), pack-reused 0
Receiving objects: 100% (821/821), 556.48 KiB | 548.00 KiB/s, done.
Resolving deltas: 100% (165/165), done.
('temp-linecount-repo' will be deleted automatically)


     686 text files.
     627 unique files.
      96 files ignored.

github.com/AlDanial/cloc v 1.90  T=0.65 s (915.6 files/s, 97633.0 lines/s)
----------------------------------------------------------------------------------------
Language                              files          blank        comment           code
----------------------------------------------------------------------------------------
Perl                                      8           2300           5037          25719
YAML                                    315             12            317           7564
Markdown                                  3            297             32           2806
ANTLR Grammar                             2            200             59           1012
R                                         3             95            312            698
C/C++ Header                              1            191            780            617
C++                                      11            132            183            603
Forth                                     2             17             84            529
TypeScript                                4             53             39            416
Logtalk                                   1             59             57            368
C                                         7            110             72            354
Windows Message File                      2             89              9            348
TeX                                       2             36             64            265
Racket                                    1             32            159            247
make                                      4             85            159            247
SVG                                       1             19              4            242
...
...
...
Literate Idris                            1              2              2              3
NAnt script                               1              1              0              3
ProGuard                                  1              7             14              3
Tcl/Tk                                    1              1              2              3
dhall                                     1              6             17              3
ColdFusion                                1              1              2              2
DOS Batch                                 1              1              2              2
Focus                                     1              1              2              1
MUMPS                                     1              0              2              1
XQuery                                    1              0              1              1
xBase                                     1              0              9              1
----------------------------------------------------------------------------------------
SUM:                                    593           5089           9803          48342
----------------------------------------------------------------------------------------
➜  Utils

非常方便。