Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
language: node_js
node_js:
- "4"
- "5"
- "6"
- "10"
before_script:
- npm install -g grunt-cli
- mkdir ~/bin
- mkdir -p ~/bin
- export PATH=~/bin:$PATH
- npm install

Expand Down
5 changes: 3 additions & 2 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-nodeunit');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-casper');
// grunt.loadNpmTasks('grunt-casper');

grunt.registerTask('runtest',function(){
var done = this.async();
Expand Down Expand Up @@ -136,7 +136,8 @@ module.exports = function(grunt) {

grunt.registerTask('optimize', ['uglify']);
// Default task.
grunt.registerTask('test', ['jshint', 'nodeunit', 'runtest', 'runbin', 'casper']);
// grunt.registerTask('test', ['jshint', 'nodeunit', 'runtest', 'runbin', 'casper']);
grunt.registerTask('test', ['jshint', 'nodeunit', 'runtest', 'runbin']);
grunt.registerTask('default', ['test']);

};
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,29 @@ Usage : plato [options] -d <output_dir> <input files>
Time to use as the report date (seconds, > 9999999999 assumed to be ms)
-n, --noempty
Skips empty lines from line count
-X, --extensions : Array (default: .js)
Specify JavaScript file extensions
```

__Example__

```shell
plato -r -d report src
```console
$ plato -r -d report src
```

__Extended example__

```console
$ plato -r -d report -l .jshintrc -t "My Awesome App" -x .json routes/*.js
```
plato -r -d report -l .jshintrc -t "My Awesome App" -x .json routes/*.js

__Extended example (Specify JavaScript file extensions)__

```console
$ plato -r -d report -X .jsx src
$ plato -r -d report --extensions=.jsx src
$ plato -r -d report -X .js,.jsx src
$ plato -r -d report -X .js -X .jsx src
```

### From scripts
Expand Down
8 changes: 4 additions & 4 deletions lib/assets/scripts/plato-overview.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,16 @@ $(function(){
reports.forEach(function(report){

// @todo shouldn't need this, 'auto [num]' doesn't seem to work : https://github.com/oesmith/morris.js/issues/201
sloc.ymax = Math.max(sloc.ymax, report.complexity.methodAggregate.sloc.physical);
bugs.ymax = Math.max(bugs.ymax, report.complexity.methodAggregate.halstead.bugs.toFixed(2));
sloc.ymax = Math.max(sloc.ymax, report.complexity.aggregate.sloc.physical);
bugs.ymax = Math.max(bugs.ymax, report.complexity.aggregate.halstead.bugs.toFixed(2));


sloc.data.push({
value : report.complexity.methodAggregate.sloc.physical,
value : report.complexity.aggregate.sloc.physical,
label : report.info.fileShort
});
bugs.data.push({
value : report.complexity.methodAggregate.halstead.bugs.toFixed(2),
value : report.complexity.aggregate.halstead.bugs.toFixed(2),
label : report.info.fileShort
});
maintainability.data.push({
Expand Down
26 changes: 16 additions & 10 deletions lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ exports.exec = function(options, done) {
q: !!exports.args.q,
title : exports.args.t && exports.args.t.value,
exclude : exports.args.x && new RegExp(exports.args.x.value),
date : exports.args.D && exports.args.D.value
date : exports.args.D && exports.args.D.value,
eslint: exports.args.e && exports.args.e.value,
extensions: exports.args.X && exports.args.X.value
};
var json;
var jshintrc = {};
Expand All @@ -43,11 +45,6 @@ exports.exec = function(options, done) {
platoOptions.jshint = { globals : jshintrc.globals || {} };
delete jshintrc.globals;
platoOptions.jshint.options = jshintrc;

} else if (exports.args.e) {
json = fs.readFileSync(exports.args.e.value).toString();
jshintrc = JSON.parse(util.stripComments(json));
platoOptions.eslint = jshintrc;
}

plato.inspect(files, outputDir, platoOptions, done);
Expand All @@ -66,18 +63,22 @@ function parseArgs(options) {// \/\\*(?:(?!\\*\/)|.|\\n)*?\\*\/
Object.keys(options).forEach(function(option){
var def = options[option];
optionString += option;
if (def.type === 'String') optionString += ':';
if (def.type === 'String' || def.type === "Array") optionString += ':';
if (def.long) optionString += '(' + def.long + ')';
if (def.required) required.push(option);
});

var parser = new getopt.BasicParser(optionString, process.argv);
var args = {}, option;

while ((option = parser.getopt())) {
var arg = args[option.option] || { count : 0};
while ((option = parser.getopt()) !== undefined && !option.error) {
var arg = args[option.option] || { count : 0, value : [] };
arg.count++;
arg.value = option.optarg || true;
if (options[option.option].type === "Array") {
arg.value = arg.value.concat(option.optarg.split(","));
} else {
arg.value = option.optarg || true;
}

args[option.option] = arg;

Expand All @@ -98,5 +99,10 @@ function parseArgs(options) {// \/\\*(?:(?!\\*\/)|.|\\n)*?\\*\/

// what's left in argv
args.files = process.argv.slice(parser.optind());
if (args.files.length < 1) {
console.log("One or more files ​​are required.");
info.help();
process.exit(1);
}
return args;
}
6 changes: 6 additions & 0 deletions lib/cli/options.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,11 @@
"long": "noempty",
"desc": "Skips empty lines from line count",
"type": "Boolean"
},
"X": {
"long": "extensions",
"desc": "Specify JavaScript file extensions",
"type": "Array",
"default": ".js"
}
}
5 changes: 3 additions & 2 deletions lib/info.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ exports.help = function() {
Object.keys(options).forEach(function(shortOption){
var option = options[shortOption];
console.log(
' -%s%s%s%s',
' -%s%s%s%s%s',
shortOption,
option.long ? ', --' + option.long : '',
option.type !== 'Boolean' ? ' : ' + option.type : '',
option.required ? ' *required*' : ''
option.required ? ' *required*' : '',
option.default ? ' (default: ' + option.default + ')' : ''
);
console.log(' %s', option.desc);
});
Expand Down
9 changes: 8 additions & 1 deletion lib/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,17 @@ var levels = [
'WARNING',
'ERROR'
];
var apiMap = {
'TRACE': 'trace',
'DEBUG': 'log',
'INFO': 'info',
'WARNING': 'warn',
'ERROR': 'error'
};

levels.forEach(function(level, i){
Logger[level] = i;
Logger.prototype[level.toLowerCase()] = function() {
if (i >= this.level) console.log.apply(console,arguments);
if (i >= this.level) console[apiMap[level]].apply(console,arguments);
};
});
8 changes: 4 additions & 4 deletions lib/models/FileHistory.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ FileHistory.prototype.addReport = function(report, date) {
date = date || report.date || new Date().toUTCString();
this.push({
date : date,
sloc : report.complexity.methodAggregate.sloc.physical,
lloc : report.complexity.methodAggregate.sloc.logical,
sloc : report.complexity.aggregate.sloc.physical,
lloc : report.complexity.aggregate.sloc.logical,
functions : report.complexity.methods.length,
deliveredBugs : report.complexity.methodAggregate.halstead.bugs,
difficulty: report.complexity.methodAggregate.halstead.difficulty,
deliveredBugs : report.complexity.aggregate.halstead.bugs,
difficulty: report.complexity.aggregate.halstead.difficulty,
maintainability: report.complexity.maintainability,
lintErrors : (report.jshint && report.jshint.messages.length) || []
});
Expand Down
36 changes: 26 additions & 10 deletions lib/plato.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ exports.inspect = function(files, outputDir, options, done) {
files = files instanceof Array ? files : [files];
files = _.flatten(files.map(unary(glob.sync)));

options.extensions = options.extensions || [".js"];

var flags = {
complexity : {
commonjs : true,
Expand All @@ -61,11 +63,25 @@ exports.inspect = function(files, outputDir, options, done) {
jshint : {} // use jshint defaults
};

// TODO: separate jshint and eslint on running `runReports`
if (options.eslint) {
options.jshint = options.eslint;
reporters.jshint = reporters.eslint;
if (typeof options.eslint === "string") {
options.jshint = {
configFile: path.resolve(options.eslint)
};
} else {
options.eslint.baseConfig = options.eslint.baseConfig || {};
["extends", "overrides", "settings"].forEach(function(configKey){
if (options.eslint[configKey]) {
options.eslint.baseConfig[configKey] = options.eslint[configKey];
delete options.eslint[configKey];
}
});
options.jshint = options.eslint;
}
delete options.eslint;
delete reporters.eslint;
reporters.jshint = reporters.eslint;
// delete reporters.eslint; // NOTE: don't delete because can't reuse `inspect`
}

Object.keys(flags).forEach(function(flag){
Expand Down Expand Up @@ -95,20 +111,20 @@ exports.inspect = function(files, outputDir, options, done) {
return path.join(file,innerFile);
});
runReports(files);
} else if (file.match(/\.js$/)) {
} else if (options.extensions.includes(path.extname(file))) {
log.info('Reading "%s"', file);

var fileShort = file.replace(commonBasePath, '');
var fileSafe = fileShort.replace(/[^a-zA-Z0-9]/g,'_');
var source = fs.readFileSync(file).toString().trim();
if (!source) {
var source = fs.readFileSync(file).toString();
if (!source.trim()) {
log.info('Not parsing empty file "%s"', file);
return;
}

// if skip empty line option
if(options.noempty) {
source = source.replace(/^\s*[\r\n]/gm ,"");
source = source.replace(/^\s*[\r\n]/gm ,"").trim();
}

// if begins with shebang
Expand Down Expand Up @@ -195,10 +211,10 @@ exports.getOverviewReport = function (reports) {

reports.forEach(function(report) {
// clone objects so we don't have to worry about side effects
summary.total.sloc += report.complexity.methodAggregate.sloc.physical;
summary.total.sloc += report.complexity.aggregate.sloc.physical;
summary.total.maintainability += report.complexity.maintainability;

var methodAggregate = _.cloneDeep(report.complexity.methodAggregate);
var aggregate = _.cloneDeep(report.complexity.aggregate);
var reportItem = {};
reportItem.info = report.info;
if (report.jshint) {
Expand All @@ -209,7 +225,7 @@ exports.getOverviewReport = function (reports) {
}
if (report.complexity) {
reportItem.complexity = {
methodAggregate : methodAggregate,
aggregate : aggregate,
module : report.complexity.module,
module_safe : report.complexity.module_safe,
maintainability : _.cloneDeep(report.complexity.maintainability)
Expand Down
7 changes: 5 additions & 2 deletions lib/reporters/eslint/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"use strict";

var ESLINT = require("eslint");
// @see http://www.phpied.com/using-eslint-in-a-script/
// @see https://eslint.org/docs/developer-guide/nodejs-api#cliengine
var CLIEngine = require("eslint").CLIEngine;

exports.process = function (source, options/*, reportInfo */) {
var results = lint(source, options);
Expand Down Expand Up @@ -36,7 +38,8 @@ function lint(source, config) {
// Remove potential Unicode BOM.
source = source.replace(/^\uFEFF/, "");

var messages = ESLINT.linter.verify(source, config);
var cli = new CLIEngine(config);
var messages = cli.executeOnText(source).results[0].messages;
results = results.concat(messages);

return {
Expand Down
4 changes: 2 additions & 2 deletions lib/reporters/jshint/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ var jsHintCli = require("jshint/src/cli.js");
// Provides a regexp to test for ES6 / ES Modules. If the pass tests then esversion is set to 6 if not already specified.
var esmRegex = /(^\s*|[}\);\n]\s*)(import\s*(['"]|(\*\s+as\s+)?[^"'\(\)\n;]+\s*from\s*['"]|\{)|export\s+\*\s+from\s+["']|export\s* (\{|default|function|class|var|const|let|async\s+function))/;

exports.process = function (source, options/*, reportInfo */) {
exports.process = function (source, options, reportInfo) {
if (options == null || Object.getOwnPropertyNames(options).length === 0) {
options = { options : {}, globals : {}};
var jsHintOptions = jsHintCli.getConfig(source);
var jsHintOptions = jsHintCli.getConfig(reportInfo.file || "");

delete jsHintOptions.dirname;
if (jsHintOptions != null && Object.getOwnPropertyNames(jsHintOptions).length > 0) {
Expand Down
4 changes: 2 additions & 2 deletions lib/templates/display.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ <h2 class="reportTitle">Worst Maintainability Scores</h2>
<div class="reportBlock locList">
<h2 class="reportTitle">Largest Files</h2>
<ul class="list-unstyled">
<% _.each(_.take(_.sortBy(report.reports, function (report) { return -1 * report.complexity.methodAggregate.sloc.physical }), 5), function(report, i) { %>
<% _.each(_.take(_.sortBy(report.reports, function (report) { return -1 * report.complexity.aggregate.sloc.physical }), 5), function(report, i) { %>
<li>
<strong><%= report.complexity.methodAggregate.sloc.physical %> lines</strong>
<strong><%= report.complexity.aggregate.sloc.physical %> lines</strong>
<small><%= report.info.fileShort %></small>
</li>
<% }); %>
Expand Down
6 changes: 3 additions & 3 deletions lib/templates/file.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ <h2 class="header">Maintainability <a href="http://blogs.msdn.com/b/codeanalysis
</div>
<div class="col-md-6">
<h2 class="header">Lines of code <i class="icon icon-info-sign" rel="popover" data-placement="top" data-trigger="hover" data-content="Source Lines of Code / Logical Lines of Code" data-original-title="SLOC/LSLOC" data-container="body"></i></h2>
<p class="stat"><%= report.complexity.methodAggregate.sloc.physical %></p>
<p class="stat"><%= report.complexity.aggregate.sloc.physical %></p>
</div>
</div>
<div class="row historical">
Expand All @@ -62,11 +62,11 @@ <h2 class="header">Lines of code <i class="icon icon-info-sign" rel="popover" da
<div class="row">
<div class="col-md-6">
<h2 class="header">Difficulty <a href="http://en.wikipedia.org/wiki/Halstead_complexity_measures"><i class="icon icon-info-sign" rel="popover" data-placement="top" data-trigger="hover" data-content="The difficulty measure is related to the difficulty of the program to write or understand." data-original-title="Difficulty" data-container="body"></i></a></h2>
<p class="stat"><%= report.complexity.methodAggregate.halstead.difficulty.toFixed(2) %></p>
<p class="stat"><%= report.complexity.aggregate.halstead.difficulty.toFixed(2) %></p>
</div>
<div class="col-md-6">
<h2 class="header">Estimated Errors <a href="http://en.wikipedia.org/wiki/Halstead_complexity_measures"><i class="icon icon-info-sign" rel="popover" data-placement="top" data-trigger="hover" data-content="Halstead's delivered bugs is an estimate for the number of errors in the implementation." data-original-title="Delivered Bugs" data-container="body"></i></a></h2>
<p class="stat"><%= report.complexity.methodAggregate.halstead.bugs.toFixed(2) %></p>
<p class="stat"><%= report.complexity.aggregate.halstead.bugs.toFixed(2) %></p>
</div>
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions lib/templates/overview.html
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ <h1 class="col-md-12">Files</h1>
<span class="col-md-4 file"><a class="file-link" href="./<%= item.info.link %>"><%= item.info.fileShort %></a></span>
<span class="col-md-8 file-chart js-file-chart"
data-lint="<%= item.jshint && item.jshint.messages %>"
data-sloc="<%= item.complexity.methodAggregate.sloc.physical %>"
data-bugs="<%= item.complexity.methodAggregate.halstead.bugs.toFixed(2) %>"
data-complexity="<%= item.complexity.methodAggregate.cyclomatic%>"
data-sloc="<%= item.complexity.aggregate.sloc.physical %>"
data-bugs="<%= item.complexity.aggregate.halstead.bugs.toFixed(2) %>"
data-complexity="<%= item.complexity.aggregate.cyclomatic%>"
></span>
</div>
</li>
Expand Down
2 changes: 1 addition & 1 deletion lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var log = new Logger(Logger.WARNING);
var path = require('path');

exports.findCommonBase = function(files) {
if (!files || files.length === 1) return '';
if (!files || files.length < 2) return '';
var lastSlash = files[0].lastIndexOf(path.sep);
if (!lastSlash) return '';
var first = files[0].substr(0, lastSlash + 1);
Expand Down
Loading