Skip to content

Commit

Permalink
add include/exclude options to readdirFilter
Browse files Browse the repository at this point in the history
  • Loading branch information
mhkeller committed Nov 16, 2015
1 parent 47c4af4 commit 155a9e6
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 141 deletions.
195 changes: 78 additions & 117 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ var parsers = {
},
yaml: {
parse: function (data) {
console.log(data)
console.log('aaaa', yaml_parser.load(data))
return yaml_parser.load(data)
}
}
Expand Down Expand Up @@ -576,103 +574,110 @@ readers.readDbf = function (path, cb) {
}

// Used internally by `readdir` functions to make more DRY
function readdir (modeInfo, dirPath, inOrExcludesStr, includeFullPath, cb) {
if (typeof cb !== 'function' && modeInfo.async === true) {
cb = includeFullPath
function readdir (modeInfo, dirPath, _opts, cb) {
if (typeof cb === undefined && modeInfo.async === true) {
cb = _opts
}
var inOrExcludesArr
if (!_.isArray(inOrExcludesStr)) {
inOrExcludesArr = [inOrExcludesStr]
var asyncMode = modeInfo.async

// Convert to array if a string
_opts.include = strToArray(_opts.include)
_opts.exclude = strToArray(_opts.exclude)

// Set defaults if not provided
_opts.includeMode = _opts.includeMode || 'some'
_opts.excludeMode = _opts.excludeMode || 'some'

if (asyncMode === true) {
fs.readdir(dirPath, function (err, files) {
cb(err, filter(files))
})
} else {
inOrExcludesArr = inOrExcludesStr
return filter(fs.readdirSync(dirPath))
}
if (modeInfo.async === true) {
fs.readdir(dirPath, filter(modeInfo.async))
} else {
// This looks slightly ugly to make it work both async and sync
// But it works nicely and is pretty succinct
return filter(modeInfo.async)(null, fs.readdirSync(dirPath))

function strToArray (val) {
if (val && !_.isArray(val)) {
val = [val]
}
return val
}

function filter (async) {
return function (err, files) {
if (err) {
throw err
}
var filtered = files.filter(function (fileName) {
// If we're including, then some can pass, otherwise, all must fail
var strictness = (modeInfo.include) ? 'some' : 'all'
return _[strictness](inOrExcludesArr, function (includeExtension) { return _.isEqual(modeInfo.include, helpers.matches(fileName, includeExtension)) })
})
if (includeFullPath === true) {
filtered = filtered.map(function (fileName) {
return path.join(dirPath, fileName)
function filter (files) {
var filtered = files.filter(function (fileName) {
var isExcluded
var isIncluded

// Don't include if matches exclusion matcher
if (_opts.exclude) {
isExcluded = _opts.exclude[_opts.excludeMode](function (matcher) {
return helpers.matches(fileName, matcher)
})
if (isExcluded === true) {
return false
}
}
if (async) {
cb(err, filtered)
} else {
return filtered

if (_opts.include) {
isIncluded = _opts.include[_opts.includeMode](function (matcher) {
return helpers.matches(fileName, matcher)
})
return isIncluded
}

return true

})

// Prefix with the full path if that's what we asked for
if (_opts.fullPath === true) {
filtered = filtered.map(function (fileName) {
return path.join(dirPath, fileName)
})
}
return filtered
}

}

/**
* Get a list of a directory's files and folders if certain critera are met.
*
* @param {String} dirPath the directory to read from
* @param {Object} options filter options, see below
* @param {String|RegExp|Array<String>|Array<RegExp>} options.include if given a string, return files that have that string as their extension. If given a Regular Expression, return the file that matches the pattern. Can also take a list of both.List matching behavior is described in `includeAll`.
* @param {String|RegExp|Array<String>|Array<RegExp>} options.exclude if given a string, return files that do not have that string as their extension. If given a Regular Expression, return the file that matches the pattern. Can also take a list of both. List matching behavior is described in `excludeAll`.
* @param {String} [options.includeMode='all'] Can be `'all'` or `'any'`. The former will require all include conditions to be met for the target to be included. The latter will only require one.
* @param {String} [options.excludeMode='any'] Can be `'all'` or `'any'`. The former will require all exclude conditions to be met for the target to be excluded. The latter will only require one.
* @param {String} dirPath The directory to read from
* @param {Object} options Filter options, see below
* @param {String|RegExp|Array<String>|Array<RegExp>} options.include If given a string, return files that have that string as their extension. If given a Regular Expression, return the file that matches the pattern. Can also take a list of both. List matching behavior is described in `includeAll`.
* @param {String|RegExp|Array<String>|Array<RegExp>} options.exclude If given a string, return files that do not have that string as their extension. If given a Regular Expression, return the file that matches the pattern. Can also take a list of both. List matching behavior is described in `excludeAll`.
* @param {String} [options.includeMode='any'] Can be `'all'` or `'any'`. The former will require all include conditions to be met for the target to be included. The latter will only require one. Default is `'any'`.
* @param {String} [options.excludeMode='any'] Can be `'all'` or `'any'`. The former will require all exclude conditions to be met for the target to be excluded. The latter will only require one. Default is `'any'`.
* @param {String} [options.fullPath=false] If `true` the full path of the file, otherwise return just the file name.
* @param {Function} callback Callback fired with signature of `(err, files)` where `files` is a list of matching file names.
*
* @example
* // dir contains `data-0.tsv`, `data-0.json`, `data-0.csv`, `data-1.csv`, `.hidden-file`
* io.readdirInclude('path/to/files', 'csv', function(err, files){
* io.readdirFilter('path/to/files', {include: 'csv'}, function(err, files){
* console.log(files) // ['data-0.csv', 'data-1.csv']
* })
*
* io.readdirInclude('path/to/files', ['csv', 'tsv'], true, function(err, files){
* io.readdirFilter('path/to/files', {include: [/^data/], exclude: ['csv', 'json']}, , function(err, files){
* console.log(files) // ['path/to/files/data-0.csv', 'path/to/files/data-1.csv', 'path/to/files/data-0.tsv']
* })
*
*/
readers.readdirFilter = function (dirPath, opts, cb) {
readdir({async: true}, dirPath, opts, cb)
readers.readdirFilter = function (dirPath, _opts, cb) {
readdir({async: true}, dirPath, _opts, cb)
}

/**
* Get a list of the files in a directory with selected extentions.
*
* @param {String} dirPath the directory to read from
* @param {Array<String>|String|Array<RegExp>|RegExp} includes the file extention(s) to include or RegExp matching file name
* @param {Boolean} [includeFullPath=false] return the `dirPath` in the result
* @param {Function} callback the callback that will accept the filtered files, takes an optional error and an array of file names
* Synchronously get a list of a directory's files and folders if certain critera are met.
*
* @example
* // dir contains `data-0.tsv`, `data-0.json`, `data-0.csv`, `data-1.csv`, `.hidden-file`
* io.readdirInclude('path/to/files', 'csv', function(err, files){
* console.log(files) // ['data-0.csv', 'data-1.csv']
* })
*
* io.readdirInclude('path/to/files', ['csv', 'tsv'], true, function(err, files){
* console.log(files) // ['path/to/files/data-0.csv', 'path/to/files/data-1.csv', 'path/to/files/data-0.tsv']
* })
*
*/
// readers.readdirInclude = function (dirPath, includesStr, includeFullPath, cb) {
// readdir({include: true, async: true}, dirPath, includesStr, includeFullPath, cb)
// }

/**
* Synchronously get a list of the files in a directory with selected extentions.
*
* @param {String} dirPath the directory to read from
* @param {Array<String>|String|Array<RegExp>|RegExp} includes the file extention(s) to include or RegExp matching file name
* @param {Boolean} [includeFullPath=false] return the `dirPath` in the result
* @returns {Array<String>} the matching files' paths
* @param {String} dirPath The directory to read from
* @param {Object} options filter options, see below
* @param {String|RegExp|Array<String>|Array<RegExp>} options.include if given a string, return files that have that string as their extension. If given a Regular Expression, return the file that matches the pattern. Can also take a list of both. List matching behavior is described in `includeAll`.
* @param {String|RegExp|Array<String>|Array<RegExp>} options.exclude if given a string, return files that do not have that string as their extension. If given a Regular Expression, return the file that matches the pattern. Can also take a list of both. List matching behavior is described in `excludeAll`.
* @param {String} [options.includeMode='any'] Can be `'all'` or `'any'`. The former will require all include conditions to be met for the target to be included. The latter will only require one. Default is `'any'`.
* @param {String} [options.excludeMode='any'] Can be `'all'` or `'any'`. The former will require all exclude conditions to be met for the target to be excluded. The latter will only require one. Default is `'any'`.
* @param {String} [options.fullPath=false] If `true` the full path of the file, otherwise return just the file name.
* @returns {Array<String>} The matching file names
*
* @example
* // dir contains `data-0.tsv`, `data-0.json`, `data-0.csv`, `data-1.csv`, `.hidden-file`
Expand All @@ -683,53 +688,9 @@ readers.readdirFilter = function (dirPath, opts, cb) {
* console.log(files) // ['path/to/files/.hidden-file','path/to/files/data-0.csv', 'path/to/files/data-1.csv', 'path/to/files/data-0.tsv']
*
*/
// readers.readdirIncludeSync = function (dirPath, includesStr, includeFullPath) {
// return readdir({include: true, async: false}, dirPath, includesStr, includeFullPath)
// }

/**
* Get a list of the files in a directory that do not have the selected extentions.
*
* @param {String} dirPath the directory to read from
* @param {Array<String>|String|Array<RegExp>|RegExp} excludes the file extention(s) to exclude or RegExp matching file name
* @param {Boolean} [includeFullPath=false] return the `dirPath` in the result
* @param {Function} callback the callback that will accept the filtered files, takes an optional error and an array of file names
*
* @example
* // dir contains `data-0.tsv`, `data-0.json`, `data-0.csv`, `data-1.csv`, `.hidden-file`
* io.readdirExclude('path/to/files', 'csv', function(err, files){
* console.log(files) // ['data-0.tsv', 'data-0.json', '.hidden-file']
* })
*
* io.readdirExclude('path/to/files', ['csv', 'tsv', /^\./], true, function(err, files){
* console.log(files) // ['path/to/files/data-0.json']
* })
*
*/
// readers.readdirExclude = function (dirPath, excludesStr, includeFullPath, cb) {
// readdir({include: false, async: true}, dirPath, excludesStr, includeFullPath, cb)
// }

/**
* Synchronously get a list of the files in a directory that do not have the selected extentions.
*
* @param {String} dirPath the directory to read from
* @param {Array<String>|String|Array<RegExp>|RegExp} excludes the file extention(s) to exclude or RegExp matching file name
* @param {Boolean} [includeFullPath=false] return the `dirPath` in the result
* @returns {Array<String>} the matching files' paths
*
* @example
* // dir contains `data-0.tsv`, `data-0.json`, `data-0.csv`, `data-1.csv`, `.hidden-file`
* var files = io.readdirExcludeSync('path/to/files', 'csv')
* console.log(files) // ['data-0.tsv', 'data-0.json', '.hidden-file']
*
* var files = io.readdirExcludeSync('path/to/files', ['csv', 'tsv', /^\./], true)
* console.log(files) // ['path/to/files/data-0.json']
*
*/
// readers.readdirExcludeSync = function (dirPath, excludesStr, includeFullPath) {
// return readdir({include: false, async: false}, dirPath, excludesStr, includeFullPath)
// }
readers.readdirFilterSync = function (dirPath, _opts) {
return readdir({async: false}, dirPath, _opts)
}

/** @namespace */
var writers = {}
Expand Down

0 comments on commit 155a9e6

Please sign in to comment.