diff --git a/es5/cli.js b/es5/cli.js index 6a03604..9e8dfe8 100644 --- a/es5/cli.js +++ b/es5/cli.js @@ -46,7 +46,7 @@ var buildVersion = JSON.parse(packageConfig).version; _commander2.default.version(buildVersion) // default cli behaviour will be an interactive walkthrough each error, with suggestions, // options to replace etc. -.option('-r, --report', 'Outputs a full report which details the unique spelling errors found.').option('-n, --ignore-numbers', 'Ignores numbers.').option('--en-us', 'American English dictionary.').option('--en-gb', 'British English dictionary.').option('--en-au', 'Australian English dictionary.').option('--es-es', 'Spanish dictionary.').option('-d, --dictionary [file]', 'specify a custom dictionary file - it should not include the file extension and will load .dic and .aiff.').option('-a, --ignore-acronyms', 'Ignores acronyms.').option('-x, --no-suggestions', 'Do not suggest words (can be slow)').option('-t, --target-relative', 'Uses ".spelling" files relative to the target.').usage("[options] source-file source-file").parse(process.argv); +.option('-r, --report', 'Outputs a full report which details the unique spelling errors found.').option('-n, --ignore-numbers', 'Ignores numbers.').option('--en-us', 'American English dictionary.').option('--en-gb', 'British English dictionary.').option('--en-au', 'Australian English dictionary.').option('--es-es', 'Spanish dictionary.').option('-d, --dictionary [file]', 'specify a custom dictionary file - it should not include the file extension and will load .dic and .aiff.').option('-a, --ignore-acronyms', 'Ignores acronyms.').option('-x, --no-suggestions', 'Do not suggest words (can be slow)').option('-t, --target-relative', 'Uses ".spelling" files relative to the target.').option('-y, --readiness [100]', 'Allows for a percentage readiness setting - default is set to 100 for no errors allowed').usage("[options] source-file source-file").parse(process.argv); var language = void 0; if (_commander2.default.enUs) { @@ -94,5 +94,8 @@ if (!_commander2.default.args.length) { } }, function (e, results) { console.log((0, _reportGenerator.generateSummaryReport)(results)); + if (_commander2.default.readiness) { + console.log((0, _reportGenerator.generateReadinessReport)(_commander2.default.readiness, results)); + } }); } \ No newline at end of file diff --git a/es5/report-generator.js b/es5/report-generator.js index 4ae6e59..c80641c 100644 --- a/es5/report-generator.js +++ b/es5/report-generator.js @@ -2,6 +2,7 @@ exports.__esModule = true; exports.generateSummaryReport = generateSummaryReport; +exports.generateReadinessReport = generateReadinessReport; exports.generateFileReport = generateFileReport; var _chalk = require('chalk'); @@ -14,6 +15,8 @@ var _context2 = _interopRequireDefault(_context); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + // Generates a report that summarises the spelling errors found across multiple // markdown files. // results is an array containing the errors (as a nested array) for each file. @@ -34,6 +37,57 @@ function generateSummaryReport(results) { return _chalk2.default.green('>>') + ' ' + results.length + ' ' + filePlural + ' ' + areOrIs + ' free from spelling errors'; } +var Stats = function Stats() { + var _this = this; + + _classCallCheck(this, Stats); + + this.values = { + 'v0': 0, + 'v1': 0, + 'v10': 0, + 'v50': 0, + 'v100': 0, + 'Total': 0 + }; + this.classify = function (val) { + //console.log(val); + if (val > 100) { + _this.values.v100++; + } else if (val > 50) { + _this.values.v50++; + } else if (val > 10) { + _this.values.v10++; + } else if (val > 1) { + _this.values.v1++; + } else { + _this.values.v0++; + } + _this.values.Total++; + }; + this.readiness = function () { + var score = _this.values.v1 + _this.values.v10 * 5 + _this.values.v50 * 10 + _this.values.v100 * 15; + return 100 - (score > _this.values.Total ? 100 : score); + }; + this.toString = function () { + return '\n ' + _this.values.v0 + ' files with 0 errors\n ' + _this.values.v1 + ' files with at least 1 error\n ' + _this.values.v10 + ' files with at least 10 errors\n ' + _this.values.v50 + ' files with at least 50 errors\n ' + _this.values.v100 + ' files with at least 100 errors\n\n Readiness indicator: ' + _this.readiness() + '%\n '; + }; +}; + +// Generate a readiness report based on weighted values on errors per file + + +function generateReadinessReport(readiness, results) { + var stats = new Stats(); + results.forEach(function (line) { + stats.classify(line.length); + }); + if (stats.readiness() >= (isNaN(readiness) ? 100 : parseInt(readiness))) { + process.exitCode = 0; + } + return stats.toString(); +} + // Generates a report for the errors found in a single markdown file. function generateFileReport(file, spellingInfo) { var report = ' ' + _chalk2.default.bold(file) + '\n'; diff --git a/es6/cli.js b/es6/cli.js index 9566dbc..00af33f 100644 --- a/es6/cli.js +++ b/es6/cli.js @@ -7,7 +7,7 @@ import chalk from 'chalk'; import multiFileProcessor from './multi-file-processor'; import relativeFileProcessor from './relative-file-processor'; import spellcheck from './spellcheck'; -import { generateSummaryReport, generateFileReport } from './report-generator'; +import { generateSummaryReport, generateFileReport, generateReadinessReport } from './report-generator'; const packageConfig = fs.readFileSync(path.join(__dirname, '../package.json')); const buildVersion = JSON.parse(packageConfig).version; @@ -26,6 +26,7 @@ program .option('-a, --ignore-acronyms', 'Ignores acronyms.') .option('-x, --no-suggestions', 'Do not suggest words (can be slow)') .option('-t, --target-relative', 'Uses ".spelling" files relative to the target.') + .option('-y, --readiness [100]', 'Allows for a percentage readiness setting - default is set to 100 for no errors allowed') .usage("[options] source-file source-file") .parse(process.argv); @@ -80,5 +81,8 @@ else { } }, (e, results) => { console.log(generateSummaryReport(results)); + if (program.readiness) { + console.log(generateReadinessReport(program.readiness, results)); + } }); } diff --git a/es6/report-generator.js b/es6/report-generator.js index d8da434..24750ad 100644 --- a/es6/report-generator.js +++ b/es6/report-generator.js @@ -6,7 +6,7 @@ import context from './context'; // results is an array containing the errors (as a nested array) for each file. export function generateSummaryReport(results) { const errorCount = results.map((e) => e && e.length ? e.length : 0) - .reduce((p, c) => p + c, 0); + .reduce((p, c) => p + c, 0); const filePlural = 'file' + (results.length > 1 ? 's' : ''); const errorPlural = 'error' + (errorCount > 1 ? 's' : ''); @@ -18,6 +18,69 @@ export function generateSummaryReport(results) { return `${chalk.green('>>')} ${results.length} ${filePlural} ${areOrIs} free from spelling errors`; } +class Stats { + constructor() { + this.values = { + 'v0': 0, + 'v1': 0, + 'v10': 0, + 'v50': 0, + 'v100': 0, + 'Total': 0 + }; + this.classify = (val) => { + //console.log(val); + if (val > 100) { + this.values.v100++; + } + else if (val > 50) { + this.values.v50++; + } + else if (val > 10) { + this.values.v10++; + } + else if (val > 1) { + this.values.v1++; + } + else { + this.values.v0++; + } + this.values.Total++; + }; + this.readiness = () => { + let score = (this.values.v1) + + (this.values.v10 * 5) + + (this.values.v50 * 10) + + (this.values.v100 * 15); + return 100 - (score > this.values.Total ? 100 : score); + }; + this.toString = () => { + return ` + ${this.values.v0} files with 0 errors + ${this.values.v1} files with at least 1 error + ${this.values.v10} files with at least 10 errors + ${this.values.v50} files with at least 50 errors + ${this.values.v100} files with at least 100 errors + + Readiness indicator: ${this.readiness()}% + `; + }; + } +} + +// Generate a readiness report based on weighted values on errors per file +export function generateReadinessReport(readiness, results) { + let stats = new Stats(); + results.forEach((line) => { + stats.classify(line.length); + }); + if (stats.readiness() >= (isNaN(readiness) ? 100 : parseInt(readiness))) { + process.exitCode = 0; + } + return stats.toString(); +} + + // Generates a report for the errors found in a single markdown file. export function generateFileReport(file, spellingInfo) { let report = ` ${chalk.bold(file)}\n`; diff --git a/readme.md b/readme.md index dfd1579..e83652e 100644 --- a/readme.md +++ b/readme.md @@ -99,6 +99,23 @@ Using the `--target-relative` (`-t`) option will augment the shared `.spelling` Using the `--report` (`-r`) option will show a report of all the spelling mistakes that have been found. This mode is useful for CI build reports. +### Report readiness + +Using the `--readiness` (`-y`) option will do two things: + +* Create a readiness report by showing how many files contain spelling errors + +```bash + 59 files with 0 errors + 5 files with at least 1 error + 1 files with at least 10 errors + 0 files with at least 50 errors + 0 files with at least 100 errors + + Readiness indicator: 90% +``` +* Allow to pass a readiness threshold value which will determine if the tool throws an error or not. For example, passing a `-y 90` would allow the current state of the files to pass the CI build without throwing an error (defaults to 100, no errors). + ## `.spelling` files The `.spelling` file is self documenting as it includes...