X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=Gruntfile.js;h=672dc9e9ed9a8dcf70aec9f8a62b0e6b2764ced9;hb=8ae115bacf021699aebd2f1f5b63d05cd9bd9536;hp=2afed9b6e4348aaecdcf67ac320da253e9c53e1e;hpb=6fb7bfbf8d4269f8c013ebf7ac2502346b780b5b;p=dlux.git diff --git a/Gruntfile.js b/Gruntfile.js index 2afed9b6..672dc9e9 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,773 +1,675 @@ -var lrSnippet = require('connect-livereload')(); -var mountFolder = function (connect, dir) { - return connect.static(require('path').resolve(dir)); -}; - -module.exports = function ( grunt ) { - - /** - * Load required Grunt tasks. These are installed based on the versions listed - * in `package.json` when you do `npm install` in this directory. - */ - grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-contrib-copy'); - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-concat'); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-coffee'); - grunt.loadNpmTasks('grunt-conventional-changelog'); - grunt.loadNpmTasks('grunt-bump'); - grunt.loadNpmTasks('grunt-coffeelint'); - //grunt.loadNpmTasks('grunt-recess'); - grunt.loadNpmTasks('grunt-karma'); - grunt.loadNpmTasks('grunt-ngmin'); - grunt.loadNpmTasks('grunt-html2js'); - grunt.loadNpmTasks('grunt-contrib-less'); - grunt.loadNpmTasks('grunt-contrib-connect'); - grunt.loadNpmTasks('grunt-open'); - - /** - * Load in our build configuration file. - */ - var userConfig = require( './build.config.js' ); - - /** - * This is the configuration object Grunt uses to give each plugin its - * instructions. - */ - var taskConfig = { - /** - * We read in our `package.json` file so we can access the package name and - * version. It's already there, so we don't repeat ourselves here. - */ - pkg: grunt.file.readJSON("package.json"), - - /** - * The banner is the comment that is placed at the top of our compiled - * source files. It is first processed as a Grunt template, where the `<%=` - * pairs are evaluated based on this very configuration object. - */ - meta: { - banner: - '/**\n' + - ' * <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' + - ' * <%= pkg.homepage %>\n' + - ' *\n' + - ' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' + - ' * Licensed <%= pkg.licenses.type %> <<%= pkg.licenses.url %>>\n' + - ' */\n' - }, - - /** - * Creates a changelog on a new version. - */ - changelog: { - options: { - dest: 'CHANGELOG.md', - template: 'changelog.tpl' - } - }, - - /** - * Increments the version number, etc. - */ - bump: { - options: { - files: [ - "package.json", - "bower.json" - ], - commit: false, - commitMessage: 'chore(release): v%VERSION%', - commitFiles: [ - "package.json", - "client/bower.json" - ], - createTag: false, - tagName: 'v%VERSION%', - tagMessage: 'Version %VERSION%', - push: false, - pushTo: 'origin' - } - }, - - /** - * The directories to delete when `grunt clean` is executed. - */ - clean: [ - '<%= build_dir %>', - '<%= compile_dir %>' - ], - - /** - * The `copy` task just copies files from A to B. We use it here to copy - * our project assets (images, fonts, etc.) and javascripts into - * `build_dir`, and then to copy the assets to `compile_dir`. - */ - copy: { - build_app_assets: { - files: [ - { - src: [ '**' ], - dest: '<%= build_dir %>/assets/', - cwd: 'src/assets', - expand: true - } - ] - }, - build_vendor_assets: { - files: [ - { - src: [ '<%= vendor_files.assets %>' ], - dest: '<%= build_dir %>/assets/', - cwd: '.', - expand: true, - flatten: true - } - ] - }, - build_appjs: { - files: [ - { - src: [ '<%= app_files.js %>' ], - dest: '<%= build_dir %>/', - cwd: '.', - expand: true - } - ] - }, - build_vendorjs: { - files: [ - { - src: [ '<%= vendor_files.js %>' ], - dest: '<%= build_dir %>/', - cwd: '.', - expand: true - } - ] - }, - build_vendorimages: { - files: [ - { - src: [ '<%= vendor_files.images %>' ], - dest: '<%= build_dir %>/', - cwd: '.', - expand: true - } - ] - }, - build_vendorcss: { - files: [ - { - src: [ '<%= vendor_files.css %>' ], - dest: '<%= build_dir %>', - cwd: '.', - expand: true - } - ] - }, - compile_assets: { - files: [ - { - src: [ '**' ], - dest: '<%= compile_dir %>/assets', - cwd: '<%= build_dir %>/assets', - expand: true - } - ] - }, - - /* build_vendor_font: { - files: [ - { - src: [ '<%= vendor_files.font %>' ], - dest: '<%= build_dir %>', - cwd: '.', - expand: true - } - ] - },*/ - - compile_font: { - files: [ - { - src: [ '**' ], - dest: '<%= compile_dir %>/font', - cwd: '<%= build_dir %>/font', - expand: true - } - ] - } - }, - - /** - * `grunt concat` concatenates multiple source files into a single file. - */ - concat: { - /** - * The `build_css` target concatenates compiled CSS and vendor CSS - * together. - */ - build_css: { - src: [ - '<%= vendor_files.css %>', - '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css' - ], - dest: '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css' - }, - /** - * The `compile_js` target is the concatenation of our application source - * code and all specified vendor source code into a single file. - */ - compile_js: { - options: { - banner: '<%= meta.banner %>' - }, - src: [ - '<%= vendor_files.js %>', - 'module.prefix', - '<%= build_dir %>/src/**/*.js', - '<%= html2js.common.dest %>', - '<%= html2js.app.dest %>', - 'module.suffix' - ], - dest: '<%= compile_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.js' - } - }, - - /** - * `grunt coffee` compiles the CoffeeScript sources. To work well with the - * rest of the build, we have a separate compilation task for sources and - * specs so they can go to different places. For example, we need the - * sources to live with the rest of the copied JavaScript so we can include - * it in the final build, but we don't want to include our specs there. - */ - coffee: { - source: { - options: { - bare: true - }, - expand: true, - cwd: '.', - src: [ '<%= app_files.coffee %>' ], - dest: '<%= build_dir %>', - ext: '.js' - } - }, - - /** - * `ng-min` annotates the sources before minifying. That is, it allows us - * to code without the array syntax. - */ - ngmin: { - compile: { - files: [ - { - src: [ '<%= app_files.js %>' ], - cwd: '<%= build_dir %>', - dest: '<%= build_dir %>', - expand: true - } - ] - } - }, - - /** - * Minify the sources! - */ - uglify: { - compile: { - options: { - banner: '<%= meta.banner %>' - }, - files: { - '<%= concat.compile_js.dest %>': '<%= concat.compile_js.dest %>' - } - } - }, - - /** - * `recess` handles our LESS compilation and uglification automatically. - * Only our `main.less` file is included in compilation; all other files - * must be imported from this file. - */ - /**recess: { - build: { - src: [ '<%= app_files.less %>' ], - dest: '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css', - options: { - compile: true, - compress: false, - noUnderscores: false, - noIDs: false, - zeroUnits: false - } - }, - compile: { - src: [ '<%= recess.build.dest %>' ], - dest: '<%= recess.build.dest %>', - options: { - compile: true, - compress: true, - noUnderscores: false, - noIDs: false, - zeroUnits: false - } - } - }, **/ - - /** - * `less` less plugin handles the LESS compilation and minification automatically - * this has been changed to the LESS plugin from recess plugin above because of - * out of memory issues with the original plugin. - */ - - less: { - development: { - options: { - paths: ["assets/css"], - compress: false, - syncImport: true, - strictImports: true - }, - files: { - '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css': '<%= app_files.less %>' - } - }, - production: { - options: { - paths: ["assets/css"], - compress: true, - cleancss: true - }, - files: { - '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css': '<%= app_files.less %>' - } - } - }, - - /** - * `jshint` defines the rules of our linter as well as which files we - * should check. This file, all javascript sources, and all our unit tests - * are linted based on the policies listed in `options`. But we can also - * specify exclusionary patterns by prefixing them with an exclamation - * point (!); this is useful when code comes from a third party but is - * nonetheless inside `src/`. - */ - jshint: { - src: [ - '<%= app_files.js %>' - ], - test: [ - '<%= app_files.jsunit %>' - ], - gruntfile: [ - 'OriginalGruntfile.js' - ], - options: { - curly: true, - immed: true, - newcap: true, - noarg: true, - sub: true, - boss: true, - eqnull: true - }, - globals: {} - }, - - /** - * `coffeelint` does the same as `jshint`, but for CoffeeScript. - * CoffeeScript is not the default in ngBoilerplate, so we're just using - * the defaults here. - */ - coffeelint: { - src: { - files: { - src: [ '<%= app_files.coffee %>' ] - } - }, - test: { - files: { - src: [ '<%= app_files.coffeeunit %>' ] - } - } - }, - - /** - * HTML2JS is a Grunt plugin that takes all of your template files and - * places them into JavaScript files as strings that are added to - * AngularJS's template cache. This means that the templates too become - * part of the initial payload as one JavaScript file. Neat! - */ - html2js: { - /** - * These are the templates from `src/app`. - */ - app: { - options: { - base: 'src/app' - }, - src: [ '<%= app_files.atpl %>' ], - dest: '<%= build_dir %>/templates-app.js' - }, - - /** - * These are the templates from `src/common`. - */ - common: { - options: { - base: 'src/common' - }, - src: [ '<%= app_files.ctpl %>' ], - dest: '<%= build_dir %>/templates-common.js' - } - }, - - /** - * The Karma configurations. - */ - karma: { - options: { - configFile: '<%= build_dir %>/karma-unit.js' - }, - unit: { - runnerPort: 9102, - background: true, - port: 9877 // IMPORTANT! - }, - continuous: { - singleRun: true - } - }, - - /** - * The `index` task compiles the `index.html` file as a Grunt template. CSS - * and JS files co-exist here but they get split apart later. - */ - index: { - - /** - * During development, we don't want to have wait for compilation, - * concatenation, minification, etc. So to avoid these steps, we simply - * add all script files directly to the `` of `index.html`. The - * `src` property contains the list of included files. - */ - build: { - dir: '<%= build_dir %>', - src: [ - '<%= vendor_files.js %>', - '<%= build_dir %>/src/**/*.js', - '<%= html2js.common.dest %>', - '<%= html2js.app.dest %>', - '<%= vendor_files.css %>', - '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css' - ] - }, - - /** - * When it is time to have a completely compiled application, we can - * alter the above to include only a single JavaScript and a single CSS - * file. Now we're back! - */ - compile: { - dir: '<%= compile_dir %>', - src: [ - '<%= concat.compile_js.dest %>', - '<%= concat.build_css.dest %>' - //'<%= recess.compile.dest %>' - ] - } - }, - - /** - * This task compiles the karma template so that changes to its file array - * don't have to be managed manually. - */ - karmaconfig: { - unit: { - dir: '<%= build_dir %>', - src: [ - '<%= vendor_files.js %>', - '<%= html2js.app.dest %>', - '<%= html2js.common.dest %>', - '<%= app_files.js_common %>', - '<%= app_files.js_app %>', - '<%= app_files.jsunit %>' - ] - } - }, - connect: { - livereload: { - options: { - port: 9000, - hostname: '0.0.0.0', - middleware: function (connect) { - return [ - mountFolder(connect, 'build'), - lrSnippet - ]; - } - } - }, - dev: { - options: { - hostname: '0.0.0.0', - port: 9000, - base: 'build' - } - }, - prod: { - options: { - port: 9001, - base: 'bin', - keepalive: true - } - } - }, - open: { - dev: { - path: 'http://127.0.0.1:9000/' - }, - prod: { - path: 'http://127.0.0.1:9001/' - } - }, - /** - * And for rapid development, we have a watch set up that checks to see if - * any of the files listed below change, and then to execute the listed - * tasks when they do. This just saves us from having to type "grunt" into - * the command-line every time we want to see what we're working on; we can - * instead just leave "grunt watch" running in a background terminal. Set it - * and forget it, as Ron Popeil used to tell us. - * - * But we don't need the same thing to happen for all the files. - */ - delta: { - /** - * By default, we want the Live Reload to work for all tasks; this is - * overridden in some tasks (like this file) where browser resources are - * unaffected. It runs by default on port 35729, which your browser - * plugin should auto-detect. - */ - options: { - livereload: true - }, - - /** - * When the Gruntfile changes, we just want to lint it. In fact, when - * your Gruntfile changes, it will automatically be reloaded! - */ - gruntfile: { - files: 'OriginalGruntfile.js', - tasks: [ 'jshint:gruntfile' ], - options: { - livereload: false - } - }, - - /** - * When our JavaScript source files change, we want to run lint them and - * run our unit tests. - */ - jssrc: { - files: [ - '<%= app_files.js %>' - ], - tasks: [ 'jshint:src', 'karma:unit:run', 'copy:build_appjs' ] - }, - - /** - * When our CoffeeScript source files change, we want to run lint them and - * run our unit tests. - */ - coffeesrc: { - files: [ - '<%= app_files.coffee %>' - ], - tasks: [ 'coffeelint:src', 'coffee:source', 'karma:unit:run', 'copy:build_appjs' ] - }, - - /** - * When assets are changed, copy them. Note that this will *not* copy new - * files, so this is probably not very useful. - */ - assets: { - files: [ - 'src/assets/**/*' - ], - tasks: [ 'copy:build_assets' ] - }, - - /** - * When index.html changes, we need to compile it. - */ - html: { - files: [ '<%= app_files.html %>' ], - tasks: [ 'index:build' ] - }, - - /** - * When our templates change, we only rewrite the template cache. - */ - tpls: { - files: [ - '<%= app_files.atpl %>', - '<%= app_files.ctpl %>' - ], - tasks: [ 'html2js' ] - }, - - /** - * When the CSS files change, we need to compile and minify them. - */ - less: { - files: [ 'src/**/*.less' ], - tasks: [ 'less:development' ] - }, - - /** - * When a JavaScript unit test file changes, we only want to lint it and - * run the unit tests. We don't want to do any live reloading. - */ - jsunit: { - files: [ - '<%= app_files.jsunit %>' - ], - tasks: [ 'jshint:test', 'karma:unit:run' ], - options: { - livereload: false - } - }, - - /** - * When a CoffeeScript unit test file changes, we only want to lint it and - * run the unit tests. We don't want to do any live reloading. - */ - coffeeunit: { - files: [ - '<%= app_files.coffeeunit %>' - ], - tasks: [ 'coffeelint:test', 'karma:unit:run' ], - options: { - livereload: false - } - } - } - }; - - grunt.initConfig( grunt.util._.extend( taskConfig, userConfig ) ); - - /** - * In order to make it safe to just compile or copy *only* what was changed, - * we need to ensure we are starting from a clean, fresh build. So we rename - * the `watch` task to `delta` (that's why the configuration var above is - * `delta`) and then add a new task called `watch` that does a clean build - * before watching for changes. - */ - grunt.renameTask( 'watch', 'delta' ); - grunt.registerTask( 'watch', [ 'build', 'karma:unit', 'delta' ] ); - - grunt.registerTask('live', ['build', 'connect:dev', 'delta']); - /** - * The default task is to build and compile. - */ - grunt.registerTask( 'default', [ 'build', 'compile' ] ); - - /** - * The `build` task gets your app ready to run for development and testing. - */ - grunt.registerTask( 'build', [ - 'clean', 'html2js', 'jshint', 'coffeelint', 'coffee', 'less:development', - 'concat:build_css', 'copy:build_app_assets', 'copy:build_vendor_assets', - 'copy:build_appjs', 'copy:build_vendorimages', 'copy:build_vendorjs', 'copy:build_vendorcss', 'karmaconfig', /*'copy:build_vendor_font',*/ 'index:build'/*, - 'karma:continuous' */ - ]); - - /** - * The `compile` task gets your app ready for deployment by concatenating and - * minifying your code. - */ - grunt.registerTask( 'compile', [ - 'less:production', 'concat:build_css', 'copy:compile_assets', 'ngmin:compile', 'concat:compile_js', 'uglify', 'index:compile' - ]); - - /** - * A utility function to get all app JavaScript sources. - */ - function filterForJS ( files ) { - return files.filter( function ( file ) { - return file.match( /\.js$/ ); - }); - } - - /** - * A utility function to get all app CSS sources. - */ - function filterForCSS ( files ) { - return files.filter( function ( file ) { - return file.match( /\.css$/ ); - }); - } - - /** - * The index.html template includes the stylesheet and javascript sources - * based on dynamic names calculated in this Gruntfile. This task assembles - * the list into variables for the template to use and then runs the - * compilation. - */ - grunt.registerMultiTask( 'index', 'Process index.html template', function () { - var dirRE = new RegExp( '^('+grunt.config('build_dir')+'|'+grunt.config('compile_dir')+')\/', 'g' ); - var jsFiles = filterForJS( this.filesSrc ).map( function ( file ) { - return file.replace( dirRE, '' ); - }); - var cssFiles = filterForCSS( this.filesSrc ).map( function ( file ) { - return file.replace( dirRE, '' ); - }); - - grunt.file.copy('src/index.html', this.data.dir + '/index.html', { - process: function ( contents, path ) { - return grunt.template.process( contents, { - data: { - scripts: jsFiles, - styles: cssFiles, - version: grunt.config( 'pkg.version' ) - } - }); - } - }); - - grunt.file.copy('src/login.html', this.data.dir + '/login.html', { - process: function ( contents, path ) { - return grunt.template.process( contents, { - data: { - scripts: jsFiles, - styles: cssFiles, - version: grunt.config( 'pkg.version' ) - } - }); - } - }); - }); - - /** - * In order to avoid having to specify manually the files needed for karma to - * run, we use grunt to manage the list for us. The `karma/*` files are - * compiled as grunt templates for use by Karma. Yay! - */ - grunt.registerMultiTask( 'karmaconfig', 'Process karma config templates', function () { - var jsFiles = filterForJS( this.filesSrc ); - - grunt.file.copy( 'karma/karma-unit.tpl.js', grunt.config( 'build_dir' ) + '/karma-unit.js', { - process: function ( contents, path ) { - return grunt.template.process( contents, { - data: { - scripts: jsFiles - } - }); - } - }); - }); - -}; +var lrSnippet = require('connect-livereload')(); +var mountFolder = function (connect, dir) { + return connect.static(require('path').resolve(dir)); +}; + +module.exports = function ( grunt ) { + + /** + * Load required Grunt tasks. These are installed based on the versions listed + * in `package.json` when you do `npm install` in this directory. + */ + grunt.loadNpmTasks('grunt-contrib-clean'); + grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-conventional-changelog'); + grunt.loadNpmTasks('grunt-bump'); + //grunt.loadNpmTasks('grunt-recess'); + grunt.loadNpmTasks('grunt-karma'); + grunt.loadNpmTasks('grunt-ngmin'); + grunt.loadNpmTasks('grunt-html2js'); + grunt.loadNpmTasks('grunt-contrib-less'); + grunt.loadNpmTasks('grunt-contrib-connect'); + grunt.loadNpmTasks('grunt-open'); + + /** + * Load in our build configuration file. + */ + var userConfig = require( './build.config.js' ); + + /** + * This is the configuration object Grunt uses to give each plugin its + * instructions. + */ + var taskConfig = { + /** + * We read in our `package.json` file so we can access the package name and + * version. It's already there, so we don't repeat ourselves here. + */ + pkg: grunt.file.readJSON("package.json"), + + /** + * The banner is the comment that is placed at the top of our compiled + * source files. It is first processed as a Grunt template, where the `<%=` + * pairs are evaluated based on this very configuration object. + */ + meta: { + banner: + '/**\n' + + ' * <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' + + ' * <%= pkg.homepage %>\n' + + ' *\n' + + ' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' + + ' * Licensed <%= pkg.licenses.type %> <<%= pkg.licenses.url %>>\n' + + ' */\n' + }, + + /** + * Creates a changelog on a new version. + */ + changelog: { + options: { + dest: 'CHANGELOG.md', + template: 'changelog.tpl' + } + }, + + /** + * Increments the version number, etc. + */ + bump: { + options: { + files: [ + "package.json", + "bower.json" + ], + commit: false, + commitMessage: 'chore(release): v%VERSION%', + commitFiles: [ + "package.json", + "client/bower.json" + ], + createTag: false, + tagName: 'v%VERSION%', + tagMessage: 'Version %VERSION%', + push: false, + pushTo: 'origin' + } + }, + + /** + * The directories to delete when `grunt clean` is executed. + */ + clean: [ + '<%= build_dir %>', + '<%= compile_dir %>' + ], + + /** + * The `copy` task just copies files from A to B. We use it here to copy + * our project assets (images, fonts, etc.) and javascripts into + * `build_dir`, and then to copy the assets to `compile_dir`. + */ + copy: { + build_app_assets: { + files: [ + { + src: [ '**' ], + dest: '<%= build_dir %>/assets/', + cwd: 'src/assets', + expand: true + } + ] + }, + build_vendor_assets: { + files: [ + { + src: [ '<%= vendor_files.assets %>' ], + dest: '<%= build_dir %>/assets/', + cwd: '.', + expand: true, + flatten: true + } + ] + }, + build_appjs: { + files: [ + { + src: [ '<%= app_files.js %>' ], + dest: '<%= build_dir %>/', + cwd: '.', + expand: true + } + ] + }, + copy_template: { + files: [ + { + src: ['<%= app_files.templates %>'], + dest: '<%= build_dir %>/', + cwd: '.', + expand: true + } + ] + }, + build_vendorjs: { + files: [ + { + src: [ '<%= vendor_files.js %>' ], + dest: '<%= build_dir %>/', + cwd: '.', + expand: true + } + ] + }, + build_vendorimages: { + files: [ + { + src: [ '<%= vendor_files.images %>' ], + dest: '<%= build_dir %>/', + cwd: '.', + expand: true + } + ] + }, + build_vendorcss: { + files: [ + { + src: [ '<%= vendor_files.css %>' ], + dest: '<%= build_dir %>', + cwd: '.', + expand: true + } + ] + }, + compile_assets: { + files: [ + { + src: [ '**' ], + dest: '<%= compile_dir %>/assets', + cwd: '<%= build_dir %>/assets', + expand: true + } + ] + }, + + compile_font: { + files: [ + { + src: [ '**' ], + dest: '<%= compile_dir %>/font', + cwd: '<%= build_dir %>/font', + expand: true + } + ] + } + }, + + /** + * `grunt concat` concatenates multiple source files into a single file. + */ + concat: { + /** + * The `build_css` target concatenates compiled CSS and vendor CSS + * together. + */ + build_css: { + src: [ + '<%= vendor_files.css %>', + '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css' + ], + dest: '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css' + }, + /** + * The `compile_js` target is the concatenation of our application source + * code and all specified vendor source code into a single file. + */ + compile_js: { + options: { + banner: '<%= meta.banner %>' + }, + src: [ + '<%= vendor_files.js %>', + 'module.prefix', + '<%= build_dir %>/src/**/*.js', + '<%= html2js.common.dest %>', + '<%= html2js.app.dest %>', + 'module.suffix' + ], + dest: '<%= compile_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.js' + } + }, + + /** + * `ng-min` annotates the sources before minifying. That is, it allows us + * to code without the array syntax. + */ + ngmin: { + compile: { + files: [ + { + src: [ '<%= app_files.js %>' ], + cwd: '<%= build_dir %>', + dest: '<%= build_dir %>', + expand: true + } + ] + } + }, + + /** + * Minify the sources! + */ + uglify: { + compile: { + options: { + banner: '<%= meta.banner %>' + }, + files: { + '<%= concat.compile_js.dest %>': '<%= concat.compile_js.dest %>' + } + } + }, + + /** + * `less` less plugin handles the LESS compilation and minification automatically + * this has been changed to the LESS plugin from recess plugin above because of + * out of memory issues with the original plugin. + */ + + less: { + development: { + options: { + paths: ["assets/css"], + compress: false, + syncImport: true, + strictImports: true + }, + files: { + '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css': '<%= app_files.less %>' + } + }, + production: { + options: { + paths: ["assets/css"], + compress: true, + cleancss: true + }, + files: { + '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css': '<%= app_files.less %>' + } + } + }, + + /** + * `jshint` defines the rules of our linter as well as which files we + * should check. This file, all javascript sources, and all our unit tests + * are linted based on the policies listed in `options`. But we can also + * specify exclusionary patterns by prefixing them with an exclamation + * point (!); this is useful when code comes from a third party but is + * nonetheless inside `src/`. + */ + jshint: { + src: [ + '<%= app_files.js %>' + ], + test: [ + '<%= app_files.jsunit %>' + ], + gruntfile: [ + 'OriginalGruntfile.js' + ], + options: { + curly: true, + immed: true, + newcap: true, + noarg: true, + sub: true, + boss: true, + eqnull: true + }, + globals: {} + }, + + + /** + * HTML2JS is a Grunt plugin that takes all of your template files and + * places them into JavaScript files as strings that are added to + * AngularJS's template cache. This means that the templates too become + * part of the initial payload as one JavaScript file. Neat! + */ + html2js: { + /** + * These are the templates from `src/app`. + */ + app: { + options: { + base: 'src/app' + }, + src: [ '<%= app_files.atpl %>' ], + dest: '<%= build_dir %>/templates-app.js' + }, + + /** + * These are the templates from `src/common`. + */ + common: { + options: { + base: 'src/common' + }, + src: [ '<%= app_files.ctpl %>' ], + dest: '<%= build_dir %>/templates-common.js' + } + }, + + /** + * The Karma configurations. + */ + karma: { + options: { + configFile: '<%= build_dir %>/karma-unit.js' + }, + unit: { + runnerPort: 9102, + background: true, + port: 9877 // IMPORTANT! + }, + continuous: { + singleRun: true + } + }, + + /** + * The `index` task compiles the `index.html` file as a Grunt template. CSS + * and JS files co-exist here but they get split apart later. + */ + index: { + + /** + * During development, we don't want to have wait for compilation, + * concatenation, minification, etc. So to avoid these steps, we simply + * add all script files directly to the `` of `index.html`. The + * `src` property contains the list of included files. + */ + build: { + dir: '<%= build_dir %>', + src: [ + '<%= html2js.common.dest %>', + '<%= html2js.app.dest %>', + '<%= vendor_files.css %>', + '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css' + ] + }, + + /** + * When it is time to have a completely compiled application, we can + * alter the above to include only a single JavaScript and a single CSS + * file. Now we're back! + */ + compile: { + dir: '<%= compile_dir %>', + src: [ + '<%= concat.compile_js.dest %>', + '<%= concat.build_css.dest %>' + //'<%= recess.compile.dest %>' + ] + } + }, + + /** + * This task compiles the karma template so that changes to its file array + * don't have to be managed manually. + */ + karmaconfig: { + unit: { + dir: '<%= build_dir %>', + src: [ + '<%= vendor_files.js %>', + '<%= html2js.app.dest %>', + '<%= html2js.common.dest %>', + '<%= app_files.js_common %>', + '<%= app_files.js_app %>', + '<%= app_files.jsunit %>' + ] + } + }, + connect: { + livereload: { + options: { + port: 9000, + hostname: '0.0.0.0', + middleware: function (connect) { + return [ + mountFolder(connect, 'build'), + lrSnippet + ]; + } + } + }, + dev: { + options: { + hostname: '0.0.0.0', + port: 9000, + base: 'build' + } + }, + prod: { + options: { + port: 9001, + base: 'bin', + keepalive: true + } + } + }, + open: { + dev: { + path: 'http://127.0.0.1:9000/' + }, + prod: { + path: 'http://127.0.0.1:9001/' + } + }, + /** + * And for rapid development, we have a watch set up that checks to see if + * any of the files listed below change, and then to execute the listed + * tasks when they do. This just saves us from having to type "grunt" into + * the command-line every time we want to see what we're working on; we can + * instead just leave "grunt watch" running in a background terminal. Set it + * and forget it, as Ron Popeil used to tell us. + * + * But we don't need the same thing to happen for all the files. + */ + delta: { + /** + * By default, we want the Live Reload to work for all tasks; this is + * overridden in some tasks (like this file) where browser resources are + * unaffected. It runs by default on port 35729, which your browser + * plugin should auto-detect. + */ + options: { + livereload: true + }, + + /** + * When the Gruntfile changes, we just want to lint it. In fact, when + * your Gruntfile changes, it will automatically be reloaded! + */ + gruntfile: { + files: 'OriginalGruntfile.js', + tasks: [ 'jshint:gruntfile' ], + options: { + livereload: false + } + }, + + /** + * When our JavaScript source files change, we want to run lint them and + * run our unit tests. + */ + jssrc: { + files: [ + '<%= app_files.js %>' + ], + tasks: [ 'jshint:src', 'karma:unit:run', 'copy:build_appjs' ] + }, + + /** + * When assets are changed, copy them. Note that this will *not* copy new + * files, so this is probably not very useful. + */ + assets: { + files: [ + 'src/assets/**/*' + ], + tasks: [ 'copy:build_app_assets' ] + }, + + /** + * When index.html changes, we need to compile it. + */ + html: { + files: [ '<%= app_files.html %>' ], + tasks: [ 'index:build' ] + }, + + /** + * When our templates change, we only rewrite the template cache. + */ + tpls: { + files: [ + '<%= app_files.atpl %>', + '<%= app_files.ctpl %>' + ], + tasks: [ 'html2js' ] + }, + + /** + * When the CSS files change, we need to compile and minify them. + */ + less: { + files: [ 'src/**/*.less' ], + tasks: [ 'less:development' ] + }, + + /** + * When a JavaScript unit test file changes, we only want to lint it and + * run the unit tests. We don't want to do any live reloading. + */ + jsunit: { + files: [ + '<%= app_files.jsunit %>' + ], + tasks: [ 'jshint:test', 'karma:unit:run' ], + options: { + livereload: false + } + } + } + }; + + grunt.initConfig( grunt.util._.extend( taskConfig, userConfig ) ); + + /** + * In order to make it safe to just compile or copy *only* what was changed, + * we need to ensure we are starting from a clean, fresh build. So we rename + * the `watch` task to `delta` (that's why the configuration var above is + * `delta`) and then add a new task called `watch` that does a clean build + * before watching for changes. + */ + grunt.renameTask( 'watch', 'delta' ); + grunt.registerTask( 'watch', [ 'build', 'karma:unit', 'delta' ] ); + + grunt.registerTask('live', ['build', 'connect:dev', 'delta']); + /** + * The default task is to build and compile. + */ + grunt.registerTask( 'default', [ 'build', 'compile' ] ); + + /** + * The `build` task gets your app ready to run for development and testing. + */ + grunt.registerTask( 'build', [ + 'clean', 'html2js', 'jshint', 'less:development', + 'concat:build_css', 'copy:build_app_assets', 'copy:build_vendor_assets', + 'copy:build_appjs', 'copy:copy_template', 'copy:build_vendorimages', 'copy:build_vendorjs', 'copy:build_vendorcss', 'karmaconfig', 'index:build' + ]); + + /** + * The `compile` task gets your app ready for deployment by concatenating and + * minifying your code. + */ + grunt.registerTask( 'compile', [ + 'less:production', 'concat:build_css', 'copy:compile_assets', 'ngmin:compile', 'concat:compile_js', 'uglify', 'index:compile' + ]); + + /** + * A utility function to get all app JavaScript sources. + */ + function filterForJS ( files ) { + return files.filter( function ( file ) { + return file.match( /\.js$/ ); + }); + } + + /** + * A utility function to get all app CSS sources. + */ + function filterForCSS ( files ) { + return files.filter( function ( file ) { + return file.match( /\.css$/ ); + }); + } + + /** + * The index.html template includes the stylesheet and javascript sources + * based on dynamic names calculated in this Gruntfile. This task assembles + * the list into variables for the template to use and then runs the + * compilation. + */ + grunt.registerMultiTask( 'index', 'Process index.html template', function () { + var dirRE = new RegExp( '^('+grunt.config('build_dir')+'|'+grunt.config('compile_dir')+')\/', 'g' ); + var jsFiles = filterForJS( this.filesSrc ).map( function ( file ) { + return file.replace( dirRE, '' ); + }); + var cssFiles = filterForCSS( this.filesSrc ).map( function ( file ) { + return file.replace( dirRE, '' ); + }); + + grunt.file.copy('src/index.html', this.data.dir + '/index.html', { + process: function ( contents, path ) { + return grunt.template.process( contents, { + data: { + scripts: jsFiles, + styles: cssFiles, + version: grunt.config( 'pkg.version' ) + } + }); + } + }); + + grunt.file.copy('src/login.html', this.data.dir + '/login.html', { + process: function ( contents, path ) { + return grunt.template.process( contents, { + data: { + scripts: jsFiles, + styles: cssFiles, + version: grunt.config( 'pkg.version' ) + } + }); + } + }); + }); + + /** + * In order to avoid having to specify manually the files needed for karma to + * run, we use grunt to manage the list for us. The `karma/*` files are + * compiled as grunt templates for use by Karma. Yay! + */ + grunt.registerMultiTask( 'karmaconfig', 'Process karma config templates', function () { + var jsFiles = filterForJS( this.filesSrc ); + + grunt.file.copy( 'karma/karma-unit.tpl.js', grunt.config( 'build_dir' ) + '/karma-unit.js', { + process: function ( contents, path ) { + return grunt.template.process( contents, { + data: { + scripts: jsFiles + } + }); + } + }); + }); + +};