module.exports = function(grunt) {

  grunt.initConfig({
    clean: {
      dist: ['dist/*.js'],
      test: ['test/**/build/*.js', '_SpecRunner.html']
    },
    browserify: {
      dist: {
        options: {
          external: ['backbone', 'underscore'],
          debug: false
        },
        src: ['src/*.js'],
        dest: 'dist/backbone.queryRouter.browser.js'
      }
    },
    uglify: {
      dist: {
        files: {
          'dist/backbone.queryRouter.browser.min.js': 'dist/backbone.queryRouter.browser.js'
        }
      }
    },
    coffee: {
      test: {
        options: {
          sourceMap: false
        },
        expand: true,
        cwd: 'test',
        src: ['**/*.coffee'],
        dest: 'test',
        rename: function(dest, src){
          return path.join(dest, path.dirname(src), "/build", path.basename(src));
        },
        ext: '.coffee.js'
      }
    },
    jasmine: {
      test: {
        src: 'dist/backbone.queryRouter.browser.js',
        options: {
          specs: 'test/spec/build/*.js',
          helpers: 'test/helpers/build/*.js',
          vendor: [
            'bower_components/jquery/dist/jquery.js',
            'bower_components/underscore/underscore.js',
            'bower_components/backbone/backbone.js'
          ]
        }
      }
    },
    docker : {
      dist : {
        src: ['src/*.js', 'README.md'], 
        dest: 'doc',
        options: {
          lineNums: true
        }
      }
    },
    jshint: {
      validate: {
        src: ['src/**/*.js']
      },
      options: grunt.file.readJSON('.jshintrc')
    },
  });


  // Load all grunt tasks in package.json
  _.each(matchdep.filterAll('grunt-*'), function(pkgName){
    grunt.loadNpmTasks(pkgName);
  });
  grunt.registerTask('test', ['clean:test', 'browserify', 'coffee:test', 'jasmine']);
  grunt.registerTask('release', ['clean:dist', 'browserify', 'uglify']);
  grunt.registerTask('default', ['jshint', 'test', 'release', 'docker']);
};
 matchkeys.filter('*').map(function(keywords) {
   matchdep.filterAll(keywords, pkg).forEach(function(match) {
     loadNpmHelpers.push(match);
   });
 });
 matchkeys.filter('*').map(function (keywords) {
   matchdep.filterAll(keywords, pkg).forEach(function (match) {
     registerHelper(match);
   });
 });
