From 5a3f1a90ba37a4d1c090dc1fa59b9f4501481adb Mon Sep 17 00:00:00 2001 From: Chris Rebert Date: Mon, 20 Jan 2014 13:06:13 -0800 Subject: [PATCH] fix #12261 --- .travis.yml | 4 ++-- Gruntfile.js | 30 +++++++++++++++--------- package.json | 2 ++ test-infra/README.md | 2 +- test-infra/npm-shrinkwrap.canonical.json | 1 + test-infra/shrinkwrap.js | 24 +++++++++++++++++++ test-infra/uncached-npm-install.sh | 4 ++++ 7 files changed, 53 insertions(+), 14 deletions(-) create mode 100644 test-infra/npm-shrinkwrap.canonical.json create mode 100644 test-infra/shrinkwrap.js create mode 100755 test-infra/uncached-npm-install.sh diff --git a/.travis.yml b/.travis.yml index 2a7b83a62d..2e080ac1dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,10 +7,10 @@ before_install: - if [ "$TWBS_TEST" = validate-html ]; then echo "ruby=$(basename $(rvm gemdir)) jekyll=$JEKYLL_VERSION" > pseudo_Gemfile.lock; fi install: - time npm install -g grunt-cli - - time ./test-infra/s3_cache.py download 'node.js packages' package.json ./node_modules || time npm install + - time ./test-infra/s3_cache.py download 'npm packages' test-infra/npm-shrinkwrap.canonical.json ./node_modules || time ./test-infra/uncached-npm-install.sh - if [ "$TWBS_TEST" = validate-html ]; then time ./test-infra/s3_cache.py download rubygems pseudo_Gemfile.lock $(rvm gemdir) || gem install -N jekyll -v $JEKYLL_VERSION; fi after_script: - - if [ "$TWBS_TEST" = core ]; then time ./test-infra/s3_cache.py upload 'node.js packages' package.json ./node_modules; fi + - if [ "$TWBS_TEST" = core ]; then time ./test-infra/s3_cache.py upload 'npm packages' test-infra/npm-shrinkwrap.canonical.json ./node_modules; fi - if [ "$TWBS_TEST" = validate-html ]; then time ./test-infra/s3_cache.py upload rubygems pseudo_Gemfile.lock $(rvm gemdir); fi env: global: diff --git a/Gruntfile.js b/Gruntfile.js index eaa9858090..764088fd91 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -21,6 +21,7 @@ module.exports = function (grunt) { var generateGlyphiconsData = require('./docs/grunt/bs-glyphicons-data-generator.js'); var BsLessdocParser = require('./docs/grunt/bs-lessdoc-parser.js'); var generateRawFilesJs = require('./docs/grunt/bs-raw-files-generator.js'); + var updateShrinkwrap = require('./test-infra/shrinkwrap.js'); // Project configuration. grunt.initConfig({ @@ -49,8 +50,8 @@ module.exports = function (grunt) { options: { jshintrc: 'js/.jshintrc' }, - gruntfile: { - src: 'Gruntfile.js' + grunt: { + src: ['Gruntfile.js', 'docs/grunt/*.js', 'test-infra/shrinkwrap.js'] }, src: { src: 'js/*.js' @@ -60,9 +61,6 @@ module.exports = function (grunt) { }, assets: { src: ['docs/assets/js/application.js', 'docs/assets/js/customizer.js'] - }, - docsGrunt: { - src: 'docs/grunt/*.js' } }, @@ -70,8 +68,8 @@ module.exports = function (grunt) { options: { config: 'js/.jscs.json', }, - gruntfile: { - src: 'Gruntfile.js' + grunt: { + src: ['Gruntfile.js', 'docs/grunt/*.js', 'test-infra/shrinkwrap.js'] }, src: { src: 'js/*.js' @@ -81,9 +79,6 @@ module.exports = function (grunt) { }, assets: { src: ['docs/assets/js/application.js', 'docs/assets/js/customizer.js'] - }, - docsGrunt: { - src: 'docs/grunt/*.js' } }, @@ -349,6 +344,15 @@ module.exports = function (grunt) { browsers: grunt.file.readYAML('test-infra/sauce_browsers.yml') } } + }, + + exec: { + npmUpdate: { + command: 'npm update' + }, + npmShrinkWrap: { + command: 'npm shrinkwrap --dev' + } } }); @@ -398,7 +402,7 @@ module.exports = function (grunt) { grunt.registerTask('dist', ['clean', 'dist-css', 'copy:fonts', 'dist-docs', 'dist-js']); // Default task. - grunt.registerTask('default', ['test', 'dist', 'build-glyphicons-data', 'build-customizer']); + grunt.registerTask('default', ['test', 'dist', 'build-glyphicons-data', 'build-customizer', 'update-shrinkwrap']); // Version numbering task. // grunt change-version-number --oldver=A.B.C --newver=X.Y.Z @@ -414,4 +418,8 @@ module.exports = function (grunt) { var banner = grunt.template.process('<%= banner %>'); generateRawFilesJs(banner); }); + + // Task for updating the npm packages used by the Travis build. + grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', 'exec:npmShrinkWrap', '_update-shrinkwrap']); + grunt.registerTask('_update-shrinkwrap', function () { updateShrinkwrap.call(this, grunt); }); }; diff --git a/package.json b/package.json index 2a8e613bd5..9dfef4f2fe 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "devDependencies": { "browserstack-runner": "~0.0.15", "btoa": "~1.1.1", + "canonical-json": "~0.0.3", "grunt": "~0.4.2", "grunt-banner": "~0.2.0", "grunt-contrib-clean": "~0.5.0", @@ -42,6 +43,7 @@ "grunt-contrib-uglify": "~0.3.0", "grunt-contrib-watch": "~0.5.3", "grunt-csscomb": "~2.0.1", + "grunt-exec": "0.4.3", "grunt-html-validation": "~0.1.13", "grunt-jekyll": "~0.4.1", "grunt-jscs-checker": "~0.3.0", diff --git a/test-infra/README.md b/test-infra/README.md index 75b2fbcd93..2ee7ed9ab4 100644 --- a/test-infra/README.md +++ b/test-infra/README.md @@ -15,7 +15,7 @@ Similar to git, `s3_cache.py` makes the assumption that [SHA-256 will effectivel ### For Bootstrap specifically `s3_cache.py` is used to cache the npm packages that our Grunt tasks depend on and the RubyGems that Jekyll depends on. (Jekyll is needed to compile our docs to HTML so that we can run them thru an HTML5 validator.) -For npm, the `node_modules` directory is cached based on our `package.json` file. +For npm, the `node_modules` directory is cached based on our `npm-shrinkwrap.canonical.json` file. For RubyGems, the `gemdir` of the current RVM-selected Ruby is cached based on the `pseudo_Gemfile.lock` file generated by our Travis build script. `pseudo_Gemfile.lock` contains the versions of Ruby and Jekyll that we're using (read our `.travis.yml` for details). diff --git a/test-infra/npm-shrinkwrap.canonical.json b/test-infra/npm-shrinkwrap.canonical.json new file mode 100644 index 0000000000..1567acd6a3 --- /dev/null +++ b/test-infra/npm-shrinkwrap.canonical.json @@ -0,0 +1 @@ +{"dependencies":{"browserstack-runner":{"dependencies":{"browserstack":{"from":"https://registry.npmjs.org/browserstack/-/browserstack-1.0.1.tgz","resolved":"https://registry.npmjs.org/browserstack/-/browserstack-1.0.1.tgz","version":"1.0.1"}},"from":"https://registry.npmjs.org/browserstack-runner/-/browserstack-runner-0.0.15.tgz","resolved":"https://registry.npmjs.org/browserstack-runner/-/browserstack-runner-0.0.15.tgz","version":"0.0.15"},"btoa":{"from":"https://registry.npmjs.org/btoa/-/btoa-1.1.1.tgz","resolved":"https://registry.npmjs.org/btoa/-/btoa-1.1.1.tgz","version":"1.1.1"},"canonical-json":{"from":"https://registry.npmjs.org/canonical-json/-/canonical-json-0.0.3.tgz","resolved":"https://registry.npmjs.org/canonical-json/-/canonical-json-0.0.3.tgz","version":"0.0.3"},"grunt":{"dependencies":{"async":{"from":"async@0.1.22","version":"0.1.22"},"coffee-script":{"from":"coffee-script@1.3.3","version":"1.3.3"},"colors":{"from":"https://registry.npmjs.org/colors/-/colors-0.6.2.tgz","resolved":"https://registry.npmjs.org/colors/-/colors-0.6.2.tgz","version":"0.6.2"},"dateformat":{"from":"dateformat@1.0.2-1.2.3","version":"1.0.2-1.2.3"},"eventemitter2":{"from":"https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.13.tgz","resolved":"https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.13.tgz","version":"0.4.13"},"exit":{"from":"https://registry.npmjs.org/exit/-/exit-0.1.2.tgz","resolved":"https://registry.npmjs.org/exit/-/exit-0.1.2.tgz","version":"0.1.2"},"findup-sync":{"dependencies":{"glob":{"dependencies":{"graceful-fs":{"from":"graceful-fs@~1.2.0","version":"1.2.3"},"inherits":{"from":"inherits@1","version":"1.0.0"},"minimatch":{"dependencies":{"lru-cache":{"from":"lru-cache@2","version":"2.5.0"},"sigmund":{"from":"sigmund@~1.0.0","version":"1.0.0"}},"from":"minimatch@~0.2.11","version":"0.2.14"}},"from":"glob@3.1.21","version":"3.1.21"},"lodash":{"from":"lodash@1.0.1","version":"1.0.1"}},"from":"https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.2.tgz","resolved":"https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.2.tgz","version":"0.1.2"},"getobject":{"from":"https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz","resolved":"https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz","version":"0.1.0"},"glob":{"dependencies":{"graceful-fs":{"from":"graceful-fs@~1.2.0","version":"1.2.3"},"inherits":{"from":"inherits@1","version":"1.0.0"}},"from":"glob@3.1.21","version":"3.1.21"},"hooker":{"from":"https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz","resolved":"https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz","version":"0.2.3"},"iconv-lite":{"from":"https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz","resolved":"https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz","version":"0.2.11"},"js-yaml":{"dependencies":{"argparse":{"dependencies":{"underscore":{"from":"underscore@~1.4.3","version":"1.4.4"},"underscore.string":{"from":"underscore.string@~2.3.1","version":"2.3.3"}},"from":"argparse@~ 0.1.11","version":"0.1.15"},"esprima":{"from":"esprima@~ 1.0.2","version":"1.0.4"}},"from":"js-yaml@2.0.5","version":"2.0.5"},"lodash":{"from":"lodash@0.9.2","version":"0.9.2"},"minimatch":{"dependencies":{"lru-cache":{"from":"https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz","resolved":"https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz","version":"2.5.0"},"sigmund":{"from":"https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz","resolved":"https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz","version":"1.0.0"}},"from":"minimatch@0.2.14","resolved":"https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz","version":"0.2.14"},"nopt":{"dependencies":{"abbrev":{"from":"abbrev@1","version":"1.0.4"}},"from":"nopt@1.0.10","version":"1.0.10"},"rimraf":{"dependencies":{"graceful-fs":{"from":"graceful-fs@~1.1","version":"1.1.14"}},"from":"rimraf@2.0.3","version":"2.0.3"},"underscore.string":{"from":"underscore.string@2.2.1","version":"2.2.1"},"which":{"from":"which@1.0.5","resolved":"https://registry.npmjs.org/which/-/which-1.0.5.tgz","version":"1.0.5"}},"from":"https://registry.npmjs.org/grunt/-/grunt-0.4.2.tgz","resolved":"https://registry.npmjs.org/grunt/-/grunt-0.4.2.tgz","version":"0.4.2"},"grunt-banner":{"from":"https://registry.npmjs.org/grunt-banner/-/grunt-banner-0.2.0.tgz","resolved":"https://registry.npmjs.org/grunt-banner/-/grunt-banner-0.2.0.tgz","version":"0.2.0"},"grunt-contrib-clean":{"dependencies":{"rimraf":{"from":"https://registry.npmjs.org/rimraf/-/rimraf-2.2.6.tgz","resolved":"https://registry.npmjs.org/rimraf/-/rimraf-2.2.6.tgz","version":"2.2.6"}},"from":"https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-0.5.0.tgz","resolved":"https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-0.5.0.tgz","version":"0.5.0"},"grunt-contrib-concat":{"from":"https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-0.3.0.tgz","resolved":"https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-0.3.0.tgz","version":"0.3.0"},"grunt-contrib-connect":{"dependencies":{"connect":{"dependencies":{"batch":{"from":"https://registry.npmjs.org/batch/-/batch-0.5.0.tgz","resolved":"https://registry.npmjs.org/batch/-/batch-0.5.0.tgz","version":"0.5.0"},"buffer-crc32":{"from":"https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz","resolved":"https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz","version":"0.2.1"},"bytes":{"from":"https://registry.npmjs.org/bytes/-/bytes-0.2.1.tgz","resolved":"https://registry.npmjs.org/bytes/-/bytes-0.2.1.tgz","version":"0.2.1"},"cookie":{"from":"https://registry.npmjs.org/cookie/-/cookie-0.1.0.tgz","resolved":"https://registry.npmjs.org/cookie/-/cookie-0.1.0.tgz","version":"0.1.0"},"cookie-signature":{"from":"https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.1.tgz","resolved":"https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.1.tgz","version":"1.0.1"},"debug":{"from":"https://registry.npmjs.org/debug/-/debug-0.7.4.tgz","resolved":"https://registry.npmjs.org/debug/-/debug-0.7.4.tgz","version":"0.7.4"},"fresh":{"from":"https://registry.npmjs.org/fresh/-/fresh-0.2.0.tgz","resolved":"https://registry.npmjs.org/fresh/-/fresh-0.2.0.tgz","version":"0.2.0"},"methods":{"from":"https://registry.npmjs.org/methods/-/methods-0.1.0.tgz","resolved":"https://registry.npmjs.org/methods/-/methods-0.1.0.tgz","version":"0.1.0"},"multiparty":{"dependencies":{"readable-stream":{"dependencies":{"core-util-is":{"from":"core-util-is@~1.0.0","version":"1.0.1"},"debuglog":{"from":"debuglog@0.0.2","version":"0.0.2"},"string_decoder":{"from":"string_decoder@~0.10.x","version":"0.10.24"}},"from":"readable-stream@~1.1.9","version":"1.1.10"},"stream-counter":{"from":"stream-counter@~0.2.0","version":"0.2.0"}},"from":"multiparty@2.2.0","version":"2.2.0"},"negotiator":{"from":"negotiator@0.3.0","version":"0.3.0"},"pause":{"from":"https://registry.npmjs.org/pause/-/pause-0.0.1.tgz","resolved":"https://registry.npmjs.org/pause/-/pause-0.0.1.tgz","version":"0.0.1"},"qs":{"from":"https://registry.npmjs.org/qs/-/qs-0.6.6.tgz","resolved":"https://registry.npmjs.org/qs/-/qs-0.6.6.tgz","version":"0.6.6"},"raw-body":{"from":"https://registry.npmjs.org/raw-body/-/raw-body-1.1.2.tgz","resolved":"https://registry.npmjs.org/raw-body/-/raw-body-1.1.2.tgz","version":"1.1.2"},"send":{"dependencies":{"mime":{"from":"https://registry.npmjs.org/mime/-/mime-1.2.11.tgz","resolved":"https://registry.npmjs.org/mime/-/mime-1.2.11.tgz","version":"1.2.11"},"range-parser":{"from":"range-parser@0.0.4","version":"0.0.4"}},"from":"https://registry.npmjs.org/send/-/send-0.1.4.tgz","resolved":"https://registry.npmjs.org/send/-/send-0.1.4.tgz","version":"0.1.4"},"uid2":{"from":"https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz","resolved":"https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz","version":"0.0.3"}},"from":"https://registry.npmjs.org/connect/-/connect-2.12.0.tgz","resolved":"https://registry.npmjs.org/connect/-/connect-2.12.0.tgz","version":"2.12.0"},"connect-livereload":{"from":"https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.3.2.tgz","resolved":"https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.3.2.tgz","version":"0.3.2"},"open":{"from":"https://registry.npmjs.org/open/-/open-0.0.4.tgz","resolved":"https://registry.npmjs.org/open/-/open-0.0.4.tgz","version":"0.0.4"}},"from":"https://registry.npmjs.org/grunt-contrib-connect/-/grunt-contrib-connect-0.6.0.tgz","resolved":"https://registry.npmjs.org/grunt-contrib-connect/-/grunt-contrib-connect-0.6.0.tgz","version":"0.6.0"},"grunt-contrib-copy":{"from":"https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-0.5.0.tgz","resolved":"https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-0.5.0.tgz","version":"0.5.0"},"grunt-contrib-csslint":{"dependencies":{"csslint":{"dependencies":{"parserlib":{"from":"https://registry.npmjs.org/parserlib/-/parserlib-0.2.4.tgz","resolved":"https://registry.npmjs.org/parserlib/-/parserlib-0.2.4.tgz","version":"0.2.4"}},"from":"https://registry.npmjs.org/csslint/-/csslint-0.10.0.tgz","resolved":"https://registry.npmjs.org/csslint/-/csslint-0.10.0.tgz","version":"0.10.0"}},"from":"https://registry.npmjs.org/grunt-contrib-csslint/-/grunt-contrib-csslint-0.2.0.tgz","resolved":"https://registry.npmjs.org/grunt-contrib-csslint/-/grunt-contrib-csslint-0.2.0.tgz","version":"0.2.0"},"grunt-contrib-cssmin":{"dependencies":{"clean-css":{"dependencies":{"commander":{"from":"commander@2.0.0","version":"2.0.0"}},"from":"https://registry.npmjs.org/clean-css/-/clean-css-2.0.7.tgz","resolved":"https://registry.npmjs.org/clean-css/-/clean-css-2.0.7.tgz","version":"2.0.7"},"grunt-lib-contrib":{"dependencies":{"zlib-browserify":{"from":"zlib-browserify@0.0.1","version":"0.0.1"}},"from":"https://registry.npmjs.org/grunt-lib-contrib/-/grunt-lib-contrib-0.6.1.tgz","resolved":"https://registry.npmjs.org/grunt-lib-contrib/-/grunt-lib-contrib-0.6.1.tgz","version":"0.6.1"}},"from":"https://registry.npmjs.org/grunt-contrib-cssmin/-/grunt-contrib-cssmin-0.7.0.tgz","resolved":"https://registry.npmjs.org/grunt-contrib-cssmin/-/grunt-contrib-cssmin-0.7.0.tgz","version":"0.7.0"},"grunt-contrib-jade":{"dependencies":{"grunt-lib-contrib":{"dependencies":{"zlib-browserify":{"from":"zlib-browserify@0.0.1","version":"0.0.1"}},"from":"https://registry.npmjs.org/grunt-lib-contrib/-/grunt-lib-contrib-0.6.1.tgz","resolved":"https://registry.npmjs.org/grunt-lib-contrib/-/grunt-lib-contrib-0.6.1.tgz","version":"0.6.1"},"jade":{"dependencies":{"character-parser":{"from":"character-parser@1.2.0","version":"1.2.0"},"commander":{"from":"commander@2.0.0","version":"2.0.0"},"constantinople":{"dependencies":{"uglify-js":{"dependencies":{"async":{"from":"async@~0.2.6","version":"0.2.10"},"optimist":{"dependencies":{"wordwrap":{"from":"wordwrap@~0.0.2","version":"0.0.2"}},"from":"optimist@~0.3.5","version":"0.3.7"},"source-map":{"dependencies":{"amdefine":{"from":"amdefine@>=0.0.4","version":"0.1.0"}},"from":"source-map@~0.1.7","version":"0.1.31"},"uglify-to-browserify":{"from":"uglify-to-browserify@~1.0.0","version":"1.0.1"}},"from":"uglify-js@~2.4.0","version":"2.4.12"}},"from":"constantinople@~1.0.2","version":"1.0.2"},"mkdirp":{"from":"mkdirp@~0.3.5","version":"0.3.5"},"monocle":{"dependencies":{"readdirp":{"dependencies":{"minimatch":{"dependencies":{"lru-cache":{"from":"lru-cache@2","version":"2.5.0"},"sigmund":{"from":"sigmund@~1.0.0","version":"1.0.0"}},"from":"minimatch@>=0.2.4","version":"0.2.14"}},"from":"readdirp@~0.2.3","version":"0.2.5"}},"from":"monocle@1.1.50","version":"1.1.50"},"transformers":{"dependencies":{"css":{"dependencies":{"css-parse":{"from":"css-parse@1.0.4","version":"1.0.4"},"css-stringify":{"from":"css-stringify@1.0.5","version":"1.0.5"}},"from":"css@~1.0.8","version":"1.0.8"},"promise":{"dependencies":{"is-promise":{"from":"is-promise@~1","version":"1.0.0"}},"from":"promise@~2.0","version":"2.0.0"},"uglify-js":{"dependencies":{"optimist":{"dependencies":{"wordwrap":{"from":"wordwrap@~0.0.2","version":"0.0.2"}},"from":"optimist@~0.3.5","version":"0.3.7"},"source-map":{"dependencies":{"amdefine":{"from":"amdefine@>=0.0.4","version":"0.1.0"}},"from":"source-map@~0.1.7","version":"0.1.31"}},"from":"uglify-js@~2.2.5","version":"2.2.5"}},"from":"transformers@2.1.0","version":"2.1.0"},"with":{"dependencies":{"uglify-js":{"dependencies":{"async":{"from":"async@~0.2.6","version":"0.2.10"},"optimist":{"dependencies":{"wordwrap":{"from":"wordwrap@~0.0.2","version":"0.0.2"}},"from":"optimist@~0.3.5","version":"0.3.7"},"source-map":{"dependencies":{"amdefine":{"from":"amdefine@>=0.0.4","version":"0.1.0"}},"from":"source-map@~0.1.7","version":"0.1.31"},"uglify-to-browserify":{"from":"uglify-to-browserify@~1.0.0","version":"1.0.1"}},"from":"uglify-js@2.4.0","version":"2.4.0"}},"from":"with@~2.0.0","version":"2.0.0"}},"from":"jade@1.0.2","version":"1.0.2"},"lodash-node":{"from":"https://registry.npmjs.org/lodash-node/-/lodash-node-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash-node/-/lodash-node-2.4.1.tgz","version":"2.4.1"}},"from":"https://registry.npmjs.org/grunt-contrib-jade/-/grunt-contrib-jade-0.9.1.tgz","resolved":"https://registry.npmjs.org/grunt-contrib-jade/-/grunt-contrib-jade-0.9.1.tgz","version":"0.9.1"},"grunt-contrib-jshint":{"dependencies":{"jshint":{"dependencies":{"cli":{"dependencies":{"glob":{"dependencies":{"inherits":{"from":"inherits@2.0.1","version":"2.0.1"}},"from":"glob@3.2.8","version":"3.2.8"}},"from":"cli@0.4.5","version":"0.4.5"},"console-browserify":{"from":"console-browserify@0.1.6","version":"0.1.6"},"htmlparser2":{"dependencies":{"domelementtype":{"from":"domelementtype@1","version":"1.1.1"},"domhandler":{"from":"domhandler@2.1","version":"2.1.0"},"domutils":{"from":"domutils@1.1","version":"1.1.6"},"readable-stream":{"dependencies":{"string_decoder":{"from":"string_decoder@~0.10.x","version":"0.10.24"}},"from":"readable-stream@1.0","version":"1.0.25"}},"from":"htmlparser2@3.3.0","version":"3.3.0"},"minimatch":{"dependencies":{"lru-cache":{"from":"lru-cache@2.5.0","resolved":"https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz","version":"2.5.0"},"sigmund":{"from":"sigmund@1.0.0","resolved":"https://registry.npmjs.org/sigmund/-/sigmund-1.0.0.tgz","version":"1.0.0"}},"from":"minimatch@0.2.14","resolved":"https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz","version":"0.2.14"},"shelljs":{"from":"shelljs@0.1.4","version":"0.1.4"},"underscore":{"from":"underscore@1.4.4","version":"1.4.4"}},"from":"https://registry.npmjs.org/jshint/-/jshint-2.4.3.tgz","resolved":"https://registry.npmjs.org/jshint/-/jshint-2.4.3.tgz","version":"2.4.3"}},"from":"https://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-0.8.0.tgz","resolved":"https://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-0.8.0.tgz","version":"0.8.0"},"grunt-contrib-less":{"dependencies":{"chalk":{"dependencies":{"ansi-styles":{"from":"https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz","resolved":"https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz","version":"1.0.0"},"has-color":{"from":"https://registry.npmjs.org/has-color/-/has-color-0.1.2.tgz","resolved":"https://registry.npmjs.org/has-color/-/has-color-0.1.2.tgz","version":"0.1.2"},"strip-ansi":{"from":"https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz","resolved":"https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz","version":"0.1.1"}},"from":"https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz","resolved":"https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz","version":"0.4.0"},"grunt-lib-contrib":{"dependencies":{"zlib-browserify":{"from":"zlib-browserify@0.0.1","version":"0.0.1"}},"from":"https://registry.npmjs.org/grunt-lib-contrib/-/grunt-lib-contrib-0.6.1.tgz","resolved":"https://registry.npmjs.org/grunt-lib-contrib/-/grunt-lib-contrib-0.6.1.tgz","version":"0.6.1"},"less":{"dependencies":{"clean-css":{"dependencies":{"commander":{"from":"commander@2.0.0","version":"2.0.0"}},"from":"https://registry.npmjs.org/clean-css/-/clean-css-2.0.7.tgz","resolved":"https://registry.npmjs.org/clean-css/-/clean-css-2.0.7.tgz","version":"2.0.7"},"mime":{"from":"mime@1.2.11","resolved":"https://registry.npmjs.org/mime/-/mime-1.2.11.tgz","version":"1.2.11"},"mkdirp":{"from":"https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz","resolved":"https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz","version":"0.3.5"},"request":{"dependencies":{"aws-sign2":{"from":"https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz","resolved":"https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz","version":"0.5.0"},"forever-agent":{"from":"https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.0.tgz","resolved":"https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.0.tgz","version":"0.5.0"},"form-data":{"dependencies":{"async":{"from":"https://registry.npmjs.org/async/-/async-0.2.10.tgz","resolved":"https://registry.npmjs.org/async/-/async-0.2.10.tgz","version":"0.2.10"},"combined-stream":{"dependencies":{"delayed-stream":{"from":"https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz","resolved":"https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz","version":"0.0.5"}},"from":"https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.4.tgz","resolved":"https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.4.tgz","version":"0.0.4"}},"from":"https://registry.npmjs.org/form-data/-/form-data-0.1.2.tgz","resolved":"https://registry.npmjs.org/form-data/-/form-data-0.1.2.tgz","version":"0.1.2"},"hawk":{"dependencies":{"boom":{"from":"boom@0.4.x","version":"0.4.2"},"cryptiles":{"from":"cryptiles@0.2.x","version":"0.2.2"},"hoek":{"from":"hoek@0.9.x","version":"0.9.1"},"sntp":{"from":"sntp@0.2.x","version":"0.2.4"}},"from":"hawk@1.0.0","version":"1.0.0"},"http-signature":{"dependencies":{"asn1":{"from":"https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz","resolved":"https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz","version":"0.1.11"},"assert-plus":{"from":"assert-plus@0.1.2","version":"0.1.2"},"ctype":{"from":"ctype@0.5.2","version":"0.5.2"}},"from":"https://registry.npmjs.org/http-signature/-/http-signature-0.10.0.tgz","resolved":"https://registry.npmjs.org/http-signature/-/http-signature-0.10.0.tgz","version":"0.10.0"},"json-stringify-safe":{"from":"https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.0.tgz","resolved":"https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.0.tgz","version":"5.0.0"},"node-uuid":{"from":"https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.1.tgz","resolved":"https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.1.tgz","version":"1.4.1"},"oauth-sign":{"from":"oauth-sign@0.3.0","version":"0.3.0"},"qs":{"from":"https://registry.npmjs.org/qs/-/qs-0.6.6.tgz","resolved":"https://registry.npmjs.org/qs/-/qs-0.6.6.tgz","version":"0.6.6"},"tough-cookie":{"dependencies":{"punycode":{"from":"https://registry.npmjs.org/punycode/-/punycode-1.2.3.tgz","resolved":"https://registry.npmjs.org/punycode/-/punycode-1.2.3.tgz","version":"1.2.3"}},"from":"https://registry.npmjs.org/tough-cookie/-/tough-cookie-0.12.1.tgz","resolved":"https://registry.npmjs.org/tough-cookie/-/tough-cookie-0.12.1.tgz","version":"0.12.1"},"tunnel-agent":{"from":"https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz","resolved":"https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz","version":"0.3.0"}},"from":"https://registry.npmjs.org/request/-/request-2.33.0.tgz","resolved":"https://registry.npmjs.org/request/-/request-2.33.0.tgz","version":"2.33.0"},"source-map":{"dependencies":{"amdefine":{"from":"https://registry.npmjs.org/amdefine/-/amdefine-0.1.0.tgz","resolved":"https://registry.npmjs.org/amdefine/-/amdefine-0.1.0.tgz","version":"0.1.0"}},"from":"https://registry.npmjs.org/source-map/-/source-map-0.1.31.tgz","resolved":"https://registry.npmjs.org/source-map/-/source-map-0.1.31.tgz","version":"0.1.31"}},"from":"https://registry.npmjs.org/less/-/less-1.6.1.tgz","resolved":"https://registry.npmjs.org/less/-/less-1.6.1.tgz","version":"1.6.1"}},"from":"https://registry.npmjs.org/grunt-contrib-less/-/grunt-contrib-less-0.9.0.tgz","resolved":"https://registry.npmjs.org/grunt-contrib-less/-/grunt-contrib-less-0.9.0.tgz","version":"0.9.0"},"grunt-contrib-qunit":{"dependencies":{"grunt-lib-phantomjs":{"dependencies":{"eventemitter2":{"from":"https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.13.tgz","resolved":"https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.13.tgz","version":"0.4.13"},"phantomjs":{"dependencies":{"adm-zip":{"from":"adm-zip@0.2.1","version":"0.2.1"},"kew":{"from":"kew@0.1.7","version":"0.1.7"},"mkdirp":{"from":"mkdirp@0.3.5","version":"0.3.5"},"ncp":{"from":"ncp@0.4.2","version":"0.4.2"},"npmconf":{"dependencies":{"config-chain":{"dependencies":{"proto-list":{"from":"proto-list@~1.2.1","version":"1.2.2"}},"from":"config-chain@~1.1.1","version":"1.1.8"},"inherits":{"from":"inherits@~1.0.0","version":"1.0.0"},"ini":{"from":"ini@~1.1.0","version":"1.1.0"},"nopt":{"dependencies":{"abbrev":{"from":"abbrev@1","version":"1.0.4"}},"from":"nopt@2","version":"2.1.2"},"once":{"from":"once@~1.1.1","version":"1.1.1"},"osenv":{"from":"osenv@0.0.3","version":"0.0.3"},"semver":{"from":"semver@~1.1.0","version":"1.1.4"}},"from":"npmconf@0.0.24","version":"0.0.24"},"rimraf":{"from":"rimraf@2.2.6","resolved":"https://registry.npmjs.org/rimraf/-/rimraf-2.2.6.tgz","version":"2.2.6"},"which":{"from":"which@1.0.5","resolved":"https://registry.npmjs.org/which/-/which-1.0.5.tgz","version":"1.0.5"}},"from":"https://registry.npmjs.org/phantomjs/-/phantomjs-1.9.6-0.tgz","resolved":"https://registry.npmjs.org/phantomjs/-/phantomjs-1.9.6-0.tgz","version":"1.9.6-0"},"semver":{"from":"semver@1.0.14","version":"1.0.14"},"temporary":{"dependencies":{"package":{"from":"https://registry.npmjs.org/package/-/package-1.0.1.tgz","resolved":"https://registry.npmjs.org/package/-/package-1.0.1.tgz","version":"1.0.1"}},"from":"https://registry.npmjs.org/temporary/-/temporary-0.0.8.tgz","resolved":"https://registry.npmjs.org/temporary/-/temporary-0.0.8.tgz","version":"0.0.8"}},"from":"https://registry.npmjs.org/grunt-lib-phantomjs/-/grunt-lib-phantomjs-0.5.0.tgz","resolved":"https://registry.npmjs.org/grunt-lib-phantomjs/-/grunt-lib-phantomjs-0.5.0.tgz","version":"0.5.0"}},"from":"https://registry.npmjs.org/grunt-contrib-qunit/-/grunt-contrib-qunit-0.4.0.tgz","resolved":"https://registry.npmjs.org/grunt-contrib-qunit/-/grunt-contrib-qunit-0.4.0.tgz","version":"0.4.0"},"grunt-contrib-uglify":{"dependencies":{"chalk":{"dependencies":{"ansi-styles":{"from":"ansi-styles@1.0.0","version":"1.0.0"},"has-color":{"from":"has-color@0.1.2","version":"0.1.2"},"strip-ansi":{"from":"strip-ansi@0.1.1","version":"0.1.1"}},"from":"https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz","resolved":"https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz","version":"0.4.0"},"grunt-lib-contrib":{"dependencies":{"zlib-browserify":{"from":"zlib-browserify@0.0.1","version":"0.0.1"}},"from":"https://registry.npmjs.org/grunt-lib-contrib/-/grunt-lib-contrib-0.6.1.tgz","resolved":"https://registry.npmjs.org/grunt-lib-contrib/-/grunt-lib-contrib-0.6.1.tgz","version":"0.6.1"},"uglify-js":{"dependencies":{"async":{"from":"https://registry.npmjs.org/async/-/async-0.2.10.tgz","resolved":"https://registry.npmjs.org/async/-/async-0.2.10.tgz","version":"0.2.10"},"optimist":{"dependencies":{"wordwrap":{"from":"wordwrap@~0.0.2","version":"0.0.2"}},"from":"optimist@0.3.7","version":"0.3.7"},"source-map":{"dependencies":{"amdefine":{"from":"amdefine@0.1.0","version":"0.1.0"}},"from":"source-map@0.1.31","version":"0.1.31"},"uglify-to-browserify":{"from":"uglify-to-browserify@1.0.1","version":"1.0.1"}},"from":"https://registry.npmjs.org/uglify-js/-/uglify-js-2.4.12.tgz","resolved":"https://registry.npmjs.org/uglify-js/-/uglify-js-2.4.12.tgz","version":"2.4.12"}},"from":"https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-0.3.2.tgz","resolved":"https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-0.3.2.tgz","version":"0.3.2"},"grunt-contrib-watch":{"dependencies":{"gaze":{"dependencies":{"globule":{"dependencies":{"glob":{"dependencies":{"graceful-fs":{"from":"graceful-fs@~1.2.0","version":"1.2.3"},"inherits":{"from":"inherits@1","version":"1.0.0"}},"from":"glob@~3.1.21","version":"3.1.21"},"lodash":{"from":"lodash@~1.0.1","version":"1.0.1"},"minimatch":{"dependencies":{"lru-cache":{"from":"lru-cache@2","version":"2.5.0"},"sigmund":{"from":"sigmund@~1.0.0","version":"1.0.0"}},"from":"minimatch@~0.2.11","version":"0.2.14"}},"from":"globule@0.1.0","version":"0.1.0"}},"from":"https://registry.npmjs.org/gaze/-/gaze-0.4.3.tgz","resolved":"https://registry.npmjs.org/gaze/-/gaze-0.4.3.tgz","version":"0.4.3"},"tiny-lr":{"dependencies":{"debug":{"from":"debug@~0.7.0","version":"0.7.4"},"faye-websocket":{"from":"faye-websocket@~0.4.3","version":"0.4.4"},"noptify":{"dependencies":{"nopt":{"dependencies":{"abbrev":{"from":"abbrev@1","version":"1.0.4"}},"from":"nopt@~2.0.0","version":"2.0.0"}},"from":"noptify@latest","version":"0.0.3"},"qs":{"from":"qs@~0.5.2","version":"0.5.6"}},"from":"tiny-lr@0.0.4","version":"0.0.4"}},"from":"https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-0.5.3.tgz","resolved":"https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-0.5.3.tgz","version":"0.5.3"},"grunt-csscomb":{"dependencies":{"csscomb":{"dependencies":{"commander":{"from":"commander@2.0.0","version":"2.0.0"},"gonzales-pe":{"from":"https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-2.0.2.tgz","resolved":"https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-2.0.2.tgz","version":"2.0.2"},"minimatch":{"dependencies":{"lru-cache":{"from":"lru-cache@2","version":"2.5.0"},"sigmund":{"from":"sigmund@~1.0.0","version":"1.0.0"}},"from":"minimatch@0.2.12","version":"0.2.12"},"vow":{"from":"vow@0.3.11","version":"0.3.11"},"vow-fs":{"dependencies":{"node-uuid":{"from":"node-uuid@1.4.0","version":"1.4.0"},"vow-queue":{"from":"vow-queue@0.0.2","version":"0.0.2"}},"from":"vow-fs@0.2.3","version":"0.2.3"}},"from":"https://registry.npmjs.org/csscomb/-/csscomb-2.0.4.tgz","resolved":"https://registry.npmjs.org/csscomb/-/csscomb-2.0.4.tgz","version":"2.0.4"}},"from":"https://registry.npmjs.org/grunt-csscomb/-/grunt-csscomb-2.0.1.tgz","resolved":"https://registry.npmjs.org/grunt-csscomb/-/grunt-csscomb-2.0.1.tgz","version":"2.0.1"},"grunt-exec":{"from":"https://registry.npmjs.org/grunt-exec/-/grunt-exec-0.4.3.tgz","resolved":"https://registry.npmjs.org/grunt-exec/-/grunt-exec-0.4.3.tgz","version":"0.4.3"},"grunt-html-validation":{"dependencies":{"colors":{"from":"https://registry.npmjs.org/colors/-/colors-0.6.2.tgz","resolved":"https://registry.npmjs.org/colors/-/colors-0.6.2.tgz","version":"0.6.2"},"request":{"dependencies":{"aws-sign":{"from":"aws-sign@~0.3.0","version":"0.3.0"},"cookie-jar":{"from":"cookie-jar@~0.3.0","version":"0.3.0"},"forever-agent":{"from":"forever-agent@~0.5.0","version":"0.5.0"},"form-data":{"dependencies":{"async":{"from":"async@~0.2.9","version":"0.2.10"},"combined-stream":{"dependencies":{"delayed-stream":{"from":"delayed-stream@0.0.5","version":"0.0.5"}},"from":"combined-stream@~0.0.4","version":"0.0.4"}},"from":"form-data@~0.1.0","version":"0.1.2"},"hawk":{"dependencies":{"boom":{"from":"boom@0.4.x","version":"0.4.2"},"cryptiles":{"from":"cryptiles@0.2.x","version":"0.2.2"},"hoek":{"from":"hoek@0.9.x","version":"0.9.1"},"sntp":{"from":"sntp@0.2.x","version":"0.2.4"}},"from":"hawk@~1.0.0","version":"1.0.0"},"http-signature":{"dependencies":{"asn1":{"from":"asn1@0.1.11","version":"0.1.11"},"assert-plus":{"from":"assert-plus@0.1.2","version":"0.1.2"},"ctype":{"from":"ctype@0.5.2","version":"0.5.2"}},"from":"http-signature@~0.10.0","version":"0.10.0"},"json-stringify-safe":{"from":"json-stringify-safe@~5.0.0","version":"5.0.0"},"mime":{"from":"mime@~1.2.9","version":"1.2.11"},"node-uuid":{"from":"node-uuid@~1.4.0","version":"1.4.1"},"oauth-sign":{"from":"oauth-sign@~0.3.0","version":"0.3.0"},"qs":{"from":"qs@~0.6.0","version":"0.6.6"},"tunnel-agent":{"from":"tunnel-agent@~0.3.0","version":"0.3.0"}},"from":"request@2.27.0","version":"2.27.0"},"w3cjs":{"dependencies":{"commander":{"from":"commander@2.0.0","version":"2.0.0"},"superagent":{"dependencies":{"cookiejar":{"from":"cookiejar@1.3.0","version":"1.3.0"},"debug":{"from":"debug@~0.7.2","version":"0.7.4"},"emitter-component":{"from":"emitter-component@1.0.0","version":"1.0.0"},"formidable":{"from":"formidable@1.0.14","version":"1.0.14"},"methods":{"from":"methods@0.0.1","version":"0.0.1"},"mime":{"from":"mime@1.2.5","version":"1.2.5"},"qs":{"from":"qs@0.6.5","version":"0.6.5"},"reduce-component":{"from":"reduce-component@1.0.1","version":"1.0.1"}},"from":"superagent@0.15.7","version":"0.15.7"},"superagent-proxy":{"dependencies":{"proxy-agent":{"dependencies":{"http-proxy-agent":{"dependencies":{"agent-base":{"from":"agent-base@~1.0.1","version":"1.0.1"},"debug":{"from":"debug@~0.7.2","version":"0.7.4"},"extend":{"from":"extend@~1.2.0","version":"1.2.1"}},"from":"http-proxy-agent@0","version":"0.2.4"},"https-proxy-agent":{"dependencies":{"agent-base":{"from":"agent-base@~1.0.1","version":"1.0.1"},"debug":{"from":"debug@~0.7.2","version":"0.7.4"},"extend":{"from":"extend@~1.2.0","version":"1.2.1"}},"from":"https-proxy-agent@0","version":"0.3.3"},"lru-cache":{"from":"lru-cache@~2.3.1","version":"2.3.1"},"socks-proxy-agent":{"dependencies":{"agent-base":{"from":"agent-base@~1.0.1","version":"1.0.1"},"extend":{"from":"extend@~1.2.0","version":"1.2.1"},"rainbowsocks":{"dependencies":{"debug":{"from":"debug@~0.7.2","version":"0.7.4"}},"from":"rainbowsocks@~0.1.0","version":"0.1.1"}},"from":"socks-proxy-agent@0","version":"0.1.0"}},"from":"proxy-agent@~0.0.2","version":"0.0.2"}},"from":"superagent-proxy@0.2.0","version":"0.2.0"}},"from":"https://registry.npmjs.org/w3cjs/-/w3cjs-0.1.24.tgz","resolved":"https://registry.npmjs.org/w3cjs/-/w3cjs-0.1.24.tgz","version":"0.1.24"}},"from":"https://registry.npmjs.org/grunt-html-validation/-/grunt-html-validation-0.1.13.tgz","resolved":"https://registry.npmjs.org/grunt-html-validation/-/grunt-html-validation-0.1.13.tgz","version":"0.1.13"},"grunt-jekyll":{"dependencies":{"tmp":{"from":"tmp@0.0.21","version":"0.0.21"}},"from":"https://registry.npmjs.org/grunt-jekyll/-/grunt-jekyll-0.4.1.tgz","resolved":"https://registry.npmjs.org/grunt-jekyll/-/grunt-jekyll-0.4.1.tgz","version":"0.4.1"},"grunt-jscs-checker":{"dependencies":{"hooker":{"from":"https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz","resolved":"https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz","version":"0.2.3"},"jscs":{"dependencies":{"colors":{"from":"colors@0.6.0-1","version":"0.6.0-1"},"commander":{"dependencies":{"keypress":{"from":"keypress@0.1.x","version":"0.1.0"}},"from":"commander@1.2.0","version":"1.2.0"},"esprima":{"from":"esprima@1.0.3","version":"1.0.3"},"glob":{"dependencies":{"inherits":{"from":"inherits@2","version":"2.0.1"}},"from":"glob@3.2.7","version":"3.2.7"},"minimatch":{"dependencies":{"lru-cache":{"from":"lru-cache@2","version":"2.5.0"},"sigmund":{"from":"sigmund@~1.0.0","version":"1.0.0"}},"from":"minimatch@0.2.12","version":"0.2.12"},"vow":{"from":"vow@0.3.9","version":"0.3.9"},"vow-fs":{"dependencies":{"node-uuid":{"from":"node-uuid@1.4.0","version":"1.4.0"},"vow-queue":{"from":"vow-queue@0.0.2","version":"0.0.2"}},"from":"vow-fs@0.2.3","version":"0.2.3"},"xmlbuilder":{"dependencies":{"underscore":{"from":"underscore@>=1.5.x","version":"1.5.2"}},"from":"xmlbuilder@1.1.2","version":"1.1.2"}},"from":"https://registry.npmjs.org/jscs/-/jscs-1.2.4.tgz","resolved":"https://registry.npmjs.org/jscs/-/jscs-1.2.4.tgz","version":"1.2.4"},"lodash.assign":{"dependencies":{"lodash._basecreatecallback":{"dependencies":{"lodash._setbinddata":{"dependencies":{"lodash._isnative":{"from":"https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz","version":"2.4.1"},"lodash.noop":{"from":"https://registry.npmjs.org/lodash.noop/-/lodash.noop-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash.noop/-/lodash.noop-2.4.1.tgz","version":"2.4.1"}},"from":"https://registry.npmjs.org/lodash._setbinddata/-/lodash._setbinddata-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._setbinddata/-/lodash._setbinddata-2.4.1.tgz","version":"2.4.1"},"lodash.bind":{"dependencies":{"lodash._createwrapper":{"dependencies":{"lodash._basebind":{"dependencies":{"lodash._basecreate":{"dependencies":{"lodash._isnative":{"from":"https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz","version":"2.4.1"},"lodash.noop":{"from":"https://registry.npmjs.org/lodash.noop/-/lodash.noop-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash.noop/-/lodash.noop-2.4.1.tgz","version":"2.4.1"}},"from":"https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-2.4.1.tgz","version":"2.4.1"},"lodash.isobject":{"from":"https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz","version":"2.4.1"}},"from":"https://registry.npmjs.org/lodash._basebind/-/lodash._basebind-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._basebind/-/lodash._basebind-2.4.1.tgz","version":"2.4.1"},"lodash._basecreatewrapper":{"dependencies":{"lodash._basecreate":{"dependencies":{"lodash._isnative":{"from":"https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz","version":"2.4.1"},"lodash.noop":{"from":"https://registry.npmjs.org/lodash.noop/-/lodash.noop-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash.noop/-/lodash.noop-2.4.1.tgz","version":"2.4.1"}},"from":"https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-2.4.1.tgz","version":"2.4.1"},"lodash.isobject":{"from":"https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz","version":"2.4.1"}},"from":"https://registry.npmjs.org/lodash._basecreatewrapper/-/lodash._basecreatewrapper-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._basecreatewrapper/-/lodash._basecreatewrapper-2.4.1.tgz","version":"2.4.1"},"lodash.isfunction":{"from":"https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-2.4.1.tgz","version":"2.4.1"}},"from":"https://registry.npmjs.org/lodash._createwrapper/-/lodash._createwrapper-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._createwrapper/-/lodash._createwrapper-2.4.1.tgz","version":"2.4.1"},"lodash._slice":{"from":"https://registry.npmjs.org/lodash._slice/-/lodash._slice-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._slice/-/lodash._slice-2.4.1.tgz","version":"2.4.1"}},"from":"https://registry.npmjs.org/lodash.bind/-/lodash.bind-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash.bind/-/lodash.bind-2.4.1.tgz","version":"2.4.1"},"lodash.identity":{"from":"https://registry.npmjs.org/lodash.identity/-/lodash.identity-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash.identity/-/lodash.identity-2.4.1.tgz","version":"2.4.1"},"lodash.support":{"dependencies":{"lodash._isnative":{"from":"https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz","version":"2.4.1"}},"from":"https://registry.npmjs.org/lodash.support/-/lodash.support-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash.support/-/lodash.support-2.4.1.tgz","version":"2.4.1"}},"from":"https://registry.npmjs.org/lodash._basecreatecallback/-/lodash._basecreatecallback-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._basecreatecallback/-/lodash._basecreatecallback-2.4.1.tgz","version":"2.4.1"},"lodash._objecttypes":{"from":"https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz","version":"2.4.1"},"lodash.keys":{"dependencies":{"lodash._isnative":{"from":"https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz","version":"2.4.1"},"lodash._shimkeys":{"from":"https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz","version":"2.4.1"},"lodash.isobject":{"from":"https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz","version":"2.4.1"}},"from":"https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz","version":"2.4.1"}},"from":"https://registry.npmjs.org/lodash.assign/-/lodash.assign-2.4.1.tgz","resolved":"https://registry.npmjs.org/lodash.assign/-/lodash.assign-2.4.1.tgz","version":"2.4.1"},"vow":{"from":"vow@0.4.0","version":"0.4.0"}},"from":"https://registry.npmjs.org/grunt-jscs-checker/-/grunt-jscs-checker-0.3.2.tgz","resolved":"https://registry.npmjs.org/grunt-jscs-checker/-/grunt-jscs-checker-0.3.2.tgz","version":"0.3.2"},"grunt-saucelabs":{"dependencies":{"colors":{"from":"https://registry.npmjs.org/colors/-/colors-0.6.2.tgz","resolved":"https://registry.npmjs.org/colors/-/colors-0.6.2.tgz","version":"0.6.2"},"request":{"dependencies":{"aws-sign":{"from":"aws-sign@~0.3.0","version":"0.3.0"},"cookie-jar":{"from":"cookie-jar@~0.3.0","version":"0.3.0"},"forever-agent":{"from":"forever-agent@~0.5.0","version":"0.5.0"},"form-data":{"dependencies":{"async":{"from":"async@~0.2.9","version":"0.2.10"},"combined-stream":{"dependencies":{"delayed-stream":{"from":"delayed-stream@0.0.5","version":"0.0.5"}},"from":"combined-stream@~0.0.4","version":"0.0.4"}},"from":"form-data@~0.1.0","version":"0.1.2"},"hawk":{"dependencies":{"boom":{"from":"boom@0.4.x","version":"0.4.2"},"cryptiles":{"from":"cryptiles@0.2.x","version":"0.2.2"},"hoek":{"from":"hoek@0.9.x","version":"0.9.1"},"sntp":{"from":"sntp@0.2.x","version":"0.2.4"}},"from":"hawk@~1.0.0","version":"1.0.0"},"http-signature":{"dependencies":{"asn1":{"from":"asn1@0.1.11","version":"0.1.11"},"assert-plus":{"from":"assert-plus@0.1.2","version":"0.1.2"},"ctype":{"from":"ctype@0.5.2","version":"0.5.2"}},"from":"http-signature@~0.10.0","version":"0.10.0"},"json-stringify-safe":{"from":"json-stringify-safe@~5.0.0","version":"5.0.0"},"mime":{"from":"mime@~1.2.9","version":"1.2.11"},"node-uuid":{"from":"node-uuid@~1.4.0","version":"1.4.1"},"oauth-sign":{"from":"oauth-sign@~0.3.0","version":"0.3.0"},"qs":{"from":"qs@~0.6.0","version":"0.6.6"},"tunnel-agent":{"from":"tunnel-agent@~0.3.0","version":"0.3.0"}},"from":"request@2.27.0","version":"2.27.0"},"sauce-tunnel":{"dependencies":{"request":{"dependencies":{"aws-sign":{"from":"aws-sign@~0.3.0","version":"0.3.0"},"cookie-jar":{"from":"cookie-jar@~0.3.0","version":"0.3.0"},"forever-agent":{"from":"forever-agent@~0.5.0","version":"0.5.0"},"form-data":{"dependencies":{"async":{"from":"async@~0.2.7","version":"0.2.10"},"combined-stream":{"dependencies":{"delayed-stream":{"from":"delayed-stream@0.0.5","version":"0.0.5"}},"from":"combined-stream@~0.0.4","version":"0.0.4"}},"from":"form-data@0.0.8","version":"0.0.8"},"hawk":{"dependencies":{"boom":{"dependencies":{"hoek":{"from":"hoek@0.9.x","version":"0.9.1"}},"from":"boom@0.4.x","version":"0.4.2"},"cryptiles":{"from":"cryptiles@0.2.x","version":"0.2.2"},"hoek":{"from":"hoek@0.8.x","version":"0.8.5"},"sntp":{"dependencies":{"hoek":{"from":"hoek@0.9.x","version":"0.9.1"}},"from":"sntp@0.2.x","version":"0.2.4"}},"from":"hawk@~0.13.0","version":"0.13.1"},"http-signature":{"dependencies":{"asn1":{"from":"asn1@0.1.11","version":"0.1.11"},"assert-plus":{"from":"assert-plus@0.1.2","version":"0.1.2"},"ctype":{"from":"ctype@0.5.2","version":"0.5.2"}},"from":"http-signature@~0.9.11","version":"0.9.11"},"json-stringify-safe":{"from":"json-stringify-safe@~4.0.0","version":"4.0.0"},"mime":{"from":"mime@~1.2.9","version":"1.2.11"},"node-uuid":{"from":"node-uuid@~1.4.0","version":"1.4.1"},"oauth-sign":{"from":"oauth-sign@~0.3.0","version":"0.3.0"},"qs":{"from":"qs@~0.6.0","version":"0.6.6"},"tunnel-agent":{"from":"tunnel-agent@~0.3.0","version":"0.3.0"}},"from":"request@~2.21.0","version":"2.21.0"}},"from":"sauce-tunnel@1.0.2","version":"1.0.2"},"saucelabs":{"from":"https://registry.npmjs.org/saucelabs/-/saucelabs-0.1.1.tgz","resolved":"https://registry.npmjs.org/saucelabs/-/saucelabs-0.1.1.tgz","version":"0.1.1"},"wd":{"dependencies":{"archiver":{"dependencies":{"iconv-lite":{"from":"iconv-lite@~0.2.11","version":"0.2.11"},"readable-stream":{"dependencies":{"string_decoder":{"from":"string_decoder@~0.10.x","version":"0.10.24"}},"from":"readable-stream@~1.0.2","version":"1.0.25"}},"from":"archiver@~0.4.6","version":"0.4.10"},"async":{"from":"async@0.2.x","version":"0.2.10"},"lodash":{"from":"lodash@~1.3.1","version":"1.3.1"},"q":{"from":"q@0.9.x","version":"0.9.7"},"request":{"dependencies":{"aws-sign":{"from":"aws-sign@~0.3.0","version":"0.3.0"},"cookie-jar":{"from":"cookie-jar@~0.3.0","version":"0.3.0"},"forever-agent":{"from":"forever-agent@~0.5.0","version":"0.5.0"},"form-data":{"dependencies":{"combined-stream":{"dependencies":{"delayed-stream":{"from":"delayed-stream@0.0.5","version":"0.0.5"}},"from":"combined-stream@~0.0.4","version":"0.0.4"}},"from":"form-data@0.0.8","version":"0.0.8"},"hawk":{"dependencies":{"boom":{"dependencies":{"hoek":{"from":"hoek@0.9.x","version":"0.9.1"}},"from":"boom@0.4.x","version":"0.4.2"},"cryptiles":{"from":"cryptiles@0.2.x","version":"0.2.2"},"hoek":{"from":"hoek@0.8.x","version":"0.8.5"},"sntp":{"dependencies":{"hoek":{"from":"hoek@0.9.x","version":"0.9.1"}},"from":"sntp@0.2.x","version":"0.2.4"}},"from":"hawk@~0.13.0","version":"0.13.1"},"http-signature":{"dependencies":{"asn1":{"from":"asn1@0.1.11","version":"0.1.11"},"assert-plus":{"from":"assert-plus@0.1.2","version":"0.1.2"},"ctype":{"from":"ctype@0.5.2","version":"0.5.2"}},"from":"http-signature@~0.9.11","version":"0.9.11"},"json-stringify-safe":{"from":"json-stringify-safe@~4.0.0","version":"4.0.0"},"mime":{"from":"mime@~1.2.9","version":"1.2.11"},"node-uuid":{"from":"node-uuid@~1.4.0","version":"1.4.1"},"oauth-sign":{"from":"oauth-sign@~0.3.0","version":"0.3.0"},"qs":{"from":"qs@~0.6.0","version":"0.6.6"},"tunnel-agent":{"from":"tunnel-agent@~0.3.0","version":"0.3.0"}},"from":"request@~2.21.0","version":"2.21.0"},"vargs":{"from":"vargs@~0.1.0","version":"0.1.0"}},"from":"wd@0.1.5","version":"0.1.5"}},"from":"https://registry.npmjs.org/grunt-saucelabs/-/grunt-saucelabs-4.1.2.tgz","resolved":"https://registry.npmjs.org/grunt-saucelabs/-/grunt-saucelabs-4.1.2.tgz","version":"4.1.2"},"grunt-sed":{"dependencies":{"replace":{"dependencies":{"colors":{"from":"colors@0.5.1","version":"0.5.1"},"minimatch":{"dependencies":{"lru-cache":{"from":"lru-cache@2.5.0","version":"2.5.0"},"sigmund":{"from":"sigmund@1.0.0","version":"1.0.0"}},"from":"minimatch@0.2.14","version":"0.2.14"},"nomnom":{"dependencies":{"colors":{"from":"colors@0.5.1","version":"0.5.1"},"underscore":{"from":"underscore@1.4.4","version":"1.4.4"}},"from":"nomnom@1.6.2","version":"1.6.2"}},"from":"https://registry.npmjs.org/replace/-/replace-0.2.9.tgz","resolved":"https://registry.npmjs.org/replace/-/replace-0.2.9.tgz","version":"0.2.9"}},"from":"https://registry.npmjs.org/grunt-sed/-/grunt-sed-0.1.1.tgz","resolved":"https://registry.npmjs.org/grunt-sed/-/grunt-sed-0.1.1.tgz","version":"0.1.1"},"load-grunt-tasks":{"dependencies":{"findup-sync":{"dependencies":{"glob":{"dependencies":{"graceful-fs":{"from":"graceful-fs@~1.2.0","version":"1.2.3"},"inherits":{"from":"inherits@1","version":"1.0.0"},"minimatch":{"dependencies":{"lru-cache":{"from":"lru-cache@2","version":"2.5.0"},"sigmund":{"from":"sigmund@~1.0.0","version":"1.0.0"}},"from":"minimatch@~0.2.11","version":"0.2.14"}},"from":"glob@~3.1.21","version":"3.1.21"},"lodash":{"from":"lodash@~1.0.1","version":"1.0.1"}},"from":"findup-sync@~0.1.2","version":"0.1.2"},"globule":{"dependencies":{"glob":{"dependencies":{"graceful-fs":{"from":"graceful-fs@~1.2.0","version":"1.2.3"},"inherits":{"from":"inherits@1","version":"1.0.0"}},"from":"glob@~3.1.21","version":"3.1.21"},"lodash":{"from":"lodash@~1.0.1","version":"1.0.1"},"minimatch":{"dependencies":{"lru-cache":{"from":"lru-cache@2","version":"2.5.0"},"sigmund":{"from":"sigmund@~1.0.0","version":"1.0.0"}},"from":"minimatch@~0.2.11","version":"0.2.14"}},"from":"globule@~0.1.0","version":"0.1.0"}},"from":"load-grunt-tasks@0.2.1","version":"0.2.1"},"markdown":{"dependencies":{"nopt":{"dependencies":{"abbrev":{"from":"https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz","resolved":"https://registry.npmjs.org/abbrev/-/abbrev-1.0.4.tgz","version":"1.0.4"}},"from":"https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz","resolved":"https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz","version":"2.1.2"}},"from":"https://registry.npmjs.org/markdown/-/markdown-0.5.0.tgz","resolved":"https://registry.npmjs.org/markdown/-/markdown-0.5.0.tgz","version":"0.5.0"}},"name":"bootstrap","version":"3.0.3"} \ No newline at end of file diff --git a/test-infra/shrinkwrap.js b/test-infra/shrinkwrap.js new file mode 100644 index 0000000000..7a0328d41f --- /dev/null +++ b/test-infra/shrinkwrap.js @@ -0,0 +1,24 @@ +/* jshint node: true */ + +/* +This Grunt task updates the npm-shrinkwrap.canonical.json file that's used as the key for Bootstrap's npm packages cache. +This task should be run and the updated file should be committed whenever Bootstrap's dependencies change. +*/ + +var canonicallyJsonStringify = require('canonical-json'); +var NON_CANONICAL_FILE = 'npm-shrinkwrap.json'; +var DEST_FILE = 'test-infra/npm-shrinkwrap.canonical.json'; + + +function updateShrinkwrap(grunt) { + // Assumption: Non-canonical shrinkwrap already generated by prerequisite Grunt task + var shrinkwrapData = grunt.file.readJSON(NON_CANONICAL_FILE); + grunt.log.writeln('Deleting ' + NON_CANONICAL_FILE.cyan + '...'); + grunt.file.delete(NON_CANONICAL_FILE); + // Output as Canonical JSON in correct location + grunt.file.write(DEST_FILE, canonicallyJsonStringify(shrinkwrapData)); + grunt.log.writeln('File ' + DEST_FILE.cyan + ' updated.'); +} + + +module.exports = updateShrinkwrap; diff --git a/test-infra/uncached-npm-install.sh b/test-infra/uncached-npm-install.sh new file mode 100755 index 0000000000..1c56249862 --- /dev/null +++ b/test-infra/uncached-npm-install.sh @@ -0,0 +1,4 @@ +#!/bin/bash +cp test-infra/npm-shrinkwrap.canonical.json npm-shrinkwrap.json +npm install +rm npm-shrinkwrap.json