diff options
Diffstat (limited to 'node_modules/glob-stream/index.js')
-rw-r--r-- | node_modules/glob-stream/index.js | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/node_modules/glob-stream/index.js b/node_modules/glob-stream/index.js new file mode 100644 index 000000000..363a29dac --- /dev/null +++ b/node_modules/glob-stream/index.js @@ -0,0 +1,209 @@ +'use strict'; + +var through2 = require('through2'); +var Combine = require('ordered-read-streams'); +var unique = require('unique-stream'); + +var glob = require('glob'); +var micromatch = require('micromatch'); +var resolveGlob = require('to-absolute-glob'); +var globParent = require('glob-parent'); +var path = require('path'); +var extend = require('extend'); +var sepRe = (process.platform === 'win32' ? /[\/\\]/ : /\/+/); + +var gs = { + // Creates a stream for a single glob or filter + createStream: function(ourGlob, negatives, opt) { + + var ourOpt = extend({}, opt); + delete ourOpt.root; + + // Extract base path from glob + var basePath = ourOpt.base || getBasePath(ourGlob, opt); + + // Remove path relativity to make globs make sense + ourGlob = resolveGlob(ourGlob, opt); + + // Create globbing stuff + var globber = new glob.Glob(ourGlob, ourOpt); + + // Create stream and map events from globber to it + var stream = through2.obj(opt, + negatives.length ? filterNegatives : undefined); + + var found = false; + + globber.on('error', stream.emit.bind(stream, 'error')); + globber.once('end', function() { + if (opt.allowEmpty !== true && !found && globIsSingular(globber)) { + stream.emit('error', + new Error('File not found with singular glob: ' + ourGlob)); + } + + stream.end(); + }); + globber.on('match', function(filename) { + found = true; + + stream.write({ + cwd: opt.cwd, + base: basePath, + path: path.normalize(filename), + }); + }); + + return stream; + + function filterNegatives(filename, enc, cb) { + var matcha = isMatch.bind(null, filename); + 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 = {}; + } + 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; + } + + // Only one glob no need to aggregate + if (!Array.isArray(globs)) { + globs = [globs]; + } + + var positives = []; + var negatives = []; + + var ourOpt = extend({}, opt); + delete ourOpt.root; + + globs.forEach(function(glob, index) { + if (typeof glob !== 'string' && !(glob instanceof RegExp)) { + throw new Error('Invalid glob at index ' + index); + } + + var globArray = isNegative(glob) ? negatives : positives; + + // Create Minimatch instances for negative glob patterns + if (globArray === negatives && typeof glob === 'string') { + var ourGlob = resolveGlob(glob, opt); + glob = micromatch.matcher(ourGlob, ourOpt); + } + + globArray.push({ + index: index, + glob: glob, + }); + }); + + if (positives.length === 0) { + throw new Error('Missing positive glob'); + } + + // Only one positive glob no need to aggregate + if (positives.length === 1) { + return streamFromPositive(positives[0]); + } + + // Create all individual streams + var streams = positives.map(streamFromPositive); + + // Then just pipe them to a single unique stream and return it + var aggregate = new Combine(streams); + var uniqueStream = unique('path'); + var returnStream = aggregate.pipe(uniqueStream); + + aggregate.on('error', function(err) { + returnStream.emit('error', err); + }); + + return returnStream; + + function streamFromPositive(positive) { + var negativeGlobs = negatives.filter(indexGreaterThan(positive.index)) + .map(toGlob); + return gs.createStream(positive.glob, negativeGlobs, opt); + } + }, +}; + +function isMatch(file, matcher) { + if (typeof matcher === 'function') { + return matcher(file.path); + } + if (matcher instanceof RegExp) { + return matcher.test(file.path); + } +} + +function isNegative(pattern) { + if (typeof pattern === 'string') { + return pattern[0] === '!'; + } + if (pattern instanceof RegExp) { + return true; + } +} + +function indexGreaterThan(index) { + return function(obj) { + return obj.index > index; + }; +} + +function toGlob(obj) { + return obj.glob; +} + +function globIsSingular(glob) { + var globSet = glob.minimatch.set; + + if (globSet.length !== 1) { + return false; + } + + return globSet[0].every(function isString(value) { + return typeof value === 'string'; + }); +} + +function getBasePath(ourGlob, opt) { + var basePath; + var parent = globParent(ourGlob); + + if (parent === '/' && opt && opt.root) { + basePath = path.normalize(opt.root); + } else { + basePath = resolveGlob(parent, opt); + } + + if (!sepRe.test(basePath.charAt(basePath.length - 1))) { + basePath += path.sep; + } + return basePath; +} + +module.exports = gs; |