sjs-clc 代码行数统计命令开发手记

上周向领导建议对项目进行重构,重构的一个回报之一就是代码复用,减少代码量,提高开发效率,现在重构工作快要结束了,作为一个严谨的人,我的工作成果必须要可以量化,这时就需要对比重构前后的代码量,重构是否减少了代码量,减少了多少,复用代码占比多少。

通常我们常用的统计代码行数的方法有几种:

  1. IDE 自带工具,方便好用,但是并不是所有工具都有这个功能,比如 Hbuilder 就没有
  2. linux find 命令,好用,但不够方便,对于 Windows 或者 命令不熟悉的人来说,就有些麻烦了
  3. 插件、工具,现在有很多的插件或工具都可以解决这个问题,比如:line-counter

几种方法各有利弊,不过最近正在学习 nodejs,所以就想自己写一个 npm 命令来实现,顺便学习一下如何实现自定义命令。

需求很明确

  1. 统计项目代码行数,实现很简单,扫描项目目录下所有文件
  2. 忽略空行、注释
  3. 忽略非代码文件,一个很简单的方法就是直接参考 .gitignore
  4. 能统计指定的文件类型

现在开始动手

首先:新建一个 nodejs 项目,执行命令 npm init 根据提示输入即可,项目初始化好之后,在项目目录下新建 index.js 文件

然后:很重要的一点,在 index.js 的开头,加上这样一行声明 #!/usr/bin/env node,这一行声明告诉 nodejs,这是一个可执行命令

接着:引用 commander
var program = require('commander')

commander 是一个 node.js 命令行界面的完整解决方案,通过他可以轻松实现 nodejs 命令结构

接着:通过 commander.option 方法,来为命令增加参数
program.option('--exts [value]', '统计特定文件类型,以|分隔,例如:js,css,html')
program.option('-c, --igc', '忽略注释行')
program.option('-e, --ige', '忽略空行')
options 方法接受两个参数,第一个参数为 参数名,-为缩写,--为完成参数名,第二个参数为命令说明,通过命令 help 可查看

最后:在 commander.action 方法中,实现命令功能,功能并不复杂,扫码目录下的文件,过滤无需统计的文件和行,最后得出总行数就好了。

//  初始化参数
var fileCount = 0;
var fileLines = 0;
var currentPath = process.cwd();
var currentArgs = {
    comment: this.igc,
    empty: this.ige,
    exts: (this.exts || '').replace(/\,/g,'|').replace(/^\,/,'').replace(/\,$/,'')
};
var gitfile = currentPath + '\\.gitignore';

//  统计行数
var enumeline = function(filename){
    
    fileCount ++ ;
        
    var num = '';
    var count = 0;
    var length = fileCount.toString().length;
    var lines = fs.readFileSync(filename);
        lines = (lines ? lines.toString() : '').split('\n') || [];
        lines.forEach(function(text){
            
            if (/^\s*\/\//ig.test(text)){
                currentArgs.comment && count++;
            } else if (/^\s*$/ig.test(text)){
                currentArgs.empty && count++;
            } else {
                count++;
            }
        });
        
        for (var i = 0; i<5-length; i ++){
            num += ' ';
        }
        
        fileLines += count;
        
        console.log(fileCount + '.' + num + filename + chalk.green(' (' + count + ')'));
};

//  枚举文件
var enumerate = function(ignore, dirname){
    
    var files = fs.readdirSync(dirname);
        files.forEach(function(item){
                
            if (!fileignore(ignore, dirname + item)){
                if (fs.statSync(dirname + item).isDirectory()){
                    enumerate(ignore, dirname + item + '\\');
                } else {
                    if (fileexts(currentArgs.exts, item)){
                        enumeline(dirname + item);
                    }
                }
            }
        });
};

//  匹配文件类型
var fileexts = function(exts, filename){
    
    if (exts){
        return new RegExp('\.(' + exts + ')([\.\?]+|$)','ig').test(filename);
    }
    return true;
};

//  匹配文件路径 gitignore 
var fileignore = function(ignore, filename){
    
    if (ignore){
        filename = filename.indexOf(currentPath) > -1 ? filename.substring(currentPath.length) : filename;
        filename = filename.charAt(0) == '\\' ? filename.substring(1) : filename;
        return ignore.ignores(filename);
    }
    return false;
};

console.log('\n      统计目录:' + currentPath + '\n');

if (fs.existsSync(gitfile)){
  var gits = fs.readFileSync(gitfile);
  enumerate(ignore().add('.git').add((gits ? gits.toString() : '').split('\n') || []), currentPath + '\\');
} else {
  enumerate(ignore().add(['.git']), currentPath + '\\');
}

console.log('\n      共计:' + chalk.green(fileLines) + ' 行代码');

现在,只需要执行命令 npm sjs-clc -e -c --exts js,css 就可以统计代码行数了

你可能感兴趣的:(sjs-clc 代码行数统计命令开发手记)