5752f3c892a1e7813d75ba1224fb8674ca17c74a.svn-base
3.95 KB
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
/*
* glob-whatev
* http://github.com/cowboy/node-glob-whatev
*
* Copyright (c) 2012 "Cowboy" Ben Alman
* Licensed under the MIT license.
* http://benalman.com/about/license/
*/
var fs = require('fs');
var path = require('path');
var existsSync = fs.existsSync || path.existsSync;
// Export minimatch, in case something else needs direct access to it.
exports.minimatch = require('minimatch');
// Windows uses \ instead of / for path separators.
var win32 = process.platform === 'win32';
var pathSeparator = win32 ? '\\' : '/';
var stripWildcard = /[*?{+(].*$/;
var stripNonpath = win32 ? /[^\/\\]*$/ : /[^\/]*$/;
// On Windows, convert all \ to /.
function normalize(filepath) {
return win32 ? filepath.replace(/\\/g, '/') : filepath;
}
// A very simple, not-at-all-efficient, synchronous file globbing util.
exports.glob = function(pattern, options) {
if (!options) { options = {}; }
var cwd = options.cwd || process.cwd();
// The current absolute working directory.
var base = normalize(path.join(cwd, pathSeparator));
// The passed pattern, resolved to an absolute path.
var absPattern = normalize(path.resolve(base, pattern));
// Since path.resolve strips off trailing '/', add it back if necessary.
if (/\/$/.test(pattern) && !/\/$/.test(absPattern)) { absPattern += '/'; }
// Was pattern-as-specified already absolute?
var wasAbsolute = normalize(pattern) === absPattern;
// Instead of recursing from the base looking for files, start recursing at
// the farthest possible subdirectory that doesn't contain any kind of
// wildcard characters. I may have missed one, so let me know if I have!
var betterBase = absPattern.replace(stripWildcard, '').replace(stripNonpath, '');
// Now that we've got a better base, we need a better pattern.
var betterPattern = absPattern.slice(betterBase.length);
// Don't recurse if we don't have to. Limit max depth.
var maxDepth = betterPattern.indexOf('**') >= 0 ? (options.maxDepth || 99)
: betterPattern.split('/').length;
// If minimatch 'matchBase' option is true, and the pattern doesn't contain
// ** or /, use the pattern as-specified and recurse to max.
if (options.matchBase && !/\*\*|\//.test(pattern)) {
maxDepth = options.maxDepth || 99;
absPattern = pattern;
}
// Build file list, recursively (only up to a certain depth).
var recurse = function(dirpath, depth) {
// Abort if, for whatever reason, dirpath doesn't exist.
if (!existsSync(dirpath)) { return; }
// Read directory contents.
fs.readdirSync(dirpath).forEach(function(filepath) {
var stat;
// Make relative path absolute.
filepath = path.join(dirpath, filepath);
try {
stat = fs.statSync(filepath);
} catch (e) {
// Ignore files that can't be "stat"ed (such as emacs's lock files)
}
if (stat && stat.isDirectory()) {
// If the path is a directory, push it onto the array, adding a
// trailing /.
filepaths.push(filepath + pathSeparator);
// Recurse.
if (depth < maxDepth) {
recurse(filepath, depth + 1);
}
} else {
// Push file path onto the array.
filepaths.push(filepath);
}
});
};
// Build files list.
var filepaths = [];
if (betterPattern) {
// A pattern exists, recurse starting at betterBase.
recurse(betterBase, 1);
} else {
// No pattern exists, just use betterBase path.
filepaths.push(betterBase);
}
// Normalize filepaths and remove those that don't match pattern.
filepaths = filepaths.map(normalize).filter(function(filepath) {
return exports.minimatch(filepath, absPattern, options);
});
// If the pattern wasn't absolute, replace each absolute filepath with one
// that is relative to the cwd.
if (!wasAbsolute) {
filepaths = filepaths.map(function(filepath) {
var relPath = normalize(path.relative(cwd, filepath));
if (/\/$/.test(filepath)) { relPath += '/'; }
return relPath;
});
}
return filepaths;
};