-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.js
147 lines (123 loc) · 3.5 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
module.exports = deglob
const findRoot = require('find-root')
const fs = require('fs')
const glob = require('glob')
const ignorePkg = require('ignore')
const os = require('os')
const parallel = require('run-parallel')
const path = require('path')
const pkgConfig = require('pkg-config')
const 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
let 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
let root
try {
root = findRoot(opts.cwd)
} catch (e) {}
if (root) {
if (opts.usePackageJson) {
const 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
let gitignores = []
gitignores = opts.gitIgnoreFile
.map(function (f) {
try {
return fs.readFileSync(path.join(root, f), 'utf8')
} catch (err) {
return null
}
})
.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)
})
}