github.com/kayoticsully/syncthing@v0.8.9-0.20140724133906-c45a2fdc03f8/assets/bootstrap-3.1.1/Gruntfile.js (about) 1 /*! 2 * Bootstrap's Gruntfile 3 * http://getbootstrap.com 4 * Copyright 2013-2014 Twitter, Inc. 5 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 */ 7 8 module.exports = function (grunt) { 9 'use strict'; 10 11 // Force use of Unix newlines 12 grunt.util.linefeed = '\n'; 13 14 RegExp.quote = function (string) { 15 return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&'); 16 }; 17 18 var fs = require('fs'); 19 var path = require('path'); 20 var generateGlyphiconsData = require('./grunt/bs-glyphicons-data-generator.js'); 21 var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js'); 22 var generateRawFilesJs = require('./grunt/bs-raw-files-generator.js'); 23 var updateShrinkwrap = require('./grunt/shrinkwrap.js'); 24 25 // Project configuration. 26 grunt.initConfig({ 27 28 // Metadata. 29 pkg: grunt.file.readJSON('package.json'), 30 banner: '/*!\n' + 31 ' * Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' + 32 ' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' + 33 ' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' + 34 ' */\n', 35 jqueryCheck: 'if (typeof jQuery === \'undefined\') { throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery\') }\n\n', 36 37 // Task configuration. 38 clean: { 39 dist: ['dist', 'docs/dist'] 40 }, 41 42 jshint: { 43 options: { 44 jshintrc: 'js/.jshintrc' 45 }, 46 grunt: { 47 options: { 48 jshintrc: 'grunt/.jshintrc' 49 }, 50 src: ['Gruntfile.js', 'grunt/*.js'] 51 }, 52 src: { 53 src: 'js/*.js' 54 }, 55 test: { 56 src: 'js/tests/unit/*.js' 57 }, 58 assets: { 59 src: ['docs/assets/js/application.js', 'docs/assets/js/customizer.js'] 60 } 61 }, 62 63 jscs: { 64 options: { 65 config: 'js/.jscs.json', 66 }, 67 grunt: { 68 src: ['Gruntfile.js', 'grunt/*.js'] 69 }, 70 src: { 71 src: 'js/*.js' 72 }, 73 test: { 74 src: 'js/tests/unit/*.js' 75 }, 76 assets: { 77 src: ['docs/assets/js/application.js', 'docs/assets/js/customizer.js'] 78 } 79 }, 80 81 csslint: { 82 options: { 83 csslintrc: 'less/.csslintrc' 84 }, 85 src: [ 86 'dist/css/bootstrap.css', 87 'dist/css/bootstrap-theme.css', 88 'docs/assets/css/docs.css', 89 'docs/examples/**/*.css' 90 ] 91 }, 92 93 concat: { 94 options: { 95 banner: '<%= banner %>\n<%= jqueryCheck %>', 96 stripBanners: false 97 }, 98 bootstrap: { 99 src: [ 100 'js/transition.js', 101 'js/alert.js', 102 'js/button.js', 103 'js/carousel.js', 104 'js/collapse.js', 105 'js/dropdown.js', 106 'js/modal.js', 107 'js/tooltip.js', 108 'js/popover.js', 109 'js/scrollspy.js', 110 'js/tab.js', 111 'js/affix.js' 112 ], 113 dest: 'dist/js/<%= pkg.name %>.js' 114 } 115 }, 116 117 uglify: { 118 options: { 119 report: 'min' 120 }, 121 bootstrap: { 122 options: { 123 banner: '<%= banner %>' 124 }, 125 src: '<%= concat.bootstrap.dest %>', 126 dest: 'dist/js/<%= pkg.name %>.min.js' 127 }, 128 customize: { 129 options: { 130 preserveComments: 'some' 131 }, 132 src: [ 133 'docs/assets/js/vendor/less.min.js', 134 'docs/assets/js/vendor/jszip.min.js', 135 'docs/assets/js/vendor/uglify.min.js', 136 'docs/assets/js/vendor/blob.js', 137 'docs/assets/js/vendor/filesaver.js', 138 'docs/assets/js/raw-files.min.js', 139 'docs/assets/js/customizer.js' 140 ], 141 dest: 'docs/assets/js/customize.min.js' 142 }, 143 docsJs: { 144 options: { 145 preserveComments: 'some' 146 }, 147 src: [ 148 'docs/assets/js/vendor/holder.js', 149 'docs/assets/js/application.js' 150 ], 151 dest: 'docs/assets/js/docs.min.js' 152 } 153 }, 154 155 less: { 156 compileCore: { 157 options: { 158 strictMath: true, 159 sourceMap: true, 160 outputSourceFiles: true, 161 sourceMapURL: '<%= pkg.name %>.css.map', 162 sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map' 163 }, 164 files: { 165 'dist/css/<%= pkg.name %>.css': 'less/bootstrap.less' 166 } 167 }, 168 compileTheme: { 169 options: { 170 strictMath: true, 171 sourceMap: true, 172 outputSourceFiles: true, 173 sourceMapURL: '<%= pkg.name %>-theme.css.map', 174 sourceMapFilename: 'dist/css/<%= pkg.name %>-theme.css.map' 175 }, 176 files: { 177 'dist/css/<%= pkg.name %>-theme.css': 'less/theme.less' 178 } 179 }, 180 minify: { 181 options: { 182 cleancss: true, 183 report: 'min' 184 }, 185 files: { 186 'dist/css/<%= pkg.name %>.min.css': 'dist/css/<%= pkg.name %>.css', 187 'dist/css/<%= pkg.name %>-theme.min.css': 'dist/css/<%= pkg.name %>-theme.css' 188 } 189 } 190 }, 191 192 cssmin: { 193 compress: { 194 options: { 195 keepSpecialComments: '*', 196 noAdvanced: true, // turn advanced optimizations off until the issue is fixed in clean-css 197 report: 'min', 198 selectorsMergeMode: 'ie8' 199 }, 200 src: [ 201 'docs/assets/css/docs.css', 202 'docs/assets/css/pygments-manni.css' 203 ], 204 dest: 'docs/assets/css/docs.min.css' 205 } 206 }, 207 208 usebanner: { 209 dist: { 210 options: { 211 position: 'top', 212 banner: '<%= banner %>' 213 }, 214 files: { 215 src: [ 216 'dist/css/<%= pkg.name %>.css', 217 'dist/css/<%= pkg.name %>.min.css', 218 'dist/css/<%= pkg.name %>-theme.css', 219 'dist/css/<%= pkg.name %>-theme.min.css' 220 ] 221 } 222 } 223 }, 224 225 csscomb: { 226 options: { 227 config: 'less/.csscomb.json' 228 }, 229 dist: { 230 files: { 231 'dist/css/<%= pkg.name %>.css': 'dist/css/<%= pkg.name %>.css', 232 'dist/css/<%= pkg.name %>-theme.css': 'dist/css/<%= pkg.name %>-theme.css' 233 } 234 }, 235 examples: { 236 expand: true, 237 cwd: 'docs/examples/', 238 src: ['**/*.css'], 239 dest: 'docs/examples/' 240 } 241 }, 242 243 copy: { 244 fonts: { 245 expand: true, 246 src: 'fonts/*', 247 dest: 'dist/' 248 }, 249 docs: { 250 expand: true, 251 cwd: './dist', 252 src: [ 253 '{css,js}/*.min.*', 254 'css/*.map', 255 'fonts/*' 256 ], 257 dest: 'docs/dist' 258 } 259 }, 260 261 qunit: { 262 options: { 263 inject: 'js/tests/unit/phantom.js' 264 }, 265 files: 'js/tests/index.html' 266 }, 267 268 connect: { 269 server: { 270 options: { 271 port: 3000, 272 base: '.' 273 } 274 } 275 }, 276 277 jekyll: { 278 docs: {} 279 }, 280 281 jade: { 282 compile: { 283 options: { 284 pretty: true, 285 data: function () { 286 var filePath = path.join(__dirname, 'less/variables.less'); 287 var fileContent = fs.readFileSync(filePath, {encoding: 'utf8'}); 288 var parser = new BsLessdocParser(fileContent); 289 return {sections: parser.parseFile()}; 290 } 291 }, 292 files: { 293 'docs/_includes/customizer-variables.html': 'docs/jade/customizer-variables.jade', 294 'docs/_includes/nav-customize.html': 'docs/jade/customizer-nav.jade' 295 } 296 } 297 }, 298 299 validation: { 300 options: { 301 charset: 'utf-8', 302 doctype: 'HTML5', 303 failHard: true, 304 reset: true, 305 relaxerror: [ 306 'Bad value X-UA-Compatible for attribute http-equiv on element meta.', 307 'Element img is missing required attribute src.' 308 ] 309 }, 310 files: { 311 src: '_gh_pages/**/*.html' 312 } 313 }, 314 315 watch: { 316 src: { 317 files: '<%= jshint.src.src %>', 318 tasks: ['jshint:src', 'qunit'] 319 }, 320 test: { 321 files: '<%= jshint.test.src %>', 322 tasks: ['jshint:test', 'qunit'] 323 }, 324 less: { 325 files: 'less/*.less', 326 tasks: 'less' 327 } 328 }, 329 330 sed: { 331 versionNumber: { 332 pattern: (function () { 333 var old = grunt.option('oldver'); 334 return old ? RegExp.quote(old) : old; 335 })(), 336 replacement: grunt.option('newver'), 337 recursive: true 338 } 339 }, 340 341 'saucelabs-qunit': { 342 all: { 343 options: { 344 build: process.env.TRAVIS_JOB_ID, 345 concurrency: 10, 346 urls: ['http://127.0.0.1:3000/js/tests/index.html'], 347 browsers: grunt.file.readYAML('test-infra/sauce_browsers.yml') 348 } 349 } 350 }, 351 352 exec: { 353 npmUpdate: { 354 command: 'npm update' 355 }, 356 npmShrinkWrap: { 357 command: 'npm shrinkwrap --dev' 358 } 359 } 360 }); 361 362 363 // These plugins provide necessary tasks. 364 require('load-grunt-tasks')(grunt, {scope: 'devDependencies'}); 365 366 // Docs HTML validation task 367 grunt.registerTask('validate-html', ['jekyll', 'validation']); 368 369 // Test task. 370 var testSubtasks = []; 371 // Skip core tests if running a different subset of the test suite 372 if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'core') { 373 testSubtasks = testSubtasks.concat(['dist-css', 'csslint', 'jshint', 'jscs', 'qunit', 'build-customizer-html']); 374 } 375 // Skip HTML validation if running a different subset of the test suite 376 if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'validate-html') { 377 testSubtasks.push('validate-html'); 378 } 379 // Only run Sauce Labs tests if there's a Sauce access key 380 if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' && 381 // Skip Sauce if running a different subset of the test suite 382 (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'sauce-js-unit')) { 383 testSubtasks.push('connect'); 384 testSubtasks.push('saucelabs-qunit'); 385 } 386 grunt.registerTask('test', testSubtasks); 387 388 // JS distribution task. 389 grunt.registerTask('dist-js', ['concat', 'uglify']); 390 391 // CSS distribution task. 392 grunt.registerTask('dist-css', ['less', 'cssmin', 'csscomb', 'usebanner']); 393 394 // Docs distribution task. 395 grunt.registerTask('dist-docs', 'copy:docs'); 396 397 // Full distribution task. 398 grunt.registerTask('dist', ['clean', 'dist-css', 'copy:fonts', 'dist-js', 'dist-docs']); 399 400 // Default task. 401 grunt.registerTask('default', ['test', 'dist', 'build-glyphicons-data', 'build-customizer', 'update-shrinkwrap']); 402 403 // Version numbering task. 404 // grunt change-version-number --oldver=A.B.C --newver=X.Y.Z 405 // This can be overzealous, so its changes should always be manually reviewed! 406 grunt.registerTask('change-version-number', 'sed'); 407 408 grunt.registerTask('build-glyphicons-data', generateGlyphiconsData); 409 410 // task for building customizer 411 grunt.registerTask('build-customizer', ['build-customizer-html', 'build-raw-files']); 412 grunt.registerTask('build-customizer-html', 'jade'); 413 grunt.registerTask('build-raw-files', 'Add scripts/less files to customizer.', function () { 414 var banner = grunt.template.process('<%= banner %>'); 415 generateRawFilesJs(banner); 416 }); 417 418 // Task for updating the npm packages used by the Travis build. 419 grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', 'exec:npmShrinkWrap', '_update-shrinkwrap']); 420 grunt.registerTask('_update-shrinkwrap', function () { updateShrinkwrap.call(this, grunt); }); 421 };