Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Makes file matching / expanding much faster (in some situations twice as fast) #1562

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 19 additions & 3 deletions lib/grunt/file.js
Expand Up @@ -38,7 +38,8 @@ file.setBase = function() {

// Process specified wildcard glob patterns or filenames against a
// callback, excluding and uniquing files in the result set.
var processPatterns = function(patterns, fn) {
var processPatterns = function(patterns, fn, exclusionFn) {
if (typeof exclusionFn === 'undefined') { exclusionFn = fn; }
// Filepaths to return.
var result = [];
// Iterate over flattened patterns array.
Expand All @@ -48,7 +49,7 @@ var processPatterns = function(patterns, fn) {
// If the pattern is an exclusion, remove the !
if (exclusion) { pattern = pattern.slice(1); }
// Find all matching files for this pattern.
var matches = fn(pattern);
var matches = (exclusion ? exclusionFn : fn)(pattern, result);
if (exclusion) {
// If an exclusion, remove matching files.
result = grunt.util._.difference(result, matches);
Expand Down Expand Up @@ -93,6 +94,8 @@ file.expand = function() {
// If the first argument is an options object, save those options to pass
// into the file.glob.sync method.
var options = grunt.util.kindOf(args[0]) === 'object' ? args.shift() : {};
// Cache fs calls across multiple file.glob.sync operations
var globOptions = grunt.util._.extend(file._createGlobIoCache(), options);
// Use the first argument if it's an Array, otherwise convert the arguments
// object to an array and use that.
var patterns = Array.isArray(args[0]) ? args[0] : args;
Expand All @@ -101,7 +104,9 @@ file.expand = function() {
// Return all matching filepaths.
var matches = processPatterns(patterns, function(pattern) {
// Find all matching files for this pattern.
return file.glob.sync(pattern, options);
return file.glob.sync(pattern, globOptions);
}, function(pattern, resultsThusFar) {
return file.match(options, [pattern], resultsThusFar);
});
// Filter result set?
if (options.filter) {
Expand Down Expand Up @@ -452,3 +457,14 @@ file.isPathInCwd = function() {
return false;
}
};

// Creates all glob options that store cached fs results for the `glob` library.
// Can be removed when this glob PR is released: https://github.com/isaacs/node-glob/pull/306
file._createGlobIoCache = function() {
return {
cache: Object.create(null),
statCache: Object.create(null),
symlinks: Object.create(null),
realpathCache: Object.create(null)
};
};
3 changes: 2 additions & 1 deletion lib/grunt/task.js
Expand Up @@ -117,6 +117,7 @@ task.normalizeMultiTaskFiles = function(data, target) {
}

// Process all normalized file objects.
var globIoCache = grunt.file._createGlobIoCache();
files = grunt.util._(files).chain().forEach(function(obj) {
if (!('src' in obj) || !obj.src) { return; }
// Normalize .src properties to flattened array.
Expand All @@ -127,7 +128,7 @@ task.normalizeMultiTaskFiles = function(data, target) {
}
}).map(function(obj) {
// Build options object, removing unwanted properties.
var expandOptions = grunt.util._.extend({}, obj);
var expandOptions = grunt.util._.extend({}, globIoCache, obj);
delete expandOptions.src;
delete expandOptions.dest;

Expand Down