From c2879592858805d7ecd0304a39c5cf079efe6a7c Mon Sep 17 00:00:00 2001 From: Philipp Tusch Date: Fri, 14 Aug 2015 13:30:16 +0200 Subject: [PATCH 1/6] Add option to only show unknown licenses Remove unused references --- README.md | 1 + lib/args.js | 1 + lib/index.js | 17 ++++++++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4a342f8..844e9d4 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ Options ------- * `--unknown` report guessed licenses as unknown licenses. +* `--onlyunknown` only list packages with unknown or guessed licenses. * `--json` output in json format. * `--csv` output in csv format. * `--out [filepath]` write the data to a specific file. diff --git a/lib/args.js b/lib/args.js index 05c1fb3..cdb615b 100644 --- a/lib/args.js +++ b/lib/args.js @@ -12,6 +12,7 @@ var nopt = require('nopt'), markdown: Boolean, out: require('path'), unknown: Boolean, + onlyunknown: Boolean, version: Boolean, color: Boolean, start: String, diff --git a/lib/index.js b/lib/index.js index 611dc3e..971480d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -19,6 +19,7 @@ var flatten = function(options) { data = options.data, key = json.name + '@' + json.version, colorize = options.color, + unknown = options.unknown, licenseData, files = [], licenseFile; if (colorize) { @@ -48,6 +49,10 @@ var flatten = function(options) { } } + if (unknown) { + moduleInfo.dependencyPath = json.path; + } + licenseData = json.license || json.licenses || undefined; if (licenseData) { if (Array.isArray(licenseData) && licenseData.length > 0) { @@ -106,6 +111,7 @@ var flatten = function(options) { deps: childDependency, data: data, color: colorize, + unknown: unknown, filter: options.filter }); }); @@ -120,6 +126,7 @@ exports.init = function(options, callback) { deps: json, data: {}, color: options.color, + unknown: options.unknown, filter: options.filter }), colorize = options.color, @@ -137,7 +144,15 @@ exports.init = function(options, callback) { } } if (data[item]) { - sorted[item] = data[item]; + if (options.onlyunknown) { + if (data[item].licenses && data[item].licenses !== UNKNOWN) { + if (data[item].licenses.indexOf('*') > -1) { + sorted[item] = data[item]; + } + } + } else { + sorted[item] = data[item]; + } } }); callback(sorted); From faf8ffd69fd8ae475484a9b47b57a7b6ea738856 Mon Sep 17 00:00:00 2001 From: Philipp Tusch Date: Thu, 3 Sep 2015 15:21:17 +0200 Subject: [PATCH 2/6] Remove trivial UNKNOWN check --- lib/index.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/index.js b/lib/index.js index b13d399..cbdf083 100644 --- a/lib/index.js +++ b/lib/index.js @@ -147,10 +147,9 @@ exports.init = function(options, callback) { } if (data[item]) { if (options.onlyunknown) { - if (data[item].licenses && data[item].licenses !== UNKNOWN) { - if (data[item].licenses.indexOf('*') > -1) { - sorted[item] = data[item]; - } + if (data[item].licenses.indexOf('*') > -1 || + data[item].licenses.indexOf('UNKNOWN') > -1) { + sorted[item] = data[item]; } } else { sorted[item] = data[item]; From 559e72ccab2420bc42bf28b498702dad13ef967a Mon Sep 17 00:00:00 2001 From: Philipp Tusch Date: Thu, 3 Sep 2015 16:37:01 +0200 Subject: [PATCH 3/6] Add test for the first function call. --- tests/test.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/test.js b/tests/test.js index bb7cfce..c04a2bf 100644 --- a/tests/test.js +++ b/tests/test.js @@ -85,6 +85,33 @@ var tests = { 'on undefined': function (d) { assert.equal(d, 'Undefined'); } + }, + 'should only list UNKNOWN licenses': { + topic: function () { + var self = this; + + checker.init({ + start: path.join(__dirname, '../'), + onlyunknown: true + }, function (sorted) { + self.callback(null, sorted); + }); + }, + 'so we check if there is not a star in a license': function(d) { + var onlyStarsFound = true; + Object.keys(d).forEach(function(item) { + if (d[item].licenses && d[item].licenses.indexOf('UNKNOWN') !== -1) { + //Okay + } else if (d[item].licenses && d[item].licenses.indexOf('*') !== -1) { + //Okay + } else { + onlyStarsFound = false; + } + }); + + assert.ok(onlyStarsFound); + } + } }; From 6b791457463dca71b22b09eecff16bbf982db682 Mon Sep 17 00:00:00 2001 From: Philipp Tusch Date: Fri, 4 Sep 2015 08:51:13 +0200 Subject: [PATCH 4/6] Add additional check to negate the test --- README.md | 1 + tests/test.js | 29 +++++++++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 94b7c2e..d839085 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,7 @@ license-checker --json > /path/to/licenses.json license-checker --csv --out /path/to/licenses.csv license-checker --unknown license-checker --exclude 'MIT, MIT/X11, BSD, ISC' +license-checker --onlyunknown ``` Requiring diff --git a/tests/test.js b/tests/test.js index c04a2bf..89d992e 100644 --- a/tests/test.js +++ b/tests/test.js @@ -86,7 +86,7 @@ var tests = { assert.equal(d, 'Undefined'); } }, - 'should only list UNKNOWN licenses': { + 'should only list UNKNOWN or guessed licenses successful': { topic: function () { var self = this; @@ -97,7 +97,7 @@ var tests = { self.callback(null, sorted); }); }, - 'so we check if there is not a star in a license': function(d) { + 'so we check if there is no license with a star or UNKNOWN found': function(d) { var onlyStarsFound = true; Object.keys(d).forEach(function(item) { if (d[item].licenses && d[item].licenses.indexOf('UNKNOWN') !== -1) { @@ -111,10 +111,31 @@ var tests = { assert.ok(onlyStarsFound); } + }, + 'should only list UNKNOWN or guessed licenses with errors (argument missing)': { + topic: function () { + var self = this; + checker.init({ + start: path.join(__dirname, '../') + }, function (sorted) { + self.callback(null, sorted); + }); + }, + 'so we check if there is no license with a star or UNKNOWN found': function(d) { + var onlyStarsFound = true; + Object.keys(d).forEach(function(item) { + if (d[item].licenses && d[item].licenses.indexOf('UNKNOWN') !== -1) { + //Okay + } else if (d[item].licenses && d[item].licenses.indexOf('*') !== -1) { + //Okay + } else { + onlyStarsFound = false; + } + }); + assert.equal(onlyStarsFound, false); + } } }; - - vows.describe('license-checker').addBatch(tests).export(module); From ce8d66108a49af7855c16231ce675c567a2ffe7f Mon Sep 17 00:00:00 2001 From: Dav Glass Date: Fri, 4 Sep 2015 08:08:55 -0500 Subject: [PATCH 5/6] tests: added 100% coverage for license file tests: added coverage check to fail if it drops tests: added tests and ignore defensive code --- lib/index.js | 14 ++++++++++ package.json | 3 +- tests/license.js | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/test.js | 53 +++++++++++++++++++++++++++++++++-- 4 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 tests/license.js diff --git a/lib/index.js b/lib/index.js index cbdf083..7ed46da 100644 --- a/lib/index.js +++ b/lib/index.js @@ -22,6 +22,7 @@ var flatten = function(options) { unknown = options.unknown, licenseData, files = [], licenseFile; + /*istanbul ignore next*/ if (colorize) { moduleInfo = { licenses: chalk.bold.red(UNKNOWN) }; key = chalk.blue(json.name) + chalk.dim('@') + chalk.green(json.version); @@ -30,6 +31,7 @@ var flatten = function(options) { // If we have processed this key already, just return the data object. // This was added so that we don't recurse forever if there was a circular // dependency in the dependency tree. + /*istanbul ignore next*/ if (data[key]) { return data; } @@ -37,6 +39,7 @@ var flatten = function(options) { data[key] = moduleInfo; if (json.repository) { + /*istanbul ignore else*/ if (typeof json.repository === 'object' && typeof json.repository.url === 'string') { moduleInfo.repository = json.repository.url.replace('git+ssh://git@', 'git://').replace('.git', ''); moduleInfo.repository = moduleInfo.repository.replace('git://github.com', 'https://github.com').replace('.git', ''); @@ -44,19 +47,23 @@ var flatten = function(options) { } } if (json.url) { + /*istanbul ignore next*/ if (typeof json.url === 'object') { moduleInfo.url = json.url.web; } } + /*istanbul ignore next*/ if (unknown) { moduleInfo.dependencyPath = json.path; } licenseData = json.license || json.licenses || undefined; if (licenseData) { + /*istanbul ignore else*/ if (Array.isArray(licenseData) && licenseData.length > 0) { moduleInfo.licenses = licenseData.map(function(license){ + /*istanbul ignore else*/ if (typeof license === 'object') { return license.type; } else if (typeof license === 'string') { @@ -72,6 +79,7 @@ var flatten = function(options) { moduleInfo.licenses = license(json.readme); } + /*istanbul ignore else*/ if (json.path && fs.existsSync(json.path)) { files = fs.readdirSync(json.path).filter(function(filename) { filename = filename.toUpperCase(); @@ -82,6 +90,7 @@ var flatten = function(options) { files.forEach(function(filename) { licenseFile = path.join(json.path, filename); // Checking that the file is in fact a normal file and not a directory for example. + /*istanbul ignore else*/ if (fs.lstatSync(licenseFile).isFile()) { if (!moduleInfo.licenses || moduleInfo.licenses.indexOf(UNKNOWN) > -1) { //Only re-check the license if we didn't get it from elsewhere @@ -92,11 +101,13 @@ var flatten = function(options) { }); if (Array.isArray(moduleInfo.licenses)) { + /*istanbul ignore else*/ if (moduleInfo.licenses.length === 1) { moduleInfo.licenses = moduleInfo.licenses[0]; } } + /*istanbul ignore else*/ if (json.dependencies) { Object.keys(json.dependencies).forEach(function(name) { var childDependency = json.dependencies[name], @@ -137,6 +148,7 @@ exports.init = function(options, callback) { if (options.unknown) { if (data[item].licenses && data[item].licenses !== UNKNOWN) { if (data[item].licenses.indexOf('*') > -1) { + /*istanbul ignore if*/ if (colorize) { data[item].licenses = chalk.bold.red(UNKNOWN); } else { @@ -145,6 +157,7 @@ exports.init = function(options, callback) { } } } + /*istanbul ignore else*/ if (data[item]) { if (options.onlyunknown) { if (data[item].licenses.indexOf('*') > -1 || @@ -169,6 +182,7 @@ exports.init = function(options, callback) { }); }; +/*istanbul ignore next*/ exports.print = function(sorted) { console.log(exports.asTree(sorted)); }; diff --git a/package.json b/package.json index 1e36e70..c54167c 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,8 @@ }, "scripts": { "pretest": "jshint --config ./node_modules/yui-lint/jshint.json ./lib/", - "test": "istanbul cover --print both vows -- --spec ./tests/*.js" + "test": "istanbul cover --print both vows -- --spec ./tests/*.js", + "posttest": "istanbul check-coverage --statements 95 --functions 100 --lines 95 --branches 90" }, "preferGlobal": "true", "bugs": { diff --git a/tests/license.js b/tests/license.js new file mode 100644 index 0000000..dea153d --- /dev/null +++ b/tests/license.js @@ -0,0 +1,72 @@ +var vows = require('vows'), + assert = require('assert'), + license = require('../lib/license'); + +var tests = { + loading: { + topic: function() { + return license; + }, + 'should be a function': function(topic) { + assert.isFunction(topic); + } + }, + 'undefined check': { + topic: function() { + return license(undefined); + }, + 'should return Undefined': function(data) { + assert.equal(data, 'Undefined'); + } + }, + 'MIT check': { + topic: function() { + return license('asdf\nasdf\nasdf\nPermission is hereby granted, free of charge, to any'); + }, + 'should return MIT': function(data) { + assert.equal(data, 'MIT*'); + } + }, + 'MIT word check': { + topic: function() { + return license('asdf\nasdf\nMIT\nasdf\n'); + }, + 'should return MIT': function(data) { + assert.equal(data, 'MIT*'); + } + }, + 'BSD check': { + topic: function() { + return license('asdf\nRedistribution and use in source and binary forms, with or without\nasdf\n'); + }, + 'should return BSD': function(data) { + assert.equal(data, 'BSD*'); + } + }, + 'BSD word check': { + topic: function() { + return license('asdf\nasdf\nBSD\nasdf\n'); + }, + 'should return BSD': function(data) { + assert.equal(data, 'BSD*'); + } + }, + 'Apache word check': { + topic: function() { + return license('asdf\nasdf\nApache License\nasdf\n'); + }, + 'should return Apache': function(data) { + assert.equal(data, 'Apache*'); + } + }, + 'WTF check': { + topic: function() { + return license('DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE'); + }, + 'should return WTF': function(data) { + assert.equal(data, 'WTF*'); + } + } +}; + +vows.describe('licenses').addBatch(tests).export(module); diff --git a/tests/test.js b/tests/test.js index 89d992e..d98cad1 100644 --- a/tests/test.js +++ b/tests/test.js @@ -57,7 +57,7 @@ var tests = { } } }, - 'should parse local with unknown': { + 'should parse local with unknown and excludes': { topic: function () { var self = this; @@ -135,7 +135,56 @@ var tests = { }); assert.equal(onlyStarsFound, false); } - } + }, + 'should export a tree': { + topic: function() { + return checker.asTree([{}]); + }, + 'and format it': function(data) { + assert.ok(data); + assert.isTrue(data.indexOf('└─') > -1); + } + }, + 'should export as csv': { + topic: function() { + return checker.asCSV({ + foo: { + licenses: 'MIT', + repository: '/path/to/foo' + } + }); + }, + 'and format it': function(data) { + assert.ok(data); + assert.isTrue(data.indexOf('"foo","MIT","/path/to/foo"') > -1); + } + }, + 'should export as csv with partial data': { + topic: function() { + return checker.asCSV({ + foo: { + } + }); + }, + 'and format it': function(data) { + assert.ok(data); + assert.isTrue(data.indexOf('"foo","",""') > -1); + } + }, + 'should export as markdown': { + topic: function() { + return checker.asMarkDown({ + foo: { + licenses: 'MIT', + repository: '/path/to/foo' + } + }); + }, + 'and format it': function(data) { + assert.ok(data); + assert.isTrue(data.indexOf('[foo](/path/to/foo) - MIT') > -1); + } + }, }; vows.describe('license-checker').addBatch(tests).export(module); From 3fbba5bd5a489ea8c17328eabf71c4d5e9beb17e Mon Sep 17 00:00:00 2001 From: Dav Glass Date: Fri, 4 Sep 2015 08:40:17 -0500 Subject: [PATCH 6/6] 4.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c54167c..01549fa 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "license-checker", "description": "Check license info for a pacakge", "author": "Dav Glass ", - "version": "3.1.0", + "version": "4.0.0", "dependencies": { "chalk": "~0.5.1", "mkdirp": "^0.3.5",