module.exports = function(grunt) {

  grunt.initConfig({

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

    // The clean task ensures all files are removed from the dist/ directory so
    // that no files linger from previous builds.
    clean: {
      build: ['dist/*']
    },

    // The lint task will run the build configuration and the application
    // JavaScript through JSHint and report any errors.  You can change the
    // options for this task, by reading this:
    // https://github.com/cowboy/grunt/blob/master/docs/task_lint.md
    jshint: {
      validate: {
        src: ['app/**/*.js']
      },
      options: grunt.file.readJSON('.jshintrc')
    },

    compass: {
      secureshare: {
        options: {
          // config: "../config.rb",
          // basePath: "../",
          force: false // not necessary unless config_prod changes
        }
      }
    },


    // The jst task compiles all application templates into JavaScript
    // functions with the underscore.js template function from 1.2.4.  You can
    // change the namespace and the template options, by reading this:
    // https://github.com/gruntjs/grunt-contrib/blob/master/docs/jst.md
    //
    // The concat task depends on this file to exist, so if you decide to
    // remove this, ensure concat is updated accordingly.
    jst: {
      'dist/templates.js': [
        'app/templates/**/*.tpl'
      ],
      options: {
        processName: function(fileName) {
          return '/' + fileName; // add leading slash to fileName so layoutmanager sees it
        }
      }

    },

    uglify: {
      options: {
        banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
                '<%= grunt.template.today("yyyy-mm-dd") %> */',
        sourceMap: function(dest){
          return dest + ".map";
        },
      },
      secureshare: {
        files: { // 'dest' : ['src']
          'dist/build.js' : [
            'dist/templates.js',
            'app/**/*.js'
          ]
        },
      },
    },

    md5: {
      compile: {
        files: [
          {src: 'dist/build.js', dest: 'dist/'},
          {src: 'css/style.css', dest: 'dist/'}
        ],
        //overide the paths in the index.html with the new md5 name
        options: {
          after: function(fileChanges, options) {
            var fs = require('fs');
            var files = {
              'index.html': fs.readFileSync('index.html', 'utf8')
            };
            // Iterate through files & replace contents based on md5
            Object.keys(files).forEach(function(fileName) {
              var file = files[fileName];
              fileChanges.forEach(function(fileChange) {
                // Remove webroot
                fileChange.newPath = fileChange.newPath.replace('webroot/', '');
                file = file.replace(fileChange.oldPath, fileChange.newPath);
              });
              fs.writeFileSync(fileName, file);
            });
          },
          keepExtension: true,
          keepBasename: true,
          encoding: 'utf8'
        }
      }
    },

    /**
     * Dev tasks
     */

    // Live reloading
    watch: {
      options: {
        //nospawn: true // This is faster but can cause problems over time
      },
      // This will simply refresh on a script change, nothing more. Not always the right answer.
      // Would love chrome debugger code hot swapping.
      scripts: {
        files: ['app/**/*.js'],
        tasks: [],
        options: {
          livereload: false
        },
      },
      templates: {
        files: ['app/**/*.tpl'],
        tasks: ['jst'],
        options: {
          livereload: false
        }
      },
      sass: {
        files: ['css/*.sass'],
        tasks: ['compass:dev'],
        options: {
          livereload: false // this will refresh the browser if true
        }
      },
      css: {
        files: ['css/**/*'],
        options: {
          livereload: true
        }
      },
    }

  });

  /**
   * Main tasks
   */

  _.each(matchdep.filterAll('grunt-*'), function(pkgName){
    grunt.loadNpmTasks(pkgName);
  });


  // The debug task will remove all contents inside the dist/ folder, lint
  // all your code, precompile all the underscore templates into
  // dist/debug/templates.js, compile all the application code into
  // dist/debug/require.js, and then concatenate the require/define shim
  // almond.js and dist/debug/templates.js into the require.js file.
  grunt.registerTask('debug', ['clean:build', 'jshint', 'jst', 'compass'/*, "jsdoc"*/]);

  // The release task will run the debug tasks and then minify the
  // dist/debug/require.js file and CSS files.
  grunt.registerTask('release', ['debug', 'uglify', 'md5']);

  grunt.registerTask('default', ['release']);
};
Beispiel #5
0
module.exports = function(grunt) {
    'use strict';

    // require it at the top and pass in the grunt instance
    require('time-grunt')(grunt);

    var matchdep = require('matchdep'),
        path = require('path'),
        _ = require('lodash'),
        meta = grunt.file.readJSON('./bower.json'),
        pkg = _.merge(grunt.file.readJSON('./package.json'),
            { asimov: { requirejs: {} } }),
        isTheme = meta.name.indexOf('-theme-') !== -1
    ;

    var readPackage = function readPackage(cwd) {
        return _.merge(
            grunt.file.readJSON(path.join(cwd, 'package.json')),
            { asimov: { requirejs: {} } }
        );
    };

    var asimoveCorePath = path.resolve(meta.name === 'asimov-core' ?
        '.' :
        './bower_components/asimov-core');


    // Create an array of asimov deps
    //
    // Since bower installs dep flat rather than nested (npm style) we can use
    // simple globbing. Alternative we could use bower.commands.list.
    var bowerDeps = grunt.file.glob.sync('bower_components/asimov-*');

    // Create a array of paths to be passed to sass' --load-path
    //
    // This allows us to use @import bowered in components' sass files as if
    // they were part of your local component/theme.
    var sassLoadPaths = [
        'src/scss',
        './bower_components',
        // Allow @import "docs/assets/scss/docs" in theme/component docs themes
        './bower_components/asimov-core/src',
        './node_modules/bootcamp/dist'
    ].concat(bowerDeps.map(function (depPath) {
        return path.join(depPath, 'src', 'scss');
    }));

    // RequireJS task settings
    //
    // If we're compiling asimov-core then we only need to compile the one file
    // If we're compiling themes or components we need to walk directories to
    // find what modules we need to build
    var rjsOptions = {
        options: {
            logLevel: 3,
            optimize: 'none',
            keepBuildDir: true,
            // skipModuleInsertion: true,
            removeCombined: true,
            shim: pkg.asimov.requirejs.shim || {},
            paths: _.merge({
                jquery: 'empty:',
                asimov: '<%= asimov.src %>/js/core'
            }, pkg.asimov.requirejs.paths)
        }
    };

    // if we're compiling a asimov-core
    if (meta.name === 'asimov-core') {
        rjsOptions = { all: _.merge({
            options: {
                baseUrl: 'src/js',
                name: 'core',
                out: 'dist/js/asimov/core.js'
            }
        }, rjsOptions) };
    // if we're compiling a theme
    } else if (isTheme) {
        var tmpRjsOptions = {};
        grunt.file.expand({ cwd: 'bower_components' }, 'asimov-*/src/js/*.js')
            .forEach(function(file) {
                var parts = file.split('/'),
                    cwd = 'bower_components/' + parts[0] + '/src/js';

                tmpRjsOptions[parts[0]] = _.merge({
                    options: {
                        // this line a work around for a bug in r.js
                        // https://github.com/jrburke/r.js/issues/587
                        // https://github.com/gruntjs/grunt-contrib-requirejs/issues/45
                        _buildPathToModuleIndex: [],

                        baseUrl: cwd,
                        dir: 'dist/js',
                        shim: readPackage(cwd + '/../../').asimov.requirejs.shim || {},
                        paths: _.mapValues(
                            readPackage(cwd + '/../../').asimov.requirejs.paths || {},
                            function(item) {
                                return '../../' + item;
                            }
                        ),
                        modules: grunt.file.expand({ cwd: cwd }, '*.js')
                            .map(function (file) {
                                return { name: file.replace(/\.js$/, '') };
                            })
                    }
                }, rjsOptions);
            });

        rjsOptions = tmpRjsOptions;
    }
    // we're compiling a component
    else {
        rjsOptions = { all: _.merge({
            options: {
                baseUrl: 'src/js',
                dir: 'dist/js',
                paths: pkg.asimov.requirejs.paths,
                modules: grunt.file.expand({ cwd: 'src/js' }, '*.js')
                    .map(function (file) {
                        return { name: file.replace(/\.js$/, '') };
                    })
            }
        }, rjsOptions) };
    }

    grunt.initConfig({
        bower: grunt.file.readJSON('bower.json'),
        jshintrc: grunt.file.exists('.jshintrc') ?
            grunt.file.readJSON('.jshintrc') :
            grunt.file.readJSON(asimoveCorePath + '/.jshintrc'),

        // Project settings

        asimov: {
            isCore: meta.name === 'asimov-core',
            core: asimoveCorePath,
            src: '<%= asimov.core %>/src'
        },

        // Remove generated files

        clean: {
            dist: ['dist/*'],
            docs: ['docs/*'],
            build: ['.build/*']
        },

        // RequireJS

        requirejs: rjsOptions,

        // Sass compilation

        sass: {
            options: {
                style: 'expanded',
                lineNumbers: false,
                trace: true,
                loadPath: sassLoadPaths,
                cacheLocation: '.build/.sass-cache',
                bundleExec: true
            },
            test: {
                files: [{
                    expand: true,
                    cwd: 'tests/scss',
                    src: ['*.scss'],
                    dest: '.build/tests/css',
                    ext: '.css'
                }]
            },
            docs: {
                files: (!grunt.file.exists('src/docs/assets/scss') ?
                [{
                    expand: true,
                    cwd: '<%= asimov.src %>/docs/assets/scss',
                    src: ['*.scss'],
                    dest: 'docs/assets/css',
                    ext: '.css'
                }] : [{
                    expand: true,
                    cwd: 'src/docs/assets/scss',
                    src: ['*.scss'],
                    dest: 'docs/assets/css',
                    ext: '.css'
                }])
            },
            dist: {
                files: [{
                    expand: true,
                    cwd: 'src/scss',
                    src: ['*.scss'],
                    dest: 'dist/css',
                    ext: '.css'
                }]
            }
        },

        bootcamp: {
            test: {
                files: {
                    src: ['.build/tests/css/index.css']
                }
            }
        },

        autoprefixer: {
            options: {
                // browsers: ['last 2 version', 'ie 8', 'ie 9']
                browsers: [
                    'last 2 version',
                    'Firefox ESR',
                    'BlackBerry 10',
                    'Android 4',
                    'Explorer 8',
                    'Explorer 9',
                    'Opera 12.1'
                ]
            },
            dist: {
                src: 'dist/css/*!(.min).css'
            }
        },

        // Create minified versions of the dist files

        cssmin: {
            dist: {
                expand: true,
                cwd: 'dist/css',
                src: ['**/*.css', '!*.min.css'],
                dest: 'dist/css',
                ext: '.min.css'
            }
        },

        uglify: {
            dist: {
                expand: true,
                cwd: 'dist/js',
                src: ['**/*.js', '!*.min.js'],
                dest: 'dist/js',
                ext: '.min.js'
            }
        },

        // Generate the docs

        symlink: _.merge({
            core: {
                src: path.join(asimoveCorePath, 'dist'),
                dest: 'docs/assets/asimov-core'
            }
        }, (meta.name === 'asimov-core' ? {} : {
            docs: {
                src: 'dist',
                dest: 'docs/assets/<%= bower.name %>'
            }
        })),

        template: {
            docs: {
                options: {
                    data: function () {
                        return {
                            styles: grunt.file.expand({ cwd: 'docs/assets' }, [
                                'asimov-!(core)/css/**/*.css',
                                '!**/*.min.css'
                            ]),
                            scripts: grunt.file.expand({ cwd: 'docs/assets' }, [
                                'asimov-!(core)/js/{*,/}*.js',
                                '!**/*.min.js'
                            ])
                        };
                    }
                },
                files: {
                    '.build/docs/index.html': ['<%= asimov.src %>/docs/index.html'],
                    '.build/docs/styleguide.md': ['<%= asimov.src %>/docs/styleguide.md']
                }
            }
        },

        sync: {
            docs: {
                files: [{
                    cwd: '<%= asimov.src %>/docs/assets',
                    src: ['**', '!scss/**'],
                    dest: 'docs/assets'
                }]
            },
            dist: {
                files: [{
                    cwd: 'src',
                    src: ['**', '!scss/**', '!js/**', '!docs/**'],
                    dest: 'dist'
                }, {
                    expand: true,
                    cwd: 'bower_components',
                    src: ['asimov-*/src/**', '!**/scss/**', '!**/js/**', '!**/docs/**'],
                    dest: 'dist',
                    filter: function(src) {
                        return grunt.file.isFile(src);
                    },
                    rename: function(dest, src) {
                        return dest + path.sep + src.replace(/asimov-[^/]+\/src\//, '');
                    }
                }]
            }
        },

        exec: {
            docs: {
                cmd: [
                    '<%= asimov.core %>/node_modules/.bin/distancss',
                    'dist/css',
                    'docs',
                    '--template',
                    '.build/docs',
                    '--public',
                    '/assets'
                ].join(' ')
            }
        },

        // Docs server

        connect: {
            options: {
                base: 'docs',
                keepalive: true,
                port: 9001
            },
            dev: {}
        },

        // Javscript QA
        //
        // 1: wash our hands of 3rd party assets
        // 2: allow for debug code when in dev

        jsvalidate: {
            dist: [
                'src/js/**/*.js',
                '!**/vendor/**'                 // 1
            ],
            docs: [
                'src/docs/assets/js/**/*.js',
                '!**/vendor/**'                 // 1
            ]
        },

        jshint: {
            options: '<%= jshintrc %>',
            dist: ['<%= jsvalidate.dist %>'],
            docs: ['<%= jsvalidate.docs %>']
        },

        gjslint: {
            options: {
                flags: [
                    '--disable 110,13'
                ],
                reporter: {
                    name: 'console'
                }
            },
            dist: ['<%= jsvalidate.dist %>'],
            docs: ['<%= jsvalidate.docs %>']
        },

        // Developement watch task

        watch: {
            options: {
                debounceDelay: 100,
                spawn: false
            },
            sass: {
                files: ['src/@(scss|docs)/**/*.scss'],
                tasks: ['build-styles:dev', 'build-docs:dev']
            },
            js: {
                files: ['src/@(scss|docs)/**/*.js'],
                tasks: ['build-scripts:dev', 'build-docs:dev']
            }
        },

        concurrent: {
            target: {
                tasks: ['connect:dev', 'watch'],
                options: {
                    logConcurrentOutput: true
                }
            }
        },

        // Creating new releases

        bump: {
            options: {
                files: ['bower.json'],
                updateConfigs: ['bower'],
                commit: true,
                commitMessage: 'chore(release): release v%VERSION%',
                commitFiles: ['bower.json', '<%= changelog.options.dest %>'],
                createTag: true,
                tagName: '%VERSION%',
                tagMessage: 'tagging version %VERSION%',
                push: true,
                pushTo: 'origin'
            }
        },

        // Automatic changelogs

        changelog: {
            options: {
                dest: 'CHANGELOG.md',
                prepend: true,
                version: '<%= bower.version %>',
                editor: 'subl -w'
            }
        },

        // Creating new releases

        release: {
            dryRun: false
        }
    });

    // Load tasks defined in asimov-core's package.json

    var base = process.cwd();
    matchdep.filterAll('grunt-!(cli)', asimoveCorePath + '/package.json')
        .forEach(function (task) {
            // need to temporarily change base for grunt.loadNpmTasks to work
            grunt.file.setBase(asimoveCorePath);
            grunt.loadNpmTasks(task);
            grunt.file.setBase(base);
        });

    // Load our custom tasks

    grunt.loadNpmTasks('bootcamp');
    grunt.loadTasks(asimoveCorePath + '/build/tasks');

    if (grunt.file.exists('./build/tasks')) {
        grunt.loadTasks('build/tasks');
    }

    // Public tasks

    grunt.registerTask('dev', [
        'clean',
        'prepare-build',
        'build-scripts:dev',
        'build-styles:dev',
        'build-docs:dev',
        'concurrent'
    ]);

    grunt.registerTask('default', [
        'clean',
        'prepare-build',
        'build-scripts:prod',
        'build-styles:prod',
        'build-docs:prod'
    ]);
};