|
| 1 | +/*global module:false*/ |
| 2 | +module.exports = function (grunt) { |
| 3 | + |
| 4 | + require('load-grunt-tasks')(grunt); |
| 5 | + var files = require('./files').files; |
| 6 | + |
| 7 | + // Project configuration. |
| 8 | + grunt.initConfig({ |
| 9 | + builddir: 'build', |
| 10 | + pkg: grunt.file.readJSON('package.json'), |
| 11 | + buildtag: '-dev-' + grunt.template.today('yyyy-mm-dd'), |
| 12 | + meta: { |
| 13 | + banner: '/**\n' + |
| 14 | + ' * <%= pkg.description %>\n' + |
| 15 | + ' * @version v<%= pkg.version %><%= buildtag %>\n' + |
| 16 | + ' * @link <%= pkg.homepage %>\n' + |
| 17 | + ' * @license MIT License, http://www.opensource.org/licenses/MIT\n' + |
| 18 | + ' */' |
| 19 | + }, |
| 20 | + clean: [ '<%= builddir %>' ], |
| 21 | + concat: { |
| 22 | + options: { |
| 23 | + banner: '<%= meta.banner %>\n\n'+ |
| 24 | + '/* commonjs package manager support (eg componentjs) */\n'+ |
| 25 | + 'if (typeof module !== "undefined" && typeof exports !== "undefined" && module.exports === exports){\n'+ |
| 26 | + ' module.exports = \'ui.router\';\n'+ |
| 27 | + '}\n\n'+ |
| 28 | + '(function (window, angular, undefined) {\n', |
| 29 | + footer: '})(window, window.angular);' |
| 30 | + }, |
| 31 | + build: { |
| 32 | + src: files.src, |
| 33 | + dest: '<%= builddir %>/<%= pkg.name %>.js' |
| 34 | + } |
| 35 | + }, |
| 36 | + uglify: { |
| 37 | + options: { |
| 38 | + banner: '<%= meta.banner %>\n' |
| 39 | + }, |
| 40 | + build: { |
| 41 | + files: { |
| 42 | + '<%= builddir %>/<%= pkg.name %>.min.js': ['<banner:meta.banner>', '<%= concat.build.dest %>'] |
| 43 | + } |
| 44 | + } |
| 45 | + }, |
| 46 | + release: { |
| 47 | + files: ['<%= pkg.name %>.js', '<%= pkg.name %>.min.js'], |
| 48 | + src: '<%= builddir %>', |
| 49 | + dest: 'release' |
| 50 | + }, |
| 51 | + jshint: { |
| 52 | + all: ['Gruntfile.js', 'src/*.js', '<%= builddir %>/<%= pkg.name %>.js'], |
| 53 | + options: { |
| 54 | + eqnull: true |
| 55 | + } |
| 56 | + }, |
| 57 | + watch: { |
| 58 | + files: ['src/*.js', 'test/**/*.js'], |
| 59 | + tasks: ['build', 'karma:background:run'] |
| 60 | + }, |
| 61 | + connect: { |
| 62 | + server: {}, |
| 63 | + sample: { |
| 64 | + options:{ |
| 65 | + port: 5555, |
| 66 | + keepalive: true |
| 67 | + } |
| 68 | + } |
| 69 | + }, |
| 70 | + karma: { |
| 71 | + options: { |
| 72 | + configFile: 'config/karma.js', |
| 73 | + singleRun: true, |
| 74 | + exclude: [], |
| 75 | + frameworks: ['jasmine'], |
| 76 | + reporters: 'dots', // 'dots' || 'progress' |
| 77 | + port: 8080, |
| 78 | + colors: true, |
| 79 | + autoWatch: false, |
| 80 | + autoWatchInterval: 0, |
| 81 | + browsers: [ grunt.option('browser') || 'PhantomJS' ] |
| 82 | + }, |
| 83 | + unit: { |
| 84 | + browsers: [ grunt.option('browser') || 'PhantomJS' ] |
| 85 | + }, |
| 86 | + debug: { |
| 87 | + singleRun: false, |
| 88 | + background: false, |
| 89 | + browsers: [ grunt.option('browser') || 'Chrome' ] |
| 90 | + }, |
| 91 | + past: { |
| 92 | + configFile: 'config/karma-1.0.8.js' |
| 93 | + }, |
| 94 | + unstable: { |
| 95 | + configFile: 'config/karma-1.1.5.js' |
| 96 | + } |
| 97 | + }, |
| 98 | + changelog: { |
| 99 | + options: { |
| 100 | + dest: 'CHANGELOG.md' |
| 101 | + } |
| 102 | + }, |
| 103 | + ngdocs: { |
| 104 | + options: { |
| 105 | + dest: 'site', |
| 106 | + html5Mode: false, |
| 107 | + title: 'UI Router', |
| 108 | + startPage: '/api', |
| 109 | + }, |
| 110 | + api: { |
| 111 | + src: ['src/**/*.js'], |
| 112 | + title: 'API Reference' |
| 113 | + } |
| 114 | + } |
| 115 | + }); |
| 116 | + |
| 117 | + grunt.registerTask('integrate', ['build', 'jshint', 'karma:unit', 'karma:past', 'karma:unstable']); |
| 118 | + grunt.registerTask('default', ['build', 'jshint', 'karma:unit']); |
| 119 | + grunt.registerTask('build', 'Perform a normal build', ['concat', 'uglify']); |
| 120 | + grunt.registerTask('dist', 'Perform a clean build and generate documentation', ['clean', 'build', 'ngdocs']); |
| 121 | + grunt.registerTask('release', 'Tag and perform a release', ['prepare-release', 'dist', 'perform-release']); |
| 122 | + grunt.registerTask('dev', 'Run dev server and watch for changes', ['build', 'connect:server', 'karma:background', 'watch']); |
| 123 | + grunt.registerTask('sample', 'Run connect server with keepalive:true for sample app development', ['connect:sample']); |
| 124 | + |
| 125 | + grunt.registerTask('publish-pages', 'Publish a clean build, docs, and sample to github.io', function () { |
| 126 | + promising(this, |
| 127 | + ensureCleanMaster().then(function () { |
| 128 | + shjs.rm('-rf', 'build'); |
| 129 | + return system('git checkout gh-pages'); |
| 130 | + }).then(function () { |
| 131 | + return system('git merge master'); |
| 132 | + }).then(function () { |
| 133 | + return system('grunt dist'); |
| 134 | + }).then(function () { |
| 135 | + return system('git commit -a -m \'Automatic gh-pages build\''); |
| 136 | + }).then(function () { |
| 137 | + return system('git checkout master'); |
| 138 | + }) |
| 139 | + ); |
| 140 | + }); |
| 141 | + |
| 142 | + grunt.registerTask('prepare-release', function () { |
| 143 | + var bower = grunt.file.readJSON('bower.json'), |
| 144 | + component = grunt.file.readJSON('component.json'), |
| 145 | + version = bower.version; |
| 146 | + if (version != grunt.config('pkg.version')) throw 'Version mismatch in bower.json'; |
| 147 | + if (version != component.version) throw 'Version mismatch in component.json'; |
| 148 | + |
| 149 | + promising(this, |
| 150 | + ensureCleanMaster().then(function () { |
| 151 | + return exec('git tag -l \'' + version + '\''); |
| 152 | + }).then(function (result) { |
| 153 | + if (result.stdout.trim() !== '') throw 'Tag \'' + version + '\' already exists'; |
| 154 | + grunt.config('buildtag', ''); |
| 155 | + grunt.config('builddir', 'release'); |
| 156 | + }) |
| 157 | + ); |
| 158 | + }); |
| 159 | + |
| 160 | + grunt.registerTask('perform-release', function () { |
| 161 | + grunt.task.requires([ 'prepare-release', 'dist' ]); |
| 162 | + |
| 163 | + var version = grunt.config('pkg.version'), releasedir = grunt.config('builddir'); |
| 164 | + promising(this, |
| 165 | + system('git add \'' + releasedir + '\'').then(function () { |
| 166 | + return system('git commit -m \'release ' + version + '\''); |
| 167 | + }).then(function () { |
| 168 | + return system('git tag \'' + version + '\''); |
| 169 | + }) |
| 170 | + ); |
| 171 | + }); |
| 172 | + |
| 173 | + |
| 174 | + // Helpers for custom tasks, mainly around promises / exec |
| 175 | + var exec = require('faithful-exec'), shjs = require('shelljs'); |
| 176 | + |
| 177 | + function system(cmd) { |
| 178 | + grunt.log.write('% ' + cmd + '\n'); |
| 179 | + return exec(cmd).then(function (result) { |
| 180 | + grunt.log.write(result.stderr + result.stdout); |
| 181 | + }, function (error) { |
| 182 | + grunt.log.write(error.stderr + '\n'); |
| 183 | + throw 'Failed to run \'' + cmd + '\''; |
| 184 | + }); |
| 185 | + } |
| 186 | + |
| 187 | + function promising(task, promise) { |
| 188 | + var done = task.async(); |
| 189 | + promise.then(function () { |
| 190 | + done(); |
| 191 | + }, function (error) { |
| 192 | + grunt.log.write(error + '\n'); |
| 193 | + done(false); |
| 194 | + }); |
| 195 | + } |
| 196 | + |
| 197 | + function ensureCleanMaster() { |
| 198 | + return exec('git symbolic-ref HEAD').then(function (result) { |
| 199 | + if (result.stdout.trim() !== 'refs/heads/master') throw 'Not on master branch, aborting'; |
| 200 | + return exec('git status --porcelain'); |
| 201 | + }).then(function (result) { |
| 202 | + if (result.stdout.trim() !== '') throw 'Working copy is dirty, aborting'; |
| 203 | + }); |
| 204 | + } |
| 205 | +}; |
0 commit comments