Grunt Files Object Format: All regular files files immediately under top level directory

154 views Asked by At

I can't figure out for the life of me how to get this work. The grunt configuration for a module I'm using (grunt-sloc) requires the Files Object Format. Using this, I want to be able to match all regular files (i.e., non-directories) immediately under the top level directory.

For example, say this is my directory structure, where + signifies a directory and - signifies a regular file:

repo
  + dir
    - unwanted.js
  - server.js

How do I use Grunt's Files Object Format to match server.js but not dir or dir/unwanted.js?

This is how it would look in the Compact Fomat:

mine: {
  src: [
    '*'
  ]
}

Or, in bash, you would get them like this:

ls -p | grep -v /;

Here's what I've tried with the Files Object Format:

  • This does not work:

    mine: {
      files: {
        '.': ['*']
      }
    }
    
  • Neither does this:

    mine: {
      files: {
        './': ['*']
      }
    }
    
  • Not even this:

    mine: {
      files: {
        './': ['*/server.js']
      }
    }
    
  • Nor this:

    mine: {
      files: {
        './': ['server.js']
      }
    }
    
  • This works, but it runs recursively, which I do not want:

    mine: {
      files: {
        './': ['**/server.js']
      }
    }
    

After doing a bunch of testing and code reading, I've verified that it is in fact the minimatch package (a depencency of Grunt), which is not returning the matches I'm looking for. So it is not the grunt module I am using; it's my grunt configuration.

Since Grunt is so popular and this seems like a very common use case, I'm guessing that there's a way to do this. Does anyone know what that is?

Update

As RobC pointed out, my last example does NOT work. It was picking up server.js's in my node_modules directory, which made me think it was working.

1

There are 1 answers

1
RobC On BEST ANSWER

Firstly FWIW, your examples listed using the Files Object Format method also did not work for me, including your last one:

 // Although this worked for you, this failed for me...
 mine: {
     files: {
         './': ['**/server.js']
     }
 }

The only way I could get this to work was to match everything and then negate the top level directories using Grunt globbing patterns.

Whilst the following gists demonstrates what worked for me, it does require knowing/configuring the names of the top-level directories you wish to exclude:

Directory Structure

Given a directory set up as follows:

repo
│
├─── dir
│   │
│   └─── unwanted.js
│
├─── foo.js
│
├─── Gruntfile.js
│
├─── node_modules
│   │
│   └─── ...
│
├─── package.json
│
└─── server.js

Gruntfile.js

...and a Gruntfile.js configured as follows:

module.exports = function(grunt) {
    grunt.initConfig({
        sloc: {
            mine: {
                files: {
                    '.': [
                        '**', // Match everything and add to the results set.

                        // Explicitly state which directories under the top
                        // level directory to negate from the results set.
                        '!**/node_modules/**',
                        '!**/dir/**',

                        // Files can be negated from the results set too.
                        '!**/Gruntfile.js' // 
                    ]
                }
            }
        }

    });
    grunt.loadNpmTasks('grunt-sloc');
    grunt.registerTask('default', [
        'sloc:mine'
    ]);
};

Sloc results

Running grunt via the CLI correctly resulted in grunt-sloc reporting statistics for two files only, namely foo.js and server.js.

As expected, stats for package.json were omitted due to JSON being a non-supported language.

Additional note:

I found the answer to this post fairly informative in explaining how patterns that begin with ! are excluded from the initial returned array.