Skip to content
Frank Stallone logo

Ignoring Files and Folders with Grunt Contrib Clean

Sharing actionable tips from my agency, enterprise, start up, and life experience with a design and developer twist.

Working with the ever so gifted and talented backend developer Rohit Chopra here at Martindale-Hubbell lately, I find myself pulling together two workflows and trying to make it a symbiotic relationship (if you will). Part of this process requires a bit of trial by fire, which Git is fantastic with as you can easily clean out one's working directory effectively hitting the reset button on situations.

I am working with Node, mainly for Grunt tasks which I have been finding unbelievably useful, and Bower. When I can get the syntax correct and things click into place, life is good. This particular post is a quick walk through of my morning's fail and by writing what not to do and what to do I can better articulate the concepts later.

For sake of making things easy, I am using the Grunt Contrib Clean task to clear out all the files in the views/ directory, with a caveat. I have one folder in this views/ folder, called dev/ or views/dev if you will, that I do not want Grunt Clean to delete, nor it's contents. Let's take a look at the original code I thought would accomplish this, and the error of my way.

1
clean: {
2
dist: {
3
src: ['application/views/*', '!application/views/dev/*']
4
},
5
options: {
6
'no-write': true
7
}
8
},
9
10
...
11
12
grunt.registerTask('delete', ['clean:dist'])

Alright so let me explain what we have here. I am telling Grunt there is a clean:object and that dist: is my name for the operations I would like Grunt Clean to accomplish. Finally we have an option of 'no-write' set to true because I did not want this to execute in case I had the wrong syntax. The registerTask line is just registering that 'clean:dist' as a task that can be run in terminal using the the grunt delete command. At this point running the grunt delete command in terminal gave me this result:

Console feedback from grunt delete task

This was near as makes no difference, useless to me. Now not knowing minimatch, the matching library Grunt uses under the hood to match files, I ended up just removing the option no-write just to see what happens. Basically the first part of src that says applications/views/* removed all files in the views/ folder & all of the sub-folders. The second part of that line !applications/views/dev/* was ignored completely (at least as it was intended). So let's try something else.

1
clean: {
2
dist: {
3
src: ['application/views/**', '!application/views/dev/**']
4
}
5
},
6
7
...
8
9
grunt.registerTask('delete', ['clean:dist'])</pre>

This completely deleted the entire views/ folder, which included it's contents and the dev/views folder. This is how my backwards brain works, and maybe a bit embarrassingly so. I thought, "Well if two asterisks remove's the entire folder, and ! is exclude, maybe..." and I proceeded to try the following code.

1
clean: {
2
dist: {
3
src: ['application/views/*', '!application/views/dev/**']
4
}
5
},
6
7
...
8
9
grunt.registerTask('delete', ['clean:dist'])</pre>

Perfect!! This did exactly what I intended it to! It removed the contents of the views/ folder, all of the sub-folders and their contents, except the views/dev folder and it's contents. All of this took a matter of 20 minutes, but it led to some fun conversations on the IRC freenode #grunt channel, a place where others ask for help and advice, and I am always thankful for their lovely help. I now have a Grunt Clean task that properly removes the files and folders I want, and excludes the files and folders I ask of it. Now this is not typically my approach, I am one of the few who actually reads the docs that comes with all my electronics, and the same for code, but this was more fun. =D

Helpful?

Want to work together?

I am working with a limited availability for consulting. Learn more about how I can sharpen your SaaS brand and product.

designzen logo

Reach out

Have a question or comment? Feel free to drop me a line below!