146 lines
3.4 KiB
JavaScript
146 lines
3.4 KiB
JavaScript
|
module.exports = deglob
|
||
|
|
||
|
var findRoot = require('find-root')
|
||
|
var fs = require('fs')
|
||
|
var glob = require('glob')
|
||
|
var ignorePkg = require('ignore')
|
||
|
var os = require('os')
|
||
|
var parallel = require('run-parallel')
|
||
|
var path = require('path')
|
||
|
var pkgConfig = require('pkg-config')
|
||
|
var uniq = require('uniq')
|
||
|
|
||
|
function deglob (files, opts, cb) {
|
||
|
if (typeof opts === 'function') return deglob(files, null, opts)
|
||
|
opts = parseOpts(opts)
|
||
|
|
||
|
if (typeof files === 'string') files = [files]
|
||
|
if (files.length === 0) return nextTick(cb, null, [])
|
||
|
|
||
|
// traverse filesystem
|
||
|
parallel(files.map(function (pattern) {
|
||
|
return function (callback) {
|
||
|
glob(pattern, {
|
||
|
cwd: opts.cwd,
|
||
|
ignore: opts._ignore,
|
||
|
nodir: true
|
||
|
}, callback)
|
||
|
}
|
||
|
}), function (err, results) {
|
||
|
if (err) return cb(err)
|
||
|
|
||
|
// flatten nested arrays
|
||
|
var files = results.reduce(function (files, result) {
|
||
|
result.forEach(function (file) {
|
||
|
files.push(path.resolve(opts.cwd, file))
|
||
|
})
|
||
|
return files
|
||
|
}, [])
|
||
|
|
||
|
// de-dupe
|
||
|
files = uniq(files)
|
||
|
|
||
|
if (opts._gitignore) {
|
||
|
files = toRelative(opts.cwd, files)
|
||
|
if (os.platform() === 'win32') files = toUnix(files)
|
||
|
files = opts._gitignore.filter(files)
|
||
|
files = toAbsolute(opts.cwd, files)
|
||
|
if (os.platform() === 'win32') files = toWin32(files)
|
||
|
}
|
||
|
|
||
|
return cb(null, files)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
function parseOpts (opts) {
|
||
|
if (!opts) opts = {}
|
||
|
opts = Object.assign({
|
||
|
useGitIgnore: true,
|
||
|
usePackageJson: true,
|
||
|
configKey: 'config',
|
||
|
gitIgnoreFile: ['.gitignore', '.git/info/exclude']
|
||
|
}, opts)
|
||
|
|
||
|
if (!opts.cwd) opts.cwd = process.cwd()
|
||
|
if (!Array.isArray(opts.gitIgnoreFile)) opts.gitIgnoreFile = [opts.gitIgnoreFile]
|
||
|
|
||
|
opts._ignore = []
|
||
|
opts._gitignore = ignorePkg()
|
||
|
|
||
|
function addIgnorePattern (patterns) {
|
||
|
opts._ignore = opts._ignore.concat(patterns)
|
||
|
opts._gitignore.addPattern(patterns)
|
||
|
}
|
||
|
|
||
|
if (opts.ignore) addIgnorePattern(opts.ignore)
|
||
|
|
||
|
// return if we're not looking for packageJson or gitIgnore
|
||
|
if (!opts.useGitIgnore && !opts.usePackageJson) {
|
||
|
return opts
|
||
|
}
|
||
|
|
||
|
// Find package.json in the project root
|
||
|
var root
|
||
|
try {
|
||
|
root = findRoot(opts.cwd)
|
||
|
} catch (e) {}
|
||
|
|
||
|
if (root) {
|
||
|
if (opts.usePackageJson) {
|
||
|
var packageOpts = pkgConfig(opts.configKey, { root: false, cwd: opts.cwd })
|
||
|
if (packageOpts && packageOpts.ignore) {
|
||
|
// Use ignore patterns from package.json ("config.ignore" property)
|
||
|
addIgnorePattern(packageOpts.ignore)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (opts.useGitIgnore) {
|
||
|
// Use ignore patterns from project root .gitignore
|
||
|
var gitignores = []
|
||
|
gitignores = opts.gitIgnoreFile
|
||
|
.map(function (f) {
|
||
|
try {
|
||
|
return fs.readFileSync(path.join(root, f), 'utf8')
|
||
|
} catch (err) {}
|
||
|
})
|
||
|
.filter(Boolean)
|
||
|
|
||
|
gitignores.forEach(function (gitignore) {
|
||
|
opts._gitignore.addPattern(gitignore.split(/\r?\n/))
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return opts
|
||
|
}
|
||
|
|
||
|
function toAbsolute (cwd, files) {
|
||
|
return files.map(function (file) {
|
||
|
return path.join(cwd, file)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
function toRelative (cwd, files) {
|
||
|
return files.map(function (file) {
|
||
|
return path.relative(cwd, file)
|
||
|
})
|
||
|
}
|
||
|
|
||
|
function toUnix (files) {
|
||
|
return files.map(function (file) {
|
||
|
return file.replace(/\\/g, '/')
|
||
|
})
|
||
|
}
|
||
|
|
||
|
function toWin32 (files) {
|
||
|
return files.map(function (file) {
|
||
|
return file.replace(/\//g, '\\')
|
||
|
})
|
||
|
}
|
||
|
|
||
|
function nextTick (cb, err, val) {
|
||
|
process.nextTick(function () {
|
||
|
cb(err, val)
|
||
|
})
|
||
|
}
|