Policy 1707 commit to LF
[policy/engine.git] / POLICY-SDK-APP / src / main / webapp / app / policyApp / CSS / bootstrap / Gruntfile.js
1 /*!
2  * Bootstrap's Gruntfile
3  * http://getbootstrap.com
4  * Copyright 2013-2015 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 npmShrinkwrap = require('npm-shrinkwrap');
21   var generateGlyphiconsData = require('./grunt/bs-glyphicons-data-generator.js');
22   var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js');
23   var getLessVarsData = function () {
24     var filePath = path.join(__dirname, 'less/variables.less');
25     var fileContent = fs.readFileSync(filePath, { encoding: 'utf8' });
26     var parser = new BsLessdocParser(fileContent);
27     return { sections: parser.parseFile() };
28   };
29   var generateRawFiles = require('./grunt/bs-raw-files-generator.js');
30   var generateCommonJSModule = require('./grunt/bs-commonjs-generator.js');
31   var configBridge = grunt.file.readJSON('./grunt/configBridge.json', { encoding: 'utf8' });
32
33   Object.keys(configBridge.paths).forEach(function (key) {
34     configBridge.paths[key].forEach(function (val, i, arr) {
35       arr[i] = path.join('./docs/assets', val);
36     });
37   });
38
39   // Project configuration.
40   grunt.initConfig({
41
42     // Metadata.
43     pkg: grunt.file.readJSON('package.json'),
44     banner: '/*!\n' +
45             ' * Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' +
46             ' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
47             ' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' +
48             ' */\n',
49     jqueryCheck: configBridge.config.jqueryCheck.join('\n'),
50     jqueryVersionCheck: configBridge.config.jqueryVersionCheck.join('\n'),
51
52     // Task configuration.
53     clean: {
54       dist: 'dist',
55       docs: 'docs/dist'
56     },
57
58     jshint: {
59       options: {
60         jshintrc: 'js/.jshintrc'
61       },
62       grunt: {
63         options: {
64           jshintrc: 'grunt/.jshintrc'
65         },
66         src: ['Gruntfile.js', 'grunt/*.js']
67       },
68       core: {
69         src: 'js/*.js'
70       },
71       test: {
72         options: {
73           jshintrc: 'js/tests/unit/.jshintrc'
74         },
75         src: 'js/tests/unit/*.js'
76       },
77       assets: {
78         src: ['docs/assets/js/src/*.js', 'docs/assets/js/*.js', '!docs/assets/js/*.min.js']
79       }
80     },
81
82     jscs: {
83       options: {
84         config: 'js/.jscsrc'
85       },
86       grunt: {
87         src: '<%= jshint.grunt.src %>'
88       },
89       core: {
90         src: '<%= jshint.core.src %>'
91       },
92       test: {
93         src: '<%= jshint.test.src %>'
94       },
95       assets: {
96         options: {
97           requireCamelCaseOrUpperCaseIdentifiers: null
98         },
99         src: '<%= jshint.assets.src %>'
100       }
101     },
102
103     concat: {
104       options: {
105         banner: '<%= banner %>\n<%= jqueryCheck %>\n<%= jqueryVersionCheck %>',
106         stripBanners: false
107       },
108       bootstrap: {
109         src: [
110           'js/transition.js',
111           'js/alert.js',
112           'js/button.js',
113           'js/carousel.js',
114           'js/collapse.js',
115           'js/dropdown.js',
116           'js/modal.js',
117           'js/tooltip.js',
118           'js/popover.js',
119           'js/scrollspy.js',
120           'js/tab.js',
121           'js/affix.js'
122         ],
123         dest: 'dist/js/<%= pkg.name %>.js'
124       }
125     },
126
127     uglify: {
128       options: {
129         preserveComments: 'some'
130       },
131       core: {
132         src: '<%= concat.bootstrap.dest %>',
133         dest: 'dist/js/<%= pkg.name %>.min.js'
134       },
135       customize: {
136         src: configBridge.paths.customizerJs,
137         dest: 'docs/assets/js/customize.min.js'
138       },
139       docsJs: {
140         src: configBridge.paths.docsJs,
141         dest: 'docs/assets/js/docs.min.js'
142       }
143     },
144
145     qunit: {
146       options: {
147         inject: 'js/tests/unit/phantom.js'
148       },
149       files: 'js/tests/index.html'
150     },
151
152     less: {
153       compileCore: {
154         options: {
155           strictMath: true,
156           sourceMap: true,
157           outputSourceFiles: true,
158           sourceMapURL: '<%= pkg.name %>.css.map',
159           sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map'
160         },
161         src: 'less/bootstrap.less',
162         dest: 'dist/css/<%= pkg.name %>.css'
163       },
164       compileTheme: {
165         options: {
166           strictMath: true,
167           sourceMap: true,
168           outputSourceFiles: true,
169           sourceMapURL: '<%= pkg.name %>-theme.css.map',
170           sourceMapFilename: 'dist/css/<%= pkg.name %>-theme.css.map'
171         },
172         src: 'less/theme.less',
173         dest: 'dist/css/<%= pkg.name %>-theme.css'
174       }
175     },
176
177     autoprefixer: {
178       options: {
179         browsers: configBridge.config.autoprefixerBrowsers
180       },
181       core: {
182         options: {
183           map: true
184         },
185         src: 'dist/css/<%= pkg.name %>.css'
186       },
187       theme: {
188         options: {
189           map: true
190         },
191         src: 'dist/css/<%= pkg.name %>-theme.css'
192       },
193       docs: {
194         src: ['docs/assets/css/anchor.css', 'docs/assets/css/src/docs.css']
195       },
196       examples: {
197         expand: true,
198         cwd: 'docs/examples/',
199         src: ['**/*.css'],
200         dest: 'docs/examples/'
201       }
202     },
203
204     csslint: {
205       options: {
206         csslintrc: 'less/.csslintrc'
207       },
208       dist: [
209         'dist/css/bootstrap.css',
210         'dist/css/bootstrap-theme.css'
211       ],
212       examples: [
213         'docs/examples/**/*.css'
214       ],
215       docs: {
216         options: {
217           ids: false,
218           'overqualified-elements': false
219         },
220         src: 'docs/assets/css/src/docs.css'
221       }
222     },
223
224     cssmin: {
225       options: {
226         // TODO: disable `zeroUnits` optimization once clean-css 3.2 is released
227         //    and then simplify the fix for https://github.com/twbs/bootstrap/issues/14837 accordingly
228         compatibility: 'ie8',
229         keepSpecialComments: '*',
230         advanced: false
231       },
232       minifyCore: {
233         src: 'dist/css/<%= pkg.name %>.css',
234         dest: 'dist/css/<%= pkg.name %>.min.css'
235       },
236       minifyTheme: {
237         src: 'dist/css/<%= pkg.name %>-theme.css',
238         dest: 'dist/css/<%= pkg.name %>-theme.min.css'
239       },
240       docs: {
241         src: [
242           'docs/assets/css/src/pygments-manni.css',
243           'docs/assets/css/src/anchor.css',
244           'docs/assets/css/src/docs.css'
245
246         ],
247         dest: 'docs/assets/css/docs.min.css'
248       }
249     },
250
251     usebanner: {
252       options: {
253         position: 'top',
254         banner: '<%= banner %>'
255       },
256       files: {
257         src: 'dist/css/*.css'
258       }
259     },
260
261     csscomb: {
262       options: {
263         config: 'less/.csscomb.json'
264       },
265       dist: {
266         expand: true,
267         cwd: 'dist/css/',
268         src: ['*.css', '!*.min.css'],
269         dest: 'dist/css/'
270       },
271       examples: {
272         expand: true,
273         cwd: 'docs/examples/',
274         src: '**/*.css',
275         dest: 'docs/examples/'
276       },
277       docs: {
278         src: 'docs/assets/css/src/docs.css',
279         dest: 'docs/assets/css/src/docs.css'
280       }
281     },
282
283     copy: {
284       fonts: {
285         expand: true,
286         src: 'fonts/*',
287         dest: 'dist/'
288       },
289       docs: {
290         expand: true,
291         cwd: 'dist/',
292         src: [
293           '**/*'
294         ],
295         dest: 'docs/dist/'
296       }
297     },
298
299     connect: {
300       server: {
301         options: {
302           port: 3000,
303           base: '.'
304         }
305       }
306     },
307
308     jekyll: {
309       options: {
310         config: '_config.yml'
311       },
312       docs: {},
313       github: {
314         options: {
315           raw: 'github: true'
316         }
317       }
318     },
319
320     jade: {
321       options: {
322         pretty: true,
323         data: getLessVarsData
324       },
325       customizerVars: {
326         src: 'docs/_jade/customizer-variables.jade',
327         dest: 'docs/_includes/customizer-variables.html'
328       },
329       customizerNav: {
330         src: 'docs/_jade/customizer-nav.jade',
331         dest: 'docs/_includes/nav/customize.html'
332       }
333     },
334
335     htmllint: {
336       options: {
337         ignore: [
338           'Attribute "autocomplete" not allowed on element "button" at this point.',
339           'Attribute "autocomplete" not allowed on element "input" at this point.',
340           'Element "img" is missing required attribute "src".'
341         ]
342       },
343       src: '_gh_pages/**/*.html'
344     },
345
346     watch: {
347       src: {
348         files: '<%= jshint.core.src %>',
349         tasks: ['jshint:src', 'qunit', 'concat']
350       },
351       test: {
352         files: '<%= jshint.test.src %>',
353         tasks: ['jshint:test', 'qunit']
354       },
355       less: {
356         files: 'less/**/*.less',
357         tasks: 'less'
358       }
359     },
360
361     sed: {
362       versionNumber: {
363         pattern: (function () {
364           var old = grunt.option('oldver');
365           return old ? RegExp.quote(old) : old;
366         })(),
367         replacement: grunt.option('newver'),
368         recursive: true
369       }
370     },
371
372     'saucelabs-qunit': {
373       all: {
374         options: {
375           build: process.env.TRAVIS_JOB_ID,
376           throttled: 10,
377           maxRetries: 3,
378           maxPollRetries: 4,
379           urls: ['http://127.0.0.1:3000/js/tests/index.html?hidepassed'],
380           browsers: grunt.file.readYAML('grunt/sauce_browsers.yml')
381         }
382       }
383     },
384
385     exec: {
386       npmUpdate: {
387         command: 'npm update'
388       }
389     },
390
391     compress: {
392       main: {
393         options: {
394           archive: 'bootstrap-<%= pkg.version %>-dist.zip',
395           mode: 'zip',
396           level: 9,
397           pretty: true
398         },
399         files: [
400           {
401             expand: true,
402             cwd: 'dist/',
403             src: ['**'],
404             dest: 'bootstrap-<%= pkg.version %>-dist'
405           }
406         ]
407       }
408     }
409
410   });
411
412
413   // These plugins provide necessary tasks.
414   require('load-grunt-tasks')(grunt, { scope: 'devDependencies' });
415   require('time-grunt')(grunt);
416
417   // Docs HTML validation task
418   grunt.registerTask('validate-html', ['jekyll:docs', 'htmllint']);
419
420   var runSubset = function (subset) {
421     return !process.env.TWBS_TEST || process.env.TWBS_TEST === subset;
422   };
423   var isUndefOrNonZero = function (val) {
424     return val === undefined || val !== '0';
425   };
426
427   // Test task.
428   var testSubtasks = [];
429   // Skip core tests if running a different subset of the test suite
430   if (runSubset('core') &&
431       // Skip core tests if this is a Savage build
432       process.env.TRAVIS_REPO_SLUG !== 'twbs-savage/bootstrap') {
433     testSubtasks = testSubtasks.concat(['dist-css', 'dist-js', 'csslint:dist', 'test-js', 'docs']);
434   }
435   // Skip HTML validation if running a different subset of the test suite
436   if (runSubset('validate-html') &&
437       // Skip HTML5 validator on Travis when [skip validator] is in the commit message
438       isUndefOrNonZero(process.env.TWBS_DO_VALIDATOR)) {
439     testSubtasks.push('validate-html');
440   }
441   // Only run Sauce Labs tests if there's a Sauce access key
442   if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' &&
443       // Skip Sauce if running a different subset of the test suite
444       runSubset('sauce-js-unit') &&
445       // Skip Sauce on Travis when [skip sauce] is in the commit message
446       isUndefOrNonZero(process.env.TWBS_DO_SAUCE)) {
447     testSubtasks.push('connect');
448     testSubtasks.push('saucelabs-qunit');
449   }
450   grunt.registerTask('test', testSubtasks);
451   grunt.registerTask('test-js', ['jshint:core', 'jshint:test', 'jshint:grunt', 'jscs:core', 'jscs:test', 'jscs:grunt', 'qunit']);
452
453   // JS distribution task.
454   grunt.registerTask('dist-js', ['concat', 'uglify:core', 'commonjs']);
455
456   // CSS distribution task.
457   grunt.registerTask('less-compile', ['less:compileCore', 'less:compileTheme']);
458   grunt.registerTask('dist-css', ['less-compile', 'autoprefixer:core', 'autoprefixer:theme', 'usebanner', 'csscomb:dist', 'cssmin:minifyCore', 'cssmin:minifyTheme']);
459
460   // Full distribution task.
461   grunt.registerTask('dist', ['clean:dist', 'dist-css', 'copy:fonts', 'dist-js']);
462
463   // Default task.
464   grunt.registerTask('default', ['clean:dist', 'copy:fonts', 'test']);
465
466   // Version numbering task.
467   // grunt change-version-number --oldver=A.B.C --newver=X.Y.Z
468   // This can be overzealous, so its changes should always be manually reviewed!
469   grunt.registerTask('change-version-number', 'sed');
470
471   grunt.registerTask('build-glyphicons-data', function () { generateGlyphiconsData.call(this, grunt); });
472
473   // task for building customizer
474   grunt.registerTask('build-customizer', ['build-customizer-html', 'build-raw-files']);
475   grunt.registerTask('build-customizer-html', 'jade');
476   grunt.registerTask('build-raw-files', 'Add scripts/less files to customizer.', function () {
477     var banner = grunt.template.process('<%= banner %>');
478     generateRawFiles(grunt, banner);
479   });
480
481   grunt.registerTask('commonjs', 'Generate CommonJS entrypoint module in dist dir.', function () {
482     var srcFiles = grunt.config.get('concat.bootstrap.src');
483     var destFilepath = 'dist/js/npm.js';
484     generateCommonJSModule(grunt, srcFiles, destFilepath);
485   });
486
487   // Docs task.
488   grunt.registerTask('docs-css', ['autoprefixer:docs', 'autoprefixer:examples', 'csscomb:docs', 'csscomb:examples', 'cssmin:docs']);
489   grunt.registerTask('lint-docs-css', ['csslint:docs', 'csslint:examples']);
490   grunt.registerTask('docs-js', ['uglify:docsJs', 'uglify:customize']);
491   grunt.registerTask('lint-docs-js', ['jshint:assets', 'jscs:assets']);
492   grunt.registerTask('docs', ['docs-css', 'lint-docs-css', 'docs-js', 'lint-docs-js', 'clean:docs', 'copy:docs', 'build-glyphicons-data', 'build-customizer']);
493
494   grunt.registerTask('prep-release', ['jekyll:github', 'compress']);
495
496   // Task for updating the cached npm packages used by the Travis build (which are controlled by test-infra/npm-shrinkwrap.json).
497   // This task should be run and the updated file should be committed whenever Bootstrap's dependencies change.
498   grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', '_update-shrinkwrap']);
499   grunt.registerTask('_update-shrinkwrap', function () {
500     var done = this.async();
501     npmShrinkwrap({ dev: true, dirname: __dirname }, function (err) {
502       if (err) {
503         grunt.fail.warn(err);
504       }
505       var dest = 'test-infra/npm-shrinkwrap.json';
506       fs.renameSync('npm-shrinkwrap.json', dest);
507       grunt.log.writeln('File ' + dest.cyan + ' updated.');
508       done();
509     });
510   });
511 };