-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
3/3: Verbose Output #50
Changes from all commits
de4d0a9
66e7079
c46fb4a
bfbc884
3e35262
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,41 +2,120 @@ | |
|
||
'use strict' | ||
|
||
var path = require('path') | ||
var argv = require('yargs') | ||
.boolean('verbose') | ||
.alias('v', 'verbose') | ||
.argv | ||
|
||
var size = require('window-size') | ||
var availableWidth = size.width || /* istanbul ignore next */ 80 | ||
var ui = require('cliui')({width: availableWidth}) | ||
|
||
var getRuleFinder = require('../lib/rule-finder') | ||
var difference = require('../lib/array-diff') | ||
var arrayDifference = require('../lib/array-diff') | ||
var objectDifference = require('../lib/object-diff') | ||
var getSortedRules = require('../lib/sort-rules') | ||
|
||
var rules = getSortedRules( | ||
difference( | ||
getRuleFinder(process.argv[2]).getCurrentRules(), | ||
getRuleFinder(process.argv[3]).getCurrentRules() | ||
) | ||
) | ||
|
||
var outputRules, outputRuleCellMapper | ||
var outputPadding = ' ' | ||
var outputMaxWidth = 0 | ||
var outputMaxCols = 0 | ||
|
||
var files = [argv._[0], argv._[1]] | ||
var collectedRules = getFilesToCompare(files).map(compareConfigs) | ||
|
||
var rulesCount = collectedRules.reduce( | ||
function getLength(prev, curr) { | ||
return prev + (curr && curr.rules ? curr.rules.length : /* istanbul ignore next */ 0) | ||
}, 0) | ||
|
||
var outputRuleCellMapper | ||
|
||
/* istanbul ignore next */ | ||
if (rules.length) { | ||
console.log('\n diff rules\n') // eslint-disable-line no-console | ||
rules = rules.map(function columnSpecification(rule) { | ||
rule = rule + outputPadding | ||
outputMaxWidth = Math.max(rule.length, outputMaxWidth) | ||
return rule | ||
}) | ||
outputMaxCols = Math.floor(availableWidth / outputMaxWidth) | ||
if (rulesCount) { | ||
console.log('\ndiff rules') // eslint-disable-line no-console | ||
|
||
outputMaxCols = argv.verbose ? 3 : Math.floor(availableWidth / outputMaxWidth) | ||
outputRuleCellMapper = getOutputRuleCellMapper(Math.floor(availableWidth / outputMaxCols)) | ||
while (rules.length) { | ||
outputRules = rules.splice(0, outputMaxCols).map(outputRuleCellMapper) | ||
ui.div.apply(ui, outputRules) | ||
|
||
collectedRules.forEach(function displayConfigs(config) { | ||
var rules = config.rules | ||
|
||
if (!rules.length) { | ||
return | ||
} | ||
|
||
if (argv.verbose) { | ||
rules.unshift('', config.base, config.head) | ||
} else { | ||
console.log( // eslint-disable-line no-console | ||
'\nin ' + config.base + ' but not in ' + config.head + ':\n' + | ||
rules.length + ' rules found\n' | ||
) | ||
} | ||
|
||
while (rules.length) { | ||
ui.div.apply( | ||
ui, | ||
rules.splice(0, outputMaxCols).map(outputRuleCellMapper) | ||
) | ||
} | ||
console.log(ui.toString()) // eslint-disable-line no-console | ||
}) | ||
} | ||
|
||
function getFilesToCompare(allFiles) { | ||
var filesToCompare = [allFiles] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is an
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But it's currently required.
For non-verbose output, we need to do two comparisons in total, first compare a to b, second compare b to a. |
||
|
||
if (!argv.verbose) { | ||
// in non-verbose output mode, compare a to be | ||
// and b to a afterwards, to obtain ALL differences | ||
// across those files, but grouped | ||
filesToCompare.push([].concat(allFiles).reverse()) | ||
} | ||
|
||
return filesToCompare | ||
} | ||
|
||
function compareConfigs(currentFiles) { | ||
var rules = rulesDifference( | ||
getRuleFinder(currentFiles[0]), | ||
getRuleFinder(currentFiles[1]) | ||
) | ||
|
||
return { | ||
base: path.basename(currentFiles[0]), | ||
head: path.basename(currentFiles[1]), | ||
rules: rules.map(transformToColumnSpecification), | ||
} | ||
} | ||
|
||
function rulesDifference(a, b) { | ||
if (argv.verbose) { | ||
return getSortedRules( | ||
objectDifference( | ||
a.getCurrentRulesDetailed(), | ||
b.getCurrentRulesDetailed() | ||
) | ||
) | ||
} | ||
|
||
return getSortedRules( | ||
arrayDifference( | ||
a.getCurrentRules(), | ||
b.getCurrentRules() | ||
) | ||
) | ||
} | ||
|
||
function transformToColumnSpecification(rule) { | ||
/* istanbul ignore if */ | ||
if (typeof rule !== 'string') { | ||
rule = JSON.stringify(rule) | ||
} | ||
console.log(ui.toString()) // eslint-disable-line no-console | ||
rule = rule + outputPadding | ||
outputMaxWidth = Math.max(rule.length, outputMaxWidth) | ||
return rule | ||
} | ||
|
||
function getOutputRuleCellMapper(width) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ var options = { | |
getPluginRules: ['plugin', 'p'], | ||
getAllAvailableRules: ['all-available', 'a'], | ||
getUnusedRules: ['unused', 'u'], | ||
verbose: ['verbose', 'v'], | ||
n: ['no-error'], | ||
} | ||
|
||
|
@@ -32,9 +33,12 @@ Object.keys(options).forEach(function findRules(option) { | |
var ruleFinderMethod = ruleFinder[option] | ||
if (argv[option] && ruleFinderMethod) { | ||
rules = ruleFinderMethod() | ||
argv.verbose && console.log( // eslint-disable-line no-console | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Something to be considered as a follow up. |
||
'\n' + options[option][0] + ' rules\n' + rules.length + ' rules found\n' | ||
) | ||
/* istanbul ignore next */ | ||
if (rules.length) { | ||
console.log('\n' + options[option][0], 'rules\n') // eslint-disable-line no-console | ||
!argv.verbose && console.log('\n' + options[option][0] + ' rules\n') // eslint-disable-line no-console | ||
rules = rules.map(function columnSpecification(rule) { | ||
rule = rule + outputPadding | ||
outputMaxWidth = Math.max(rule.length, outputMaxWidth) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
var assert = require('assert') | ||
|
||
function difference(a, b) { | ||
var diff = {} | ||
|
||
Object.keys(a).forEach(compare(diff, a, b)) | ||
Object.keys(b).forEach(compare(diff, a, b)) | ||
|
||
return diff | ||
} | ||
|
||
function compare(diff, a, b) { | ||
return function curried(n) { | ||
if (!diff[n]) { | ||
try { | ||
assert.deepEqual(a[n], b[n]) | ||
} catch (e) { | ||
diff[n] = { | ||
config1: a[n], | ||
config2: b[n], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we prune the
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we do that, I guess we don't need the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's ok to address this in a subsequent PR, provided that there is an issue opened for this. 😈 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's an interesting point, I'll consider when pulling |
||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
module.exports = difference |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,6 +75,11 @@ function RuleFinder(specifiedFile) { | |
return getSortedRules(currentRules) | ||
} | ||
|
||
// get all the current rules' particular configuration | ||
this.getCurrentRulesDetailed = function getCurrentRulesDetailed() { | ||
return config.rules | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Strange!! why is this still in diff? Do you need to rebase this with |
||
// get all the plugin rules instead of referring the extended files or documentation | ||
this.getPluginRules = function getPluginRules() { | ||
return getSortedRules(pluginRules) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,27 @@ | ||
'use strict' | ||
|
||
function getSortedRules(rules) { | ||
return rules.sort(function sort(a, b) { | ||
return a > b ? 1 : -1 | ||
}) | ||
return Array.isArray(rules) ? getSortedRulesArray(rules) : transformIntoSortedRulesArray(rules) | ||
} | ||
|
||
function getSortedRulesArray(rules) { | ||
return rules.sort(sortAlphabetically) | ||
} | ||
|
||
function transformIntoSortedRulesArray(rules) { | ||
var sortedRules = [] | ||
|
||
Object.keys(rules) | ||
.sort(sortAlphabetically) | ||
.forEach(function map(ruleName) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use a different name than |
||
sortedRules.push(ruleName, rules[ruleName].config1, rules[ruleName].config2) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Am I reading this correct? // sortedRules
['foo-rule', '0 foo', '2 foo', 'bar-rule', '2 bar', '1 bar', ...] If I am reading this correct, I am afraid, it would not be difficult to maintain. I would expect it to be [{ 'foo-rule': {config1: '0 foo', config2: '2 foo'} }, ....] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am confused 😕 Why does this is look different to me than There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess, now I understand
Looks like, If yes, I would request to use non-positional schema. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess you are preferring this schema for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Making the module's output to read [{ 'foo-rule': {config1: '0 foo', config2: '2 foo'} }, ....] sounds good, let that |
||
}) | ||
|
||
return sortedRules | ||
} | ||
|
||
function sortAlphabetically(a, b) { | ||
return a > b ? 1 : -1 | ||
} | ||
|
||
module.exports = getSortedRules |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,15 +4,18 @@ var sinon = require('sinon') | |
|
||
var consoleLog = console.log // eslint-disable-line no-console | ||
|
||
var difference = sinon.stub().returns(['diff']) | ||
var arrayDifference = sinon.stub().returns(['diff']) | ||
var objectDifference = sinon.stub().returns(['diff']) | ||
|
||
var stub = { | ||
'../lib/rule-finder': function() { | ||
return { | ||
getCurrentRules: function noop() {}, | ||
getCurrentRulesDetailed: function noop() {}, | ||
} | ||
}, | ||
'../lib/array-diff': difference, | ||
'../lib/array-diff': arrayDifference, | ||
'../lib/object-diff': objectDifference, | ||
} | ||
|
||
describe('diff', function() { | ||
|
@@ -23,18 +26,34 @@ describe('diff', function() { | |
|
||
afterEach(function() { | ||
console.log = consoleLog // eslint-disable-line no-console | ||
// purge yargs cache | ||
delete require.cache[require.resolve('yargs')] | ||
}) | ||
|
||
it('log diff', function() { | ||
process.argv[2] = './foo' | ||
process.argv[3] = './bar' | ||
console.log = function() { // eslint-disable-line no-console | ||
if (arguments[0].match(/(diff|but not in|rules found)/)) { | ||
return | ||
} | ||
consoleLog.apply(null, arguments) | ||
} | ||
proxyquire('../../src/bin/diff', stub) | ||
assert.ok(arrayDifference.called) | ||
}) | ||
|
||
it('verbose log diff', function() { | ||
process.argv[2] = './foo' | ||
process.argv[3] = './bar' | ||
process.argv[4] = '-v' | ||
console.log = function() { // eslint-disable-line no-console | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can club both the |
||
if (arguments[0].match(/(diff)/)) { | ||
return | ||
} | ||
consoleLog.apply(null, arguments) | ||
} | ||
proxyquire('../../src/bin/diff', stub) | ||
assert.ok(difference.called) | ||
assert.ok(objectDifference.called) | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
var assert = require('assert') | ||
var difference = require('../../src/lib/object-diff') | ||
|
||
describe('object difference', function() { | ||
it('should return difference', function() { | ||
assert.deepEqual( | ||
difference({'foo-rule': [2, 'foo']}, {'foo-rule': [2, 'bar']}), | ||
{'foo-rule': {config1: [2, 'foo'], config2: [2, 'bar']}} | ||
) | ||
assert.deepEqual( | ||
difference({'foo-rule': [2, 'foo', 'bar']}, {'foo-rule': 2}), | ||
{'foo-rule': {config1: [2, 'foo', 'bar'], config2: 2}} | ||
) | ||
assert.deepEqual( | ||
difference({'foo-rule': [0, 'foo']}, {'bar-rule': [1, 'bar']}), | ||
{ | ||
'foo-rule': {config1: [0, 'foo'], config2: undefined}, | ||
'bar-rule': {config1: undefined, config2: [1, 'bar']}, | ||
} | ||
) | ||
|
||
assert.deepEqual( | ||
difference({'foo-rule': [1, 'foo', 'bar']}, {'foo-rule': [1, 'foo', 'bar']}), | ||
{} | ||
) | ||
}) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strange!! why is this still in diff?
Do you need to rebase this with
upstream/master
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, probably just forgot to rebase m(