grunt (minimatch/glob) folder exclusion

Jesse picture Jesse · Sep 28, 2012 · Viewed 51k times · Source

I have a situation where I'm trying to use grunt to lint a codebase, excluding specific folders.

grunt uses minimatch (similar to bsdglob) under the hood to match files, but I can't seem to figure out how to do a .gitignore style exclude of a folder.

I'd like to ingest this:

ignoreme

and match these:

/folder/path/here/to/something/ok.js
/another/folder/path.js
/test.js

but not match these:

/folder/ignoreme/something.js
/folder/path/here/to/ignoreme/metoo/file.js

This will match everything, including ignoreme:

/**/*.js

So I figured I could do something like:

/**/!(ignoreme)/**/*.js

but that matches files in the ignoreme folder.

I'm used to regexes, but can't seem to figure out how to repeat a pattern or something here - I also tried stuff like:

/(!(ignoreme)|*)*/*.js

hoping the container would repeat, but that doesn't work, it just fails to match everything.

Any way to either pass a regex to grunt file paths, or make this work for me?

Update:

Here's how I'm currently dealing with this issue:

var pattern = /\/ignoreme\//
var files = grunt.file.expandFiles(arrayOfFilesPassedToMinimatch).filter(function(f){
  return !pattern.test(f)
})

I'd still be interested if folder excludes are possible in minimatch.

Answer

Cowboy Ben Alman picture Cowboy Ben Alman · Sep 28, 2012

In the currently-in-development version 0.4.0a, the grunt.file.expand method now supports exclusions, and does so in an arguably less complex way than the underlying minimatch matching library. This is possible because grunt.file.expand accepts multiple patterns (whereas minimatch only accepts one).

From the grunt.file.expand documentation:

This method accepts either comma separated wildcard patterns or an array of wildcard patterns. Paths matching patterns that begin with ! will be excluded from the returned array. Patterns are processed in order, so inclusion and exclusion order is significant.

That means you could specify ['/**/*.js', '!**/ignoreme/**'] and while the first pattern would add all .js files to the result set, the second pattern would then remove all /ignoreme/ files from the result set.

Take a look at the grunt.file.match unit tests if you're really curious.

Note that the version of grunt offering this functionality hasn't officially been released, but if you're interested in using it in a project, see the When will I be able to use in-development feature 'X'? FAQ entry.