From a11f1322c2870ddb14725ef2b2cc35543e46a0fd Mon Sep 17 00:00:00 2001 From: Denis Seleznev Date: Sat, 4 Jun 2016 22:12:54 +0300 Subject: [PATCH] Added support for stdin #45 --- lib/cli.js | 105 ++++++---------------------------- lib/dictionary.js | 22 ++++--- lib/tasks.js | 123 ++++++++++++++++++++++++++++++++++++++++ test/test.dictionary.js | 50 ++++++++-------- 4 files changed, 181 insertions(+), 119 deletions(-) create mode 100644 lib/tasks.js diff --git a/lib/cli.js b/lib/cli.js index 99293de..7c813be 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -1,35 +1,24 @@ 'use strict'; -var fs = require('fs'), - async = require('async'), +var async = require('async'), chalk = require('chalk'), program = require('commander'), - pth = require('path'), programOptions = require('./options'), debug = require('./debug'), dict = require('./dictionary'), report = require('./report'), + tasks = require('./tasks'), utils = require('./utils'), - yaspeller = require('./yaspeller'), _ = require('lodash'), - exitCodes = require('./exit-codes'), - exitCode = 0, json, jsonConfig, jsonDefault = require('../.yaspellerrc.default.json'), - dictionary = [], settings = {}; -programOptions.set({ - ignoreTags: jsonDefault.ignoreTags.join(',') -}); +programOptions.set({ignoreTags: jsonDefault.ignoreTags.join(',')}); program.parse(process.argv); -if(!program.args.length) { - program.help(); -} - jsonConfig = utils.getConfig(program.config); json = _.assign(jsonDefault, jsonConfig); @@ -55,82 +44,20 @@ programOptions.apiOptions.forEach(function(el) { } }); -dictionary = dict.getDictionary(program.dictionary, json.dictionary); - -var tasks = [], - hasData = function(err, data) { - return !err && data && Array.isArray(data.data) && data.data.length; - }, - onResource = function(err, data) { - if(hasData(err, data)) { - data.data = dict.removeDictWords(data.data, dictionary); - data.data = yaspeller.removeDuplicates(data.data); - } - - if(!exitCode && hasData(err, data)) { - exitCode = exitCodes.HAS_TYPOS; - } - - if(err) { - exitCode = exitCodes.ERROR_LOADING; - } - - report.oneach(err, data); - }; +dict.set(program.dictionary, json.dictionary); report.addReports(program.report || json.report); -program.args.forEach(function(resource) { - tasks.push(function(cb) { - var subTasks = []; - if(utils.isUrl(resource)) { - if(utils.isSitemap(resource)) { - yaspeller.checkSitemap(resource, function() { - cb(); - }, settings, onResource); - } else { - yaspeller.checkUrl(resource, function(err, data) { - onResource(err, data); - cb(); - }, settings); - } - } else { - if(fs.existsSync(resource)) { - if(utils.isDir(resource)) { - utils - .findFiles(resource, settings.fileExtensions, settings.excludeFiles) - .forEach(function(file) { - subTasks.push(function(subcb) { - yaspeller.checkFile(file, function(err, data) { - onResource(err, data); - subcb(); - }, settings); - }); - }); - - async.parallelLimit(subTasks, settings.maxRequests, function() { - cb(); - }); - } else { - var file = pth.resolve(resource); - if(utils.isExcludedFile(file, settings.excludeFiles)) { - cb(); - } else { - yaspeller.checkFile(file, function(err, data) { - onResource(err, data); - cb(); - }, settings); - } - } - } else { - onResource(true, Error(resource + ': is not exists')); - cb(); - } - } - }); -}); +if(process.stdin.isTTY && !program.args.length) { + program.help(); +} -async.series(tasks, function() { - report.onend(); - process.exit(exitCode); -}); +async.series( + process.stdin.isTTY ? + tasks.forResources(program.args, settings) : + tasks.forStdin(settings), + function() { + report.onend(); + process.exit(); + } +); diff --git a/lib/dictionary.js b/lib/dictionary.js index ffc04c7..f18a9a1 100644 --- a/lib/dictionary.js +++ b/lib/dictionary.js @@ -11,13 +11,12 @@ var chalk = require('chalk'), module.exports = { /** - * Get dictionary. + * Set dictionary. * * @param {Array} files * @param {Array} configDictionary - Dictionary from .yaspellerrc - * @return {Array} */ - getDictionary: function(files, configDictionary) { + set: function(files, configDictionary) { var result = [], count = 0, commonUniqueWords = [], @@ -45,8 +44,17 @@ module.exports = { this.checkDuplicates(commonUniqueWords, 'Duplicate words in dictionaries:'); } - return this.prepareDictionary(result); + this._dict = this.prepareDictionary(result); }, + /** + * Get dictionary. + * + * @return {Array} + */ + get: function() { + return this._dict; + }, + _dict: [], /** * Load dictionary. * @@ -116,11 +124,11 @@ module.exports = { * Remove typos that is in the dictionary. * * @param {Object[]} data - Array of typos. - * @param {string[]|RegExp[]} dictionary * @return {Object[]} */ - removeDictWords: function(data, dictionary) { - var result = []; + removeDictWords: function(data) { + var result = [], + dictionary = this.get(); data.forEach(function(typo) { if((typo.code !== 1 && typo.code !== 3) || this.isTypo(typo.word, dictionary)) { diff --git a/lib/tasks.js b/lib/tasks.js new file mode 100644 index 0000000..b746e81 --- /dev/null +++ b/lib/tasks.js @@ -0,0 +1,123 @@ +'use strict'; + +var async = require('async'), + fs = require('fs'), + pth = require('path'), + dict = require('./dictionary'), + exitCodes = require('./exit-codes'), + report = require('./report'), + utils = require('./utils'), + yaspeller = require('./yaspeller'); + +function hasData(err, data) { + return !err && data && Array.isArray(data.data) && data.data.length; +} + +function onResource(err, data) { + if(hasData(err, data)) { + data.data = dict.removeDictWords(data.data); + data.data = yaspeller.removeDuplicates(data.data); + } + + if(!process.exitCode && hasData(err, data)) { + process.exitCode = exitCodes.HAS_TYPOS; + } + + if(err) { + process.exitCode = exitCodes.ERROR_LOADING; + } + + report.oneach(err, data); +} + +module.exports = { + /** + * Prepare tasks for resources. + * + * @param {Array} resources + * @param {Object} settings + * @return {Array} + */ + forResources: function(resources, settings) { + var tasks = []; + + resources.forEach(function(resource) { + tasks.push(function(cb) { + var subTasks = []; + if(utils.isUrl(resource)) { + if(utils.isSitemap(resource)) { + yaspeller.checkSitemap(resource, function() { + cb(); + }, settings, onResource); + } else { + yaspeller.checkUrl(resource, function(err, data) { + onResource(err, data); + cb(); + }, settings); + } + } else { + if(fs.existsSync(resource)) { + if(utils.isDir(resource)) { + utils + .findFiles(resource, settings.fileExtensions, settings.excludeFiles) + .forEach(function(file) { + subTasks.push(function(subcb) { + yaspeller.checkFile(file, function(err, data) { + onResource(err, data); + subcb(); + }, settings); + }); + }); + + async.parallelLimit(subTasks, settings.maxRequests, function() { + cb(); + }); + } else { + var file = pth.resolve(resource); + if(utils.isExcludedFile(file, settings.excludeFiles)) { + cb(); + } else { + yaspeller.checkFile(file, function(err, data) { + onResource(err, data); + cb(); + }, settings); + } + } + } else { + onResource(true, Error(resource + ': is not exists')); + cb(); + } + } + }); + }); + + return tasks; + }, + /** + * Prepare task for stdin. + * + * @param {Object} settings + * @return {Array} + */ + forStdin: function(settings) { + return [function(cb) { + var text = ''; + + process.stdin.setEncoding('utf8'); + + process.stdin.on('readable', function() { + var chunk = process.stdin.read(); + if(chunk !== null) { + text += chunk; + } + }); + + process.stdin.on('end', function() { + yaspeller.checkText(text, function(err, data) { + onResource(err, data); + cb(); + }, settings); + }); + }]; + } +}; diff --git a/test/test.dictionary.js b/test/test.dictionary.js index 1b6fad4..0e14cb6 100644 --- a/test/test.dictionary.js +++ b/test/test.dictionary.js @@ -28,7 +28,9 @@ describe('Dictionary', function() { } ]; - var result = dictionary.removeDictWords(typos, dict); + dictionary._dict = dict; + + var result = dictionary.removeDictWords(typos); assert.deepEqual(result, [ { code: 2, @@ -70,7 +72,9 @@ describe('Dictionary', function() { } ]; - var result = dictionary.removeDictWords(typos, dict); + dictionary._dict = dict; + + var result = dictionary.removeDictWords(typos); assert.deepEqual(result, [ { code: 1, @@ -159,18 +163,18 @@ describe('Dictionary', function() { }); it('getDictionary(), empty params', function() { - var result = dictionary.getDictionary(); - assert.deepEqual(result, []); + dictionary.set(); + assert.deepEqual(dictionary._dict, []); }); - it('getDictionary(), dictionary from config', function() { - var result = dictionary.getDictionary([], ['a']); - assert.deepEqual(result, [/[aA]/]); + it('set(), dictionary from config', function() { + dictionary.set([], ['a']); + assert.deepEqual(dictionary._dict, [/[aA]/]); }); - it('getDictionary()', function() { - var result = dictionary.getDictionary(['test/dict/a.json', 'test/dict/b.json'], ['a']); - assert.deepEqual(result, [ + it('set()', function() { + dictionary.set(['test/dict/a.json', 'test/dict/b.json'], ['a']); + assert.deepEqual(dictionary._dict, [ /[aA]/, /[xX]yz/, /[aA]bc/, @@ -179,18 +183,18 @@ describe('Dictionary', function() { ]); }); - it('getDictionary(), is not utf8', function() { - dictionary.getDictionary(['test/dict/not_utf8.json']); + it('set(), is not utf8', function() { + dictionary.set(['test/dict/not_utf8.json']); assert.equal(process.exit.args[0], exitCodes.ERROR_DICTIONARY); }); - it('getDictionary(), error parsing', function() { - dictionary.getDictionary(['test/dict/error_parsing.json']); + it('set(), error parsing', function() { + dictionary.set(['test/dict/error_parsing.json']); assert.equal(process.exit.args[0], exitCodes.ERROR_DICTIONARY); }); - it('getDictionary(), not exists', function() { - dictionary.getDictionary(['test/dict/not_exists.json']); + it('set(), not exists', function() { + dictionary.set(['test/dict/not_exists.json']); assert.equal(process.exit.args[0], exitCodes.ERROR_DICTIONARY); }); @@ -198,25 +202,25 @@ describe('Dictionary', function() { assert.isFalse(dictionary.isNotOptimizedRegExp('/Unknownword/')); assert.isTrue(dictionary.isNotOptimizedRegExp('/[U]nknownword/')); assert.isTrue(dictionary.isNotOptimizedRegExp('[U]nknownword')); - + assert.isTrue(dictionary.isNotOptimizedRegExp('/Unknownwor[d]/')); assert.isTrue(dictionary.isNotOptimizedRegExp('Unknownwor[d]')); - + assert.isTrue(dictionary.isNotOptimizedRegExp('/()Unknownword/')); assert.isTrue(dictionary.isNotOptimizedRegExp('()Unknownword')); - + assert.isTrue(dictionary.isNotOptimizedRegExp('/Unknownword()/')); assert.isTrue(dictionary.isNotOptimizedRegExp('Unknownword()')); - + assert.isTrue(dictionary.isNotOptimizedRegExp('/Unknow[]nword/')); assert.isTrue(dictionary.isNotOptimizedRegExp('Unknow[]nword')); - + assert.isFalse(dictionary.isNotOptimizedRegExp('/Unknow[ab]nword/')); assert.isFalse(dictionary.isNotOptimizedRegExp('Unknow[ab]nword')); - + assert.isTrue(dictionary.isNotOptimizedRegExp('/Unknow[a]nword/')); assert.isTrue(dictionary.isNotOptimizedRegExp('Unknow[a]nword')); - + assert.isTrue(dictionary.isNotOptimizedRegExp('/Unknow(a)nword/')); assert.isTrue(dictionary.isNotOptimizedRegExp('Unknow(a)nword')); });