From 7c15e869afee9b97dc4863ee15bca846795cfb10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jimmy=20Wa=CC=88rting?= Date: Wed, 10 Nov 2021 20:52:34 +0100 Subject: [PATCH] modernize --- index.js | 785 +++++++++++++++++++++++----------------------- jakefile.js | 20 +- package-lock.json | 233 +++++++++++++- test/filelist.js | 91 +++--- 4 files changed, 670 insertions(+), 459 deletions(-) diff --git a/index.js b/index.js index fef873a..3a937c5 100644 --- a/index.js +++ b/index.js @@ -14,473 +14,460 @@ * See the License for the specific language governing permissions and * limitations under the License. * -*/ -var fs = require('fs') -, path = require('path') -, minimatch = require('minimatch') -, escapeRegExpChars -, merge -, basedir -, _readDir -, readdirR -, globSync; + */ - /** - @name escapeRegExpChars - @function - @return {String} A string of escaped characters - @description Escapes regex control-characters in strings - used to build regexes dynamically - @param {String} string The string of chars to escape - */ - escapeRegExpChars = (function () { - var specials = [ '^', '$', '/', '.', '*', '+', '?', '|', '(', ')', - '[', ']', '{', '}', '\\' ]; - var sRE = new RegExp('(\\' + specials.join('|\\') + ')', 'g'); - return function (string) { - var str = string || ''; - str = String(str); - return str.replace(sRE, '\\$1'); - }; - })(); - - /** - @name merge - @function - @return {Object} Returns the merged object - @description Merge merges `otherObject` into `object` and takes care of deep - merging of objects - @param {Object} object Object to merge into - @param {Object} otherObject Object to read from - */ - merge = function (object, otherObject) { - var obj = object || {} - , otherObj = otherObject || {} - , key, value; - - for (key in otherObj) { - value = otherObj[key]; - - // Check if a value is an Object, if so recursively add it's key/values - if (typeof value === 'object' && !(value instanceof Array)) { - // Update value of object to the one from otherObj - obj[key] = merge(obj[key], value); - } - // Value is anything other than an Object, so just add it - else { - obj[key] = value; - } - } +const fs = require('fs') +const path = require('path') +const minimatch = require('minimatch') - return obj; - }; - /** - Given a patern, return the base directory of it (ie. the folder - that will contain all the files matching the path). - eg. file.basedir('/test/**') => '/test/' - Path ending by '/' are considerd as folder while other are considerd - as files, eg.: - file.basedir('/test/a/') => '/test/a' - file.basedir('/test/a') => '/test' - The returned path always end with a '/' so we have: - file.basedir(file.basedir(x)) == file.basedir(x) - */ - basedir = function (pathParam) { - var bd = '' - , parts - , part - , pos = 0 - , p = pathParam || ''; - - // If the path has a leading asterisk, basedir is the current dir - if (p.indexOf('*') == 0 || p.indexOf('**') == 0) { - return '.'; - } - - // always consider .. at the end as a folder and not a filename - if (/(?:^|\/|\\)\.\.$/.test(p.slice(-3))) { - p += '/'; - } +/** + * Escapes regex control-characters in strings + * used to build regexes dynamically + * + * @name escapeRegExpChars + * @function + * @return {String} A string of escaped characters + * @param {String} string The string of chars to escape + */ +const escapeRegExpChars = (function () { + const specials = ['^', '$', '/', '.', '*', '+', '?', '|', '(', ')', + '[', ']', '{', '}', '\\'] + const sRE = new RegExp('(\\' + specials.join('|\\') + ')', 'g') + return function (string) { + let str = string || '' + str = String(str) + return str.replace(sRE, '\\$1') + } +})() - parts = p.split(/\\|\//); - for (var i = 0, l = parts.length - 1; i < l; i++) { - part = parts[i]; - if (part.indexOf('*') > -1 || part.indexOf('**') > -1) { - break; - } - pos += part.length + 1; - bd += part + p[pos - 1]; - } - if (!bd) { - bd = '.'; +/** + * Merge merges `otherObject` into `object` and takes care + * of deep merging of objects + * + * @name merge + * @function + * @return {Object} Returns the merged object + * @param {Object} object Object to merge into + * @param {Object} otherObject Object to read from + */ +function merge (object, otherObject) { + const obj = object || {} + const otherObj = otherObject || {} + let key; let value + + for (key in otherObj) { + value = otherObj[key] + + // Check if a value is an Object, if so recursively add it's key/values + if (typeof value === 'object' && !(value instanceof Array)) { + // Update value of object to the one from otherObj + obj[key] = merge(obj[key], value) } - // Strip trailing slashes - if (!(bd == '\\' || bd == '/')) { - bd = bd.replace(/\\$|\/$/, ''); + // Value is anything other than an Object, so just add it + else { + obj[key] = value } - return bd; + } - }; + return obj +} + +/** + * Given a patern, return the base directory of it (ie. the folder + * that will contain all the files matching the path). + * eg. file.basedir('/test/**') => '/test/' + * Path ending by '/' are considerd as folder while other are considerd + * as files, eg.: + * file.basedir('/test/a/') => '/test/a' + * file.basedir('/test/a') => '/test' + * The returned path always end with a '/' so we have: + * file.basedir(file.basedir(x)) == file.basedir(x) + */ +function basedir (pathParam) { + let bd = '' + let pos = 0 + let p = pathParam || '' + + // If the path has a leading asterisk, basedir is the current dir + if (p.indexOf('*') === 0 || p.indexOf('**') === 0) { + return '.' + } - // Return the contents of a given directory - _readDir = function (dirPath) { - var dir = path.normalize(dirPath) - , paths = [] - , ret = [dir] - , msg; + // always consider .. at the end as a folder and not a filename + if (/(?:^|\/|\\)\.\.$/.test(p.slice(-3))) { + p += '/' + } - try { - paths = fs.readdirSync(dir); - } - catch (e) { - msg = 'Could not read path ' + dir + '\n'; - if (e.stack) { - msg += e.stack; - } - throw new Error(msg); + const parts = p.split(/\\|\//) + for (let i = 0, l = parts.length - 1; i < l; i++) { + let part = parts[i] + if (part.indexOf('*') > -1 || part.indexOf('**') > -1) { + break } + pos += part.length + 1 + bd += part + p[pos - 1] + } + if (!bd) { + bd = '.' + } + // Strip trailing slashes + if (!(bd == '\\' || bd == '/')) { + bd = bd.replace(/\\$|\/$/, '') + } + return bd +} - paths.forEach(function (p) { - var curr = path.join(dir, p); - var stat = fs.statSync(curr); - if (stat.isDirectory()) { - ret = ret.concat(_readDir(curr)); - } - else { - ret.push(curr); - } - }); +// Return the contents of a given directory +function _readDir (dirPath) { + const dir = path.normalize(dirPath) + let paths = [] + let ret = [dir] + let msg - return ret; - }; + try { + paths = fs.readdirSync(dir) + } catch (e) { + msg = 'Could not read path ' + dir + '\n' + if (e.stack) { + msg += e.stack + } + throw new Error(msg) + } - /** - @name file#readdirR - @function - @return {Array} Returns the contents as an Array, can be configured via opts.format - @description Reads the given directory returning it's contents - @param {String} dir The directory to read - @param {Object} opts Options to use - @param {String} [opts.format] Set the format to return(Default: Array) - */ - readdirR = function (dir, opts) { - var options = opts || {} - , format = options.format || 'array' - , ret; - ret = _readDir(dir); - return format == 'string' ? ret.join('\n') : ret; - }; - - -globSync = function (pat, opts) { - var dirname = basedir(pat) - , files - , matches; + paths.forEach(function (p) { + const curr = path.join(dir, p) + const stat = fs.statSync(curr) + if (stat.isDirectory()) { + ret = ret.concat(_readDir(curr)) + } else { + ret.push(curr) + } + }) + + return ret +} + +/** + * @name file#readdirR + * @function + * @return {Array|string} Returns the contents as an Array, can be configured via opts.format + * @description Reads the given directory returning it's contents + * @param {String} dir The directory to read + * @param {Object} [opts] Options to use + * @param {String} [opts.format] Set the format to return(Default: Array) + */ +function readdirR (dir, opts) { + const options = opts || {} + const format = options.format || 'array' + let ret + ret = _readDir(dir) + return format === 'string' ? ret.join('\n') : ret +} + +function globSync (pat, opts) { + const dirname = basedir(pat) + let files + let matches try { - files = readdirR(dirname).map(function(file){ - return file.replace(/\\/g, '/'); - }); + files = readdirR(dirname).map(function (file) { + return file.replace(/\\/g, '/') + }) } // Bail if path doesn't exist -- assume no files - catch(e) { - if (FileList.verbose) console.error(e.message); + catch (e) { + if (FileList.verbose) console.error(e.message) } if (files) { - pat = path.normalize(pat); - matches = minimatch.match(files, pat, opts || {}); + pat = path.normalize(pat) + matches = minimatch.match(files, pat, opts || {}) } - return matches || []; -}; + return matches || [] +} // Constants // --------------- + +const globPattern = /[*?\[\{]/ + // List of all the builtin Array methods we want to override -var ARRAY_METHODS = Object.getOwnPropertyNames(Array.prototype) +const ARRAY_METHODS = Object.getOwnPropertyNames(Array.prototype) + // Array methods that return a copy instead of affecting the original - , SPECIAL_RETURN = { - 'concat': true - , 'slice': true - , 'filter': true - , 'map': true - } +const SPECIAL_RETURN = { + concat: true, + slice: true, + filter: true, + map: true +} + // Default file-patterns we want to ignore - , DEFAULT_IGNORE_PATTERNS = [ - /(^|[\/\\])CVS([\/\\]|$)/ - , /(^|[\/\\])\.svn([\/\\]|$)/ - , /(^|[\/\\])\.git([\/\\]|$)/ - , /\.bak$/ - , /~$/ - ] +const DEFAULT_IGNORE_PATTERNS = [ + /(^|[\/\\])CVS([\/\\]|$)/, + /(^|[\/\\])\.svn([\/\\]|$)/, + /(^|[\/\\])\.git([\/\\]|$)/, + /\.bak$/, + /~$/ +] + // Ignore core files - , DEFAULT_IGNORE_FUNCS = [ - function (name) { - var isDir = false - , stats; - try { - stats = fs.statSync(name); - isDir = stats.isDirectory(); - } - catch(e) {} - return (/(^|[\/\\])core$/).test(name) && !isDir; - } - ]; - -var FileList = function () { - var self = this - , wrap; - - // List of glob-patterns or specific filenames - this.pendingAdd = []; - // Switched to false after lazy-eval of files - this.pending = true; - // Used to calculate exclusions from the list of files - this.excludes = { - pats: DEFAULT_IGNORE_PATTERNS.slice() - , funcs: DEFAULT_IGNORE_FUNCS.slice() - , regex: null - }; - this.items = []; - - // Wrap the array methods with the delegates - wrap = function (prop) { - var arr; - self[prop] = function () { - if (self.pending) { - self.resolve(); - } - if (typeof self.items[prop] == 'function') { - // Special method that return a copy - if (SPECIAL_RETURN[prop]) { - arr = self.items[prop].apply(self.items, arguments); - return FileList.clone(self, arr); - } - else { - return self.items[prop].apply(self.items, arguments); - } - } - else { - return self.items[prop]; - } - }; - }; - for (var i = 0, ii = ARRAY_METHODS.length; i < ii; i++) { - wrap(ARRAY_METHODS[i]); +const DEFAULT_IGNORE_FUNCS = [ + function (name) { + let isDir = false + let stats + try { + stats = fs.statSync(name) + isDir = stats.isDirectory() + } catch (e) {} + return (/(^|[\/\\])core$/).test(name) && !isDir } +] - // Include whatever files got passed to the constructor - this.include.apply(this, arguments); - - // Fix constructor linkage - this.constructor = FileList; -}; - -FileList.prototype = new (function () { - var globPattern = /[*?\[\{]/; - - var _addMatching = function (item) { - var matches = globSync(item.path, item.options); - this.items = this.items.concat(matches); - } +class FileList { + constructor () { + const self = this - , _resolveAdd = function (item) { - if (globPattern.test(item.path)) { - _addMatching.call(this, item); - } - else { - this.push(item.path); + // List of glob-patterns or specific filenames + this.pendingAdd = [] + // Switched to false after lazy-eval of files + this.pending = true + // Used to calculate exclusions from the list of files + this.excludes = { + pats: DEFAULT_IGNORE_PATTERNS.slice(), + funcs: DEFAULT_IGNORE_FUNCS.slice(), + regex: null + } + this.items = [] + + // Wrap the array methods with the delegates + function wrap (prop) { + if (prop === 'constructor') return + let arr + self[prop] = function () { + if (self.pending) { + self.resolve() } - } - - , _calculateExcludeRe = function () { - var pats = this.excludes.pats - , pat - , excl = [] - , matches = []; - - for (var i = 0, ii = pats.length; i < ii; i++) { - pat = pats[i]; - if (typeof pat == 'string') { - // Glob, look up files - if (/[*?]/.test(pat)) { - matches = globSync(pat); - matches = matches.map(function (m) { - return escapeRegExpChars(m); - }); - excl = excl.concat(matches); - } - // String for regex - else { - excl.push(escapeRegExpChars(pat)); - } - } - // Regex, grab the string-representation - else if (pat instanceof RegExp) { - excl.push(pat.toString().replace(/^\/|\/$/g, '')); + if (typeof self.items[prop] === 'function') { + // Special method that return a copy + if (SPECIAL_RETURN[prop]) { + arr = self.items[prop](...arguments) + return FileList.clone(self, arr) + } else { + return self.items[prop](...arguments) } - } - if (excl.length) { - this.excludes.regex = new RegExp('(' + excl.join(')|(') + ')'); - } - else { - this.excludes.regex = /^$/; + } else { + return self.items[prop] } } + } - , _resolveExclude = function () { - var self = this; - _calculateExcludeRe.call(this); - // No `reject` method, so use reverse-filter - this.items = this.items.filter(function (name) { - return !self.shouldExclude(name); - }); - }; - - /** - * Includes file-patterns in the FileList. Should be called with one or more - * pattern for finding file to include in the list. Arguments should be strings - * for either a glob-pattern or a specific file-name, or an array of them - */ - this.include = function () { - var args = Array.prototype.slice.call(arguments) - , arg - , includes = { items: [], options: {} }; + ARRAY_METHODS.forEach(wrap) - for (var i = 0, ilen = args.length; i < ilen; i++) { - arg = args[i]; + // Include whatever files got passed to the constructor + this.include(...arguments) + } - if (typeof arg === 'object' && !Array.isArray(arg)) { - merge(includes.options, arg); - } else { - includes.items = includes.items.concat(arg).filter(function (item) { - return !!item; - }); - } + // Static method, used to create copy returned by special + // array methods + static clone (list, items) { + const clone = new FileList() + if (items) { + clone.items = items } + clone.pendingAdd = list.pendingAdd + clone.pending = list.pending + for (const p in list.excludes) { + clone.excludes[p] = list.excludes[p] + } + return clone + } - var items = includes.items.map(function(item) { - return { path: item, options: includes.options }; - }); - - this.pendingAdd = this.pendingAdd.concat(items); - - return this; - }; + /** + * Clear any pending items -- only useful before + * calling `resolve` + */ + clearInclusions () { + this.pendingAdd = [] + return this + } /** - * Indicates whether a particular file would be filtered out by the current - * exclusion rules for this FileList. - * @param {String} name The filename to check - * @return {Boolean} Whether or not the file should be excluded + * Clear any current exclusion rules */ - this.shouldExclude = function (name) { - if (!this.excludes.regex) { - _calculateExcludeRe.call(this); + clearExclusions () { + this.excludes = { + pats: [], + funcs: [], + regex: null } - var excl = this.excludes; - return excl.regex.test(name) || excl.funcs.some(function (f) { - return !!f(name); - }); - }; + return this + } /** - * Excludes file-patterns from the FileList. Should be called with one or more - * pattern for finding file to include in the list. Arguments can be: - * 1. Strings for either a glob-pattern or a specific file-name - * 2. Regular expression literals - * 3. Functions to be run on the filename that return a true/false + * Convert to a plain-jane array */ - this.exclude = function () { - var args = Array.isArray(arguments[0]) ? arguments[0] : arguments - , arg; - for (var i = 0, ii = args.length; i < ii; i++) { - arg = args[i]; - if (typeof arg == 'function' && !(arg instanceof RegExp)) { - this.excludes.funcs.push(arg); - } - else { - this.excludes.pats.push(arg); - } - } - if (!this.pending) { - _resolveExclude.call(this); - } - return this; - }; + toArray () { + // Call slice to ensure lazy-resolution before slicing items + const ret = this.slice().items.slice() + return ret + } /** * Populates the FileList from the include/exclude rules with a list of * actual files */ - this.resolve = function () { - var item - , uniqueFunc = function (p, c) { - if (p.indexOf(c) < 0) { - p.push(c); - } - return p; - }; + resolve () { + let item + const uniqueFunc = function (p, c) { + if (p.indexOf(c) < 0) { + p.push(c) + } + return p + } if (this.pending) { - this.pending = false; + this.pending = false while ((item = this.pendingAdd.shift())) { - _resolveAdd.call(this, item); + this._resolveAdd(item) } // Reduce to a unique list - this.items = this.items.reduce(uniqueFunc, []); + this.items = this.items.reduce(uniqueFunc, []) // Remove exclusions - _resolveExclude.call(this); + this._resolveExclude() } - return this; - }; + return this + } /** - * Convert to a plain-jane array + * Excludes file-patterns from the FileList. Should be called with one or more + * pattern for finding file to include in the list. Arguments can be: + * 1. Strings for either a glob-pattern or a specific file-name + * 2. Regular expression literals + * 3. Functions to be run on the filename that return a true/false */ - this.toArray = function () { - // Call slice to ensure lazy-resolution before slicing items - var ret = this.slice().items.slice(); - return ret; - }; + exclude () { + const args = Array.isArray(arguments[0]) ? arguments[0] : arguments + let arg + for (let i = 0, len = args.length; i < len; i++) { + arg = args[i] + if (typeof arg === 'function' && !(arg instanceof RegExp)) { + this.excludes.funcs.push(arg) + } else { + this.excludes.pats.push(arg) + } + } + if (!this.pending) { + this._resolveExclude() + } + return this + } /** - * Clear any pending items -- only useful before - * calling `resolve` + * Indicates whether a particular file would be filtered out by the current + * exclusion rules for this FileList. + * @param {String} name The filename to check + * @return {Boolean} Whether or not the file should be excluded */ - this.clearInclusions = function () { - this.pendingAdd = []; - return this; - }; + shouldExclude (name) { + if (!this.excludes.regex) { + this._calculateExcludeRe() + } + const excl = this.excludes + return excl.regex.test(name) || excl.funcs.some(function (f) { + return !!f(name) + }) + } /** - * Clear any current exclusion rules + * Includes file-patterns in the FileList. Should be called with one or more + * pattern for finding file to include in the list. Arguments should be strings + * for either a glob-pattern or a specific file-name, or an array of them */ - this.clearExclusions = function () { - this.excludes = { - pats: [] - , funcs: [] - , regex: null - }; - return this; - }; - -})(); - -// Static method, used to create copy returned by special -// array methods -FileList.clone = function (list, items) { - var clone = new FileList(); - if (items) { - clone.items = items; + include (...args) { + let arg + const includes = { items: [], options: {} } + + for (let i = 0, len = args.length; i < len; i++) { + arg = args[i] + + if (typeof arg === 'object' && !Array.isArray(arg)) { + merge(includes.options, arg) + } else { + includes.items = includes.items.concat(arg).filter(Boolean) + } + } + + const items = includes.items.map(item => ({ + path: item, + options: includes.options + })) + + this.pendingAdd = this.pendingAdd.concat(items) + + return this + } + + /** @private */ + _resolveExclude () { + const self = this + this._calculateExcludeRe() + // No `reject` method, so use reverse-filter + this.items = self.items.filter(function (name) { + return !self.shouldExclude(name) + }) + } + + /** @private */ + _addMatching (item) { + const matches = globSync(item.path, item.options) + this.items = this.items.concat(matches) } - clone.pendingAdd = list.pendingAdd; - clone.pending = list.pending; - for (var p in list.excludes) { - clone.excludes[p] = list.excludes[p]; + + /** @private */ + _resolveAdd (item) { + if (globPattern.test(item.path)) { + this._addMatching(item) + } else { + this.push(item.path) + } + } + + /** @private */ + _calculateExcludeRe () { + const pats = this.excludes.pats + let pat + let excl = [] + let matches = [] + + for (let i = 0, len = pats.length; i < len; i++) { + pat = pats[i] + if (typeof pat === 'string') { + // Glob, look up files + if (/[*?]/.test(pat)) { + matches = globSync(pat) + matches = matches.map(function (m) { + return escapeRegExpChars(m) + }) + excl = excl.concat(matches) + } + // String for regex + else { + excl.push(escapeRegExpChars(pat)) + } + } + // Regex, grab the string-representation + else if (pat instanceof RegExp) { + excl.push(pat.toString().replace(/^\/|\/$/g, '')) + } + } + if (excl.length) { + this.excludes.regex = new RegExp('(' + excl.join(')|(') + ')') + } else { + this.excludes.regex = /^$/ + } } - return clone; -}; +} FileList.verbose = true -exports.FileList = FileList; +exports.FileList = FileList diff --git a/jakefile.js b/jakefile.js index 18d4d7d..12c9aa4 100644 --- a/jakefile.js +++ b/jakefile.js @@ -1,15 +1,13 @@ testTask('FileList', function () { - this.testFiles.include('test/*.js'); -}); + this.testFiles.include('test/*.js') +}) publishTask('FileList', function () { this.packageFiles.include([ - 'jakefile.js', - 'README.md', - 'package.json', - 'index.js', - 'index.d.ts' - ]); -}); - - + 'jakefile.js', + 'README.md', + 'package.json', + 'index.js', + 'index.d.ts' + ]) +}) diff --git a/package-lock.json b/package-lock.json index fb7ddbe..6d0a940 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,170 @@ { "name": "filelist", - "version": "1.0.1", - "lockfileVersion": 1, + "version": "1.0.2", + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "version": "1.0.2", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^3.0.4" + }, + "devDependencies": { + "jake": "^10.8.2" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/filelist": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", + "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", + "dev": true, + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/jake": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", + "dev": true, + "dependencies": { + "async": "0.9.x", + "chalk": "^2.4.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + } + }, "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -18,11 +179,70 @@ "concat-map": "0.0.1" } }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "filelist": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", + "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "jake": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", + "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", + "dev": true, + "requires": { + "async": "0.9.x", + "chalk": "^2.4.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + } + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -30,6 +250,15 @@ "requires": { "brace-expansion": "^1.1.7" } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } } diff --git a/test/filelist.js b/test/filelist.js index e278f0d..934931c 100644 --- a/test/filelist.js +++ b/test/filelist.js @@ -1,50 +1,47 @@ -var FileList = require('../index').FileList - , fs = require("fs") - , assert = require("assert") - , tests; - -tests = { - - 'beforeEach': function () { - jake.mkdirP("./test/tmp/one/two/three"); - jake.mkdirP("./test/tmp/one/exclude"); - - fs.writeFileSync("./test/tmp/one/two/three/file.txt", "hello"); - fs.writeFileSync("./test/tmp/one/exclude/file.txt", "world"); - - fs.writeFileSync("./test/tmp/foo.json", "{}") - fs.writeFileSync("./test/tmp/bar.JSON", "{}") - } - -, 'afterEach': function () { - jake.rmRf('./test/tmp/one', {silent: true}); - } - -, 'after': function () { - jake.rmRf('./test/tmp', {silent:true}); - } - -, 'path separator can be used by exclude': function () { - var fileList = new FileList(); - fileList.include("test/tmp/one/**/*.txt"); - assert.equal(fileList.toArray().length, 2); - fileList.exclude("tmp/one/exclude"); - assert.equal(fileList.toArray().length, 1); - } - -, 'returns a list of unique file entries': function () { - var fileList = new FileList(); - fileList.include("test/tmp/one/**/*.txt"); - fileList.include("test/tmp/one/two/three/file.txt"); - assert.equal(fileList.toArray().length, 2); - } - -, 'passing options to minimatch object': function () { - var filelist = new FileList; - filelist.include("test/tmp/*.json", { nocase: true }) +const { FileList } = require('../index.js') +const fs = require('fs') +const assert = require('assert') + +const tests = { + beforeEach () { + jake.mkdirP('./test/tmp/one/two/three') + jake.mkdirP('./test/tmp/one/exclude') + + fs.writeFileSync('./test/tmp/one/two/three/file.txt', 'hello') + fs.writeFileSync('./test/tmp/one/exclude/file.txt', 'world') + + fs.writeFileSync('./test/tmp/foo.json', '{}') + fs.writeFileSync('./test/tmp/bar.JSON', '{}') + }, + + afterEach () { + jake.rmRf('./test/tmp/one', { silent: true }) + }, + + after () { + jake.rmRf('./test/tmp', { silent: true }) + }, + + 'path separator can be used by exclude' () { + const fileList = new FileList() + fileList.include('test/tmp/one/**/*.txt') + assert.equal(fileList.toArray().length, 2) + fileList.exclude('tmp/one/exclude') + assert.equal(fileList.toArray().length, 1) + }, + + 'returns a list of unique file entries' () { + const fileList = new FileList() + fileList.include('test/tmp/one/**/*.txt') + fileList.include('test/tmp/one/two/three/file.txt') + assert.equal(fileList.toArray().length, 2) + }, + + 'passing options to minimatch object' () { + const filelist = new FileList() + filelist.include('test/tmp/*.json', { nocase: true }) assert.equal(filelist.toArray().length, 2) } +} -}; - -module.exports = tests; +module.exports = tests