You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.1 KiB
128 lines
3.1 KiB
'use strict'; |
|
const arrayUnion = require('array-union'); |
|
const glob = require('glob'); |
|
const fastGlob = require('fast-glob'); |
|
const dirGlob = require('dir-glob'); |
|
const gitignore = require('./gitignore'); |
|
|
|
const DEFAULT_FILTER = () => false; |
|
|
|
const isNegative = pattern => pattern[0] === '!'; |
|
|
|
const assertPatternsInput = patterns => { |
|
if (!patterns.every(x => typeof x === 'string')) { |
|
throw new TypeError('Patterns must be a string or an array of strings'); |
|
} |
|
}; |
|
|
|
const generateGlobTasks = (patterns, taskOpts) => { |
|
patterns = [].concat(patterns); |
|
assertPatternsInput(patterns); |
|
|
|
const globTasks = []; |
|
|
|
taskOpts = Object.assign({ |
|
ignore: [], |
|
expandDirectories: true |
|
}, taskOpts); |
|
|
|
patterns.forEach((pattern, i) => { |
|
if (isNegative(pattern)) { |
|
return; |
|
} |
|
|
|
const ignore = patterns |
|
.slice(i) |
|
.filter(isNegative) |
|
.map(pattern => pattern.slice(1)); |
|
|
|
const opts = Object.assign({}, taskOpts, { |
|
ignore: taskOpts.ignore.concat(ignore) |
|
}); |
|
|
|
globTasks.push({pattern, opts}); |
|
}); |
|
|
|
return globTasks; |
|
}; |
|
|
|
const globDirs = (task, fn) => { |
|
let opts = {cwd: task.opts.cwd}; |
|
|
|
if (Array.isArray(task.opts.expandDirectories)) { |
|
opts = Object.assign(opts, {files: task.opts.expandDirectories}); |
|
} else if (typeof task.opts.expandDirectories === 'object') { |
|
opts = Object.assign(opts, task.opts.expandDirectories); |
|
} |
|
|
|
return fn(task.pattern, opts); |
|
}; |
|
|
|
const getPattern = (task, fn) => task.opts.expandDirectories ? globDirs(task, fn) : [task.pattern]; |
|
|
|
module.exports = (patterns, opts) => { |
|
let globTasks; |
|
|
|
try { |
|
globTasks = generateGlobTasks(patterns, opts); |
|
} catch (err) { |
|
return Promise.reject(err); |
|
} |
|
|
|
const getTasks = Promise.all(globTasks.map(task => Promise.resolve(getPattern(task, dirGlob)) |
|
.then(globs => Promise.all(globs.map(glob => ({ |
|
pattern: glob, |
|
opts: task.opts |
|
})))) |
|
)) |
|
.then(tasks => arrayUnion.apply(null, tasks)); |
|
|
|
const getFilter = () => { |
|
return Promise.resolve( |
|
opts && opts.gitignore ? |
|
gitignore({cwd: opts.cwd, ignore: opts.ignore}) : |
|
DEFAULT_FILTER |
|
); |
|
}; |
|
|
|
return getFilter() |
|
.then(filter => { |
|
return getTasks |
|
.then(tasks => Promise.all(tasks.map(task => fastGlob(task.pattern, task.opts)))) |
|
.then(paths => arrayUnion.apply(null, paths)) |
|
.then(paths => paths.filter(p => !filter(p))); |
|
}); |
|
}; |
|
|
|
module.exports.sync = (patterns, opts) => { |
|
const globTasks = generateGlobTasks(patterns, opts); |
|
|
|
const getFilter = () => { |
|
return opts && opts.gitignore ? |
|
gitignore.sync({cwd: opts.cwd, ignore: opts.ignore}) : |
|
DEFAULT_FILTER; |
|
}; |
|
|
|
const tasks = globTasks.reduce((tasks, task) => { |
|
const newTask = getPattern(task, dirGlob.sync).map(glob => ({ |
|
pattern: glob, |
|
opts: task.opts |
|
})); |
|
return tasks.concat(newTask); |
|
}, []); |
|
|
|
const filter = getFilter(); |
|
|
|
return tasks.reduce( |
|
(matches, task) => arrayUnion(matches, fastGlob.sync(task.pattern, task.opts)), |
|
[] |
|
).filter(p => !filter(p)); |
|
}; |
|
|
|
module.exports.generateGlobTasks = generateGlobTasks; |
|
|
|
module.exports.hasMagic = (patterns, opts) => [] |
|
.concat(patterns) |
|
.some(pattern => glob.hasMagic(pattern, opts)); |
|
|
|
module.exports.gitignore = gitignore;
|
|
|