real-life Gruntfile for a FuelPHP project which shall remain nameless added by sjamaan on Wed Mar 26 08:37:39 2014

module.exports = function (grunt) {
    'use strict';

    // All frontend source files.
    var frontendSourceFiles = [
        // Main folder.
        '*.js',

        // Collections.
        'collection/**/*.js',

        // Config.
        'config/**/*.js',

        // Constrollers.
        'controller/**/*.js',

        // Helpers.
        'helper/**/*.js',

        // Mixins.
        'mixin/**/*.js',

        // Models.
        'model/**/*.js',

        // Translations.
        'nls/**/*.js',

        // Routers.
        'router/**/*.js',

        // Tests.
        'test/**/*.js',

        // Views.
        'view/**/*.js'
    ],

    // All backend source files.
    backendSourceFiles = [
        // App.
        '../../fuel/app/classes/**/*.php',

        // Config.
        '../../fuel/app/config/**/*.php',

        // Lang.
        '../../fuel/app/config/**/*.php',

        // Migrations.
        '../../fuel/app/migrations/**/*.php',

        // Modules.
        '../../fuel/app/modules/**/*.php',

        // Tasks.
        '../../fuel/app/tasks/**/*.php',

        // Tests.
        '../../fuel/app/tests/**',

        // Views.
        '../../fuel/app/views/**/*.php'
    ],

    // All source files.
    sourceFiles = frontendSourceFiles.concat(backendSourceFiles);



    grunt.initConfig({
        less: {
            production: {
                options: {
                    paths: ['../assets/less/*.less'],
                    compress: true,
                    cleancss: true
                },
                files: [{
                    expand: true,
                    src: ['../assets/less/*.less'],
                    dest: '../assets/css/',
                    rename: function (dest, src) {
                        var fileName = src.replace(/^.*[\\\/]/, '').split('.');

                        // Remove extension.
                        fileName.pop();

                        // Add version.
                        fileName = dest + fileName.join('.') + '-' + grunt.file.read('../../fuel/app/config/version.txt').trim() + '.css';

                        return fileName;
                    }
                }]
            },
            development: {
                options: {
                    paths: ['../assets/less/*.less'],
                    compress: true
                },
                files: [{
                    expand: true,
                    src: ['../assets/less/*.less'],
                    dest: '../assets/css/',
                    rename: function (dest, src) {
                        var fileName = src.replace(/^.*[\\\/]/, '').split('.');

                        // Remove extension.
                        fileName.pop();

                        // Add extension.
                        fileName = dest + fileName.join('.') + '.css';

                        return fileName;
                    }
                }]
            },
        },
        watch: {
            less: {
                files: './../assets/less/*.less',
                tasks: ['less']
                // files: '../../bootstrap-2.3.2/less/*.less',
                // tasks: ['exec:bootstrap']
            },
            frontendQuality: {
                files: frontendSourceFiles,
                tasks: ['exec:unitTest:frontend', 'jshint']
            },
            backendQuality: {
                files: backendSourceFiles,
                tasks: ['exec:unitTest:backend']
            },
            backendLint: {
                files: backendSourceFiles,
                tasks: ['exec:phpcs']
            },
            sync: {
                files: sourceFiles,
                tasks: ['sync:all']
            }
        },
        concurrent: {
            options: {
                logConcurrentOutput: true
            },
            watchQuality: ['watch:frontendQuality', 'watch:backendQuality'],
            watchLocal: ['watch:sync', 'watch:less'],
        },
        sync: {
            all: {
                files: [{
                    expand: true,
                    /**
                     * Don't do anything if .syncrc doesn't exists.
                     *
                     * @return String True if .syncrc exists, false otherwise.
                     */
                    filter: function () {
                        return grunt.file.exists('.syncrc');
                    },
                    /**
                     * Set dest dir based on .syncrc.
                     *
                     * @return String Dest dir.
                     */
                    rename: function (dest, src) {
                        return grunt.file.read('.syncrc').trim();
                    },
                    src: sourceFiles,
                    dest: '',
                }]
            }
        },
        exec: {
            unitTest: {
                command: function (type) {
                    switch (type) {
                        case 'backend':
                            return 'cd ../../; php oil test';
                        case 'frontend':
                            return 'node_modules/phantomjs/bin/phantomjs test/run-jasmine.js test/index.html';
                    }
                },
            },
            phpcs: {
                command: './../../fuel/vendor/bin/phpcs --standard=psr1,psr2 ../../fuel/app/classes/model/donor.php'
            },
            docker: {
                command: function() {
                    var cmd = 'node_modules/docker/docker -i ../../fuel/app/ -o ../../doc/backend/ -x logs';

                    // Copy README.MD.
                    if(this.file.exists('../../fuel/app/README.md')) {
                        cmd = 'cp ../../fuel/app/README.md ../../fuel/app/README.md;' + cmd + ';rm ../../fuel/app/README.md';
                    }

                    cmd += ';node_modules/docker/docker -i / -o ../../doc/frontend/ -x components,node_modules';

                    return cmd;
                }
            },
            bootstrap: {
                command: 'cd ../../bootstrap-2.3.2/ && make'
            },
            optimize: {
                command: function () {
                    return 'node ./node_modules/requirejs/bin/r.js -o build.json include=components/requirejs/require out=./../app-' + this.file.read('../../fuel/app/config/version.txt').trim() + '.js';
                }
            },
            writeVersion: {
                command: 'echo "$(hg parents --template {latesttag})-$(hg parents --template {rev})" > ../../fuel/app/config/version.txt;echo "$(hg parents --template {latesttag})-$(hg parents --template {rev})" > config/version.txt'
            }
        },
        jshint: {
            all: {
                src: frontendSourceFiles,
                options: {
                    jshintrc: true,
                    jshintignore: true
                }
            }
        },
        phpcs: {
            application: {
                dir: '../../fuel/app/classes/controller/'
            },
            options: {
                bin: '../../fuel/vendor/bin/phpcs',
                standard: 'PSR2'
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-exec');
    grunt.loadNpmTasks('grunt-sync');
    grunt.loadNpmTasks('grunt-concurrent');
    // grunt.loadNpmTasks('grunt-phpcs');

    grunt.registerTask('watchQuality', ['concurrent:watchQuality']);
    grunt.registerTask('build', ['exec:writeVersion', 'exec:optimize', 'less:production']);
    grunt.registerTask('buildLess', ['exec:writeVersion', 'less']);
    grunt.registerTask('default', ['concurrent:watchLocal']);
    grunt.registerTask('checkQuality', ['jshint', 'exec:unitTest:frontend', 'exec:unitTest:backend']);
};