0
0
mirror of https://github.com/twbs/bootstrap.git synced 2024-11-29 11:24:18 +01:00
Bootstrap/Gruntfile.js

339 lines
9.3 KiB
JavaScript
Raw Normal View History

2014-01-21 01:00:52 +01:00
/*!
* Bootstrap's Gruntfile
* https://getbootstrap.com
2016-12-31 16:20:11 +01:00
* Copyright 2013-2017 The Bootstrap Authors
* Copyright 2013-2017 Twitter, Inc.
2014-01-21 01:00:52 +01:00
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
2013-12-07 01:51:59 +01:00
module.exports = function (grunt) {
'use strict'
// Force use of Unix newlines
grunt.util.linefeed = '\n'
2013-12-08 11:24:47 +01:00
RegExp.quote = function (string) {
return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&')
}
var path = require('path')
var isTravis = require('is-travis')
2014-12-10 22:51:43 +01:00
var configBridge = grunt.file.readJSON('./grunt/configBridge.json', { encoding: 'utf8' })
Object.keys(configBridge.paths).forEach(function (key) {
configBridge.paths[key].forEach(function (val, i, arr) {
arr[i] = path.join('./docs', val)
})
})
// Project configuration.
grunt.initConfig({
// Metadata.
pkg: grunt.file.readJSON('package.json'),
banner: '/*!\n' +
2014-01-28 12:16:13 +01:00
' * Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' +
' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
' * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n' +
2014-01-28 12:16:13 +01:00
' */\n',
jqueryCheck: 'if (typeof jQuery === \'undefined\') {\n' +
' throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\\\'s JavaScript.\')\n' +
'}\n',
jqueryVersionCheck: '+function ($) {\n' +
' var version = $.fn.jquery.split(\' \')[0].split(\'.\')\n' +
' if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] >= 4)) {\n' +
' throw new Error(\'Bootstrap\\\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0\')\n' +
' }\n' +
'}(jQuery);\n\n',
// Task configuration.
clean: {
dist: 'dist',
docs: 'docs/dist'
},
// JS build configuration
2015-05-07 21:48:22 +02:00
babel: {
2015-05-13 21:48:34 +02:00
dev: {
options: {
sourceMap: true
},
2015-05-07 21:48:22 +02:00
files: {
2015-05-11 21:05:35 +02:00
'js/dist/util.js' : 'js/src/util.js',
'js/dist/alert.js' : 'js/src/alert.js',
'js/dist/button.js' : 'js/src/button.js',
'js/dist/carousel.js' : 'js/src/carousel.js',
'js/dist/collapse.js' : 'js/src/collapse.js',
'js/dist/dropdown.js' : 'js/src/dropdown.js',
'js/dist/modal.js' : 'js/src/modal.js',
2015-05-11 21:29:06 +02:00
'js/dist/scrollspy.js' : 'js/src/scrollspy.js',
'js/dist/tab.js' : 'js/src/tab.js',
2015-05-12 23:28:11 +02:00
'js/dist/tooltip.js' : 'js/src/tooltip.js',
'js/dist/popover.js' : 'js/src/popover.js'
2015-05-07 21:48:22 +02:00
}
},
dist: {
options: {
extends: '../../js/.babelrc'
},
files: {
'<%= concat.bootstrap.dest %>' : '<%= concat.bootstrap.dest %>'
}
}
},
2013-08-08 08:06:29 +02:00
stamp: {
options: {
banner: '<%= banner %>\n<%= jqueryCheck %>\n<%= jqueryVersionCheck %>\n+function () {\n',
footer: '\n}();'
},
bootstrap: {
files: {
src: '<%= concat.bootstrap.dest %>'
}
}
},
2013-08-08 08:06:29 +02:00
concat: {
2014-06-15 16:41:24 +02:00
options: {
// Custom function to remove all export and import statements
process: function (src) {
return src.replace(/^(export|import).*/gm, '')
}
2014-06-15 16:41:24 +02:00
},
bootstrap: {
2015-01-03 22:58:44 +01:00
src: [
'js/src/util.js',
'js/src/alert.js',
'js/src/button.js',
'js/src/carousel.js',
'js/src/collapse.js',
'js/src/dropdown.js',
'js/src/modal.js',
'js/src/scrollspy.js',
'js/src/tab.js',
'js/src/tooltip.js',
'js/src/popover.js'
2015-01-03 22:58:44 +01:00
],
dest: 'dist/js/<%= pkg.name %>.js'
2015-01-03 22:58:44 +01:00
}
},
2014-03-10 00:09:36 +01:00
qunit: {
options: {
inject: 'js/tests/unit/phantom.js'
},
files: 'js/tests/index.html'
},
// CSS build configuration
2013-08-18 09:36:51 +02:00
copy: {
2013-12-31 20:38:32 +01:00
docs: {
2015-02-20 10:22:06 +01:00
expand: true,
cwd: 'dist/',
src: [
'**/*'
],
dest: 'docs/dist/'
2013-08-18 09:36:51 +02:00
}
},
connect: {
server: {
options: {
port: 3000,
base: '.'
}
}
},
jekyll: {
options: {
2015-08-25 07:43:47 +02:00
bundleExec: true,
2015-10-28 06:20:47 +01:00
config: '_config.yml',
incremental: false
},
docs: {},
github: {
options: {
raw: 'github: true'
}
}
},
watch: {
src: {
files: '<%= concat.bootstrap.src %>',
2015-05-13 21:48:34 +02:00
tasks: ['babel:dev']
},
sass: {
files: 'scss/**/*.scss',
2015-08-13 05:14:14 +02:00
tasks: ['dist-css', 'docs']
},
docs: {
files: 'docs/assets/scss/**/*.scss',
tasks: ['dist-css', 'docs']
}
},
'saucelabs-qunit': {
all: {
options: {
build: process.env.TRAVIS_JOB_ID,
concurrency: 10,
maxRetries: 3,
maxPollRetries: 4,
urls: ['http://127.0.0.1:3000/js/tests/index.html?hidepassed'],
browsers: grunt.file.readYAML('grunt/sauce_browsers.yml')
}
}
2014-01-20 22:06:13 +01:00
},
exec: {
2016-12-23 05:02:54 +01:00
'clean-css': {
command: 'npm run clean-css'
},
'clean-css-docs': {
command: 'npm run clean-css-docs'
},
postcss: {
command: 'npm run postcss'
},
'postcss-docs': {
command: 'npm run postcss-docs'
},
htmlhint: {
command: 'npm run htmlhint'
2016-12-21 07:38:32 +01:00
},
2017-01-23 10:38:34 +01:00
htmllint: {
command: 'npm run htmllint'
},
sass: {
command: 'npm run sass'
},
'sass-docs': {
command: 'npm run sass-docs'
},
2016-12-21 07:38:32 +01:00
'scss-lint': {
command: 'npm run scss-lint'
},
'scss-lint-docs': {
command: 'npm run scss-lint-docs'
2016-12-23 13:43:46 +01:00
},
uglify: {
command: 'npm run uglify'
},
'uglify-docs': {
command: 'npm run uglify-docs'
}
2015-08-19 07:47:26 +02:00
},
buildcontrol: {
options: {
dir: '_gh_pages',
commit: true,
push: true,
message: 'Built %sourceName% from commit %sourceCommit% on branch %sourceBranch%'
},
pages: {
options: {
remote: 'git@github.com:twbs/derpstrap.git',
branch: 'gh-pages'
}
}
},
compress: {
main: {
options: {
archive: 'bootstrap-<%= pkg.version %>-dist.zip',
mode: 'zip',
level: 9,
pretty: true
},
files: [
{
expand: true,
cwd: 'dist/',
src: ['**'],
dest: 'bootstrap-<%= pkg.version %>-dist'
}
]
}
}
})
// These plugins provide necessary tasks.
require('load-grunt-tasks')(grunt)
require('time-grunt')(grunt)
// Docs HTML validation task
2017-01-23 10:38:34 +01:00
grunt.registerTask('validate-html', ['jekyll:docs', 'exec:htmllint', 'exec:htmlhint'])
2014-05-19 00:52:42 +02:00
var runSubset = function (subset) {
return !process.env.TWBS_TEST || process.env.TWBS_TEST === subset
}
var isUndefOrNonZero = function (val) {
return val === undefined || val !== '0'
}
2014-05-19 00:52:42 +02:00
// Test task.
var testSubtasks = []
// Skip core tests if running a different subset of the test suite
2014-11-20 00:43:23 +01:00
if (runSubset('core') &&
2014-12-01 05:29:47 +01:00
// Skip core tests if this is a Savage build
process.env.TRAVIS_REPO_SLUG !== 'twbs-savage/bootstrap') {
testSubtasks = testSubtasks.concat(['dist-css', 'dist-js', 'test-scss', 'qunit', 'docs'])
}
// Skip HTML validation if running a different subset of the test suite
if (runSubset('validate-html') &&
isTravis &&
// Skip HTML5 validator when [skip validator] is in the commit message
isUndefOrNonZero(process.env.TWBS_DO_VALIDATOR)) {
testSubtasks.push('validate-html')
}
// Only run Sauce Labs tests if there's a Sauce access key
2014-01-17 20:51:53 +01:00
if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' &&
// Skip Sauce if running a different subset of the test suite
runSubset('sauce-js-unit')) {
testSubtasks = testSubtasks.concat(['dist', 'docs-css', 'docs-js', 'clean:docs', 'copy:docs'])
// Skip Sauce on Travis when [skip sauce] is in the commit message
if (isUndefOrNonZero(process.env.TWBS_DO_SAUCE)) {
testSubtasks.push('connect')
testSubtasks.push('saucelabs-qunit')
}
2013-08-06 09:39:35 +02:00
}
grunt.registerTask('test', testSubtasks)
// JS distribution task.
grunt.registerTask('dist-js', ['babel:dev', 'concat', 'babel:dist', 'stamp', 'exec:uglify'])
grunt.registerTask('test-scss', ['exec:scss-lint'])
2014-12-09 04:02:25 +01:00
// CSS distribution task.
grunt.registerTask('sass-compile', ['exec:sass', 'exec:sass-docs'])
grunt.registerTask('dist-css', ['sass-compile', 'exec:postcss', 'exec:clean-css', 'exec:clean-css-docs'])
2013-08-18 09:36:51 +02:00
// Full distribution task.
grunt.registerTask('dist', ['clean:dist', 'dist-css', 'dist-js'])
// Default task.
grunt.registerTask('default', ['clean:dist', 'test'])
2013-08-08 08:06:29 +02:00
// Docs task.
grunt.registerTask('docs-css', ['exec:clean-css-docs', 'exec:postcss-docs'])
grunt.registerTask('lint-docs-css', ['exec:scss-lint-docs'])
grunt.registerTask('docs-js', ['exec:uglify-docs'])
grunt.registerTask('docs', ['lint-docs-css', 'docs-css', 'docs-js', 'clean:docs', 'copy:docs'])
grunt.registerTask('docs-github', ['jekyll:github'])
grunt.registerTask('prep-release', ['dist', 'docs', 'docs-github', 'compress'])
2015-08-19 07:49:26 +02:00
// Publish to GitHub
grunt.registerTask('publish', ['buildcontrol:pages'])
}