index.js
3.29 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
109
110
111
112
113
114
115
116
117
/*jslint node: true */
'use strict';
var through2 = require('through2');
var Combine = require('ordered-read-streams');
var unique = require('unique-stream');
var glob = require('glob');
var minimatch = require('minimatch');
var glob2base = require('glob2base');
var path = require('path');
var gs = {
// creates a stream for a single glob or filter
createStream: function(ourGlob, negatives, opt) {
if (!negatives) negatives = [];
if (!opt) opt = {};
if (typeof opt.cwd !== 'string') opt.cwd = process.cwd();
if (typeof opt.dot !== 'boolean') opt.dot = false;
if (typeof opt.silent !== 'boolean') opt.silent = true;
if (typeof opt.nonull !== 'boolean') opt.nonull = false;
if (typeof opt.cwdbase !== 'boolean') opt.cwdbase = false;
if (opt.cwdbase) opt.base = opt.cwd;
// remove path relativity to make globs make sense
ourGlob = unrelative(opt.cwd, ourGlob);
negatives = negatives.map(unrelative.bind(null, opt.cwd));
// create globbing stuff
var globber = new glob.Glob(ourGlob, opt);
// extract base path from glob
var basePath = opt.base ? opt.base : glob2base(globber);
// create stream and map events from globber to it
var stream = through2.obj(negatives.length ? filterNegatives : undefined);
globber.on('error', stream.emit.bind(stream, 'error'));
globber.on('end', function(/* some args here so can't use bind directly */){
stream.end();
});
globber.on('match', function(filename) {
stream.write({
cwd: opt.cwd,
base: basePath,
path: path.resolve(opt.cwd, filename)
});
});
return stream;
function filterNegatives(filename, enc, cb) {
var matcha = isMatch.bind(null, filename, opt);
if (negatives.every(matcha)) {
cb(null, filename); // pass
} else {
cb(); // ignore
}
}
},
// creates a stream for multiple globs or filters
create: function(globs, opt) {
if (!opt) opt = {};
// only one glob no need to aggregate
if (!Array.isArray(globs)) return gs.createStream(globs, null, opt);
var positives = globs.filter(isPositive);
var negatives = globs.filter(isNegative);
if (positives.length === 0) throw new Error("Missing positive glob");
// only one positive glob no need to aggregate
if (positives.length === 1) return gs.createStream(positives[0], negatives, opt);
// create all individual streams
var streams = positives.map(function(glob){
return gs.createStream(glob, negatives, opt);
});
// then just pipe them to a single unique stream and return it
var aggregate = new Combine(streams);
var uniqueStream = unique('path');
return aggregate.pipe(uniqueStream);
}
};
function isMatch(file, opt, pattern) {
if (typeof pattern === 'string') return minimatch(file.path, pattern, opt);
if (pattern instanceof RegExp) return pattern.test(file.path);
return true; // unknown glob type?
}
function isNegative(pattern) {
if (typeof pattern !== 'string') return true;
if (pattern[0] === '!') return true;
return false;
}
function isPositive(pattern) {
return !isNegative(pattern);
}
function unrelative(cwd, glob) {
var mod = '';
if (glob[0] === '!') {
mod = glob[0];
glob = glob.slice(1);
}
return mod+path.resolve(cwd, glob);
}
module.exports = gs;