Skip to content

Instantly share code, notes, and snippets.

@georgiyordanov
Last active August 29, 2015 14:13
Show Gist options
  • Save georgiyordanov/577513f44906369793ee to your computer and use it in GitHub Desktop.
Save georgiyordanov/577513f44906369793ee to your computer and use it in GitHub Desktop.
'use strict';
/*global require, module, process*/
/*jshint -W097*/ // Use the function form of "use strict".
var _ = require('lodash'),
glob = require('glob'),
minimatch = require('minimatch'),
glob2base = require('glob2base'),
path = require('path');
_.str = require('underscore.string');
// expand all globs the way gulp would expland them synchronously
// a relative path is also added for convenience
// this is a direct port of glob-stream which gulp uses, but without asynchrony and streams
// https://github.com/wearefractal/glob-stream/blob/master/index.js
module.exports = function (globs, opt) {
//jscs:disable requireCurlyBraces
// enable one line if statements intentionally
function isMatch(file, pattern) {
if (typeof pattern === 'string') return minimatch(file.path, pattern);
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);
}
if (!opt) opt = {};
if (!Array.isArray(globs)) globs = [globs];
var positives = _.filter(globs, isPositive),
negatives = _.filter(globs, isNegative);
if (positives.length === 0) throw new Error('Missing positive glob');
if (!negatives) negatives = [];
if (typeof opt.cwd !== 'string') opt.cwd = process.cwd();
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;
//jscs:enable requireCurlyBraces
return _(positives)
.map(function (ourGlob) {
// remove path relativity to make globs make sense
ourGlob = unrelative(opt.cwd, ourGlob);
negatives = negatives.map(unrelative.bind(null, opt.cwd));
// extract base path from glob
var globber = new glob.Glob(ourGlob, opt),
basePath = opt.base ? opt.base : glob2base(globber);
return _.map(glob.sync(ourGlob, opt), function (filename) {
return {
cwd: opt.cwd,
base: basePath,
path: path.resolve(opt.cwd, filename),
relative: path.relative(basePath, filename)
};
});
})
.flatten(true)
.filter(function (file) {
var matcha = isMatch.bind(null, file);
return _.every(negatives, matcha);
})
.uniq('path')
.value();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment