MaximeDesRoches
MaximeDesRoches

Reputation: 110

How to execute tasks based on a subfolder with Grunt and Grunt-Watch

I want to be able to have different subprojects inside my main project. For example:

-- my-project/
   - Gruntfile.js
   - subproject1/
     - index.html
     - scss/
       - main.scss
   - subproject2/
     - index.html
     - scss/
       - main.scss

I want to be able to modify a file in subproject1 without triggering subproject2 tasks.

As of right now I'm configuring my gruntfile like so:

watch: {
    subproject1: {
        files: ['subproject1/*.html', 'subproject1/scss/**/*.scss'],
        tasks: ['sass', 'premailer:subproject1']
    },
    subproject2: {
        files: ['subproject2/*.html', 'subproject2/scss/**/*.scss'],
        tasks: ['sass', 'premailer:subproject2']
    }
},

premailer: {
    subproject1: {
        options: {
            css: 'subproject1/css/main.css',
            verbose: false
        },
        files: [
            {
            'subproject1/dist/index.html' : 'subproject1/index.html'
            }
        ]
    },
    subproject2: {
        options: {
            css: 'subproject2/css/main.css',
            verbose: false
        },
        files: [
            {
            'subproject2/dist/index.html' : 'subproject2/index.html'
            }
        ]
    },
}

Is there a way to dynamically specify to grunt what task to run depending on file modified (eg, I modify folder/index.html, then run premailer:folder) or is this the only way to achieve it ?

Upvotes: 0

Views: 249

Answers (1)

theCodeSurgeon
theCodeSurgeon

Reputation: 460

You can check all folders in your main folder inside your Gruntfile, using the grunt.file methods (docs here), create an array of subproject names and then using forEach to create your task dynamically.

Something like this should go:

/*global module:false*/
module.exports = function(grunt) {

    var mycwd = "./";

    var tempFileList = grunt.file.expand(
        { filter: function (src) {
            if (grunt.file.isDir(src) == true) {
                return true;
            }
            return false;
        } },
        [ mycwd + "!(Gruntfile.js|node_modules|package.json)" ] // structure to analyse
    );

    // I create an empty array to put all elements in, once cleaned.
    var fileList = [];

    tempFileList.forEach(function(url){
        var cwd = url;
        cwd = cwd.replace(mycwd, "");
        fileList.push(cwd);
    })

    var watchObject = {};
    var premailerObject = {};

    fileList.forEach(function(name) {
        watchObject[name] = {
            files: [name + '/*.html', name + '/scss/**/*.scss'],
            tasks: ['sass', 'premailer:' + name]
        };
        var filesObject = {};
        filesObject[name+'/css/main.css'] = name + '/index.html';
        premailerObject[name] = {
            options: { css: name + '/css/main.css', verbose: false },
            files: [ filesObject ]
        };
    });

    var configObject = {
        watch: watchObject,
        premailer: premailerObject
    };

    // just to check the final structure
    console.log(configObject); 

    grunt.initConfig(configObject);

};

Upvotes: 1

Related Questions