mirror of https://github.com/twbs/bootstrap.git
Replace Makefile with GruntJS
A rebase (against soon-to-be 3.0.0-rc.1) & squash of https://github.com/twbs/bootstrap/pull/7786 AKA https://github.com/twitter/bootstrap/pull/7786 originally by @seriema @mokkabonna @jojohess Rebased by @cvrebert
This commit is contained in:
parent
995add132e
commit
0d33455ef4
|
@ -1,3 +1,5 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 0.6
|
||||
- 0.8
|
||||
before_script:
|
||||
- npm install -g grunt-cli
|
|
@ -0,0 +1,124 @@
|
|||
module.exports = function(grunt) {
|
||||
|
||||
// Project configuration.
|
||||
grunt.initConfig({
|
||||
// Metadata.
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
banner: '/**\n' +
|
||||
'* <%= pkg.name %>.js v<%= pkg.version %> by @fat and @mdo\n' +
|
||||
'* Copyright <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
|
||||
'* <%= _.pluck(pkg.licenses, "url").join(", ") %>\n' +
|
||||
'*/\n',
|
||||
// Task configuration.
|
||||
clean: {
|
||||
dist: ['dist']
|
||||
},
|
||||
concat: {
|
||||
options: {
|
||||
banner: '<%= banner %>',
|
||||
stripBanners: false
|
||||
},
|
||||
bootstrap: {
|
||||
src: ['js/*.js'],
|
||||
dest: 'dist/js/<%= pkg.name %>.js'
|
||||
}
|
||||
},
|
||||
jshint: {
|
||||
options: {
|
||||
jshintrc: 'js/.jshintrc'
|
||||
},
|
||||
gruntfile: {
|
||||
src: 'Gruntfile.js'
|
||||
},
|
||||
src: {
|
||||
src: ['js/*.js']
|
||||
},
|
||||
test: {
|
||||
src: ['js/tests/unit/*.js']
|
||||
}
|
||||
},
|
||||
recess: {
|
||||
options: {
|
||||
compile: true
|
||||
},
|
||||
bootstrap: {
|
||||
files: {
|
||||
'dist/css/bootstrap.css': ['less/bootstrap.less']
|
||||
}
|
||||
},
|
||||
min: {
|
||||
options: {
|
||||
compress: true
|
||||
},
|
||||
files: {
|
||||
'dist/css/bootstrap.min.css': ['less/bootstrap.less']
|
||||
}
|
||||
}
|
||||
},
|
||||
uglify: {
|
||||
options: {
|
||||
banner: '<%= banner %>'
|
||||
},
|
||||
bootstrap: {
|
||||
files: {
|
||||
'dist/js/<%= pkg.name %>.min.js': ['<%= concat.bootstrap.dest %>']
|
||||
}
|
||||
}
|
||||
},
|
||||
qunit: {
|
||||
options: {
|
||||
inject: 'js/tests/unit/phantom.js'
|
||||
},
|
||||
files: ['js/tests/*.html']
|
||||
},
|
||||
connect: {
|
||||
server: {
|
||||
options: {
|
||||
port: 3000,
|
||||
base: '.'
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
src: {
|
||||
files: '<%= jshint.src.src %>',
|
||||
tasks: ['jshint:src', 'qunit']
|
||||
},
|
||||
test: {
|
||||
files: '<%= jshint.test.src %>',
|
||||
tasks: ['jshint:test', 'qunit']
|
||||
},
|
||||
recess: {
|
||||
files: 'less/*.less',
|
||||
tasks: ['recess']
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// These plugins provide necessary tasks.
|
||||
grunt.loadNpmTasks('grunt-contrib-connect');
|
||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-qunit');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-recess');
|
||||
|
||||
|
||||
// Test task.
|
||||
grunt.registerTask('test', ['jshint', 'qunit']);
|
||||
|
||||
// JS distribution task.
|
||||
grunt.registerTask('dist-js', ['concat', 'uglify']);
|
||||
|
||||
// CSS distribution task.
|
||||
grunt.registerTask('dist-css', ['recess']);
|
||||
|
||||
// Full distribution task.
|
||||
grunt.registerTask('dist', ['clean', 'dist-css', 'dist-js']);
|
||||
|
||||
// Default task.
|
||||
grunt.registerTask('default', ['test', 'dist']);
|
||||
};
|
107
Makefile
107
Makefile
|
@ -1,107 +0,0 @@
|
|||
BOOTSTRAP ?= ./dist/css/bootstrap.css
|
||||
BOOTSTRAP_MIN ?= ./dist/css/bootstrap.min.css
|
||||
BOOTSTRAP_LESS ?= ./less/bootstrap.less
|
||||
DATE=$(shell date +%I:%M%p)
|
||||
CHECK=\033[32m✔ Done\033[39m
|
||||
HR=\033[37m--------------------------------------------------\033[39m
|
||||
PATH := ./node_modules/.bin:$(PATH)
|
||||
|
||||
|
||||
#
|
||||
# BUILD DOCS
|
||||
#
|
||||
|
||||
build:
|
||||
@echo "\n\n"
|
||||
@echo "\033[36mBuilding Bootstrap...\033[39m"
|
||||
@echo "${HR}"
|
||||
@printf "Running JSHint on JavaScript..."
|
||||
@jshint js/*.js --config js/.jshintrc
|
||||
@jshint js/tests/unit/*.js --config js/.jshintrc
|
||||
@echo " ${CHECK}"
|
||||
@printf "Compiling LESS with Recess..."
|
||||
@recess --compile ${BOOTSTRAP_LESS} > ${BOOTSTRAP}
|
||||
@recess --compress ${BOOTSTRAP_LESS} > ${BOOTSTRAP_MIN}
|
||||
@echo " ${CHECK}"
|
||||
@printf "Prepping documentation assets..."
|
||||
@cp js/tests/vendor/jquery.js assets/js/
|
||||
@echo " ${CHECK}"
|
||||
@printf "Compiling and minifying JavaScript..."
|
||||
@echo "if (!jQuery) { throw new Error(\"Bootstrap requires jQuery\") }\n\n" | cat - js/transition.js js/alert.js js/button.js js/carousel.js js/collapse.js js/dropdown.js js/modal.js js/tooltip.js js/popover.js js/scrollspy.js js/tab.js js/affix.js > dist/js/bootstrap.js
|
||||
@uglifyjs -nc dist/js/bootstrap.js > dist/js/bootstrap.min.tmp.js
|
||||
@echo "/**\n* Bootstrap.js v3.0.0 by @fat & @mdo\n* Copyright 2013 Twitter, Inc.\n* http://www.apache.org/licenses/LICENSE-2.0.txt\n*/" > dist/js/copyright.js
|
||||
@cat dist/js/copyright.js dist/js/bootstrap.min.tmp.js > dist/js/bootstrap.min.js
|
||||
@rm dist/js/copyright.js dist/js/bootstrap.min.tmp.js
|
||||
@echo " ${CHECK}"
|
||||
@echo "${HR}"
|
||||
@echo "\033[36mSuccess!\n\033[39m"
|
||||
@echo "\033[37mThanks for using Bootstrap,"
|
||||
@echo "<3 @mdo and @fat\n\033[39m"
|
||||
|
||||
#
|
||||
# RUN JSHINT & QUNIT TESTS IN PHANTOMJS
|
||||
#
|
||||
|
||||
test:
|
||||
jshint js/*.js --config js/.jshintrc
|
||||
jshint js/tests/unit/*.js --config js/.jshintrc
|
||||
node js/tests/server.js &
|
||||
phantomjs js/tests/phantom.js "http://localhost:3000/js/tests"
|
||||
kill -9 `cat js/tests/pid.txt`
|
||||
rm js/tests/pid.txt
|
||||
|
||||
#
|
||||
# CLEANS THE ROOT DIRECTORY OF PRIOR BUILDS
|
||||
#
|
||||
|
||||
clean:
|
||||
rm -r bootstrap
|
||||
|
||||
#
|
||||
# BUILD SIMPLE BOOTSTRAP DIRECTORY
|
||||
# recess & uglifyjs are required
|
||||
#
|
||||
|
||||
bootstrap: bootstrap-css bootstrap-js
|
||||
|
||||
|
||||
#
|
||||
# JS COMPILE
|
||||
#
|
||||
bootstrap-js: bootstrap/js/*.js
|
||||
|
||||
bootstrap/js/*.js: js/*.js
|
||||
mkdir -p bootstrap/js
|
||||
cat js/transition.js js/alert.js js/button.js js/carousel.js js/collapse.js js/dropdown.js js/modal.js js/tooltip.js js/popover.js js/scrollspy.js js/tab.js js/affix.js > bootstrap/js/bootstrap.js
|
||||
uglifyjs -nc bootstrap/js/bootstrap.js > bootstrap/js/bootstrap.min.tmp.js
|
||||
echo "/*!\n* Bootstrap.js by @fat & @mdo\n* Copyright 2013 Twitter, Inc.\n* http://www.apache.org/licenses/LICENSE-2.0.txt\n*/" > bootstrap/js/copyright.js
|
||||
cat bootstrap/js/copyright.js bootstrap/js/bootstrap.min.tmp.js > bootstrap/js/bootstrap.min.js
|
||||
rm bootstrap/js/copyright.js bootstrap/js/bootstrap.min.tmp.js
|
||||
|
||||
#
|
||||
# CSS COMPILE
|
||||
#
|
||||
|
||||
bootstrap-css: bootstrap/css/*.css
|
||||
|
||||
bootstrap/css/*.css: less/*.less
|
||||
mkdir -p bootstrap/css
|
||||
recess --compile ${BOOTSTRAP_LESS} > bootstrap/css/bootstrap.css
|
||||
recess --compress ${BOOTSTRAP_LESS} > bootstrap/css/bootstrap.min.css
|
||||
|
||||
#
|
||||
# WATCH LESS FILES
|
||||
#
|
||||
|
||||
watch:
|
||||
echo "Watching less files..."; \
|
||||
watchr -e "watch('less/.*\.less') { system 'make' }"
|
||||
|
||||
#
|
||||
# BUILD AND START SERVER
|
||||
#
|
||||
|
||||
run: build
|
||||
jekyll build && jekyll server
|
||||
|
||||
.PHONY: docs watch gh-pages bootstrap-css bootstrap-js
|
25
README.md
25
README.md
|
@ -46,33 +46,36 @@ Documentation for v2.3.2 has been made available for the time being at [http://g
|
|||
|
||||
## Compiling CSS and JavaScript
|
||||
|
||||
Bootstrap includes a [makefile](Makefile) with convenient methods for working with the framework. Before getting started, install [the necessary local dependencies](package.json):
|
||||
Bootstrap uses [GruntJS](http://gruntjs.com/) with convenient methods for working with the framework. Before getting started, be sure to have `grunt-cli` installed globally (`npm install -g grunt-cli`) and then install [the necessary local dependencies](package.json):
|
||||
|
||||
```
|
||||
# if grunt-cli isn't already installed
|
||||
$ npm install -g grunt-cli
|
||||
|
||||
$ npm install
|
||||
```
|
||||
|
||||
When completed, you'll be able to run the various make commands provided.
|
||||
When completed, you'll be able to run the various grunt commands provided.
|
||||
|
||||
**Unfamiliar with `npm`? Don't have node installed?** That's a-okay. npm stands for [node packaged modules](http://npmjs.org/) and is a way to manage development dependencies through node.js. [Download and install node.js](http://nodejs.org/download/) before proceeding.
|
||||
|
||||
### Available makefile commands
|
||||
### Available grunt commands
|
||||
|
||||
#### Build - `make`
|
||||
`make` runs the Recess compiler to rebuild the `/less` files and compile the docs. **Requires recess and uglify-js.**
|
||||
#### Build - `grunt`
|
||||
`grunt` runs the Recess compiler to rebuild the `/less` files and compile the docs. **Requires recess and uglify-js.**
|
||||
|
||||
#### Compile CSS, JS, and fonts - `make bootstrap`
|
||||
`make bootstrap` creates the `/bootstrap` directory with compiled files. **Requires recess and uglify-js.**
|
||||
#### Compile CSS, JS, and fonts - `grunt bootstrap`
|
||||
`grunt bootstrap` creates the `/bootstrap` directory with compiled files. **Requires recess and uglify-js.**
|
||||
|
||||
#### Tests - `make test`
|
||||
#### Tests - `grunt test`
|
||||
Runs jshint and qunit tests headlessly in [phantomjs](http://code.google.com/p/phantomjs/) (used for ci). **Requires phantomjs.**
|
||||
|
||||
#### Watch - `make watch`
|
||||
This is a convenience method for watching just Less files and automatically building them whenever you save. **Requires the watchr gem.**
|
||||
#### Watch - `grunt watch`
|
||||
This is a convenience method for watching just Less files and automatically building them whenever you save.
|
||||
|
||||
### Troubleshooting dependencies
|
||||
|
||||
Should you encounter problems with installing dependencies or running makefile commands, uninstall all previous dependency versions (global and local). Then, rerun `npm install`.
|
||||
Should you encounter problems with installing dependencies or running grunt commands, uninstall all previous dependency versions (global and local). Then, rerun `npm install`.
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -4668,4 +4668,4 @@ td.visible-print {
|
|||
td.hidden-print {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -11,9 +11,6 @@
|
|||
<link rel="stylesheet" href="vendor/qunit.css" type="text/css" media="screen" />
|
||||
<script src="vendor/qunit.js"></script>
|
||||
|
||||
<!-- phantomjs logging script-->
|
||||
<script src="unit/phantom.js"></script>
|
||||
|
||||
<!-- plugin sources -->
|
||||
<script src="../../js/transition.js"></script>
|
||||
<script src="../../js/alert.js"></script>
|
||||
|
|
|
@ -40,14 +40,15 @@ $(function () {
|
|||
ok(btn.hasClass('disabled'), 'btn has disabled class')
|
||||
start()
|
||||
stop()
|
||||
btn.button('reset')
|
||||
equals(btn.html(), 'mdo', 'btn text equals mdo')
|
||||
setTimeout(function () {
|
||||
ok(!btn.attr('disabled'), 'btn is not disabled')
|
||||
ok(!btn.hasClass('disabled'), 'btn does not have disabled class')
|
||||
start()
|
||||
}, 0)
|
||||
}, 0)
|
||||
btn.button('reset')
|
||||
equals(btn.html(), 'mdo', 'btn text equals mdo')
|
||||
setTimeout(function () {
|
||||
ok(!btn.attr('disabled'), 'btn is not disabled')
|
||||
ok(!btn.hasClass('disabled'), 'btn does not have disabled class')
|
||||
start()
|
||||
}, 0)
|
||||
|
||||
})
|
||||
|
||||
test("should toggle active", function () {
|
||||
|
|
|
@ -1,21 +1,69 @@
|
|||
// Logging setup for phantom integration
|
||||
// adapted from Modernizr
|
||||
/*
|
||||
* grunt-contrib-qunit
|
||||
* http://gruntjs.com/
|
||||
*
|
||||
* Copyright (c) 2013 "Cowboy" Ben Alman, contributors
|
||||
* Licensed under the MIT license.
|
||||
*/
|
||||
|
||||
QUnit.begin = function () {
|
||||
console.log("Starting test suite")
|
||||
console.log("================================================\n")
|
||||
}
|
||||
/*global QUnit:true, alert:true*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
QUnit.moduleDone = function (opts) {
|
||||
if (opts.failed === 0) {
|
||||
console.log("\u2714 All tests passed in '" + opts.name + "' module")
|
||||
} else {
|
||||
console.log("\u2716 " + opts.failed + " tests failed in '" + opts.name + "' module")
|
||||
// Don't re-order tests.
|
||||
QUnit.config.reorder = false
|
||||
// Run tests serially, not in parallel.
|
||||
QUnit.config.autorun = false
|
||||
|
||||
// Send messages to the parent PhantomJS process via alert! Good times!!
|
||||
function sendMessage() {
|
||||
var args = [].slice.call(arguments)
|
||||
alert(JSON.stringify(args))
|
||||
}
|
||||
}
|
||||
|
||||
QUnit.done = function (opts) {
|
||||
console.log("\n================================================")
|
||||
console.log("Tests completed in " + opts.runtime + " milliseconds")
|
||||
console.log(opts.passed + " tests of " + opts.total + " passed, " + opts.failed + " failed.")
|
||||
}
|
||||
// These methods connect QUnit to PhantomJS.
|
||||
QUnit.log = function(obj) {
|
||||
// What is this I don’t even
|
||||
if (obj.message === '[object Object], undefined:undefined') { return }
|
||||
// Parse some stuff before sending it.
|
||||
var actual = QUnit.jsDump.parse(obj.actual)
|
||||
var expected = QUnit.jsDump.parse(obj.expected)
|
||||
// Send it.
|
||||
sendMessage('qunit.log', obj.result, actual, expected, obj.message, obj.source)
|
||||
}
|
||||
|
||||
QUnit.testStart = function(obj) {
|
||||
sendMessage('qunit.testStart', obj.name)
|
||||
}
|
||||
|
||||
QUnit.testDone = function(obj) {
|
||||
sendMessage('qunit.testDone', obj.name, obj.failed, obj.passed, obj.total)
|
||||
}
|
||||
|
||||
QUnit.moduleStart = function(obj) {
|
||||
sendMessage('qunit.moduleStart', obj.name)
|
||||
}
|
||||
|
||||
QUnit.begin = function () {
|
||||
sendMessage('qunit.begin')
|
||||
console.log("Starting test suite")
|
||||
console.log("================================================\n")
|
||||
}
|
||||
|
||||
QUnit.moduleDone = function (opts) {
|
||||
if (opts.failed === 0) {
|
||||
console.log("\r\u2714 All tests passed in '" + opts.name + "' module")
|
||||
} else {
|
||||
console.log("\u2716 " + opts.failed + " tests failed in '" + opts.name + "' module")
|
||||
}
|
||||
sendMessage('qunit.moduleDone', opts.name, opts.failed, opts.passed, opts.total)
|
||||
}
|
||||
|
||||
QUnit.done = function (opts) {
|
||||
console.log("\n================================================")
|
||||
console.log("Tests completed in " + opts.runtime + " milliseconds")
|
||||
console.log(opts.passed + " tests of " + opts.total + " passed, " + opts.failed + " failed.")
|
||||
sendMessage('qunit.done', opts.failed, opts.passed, opts.total, opts.runtime)
|
||||
}
|
||||
|
||||
}())
|
||||
|
|
15
package.json
15
package.json
|
@ -5,7 +5,7 @@
|
|||
, "keywords": ["bootstrap", "css"]
|
||||
, "homepage": "http://twbs.github.com/bootstrap/"
|
||||
, "author": "Twitter Inc."
|
||||
, "scripts": { "test": "make test" }
|
||||
, "scripts": { "test": "grunt test" }
|
||||
, "repository": {
|
||||
"type": "git"
|
||||
, "url": "https://github.com/twbs/bootstrap.git"
|
||||
|
@ -17,9 +17,14 @@
|
|||
}
|
||||
]
|
||||
, "devDependencies": {
|
||||
"uglify-js": "1.3.4"
|
||||
, "jshint": "2.1.2"
|
||||
, "recess": "1.1.7"
|
||||
, "connect": "2.1.3"
|
||||
"grunt": "~0.4.1"
|
||||
, "grunt-contrib-connect": "~0.3.0"
|
||||
, "grunt-contrib-clean": "~0.5.0"
|
||||
, "grunt-contrib-concat": "~0.3.0"
|
||||
, "grunt-contrib-jshint": "~0.6.0"
|
||||
, "grunt-contrib-uglify": "~0.2.2"
|
||||
, "grunt-contrib-qunit": "~0.2.2"
|
||||
, "grunt-contrib-watch": "~0.5.1"
|
||||
, "grunt-recess": "~0.3.3"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue