sympmarc/SPServices

View on GitHub
Gruntfile.js

Summary

Maintainability
C
1 day
Test Coverage
/**
 * Created by Marc on 4/26/2015.
 */
module.exports = function(grunt) {
    require('jit-grunt')(grunt);

    "use strict";

    var
//    path        = require("path"),
    fs          = require("fs"),
    buildDate   = grunt.template.today('yyyy-mm-dd'),
    buildYear   = grunt.template.today('yyyy'),
    buildId     = (new Date()).getTime(),
    banner      = "/*\n" +
        "* <%= pkg.name %> - <%= pkg.description_short %>\n" +
        "* Version <%= pkg.version %>\n" +
        "* @requires <%= pkg.requires %>\n" +
        "*\n" +
        "* Copyright (c) <%= pkg.copyright %>\n" +
        "* Examples and docs at:\n" +
        "* <%= pkg.homepage %>\n" +
        "* Licensed under the MIT license:\n" +
        "* http://www.opensource.org/licenses/mit-license.php\n" +
        "*/\n" +
        "/*\n" +
        "* @description <%= pkg.description_long %>\n" +
        "* @type jQuery\n" +
        "* @name <%= pkg.name %>\n" +
        "* @category Plugins/<%= pkg.name %>\n" +
        "* @author <%= pkg.authors %>\n" +
        "* @build <%= pkg.name %> <%= pkg.version %> <%= grunt.template.today('yyyy-mm-dd hh:MM:ss') %>\n" +
        "*/\n";

    // If we don't yet have a user's build file, create it.
    if (!grunt.file.isFile('me.build.json')) {
        grunt.file.write('me.build.json',
            JSON.stringify({
                deployLocation: ''
            }, null, 4)
        );
        grunt.log.writeln("me.build.json file was created at the root of the project" );
    }


    /**
     * Returns a function that can be used with grunt's copy
     * task 'filter' option. Checks if file being copied
     * is newer than that destination file.
     *
     * @param {Object} target
     *      The config object from copy task.
     * @param {String} timestampFile
     *      A timestamp file. Will be used instead of accessing the
     *      destination file when determining if file should be copied.
     *
     * @return {Boolean}
     *      True - yes, its new
     *      false - no, its not new
     *
     * @see {https://github.com/gruntjs/grunt-contrib-copy/issues/78#issuecomment-19027806}
     *
     */

/*
    function onlyNew(target, timestampFile) {

        if (!onlyNew.isTaskCreated) {
            onlyNew.isTaskCreated = true;
            grunt.registerTask('onlyNewPostRun', function(){
                var file = Array.prototype.slice.call(arguments, 0).join(':');
                grunt.log.writeln("onlyNewPostRun Task RUNNING for file: " + file);
                fs.writeFileSync(timestampFile, 'temp file');
            });
            onlyNew.timestampFiles = {};
        }

        // Return the callback function for each file check - used in the task
        return function(src) {

            var dest    = grunt.config(target.concat('dest')),
                cwd     = grunt.config(target.concat('cwd')),
                dstat, stat, response;

            if (!timestampFile) {
                dest = cwd ?
                       path.join(dest, path.relative(cwd, src)) :
                       path.join(dest, src);
            } else {
                dest = timestampFile;
            }

            if (timestampFile && !onlyNew.timestampFiles[timestampFile]) {
                onlyNew.timestampFiles[timestampFile] = true;
                grunt.task.run("onlyNewPostRun:" + timestampFile);
            }

            // grunt.log.writeln("this.target: " + this.name);
            grunt.verbose.writeln("Src  File: " + src);
            grunt.verbose.writeln("Dest File: " + dest);

            try {
                dstat   = fs.statSync(dest);
                stat    = fs.statSync(src);
            } catch (e) {
                // grunt.log.writeln("    Unable to get stat data... Returning True");
                return true;
            }

            // grunt.log.writeln("    Src  is File: " + stat.isFile() + " | mTime: " + stat.mtime.getTime());
            // grunt.log.writeln("    Dest is File: " + dstat.isFile() + " | mTime: " + dstat.mtime.getTime());
            // grunt.log.writeln("mod[" + dstat.mtime.getTime() + "]: " + dest);
            response = ( stat.isFile() && stat.mtime.getTime() > dstat.mtime.getTime() );
            // grunt.log.writeln("    Response: " + response);
            return response;
        };

    } //end: onlyNew()
*/

    /**
     * Replaces build variables in files with actual values. Meant to be used
     * with the 'copy' task as a contentProcess function
     *
     * @param {String} fileContent
     * @param {String} srcPath
     *
     * @return {String}
     */
    function replaceBuildVariables(fileContent, srcPath){

        grunt.verbose.writeln("Processing : " + srcPath );

        return fileContent
            .replace( /@BUILD/g, buildId)
            .replace( /@VERSION/g, grunt.template.process("<%= pkg.version %>"))
            .replace( /@DATE/g, buildDate )
            .replace( /@YEAR/g, buildYear )
            .replace( /@AUTHOR/g, grunt.template.process("<%= pkg.author %>") );

    } //end: replaceBuildVariables()

    // Project configuration.
    grunt.initConfig({

        pkg: grunt.file.readJSON('package.json'),

        userBuildOpt: grunt.file.readJSON("me.build.json"),

        copy: {
            options : {
                processContentExclude: [
                    '**/*.{png,gif,jpg,ico,psd}'
                ]
            },
            // DEPLOY:
            // Copies the files from /src/* and build/* to the folder defined by
            // the user's build options (me.build.json) attribute 'deployLocation'
            // deploy only copies files that have changed since last time.
            deploy: {
                options : {
                    processContent: function(fileContent, filePath){
                        return replaceBuildVariables(fileContent, filePath);
                    }
                },
                src:    [
                    "src/**/*",
                    "build/**/*.js",
                    "tests/**/*"
                ],
                dest:   "<%= userBuildOpt.deployLocation %>",
                expand: true
//                ,
//                filter: onlyNew(['copy', 'deploy'], "me.deploy.timestamp.txt")
            },

            // DEPLOY ALWAYS
            // These file are always deployed.
            deployAlways: {
                options : {
                    processContent: function(fileContent, filePath){
                        return replaceBuildVariables(fileContent, filePath);
                    }
                },
                src:    [
                    "src/dev.aspx"
                ],
                dest:   "<%= userBuildOpt.deployLocation %>",
                expand: true
            },

            processBuildVariables: {
                options : {
                    processContent: function(fileContent, filePath){
                        return replaceBuildVariables(fileContent, filePath);
                    }
                },
                src:    "build/<%= pkg.filename %>.js",
                dest:   "build/<%= pkg.filename %>.js"
            }
        },

        concat: {
            license: {
                src: "license.txt",
                dest: "build/license.txt"
            },
            src: {
                options: {
                    banner: banner
                },
                src:    "build/<%= pkg.filename %>.js",
                dest:   "build/<%= pkg.filename %>.js"
            }
        },

        uglify: {
            options: {
                banner: banner
            },
            build: {
                src:    "build/<%= pkg.filename %>.js",
                dest:   "build/<%= pkg.filename %>.min.js"
            }
        },

        zip: {
            package: {
                src: "<%= pkg.package_zipfiles %>",
                dest: 'build/<%= pkg.filename %>.zip'
            }
        },

        jshint : {
            options : {
                jshintrc : true,
                ignores: [
                    "src/jquery.SPServices Intellisense.js"
                ]
            },
            gruntfile : {
                src : 'Gruntfile.js'
            },
            src : {
                src : ['src/**/*.js']
            }
        },

        watch : {
            gruntfile : {
                files : 'Gruntfile.js',
                tasks : ['jshint:gruntfile']
            },
            src : {
                files : ['src/**/*'],
                tasks : ['jshint:src']
            }
        },

        requirejs: {

            // See requireJS builder documentation (r.js) of more on how to set this up
            // http://requirejs.org/docs/optimization.html#options
            // https://github.com/jrburke/r.js/blob/master/build/example.build.js
            compile: {
                options: {
                    baseUrl: ".",
                    paths: {
                        jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min'
                    },
                    exclude: ["jquery"],
                    optimize: "none",

                    optimizeCss: "standard.keepLines.keepWhitespace",

                    wrap: {
                        // AMD loader code
                        start: ';(function(factory){\n' +
                                '    if ( typeof define === "function" && define.amd ) {\n' +
                                    '        define(["jquery"], factory );\n' +
                                '    } else {\n' +
                                    '        factory(jQuery);' +
                                '    }' +
                            '}(function($) {\n   var jquery = jQuery;\n',
                        end: '}));'
                    },
                    done: function(done, output) {

                        // Let's check to ensure that no one module was built/included more than once.
                        var duplicates = require('rjs-build-analysis').duplicates(output);

                        if (Object.keys(duplicates).length > 0) {
                            grunt.log.subhead('Duplicates found in requirejs build:');
                            for (var key in duplicates) {
                                grunt.log.error(duplicates[key] + ": " + key);
                            }
                            return done(new Error('r.js built duplicate modules, please check the excludes option.'));
                        } else {
                            grunt.log.success("No duplicates found!");
                        }

                        done();
                    },
                    onModuleBundleComplete: function (data) {

                        var amdclean = require('amdclean');

                        // Make a copy of the requireJS optimized file
                        // Uncomment this if you would like to get a single requirejs file
                        // fs.writeFileSync(
                            // data.path + ".compiled.js",
                            // fs.readFileSync(outputFile)
                        // );

                        fs.writeFileSync(data.path, amdclean.clean({
                            'filePath': data.path,
                            'ignoreModules': ["jquery"],
                            transformAMDChecks: false
                        }));

                    },
                    name: "src/SPServices",
                    out: "build/jquery.SPServices.js"
                }
            }

        },

        less: {
            development: {
                options: {
                    compress: true,
                    yuicompress: true,
                    optimization: 2,
                    paths: ["src/css"]
                },
                files: {
                    "src/css/SPServices.css": "src/less/SPServices.less"
                }
            }

        }


    });

    // Load the plugins for tasks.
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-zip');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-requirejs');
    grunt.loadNpmTasks('grunt-contrib-less');

    // Default task(s).
    grunt.registerTask('default', [
        'jshint',
        'less',
        'requirejs:compile',
        'concat',
        'copy:processBuildVariables',
        'uglify',
        'zip'
    ]);

    grunt.registerTask('deploy', function(){

        if (!grunt.config(['userBuildOpt', 'deployLocation'])) {
            grunt.fail.fatal("deployLocation property in me.build.json \n" +
                "is not defined. Unable to deploy");
            return;
        }

        grunt.task.run([
            "default",
            "copy:deploy",
            "copy:deployAlways"
        ]);

    });

};