From 5508c70f3afd614d240101e9dec0e88359f3c7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 19 Apr 2013 11:19:47 +0100 Subject: [PATCH 0001/1021] Setup module. --- packages/bower-json/.gitignore | 3 ++ packages/bower-json/.jshintrc | 61 ++++++++++++++++++++++++++++ packages/bower-json/.travis.yml | 4 ++ packages/bower-json/lib/read-json.js | 0 packages/bower-json/package.json | 23 +++++++++++ packages/bower-json/test/test.js | 0 6 files changed, 91 insertions(+) create mode 100644 packages/bower-json/.gitignore create mode 100644 packages/bower-json/.jshintrc create mode 100644 packages/bower-json/.travis.yml create mode 100644 packages/bower-json/lib/read-json.js create mode 100644 packages/bower-json/package.json create mode 100644 packages/bower-json/test/test.js diff --git a/packages/bower-json/.gitignore b/packages/bower-json/.gitignore new file mode 100644 index 000000000..07ddee34e --- /dev/null +++ b/packages/bower-json/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +Thumbs.db +node_modules \ No newline at end of file diff --git a/packages/bower-json/.jshintrc b/packages/bower-json/.jshintrc new file mode 100644 index 000000000..52c609091 --- /dev/null +++ b/packages/bower-json/.jshintrc @@ -0,0 +1,61 @@ +{ + "predef": [ + "console", + "describe", + "it", + "after", + "afterEach", + "before", + "beforeEach" + ], + + "indent": 4, + "node": true, + "devel": true, + + "bitwise": false, + "curly": false, + "eqeqeq": true, + "forin": false, + "immed": true, + "latedef": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": true, + "plusplus": false, + "regexp": false, + "undef": true, + "unused": true, + "quotmark": "single", + "strict": false, + "trailing": true, + + "asi": false, + "boss": true, + "debug": false, + "eqnull": true, + "es5": false, + "esnext": false, + "evil": false, + "expr": false, + "funcscope": false, + "globalstrict": false, + "iterator": false, + "lastsemic": false, + "laxbreak": true, + "laxcomma": false, + "loopfunc": true, + "multistr": false, + "onecase": true, + "regexdash": false, + "scripturl": false, + "smarttabs": false, + "shadow": false, + "sub": false, + "supernew": true, + "validthis": false, + + "nomen": false, + "white": true +} diff --git a/packages/bower-json/.travis.yml b/packages/bower-json/.travis.yml new file mode 100644 index 000000000..2ca91f289 --- /dev/null +++ b/packages/bower-json/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.10" + - "0.8" \ No newline at end of file diff --git a/packages/bower-json/lib/read-json.js b/packages/bower-json/lib/read-json.js new file mode 100644 index 000000000..e69de29bb diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json new file mode 100644 index 000000000..15b37251b --- /dev/null +++ b/packages/bower-json/package.json @@ -0,0 +1,23 @@ +{ + "name": "read-bower-json", + "version": "0.0.0", + "description": "Read bower.json files with semantics, normalisation, defaults and validation.", + "author": "Twitter", + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/bower/read-bower-json/blob/master/LICENSE" + } + ], + "main": "lib/read-json", + "engines": { + "node": ">=0.8.0" + }, + "devDependencies": { + "mocha": "~1.8.2", + "expect.js": "~0.2.0" + }, + "scripts": { + "test": "mocha -R spec" + } +} diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js new file mode 100644 index 000000000..e69de29bb From 70880c066f24ecaeaa0db8f17d06843258e39885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 19 Apr 2013 12:27:35 +0100 Subject: [PATCH 0002/1021] Add LICENSE and README. --- packages/bower-json/LICENSE | 7 +++ packages/bower-json/README.md | 81 +++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 packages/bower-json/LICENSE create mode 100644 packages/bower-json/README.md diff --git a/packages/bower-json/LICENSE b/packages/bower-json/LICENSE new file mode 100644 index 000000000..fc4e20bc0 --- /dev/null +++ b/packages/bower-json/LICENSE @@ -0,0 +1,7 @@ +Copyright (c) 2012 Twitter and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md new file mode 100644 index 000000000..813e92922 --- /dev/null +++ b/packages/bower-json/README.md @@ -0,0 +1,81 @@ +read-bower-json + +---------------- + +Read `bower.json` files with semantics, normalisation, defaults and validation. + + +## Usage + +#### readJson(file, callback) + +Reads `file` and applies normalisation, defaults and validation according to the `bower.json` spec. + +```js +// Reads the `json` file. +readJson('/path/to/bower.json', function (err, json) { + if (err) { + console.error('There was an error reading the file'); + console.error(err.message); + return; + } + + console.log('JSON: ', json); +}); + +``` + + +#### readJson.parse(json, callback) + +Parses an object as `json` file. Useful when you want to apply normalisation, defaults and validation +directly to an object. + +```js +var readJson = require('read-bower-json'); + +var json = { + name: 'my-package', + version: '0.0.1' +}; + +readJson.parse(json, function (err, filename) { + if (err) { + console.error('There was an error parsing the object'); + console.error(err.message); + return; + } + + console.log('JSON: ', json); +}); +``` + + +#### readJson.find(folder, callback) + +Finds the `json` filename inside a folder. +Checks if a `bower.json` exists, falling back to the deprecated `component.json`. + +```js +var readJson = require('read-bower-json'); + +readJson.find('/path/to/folder', function (err, filename) { + if (err) { + console.error('There is no json file in the folder'); + return; + } + + console.log('Filename: ', filename); + + // Read its contents + readJson(filename, function () { + if (err) { + console.error('There was an error reading the file'); + console.error(err.message); + return; + } + + console.log('JSON: ', json); + }); +}); +``` From f5d5e59040c485b165bdc7d05e107a6faddb1d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 19 Apr 2013 12:31:04 +0100 Subject: [PATCH 0003/1021] Typo. --- packages/bower-json/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index 813e92922..c3bc5d6a6 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -28,7 +28,7 @@ readJson('/path/to/bower.json', function (err, json) { #### readJson.parse(json, callback) -Parses an object as `json` file. Useful when you want to apply normalisation, defaults and validation +Parses an object. Useful when you want to apply normalisation, defaults and validation directly to an object. ```js From 9c3757fb0c1e169c7f26d20bda14f1c01e42727d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 19 Apr 2013 12:32:03 +0100 Subject: [PATCH 0004/1021] Doc improv. --- packages/bower-json/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index c3bc5d6a6..3bb440e07 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -12,7 +12,8 @@ Read `bower.json` files with semantics, normalisation, defaults and validation. Reads `file` and applies normalisation, defaults and validation according to the `bower.json` spec. ```js -// Reads the `json` file. +var readJson = require('read-bower-json'); + readJson('/path/to/bower.json', function (err, json) { if (err) { console.error('There was an error reading the file'); @@ -67,7 +68,7 @@ readJson.find('/path/to/folder', function (err, filename) { console.log('Filename: ', filename); - // Read its contents + // Now that we got the filename, we can read its contents readJson(filename, function () { if (err) { console.error('There was an error reading the file'); From 07281f050c23c043d12c9fabc3bc2d3cc0d39cc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 19 Apr 2013 13:58:18 +0100 Subject: [PATCH 0005/1021] Change to just bower-json. --- packages/bower-json/README.md | 24 ++++++++++--------- .../lib/{read-json.js => bower-json.js} | 0 packages/bower-json/package.json | 4 ++-- 3 files changed, 15 insertions(+), 13 deletions(-) rename packages/bower-json/lib/{read-json.js => bower-json.js} (100%) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index 3bb440e07..41d5aa6c3 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -1,4 +1,4 @@ -read-bower-json +bower-json ---------------- @@ -7,14 +7,14 @@ Read `bower.json` files with semantics, normalisation, defaults and validation. ## Usage -#### readJson(file, callback) +#### .read(file, callback) Reads `file` and applies normalisation, defaults and validation according to the `bower.json` spec. ```js -var readJson = require('read-bower-json'); +var bowerJson = require('bower-json'); -readJson('/path/to/bower.json', function (err, json) { +bowerJson.read('/path/to/bower.json', function (err, json) { if (err) { console.error('There was an error reading the file'); console.error(err.message); @@ -24,23 +24,25 @@ readJson('/path/to/bower.json', function (err, json) { console.log('JSON: ', json); }); +// Can also be used by simply calling bowerJson() + ``` -#### readJson.parse(json, callback) +#### .parse(json, callback) Parses an object. Useful when you want to apply normalisation, defaults and validation directly to an object. ```js -var readJson = require('read-bower-json'); +var bowerJson = require('bower-json'); var json = { name: 'my-package', version: '0.0.1' }; -readJson.parse(json, function (err, filename) { +bowerJson.parse(json, function (err, filename) { if (err) { console.error('There was an error parsing the object'); console.error(err.message); @@ -52,15 +54,15 @@ readJson.parse(json, function (err, filename) { ``` -#### readJson.find(folder, callback) +#### .find(folder, callback) Finds the `json` filename inside a folder. Checks if a `bower.json` exists, falling back to the deprecated `component.json`. ```js -var readJson = require('read-bower-json'); +var bowerJson = require('bower-json'); -readJson.find('/path/to/folder', function (err, filename) { +bowerJson.find('/path/to/folder', function (err, filename) { if (err) { console.error('There is no json file in the folder'); return; @@ -69,7 +71,7 @@ readJson.find('/path/to/folder', function (err, filename) { console.log('Filename: ', filename); // Now that we got the filename, we can read its contents - readJson(filename, function () { + bowerJson.read(filename, function () { if (err) { console.error('There was an error reading the file'); console.error(err.message); diff --git a/packages/bower-json/lib/read-json.js b/packages/bower-json/lib/bower-json.js similarity index 100% rename from packages/bower-json/lib/read-json.js rename to packages/bower-json/lib/bower-json.js diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 15b37251b..69fcca0be 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,12 +1,12 @@ { - "name": "read-bower-json", + "name": "bower-json", "version": "0.0.0", "description": "Read bower.json files with semantics, normalisation, defaults and validation.", "author": "Twitter", "licenses": [ { "type": "MIT", - "url": "https://github.com/bower/read-bower-json/blob/master/LICENSE" + "url": "https://github.com/bower/bower-json/blob/master/LICENSE" } ], "main": "lib/read-json", From 5a17314b2cb8cd6e39b02ce4730f477756e82bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Fri, 19 Apr 2013 22:00:24 +0200 Subject: [PATCH 0006/1021] Oops. --- packages/bower-json/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 69fcca0be..4bd00521e 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/bower/bower-json/blob/master/LICENSE" } ], - "main": "lib/read-json", + "main": "lib/bower-json", "engines": { "node": ">=0.8.0" }, From c3311df2a87435e58d7f9be9ddd8fa0d2559c258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 20 Apr 2013 11:20:41 +0100 Subject: [PATCH 0007/1021] Initial implementation and tests. --- packages/bower-json/lib/bower-json.js | 48 +++++++++++++ .../bower-json/test/pkg-bower-json/bower.json | 4 ++ .../test/pkg-component-json/component.json | 4 ++ packages/bower-json/test/test.js | 67 +++++++++++++++++++ 4 files changed, 123 insertions(+) create mode 100644 packages/bower-json/test/pkg-bower-json/bower.json create mode 100644 packages/bower-json/test/pkg-component-json/component.json diff --git a/packages/bower-json/lib/bower-json.js b/packages/bower-json/lib/bower-json.js index e69de29bb..922958ac2 100644 --- a/packages/bower-json/lib/bower-json.js +++ b/packages/bower-json/lib/bower-json.js @@ -0,0 +1,48 @@ +var fs = require('fs'); +var path = require('path'); + +function read(file, callback) { + fs.readFile(file, function (err, contents) { + if (err) return callback(err); + + var json; + + try { + json = JSON.parse(contents); + } catch (e) { + err = new Error('Not a valid JSON file: ' + e.message); + err.code = 'EINVFRMT'; + return callback(err); + } + + callback(null, parse(json)); + }); +} + +function parse(json) { + // Apply normalisation, defaults, validation here + return json; +} + +function find(folder, callback) { + var file = path.resolve(path.join(folder, 'bower.json')); + + fs.exists(file, function (exists) { + if (exists) return callback(null, file); + + file = path.resolve(path.join(folder, 'component.json')); + + fs.exists(file, function (exists) { + if (exists) return callback(null, file); + + var err = new Error('Folder has no json file'); + err.code = 'ENOENT'; + callback(err); + }); + }); +} + +module.exports = read; +module.exports.read = read; +module.exports.parse = parse; +module.exports.find = find; \ No newline at end of file diff --git a/packages/bower-json/test/pkg-bower-json/bower.json b/packages/bower-json/test/pkg-bower-json/bower.json new file mode 100644 index 000000000..099c57f8c --- /dev/null +++ b/packages/bower-json/test/pkg-bower-json/bower.json @@ -0,0 +1,4 @@ +{ + "name": "some-pkg", + "version": "0.0.0" +} \ No newline at end of file diff --git a/packages/bower-json/test/pkg-component-json/component.json b/packages/bower-json/test/pkg-component-json/component.json new file mode 100644 index 000000000..099c57f8c --- /dev/null +++ b/packages/bower-json/test/pkg-component-json/component.json @@ -0,0 +1,4 @@ +{ + "name": "some-pkg", + "version": "0.0.0" +} \ No newline at end of file diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index e69de29bb..e7e87c2ae 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -0,0 +1,67 @@ +var path = require('path'); +var expect = require('expect.js'); +var bowerJson = require('../lib/bower-json'); + +describe('.find', function () { + it('should find the bower.json file', function (done) { + bowerJson.find(__dirname + '/pkg-bower-json', function (err, file) { + if (err) return done(err); + + expect(file).to.equal(path.resolve(__dirname + '/pkg-bower-json/bower.json')); + done(); + }); + }); + + it('should fallback to the component.json file', function (done) { + bowerJson.find(__dirname + '/pkg-component-json', function (err, file) { + if (err) return done(err); + + expect(file).to.equal(path.resolve(__dirname + '/pkg-component-json/component.json')); + done(); + }); + }); + + it('should give error if no component.json / bower.json is found', function (done) { + bowerJson.find(__dirname, function (err) { + expect(err).to.be.an(Error); + expect(err.code).to.equal('ENOENT'); + done(); + }); + }); +}); + +describe('.read', function () { + it('should give error if file does not exists', function (done) { + bowerJson.read(__dirname + '/willneverexist', function (err) { + expect(err).to.be.an(Error); + expect(err.code).to.equal('ENOENT'); + done(); + }); + }); + + it('should read the file and give an object', function (done) { + bowerJson.read(__dirname + '/pkg-bower-json/bower.json', function (err, json) { + if (err) return done(err); + + expect(json).to.be.an('object'); + expect(json.name).to.equal('some-pkg'); + expect(json.version).to.equal('0.0.0'); + done(); + }); + }); + + it.skip('should validate the returned object'); +}); + +describe('.parse', function () { + it('should return the same object', function () { + var json = { + name: 'foo', + version: '0.0.0' + }; + + expect(bowerJson.parse(json)).to.equal(json); + }); + + it.skip('should validate the passed object'); +}); \ No newline at end of file From eacf121f78663a3b65babe9da255324b4a4aeaae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 20 Apr 2013 11:23:24 +0100 Subject: [PATCH 0008/1021] Update README. --- packages/bower-json/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index 41d5aa6c3..2b5838ae5 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -14,6 +14,7 @@ Reads `file` and applies normalisation, defaults and validation according to the ```js var bowerJson = require('bower-json'); +// Can also be used by simply calling bowerJson() bowerJson.read('/path/to/bower.json', function (err, json) { if (err) { console.error('There was an error reading the file'); @@ -23,9 +24,6 @@ bowerJson.read('/path/to/bower.json', function (err, json) { console.log('JSON: ', json); }); - -// Can also be used by simply calling bowerJson() - ``` From 30608665860dad56eb935b09874eb740b26dfba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 20 Apr 2013 11:37:15 +0100 Subject: [PATCH 0009/1021] Add test for invalid json. --- packages/bower-json/lib/bower-json.js | 5 ++--- packages/bower-json/package.json | 2 +- .../bower-json/test/pkg-bower-json-invalid/bower.json | 1 + packages/bower-json/test/test.js | 10 +++++++++- 4 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 packages/bower-json/test/pkg-bower-json-invalid/bower.json diff --git a/packages/bower-json/lib/bower-json.js b/packages/bower-json/lib/bower-json.js index 922958ac2..01eb59020 100644 --- a/packages/bower-json/lib/bower-json.js +++ b/packages/bower-json/lib/bower-json.js @@ -9,9 +9,8 @@ function read(file, callback) { try { json = JSON.parse(contents); - } catch (e) { - err = new Error('Not a valid JSON file: ' + e.message); - err.code = 'EINVFRMT'; + } catch (err) { + err.code = 'ESYNTAX'; return callback(err); } diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 4bd00521e..2da9d7943 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,6 +1,6 @@ { "name": "bower-json", - "version": "0.0.0", + "version": "0.0.0-rc0", "description": "Read bower.json files with semantics, normalisation, defaults and validation.", "author": "Twitter", "licenses": [ diff --git a/packages/bower-json/test/pkg-bower-json-invalid/bower.json b/packages/bower-json/test/pkg-bower-json-invalid/bower.json new file mode 100644 index 000000000..81750b96f --- /dev/null +++ b/packages/bower-json/test/pkg-bower-json-invalid/bower.json @@ -0,0 +1 @@ +{ \ No newline at end of file diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index e7e87c2ae..cb7bb01eb 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -21,7 +21,7 @@ describe('.find', function () { }); }); - it('should give error if no component.json / bower.json is found', function (done) { + it('should error if no component.json / bower.json is found', function (done) { bowerJson.find(__dirname, function (err) { expect(err).to.be.an(Error); expect(err.code).to.equal('ENOENT'); @@ -39,6 +39,14 @@ describe('.read', function () { }); }); + it('should give error if when reading an invalid json', function (done) { + bowerJson.read(__dirname + '/pkg-bower-json-invalid/bower.json', function (err) { + expect(err).to.be.an(Error); + expect(err.code).to.equal('ESYNTAX'); + done(); + }); + }); + it('should read the file and give an object', function (done) { bowerJson.read(__dirname + '/pkg-bower-json/bower.json', function (err, json) { if (err) return done(err); From bb98627d2b6fb417906979f71d40e36177c434b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 20 Apr 2013 12:17:00 +0100 Subject: [PATCH 0010/1021] Made parse async for consistency, tweak error codes. --- packages/bower-json/README.md | 13 ++++++++----- packages/bower-json/lib/bower-json.js | 11 ++++++----- packages/bower-json/test/test.js | 10 +++++++--- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index 2b5838ae5..c40eb13fd 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -9,8 +9,10 @@ Read `bower.json` files with semantics, normalisation, defaults and validation. #### .read(file, callback) -Reads `file` and applies normalisation, defaults and validation according to the `bower.json` spec. - +Reads `file` and applies normalisation, defaults and validation according to the `bower.json` spec. +If the passed `file` does not exists, the callback is called with a `error.code` of `ENOENT`. +If the passed `file` contents are not a valid JSON, the callback is called a `error.code` of `EMALFORMED`. +If the passed ```js var bowerJson = require('bower-json'); @@ -29,8 +31,8 @@ bowerJson.read('/path/to/bower.json', function (err, json) { #### .parse(json, callback) -Parses an object. Useful when you want to apply normalisation, defaults and validation -directly to an object. +Parses an object. Useful when you want to apply normalisation, defaults and validation directly to an object. +If the `json` is invalid, the callback is called with a `error.code` of `EINVALID`. ```js var bowerJson = require('bower-json'); @@ -56,6 +58,7 @@ bowerJson.parse(json, function (err, filename) { Finds the `json` filename inside a folder. Checks if a `bower.json` exists, falling back to the deprecated `component.json`. +If no file was found, the callback is called with a `error.code` of `ENOENT`. ```js var bowerJson = require('bower-json'); @@ -79,4 +82,4 @@ bowerJson.find('/path/to/folder', function (err, filename) { console.log('JSON: ', json); }); }); -``` +``` \ No newline at end of file diff --git a/packages/bower-json/lib/bower-json.js b/packages/bower-json/lib/bower-json.js index 01eb59020..45a444d5f 100644 --- a/packages/bower-json/lib/bower-json.js +++ b/packages/bower-json/lib/bower-json.js @@ -8,19 +8,20 @@ function read(file, callback) { var json; try { - json = JSON.parse(contents); + json = JSON.parse(contents.toString()); } catch (err) { - err.code = 'ESYNTAX'; + err.code = 'EMALFORMED'; return callback(err); } - callback(null, parse(json)); + parse(json, callback); }); } -function parse(json) { +function parse(json, callback) { // Apply normalisation, defaults, validation here - return json; + // If something is invalid, the error.code should be EINVALID + callback(null, json); } function find(folder, callback) { diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index cb7bb01eb..c9cb10678 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -25,6 +25,7 @@ describe('.find', function () { bowerJson.find(__dirname, function (err) { expect(err).to.be.an(Error); expect(err.code).to.equal('ENOENT'); + expect(err.message).to.contain('no json file'); done(); }); }); @@ -42,7 +43,7 @@ describe('.read', function () { it('should give error if when reading an invalid json', function (done) { bowerJson.read(__dirname + '/pkg-bower-json-invalid/bower.json', function (err) { expect(err).to.be.an(Error); - expect(err.code).to.equal('ESYNTAX'); + expect(err.code).to.equal('EMALFORMED'); done(); }); }); @@ -62,13 +63,16 @@ describe('.read', function () { }); describe('.parse', function () { - it('should return the same object', function () { + it('should parse an object, giving a parsed object', function (done) { var json = { name: 'foo', version: '0.0.0' }; - expect(bowerJson.parse(json)).to.equal(json); + bowerJson.parse(json, function (err, retJson) { + expect(json).to.eql(retJson); + done(); + }); }); it.skip('should validate the passed object'); From a7c8c08183be6f37d097e242065b49cf1c8d1e18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Tue, 23 Apr 2013 10:12:47 +0200 Subject: [PATCH 0011/1021] Update README.md --- packages/bower-json/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index c40eb13fd..4883ac91c 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -1,6 +1,4 @@ -bower-json - ----------------- +# bower-json Read `bower.json` files with semantics, normalisation, defaults and validation. @@ -82,4 +80,4 @@ bowerJson.find('/path/to/folder', function (err, filename) { console.log('JSON: ', json); }); }); -``` \ No newline at end of file +``` From 080b25e30c994e850fe7498970086ef8ed1e36bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 23 Apr 2013 23:58:35 +0100 Subject: [PATCH 0012/1021] Update .gitignore. --- packages/bower-json/.gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/bower-json/.gitignore b/packages/bower-json/.gitignore index 07ddee34e..c2a79d649 100644 --- a/packages/bower-json/.gitignore +++ b/packages/bower-json/.gitignore @@ -1,3 +1,5 @@ +# General .DS_Store Thumbs.db -node_modules \ No newline at end of file +node_modules +npm-debug.log \ No newline at end of file From 19475db7dd611a52f3c3955549f7053f9fa00c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Sun, 5 May 2013 04:00:55 +0200 Subject: [PATCH 0013/1021] Typos. --- packages/bower-json/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index 4883ac91c..b82042c99 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -8,9 +8,9 @@ Read `bower.json` files with semantics, normalisation, defaults and validation. #### .read(file, callback) Reads `file` and applies normalisation, defaults and validation according to the `bower.json` spec. -If the passed `file` does not exists, the callback is called with a `error.code` of `ENOENT`. -If the passed `file` contents are not a valid JSON, the callback is called a `error.code` of `EMALFORMED`. -If the passed +If the passed `file` does not exists, the callback is called with `error.code` equal to `ENOENT`. +If the passed `file` contents are not a valid JSON, the callback is called with `error.code` equal to `EMALFORMED`. + ```js var bowerJson = require('bower-json'); @@ -30,7 +30,7 @@ bowerJson.read('/path/to/bower.json', function (err, json) { #### .parse(json, callback) Parses an object. Useful when you want to apply normalisation, defaults and validation directly to an object. -If the `json` is invalid, the callback is called with a `error.code` of `EINVALID`. +If the `json` is invalid, the callback is called with `error.code` equal to `EINVALID`. ```js var bowerJson = require('bower-json'); From 05275c8938ff887dda8a6cf9adba92658b07defb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Sun, 5 May 2013 04:02:15 +0200 Subject: [PATCH 0014/1021] Improve README. --- packages/bower-json/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index b82042c99..c01d4ddb5 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -10,6 +10,7 @@ Read `bower.json` files with semantics, normalisation, defaults and validation. Reads `file` and applies normalisation, defaults and validation according to the `bower.json` spec. If the passed `file` does not exists, the callback is called with `error.code` equal to `ENOENT`. If the passed `file` contents are not a valid JSON, the callback is called with `error.code` equal to `EMALFORMED`. +If the `json` does not comply with the `bower.json` spec, the callback is called with `error.code` equal to `EINVALID`. ```js var bowerJson = require('bower-json'); @@ -30,7 +31,7 @@ bowerJson.read('/path/to/bower.json', function (err, json) { #### .parse(json, callback) Parses an object. Useful when you want to apply normalisation, defaults and validation directly to an object. -If the `json` is invalid, the callback is called with `error.code` equal to `EINVALID`. +If the `json` does not comply with the `bower.json` spec, the callback is called with `error.code` equal to `EINVALID`. ```js var bowerJson = require('bower-json'); From 93e0e815d7ce2ac01b4a89154aa7422022480250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Sun, 5 May 2013 04:02:34 +0200 Subject: [PATCH 0015/1021] Fix indentation. --- packages/bower-json/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index c01d4ddb5..30168ad8a 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -9,7 +9,7 @@ Read `bower.json` files with semantics, normalisation, defaults and validation. Reads `file` and applies normalisation, defaults and validation according to the `bower.json` spec. If the passed `file` does not exists, the callback is called with `error.code` equal to `ENOENT`. -If the passed `file` contents are not a valid JSON, the callback is called with `error.code` equal to `EMALFORMED`. +If the passed `file` contents are not a valid JSON, the callback is called with `error.code` equal to `EMALFORMED`. If the `json` does not comply with the `bower.json` spec, the callback is called with `error.code` equal to `EINVALID`. ```js From f668596667103132fc489e89fa0c91f792b97409 Mon Sep 17 00:00:00 2001 From: Dylan Greene Date: Mon, 6 May 2013 17:02:57 -0400 Subject: [PATCH 0016/1021] Made the error message more understandable. --- packages/bower-json/lib/bower-json.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/lib/bower-json.js b/packages/bower-json/lib/bower-json.js index 45a444d5f..0e75536c6 100644 --- a/packages/bower-json/lib/bower-json.js +++ b/packages/bower-json/lib/bower-json.js @@ -35,7 +35,7 @@ function find(folder, callback) { fs.exists(file, function (exists) { if (exists) return callback(null, file); - var err = new Error('Folder has no json file'); + var err = new Error('Neither bower.json nor component.json were found in ' + folder); err.code = 'ENOENT'; callback(err); }); From 373abf1b24be342c736c599cd901f56b1d995865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Mon, 6 May 2013 23:11:51 +0200 Subject: [PATCH 0017/1021] Update README.md --- packages/bower-json/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index 30168ad8a..c6d68a1e7 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -1,4 +1,4 @@ -# bower-json +# bower-json [![Build Status](https://secure.travis-ci.org/bower/bower-json.png?branch=master)](http://travis-ci.org/bower/bower-json) Read `bower.json` files with semantics, normalisation, defaults and validation. From cff641ef80b611237879507cf67886fb11c5cc4f Mon Sep 17 00:00:00 2001 From: Dylan Greene Date: Mon, 6 May 2013 22:16:52 -0400 Subject: [PATCH 0018/1021] add quotes around the path and fix the test --- packages/bower-json/lib/bower-json.js | 2 +- packages/bower-json/test/test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-json/lib/bower-json.js b/packages/bower-json/lib/bower-json.js index 0e75536c6..b0a0059e2 100644 --- a/packages/bower-json/lib/bower-json.js +++ b/packages/bower-json/lib/bower-json.js @@ -35,7 +35,7 @@ function find(folder, callback) { fs.exists(file, function (exists) { if (exists) return callback(null, file); - var err = new Error('Neither bower.json nor component.json were found in ' + folder); + var err = new Error('Neither bower.json nor component.json were found in "' + folder + '"'); err.code = 'ENOENT'; callback(err); }); diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index c9cb10678..a391435b9 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -25,7 +25,7 @@ describe('.find', function () { bowerJson.find(__dirname, function (err) { expect(err).to.be.an(Error); expect(err.code).to.equal('ENOENT'); - expect(err.message).to.contain('no json file'); + expect(err.message).to.equal('Neither bower.json nor component.json were found in "' + __dirname + '"'); done(); }); }); From 6932b8c378e4b3914e0138563cd846be57cb071b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 7 May 2013 17:26:10 +0100 Subject: [PATCH 0019/1021] Better license format. --- packages/bower-json/LICENSE | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/bower-json/LICENSE b/packages/bower-json/LICENSE index fc4e20bc0..13e8246fd 100644 --- a/packages/bower-json/LICENSE +++ b/packages/bower-json/LICENSE @@ -1,7 +1,19 @@ Copyright (c) 2012 Twitter and other contributors -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 42775d3477c30aece7d97d2fa8227797508fef7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 7 May 2013 17:26:22 +0100 Subject: [PATCH 0020/1021] Improve gitignore. --- packages/bower-json/.gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/bower-json/.gitignore b/packages/bower-json/.gitignore index c2a79d649..5171c5408 100644 --- a/packages/bower-json/.gitignore +++ b/packages/bower-json/.gitignore @@ -1,5 +1,2 @@ -# General -.DS_Store -Thumbs.db node_modules npm-debug.log \ No newline at end of file From 7f2db8a9a7bfd5954449f125ac0760fca30d4ec8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 7 May 2013 17:30:29 +0100 Subject: [PATCH 0021/1021] Setup project. --- packages/bower-registry-client/.gitignore | 2 + packages/bower-registry-client/.jshintrc | 61 +++++++++++++++++++++ packages/bower-registry-client/.travis.yml | 4 ++ packages/bower-registry-client/LICENSE | 19 +++++++ packages/bower-registry-client/README.md | 32 +++++++++++ packages/bower-registry-client/package.json | 23 ++++++++ 6 files changed, 141 insertions(+) create mode 100644 packages/bower-registry-client/.gitignore create mode 100644 packages/bower-registry-client/.jshintrc create mode 100644 packages/bower-registry-client/.travis.yml create mode 100644 packages/bower-registry-client/LICENSE create mode 100644 packages/bower-registry-client/README.md create mode 100644 packages/bower-registry-client/package.json diff --git a/packages/bower-registry-client/.gitignore b/packages/bower-registry-client/.gitignore new file mode 100644 index 000000000..5171c5408 --- /dev/null +++ b/packages/bower-registry-client/.gitignore @@ -0,0 +1,2 @@ +node_modules +npm-debug.log \ No newline at end of file diff --git a/packages/bower-registry-client/.jshintrc b/packages/bower-registry-client/.jshintrc new file mode 100644 index 000000000..52c609091 --- /dev/null +++ b/packages/bower-registry-client/.jshintrc @@ -0,0 +1,61 @@ +{ + "predef": [ + "console", + "describe", + "it", + "after", + "afterEach", + "before", + "beforeEach" + ], + + "indent": 4, + "node": true, + "devel": true, + + "bitwise": false, + "curly": false, + "eqeqeq": true, + "forin": false, + "immed": true, + "latedef": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": true, + "plusplus": false, + "regexp": false, + "undef": true, + "unused": true, + "quotmark": "single", + "strict": false, + "trailing": true, + + "asi": false, + "boss": true, + "debug": false, + "eqnull": true, + "es5": false, + "esnext": false, + "evil": false, + "expr": false, + "funcscope": false, + "globalstrict": false, + "iterator": false, + "lastsemic": false, + "laxbreak": true, + "laxcomma": false, + "loopfunc": true, + "multistr": false, + "onecase": true, + "regexdash": false, + "scripturl": false, + "smarttabs": false, + "shadow": false, + "sub": false, + "supernew": true, + "validthis": false, + + "nomen": false, + "white": true +} diff --git a/packages/bower-registry-client/.travis.yml b/packages/bower-registry-client/.travis.yml new file mode 100644 index 000000000..2ca91f289 --- /dev/null +++ b/packages/bower-registry-client/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.10" + - "0.8" \ No newline at end of file diff --git a/packages/bower-registry-client/LICENSE b/packages/bower-registry-client/LICENSE new file mode 100644 index 000000000..13e8246fd --- /dev/null +++ b/packages/bower-registry-client/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012 Twitter and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md new file mode 100644 index 000000000..25ac3d6b7 --- /dev/null +++ b/packages/bower-registry-client/README.md @@ -0,0 +1,32 @@ +# bower-courier + +A messenger, usually travelling in haste, bearing urgent news, important reports or packages, diplomatic messages, etc. +This module allows you to interact with the Bower server API. + + +## Usage + +#### .lookup(name, options, callback) + +Looks the package `name`, giving you the associated registered URL. +The `options` argument is optional. + +```js +var courier = require('bower-courier'); + +// Can also be used by simply calling bowerJson() +courier.lookup(name, function (err, url) { + if (err) { + console.error(err.message); + return; + } + + console.log('URL: ', url); +}); +``` + +#### .register(name, url, options, callback) + +#### .search(str, options, callback) + +#### .info(name, options, callback) \ No newline at end of file diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json new file mode 100644 index 000000000..680f926f5 --- /dev/null +++ b/packages/bower-registry-client/package.json @@ -0,0 +1,23 @@ +{ + "name": "bower-courier", + "version": "0.0.0-rc0", + "description": "Provides easily interaction with the Bower server API.", + "author": "Twitter", + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/bower/bower-courier/blob/master/LICENSE" + } + ], + "main": "lib/courier", + "engines": { + "node": ">=0.8.0" + }, + "devDependencies": { + "mocha": "~1.8.2", + "expect.js": "~0.2.0" + }, + "scripts": { + "test": "mocha -R spec" + } +} From 3e90471fa2023d7315d2606a9128266468f76604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 7 May 2013 17:31:12 +0100 Subject: [PATCH 0022/1021] Setup project. --- packages/bower-registry-client/README.md | 14 +++++++++----- packages/bower-registry-client/package.json | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index 25ac3d6b7..017274311 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -1,20 +1,24 @@ -# bower-courier +# bower-courier [![Build Status](https://secure.travis-ci.org/bower/courier.png?branch=master)](http://travis-ci.org/bower/courier) -A messenger, usually travelling in haste, bearing urgent news, important reports or packages, diplomatic messages, etc. -This module allows you to interact with the Bower server API. +*A messenger, usually travelling in haste, bearing urgent news, important reports or packages, diplomatic messages, etc.* +This module allows you to easily interact with the Bower server API. ## Usage #### .lookup(name, options, callback) -Looks the package `name`, giving you the associated registered URL. +Looks the package `name`, giving you the associated registered URL. The `options` argument is optional. +Available options: +- registry: an array of registry search endpoints (defaults to the Bower server) +- skipCache: true to skip lookup cache (defaults to false) +- timeout: the timeout for the requests to finish (defaults to 5000) + ```js var courier = require('bower-courier'); -// Can also be used by simply calling bowerJson() courier.lookup(name, function (err, url) { if (err) { console.error(err.message); diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 680f926f5..962dbd99d 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,7 +1,7 @@ { "name": "bower-courier", "version": "0.0.0-rc0", - "description": "Provides easily interaction with the Bower server API.", + "description": "Provides easy interaction with the Bower server API.", "author": "Twitter", "licenses": [ { From 73bab73db6a00b8fb93746bca66ecfc1836a59d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Thu, 9 May 2013 13:11:57 +0100 Subject: [PATCH 0023/1021] Initial implementation of lookup. --- packages/bower-registry-client/README.md | 2 +- packages/bower-registry-client/lib/index.js | 11 +++ packages/bower-registry-client/lib/info.js | 0 packages/bower-registry-client/lib/lookup.js | 75 +++++++++++++++++++ .../bower-registry-client/lib/register.js | 0 packages/bower-registry-client/lib/search.js | 0 .../lib/util/createError.js | 8 ++ .../lib/util/parseOptions.js | 42 +++++++++++ packages/bower-registry-client/package.json | 6 +- 9 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 packages/bower-registry-client/lib/index.js create mode 100644 packages/bower-registry-client/lib/info.js create mode 100644 packages/bower-registry-client/lib/lookup.js create mode 100644 packages/bower-registry-client/lib/register.js create mode 100644 packages/bower-registry-client/lib/search.js create mode 100644 packages/bower-registry-client/lib/util/createError.js create mode 100644 packages/bower-registry-client/lib/util/parseOptions.js diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index 017274311..ec6e37294 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -8,7 +8,7 @@ This module allows you to easily interact with the Bower server API. #### .lookup(name, options, callback) -Looks the package `name`, giving you the associated registered URL. +Looks the registry for the package `name`, giving you the associated registered URL. The `options` argument is optional. Available options: diff --git a/packages/bower-registry-client/lib/index.js b/packages/bower-registry-client/lib/index.js new file mode 100644 index 000000000..a0c88b8bd --- /dev/null +++ b/packages/bower-registry-client/lib/index.js @@ -0,0 +1,11 @@ +var info = require('./info'); +var lookup = require('./lookup'); +var search = require('./search'); +var register = require('./register'); + +module.exports = { + info: info, + lookup: lookup, + search: search, + register: register +}; \ No newline at end of file diff --git a/packages/bower-registry-client/lib/info.js b/packages/bower-registry-client/lib/info.js new file mode 100644 index 000000000..e69de29bb diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js new file mode 100644 index 000000000..feaebffbd --- /dev/null +++ b/packages/bower-registry-client/lib/lookup.js @@ -0,0 +1,75 @@ +var async = require('async'); +var request = require('request'); +var parseOptions = require('./util/parseOptions'); +var createError = require('./util/createError'); + +function lookup(name, options, callback) { + var url; + var total; + var current = 0; + + if (typeof options === 'function') { + callback = options; + options = {}; + } + + // Parse and set default options + options = parseOptions.forRead(options); + + // If no registry entries where passed, simply + // error with package not found + total = options.registry.length; + if (!total) { + return callback(createError('Package "' + name + '" not found', 'ENOTFOUND')); + } + + // Lookup package in series until we got its URL + async.doUntil(function (next) { + var requestUrl = options.registry[current] + '/packages/' + encodeURIComponent(name); + + request.get(requestUrl, { + proxy: options.proxy, + timeout: options.timeout, + json: true + }, function (err, response, body) { + // If there was an internal error (e.g. timeout) + if (err) { + return next(createError('Request to "' + requestUrl + '" failed: ' + err.message, err.code)); + } + + // If not found, try next + if (response.statusCode === 404) { + return next(); + } + + // Abort if there was an error (range different than 2xx) + if (response.statusCode < 200 || response.statusCode > 299) { + return next(createError('Request to "' + requestUrl + '" failed with ' + response.statusCode, 'EINVRES')); + } + + // Validate response body, since we are expecting a JSON object + // If the server returns an invalid JSON, it's still a string + if (typeof body !== 'object') { + return next(createError('Response of request to "' + requestUrl + '" is not a valid json', 'EINVRES')); + } + + callback(null, body.url); + }); + }, function () { + return !url && current++ < total; + }, function (err) { + // If some of the registry entries failed, error out + if (err) { + return callback(err); + } + + // If at the end we still have no URL, create an appropriate error + if (!url) { + return callback(createError('Package "' + name + '" not found', 'ENOTFOUND')); + } + + callback(null, url); + }); +} + +module.exports = lookup; \ No newline at end of file diff --git a/packages/bower-registry-client/lib/register.js b/packages/bower-registry-client/lib/register.js new file mode 100644 index 000000000..e69de29bb diff --git a/packages/bower-registry-client/lib/search.js b/packages/bower-registry-client/lib/search.js new file mode 100644 index 000000000..e69de29bb diff --git a/packages/bower-registry-client/lib/util/createError.js b/packages/bower-registry-client/lib/util/createError.js new file mode 100644 index 000000000..6be8e2810 --- /dev/null +++ b/packages/bower-registry-client/lib/util/createError.js @@ -0,0 +1,8 @@ +function createError(msg, code) { + var err = new Error(msg); + err.code = code; + + return err; +} + +module.exports = createError; \ No newline at end of file diff --git a/packages/bower-registry-client/lib/util/parseOptions.js b/packages/bower-registry-client/lib/util/parseOptions.js new file mode 100644 index 000000000..4ecb3836d --- /dev/null +++ b/packages/bower-registry-client/lib/util/parseOptions.js @@ -0,0 +1,42 @@ +function forRead(options) { + options = options || {}; + + // Registry + if (!options.registry) { + options.registry = ['https://bower.herokuapp.com']; + } else { + if (!Array.isArray(options.registry)) { + options.registry = [options.registry]; + } + + // Ensure that every registry does not end with / + options.registry = options.registry.map(function (url) { + return url.replace(/\/+$/, ''); + }); + } + + // Timeout + if (typeof options.timeout !== 'number') { + options.timeout = 5000; + } + + return options; +} + +function forWrite(options) { + options = options || {}; + + // Registry + if (!options.registry) { + options.registry = 'https://bower.herokuapp.com'; + } else { + options.registry.replace(/\/+$/, ''); + } + + // TODO: + + return options; +} + +module.exports.forRead = forRead; +module.exports.forWrite = forWrite; \ No newline at end of file diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 962dbd99d..ff21bc806 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/bower/bower-courier/blob/master/LICENSE" } ], - "main": "lib/courier", + "main": "lib", "engines": { "node": ">=0.8.0" }, @@ -19,5 +19,9 @@ }, "scripts": { "test": "mocha -R spec" + }, + "dependencies": { + "async": "~0.2.8", + "request": "~2.21.0" } } From 423ce54d8a5f7e9933b1a0e53365752fc450c265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Thu, 9 May 2013 13:17:56 +0100 Subject: [PATCH 0024/1021] Add empty tests and add cache TODO. --- packages/bower-registry-client/lib/lookup.js | 10 ++++++++-- packages/bower-registry-client/test/lookup.js | 0 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 packages/bower-registry-client/test/lookup.js diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index feaebffbd..452cb7d81 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -16,14 +16,20 @@ function lookup(name, options, callback) { // Parse and set default options options = parseOptions.forRead(options); - // If no registry entries where passed, simply + // If no registry entries were passed, simply // error with package not found total = options.registry.length; if (!total) { return callback(createError('Package "' + name + '" not found', 'ENOTFOUND')); } - // Lookup package in series until we got its URL + // TODO: Add cache layer to avoid querying the registry always + // The cache should be persistent and by-passable with a skipCache option + // Beware that cache should take the configured registries in account + // Ideally each registry should have an independent cache, so that each step + // below would query the cache individually + + // Lookup package in series until we got the URL async.doUntil(function (next) { var requestUrl = options.registry[current] + '/packages/' + encodeURIComponent(name); diff --git a/packages/bower-registry-client/test/lookup.js b/packages/bower-registry-client/test/lookup.js new file mode 100644 index 000000000..e69de29bb From 28780dc67ef00cd4a8df3a2595af2f071f5de0ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Thu, 9 May 2013 21:15:49 +0100 Subject: [PATCH 0025/1021] Wrong async usage of doUntil. --- packages/bower-registry-client/lib/lookup.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index 452cb7d81..709f887c1 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -59,10 +59,12 @@ function lookup(name, options, callback) { return next(createError('Response of request to "' + requestUrl + '" is not a valid json', 'EINVRES')); } - callback(null, body.url); + url = body.url; + next(); }); }, function () { - return !url && current++ < total; + // Until the url is unknown or there's still registries to tests + return !!url || current++ < total; }, function (err) { // If some of the registry entries failed, error out if (err) { From 1c9913317798ce71636b5b58e79805d381720f80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 10 May 2013 19:46:52 +0100 Subject: [PATCH 0026/1021] Change package to bower-registry-client. Some changes to the codebase. --- packages/bower-registry-client/README.md | 41 +++++++--- packages/bower-registry-client/client.js | 77 +++++++++++++++++++ packages/bower-registry-client/lib/index.js | 11 --- packages/bower-registry-client/lib/lookup.js | 48 +++++++----- .../lib/util/parseOptions.js | 42 ---------- packages/bower-registry-client/package.json | 11 +-- 6 files changed, 144 insertions(+), 86 deletions(-) create mode 100644 packages/bower-registry-client/client.js delete mode 100644 packages/bower-registry-client/lib/index.js delete mode 100644 packages/bower-registry-client/lib/util/parseOptions.js diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index ec6e37294..ced999091 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -1,24 +1,40 @@ -# bower-courier [![Build Status](https://secure.travis-ci.org/bower/courier.png?branch=master)](http://travis-ci.org/bower/courier) +# bower-registry-client [![Build Status](https://secure.travis-ci.org/bower/registry-client.png?branch=master)](http://travis-ci.org/bower/registry-client) -*A messenger, usually travelling in haste, bearing urgent news, important reports or packages, diplomatic messages, etc.* This module allows you to easily interact with the Bower server API. ## Usage -#### .lookup(name, options, callback) +```js -Looks the registry for the package `name`, giving you the associated registered URL. -The `options` argument is optional. +var RegistryClient = require('bower-registry-client'); +var courier = new RegistryClient(options); + +``` Available options: -- registry: an array of registry search endpoints (defaults to the Bower server) -- skipCache: true to skip lookup cache (defaults to false) + +- registry.search: an array of registry search endpoints (defaults to the Bower server) +- registry.register: the endpoint to use when registering packages (defaults to the Bower server) +- registry.publish: the endpoint to use when publishing packages (defaults to the Bower server) +- ca.search: an array of CA certificates for each registry.search (defaults to null). +- ca.register: the CA certificate for registry.register +- ca.publish: the CA certificate for registry.publish +- proxy: the proxy to use for http requests (defaults to null) +- httpsProxy: the proxy to use for https requests (defaults to null) +- strictSsl: whether or not to do SSL key validation when making requests via https (defaults to true). +- userAgent: the user agent to use for the requests (defaults to null) +- cache: the cache folder to use for some operations, null value will disable cache (defaults to OS temp folder) - timeout: the timeout for the requests to finish (defaults to 5000) -```js -var courier = require('bower-courier'); +#### .lookup(name, force, callback) + +Looks the registry for the package `name`, giving you the associated registered URL. +The `force` argument is optional and defaults to `false`. If set to `true`, cache will be bypassed and remotes will always be hit. + + +```js courier.lookup(name, function (err, url) { if (err) { console.error(err.message); @@ -33,4 +49,9 @@ courier.lookup(name, function (err, url) { #### .search(str, options, callback) -#### .info(name, options, callback) \ No newline at end of file +#### .info(name, options, callback) + +#### .clearCache(name, callback) + +Clear the cache associated with the `name` package. +If `name` is null, clears all the cache; \ No newline at end of file diff --git a/packages/bower-registry-client/client.js b/packages/bower-registry-client/client.js new file mode 100644 index 000000000..b520c1dd3 --- /dev/null +++ b/packages/bower-registry-client/client.js @@ -0,0 +1,77 @@ +var os = require('os'); +var path = require('path'); +var rimraf = require('rimraf'); +var info = require('./lib/info'); +var lookup = require('./lib/lookup'); +var search = require('./lib/search'); +var register = require('./lib/register'); + +var RegistryClient = function (options) { + options = options || {}; + + // Registry + options.registry = options.registry || 'https://bower.herokuapp.com'; + if (typeof options.registry !== 'object') { + options.registry = { + search: [options.registry], + register: options.registry, + publish: options.registry + }; + } else if (!Array.isArray(options.registry.search)) { + options.registry.search = [options.registry.search]; + } + + // Ensure that every registry endpoint does not end with / + options.registry.search = options.registry.search.map(function (url) { + return url.replace(/\/+$/, ''); + }); + options.registry.register = options.registry.register.replace(/\/+$/, ''); + options.registry.publish = options.registry.publish.replace(/\/+$/, ''); + + // CA + if (typeof options.ca !== 'object') { + options.ca = { + search: [options.ca], + register: options.ca, + publish: options.ca + }; + } else if (!Array.isArray(options.ca.search)) { + options.ca.search = [options.ca.search]; + } + + // Cache + if (!options.cache) { + options.cache = path.join(os.tmpdir ? os.tmpdir() : os.tmpDir(), 'bower-registry'); + } + + // Timeout + if (typeof options.timeout !== 'number') { + options.timeout = 5000; + } + + // Strict ssl + options.strictSsl = options.strictSsl == null ? true : !! options.strictSsl; + + this._options = options; +}; + +RegistryClient.prototype.clearCache = function (name, callback) { + if (typeof name === 'function') { + callback = name; + name = null; + } + + if (!name) { + rimraf(this._options.cache, callback); + } else { + // TODO: switch to async parallel and call clear cache of all commands + this.lookup.clearCache(name, callback); + } +}; + +RegistryClient.prototype.lookup = lookup; +RegistryClient.prototype.search = search; +RegistryClient.prototype.register = register; +RegistryClient.prototype.info = info; + +module.exports = RegistryClient; \ No newline at end of file diff --git a/packages/bower-registry-client/lib/index.js b/packages/bower-registry-client/lib/index.js deleted file mode 100644 index a0c88b8bd..000000000 --- a/packages/bower-registry-client/lib/index.js +++ /dev/null @@ -1,11 +0,0 @@ -var info = require('./info'); -var lookup = require('./lookup'); -var search = require('./search'); -var register = require('./register'); - -module.exports = { - info: info, - lookup: lookup, - search: search, - register: register -}; \ No newline at end of file diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index 709f887c1..745c0ca20 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -1,24 +1,23 @@ var async = require('async'); var request = require('request'); -var parseOptions = require('./util/parseOptions'); +var url = require('url'); var createError = require('./util/createError'); -function lookup(name, options, callback) { - var url; +function lookup(name, force, callback) { + var packageUrl; var total; - var current = 0; + var index = 0; + var options = this._options; + var registry = options.registry.search; - if (typeof options === 'function') { - callback = options; - options = {}; + if (typeof force === 'function') { + callback = force; + force = false; } - // Parse and set default options - options = parseOptions.forRead(options); - // If no registry entries were passed, simply // error with package not found - total = options.registry.length; + total = registry.length; if (!total) { return callback(createError('Package "' + name + '" not found', 'ENOTFOUND')); } @@ -31,10 +30,18 @@ function lookup(name, options, callback) { // Lookup package in series until we got the URL async.doUntil(function (next) { - var requestUrl = options.registry[current] + '/packages/' + encodeURIComponent(name); + var requestUrl = registry[index] + '/packages/' + encodeURIComponent(name); + var remote = url.parse(requestUrl); + var headers = {}; + + if (options.userAgent) { + headers['User-Agent'] = options.userAgent; + } request.get(requestUrl, { - proxy: options.proxy, + proxy: remote.protocol === 'https:' ? options.httpsProxy : options.proxy, + ca: options.ca.search[index], + strictSSL: options.strictSsl, timeout: options.timeout, json: true }, function (err, response, body) { @@ -59,12 +66,12 @@ function lookup(name, options, callback) { return next(createError('Response of request to "' + requestUrl + '" is not a valid json', 'EINVRES')); } - url = body.url; + packageUrl = body.url; next(); }); }, function () { // Until the url is unknown or there's still registries to tests - return !!url || current++ < total; + return !!packageUrl || index++ < total; }, function (err) { // If some of the registry entries failed, error out if (err) { @@ -72,12 +79,17 @@ function lookup(name, options, callback) { } // If at the end we still have no URL, create an appropriate error - if (!url) { + if (!packageUrl) { return callback(createError('Package "' + name + '" not found', 'ENOTFOUND')); } - callback(null, url); + callback(null, packageUrl); }); } -module.exports = lookup; \ No newline at end of file +function clearCache(name) { + // TODO +} + +module.exports = lookup; +module.exports.clearCache = clearCache; \ No newline at end of file diff --git a/packages/bower-registry-client/lib/util/parseOptions.js b/packages/bower-registry-client/lib/util/parseOptions.js deleted file mode 100644 index 4ecb3836d..000000000 --- a/packages/bower-registry-client/lib/util/parseOptions.js +++ /dev/null @@ -1,42 +0,0 @@ -function forRead(options) { - options = options || {}; - - // Registry - if (!options.registry) { - options.registry = ['https://bower.herokuapp.com']; - } else { - if (!Array.isArray(options.registry)) { - options.registry = [options.registry]; - } - - // Ensure that every registry does not end with / - options.registry = options.registry.map(function (url) { - return url.replace(/\/+$/, ''); - }); - } - - // Timeout - if (typeof options.timeout !== 'number') { - options.timeout = 5000; - } - - return options; -} - -function forWrite(options) { - options = options || {}; - - // Registry - if (!options.registry) { - options.registry = 'https://bower.herokuapp.com'; - } else { - options.registry.replace(/\/+$/, ''); - } - - // TODO: - - return options; -} - -module.exports.forRead = forRead; -module.exports.forWrite = forWrite; \ No newline at end of file diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index ff21bc806..b1658caa1 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,15 +1,15 @@ { - "name": "bower-courier", + "name": "bower-registry-client", "version": "0.0.0-rc0", - "description": "Provides easy interaction with the Bower server API.", + "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ { "type": "MIT", - "url": "https://github.com/bower/bower-courier/blob/master/LICENSE" + "url": "https://github.com/bower/bower-registry/blob/master/LICENSE" } ], - "main": "lib", + "main": "client", "engines": { "node": ">=0.8.0" }, @@ -22,6 +22,7 @@ }, "dependencies": { "async": "~0.2.8", - "request": "~2.21.0" + "request": "~2.21.0", + "rimraf": "~2.1.4" } } From 08104966b26ded53696743e3dcc7ca91e06a110e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 10 May 2013 19:53:18 +0100 Subject: [PATCH 0027/1021] Improve doc. --- packages/bower-registry-client/README.md | 33 +++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index ced999091..3ffe5b5c8 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -8,11 +8,10 @@ This module allows you to easily interact with the Bower server API. ```js var RegistryClient = require('bower-registry-client'); -var courier = new RegistryClient(options); - +var registry = new RegistryClient(options); ``` -Available options: +Available constructor options: - registry.search: an array of registry search endpoints (defaults to the Bower server) - registry.register: the endpoint to use when registering packages (defaults to the Bower server) @@ -35,7 +34,7 @@ The `force` argument is optional and defaults to `false`. If set to `true`, cach ```js -courier.lookup(name, function (err, url) { +registry.lookup(name, function (err, url) { if (err) { console.error(err.message); return; @@ -53,5 +52,27 @@ courier.lookup(name, function (err, url) { #### .clearCache(name, callback) -Clear the cache associated with the `name` package. -If `name` is null, clears all the cache; \ No newline at end of file +Clear the cache associated with the `name` package. +If `name` is null, clears all the cache. + +```js +// Clear jquery cache +registry.clearCache('jquery', function (err) { + if (err) { + console.error(err.message); + return; + } + + console.log('Done'); +}); + +// Clear all cache +registry.clearCache(function (err) { + if (err) { + console.error(err.message); + return; + } + + console.log('Done'); +}); +``` \ No newline at end of file From fdbdcc41303fa1250e9e614ce1c7052716c5e365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 10 May 2013 20:01:35 +0100 Subject: [PATCH 0028/1021] More doc typos. --- packages/bower-registry-client/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index 3ffe5b5c8..72eefaff8 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -23,9 +23,11 @@ Available constructor options: - httpsProxy: the proxy to use for https requests (defaults to null) - strictSsl: whether or not to do SSL key validation when making requests via https (defaults to true). - userAgent: the user agent to use for the requests (defaults to null) -- cache: the cache folder to use for some operations, null value will disable cache (defaults to OS temp folder) +- cache: the cache folder to use for some operations; using null will disable cache (defaults to OS temp folder) - timeout: the timeout for the requests to finish (defaults to 5000) +The cache will speedup operations such as `lookup` and `info`. +Different operations may have different cache expiration times. #### .lookup(name, force, callback) @@ -44,11 +46,11 @@ registry.lookup(name, function (err, url) { }); ``` -#### .register(name, url, options, callback) +#### .register(name, url, callback) -#### .search(str, options, callback) +#### .search(str, force, callback) -#### .info(name, options, callback) +#### .info(name, force, callback) #### .clearCache(name, callback) From 99b37f24bb48137360e5e6b1439966b40a08380d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 11 May 2013 13:22:38 +0100 Subject: [PATCH 0029/1021] Slightly different strategy, implement lookup cache. --- packages/bower-registry-client/README.md | 24 ++- .../{client.js => lib/Client.js} | 45 ++-- packages/bower-registry-client/lib/lookup.js | 200 ++++++++++++------ .../bower-registry-client/lib/util/Cache.js | 154 ++++++++++++++ packages/bower-registry-client/package.json | 5 +- 5 files changed, 336 insertions(+), 92 deletions(-) rename packages/bower-registry-client/{client.js => lib/Client.js} (73%) create mode 100644 packages/bower-registry-client/lib/util/Cache.js diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index 72eefaff8..196d7d0d6 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -29,33 +29,41 @@ Available constructor options: The cache will speedup operations such as `lookup` and `info`. Different operations may have different cache expiration times. -#### .lookup(name, force, callback) +#### .lookup(name, options, callback) -Looks the registry for the package `name`, giving you the associated registered URL. -The `force` argument is optional and defaults to `false`. If set to `true`, cache will be bypassed and remotes will always be hit. +Looks the registry for the package `name`, +The `options` argument is optional. +Available options: + +- force: If set to `true`, cache will be bypassed and remotes will always be hit (defaults to `false`). +- offline: If set to `true`, only the cache will be used (defaults to `false`). + +Note that `force` and `offline` are mutually exclusive. ```js -registry.lookup(name, function (err, url) { +registry.lookup(name, function (err, resp) { if (err) { console.error(err.message); return; } - console.log('URL: ', url); + // For now resp.type is always 'alias' + console.log('type', resp.type); + console.log('url: ', resp.url); }); ``` #### .register(name, url, callback) -#### .search(str, force, callback) +#### .search(str, options, callback) -#### .info(name, force, callback) +#### .info(name, options, callback) #### .clearCache(name, callback) Clear the cache associated with the `name` package. -If `name` is null, clears all the cache. +If `name` is null, clears the cache for every package. ```js // Clear jquery cache diff --git a/packages/bower-registry-client/client.js b/packages/bower-registry-client/lib/Client.js similarity index 73% rename from packages/bower-registry-client/client.js rename to packages/bower-registry-client/lib/Client.js index b520c1dd3..6ee609fc6 100644 --- a/packages/bower-registry-client/client.js +++ b/packages/bower-registry-client/lib/Client.js @@ -1,14 +1,14 @@ var os = require('os'); var path = require('path'); -var rimraf = require('rimraf'); -var info = require('./lib/info'); -var lookup = require('./lib/lookup'); -var search = require('./lib/search'); -var register = require('./lib/register'); +var info = require('./info'); +var lookup = require('./lookup'); +var search = require('./search'); +var register = require('./register'); var RegistryClient = function (options) { options = options || {}; + // Parse options // Registry options.registry = options.registry || 'https://bower.herokuapp.com'; if (typeof options.registry !== 'object') { @@ -50,28 +50,31 @@ var RegistryClient = function (options) { } // Strict ssl - options.strictSsl = options.strictSsl == null ? true : !! options.strictSsl; + options.strictSsl = options.strictSsl == null ? true : !!options.strictSsl; - this._options = options; -}; - -RegistryClient.prototype.clearCache = function (name, callback) { - if (typeof name === 'function') { - callback = name; - name = null; - } - - if (!name) { - rimraf(this._options.cache, callback); - } else { - // TODO: switch to async parallel and call clear cache of all commands - this.lookup.clearCache(name, callback); - } + // Store config and init the cache + this._config = options; + this._initCache(); }; RegistryClient.prototype.lookup = lookup; + RegistryClient.prototype.search = search; + RegistryClient.prototype.register = register; + RegistryClient.prototype.info = info; +RegistryClient.prototype.clearCache = function (name, callback) { + // TODO: call other methods once they are done + this.lookup.clearCache.call(this, name, callback); +}; + +// ----------------------------- + +RegistryClient.prototype._initCache = function () { + // TODO: call other methods once they are done + this.lookup.initCache.call(this, this._config.cache); +}; + module.exports = RegistryClient; \ No newline at end of file diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index 745c0ca20..c93417cad 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -1,95 +1,173 @@ +var path = require('path'); +var url = require('url'); var async = require('async'); var request = require('request'); -var url = require('url'); +var mkdirp = require('mkdirp'); var createError = require('./util/createError'); +var Cache = require('./util/Cache'); -function lookup(name, force, callback) { - var packageUrl; - var total; +function lookup(name, options, callback) { + var data; + var that = this; + var registry = this._config.registry.search; + var total = registry.length; var index = 0; - var options = this._options; - var registry = options.registry.search; - if (typeof force === 'function') { - callback = force; - force = false; + if (typeof options === 'function') { + callback = options; + options = {}; + } else if (!options) { + options = {}; } // If no registry entries were passed, simply // error with package not found - total = registry.length; if (!total) { return callback(createError('Package "' + name + '" not found', 'ENOTFOUND')); } - // TODO: Add cache layer to avoid querying the registry always - // The cache should be persistent and by-passable with a skipCache option - // Beware that cache should take the configured registries in account - // Ideally each registry should have an independent cache, so that each step - // below would query the cache individually - - // Lookup package in series until we got the URL + // Lookup package in series in each registry + // endpoint until we got the data async.doUntil(function (next) { - var requestUrl = registry[index] + '/packages/' + encodeURIComponent(name); - var remote = url.parse(requestUrl); - var headers = {}; + var remote = url.parse(registry[index]); - if (options.userAgent) { - headers['User-Agent'] = options.userAgent; - } + // If force flag is disabled we check the cache + // and fallback to a request if the offline flag is disabled + if (!options.force) { + that._lookupCache[remote.host].get(name, function (err, value) { + data = value; - request.get(requestUrl, { - proxy: remote.protocol === 'https:' ? options.httpsProxy : options.proxy, - ca: options.ca.search[index], - strictSSL: options.strictSsl, - timeout: options.timeout, - json: true - }, function (err, response, body) { - // If there was an internal error (e.g. timeout) - if (err) { - return next(createError('Request to "' + requestUrl + '" failed: ' + err.message, err.code)); - } - - // If not found, try next - if (response.statusCode === 404) { - return next(); - } - - // Abort if there was an error (range different than 2xx) - if (response.statusCode < 200 || response.statusCode > 299) { - return next(createError('Request to "' + requestUrl + '" failed with ' + response.statusCode, 'EINVRES')); - } - - // Validate response body, since we are expecting a JSON object - // If the server returns an invalid JSON, it's still a string - if (typeof body !== 'object') { - return next(createError('Response of request to "' + requestUrl + '" is not a valid json', 'EINVRES')); - } - - packageUrl = body.url; - next(); - }); + // Don't proceed with making a request if we got + // an error, a value from the cache or if the offline flag is + // enabled + if (err || data || options.offline) { + return next(err); + } + + doRequest(name, index, that._config, function (err, response) { + if (err) { + return next(err); + } + + // Store in cache + that._lookupCache[remote.host].set(name, data = response, next); + }); + }); + // Otherwise, we totally bypass the cache and + // make only the request + } else { + doRequest(name, index, that._config, function (err, response) { + if (err) { + return next(err); + } + + // Store in cache + that._lookupCache[remote.host].set(name, data = response, next); + }); + } }, function () { - // Until the url is unknown or there's still registries to tests - return !!packageUrl || index++ < total; + // Until the data is unknown or there's still registries to test + return !!data || index++ < total; }, function (err) { // If some of the registry entries failed, error out if (err) { return callback(err); } - // If at the end we still have no URL, create an appropriate error - if (!packageUrl) { + // If at the end we still have no data, create an appropriate error + if (!data) { return callback(createError('Package "' + name + '" not found', 'ENOTFOUND')); } - callback(null, packageUrl); + callback(null, data); }); } -function clearCache(name) { - // TODO +function doRequest(name, index, config, callback) { + var requestUrl = config.registry.search[index] + '/packages/' + encodeURIComponent(name); + var remote = url.parse(requestUrl); + var headers = {}; + + if (config.userAgent) { + headers['User-Agent'] = config.userAgent; + } + + request.get(requestUrl, { + proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, + ca: config.ca.search[index], + strictSSL: config.strictSsl, + timeout: config.timeout, + json: true + }, function (err, response, body) { + // If there was an internal error (e.g. timeout) + if (err) { + return callback(createError('Request to "' + requestUrl + '" failed: ' + err.message, err.code)); + } + + // If not found, try next + if (response.statusCode === 404) { + return callback(); + } + + // Abort if there was an error (range different than 2xx) + if (response.statusCode < 200 || response.statusCode > 299) { + return callback(createError('Request to "' + requestUrl + '" failed with ' + response.statusCode, 'EINVRES')); + } + + // Validate response body, since we are expecting a JSON object + // If the server returns an invalid JSON, it's still a string + if (typeof body !== 'object') { + return callback(createError('Response of request to "' + requestUrl + '" is not a valid json', 'EINVRES')); + } + + callback(null, { + type: 'alias', + url: body.url + }); + }); +} + +function initCache() { + this._lookupCache = {}; + + // Generate a cache instance for each registry endpoint + this._config.registry.search.forEach(function (registry) { + var cacheDir; + var host = url.parse(registry).host; + + // Skip if there's a cache for the same host + if (this._lookupCache[host]) { + return; + } + + if (this._config.cache) { + cacheDir = path.join(this._config.cache, encodeURIComponent(host)); + mkdirp.sync(cacheDir); + } + + this._lookupCache[host] = new Cache(cacheDir); + }, this); +} + +function clearCache(name, callback) { + var key; + + if (typeof name === 'function') { + callback = name; + name = null; + } + + if (name) { + for (key in this._lookupCache) { + this._lookupCache[key].del(name); + } + } else { + for (key in this._lookupCache) { + this._lookupCache[key].clear(); + } + } } module.exports = lookup; +module.exports.initCache = initCache; module.exports.clearCache = clearCache; \ No newline at end of file diff --git a/packages/bower-registry-client/lib/util/Cache.js b/packages/bower-registry-client/lib/util/Cache.js new file mode 100644 index 000000000..3b2508977 --- /dev/null +++ b/packages/bower-registry-client/lib/util/Cache.js @@ -0,0 +1,154 @@ +var fs = require('fs'); +var path = require('path'); +var async = require('async'); + +var hasOwn = Object.prototype.hasOwnProperty; + +var Cache = function (dir, options) { + options = options || {}; + + // Default max age of 5 days + if (typeof options.maxAge !== 'number') { + options.maxAge = 5 * 24 * 60 * 60 * 1000; + } + + this._dir = dir; + this._options = options; + this._cache = {}; // TODO: switch to LRU +}; + +Cache.prototype.get = function (key, callback) { + var file; + + // Check in memory + if (hasOwn.call(this._cache, key)) { + if (this._hasExpired(this._cache[key])) { + this.del(key, callback); + } else { + callback(null, this._cache[key]); + } + + return; + } + + // Check in disk + if (!this._dir) { + return callback(null); + } + + file = this._getFile(key); + fs.readFile(file, function (err, contents) { + var json; + + // If there was an error reading + // Note that if the file does not exist then + // we don't got its value + if (err) { + return callback(err.code === 'ENOENT' ? null : err); + } + + // If there was an error reading the file as json + // simply assume it doesn't exist + try { + json = JSON.parse(contents.toString()); + } catch (e) { + return this.del(key, callback); // If so, delete it + } + + // Check if it has expired + if (this._hasExpired(json)) { + return this.del(key, callback); + } + + this._cache[key] = json; + callback(null, json.value); + }.bind(this)); +}; + +Cache.prototype.set = function (key, value, maxAge, callback) { + var file; + var entry; + var str; + + if (typeof maxAge === 'function') { + callback = maxAge; + maxAge = this._options.maxAge; + } + + entry = { + expires: Date.now() + maxAge, + value: value + }; + + // Store in memory + this._cache[key] = entry; + + // Store in disk + if (!this._dir) { + return callback(null); + } + + // If there was an error generating the json + // then there's some cyclic reference or some other issue + try { + str = JSON.stringify(entry); + } catch (e) { + return callback(e); + } + + file = this._getFile(key); + fs.writeFile(file, str, callback); +}; + +Cache.prototype.del = function (key, callback) { + // Delete from memory + delete this._cache[key]; + + // Delete from disk + if (!this._dir) { + return callback(null); + } + + fs.unlink(this._getFile(key), callback); +}; + +Cache.prototype.clear = function (callback) { + var dir = this._dir; + + // Clear in memory cache + this._cache = {}; + + // Clear everything from the disk + if (!dir) { + return callback(null); + } + + fs.readdir(dir, function (err, files) { + if (err) { + return callback(err); + } + + // Delete every file in parallel + async.forEach(files, function (file, next) { + fs.unlink(path.join(dir, file), next); + }, callback); + }); +}; + +Cache.prototype._hasExpired = function (json) { + var expires = json.expires; + + if (!expires) { + return false; + } + + // Check if the key has expired + expires = parseInt(json.expires, 10); + return !expires || Date.now() > expires; +}; + +Cache.prototype._getFile = function (key) { + return path.join(this._dir, encodeURIComponent(key)); +}; + +module.exports = Cache; \ No newline at end of file diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index b1658caa1..06935fee7 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/bower/bower-registry/blob/master/LICENSE" } ], - "main": "client", + "main": "lib/Client", "engines": { "node": ">=0.8.0" }, @@ -23,6 +23,7 @@ "dependencies": { "async": "~0.2.8", "request": "~2.21.0", - "rimraf": "~2.1.4" + "rimraf": "~2.1.4", + "mkdirp": "~0.3.5" } } From e80270d1fa52441922a756d8b625b0b21b75c1a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 11 May 2013 13:40:59 +0100 Subject: [PATCH 0030/1021] Add correct maxAge for the cache entries. --- packages/bower-registry-client/lib/lookup.js | 22 ++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index c93417cad..ecd2decba 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -44,25 +44,29 @@ function lookup(name, options, callback) { return next(err); } - doRequest(name, index, that._config, function (err, response) { + doRequest(name, index, that._config, function (err, info) { if (err) { return next(err); } + data = info; + // Store in cache - that._lookupCache[remote.host].set(name, data = response, next); + that._lookupCache[remote.host].set(name, info, getMaxAge(info), next); }); }); // Otherwise, we totally bypass the cache and // make only the request } else { - doRequest(name, index, that._config, function (err, response) { + doRequest(name, index, that._config, function (err, info) { if (err) { return next(err); } + data = info; + // Store in cache - that._lookupCache[remote.host].set(name, data = response, next); + that._lookupCache[remote.host].set(name, info, getMaxAge(info), next); }); } }, function () { @@ -127,6 +131,16 @@ function doRequest(name, index, config, callback) { }); } +function getMaxAge(info) { + // If type is alias, make it 5 days + if (info.type === 'alias') { + return 5 * 24 * 60 * 60 * 1000; + } + + // Otherwise make it 5 minutes + return 5 * 60 * 60 * 1000; +} + function initCache() { this._lookupCache = {}; From 3158b544d55455305c825966f8eb13d843180c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 11 May 2013 13:42:23 +0100 Subject: [PATCH 0031/1021] Minor lang change. --- packages/bower-registry-client/README.md | 6 +++--- packages/bower-registry-client/lib/lookup.js | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index 196d7d0d6..e4e1b90e0 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -42,15 +42,15 @@ Available options: Note that `force` and `offline` are mutually exclusive. ```js -registry.lookup(name, function (err, resp) { +registry.lookup(name, function (err, entry) { if (err) { console.error(err.message); return; } // For now resp.type is always 'alias' - console.log('type', resp.type); - console.log('url: ', resp.url); + console.log('type', entry.type); + console.log('url: ', entry.url); }); ``` diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index ecd2decba..f17b85ca2 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -44,29 +44,29 @@ function lookup(name, options, callback) { return next(err); } - doRequest(name, index, that._config, function (err, info) { + doRequest(name, index, that._config, function (err, entry) { if (err) { return next(err); } - data = info; + data = entry; // Store in cache - that._lookupCache[remote.host].set(name, info, getMaxAge(info), next); + that._lookupCache[remote.host].set(name, entry, getMaxAge(entry), next); }); }); // Otherwise, we totally bypass the cache and // make only the request } else { - doRequest(name, index, that._config, function (err, info) { + doRequest(name, index, that._config, function (err, entry) { if (err) { return next(err); } - data = info; + data = entry; // Store in cache - that._lookupCache[remote.host].set(name, info, getMaxAge(info), next); + that._lookupCache[remote.host].set(name, entry, getMaxAge(entry), next); }); } }, function () { @@ -131,9 +131,9 @@ function doRequest(name, index, config, callback) { }); } -function getMaxAge(info) { +function getMaxAge(entry) { // If type is alias, make it 5 days - if (info.type === 'alias') { + if (entry.type === 'alias') { return 5 * 24 * 60 * 60 * 1000; } From cb59c2489b3421b6d4586aa44fb8b67eeed1e1b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 11 May 2013 13:56:48 +0100 Subject: [PATCH 0032/1021] Change main file. --- packages/bower-json/lib/{bower-json.js => json.js} | 0 packages/bower-json/package.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename packages/bower-json/lib/{bower-json.js => json.js} (100%) diff --git a/packages/bower-json/lib/bower-json.js b/packages/bower-json/lib/json.js similarity index 100% rename from packages/bower-json/lib/bower-json.js rename to packages/bower-json/lib/json.js diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 2da9d7943..c56527de0 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/bower/bower-json/blob/master/LICENSE" } ], - "main": "lib/bower-json", + "main": "lib/json", "engines": { "node": ">=0.8.0" }, From 0742e18edde70bc7900699a8757852ad0b7446fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 11 May 2013 14:00:11 +0100 Subject: [PATCH 0033/1021] Oops. --- packages/bower-json/README.md | 2 +- packages/bower-json/test/test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index c6d68a1e7..bb87314e3 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -1,4 +1,4 @@ -# bower-json [![Build Status](https://secure.travis-ci.org/bower/bower-json.png?branch=master)](http://travis-ci.org/bower/bower-json) +# bower-json [![Build Status](https://secure.travis-ci.org/bower/json.png?branch=master)](http://travis-ci.org/bower/json) Read `bower.json` files with semantics, normalisation, defaults and validation. diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index a391435b9..4323a59cf 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -1,6 +1,6 @@ var path = require('path'); var expect = require('expect.js'); -var bowerJson = require('../lib/bower-json'); +var bowerJson = require('../lib/json'); describe('.find', function () { it('should find the bower.json file', function (done) { From 9b6c5741de5133f3c9283a5b71ec479e07388c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 13 May 2013 11:10:10 +0100 Subject: [PATCH 0034/1021] Move cache did creation to appropriate class, small pert improvement.. --- packages/bower-registry-client/lib/lookup.js | 9 ++++----- packages/bower-registry-client/lib/util/Cache.js | 5 +++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index f17b85ca2..187578f9e 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -2,7 +2,6 @@ var path = require('path'); var url = require('url'); var async = require('async'); var request = require('request'); -var mkdirp = require('mkdirp'); var createError = require('./util/createError'); var Cache = require('./util/Cache'); @@ -30,11 +29,12 @@ function lookup(name, options, callback) { // endpoint until we got the data async.doUntil(function (next) { var remote = url.parse(registry[index]); + var lookupCache = that._lookupCache[remote.host]; // If force flag is disabled we check the cache // and fallback to a request if the offline flag is disabled if (!options.force) { - that._lookupCache[remote.host].get(name, function (err, value) { + lookupCache.get(name, function (err, value) { data = value; // Don't proceed with making a request if we got @@ -52,7 +52,7 @@ function lookup(name, options, callback) { data = entry; // Store in cache - that._lookupCache[remote.host].set(name, entry, getMaxAge(entry), next); + lookupCache.set(name, entry, getMaxAge(entry), next); }); }); // Otherwise, we totally bypass the cache and @@ -66,7 +66,7 @@ function lookup(name, options, callback) { data = entry; // Store in cache - that._lookupCache[remote.host].set(name, entry, getMaxAge(entry), next); + lookupCache.set(name, entry, getMaxAge(entry), next); }); } }, function () { @@ -156,7 +156,6 @@ function initCache() { if (this._config.cache) { cacheDir = path.join(this._config.cache, encodeURIComponent(host)); - mkdirp.sync(cacheDir); } this._lookupCache[host] = new Cache(cacheDir); diff --git a/packages/bower-registry-client/lib/util/Cache.js b/packages/bower-registry-client/lib/util/Cache.js index 3b2508977..53e889cdf 100644 --- a/packages/bower-registry-client/lib/util/Cache.js +++ b/packages/bower-registry-client/lib/util/Cache.js @@ -1,6 +1,7 @@ var fs = require('fs'); var path = require('path'); var async = require('async'); +var mkdirp = require('mkdirp'); var hasOwn = Object.prototype.hasOwnProperty; @@ -15,6 +16,10 @@ var Cache = function (dir, options) { this._dir = dir; this._options = options; this._cache = {}; // TODO: switch to LRU + + if (dir) { + mkdirp.sync(dir); + } }; Cache.prototype.get = function (key, callback) { From 780b1f8acca3c46ccf0979e4d5526c278812a7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 17 May 2013 13:13:47 +0100 Subject: [PATCH 0035/1021] Fix various bugs. --- packages/bower-registry-client/lib/Client.js | 4 ++-- packages/bower-registry-client/lib/util/Cache.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bower-registry-client/lib/Client.js b/packages/bower-registry-client/lib/Client.js index 6ee609fc6..4f88dbdb5 100644 --- a/packages/bower-registry-client/lib/Client.js +++ b/packages/bower-registry-client/lib/Client.js @@ -11,7 +11,7 @@ var RegistryClient = function (options) { // Parse options // Registry options.registry = options.registry || 'https://bower.herokuapp.com'; - if (typeof options.registry !== 'object') { + if (typeof options.registry === 'string') { options.registry = { search: [options.registry], register: options.registry, @@ -29,7 +29,7 @@ var RegistryClient = function (options) { options.registry.publish = options.registry.publish.replace(/\/+$/, ''); // CA - if (typeof options.ca !== 'object') { + if (!options.ca || typeof options.ca === 'string') { options.ca = { search: [options.ca], register: options.ca, diff --git a/packages/bower-registry-client/lib/util/Cache.js b/packages/bower-registry-client/lib/util/Cache.js index 53e889cdf..d726d321b 100644 --- a/packages/bower-registry-client/lib/util/Cache.js +++ b/packages/bower-registry-client/lib/util/Cache.js @@ -30,7 +30,7 @@ Cache.prototype.get = function (key, callback) { if (this._hasExpired(this._cache[key])) { this.del(key, callback); } else { - callback(null, this._cache[key]); + callback(null, this._cache[key].value); } return; From 1d9504d0f047a009f17bd62440881533ea4edd57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 17 May 2013 13:14:53 +0100 Subject: [PATCH 0036/1021] Bump rc. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 06935fee7..bb6568075 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.0.0-rc0", + "version": "0.0.0-rc1", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From c56026c18a053c46bb101d2f9e04718bee64339d Mon Sep 17 00:00:00 2001 From: Duncan Wong Date: Sat, 18 May 2013 19:26:49 -0600 Subject: [PATCH 0037/1021] quick fix for bowerJson.find() example --- packages/bower-json/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index bb87314e3..71e053c2b 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -71,7 +71,7 @@ bowerJson.find('/path/to/folder', function (err, filename) { console.log('Filename: ', filename); // Now that we got the filename, we can read its contents - bowerJson.read(filename, function () { + bowerJson.read(filename, function (err, json) { if (err) { console.error('There was an error reading the file'); console.error(err.message); From 26bab84d048a8ec1b22d9f8665236fb77606fdef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Sun, 19 May 2013 14:27:36 +0200 Subject: [PATCH 0038/1021] Fix parse usage in README. --- packages/bower-json/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index 71e053c2b..6305e53d4 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -41,14 +41,14 @@ var json = { version: '0.0.1' }; -bowerJson.parse(json, function (err, filename) { +bowerJson.parse(json, function (err, json) { if (err) { console.error('There was an error parsing the object'); console.error(err.message); return; } - console.log('JSON: ', json); + console.log('Parsed: ', json); }); ``` From c7780a2708e2ee421ce1598e0317d8515ffa8bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 24 May 2013 22:53:17 +0100 Subject: [PATCH 0039/1021] Try next registry endpoint on 404. --- packages/bower-registry-client/lib/lookup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index 187578f9e..dc1f4f062 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -45,7 +45,7 @@ function lookup(name, options, callback) { } doRequest(name, index, that._config, function (err, entry) { - if (err) { + if (err || !entry) { return next(err); } @@ -59,7 +59,7 @@ function lookup(name, options, callback) { // make only the request } else { doRequest(name, index, that._config, function (err, entry) { - if (err) { + if (err || !entry) { return next(err); } From 70e3528809c742ad1fd1c44bcb1173f6945a3a4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 24 May 2013 22:53:52 +0100 Subject: [PATCH 0040/1021] Add repository to package.json and bump rc version. --- packages/bower-registry-client/package.json | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index bb6568075..50991100b 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,29 +1,33 @@ { "name": "bower-registry-client", - "version": "0.0.0-rc1", + "version": "0.0.0-rc2", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ { "type": "MIT", - "url": "https://github.com/bower/bower-registry/blob/master/LICENSE" + "url": "https://github.com/bower/registry-client/blob/master/LICENSE" } ], + "repository": { + "type": "git", + "url": "git://github.com/bower/registry-client.git" + }, "main": "lib/Client", "engines": { "node": ">=0.8.0" }, + "dependencies": { + "async": "~0.2.8", + "request": "~2.21.0", + "rimraf": "~2.1.4", + "mkdirp": "~0.3.5" + }, "devDependencies": { "mocha": "~1.8.2", "expect.js": "~0.2.0" }, "scripts": { "test": "mocha -R spec" - }, - "dependencies": { - "async": "~0.2.8", - "request": "~2.21.0", - "rimraf": "~2.1.4", - "mkdirp": "~0.3.5" } } From 7dcefa6bee94c5187d4a3573b4d83b757fe8580f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 24 May 2013 22:54:41 +0100 Subject: [PATCH 0041/1021] Add repository to package.json and fix URL's, also bump rc version. --- packages/bower-json/package.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index c56527de0..eabca990b 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,14 +1,18 @@ { "name": "bower-json", - "version": "0.0.0-rc0", + "version": "0.0.0-rc1", "description": "Read bower.json files with semantics, normalisation, defaults and validation.", "author": "Twitter", "licenses": [ { "type": "MIT", - "url": "https://github.com/bower/bower-json/blob/master/LICENSE" + "url": "https://github.com/bower/json/blob/master/LICENSE" } ], + "repository": { + "type": "git", + "url": "git://github.com/bower/json.git" + }, "main": "lib/json", "engines": { "node": ">=0.8.0" From cb000549bd63edd8aa5fbf8c0bb7cf132fd1415c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 26 May 2013 12:46:45 +0100 Subject: [PATCH 0042/1021] Small tweaks. --- packages/bower-registry-client/Client.js | 76 ++++++++++++++++++ packages/bower-registry-client/lib/Client.js | 80 ------------------- packages/bower-registry-client/lib/index.js | 6 ++ packages/bower-registry-client/lib/lookup.js | 7 +- .../bower-registry-client/lib/util/Cache.js | 6 +- .../lib/util/createError.js | 2 +- packages/bower-registry-client/package.json | 2 +- 7 files changed, 92 insertions(+), 87 deletions(-) create mode 100644 packages/bower-registry-client/Client.js delete mode 100644 packages/bower-registry-client/lib/Client.js create mode 100644 packages/bower-registry-client/lib/index.js diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js new file mode 100644 index 000000000..2645404d5 --- /dev/null +++ b/packages/bower-registry-client/Client.js @@ -0,0 +1,76 @@ +var os = require('os'); +var path = require('path'); +var methods = require('./lib'); + +var name; + +function RegistryClient(config) { + config = config || {}; + + // Parse config + // Registry + config.registry = config.registry || 'https://bower.herokuapp.com'; + if (typeof config.registry === 'string') { + config.registry = { + search: [config.registry], + register: config.registry, + publish: config.registry + }; + } else if (!Array.isArray(config.registry.search)) { + config.registry.search = [config.registry.search]; + } + + // Ensure that every registry endpoint does not end with / + config.registry.search = config.registry.search.map(function (url) { + return url.replace(/\/+$/, ''); + }); + config.registry.register = config.registry.register.replace(/\/+$/, ''); + config.registry.publish = config.registry.publish.replace(/\/+$/, ''); + + // CA + if (!config.ca || typeof config.ca === 'string') { + config.ca = { + search: [config.ca], + register: config.ca, + publish: config.ca + }; + } else if (!Array.isArray(config.ca.search)) { + config.ca.search = [config.ca.search]; + } + + // Cache + if (!config.cache) { + config.cache = path.join(os.tmpdir ? os.tmpdir() : os.tmpDir(), 'bower-registry'); + } + + // Timeout + if (typeof config.timeout !== 'number') { + config.timeout = 5000; + } + + // Strict ssl + config.strictSsl = config.strictSsl == null ? true : !!config.strictSsl; + + // Store config and init the cache + this._config = config; + this._initCache(); +} + +// Add every method to the prototype +for (name in methods) { + RegistryClient.prototype[name] = methods[name]; +} + +RegistryClient.prototype.clearCache = function (name, callback) { + // TODO: call other methods once they are done + this.lookup.clearCache.call(this, name, callback); +}; + +// ----------------------------- + +RegistryClient.prototype._initCache = function () { + // TODO: call other methods once they are done + this.lookup.initCache.call(this, this._config.cache); +}; + +module.exports = RegistryClient; diff --git a/packages/bower-registry-client/lib/Client.js b/packages/bower-registry-client/lib/Client.js deleted file mode 100644 index 4f88dbdb5..000000000 --- a/packages/bower-registry-client/lib/Client.js +++ /dev/null @@ -1,80 +0,0 @@ -var os = require('os'); -var path = require('path'); -var info = require('./info'); -var lookup = require('./lookup'); -var search = require('./search'); -var register = require('./register'); - -var RegistryClient = function (options) { - options = options || {}; - - // Parse options - // Registry - options.registry = options.registry || 'https://bower.herokuapp.com'; - if (typeof options.registry === 'string') { - options.registry = { - search: [options.registry], - register: options.registry, - publish: options.registry - }; - } else if (!Array.isArray(options.registry.search)) { - options.registry.search = [options.registry.search]; - } - - // Ensure that every registry endpoint does not end with / - options.registry.search = options.registry.search.map(function (url) { - return url.replace(/\/+$/, ''); - }); - options.registry.register = options.registry.register.replace(/\/+$/, ''); - options.registry.publish = options.registry.publish.replace(/\/+$/, ''); - - // CA - if (!options.ca || typeof options.ca === 'string') { - options.ca = { - search: [options.ca], - register: options.ca, - publish: options.ca - }; - } else if (!Array.isArray(options.ca.search)) { - options.ca.search = [options.ca.search]; - } - - // Cache - if (!options.cache) { - options.cache = path.join(os.tmpdir ? os.tmpdir() : os.tmpDir(), 'bower-registry'); - } - - // Timeout - if (typeof options.timeout !== 'number') { - options.timeout = 5000; - } - - // Strict ssl - options.strictSsl = options.strictSsl == null ? true : !!options.strictSsl; - - // Store config and init the cache - this._config = options; - this._initCache(); -}; - -RegistryClient.prototype.lookup = lookup; - -RegistryClient.prototype.search = search; - -RegistryClient.prototype.register = register; - -RegistryClient.prototype.info = info; - -RegistryClient.prototype.clearCache = function (name, callback) { - // TODO: call other methods once they are done - this.lookup.clearCache.call(this, name, callback); -}; - -// ----------------------------- - -RegistryClient.prototype._initCache = function () { - // TODO: call other methods once they are done - this.lookup.initCache.call(this, this._config.cache); -}; - -module.exports = RegistryClient; \ No newline at end of file diff --git a/packages/bower-registry-client/lib/index.js b/packages/bower-registry-client/lib/index.js new file mode 100644 index 000000000..6dd32185d --- /dev/null +++ b/packages/bower-registry-client/lib/index.js @@ -0,0 +1,6 @@ +return { + info: require('./info'), + lookup: require('./lookup'), + register: require('./register'), + search: require('./search') +}; diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index dc1f4f062..b818ec58b 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -181,6 +181,9 @@ function clearCache(name, callback) { } } +// --------------- + +lookup.initCache = initCache; +lookup.clearCache = clearCache; + module.exports = lookup; -module.exports.initCache = initCache; -module.exports.clearCache = clearCache; \ No newline at end of file diff --git a/packages/bower-registry-client/lib/util/Cache.js b/packages/bower-registry-client/lib/util/Cache.js index d726d321b..05bb0ee54 100644 --- a/packages/bower-registry-client/lib/util/Cache.js +++ b/packages/bower-registry-client/lib/util/Cache.js @@ -5,7 +5,7 @@ var mkdirp = require('mkdirp'); var hasOwn = Object.prototype.hasOwnProperty; -var Cache = function (dir, options) { +function Cache(dir, options) { options = options || {}; // Default max age of 5 days @@ -20,7 +20,7 @@ var Cache = function (dir, options) { if (dir) { mkdirp.sync(dir); } -}; +} Cache.prototype.get = function (key, callback) { var file; @@ -156,4 +156,4 @@ Cache.prototype._getFile = function (key) { return path.join(this._dir, encodeURIComponent(key)); }; -module.exports = Cache; \ No newline at end of file +module.exports = Cache; diff --git a/packages/bower-registry-client/lib/util/createError.js b/packages/bower-registry-client/lib/util/createError.js index 6be8e2810..8e9a4168a 100644 --- a/packages/bower-registry-client/lib/util/createError.js +++ b/packages/bower-registry-client/lib/util/createError.js @@ -5,4 +5,4 @@ function createError(msg, code) { return err; } -module.exports = createError; \ No newline at end of file +module.exports = createError; diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 50991100b..a5d70b1be 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -13,7 +13,7 @@ "type": "git", "url": "git://github.com/bower/registry-client.git" }, - "main": "lib/Client", + "main": "Client", "engines": { "node": ">=0.8.0" }, From f1717f8319d77f69daddec56efe05671865c262d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 26 May 2013 13:12:54 +0100 Subject: [PATCH 0043/1021] Move force and offline options to the constructor. --- packages/bower-registry-client/README.md | 20 ++++++++----------- packages/bower-registry-client/lib/lookup.js | 13 +++--------- .../bower-registry-client/lib/util/Cache.js | 6 +++++- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index e4e1b90e0..23511c6b7 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -13,6 +13,7 @@ var registry = new RegistryClient(options); Available constructor options: +- cache: the cache folder to use for some operations; using null will disable persistent cache (defaults to OS temp folder) - registry.search: an array of registry search endpoints (defaults to the Bower server) - registry.register: the endpoint to use when registering packages (defaults to the Bower server) - registry.publish: the endpoint to use when publishing packages (defaults to the Bower server) @@ -23,23 +24,18 @@ Available constructor options: - httpsProxy: the proxy to use for https requests (defaults to null) - strictSsl: whether or not to do SSL key validation when making requests via https (defaults to true). - userAgent: the user agent to use for the requests (defaults to null) -- cache: the cache folder to use for some operations; using null will disable cache (defaults to OS temp folder) - timeout: the timeout for the requests to finish (defaults to 5000) +- force: If set to true, cache will be bypassed and remotes will always be hit (defaults to false). +- offline: If set to true, only the cache will be used (defaults to false). +Note that `force` and `offline` are mutually exclusive. The cache will speedup operations such as `lookup` and `info`. Different operations may have different cache expiration times. -#### .lookup(name, options, callback) - -Looks the registry for the package `name`, -The `options` argument is optional. -Available options: +#### .lookup(name, callback) -- force: If set to `true`, cache will be bypassed and remotes will always be hit (defaults to `false`). -- offline: If set to `true`, only the cache will be used (defaults to `false`). - -Note that `force` and `offline` are mutually exclusive. +Looks the registry for the package `name`, ```js registry.lookup(name, function (err, entry) { @@ -56,9 +52,9 @@ registry.lookup(name, function (err, entry) { #### .register(name, url, callback) -#### .search(str, options, callback) +#### .search(str, callback) -#### .info(name, options, callback) +#### .info(name, callback) #### .clearCache(name, callback) diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index b818ec58b..6f88beea1 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -5,20 +5,13 @@ var request = require('request'); var createError = require('./util/createError'); var Cache = require('./util/Cache'); -function lookup(name, options, callback) { +function lookup(name, callback) { var data; var that = this; var registry = this._config.registry.search; var total = registry.length; var index = 0; - if (typeof options === 'function') { - callback = options; - options = {}; - } else if (!options) { - options = {}; - } - // If no registry entries were passed, simply // error with package not found if (!total) { @@ -33,14 +26,14 @@ function lookup(name, options, callback) { // If force flag is disabled we check the cache // and fallback to a request if the offline flag is disabled - if (!options.force) { + if (!that._config.force) { lookupCache.get(name, function (err, value) { data = value; // Don't proceed with making a request if we got // an error, a value from the cache or if the offline flag is // enabled - if (err || data || options.offline) { + if (err || data || that._config.offline) { return next(err); } diff --git a/packages/bower-registry-client/lib/util/Cache.js b/packages/bower-registry-client/lib/util/Cache.js index 05bb0ee54..87f7468c2 100644 --- a/packages/bower-registry-client/lib/util/Cache.js +++ b/packages/bower-registry-client/lib/util/Cache.js @@ -15,7 +15,11 @@ function Cache(dir, options) { this._dir = dir; this._options = options; - this._cache = {}; // TODO: switch to LRU + this._cache = {}; + + // TODO: Switch to LRU + // Though, we need to get this merged before: + // https://github.com/isaacs/node-lru-cache/pull/11 if (dir) { mkdirp.sync(dir); From 4ac052c10b03d8e7df0f7eeb53f64ec686efa144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 26 May 2013 13:17:54 +0100 Subject: [PATCH 0044/1021] Oops. --- packages/bower-registry-client/Client.js | 4 ++-- packages/bower-registry-client/lib/index.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js index 2645404d5..e79d511fb 100644 --- a/packages/bower-registry-client/Client.js +++ b/packages/bower-registry-client/Client.js @@ -6,6 +6,7 @@ var name; function RegistryClient(config) { config = config || {}; + this._config = config; // Parse config // Registry @@ -51,8 +52,7 @@ function RegistryClient(config) { // Strict ssl config.strictSsl = config.strictSsl == null ? true : !!config.strictSsl; - // Store config and init the cache - this._config = config; + // Init the cache this._initCache(); } diff --git a/packages/bower-registry-client/lib/index.js b/packages/bower-registry-client/lib/index.js index 6dd32185d..bb84f53fd 100644 --- a/packages/bower-registry-client/lib/index.js +++ b/packages/bower-registry-client/lib/index.js @@ -1,4 +1,4 @@ -return { +module.exports = { info: require('./info'), lookup: require('./lookup'), register: require('./register'), From 83ae9b66a311d64d8dab94d85312806495df2dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 22 Jun 2013 14:07:51 +0100 Subject: [PATCH 0045/1021] Add license note, misc tweaks. --- packages/bower-json/.gitignore | 4 ++-- packages/bower-json/README.md | 5 +++++ packages/bower-json/lib/json.js | 6 +++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/bower-json/.gitignore b/packages/bower-json/.gitignore index 5171c5408..1b6c50d99 100644 --- a/packages/bower-json/.gitignore +++ b/packages/bower-json/.gitignore @@ -1,2 +1,2 @@ -node_modules -npm-debug.log \ No newline at end of file +/node_modules +/npm-debug.* \ No newline at end of file diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index 6305e53d4..4da36c6ab 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -82,3 +82,8 @@ bowerJson.find('/path/to/folder', function (err, filename) { }); }); ``` + + +## License + +Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index b0a0059e2..bf0562cc0 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -19,7 +19,7 @@ function read(file, callback) { } function parse(json, callback) { - // Apply normalisation, defaults, validation here + // Apply normalisation and validation here // If something is invalid, the error.code should be EINVALID callback(null, json); } @@ -35,7 +35,7 @@ function find(folder, callback) { fs.exists(file, function (exists) { if (exists) return callback(null, file); - var err = new Error('Neither bower.json nor component.json were found in "' + folder + '"'); + var err = new Error('Neither bower.json nor component.json were found in ' + folder); err.code = 'ENOENT'; callback(err); }); @@ -45,4 +45,4 @@ function find(folder, callback) { module.exports = read; module.exports.read = read; module.exports.parse = parse; -module.exports.find = find; \ No newline at end of file +module.exports.find = find; From d8e69360b97e5aa7d133b2a08948d6376dfd04f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 22 Jun 2013 14:11:11 +0100 Subject: [PATCH 0046/1021] Add search command, other fixes/changes. - Use LRU to prevent huge memory usage when using the module in long-living programs - Lookup no longer throws when a package is not found (null is returned instead). - Cache mechanism improvements. - Misc fixes. --- packages/bower-registry-client/.gitignore | 4 +- packages/bower-registry-client/Client.js | 30 ++- packages/bower-registry-client/README.md | 7 +- packages/bower-registry-client/lib/index.js | 2 +- packages/bower-registry-client/lib/info.js | 0 packages/bower-registry-client/lib/list.js | 173 ++++++++++++++++ packages/bower-registry-client/lib/lookup.js | 53 ++--- packages/bower-registry-client/lib/search.js | 188 ++++++++++++++++++ .../bower-registry-client/lib/util/Cache.js | 58 +++--- packages/bower-registry-client/package.json | 1 + 10 files changed, 451 insertions(+), 65 deletions(-) delete mode 100644 packages/bower-registry-client/lib/info.js create mode 100644 packages/bower-registry-client/lib/list.js diff --git a/packages/bower-registry-client/.gitignore b/packages/bower-registry-client/.gitignore index 5171c5408..1b6c50d99 100644 --- a/packages/bower-registry-client/.gitignore +++ b/packages/bower-registry-client/.gitignore @@ -1,2 +1,2 @@ -node_modules -npm-debug.log \ No newline at end of file +/node_modules +/npm-debug.* \ No newline at end of file diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js index e79d511fb..795953de3 100644 --- a/packages/bower-registry-client/Client.js +++ b/packages/bower-registry-client/Client.js @@ -2,8 +2,6 @@ var os = require('os'); var path = require('path'); var methods = require('./lib'); -var name; - function RegistryClient(config) { config = config || {}; this._config = config; @@ -57,20 +55,36 @@ function RegistryClient(config) { } // Add every method to the prototype -for (name in methods) { - RegistryClient.prototype[name] = methods[name]; -} +RegistryClient.prototype.lookup = methods.lookup; +RegistryClient.prototype.search = methods.search; +RegistryClient.prototype.list = methods.list; +RegistryClient.prototype.register = methods.register; RegistryClient.prototype.clearCache = function (name, callback) { - // TODO: call other methods once they are done this.lookup.clearCache.call(this, name, callback); + this.search.clearCache.call(this, name, callback); + this.list.clearCache.call(this, callback); +}; +RegistryClient.prototype.cleanRuntimeCache = function () { + this.lookup.cleanRuntimeCache.call(this); + this.search.cleanRuntimeCache.call(this); + this.list.cleanRuntimeCache.call(this); }; // ----------------------------- RegistryClient.prototype._initCache = function () { - // TODO: call other methods once they are done - this.lookup.initCache.call(this, this._config.cache); + var cache; + var dir = this._config.cache; + + // Cache is stored/retrieved statically to ensure singularity + // among instances + cache = this.constructor._cache = this.constructor._cache || {}; + this._cache = cache[dir] = cache[dir] || {}; + + this.lookup.initCache.call(this); + this.search.initCache.call(this); + this.list.initCache.call(this); }; module.exports = RegistryClient; diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index 23511c6b7..5db9f5b79 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -81,4 +81,9 @@ registry.clearCache(function (err) { console.log('Done'); }); -``` \ No newline at end of file +``` + + +## License + +Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). \ No newline at end of file diff --git a/packages/bower-registry-client/lib/index.js b/packages/bower-registry-client/lib/index.js index bb84f53fd..e1e980497 100644 --- a/packages/bower-registry-client/lib/index.js +++ b/packages/bower-registry-client/lib/index.js @@ -1,6 +1,6 @@ module.exports = { - info: require('./info'), lookup: require('./lookup'), + list: require('./list'), register: require('./register'), search: require('./search') }; diff --git a/packages/bower-registry-client/lib/info.js b/packages/bower-registry-client/lib/info.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/bower-registry-client/lib/list.js b/packages/bower-registry-client/lib/list.js new file mode 100644 index 000000000..74eb18284 --- /dev/null +++ b/packages/bower-registry-client/lib/list.js @@ -0,0 +1,173 @@ +var path = require('path'); +var url = require('url'); +var async = require('async'); +var request = require('request'); +var Cache = require('./util/Cache'); +var createError = require('./util/createError'); + +function list(callback) { + var data = []; + var that = this; + var registry = this._config.registry.search; + var total = registry.length; + var index = 0; + + // If no registry entries were passed, simply + // error with package not found + if (!total) { + return callback(null, []); + } + + // Lookup package in series in each registry + // endpoint until we got the data + async.doUntil(function (next) { + var remote = url.parse(registry[index]); + var listCache = that._listCache[remote.host]; + + // If offline flag is passed, only query the cache + if (that._config.offline) { + return listCache.get('list', function (err, results) { + if (err || !results) { + return next(err); + } + + // Add each result + results.forEach(function (result) { + addResult(data, result); + }); + + next(); + }); + } + + // Otherwise make a request to always obtain fresh data + doRequest(index, that._config, function (err, results) { + if (err || !results) { + return next(err); + } + + // Add each result + results.forEach(function (result) { + addResult(data, result); + }); + + // Store in cache for future offline usage + listCache.set('list', results, getMaxAge(), next); + }); + }, function () { + // Until the data is unknown or there's still registries to test + return index++ < total; + }, function (err) { + // Clear runtime cache, keeping the persistent data + // in files for future offline usage + clearRuntimeCache(); + + // If some of the registry entries failed, error out + if (err) { + return callback(err); + } + + callback(null, data); + }); +} + +function addResult(accumulated, result) { + var exists = accumulated.some(function (current) { + return current.name === result.name; + }); + + if (!exists) { + accumulated.push(result); + } +} + +function doRequest(index, config, callback) { + var requestUrl = config.registry.search[index] + '/packages'; + var remote = url.parse(requestUrl); + var headers = {}; + + if (config.userAgent) { + headers['User-Agent'] = config.userAgent; + } + + request.get(requestUrl, { + proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, + ca: config.ca.search[index], + strictSSL: config.strictSsl, + timeout: config.timeout, + json: true + }, function (err, response, body) { + // If there was an internal error (e.g. timeout) + if (err) { + return callback(createError('Request to ' + requestUrl + ' failed: ' + err.message, err.code)); + } + + // Abort if there was an error (range different than 2xx) + if (response.statusCode < 200 || response.statusCode > 299) { + return callback(createError('Request to ' + requestUrl + ' failed with ' + response.statusCode, 'EINVRES')); + } + + // Validate response body, since we are expecting a JSON object + // If the server returns an invalid JSON, it's still a string + if (typeof body !== 'object') { + return callback(createError('Response of request to ' + requestUrl + ' is not a valid json', 'EINVRES')); + } + + callback(null, body); + }); +} + +function getMaxAge() { + // Make it 5 minutes + return 5 * 60 * 60 * 1000; +} + +function initCache() { + this._listCache = this._cache.list || {}; + + // Generate a cache instance for each registry endpoint + this._config.registry.search.forEach(function (registry) { + var cacheDir; + var host = url.parse(registry).host; + + // Skip if there's a cache for the same host + if (this._listCache[host]) { + return; + } + + if (this._config.cache) { + cacheDir = path.join(this._config.cache, encodeURIComponent(host), 'list'); + } + + this._listCache[host] = new Cache(cacheDir, { + max: 250, + // If offline flag is passed, we use stale entries from the cache + useStale: this._config.offline + }); + }, this); +} + +function clearCache(callback) { + var listCache = this._listCache; + var remotes = Object.keys(listCache); + + // There's only one key, which is 'list'.. + // But we clear everything anyway + async.forEach(remotes, function (remote, next) { + listCache[remote].clear(next); + }, callback); +} + +function clearRuntimeCache() { + var remote; + + for (remote in this._listCache) { + this._listCache[remote].reset(); + } +} + +list.initCache = initCache; +list.clearCache = clearCache; +list.clearRuntimeCache = clearRuntimeCache; + +module.exports = list; diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index 6f88beea1..9d825ac0d 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -15,7 +15,7 @@ function lookup(name, callback) { // If no registry entries were passed, simply // error with package not found if (!total) { - return callback(createError('Package "' + name + '" not found', 'ENOTFOUND')); + return callback(); } // Lookup package in series in each registry @@ -25,14 +25,12 @@ function lookup(name, callback) { var lookupCache = that._lookupCache[remote.host]; // If force flag is disabled we check the cache - // and fallback to a request if the offline flag is disabled if (!that._config.force) { lookupCache.get(name, function (err, value) { data = value; - // Don't proceed with making a request if we got - // an error, a value from the cache or if the offline flag is - // enabled + // Don't proceed with making a request if we got an error, + // a value from the cache or if the offline flag is enabled if (err || data || that._config.offline) { return next(err); } @@ -71,11 +69,6 @@ function lookup(name, callback) { return callback(err); } - // If at the end we still have no data, create an appropriate error - if (!data) { - return callback(createError('Package "' + name + '" not found', 'ENOTFOUND')); - } - callback(null, data); }); } @@ -98,7 +91,7 @@ function doRequest(name, index, config, callback) { }, function (err, response, body) { // If there was an internal error (e.g. timeout) if (err) { - return callback(createError('Request to "' + requestUrl + '" failed: ' + err.message, err.code)); + return callback(createError('Request to ' + requestUrl + ' failed: ' + err.message, err.code)); } // If not found, try next @@ -108,13 +101,13 @@ function doRequest(name, index, config, callback) { // Abort if there was an error (range different than 2xx) if (response.statusCode < 200 || response.statusCode > 299) { - return callback(createError('Request to "' + requestUrl + '" failed with ' + response.statusCode, 'EINVRES')); + return callback(createError('Request to ' + requestUrl + ' failed with ' + response.statusCode, 'EINVRES')); } // Validate response body, since we are expecting a JSON object // If the server returns an invalid JSON, it's still a string if (typeof body !== 'object') { - return callback(createError('Response of request to "' + requestUrl + '" is not a valid json', 'EINVRES')); + return callback(createError('Response of request to ' + requestUrl + ' is not a valid json', 'EINVRES')); } callback(null, { @@ -135,7 +128,7 @@ function getMaxAge(entry) { } function initCache() { - this._lookupCache = {}; + this._lookupCache = this._cache.lookup || {}; // Generate a cache instance for each registry endpoint this._config.registry.search.forEach(function (registry) { @@ -148,15 +141,20 @@ function initCache() { } if (this._config.cache) { - cacheDir = path.join(this._config.cache, encodeURIComponent(host)); + cacheDir = path.join(this._config.cache, encodeURIComponent(host), 'lookup'); } - this._lookupCache[host] = new Cache(cacheDir); + this._lookupCache[host] = new Cache(cacheDir, { + max: 250, + // If offline flag is passed, we use stale entries from the cache + useStale: this._config.offline + }); }, this); } function clearCache(name, callback) { - var key; + var lookupCache = this._lookupCache; + var remotes = Object.keys(lookupCache); if (typeof name === 'function') { callback = name; @@ -164,19 +162,26 @@ function clearCache(name, callback) { } if (name) { - for (key in this._lookupCache) { - this._lookupCache[key].del(name); - } + async.forEach(remotes, function (remote, next) { + lookupCache[remote].del(name, next); + }, callback); } else { - for (key in this._lookupCache) { - this._lookupCache[key].clear(); - } + async.forEach(remotes, function (remote, next) { + lookupCache[remote].clear(next); + }, callback); } } -// --------------- +function clearRuntimeCache() { + var remote; + + for (remote in this._lookupCache) { + this._lookupCache[remote].reset(); + } +} lookup.initCache = initCache; lookup.clearCache = clearCache; +lookup.clearRuntimeCache = clearRuntimeCache; module.exports = lookup; diff --git a/packages/bower-registry-client/lib/search.js b/packages/bower-registry-client/lib/search.js index e69de29bb..e0ff7a29b 100644 --- a/packages/bower-registry-client/lib/search.js +++ b/packages/bower-registry-client/lib/search.js @@ -0,0 +1,188 @@ +var path = require('path'); +var url = require('url'); +var async = require('async'); +var request = require('request'); +var Cache = require('./util/Cache'); +var createError = require('./util/createError'); + +// TODO: +// The search cache simply stores a specific search result +// into a file. This is a very rudimentary algorithm but +// works to support elementary offline support +// Once the registry server is rewritten, a better strategy +// can be implemented (with diffs and local search), similar to npm. + +function search(name, callback) { + var data = []; + var that = this; + var registry = this._config.registry.search; + var total = registry.length; + var index = 0; + + // If no registry entries were passed, simply + // error with package not found + if (!total) { + return callback(null, []); + } + + // Search package in series in each registry, + // merging results together + async.doUntil(function (next) { + var remote = url.parse(registry[index]); + var searchCache = that._searchCache[remote.host]; + + // If offline flag is passed, only query the cache + if (that._config.offline) { + return searchCache.get(name, function (err, results) { + if (err || !results || !results.length) { + return next(err); + } + + // Add each result + results.forEach(function (result) { + addResult(data, result); + }); + + next(); + }); + } + + // Otherwise make a request to always obtain fresh data + doRequest(name, index, that._config, function (err, results) { + if (err || !results || !results.length) { + return next(err); + } + + // Add each result + results.forEach(function (result) { + addResult(data, result); + }); + + // Store in cache for future offline usage + searchCache.set(name, results, getMaxAge(), next); + }); + }, function () { + // Until the data is unknown or there's still registries to test + return index++ < total; + }, function (err) { + // Clear runtime cache, keeping the persistent data + // in files for future offline usage + clearRuntimeCache(); + + // If some of the registry entries failed, error out + if (err) { + return callback(err); + } + + callback(null, data); + }); +} + +function addResult(accumulated, result) { + var exists = accumulated.some(function (current) { + return current.name === result.name; + }); + + if (!exists) { + accumulated.push(result); + } +} + +function doRequest(name, index, config, callback) { + var requestUrl = config.registry.search[index] + '/packages/search/' + encodeURIComponent(name); + var remote = url.parse(requestUrl); + var headers = {}; + + if (config.userAgent) { + headers['User-Agent'] = config.userAgent; + } + + request.get(requestUrl, { + proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, + ca: config.ca.search[index], + strictSSL: config.strictSsl, + timeout: config.timeout, + json: true + }, function (err, response, body) { + // If there was an internal error (e.g. timeout) + if (err) { + return callback(createError('Request to ' + requestUrl + ' failed: ' + err.message, err.code)); + } + + // Abort if there was an error (range different than 2xx) + if (response.statusCode < 200 || response.statusCode > 299) { + return callback(createError('Request to ' + requestUrl + ' failed with ' + response.statusCode, 'EINVRES')); + } + + // Validate response body, since we are expecting a JSON object + // If the server returns an invalid JSON, it's still a string + if (typeof body !== 'object') { + return callback(createError('Response of request to ' + requestUrl + ' is not a valid json', 'EINVRES')); + } + + callback(null, body); + }); +} + +function getMaxAge() { + // Make it 5 minutes + return 5 * 60 * 60 * 1000; +} + +function initCache() { + this._searchCache = this._cache.search || {}; + + // Generate a cache instance for each registry endpoint + this._config.registry.search.forEach(function (registry) { + var cacheDir; + var host = url.parse(registry).host; + + // Skip if there's a cache for the same host + if (this._searchCache[host]) { + return; + } + + if (this._config.cache) { + cacheDir = path.join(this._config.cache, encodeURIComponent(host), 'search'); + } + + this._searchCache[host] = new Cache(cacheDir, { + max: 250, + // If offline flag is passed, we use stale entries from the cache + useStale: this._config.offline + }); + }, this); +} + +function clearCache(name, callback) { + var searchCache = this._searchCache; + var remotes = Object.keys(searchCache); + + if (typeof name === 'function') { + callback = name; + name = null; + } + + // Simply erase everything since other searches could + // contain the "name" package + // One possible solution would be to read every entry from the cache and + // delete if the package is contained in the search results + // But this is too expensive + async.forEach(remotes, function (remote, next) { + searchCache[remote].clear(next); + }, callback); +} + +function clearRuntimeCache() { + var remote; + + for (remote in this._searchCache) { + this._searchCache[remote].reset(); + } +} + +search.initCache = initCache; +search.clearCache = clearCache; +search.clearRuntimeCache = clearRuntimeCache; + +module.exports = search; diff --git a/packages/bower-registry-client/lib/util/Cache.js b/packages/bower-registry-client/lib/util/Cache.js index 87f7468c2..c513cfec0 100644 --- a/packages/bower-registry-client/lib/util/Cache.js +++ b/packages/bower-registry-client/lib/util/Cache.js @@ -2,24 +2,19 @@ var fs = require('fs'); var path = require('path'); var async = require('async'); var mkdirp = require('mkdirp'); - -var hasOwn = Object.prototype.hasOwnProperty; +var LRU = require('lru-cache'); function Cache(dir, options) { options = options || {}; - // Default max age of 5 days - if (typeof options.maxAge !== 'number') { - options.maxAge = 5 * 24 * 60 * 60 * 1000; - } - this._dir = dir; this._options = options; - this._cache = {}; + this._cache = this.constructor._cache.get(this._dir); - // TODO: Switch to LRU - // Though, we need to get this merged before: - // https://github.com/isaacs/node-lru-cache/pull/11 + if (!this._cache) { + this._cache = new LRU(options); + this.constructor._cache.set(this._dir, this._cache); + } if (dir) { mkdirp.sync(dir); @@ -28,13 +23,14 @@ function Cache(dir, options) { Cache.prototype.get = function (key, callback) { var file; + var json = this._cache.get(key); // Check in memory - if (hasOwn.call(this._cache, key)) { - if (this._hasExpired(this._cache[key])) { + if (json) { + if (this._hasExpired(json)) { this.del(key, callback); } else { - callback(null, this._cache[key].value); + callback(null, json.value); } return; @@ -49,9 +45,9 @@ Cache.prototype.get = function (key, callback) { fs.readFile(file, function (err, contents) { var json; - // If there was an error reading + // Check if there was an error reading // Note that if the file does not exist then - // we don't got its value + // we don't have its value if (err) { return callback(err.code === 'ENOENT' ? null : err); } @@ -69,7 +65,7 @@ Cache.prototype.get = function (key, callback) { return this.del(key, callback); } - this._cache[key] = json; + this._cache.set(key, json); callback(null, json.value); }.bind(this)); }; @@ -79,18 +75,14 @@ Cache.prototype.set = function (key, value, maxAge, callback) { var entry; var str; - if (typeof maxAge === 'function') { - callback = maxAge; - maxAge = this._options.maxAge; - } - + maxAge = maxAge != null ? maxAge : this._options.maxAge; entry = { - expires: Date.now() + maxAge, + expires: maxAge ? Date.now() + maxAge : null, value: value }; // Store in memory - this._cache[key] = entry; + this._cache.set(key, entry); // Store in disk if (!this._dir) { @@ -111,7 +103,7 @@ Cache.prototype.set = function (key, value, maxAge, callback) { Cache.prototype.del = function (key, callback) { // Delete from memory - delete this._cache[key]; + this._cache.del(key); // Delete from disk if (!this._dir) { @@ -125,7 +117,7 @@ Cache.prototype.clear = function (callback) { var dir = this._dir; // Clear in memory cache - this._cache = {}; + this._cache.reset(); // Clear everything from the disk if (!dir) { @@ -144,20 +136,28 @@ Cache.prototype.clear = function (callback) { }); }; +Cache.prototype.reset = function () { + this._cache.reset(); +}; + Cache.prototype._hasExpired = function (json) { var expires = json.expires; - if (!expires) { + if (!expires || this._options.useStale) { return false; } // Check if the key has expired - expires = parseInt(json.expires, 10); - return !expires || Date.now() > expires; + return Date.now() > expires; }; Cache.prototype._getFile = function (key) { return path.join(this._dir, encodeURIComponent(key)); }; +Cache._cache = new LRU({ + max: 5, + maxAge: 60 * 30 * 1000 // 30 minutes +}); + module.exports = Cache; diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index a5d70b1be..615304642 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -19,6 +19,7 @@ }, "dependencies": { "async": "~0.2.8", + "lru-cache": "~2.3.0", "request": "~2.21.0", "rimraf": "~2.1.4", "mkdirp": "~0.3.5" From b80d96d9c7dce0bd4482a0c0c97a75fa0d469d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 22 Jun 2013 14:15:35 +0100 Subject: [PATCH 0047/1021] Fix tests. --- packages/bower-json/test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index 4323a59cf..79105db5a 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -25,7 +25,7 @@ describe('.find', function () { bowerJson.find(__dirname, function (err) { expect(err).to.be.an(Error); expect(err.code).to.equal('ENOENT'); - expect(err.message).to.equal('Neither bower.json nor component.json were found in "' + __dirname + '"'); + expect(err.message).to.equal('Neither bower.json nor component.json were found in ' + __dirname); done(); }); }); From 7fbbae8cd4c56273e53ae59ab9c0951534bdbfc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 22 Jun 2013 17:05:13 +0100 Subject: [PATCH 0048/1021] Bump (rc3). --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 615304642..d4228ae84 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.0.0-rc2", + "version": "0.0.0-rc3", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From 242e11eefc96ba8e991d68c47a11d9a105cd1e77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 23 Jun 2013 17:43:52 +0100 Subject: [PATCH 0049/1021] Add register. --- .../bower-registry-client/lib/register.js | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/packages/bower-registry-client/lib/register.js b/packages/bower-registry-client/lib/register.js index e69de29bb..286375003 100644 --- a/packages/bower-registry-client/lib/register.js +++ b/packages/bower-registry-client/lib/register.js @@ -0,0 +1,54 @@ +var parseUrl = require('url').parse; +var request = require('request'); +var createError = require('./util/createError'); + +function register(name, url, callback) { + var config = this._config; + var requestUrl = config.registry.register + '/packages'; + var remote = parseUrl(requestUrl); + var headers = {}; + + if (config.userAgent) { + headers['User-Agent'] = config.userAgent; + } + + request.post({ + url: requestUrl, + proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, + ca: config.ca.register, + strictSSL: config.strictSsl, + timeout: config.timeout, + json: true, + form: { + name: name, + url: url + } + }, function (err, response) { + // If there was an internal error (e.g. timeout) + if (err) { + return callback(createError('Request to ' + requestUrl + ' failed: ' + err.message, err.code)); + } + + // Duplicate + if (response.statusCode === 406) { + return callback(createError('Duplicate package', 'EDUPLICATE')); + } + + // Invalid format + if (response.statusCode === 400) { + return callback(createError('Invalid URL format', 'EINVFORMAT')); + } + + // Everything other than 201 is unknown + if (response.statusCode !== 201) { + return callback(createError('Unknown error: ' + response.statusCode, 'EUNKNOWN')); + } + + callback(null, { + name: name, + url: url + }); + }); +} + +module.exports = register; From 442d771a7a0392086560769dba0ce95f35c1a2b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 23 Jun 2013 17:44:29 +0100 Subject: [PATCH 0050/1021] Bump rc version. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index d4228ae84..bf571099f 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.0.0-rc3", + "version": "0.0.0-rc4", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From 94f6945d5a3d5de4849a64eda8fc00977276c251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 24 Jun 2013 14:48:20 +0100 Subject: [PATCH 0051/1021] Complete README, change cleanRuntimeCache to clearRuntimeCache. --- packages/bower-registry-client/Client.js | 2 +- packages/bower-registry-client/README.md | 58 ++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js index 795953de3..6ac2be424 100644 --- a/packages/bower-registry-client/Client.js +++ b/packages/bower-registry-client/Client.js @@ -65,7 +65,7 @@ RegistryClient.prototype.clearCache = function (name, callback) { this.search.clearCache.call(this, name, callback); this.list.clearCache.call(this, callback); }; -RegistryClient.prototype.cleanRuntimeCache = function () { +RegistryClient.prototype.clearRuntimeCache = function () { this.lookup.cleanRuntimeCache.call(this); this.search.cleanRuntimeCache.call(this); this.list.cleanRuntimeCache.call(this); diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index 5db9f5b79..e3d415b21 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -38,7 +38,7 @@ Different operations may have different cache expiration times. Looks the registry for the package `name`, ```js -registry.lookup(name, function (err, entry) { +registry.lookup('jquery', function (err, entry) { if (err) { console.error(err.message); return; @@ -52,15 +52,46 @@ registry.lookup(name, function (err, entry) { #### .register(name, url, callback) +Registers a package in the registry. + +```js +registry.register('my-package', 'git://github.com/my-org/my-package.git', function (err, pkg) { + if (err) { + console.error(err.message); + return; + } + + console.log('name', pkg.name); + console.log('url: ', pkg.url); +}); +``` + #### .search(str, callback) -#### .info(name, callback) +Searches the registry. + +```js +registry.search('jquery', url, function (err, results) { + if (err) { + console.error(err.message); + return; + } + + results.forEach(function (pkg) { + console.log('name', pkg.name); + console.log('url', pkg.url); + }); +}); +``` #### .clearCache(name, callback) -Clear the cache associated with the `name` package. +Clear the persistent and runtime cache associated with the `name` package. If `name` is null, clears the cache for every package. +Note that in most cases, you don't need to clear the cache since it has +self expiration times. + ```js // Clear jquery cache registry.clearCache('jquery', function (err) { @@ -84,6 +115,27 @@ registry.clearCache(function (err) { ``` +#### .clearRuntimeCache(callback) + +Clear the in-memory cache used to speed up the module. + +Note that in most cases, you don't need to clear the runtime cache since it has +self expiration times. +Might be useful if you use this module in long-living programs. + +```js + +registry.clearRuntimeCache(function (err) { + if (err) { + console.error(err.message); + return; + } + + console.log('Done'); +}); +``` + + ## License Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). \ No newline at end of file From a100abc3b6de23e4f04713c352b8dd73263cb38d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 24 Jun 2013 14:48:36 +0100 Subject: [PATCH 0052/1021] Bump rc version. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index bf571099f..b53463801 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.0.0-rc4", + "version": "0.0.0-rc5", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From 0ebd7e6a58dc8ccad00f0acb4f3926e6d126c820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 24 Jun 2013 14:49:36 +0100 Subject: [PATCH 0053/1021] Small typo in README. --- packages/bower-registry-client/README.md | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index e3d415b21..91647088b 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -46,7 +46,7 @@ registry.lookup('jquery', function (err, entry) { // For now resp.type is always 'alias' console.log('type', entry.type); - console.log('url: ', entry.url); + console.log('url', entry.url); }); ``` @@ -71,7 +71,7 @@ registry.register('my-package', 'git://github.com/my-org/my-package.git', functi Searches the registry. ```js -registry.search('jquery', url, function (err, results) { +registry.search('jquery', function (err, results) { if (err) { console.error(err.message); return; @@ -86,7 +86,7 @@ registry.search('jquery', url, function (err, results) { #### .clearCache(name, callback) -Clear the persistent and runtime cache associated with the `name` package. +Clears the persistent and runtime cache associated with the `name` package. If `name` is null, clears the cache for every package. Note that in most cases, you don't need to clear the cache since it has @@ -115,9 +115,9 @@ registry.clearCache(function (err) { ``` -#### .clearRuntimeCache(callback) +#### .clearRuntimeCache() -Clear the in-memory cache used to speed up the module. +Clears the in-memory cache used to speed up the module. Note that in most cases, you don't need to clear the runtime cache since it has self expiration times. @@ -125,14 +125,7 @@ Might be useful if you use this module in long-living programs. ```js -registry.clearRuntimeCache(function (err) { - if (err) { - console.error(err.message); - return; - } - - console.log('Done'); -}); +registry.clearRuntimeCache(); ``` From 9d9585ecba4021868289fd1243789fdd88333df6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 28 Jun 2013 21:59:24 +0100 Subject: [PATCH 0054/1021] Ignore ENOENT erros when deleting from the cache. --- packages/bower-registry-client/lib/util/Cache.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/bower-registry-client/lib/util/Cache.js b/packages/bower-registry-client/lib/util/Cache.js index c513cfec0..c2931f3c0 100644 --- a/packages/bower-registry-client/lib/util/Cache.js +++ b/packages/bower-registry-client/lib/util/Cache.js @@ -110,7 +110,13 @@ Cache.prototype.del = function (key, callback) { return callback(null); } - fs.unlink(this._getFile(key), callback); + fs.unlink(this._getFile(key), function (err) { + if (!err || err.code !== 'ENOENT') { + return callback(err); + } + + callback(); + }); }; Cache.prototype.clear = function (callback) { @@ -131,7 +137,13 @@ Cache.prototype.clear = function (callback) { // Delete every file in parallel async.forEach(files, function (file, next) { - fs.unlink(path.join(dir, file), next); + fs.unlink(path.join(dir, file), function (err) { + if (!err || err.code !== 'ENOENT') { + return next(err); + } + + next(); + }); }, callback); }); }; From c9a7cfafd047e71965d8a1ffa85fb06c9a366716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 28 Jun 2013 21:59:56 +0100 Subject: [PATCH 0055/1021] Bump rc version! --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index b53463801..f4cf24f34 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.0.0-rc5", + "version": "0.0.0-rc6", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From dc9bce915bf9651ea665b71bc6a9a38da8b3e888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 1 Jul 2013 20:28:11 +0100 Subject: [PATCH 0056/1021] Switch to graceful-fs. --- packages/bower-registry-client/lib/util/Cache.js | 2 +- packages/bower-registry-client/package.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/bower-registry-client/lib/util/Cache.js b/packages/bower-registry-client/lib/util/Cache.js index c2931f3c0..e2f1cf4df 100644 --- a/packages/bower-registry-client/lib/util/Cache.js +++ b/packages/bower-registry-client/lib/util/Cache.js @@ -1,4 +1,4 @@ -var fs = require('fs'); +var fs = require('graceful-fs'); var path = require('path'); var async = require('async'); var mkdirp = require('mkdirp'); diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index f4cf24f34..e3cd01f2b 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -19,6 +19,7 @@ }, "dependencies": { "async": "~0.2.8", + "graceful-fs": "~1.2.2", "lru-cache": "~2.3.0", "request": "~2.21.0", "rimraf": "~2.1.4", From 36b033c2f742555aee3388a3c1ba74b37952249b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 1 Jul 2013 20:28:37 +0100 Subject: [PATCH 0057/1021] Switch to graceful-fs. --- packages/bower-json/lib/json.js | 2 +- packages/bower-json/package.json | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index bf0562cc0..34ca37a4a 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -1,4 +1,4 @@ -var fs = require('fs'); +var fs = require('graceful-fs'); var path = require('path'); function read(file, callback) { diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index eabca990b..380856912 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -17,6 +17,9 @@ "engines": { "node": ">=0.8.0" }, + "dependencies": { + "graceful-fs": "~1.2.2" + }, "devDependencies": { "mocha": "~1.8.2", "expect.js": "~0.2.0" From 649d5f56c965dfa1657e379fcaed2a5a883a0590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Tue, 2 Jul 2013 09:41:17 +0100 Subject: [PATCH 0058/1021] Minor doc typo. --- packages/bower-registry-client/lib/lookup.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index 9d825ac0d..edf85b13a 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -12,8 +12,7 @@ function lookup(name, callback) { var total = registry.length; var index = 0; - // If no registry entries were passed, simply - // error with package not found + // If no registry entries were passed.. if (!total) { return callback(); } From d30a7bf6a18092a9082c6ab2616739bf381bb41e Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Tue, 2 Jul 2013 22:50:26 +0100 Subject: [PATCH 0059/1021] adds .editorconfig --- packages/bower-registry-client/.editorconfig | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 packages/bower-registry-client/.editorconfig diff --git a/packages/bower-registry-client/.editorconfig b/packages/bower-registry-client/.editorconfig new file mode 100644 index 000000000..ba4428907 --- /dev/null +++ b/packages/bower-registry-client/.editorconfig @@ -0,0 +1,8 @@ +root = true + +[*] + +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 From c894b1d335d1b202b1db9abc26522cd64b5bec2e Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Tue, 2 Jul 2013 22:51:43 +0100 Subject: [PATCH 0060/1021] adds grunt and test runner setup --- packages/bower-registry-client/Gruntfile.js | 49 +++++++++++++++++++ packages/bower-registry-client/package.json | 6 ++- packages/bower-registry-client/test/Client.js | 20 ++++++++ packages/bower-registry-client/test/runner.js | 2 + 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 packages/bower-registry-client/Gruntfile.js create mode 100644 packages/bower-registry-client/test/Client.js create mode 100644 packages/bower-registry-client/test/runner.js diff --git a/packages/bower-registry-client/Gruntfile.js b/packages/bower-registry-client/Gruntfile.js new file mode 100644 index 000000000..e55a81c61 --- /dev/null +++ b/packages/bower-registry-client/Gruntfile.js @@ -0,0 +1,49 @@ +/*global module:false*/ + +module.exports = function (grunt) { + + 'use strict'; + + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-simple-mocha'); + + // Project configuration. + grunt.initConfig({ + + jshint: { + files: [ + 'Gruntfile.js', + 'lib/**/*.js' + ], + options: { + jshintrc: '.jshintrc' + } + }, + + simplemocha: { + options: { + reporter: 'spec' + }, + full: { src: ['test/runner.js'] }, + short: { + options: { + reporter: 'dot' + }, + src: ['test/runner.js'] + } + }, + + + watch: { + files: [''], + tasks: 'jshint' + } + + }); + + // Default task. + grunt.registerTask('default', 'jshint'); + grunt.registerTask('test', 'simplemocha:full'); + +}; diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index e3cd01f2b..fe65e5ba2 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -27,7 +27,11 @@ }, "devDependencies": { "mocha": "~1.8.2", - "expect.js": "~0.2.0" + "expect.js": "~0.2.0", + "grunt": "~0.4.1", + "grunt-contrib-watch": "~0.4.4", + "grunt-contrib-jshint": "~0.6.0", + "grunt-simple-mocha": "~0.4.0" }, "scripts": { "test": "mocha -R spec" diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js new file mode 100644 index 000000000..903c71580 --- /dev/null +++ b/packages/bower-registry-client/test/Client.js @@ -0,0 +1,20 @@ +var RegistryClient = require('../Client'); + +describe('RegistryClient', function () { + + beforeEach(function () { + + + + }); + + afterEach(function () { + + }); + + describe('Constructor', function () { + + + }); + +}); diff --git a/packages/bower-registry-client/test/runner.js b/packages/bower-registry-client/test/runner.js new file mode 100644 index 000000000..6262134f3 --- /dev/null +++ b/packages/bower-registry-client/test/runner.js @@ -0,0 +1,2 @@ +require('./client'); + From 8d22059462b7c70693140134f39395f3ed8fce18 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Tue, 2 Jul 2013 23:26:07 +0100 Subject: [PATCH 0061/1021] adds grunt travis setup --- packages/bower-registry-client/.travis.yml | 4 +++- packages/bower-registry-client/Gruntfile.js | 12 +++++++++-- packages/bower-registry-client/package.json | 5 +++-- packages/bower-registry-client/test/Client.js | 20 ++++++++++++------- .../test/{ => core}/lookup.js | 0 5 files changed, 29 insertions(+), 12 deletions(-) rename packages/bower-registry-client/test/{ => core}/lookup.js (100%) diff --git a/packages/bower-registry-client/.travis.yml b/packages/bower-registry-client/.travis.yml index 2ca91f289..7ab092601 100644 --- a/packages/bower-registry-client/.travis.yml +++ b/packages/bower-registry-client/.travis.yml @@ -1,4 +1,6 @@ +before_script: + - npm install -g grunt-cli language: node_js node_js: - "0.10" - - "0.8" \ No newline at end of file + - "0.8" diff --git a/packages/bower-registry-client/Gruntfile.js b/packages/bower-registry-client/Gruntfile.js index e55a81c61..e93add5d5 100644 --- a/packages/bower-registry-client/Gruntfile.js +++ b/packages/bower-registry-client/Gruntfile.js @@ -31,13 +31,20 @@ module.exports = function (grunt) { reporter: 'dot' }, src: ['test/runner.js'] + }, + build: { + options: { + reporter: 'tap' + }, + src: ['test/runner.js'] } + }, watch: { - files: [''], - tasks: 'jshint' + files: ['<%= jshint.files %>'], + tasks: ['jshint', 'simplemocha:short'] } }); @@ -45,5 +52,6 @@ module.exports = function (grunt) { // Default task. grunt.registerTask('default', 'jshint'); grunt.registerTask('test', 'simplemocha:full'); + grunt.registerTask('build', ['jshint', 'simplemocha:build']); }; diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index fe65e5ba2..2b9cf25da 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -31,9 +31,10 @@ "grunt": "~0.4.1", "grunt-contrib-watch": "~0.4.4", "grunt-contrib-jshint": "~0.6.0", - "grunt-simple-mocha": "~0.4.0" + "grunt-simple-mocha": "~0.4.0", + "chai": "~1.7.2" }, "scripts": { - "test": "mocha -R spec" + "test": "grunt build --verbose" } } diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 903c71580..7102073d7 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -1,19 +1,25 @@ -var RegistryClient = require('../Client'); +var RegistryClient = require('../Client'), + expect = require('chai').expect; describe('RegistryClient', function () { beforeEach(function () { - - - + this.client = new RegistryClient(); }); - afterEach(function () { + describe('Constructor', function () { - }); + describe('instantiating a client', function () { - describe('Constructor', function () { + it('should set properties correctly', function () { + expect(this.client).to.have.ownProperty('_config'); + expect(this.client).to.have.ownProperty('_cache'); + expect(this.client).to.have.ownProperty('_lookupCache'); + expect(this.client).to.have.ownProperty('_searchCache'); + expect(this.client).to.have.ownProperty('_listCache'); + }); + }); }); diff --git a/packages/bower-registry-client/test/lookup.js b/packages/bower-registry-client/test/core/lookup.js similarity index 100% rename from packages/bower-registry-client/test/lookup.js rename to packages/bower-registry-client/test/core/lookup.js From ff5bf16111607b68ba91f4da65c7432981d7763f Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Tue, 2 Jul 2013 23:33:52 +0100 Subject: [PATCH 0062/1021] fix file reference --- packages/bower-registry-client/test/runner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/test/runner.js b/packages/bower-registry-client/test/runner.js index 6262134f3..f6f73ceda 100644 --- a/packages/bower-registry-client/test/runner.js +++ b/packages/bower-registry-client/test/runner.js @@ -1,2 +1,2 @@ -require('./client'); +require('./Client'); From 67a96bc2f38da44a4457e02d25253240b89f2201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 3 Jul 2013 16:18:22 +0100 Subject: [PATCH 0063/1021] Typo ignoring ENOENT errors. --- packages/bower-registry-client/lib/util/Cache.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-registry-client/lib/util/Cache.js b/packages/bower-registry-client/lib/util/Cache.js index e2f1cf4df..909d279ff 100644 --- a/packages/bower-registry-client/lib/util/Cache.js +++ b/packages/bower-registry-client/lib/util/Cache.js @@ -111,7 +111,7 @@ Cache.prototype.del = function (key, callback) { } fs.unlink(this._getFile(key), function (err) { - if (!err || err.code !== 'ENOENT') { + if (err && err.code !== 'ENOENT') { return callback(err); } @@ -138,7 +138,7 @@ Cache.prototype.clear = function (callback) { // Delete every file in parallel async.forEach(files, function (file, next) { fs.unlink(path.join(dir, file), function (err) { - if (!err || err.code !== 'ENOENT') { + if (err && err.code !== 'ENOENT') { return next(err); } From 9dc835c60c0f047922b65e31b7243753af49f186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 3 Jul 2013 16:18:50 +0100 Subject: [PATCH 0064/1021] Bump rc version. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index e3cd01f2b..6986de3b3 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.0.0-rc6", + "version": "0.0.0-rc7", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From 827fbaac1f6209b55a118d01011383d749f57b9f Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 4 Jul 2013 10:40:03 +0100 Subject: [PATCH 0065/1021] update jshint settings --- packages/bower-registry-client/.jshintrc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/bower-registry-client/.jshintrc b/packages/bower-registry-client/.jshintrc index 52c609091..1669bec7f 100644 --- a/packages/bower-registry-client/.jshintrc +++ b/packages/bower-registry-client/.jshintrc @@ -35,10 +35,9 @@ "boss": true, "debug": false, "eqnull": true, - "es5": false, "esnext": false, "evil": false, - "expr": false, + "expr": true, "funcscope": false, "globalstrict": false, "iterator": false, From a08a0fb0847173b82dd7ac4dc0fc45e3c8647423 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 4 Jul 2013 10:40:21 +0100 Subject: [PATCH 0066/1021] add tests to jshint --- packages/bower-registry-client/Gruntfile.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/bower-registry-client/Gruntfile.js b/packages/bower-registry-client/Gruntfile.js index e93add5d5..1cdba105a 100644 --- a/packages/bower-registry-client/Gruntfile.js +++ b/packages/bower-registry-client/Gruntfile.js @@ -14,7 +14,8 @@ module.exports = function (grunt) { jshint: { files: [ 'Gruntfile.js', - 'lib/**/*.js' + 'lib/**/*.js', + 'test/**/*.js' ], options: { jshintrc: '.jshintrc' From 720492932f584dc8bf91905eef943abdec071182 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 4 Jul 2013 10:40:36 +0100 Subject: [PATCH 0067/1021] update Client.js tests --- packages/bower-registry-client/test/Client.js | 69 ++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 7102073d7..7c16afbc4 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -4,12 +4,23 @@ var RegistryClient = require('../Client'), describe('RegistryClient', function () { beforeEach(function () { + this.uri = 'https://bower.herokuapp.com'; + this.timeoutVal = 5000; this.client = new RegistryClient(); + this.conf = { + search: [this.uri], + register: this.uri, + publish: this.uri + }; }); describe('Constructor', function () { - describe('instantiating a client', function () { + describe('instantiating a client without custom options', function () { + + it('should provide an instance of RegistryClient', function () { + expect(this.client instanceof RegistryClient).to.be.ok; + }); it('should set properties correctly', function () { expect(this.client).to.have.ownProperty('_config'); @@ -19,6 +30,62 @@ describe('RegistryClient', function () { expect(this.client).to.have.ownProperty('_listCache'); }); + it('should set default registry config', function () { + expect(this.client._config.registry).to.deep.equal(this.conf); + }); + + it('should set default search config', function () { + expect(this.client._config.registry.search[0]).to.equal(this.uri); + }); + + it('should set default register config', function () { + expect(this.client._config.registry.register).to.equal(this.uri); + }); + + it('should set default publish config', function () { + expect(this.client._config.registry.publish).to.equal(this.uri); + }); + + it('should set default cache path config', function () { + expect(typeof this.client._config.cache === 'string').to.be.ok; + }); + + it('should set default timeout config', function () { + expect(this.client._config.timeout).to.equal(this.timeoutVal); + }); + + it('should set default strictSsl config', function () { + expect(this.client._config.strictSsl).to.be.ok; + }); + + }); + + it('should have a lookup prototype method', function () { + expect(RegistryClient.prototype).to.have.ownProperty('lookup'); + }); + + it('should have a search prototype method', function () { + expect(RegistryClient.prototype).to.have.ownProperty('search'); + }); + + it('should have a list prototype method', function () { + expect(RegistryClient.prototype).to.have.ownProperty('list'); + }); + + it('should have a register prototype method', function () { + expect(RegistryClient.prototype).to.have.ownProperty('register'); + }); + + it('should have a clearCache prototype method', function () { + expect(RegistryClient.prototype).to.have.ownProperty('clearCache'); + }); + + it('should have a clearRuntimeCache prototype method', function () { + expect(RegistryClient.prototype).to.have.ownProperty('clearRuntimeCache'); + }); + + it('should have a _initCache prototype method', function () { + expect(RegistryClient.prototype).to.have.ownProperty('_initCache'); }); }); From 15c8259ac2c5f656c1c17bf5ed181614c31c4201 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 4 Jul 2013 14:50:32 +0100 Subject: [PATCH 0068/1021] adds lookup tests --- .../bower-registry-client/test/core/lookup.js | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/packages/bower-registry-client/test/core/lookup.js b/packages/bower-registry-client/test/core/lookup.js index e69de29bb..122754867 100644 --- a/packages/bower-registry-client/test/core/lookup.js +++ b/packages/bower-registry-client/test/core/lookup.js @@ -0,0 +1,29 @@ +var lookup = require('../../lib/lookup'), + expect = require('chai').expect; + +describe('lookup module', function () { + + describe('requiring the lookup module', function () { + + it('should expose a lookup method', function () { + expect(typeof lookup === 'function').to.be.ok; + }); + + it('should expose a initCache method', function () { + expect(lookup.initCache).to.be.ok; + expect(typeof lookup.initCache === 'function').to.be.ok; + }); + + it('should expose a clearCache method', function () { + expect(lookup.clearCache).to.be.ok; + expect(typeof lookup.clearCache === 'function').to.be.ok; + }); + + it('should expose a ClearRuntimeCache method', function () { + expect(lookup.clearCache).to.be.ok; + expect(typeof lookup.clearCache === 'function').to.be.ok; + }); + + }); + +}); From b8ba6e48276166be905a1ee7a1a3efadee1712d9 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 4 Jul 2013 14:50:39 +0100 Subject: [PATCH 0069/1021] adds index tests --- .../bower-registry-client/test/core/index.js | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 packages/bower-registry-client/test/core/index.js diff --git a/packages/bower-registry-client/test/core/index.js b/packages/bower-registry-client/test/core/index.js new file mode 100644 index 000000000..923a7fb3a --- /dev/null +++ b/packages/bower-registry-client/test/core/index.js @@ -0,0 +1,26 @@ +var index = require('../../lib/index'), + expect = require('chai').expect; + +describe('index module', function () { + + describe('requiring the index module', function () { + + it('should expose a lookup method', function () { + expect(index.lookup).to.be.ok; + }); + + it('should expose a list method', function () { + expect(index.list).to.be.ok; + }); + + it('should expose a register method', function () { + expect(index.register).to.be.ok; + }); + + it('should expose a search method', function () { + expect(index.search).to.be.ok; + }); + + }); + +}); From 223161c7d61581487a9f7f2e505a535d6533c74a Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 4 Jul 2013 14:50:47 +0100 Subject: [PATCH 0070/1021] adds list tests --- .../bower-registry-client/test/core/list.js | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 packages/bower-registry-client/test/core/list.js diff --git a/packages/bower-registry-client/test/core/list.js b/packages/bower-registry-client/test/core/list.js new file mode 100644 index 000000000..cb4c955fe --- /dev/null +++ b/packages/bower-registry-client/test/core/list.js @@ -0,0 +1,29 @@ +var list = require('../../lib/list'), + expect = require('chai').expect; + +describe('list module', function () { + + describe('requiring the list module', function () { + + it('should expose a list method', function () { + expect(typeof list === 'function').to.be.ok; + }); + + it('should expose a initCache method', function () { + expect(list.initCache).to.be.ok; + expect(typeof list.initCache === 'function').to.be.ok; + }); + + it('should expose a clearCache method', function () { + expect(list.clearCache).to.be.ok; + expect(typeof list.clearCache === 'function').to.be.ok; + }); + + it('should expose a ClearRuntimeCache method', function () { + expect(list.clearCache).to.be.ok; + expect(typeof list.clearCache === 'function').to.be.ok; + }); + + }); + +}); From f5eec3283c00e5b43da4576f43da8c873a87c352 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 4 Jul 2013 14:50:54 +0100 Subject: [PATCH 0071/1021] adds register tests --- .../bower-registry-client/test/core/register.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 packages/bower-registry-client/test/core/register.js diff --git a/packages/bower-registry-client/test/core/register.js b/packages/bower-registry-client/test/core/register.js new file mode 100644 index 000000000..42ea303ce --- /dev/null +++ b/packages/bower-registry-client/test/core/register.js @@ -0,0 +1,14 @@ +var register = require('../../lib/register'), + expect = require('chai').expect; + +describe('register module', function () { + + describe('requiring the register module', function () { + + it('should expose a register method', function () { + expect(typeof register === 'function').to.be.ok; + }); + + }); + +}); From bf8e93f5810f56f63549155177b47e6f6e18f74e Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 4 Jul 2013 14:51:03 +0100 Subject: [PATCH 0072/1021] adds search tests --- .../bower-registry-client/test/core/search.js | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 packages/bower-registry-client/test/core/search.js diff --git a/packages/bower-registry-client/test/core/search.js b/packages/bower-registry-client/test/core/search.js new file mode 100644 index 000000000..d0227d00e --- /dev/null +++ b/packages/bower-registry-client/test/core/search.js @@ -0,0 +1,29 @@ +var search = require('../../lib/search'), + expect = require('chai').expect; + +describe('search module', function () { + + describe('requiring the search module', function () { + + it('should expose a search method', function () { + expect(typeof search === 'function').to.be.ok; + }); + + it('should expose a initCache method', function () { + expect(search.initCache).to.be.ok; + expect(typeof search.initCache === 'function').to.be.ok; + }); + + it('should expose a clearCache method', function () { + expect(search.clearCache).to.be.ok; + expect(typeof search.clearCache === 'function').to.be.ok; + }); + + it('should expose a clearRuntimeCache method', function () { + expect(search.clearRuntimeCache).to.be.ok; + expect(typeof search.clearRuntimeCache === 'function').to.be.ok; + }); + + }); + +}); From 2df41e52edcff1ca8d17dc3502c4f3401e33d07e Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 4 Jul 2013 14:51:09 +0100 Subject: [PATCH 0073/1021] adds Cache tests --- .../test/core/util/Cache.js | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 packages/bower-registry-client/test/core/util/Cache.js diff --git a/packages/bower-registry-client/test/core/util/Cache.js b/packages/bower-registry-client/test/core/util/Cache.js new file mode 100644 index 000000000..4842da6eb --- /dev/null +++ b/packages/bower-registry-client/test/core/util/Cache.js @@ -0,0 +1,69 @@ +var Cache = require('../../../lib/util/Cache'), + expect = require('chai').expect; + +describe('Cache', function () { + + beforeEach(function () { + this.cache = new Cache(); + }); + + describe('Constructor', function () { + + describe('instantiating cache', function () { + + it('should provide an instance of RegistryClient', function () { + expect(this.cache instanceof Cache).to.be.ok; + }); + + it('should set properties correctly', function () { + expect(this.cache).to.have.ownProperty('_cache'); + expect(this.cache).to.have.ownProperty('_options'); + }); + + it('should inherit LRU cache methods', function () { + var self = this, + lruMethods = [ + 'max', 'lengthCalculator', 'length', 'itemCount', 'forEach', + 'keys', 'values', 'reset', 'dump', 'dumpLru', 'set', 'has', + 'get', 'peek', 'del' + ]; + + lruMethods.forEach(function (method) { + expect(self.cache._cache).to.have.ownProperty(method); + }); + + }); + + }); + + it('should have a get prototype method', function () { + expect(Cache.prototype).to.have.ownProperty('get'); + }); + + it('should have a set prototype method', function () { + expect(Cache.prototype).to.have.ownProperty('set'); + }); + + it('should have a del prototype method', function () { + expect(Cache.prototype).to.have.ownProperty('del'); + }); + + it('should have a clear prototype method', function () { + expect(Cache.prototype).to.have.ownProperty('clear'); + }); + + it('should have a reset prototype method', function () { + expect(Cache.prototype).to.have.ownProperty('reset'); + }); + + it('should have a reset _hasExpired method', function () { + expect(Cache.prototype).to.have.ownProperty('_hasExpired'); + }); + + it('should have a reset _getFile method', function () { + expect(Cache.prototype).to.have.ownProperty('_getFile'); + }); + + }); + +}); From 2e845ac0ab7c49cd4d971021e67e2932824a928c Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 4 Jul 2013 14:51:17 +0100 Subject: [PATCH 0074/1021] adds createError tests --- .../test/core/util/createError.js | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 packages/bower-registry-client/test/core/util/createError.js diff --git a/packages/bower-registry-client/test/core/util/createError.js b/packages/bower-registry-client/test/core/util/createError.js new file mode 100644 index 000000000..c91a97e2c --- /dev/null +++ b/packages/bower-registry-client/test/core/util/createError.js @@ -0,0 +1,35 @@ +var createError = require('../../../lib/util/createError'), + expect = require('chai').expect; + +describe('createError', function () { + + beforeEach(function () { + this.err = createError('message', 500); + }); + + describe('requiring the createError module', function () { + + it('should expose a createError method', function () { + expect(typeof createError === 'function').to.be.ok; + }); + + }); + + describe('invoking createError', function () { + + it('should return a new Error Object', function () { + expect(typeof createError() === 'object').to.be.ok; + }); + + it('should return an Error with message', function () { + expect(this.err.message).to.equal('message'); + }); + + it('should return an Error with code', function () { + expect(this.err.code).to.equal(500); + }); + + }); + + +}); From 7e62e671e3fffab04d2fd19012c2b1e8b5ee8634 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 4 Jul 2013 14:51:29 +0100 Subject: [PATCH 0075/1021] updates testrunner --- packages/bower-registry-client/test/runner.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/bower-registry-client/test/runner.js b/packages/bower-registry-client/test/runner.js index f6f73ceda..8c1b6a195 100644 --- a/packages/bower-registry-client/test/runner.js +++ b/packages/bower-registry-client/test/runner.js @@ -1,2 +1,9 @@ require('./Client'); +require('./core/search'); +require('./core/register'); +require('./core/lookup'); +require('./core/list'); +require('./core/index'); +require('./core/util/Cache'); +require('./core/util/createError'); From 73020a711dcafeffa2b7283ce97f4032df2b5986 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 4 Jul 2013 15:00:15 +0100 Subject: [PATCH 0076/1021] tweaking docs --- packages/bower-registry-client/README.md | 29 ++++++++++++------------ 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index 91647088b..1b4bbd75a 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -13,20 +13,21 @@ var registry = new RegistryClient(options); Available constructor options: -- cache: the cache folder to use for some operations; using null will disable persistent cache (defaults to OS temp folder) -- registry.search: an array of registry search endpoints (defaults to the Bower server) -- registry.register: the endpoint to use when registering packages (defaults to the Bower server) -- registry.publish: the endpoint to use when publishing packages (defaults to the Bower server) -- ca.search: an array of CA certificates for each registry.search (defaults to null). -- ca.register: the CA certificate for registry.register -- ca.publish: the CA certificate for registry.publish -- proxy: the proxy to use for http requests (defaults to null) -- httpsProxy: the proxy to use for https requests (defaults to null) -- strictSsl: whether or not to do SSL key validation when making requests via https (defaults to true). -- userAgent: the user agent to use for the requests (defaults to null) -- timeout: the timeout for the requests to finish (defaults to 5000) -- force: If set to true, cache will be bypassed and remotes will always be hit (defaults to false). -- offline: If set to true, only the cache will be used (defaults to false). +- `cache`: the cache folder to use for some operations; using null will disable persistent cache (defaults to OS temp folder) +- `registry.search`: an array of registry search endpoints (defaults to the Bower server) +- `registry.register`: the endpoint to use when registering packages (defaults to the Bower server) +- `registry.publish`: the endpoint to use when publishing packages (defaults to the Bower server) +- `ca.search`: an array of CA certificates for each registry.search (defaults to null). +- `ca.register`: the CA certificate for registry.register +- `ca.publish`: the CA certificate for registry.publish +- `proxy`: the proxy to use for http requests (defaults to null) +- `httpsProxy`: the proxy to use for https requests (defaults to null) +- `strictSsl`: whether or not to do SSL key validation when making requests via https (defaults to true). +- `userAgent`: the user agent to use for the requests (defaults to null) +- `timeout`: the timeout for the requests to finish (defaults to 5000) +- `force`: If set to true, cache will be bypassed and remotes will always be hit (defaults to false). +- `offline`: If set to true, only the cache will be used (defaults to false). + Note that `force` and `offline` are mutually exclusive. The cache will speedup operations such as `lookup` and `info`. From aea19b93b11b6fbdc14fcad5c6e434cf9732144f Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 4 Jul 2013 15:11:44 +0100 Subject: [PATCH 0077/1021] rename client -> registry because that's what it is right? --- packages/bower-registry-client/test/Client.js | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 7c16afbc4..a6fb5101d 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -6,7 +6,7 @@ describe('RegistryClient', function () { beforeEach(function () { this.uri = 'https://bower.herokuapp.com'; this.timeoutVal = 5000; - this.client = new RegistryClient(); + this.registry = new RegistryClient(); this.conf = { search: [this.uri], register: this.uri, @@ -19,43 +19,43 @@ describe('RegistryClient', function () { describe('instantiating a client without custom options', function () { it('should provide an instance of RegistryClient', function () { - expect(this.client instanceof RegistryClient).to.be.ok; + expect(this.registry instanceof RegistryClient).to.be.ok; }); it('should set properties correctly', function () { - expect(this.client).to.have.ownProperty('_config'); - expect(this.client).to.have.ownProperty('_cache'); - expect(this.client).to.have.ownProperty('_lookupCache'); - expect(this.client).to.have.ownProperty('_searchCache'); - expect(this.client).to.have.ownProperty('_listCache'); + expect(this.registry).to.have.ownProperty('_config'); + expect(this.registry).to.have.ownProperty('_cache'); + expect(this.registry).to.have.ownProperty('_lookupCache'); + expect(this.registry).to.have.ownProperty('_searchCache'); + expect(this.registry).to.have.ownProperty('_listCache'); }); it('should set default registry config', function () { - expect(this.client._config.registry).to.deep.equal(this.conf); + expect(this.registry._config.registry).to.deep.equal(this.conf); }); it('should set default search config', function () { - expect(this.client._config.registry.search[0]).to.equal(this.uri); + expect(this.registry._config.registry.search[0]).to.equal(this.uri); }); it('should set default register config', function () { - expect(this.client._config.registry.register).to.equal(this.uri); + expect(this.registry._config.registry.register).to.equal(this.uri); }); it('should set default publish config', function () { - expect(this.client._config.registry.publish).to.equal(this.uri); + expect(this.registry._config.registry.publish).to.equal(this.uri); }); it('should set default cache path config', function () { - expect(typeof this.client._config.cache === 'string').to.be.ok; + expect(typeof this.registry._config.cache === 'string').to.be.ok; }); it('should set default timeout config', function () { - expect(this.client._config.timeout).to.equal(this.timeoutVal); + expect(this.registry._config.timeout).to.equal(this.timeoutVal); }); it('should set default strictSsl config', function () { - expect(this.client._config.strictSsl).to.be.ok; + expect(this.registry._config.strictSsl).to.be.ok; }); }); From 724283433a3500d8968ff023eb801bdbe209360b Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 4 Jul 2013 15:55:10 +0100 Subject: [PATCH 0078/1021] adds lookup method tests --- packages/bower-registry-client/test/Client.js | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index a6fb5101d..ab92af317 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -90,4 +90,40 @@ describe('RegistryClient', function () { }); + describe('calling the lookup instance method with argument', function () { + + it('should not return an error', function () { + this.registry.lookup('jquery', function (err) { + expect(err).to.be.null; + }); + }); + + it('should provide a result type', function () { + this.registry.lookup('jquery', function (err, entry) { + expect(err).to.be.null; + expect(entry.type).to.equal('alias'); + }); + }); + + it('should provide a result url ', function () { + this.registry.lookup('jquery', function (err, entry) { + expect(err).to.be.null; + expect(entry.url).to.equal('git://github.com/components/jquery.git'); + }); + }); + + }); + + describe('calling the lookup instance method without argument', function () { + + it('should', function () { + this.registry.lookup('', function (err, entry) { + expect(err).to.not.be.null; + expect(entry).to.be.undefined; + }); + }); + + }); + + }); From 012f4d68bc621c17eb98dc72f5bcc5f0fae848b5 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Fri, 5 Jul 2013 10:46:48 +0100 Subject: [PATCH 0079/1021] [wip] update tests --- .../137301211087471681 | 13 +++ packages/bower-registry-client/package.json | 3 +- packages/bower-registry-client/test/Client.js | 100 +++++++++++++++++- .../bower.herokuapp.com-443/13730125556166981 | 13 +++ .../137301264716848618 | 13 +++ 5 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 packages/bower-registry-client/fixtures/bower.herokuapp.com-443/137301211087471681 create mode 100644 packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/13730125556166981 create mode 100644 packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/137301264716848618 diff --git a/packages/bower-registry-client/fixtures/bower.herokuapp.com-443/137301211087471681 b/packages/bower-registry-client/fixtures/bower.herokuapp.com-443/137301211087471681 new file mode 100644 index 000000000..687923656 --- /dev/null +++ b/packages/bower-registry-client/fixtures/bower.herokuapp.com-443/137301211087471681 @@ -0,0 +1,13 @@ +POST /packages +host: bower.herokuapp.com +content-type: application/x-www-form-urlencoded; charset=utf-8 +accept: application/json + +406 HTTP/1.1 +content-type: text/html;charset=utf-8 +server: thin 1.3.1 codename Triple Espresso +x-frame-options: sameorigin +x-xss-protection: 1; mode=block +content-length: 0 +connection: keep-alive + diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 0c10eff83..fed9610a5 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -32,7 +32,8 @@ "grunt-contrib-watch": "~0.4.4", "grunt-contrib-jshint": "~0.6.0", "grunt-simple-mocha": "~0.4.0", - "chai": "~1.7.2" + "chai": "~1.7.2", + "reply": "~0.3.0" }, "scripts": { "test": "grunt build --verbose" diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index ab92af317..f480103a0 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -1,12 +1,20 @@ var RegistryClient = require('../Client'), - expect = require('chai').expect; + expect = require('chai').expect, + replay = require('replay'); + + +replay.mode = 'replay'; +replay.fixtures = __dirname + '/fixtures/replay'; + describe('RegistryClient', function () { beforeEach(function () { this.uri = 'https://bower.herokuapp.com'; this.timeoutVal = 5000; - this.registry = new RegistryClient(); + this.registry = new RegistryClient({ + strictSsl: false + }); this.conf = { search: [this.uri], register: this.uri, @@ -54,7 +62,7 @@ describe('RegistryClient', function () { expect(this.registry._config.timeout).to.equal(this.timeoutVal); }); - it('should set default strictSsl config', function () { + xit('should set default strictSsl config', function () { expect(this.registry._config.strictSsl).to.be.ok; }); @@ -98,14 +106,14 @@ describe('RegistryClient', function () { }); }); - it('should provide a result type', function () { + it('should return entry type', function () { this.registry.lookup('jquery', function (err, entry) { expect(err).to.be.null; expect(entry.type).to.equal('alias'); }); }); - it('should provide a result url ', function () { + it('should return entry url ', function () { this.registry.lookup('jquery', function (err, entry) { expect(err).to.be.null; expect(entry.url).to.equal('git://github.com/components/jquery.git'); @@ -125,5 +133,87 @@ describe('RegistryClient', function () { }); + describe('calling the register instance method with argument', function () { + + beforeEach(function () { + this.pkg = 'jquery'; + this.pkgUrl = 'git://github.com/components/jquery.git'; + }); + + it('should not return an error', function (done) { + this.registry.register(this.pkg, this.pkgUrl, function (err) { + expect(err).to.be.null; + done(); + }); + }); + + it('should return entry name', function (done) { + var self = this; + + this.registry.register(this.pkg, this.pkgUrl, function (err, entry) { + expect(err).to.be.null; + expect(entry.name).to.equal(self.pkg); + done(); + }); + }); + + it('should return entry url', function (done) { + var self = this; + + this.registry.register(this.pkg, this.pkgUrl, function (err, entry) { + expect(err).to.be.null; + expect(entry.url).to.equal(self.pkgUrl); + done(); + }); + }); + + }); + + //describe('calling the register instance method without argument', function () {}); + + describe('calling the search instance method with argument', function () { + + beforeEach(function () { + this.pkg = 'jquery'; + this.pkgUrl = 'git://github.com/components/jquery.git'; + }); + + it('should not return an error', function (done) { + this.registry.search(this.pkg, function (err) { + expect(err).to.be.null; + done(); + }); + }); + + it('should return entry name', function (done) { + var self = this; + + this.registry.search(this.pkg, function (err, results) { + results.forEach(function (entry) { + if (entry.name === self.pkg) { + expect(entry.name).to.equal(self.pkg); + done(); + } + }); + }); + }); + + it('should return entry url', function (done) { + var self = this; + + this.registry.search(this.pkg, function (err, results) { + results.forEach(function (entry) { + if (entry.name === self.pkg) { + expect(entry.url).to.equal(self.pkgUrl); + done(); + } + }); + }); + }); + + }); + + describe('calling the search instance method without argument', function () { + }); }); diff --git a/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/13730125556166981 b/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/13730125556166981 new file mode 100644 index 000000000..851a296be --- /dev/null +++ b/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/13730125556166981 @@ -0,0 +1,13 @@ +GET /packages/search/jquery +host: bower.herokuapp.com +accept: application/json + +200 HTTP/1.1 +content-type: text/html;charset=utf-8 +server: thin 1.3.1 codename Triple Espresso +x-frame-options: sameorigin +x-xss-protection: 1; mode=block +content-length: 27548 +connection: keep-alive + +[{"name":"jquery","url":"git://github.com/components/jquery.git"},{"name":"jquery-ui","url":"git://github.com/components/jqueryui"},{"name":"jquery.cookie","url":"git://github.com/carhartl/jquery-cookie.git"},{"name":"jquery-placeholder","url":"git://github.com/mathiasbynens/jquery-placeholder.git"},{"name":"jasmine-jquery","url":"git://github.com/velesin/jasmine-jquery"},{"name":"jquery-file-upload","url":"git://github.com/blueimp/jQuery-File-Upload.git"},{"name":"jquery-waypoints","url":"git://github.com/imakewebthings/jquery-waypoints.git"},{"name":"jquery-pjax","url":"git://github.com/defunkt/jquery-pjax.git"},{"name":"jquery.scrollTo","url":"git://github.com/flesler/jquery.scrollTo.git"},{"name":"jquery.ui","url":"git://github.com/jquery/jquery-ui.git"},{"name":"jquery.validation","url":"git://github.com/jzaefferer/jquery-validation.git"},{"name":"jquery.sticky","url":"git://github.com/yatskevich/sticky.git"},{"name":"jquery-mousewheel","url":"git://github.com/brandonaaron/jquery-mousewheel.git"},{"name":"jquery.transit","url":"git://github.com/rstacruz/jquery.transit.git"},{"name":"jquery-form","url":"git://github.com/malsup/form.git"},{"name":"jquery-autosize","url":"git://github.com/jackmoore/autosize.git"},{"name":"jquery-masonry","url":"git://github.com/desandro/masonry"},{"name":"jquery-timeago","url":"git://github.com/rmm5t/jquery-timeago.git"},{"name":"jquery.tablesorter","url":"git://github.com/Mottie/tablesorter.git"},{"name":"jquery-color","url":"git://github.com/jquery/jquery-color.git"},{"name":"jquery-easing","url":"git://github.com/rajkissu/jquery-easing.git"},{"name":"jquery-migrate","url":"git://github.com/appleboy/jquery-migrate.git"},{"name":"jqueryui-touch-punch","url":"git://github.com/furf/jquery-ui-touch-punch.git"},{"name":"chai-jquery","url":"git://github.com/chaijs/chai-jquery.git"},{"name":"jquery-mobile","url":"git://github.com/jquery/jquery-mobile.git"},{"name":"jquery-minicolors","url":"git://github.com/claviska/jquery-miniColors.git"},{"name":"jquery-filedrop","url":"git://github.com/weixiyen/jquery-filedrop.git"},{"name":"jquery.cycle","url":"git://github.com/kertal/cycle"},{"name":"jquery-powertip","url":"git://github.com/stevenbenner/jquery-powertip.git"},{"name":"jquery-nicescroll","url":"git://github.com/inuyaksa/jquery.nicescroll.git"},{"name":"jquery-ui-touch-punch","url":"git://github.com/functino/jquery-ui-touch-punch.git"},{"name":"jquery.stellar","url":"git://github.com/markdalgleish/stellar.js.git"},{"name":"jquery.colorbox","url":"git://github.com/jackmoore/colorbox.git"},{"name":"jquery.watermark","url":"git://github.com/chiefy/jQuery-Watermark"},{"name":"jquery.maskedinput","url":"git://github.com/gustavohenke/jquery.maskedinput"},{"name":"jqjquery-wysibb","url":"git://github.com/wbb/WysiBB.git"},{"name":"jquery-serialize-object","url":"git://github.com/macek/jquery-serialize-object.git"},{"name":"jquery.lazyload","url":"git://github.com/tuupola/jquery_lazyload.git"},{"name":"embedly-jquery","url":"git://github.com/embedly/embedly-jquery.git"},{"name":"jquery-mockjax","url":"git://github.com/appendto/jquery-mockjax"},{"name":"jquery.uniform","url":"git://github.com/pixelmatrix/uniform.git"},{"name":"jquery-tmpl","url":"git://github.com/jquery/jquery-tmpl.git"},{"name":"jquery.form","url":"git://github.com/chiefy/form.git"},{"name":"jqueryuibootstrap","url":"git://github.com/addyosmani/jquery-ui-bootstrap.git"},{"name":"jquery.smooth-scroll","url":"git://github.com/kswedberg/jquery-smooth-scroll.git"},{"name":"jquery.tools","url":"git://github.com/jquerytools/jquerytools.git"},{"name":"jquery-ui-bootstrap","url":"git://github.com/gustavohenke/jquery-ui-bootstrap"},{"name":"jquery-mobile-angular-adapter","url":"git://github.com/tigbro/jquery-mobile-angular-adapter.git"},{"name":"jquery.tagsinput","url":"git://github.com/xoxco/jQuery-Tags-Input.git"},{"name":"jquery-grill","url":"git://github.com/peterpajchl/jquery-grill.git"},{"name":"jquery-simpleweather","url":"git://github.com/monkeecreate/jquery.simpleWeather"},{"name":"jquery.atwho","url":"git://github.com/ichord/At.js.git"},{"name":"jquery-timepicker-jt","url":"git://github.com/jonthornton/jquery-timepicker.git"},{"name":"jquery.jscrollpane","url":"git://github.com/blittle/jscrollpane.git"},{"name":"jqueryjs","url":"git://github.com/bowerjs/jquery.git"},{"name":"jquery.localScroll","url":"git://github.com/flesler/jquery.localScroll.git"},{"name":"jquery-idletimer","url":"git://github.com/mikesherov/jquery-idletimer.git"},{"name":"jquery.event.swipe","url":"git://github.com/stephband/jquery.event.swipe.git"},{"name":"jquery.event.move","url":"git://github.com/stephband/jquery.event.move.git"},{"name":"jquery.serialScroll","url":"git://github.com/flesler/jquery.serialScroll.git"},{"name":"jquery.autoellipsis","url":"git://github.com/pvdspek/jquery.autoellipsis.git"},{"name":"jquery-cycle","url":"git://github.com/malsup/cycle.git"},{"name":"jquery-knob","url":"git://github.com/aterrien/jQuery-Knob"},{"name":"jquery-bridget","url":"git://github.com/desandro/jquery-bridget.git"},{"name":"jquery-tiny-pubsub","url":"git://github.com/wixo/jquery-tiny-pubsub.git"},{"name":"jquery-galleria","url":"git://github.com/aino/galleria.git"},{"name":"jquery.slimscroll","url":"git://github.com/rochal/jQuery-slimScroll/"},{"name":"jquery-hoverIntent","url":"git://github.com/briancherne/jquery-hoverIntent.git"},{"name":"jquery-autocomplete","url":"git://github.com/trendalytics/bower-jquery-autocomplete.git"},{"name":"jquerypp","url":"git://github.com/bitovi/jquerypp.git"},{"name":"cometd-javascript-jquery","url":"git://github.com/marksherretta/cometd-javascript-jquery.git"},{"name":"geonames-server-jquery-plugin","url":"git://github.com/alchemy-fr/GeonamesServer-jQuery-Plugin.git"},{"name":"jquery.flip","url":"git://github.com/roncioso/Flip-jQuery.git"},{"name":"jquery-validation.password","url":"git://github.com/jzaefferer/jquery-validation.password.git"},{"name":"jquery-whenall","url":"git://github.com/soundcloud/jquery-whenall"},{"name":"jquery.expander","url":"git://github.com/kswedberg/jquery-expander.git"},{"name":"wookmark-jquery","url":"git://github.com/GBKS/Wookmark-jQuery.git"},{"name":"jquery-ujs","url":"git://github.com/rails/jquery-ujs.git"},{"name":"jquery-drilldown","url":"git://github.com/Cinamonas/jquery-drilldown.git"},{"name":"jquery-resize","url":"git://github.com/cowboy/jquery-resize.git"},{"name":"jquery-modal","url":"git://github.com/kylefox/jquery-modal.git"},{"name":"jquery-timepicker","url":"git://github.com/fgelinas/timepicker.git"},{"name":"jquery-requestAnimationFrame","url":"git://github.com/gnarf37/jquery-requestAnimationFrame.git"},{"name":"jquery-touchswipe","url":"git://github.com/mattbryson/TouchSwipe-Jquery-Plugin.git"},{"name":"jquery-bgiframe","url":"git://github.com/brandonaaron/bgiframe.git"},{"name":"jquery-metadata","url":"git://github.com/jquery/jquery-metadata"},{"name":"jquery-bootstrap-scripting","url":"git://github.com/Nikku/jquery-bootstrap-scripting.git"},{"name":"jquery-backstretch","url":"git://github.com/srobbin/jquery-backstretch.git"},{"name":"spinjs-jquery","url":"git://gist.github.com/1290439.git"},{"name":"jquery-ellipsis","url":"git://github.com/STAR-ZERO/jquery-ellipsis.git"},{"name":"jquery-linkify","url":"git://github.com/maranomynet/linkify.git"},{"name":"jquery-nod","url":"git://github.com/casperin/nod.git"},{"name":"jquery-validation","url":"git://github.com/niftylettuce/jquery-validation.git"},{"name":"jquery-dragndrop","url":"git://github.com/Cinamonas/jquery-dragndrop.git"},{"name":"cometd-js-jquery","url":"git://github.com/askarby/cometd-js-jquery"},{"name":"jquery.animate-enhanced","url":"git://github.com/benbarnett/jQuery-Animate-Enhanced.git"},{"name":"jquery-cycle2","url":"git://github.com/malsup/cycle2.git"},{"name":"jquery-crop","url":"git://github.com/Cinamonas/jquery-crop.git"},{"name":"jquery-multiselect","url":"git://github.com/dio-el-claire/jquery-multiselect"},{"name":"jquery.shuffle","url":"git://github.com/caphun/jquery.shuffle.git"},{"name":"jquery-rotate","url":"git://github.com/schickling/jquery-rotate"},{"name":"jquery-overscroll","url":"git://github.com/azoff/Overscroll"},{"name":"jquery.customSelect","url":"git://github.com/adamcoulombe/jquery.customSelect.git"},{"name":"jquery-throttle-debounce","url":"git://github.com/cowboy/jquery-throttle-debounce.git"},{"name":"jquery-browser-selector","url":"git://github.com/schickling/jquery-browser-selector"},{"name":"jquery.videobackground","url":"git://github.com/georgepaterson/jquery-videobackground.git"},{"name":"jquery-serializeObject","url":"git://github.com/gillesruppert/jquery-serializeObject"},{"name":"jquery-address","url":"git://github.com/asual/jquery-address.git"},{"name":"jquery.atmosphere","url":"git://github.com/blittle/atmosphere.git"},{"name":"jquery-zclip","url":"git://github.com/patricklodder/jquery-zclip.git"},{"name":"jquery-oauthpopup","url":"git://github.com/MfgLabs/jquery-oauthpopup.git"},{"name":"jquery-cardify","url":"git://github.com/mverhaagen/cardify.git"},{"name":"jquery.DataTables","url":"git://github.com/UnityTeam/DataTables.git"},{"name":"jquery-extended-selectors","url":"git://github.com/keithclark/JQuery-Extended-Selectors.git"},{"name":"jquery-dropout-menu","url":"git://github.com/psirenny/jquery-dropout-menu.git"},{"name":"jquery-colorbox","url":"git://github.com/jackmoore/colorbox"},{"name":"bootstrap-jquery-tags","url":"git://github.com/sunliwen/bootstrap-jquery-tags.git"},{"name":"zepto-as-jquery","url":"git://github.com/pleasedontbelong/zepto.git"},{"name":"jquery-simulate","url":"git://github.com/jquery/jquery-simulate.git"},{"name":"jquery-simple-slider","url":"git://github.com/loopj/jquery-simple-slider.git"},{"name":"jquery.scrollorama","url":"git://github.com/johnpolacek/scrollorama.git"},{"name":"jquery.videoBG","url":"git://github.com/sydlawrence/jquery.videoBG.git"},{"name":"buster-jquery-assertions","url":"git://github.com/blittle/buster-jquery-assertions.git"},{"name":"jquery2","url":"git://github.com/iki/jquery2.git"},{"name":"jquery-jsonp","url":"git://github.com/jaubourg/jquery-jsonp.git"},{"name":"jquery.customInput","url":"git://github.com/bmatzner/jQuery-Custom-Input.git"},{"name":"jquery.socialshareprivacy","url":"git://github.com/patrickheck/socialshareprivacy.git"},{"name":"jquery.center.js","url":"git://github.com/bebraw/jquery.center.js"},{"name":"jquery-zoom","url":"git://github.com/jackmoore/zoom.git"},{"name":"jquery-marcopolo","url":"git://github.com/jstayton/jquery-marcopolo"},{"name":"jquery.blockUI","url":"git://github.com/malsup/blockui#~2.55.0-2013.01.23"},{"name":"jquery.easy-pie-chart","url":"git://github.com/rendro/easy-pie-chart.git"},{"name":"jquery.dform","url":"git://github.com/daffl/jquery.dform.git"},{"name":"jquery-localize","url":"git://github.com/davidchambers/jQuery.localize.git"},{"name":"jakobmattsson-jquery-elastic","url":"git://github.com/jakobmattsson/jquery-elastic"},{"name":"jquery.svg","url":"git://github.com/apendleton/jquery-svg.git"},{"name":"jquery-Mustache","url":"git://github.com/jonnyreeves/jquery-Mustache.git"},{"name":"jquery-transition","url":"git://github.com/peteboere/jquery-transition.git"},{"name":"jquery-prestige","url":"git://github.com/Munter/jquery-prestige.git"},{"name":"rxjs-jquery","url":"git://github.com/Reactive-Extensions/rxjs-jquery"},{"name":"jquery.ajax.fake","url":"git://github.com/anasnakawa/jquery.ajax.fake.git"},{"name":"jquery.backgroundSize","url":"git://github.com/louisremi/jquery.backgroundSize.js.git"},{"name":"jqueryui-amd","url":"git://github.com/jrburke/jqueryui-amd.git"},{"name":"jquery.tinymce","url":"git://github.com/rsilve/jquery.tinymce.git"},{"name":"jquery-number","url":"git://github.com/teamdf/jquery-number"},{"name":"zepto-replace-jquery","url":"git://github.com/iki/zepto-replace-jquery.git"},{"name":"jquery-image-uploader","url":"git://github.com/jdeniau/jquery-image-uploader.git"},{"name":"jquery.query.js","url":"git://github.com/plasticine/jquery.query.js.git"},{"name":"jquery-popover","url":"git://github.com/klaas4/jQuery.popover.git"},{"name":"jquery-grab-bag","url":"git://github.com/panayi/jquery-grab-bag.git"},{"name":"jqueryui-selectmenu","url":"git://github.com/pixeldrew/jqueryui-selectmenu.git"},{"name":"jquery.hotkeys","url":"git://github.com/tzuryby/jquery.hotkeys.git"},{"name":"jskit-jquery","url":"git://github.com/kctang/jskit-jquery.git"},{"name":"jquery.colorpicker","url":"git://github.com/vanderlee/colorpicker"},{"name":"jquery-mobile-events","url":"git://github.com/caseywebdev/jquery-mobile-events"},{"name":"jquery-sortable","url":"git://github.com/johnny/jquery-sortable.git"},{"name":"jquery-transform","url":"git://github.com/louisremi/jquery.transform.js.git"},{"name":"jquery-maskedinputs","url":"git://github.com/digitalBush/jquery.maskedinput.git"},{"name":"jquery-imagefit-plugin","url":"git://github.com/cbulock/jquery-imagefit-plugin.git"},{"name":"jquery.spinjs","url":"git://github.com/tdoherty/jQuery.SpinJS.git"},{"name":"jquery.unslider","url":"git://github.com/idiot/unslider.git"},{"name":"jquery-caret","url":"git://github.com/DrPheltRight/jquery-caret.git"},{"name":"jquery-hashchange","url":"git://github.com/cowboy/jquery-hashchange.git"},{"name":"jquery-ui-touch-punch-amd","url":"git://github.com/GeneralElectric/jquery-ui-touch-punch.git"},{"name":"jquery-dropkick","url":"git://github.com/JamieLottering/DropKick.git"},{"name":"jquery-async","url":"git://github.com/panayi/jquery-async.git"},{"name":"jquery.columnizer","url":"git://github.com/adamwulf/Columnizer-jQuery-Plugin.git"},{"name":"stacknav.jquery.js","url":"git://github.com/EtienneDion/stacknav.jquery.js.git"},{"name":"jquery.autotab","url":"git://github.com/map7/jquery.autotab"},{"name":"jquery.placeholder","url":"git://github.com/matoilic/jquery.placeholder.git"},{"name":"jquery-dropkick2","url":"git://github.com/changalberto/DropKick"},{"name":"jquery-simple-touch","url":"git://github.com/marcol/jquery-touch.git"},{"name":"quicksandpaginated.jquery.js","url":"git://github.com/EtienneDion/quicksandpaginated.jquery.js.git"},{"name":"jquery-relativeTime","url":"git://github.com/hiromitz/jquery-relativeTime.git"},{"name":"jquery-mobile-reset","url":"git://github.com/bhurlow/jqmobile-reset.git"},{"name":"jquery-selectboxit","url":"git://github.com/gfranko/jquery.selectBoxIt.js.git"},{"name":"jquery.iconfield","url":"git://github.com/yotamofek/jquery.iconfield.git"},{"name":"jquery-dragon","url":"git://github.com/jeremyckahn/dragon.git"},{"name":"dt-jquery2","url":"git://github.com/dt-bower/dt-jquery.git"},{"name":"jquery-boilerplate","url":"git://github.com/zenorocha/jquery-boilerplate"},{"name":"jquery.TubePlayer","url":"git://github.com/nirvanatikku/jQuery-TubePlayer-Plugin.git"},{"name":"inline-svg.jquery.js","url":"git://github.com/jswinarton/inline-svg.jquery.js.git"},{"name":"jquery.ut-image-panel","url":"git://github.com/urturn/jquery.ut-image-panel.git"},{"name":"jquery-popunder","url":"git://github.com/hpbuniat/jquery-popunder.git"},{"name":"requirejs-jquery","url":"git://github.com/jrburke/require-jquery.git"},{"name":"jquery.avgrund","url":"git://github.com/voronianski/jquery.avgrund.js.git"},{"name":"jquery.mobilemenu","url":"git://github.com/mattkersley/Responsive-Menu.git"},{"name":"jquery.tube","url":"git://github.com/inukshuk/jquery.tube.js.git"},{"name":"jquery-csspick","url":"git://github.com/oscarlgz/jquery-csspick.git"},{"name":"jquery.metadata","url":"git://github.com/jquery-orphans/jquery-metadata.git"},{"name":"jquery-modality","url":"git://github.com/Cinamonas/jquery-modality.git"},{"name":"jquery-md5","url":"git://github.com/placemarker/jQuery-MD5"},{"name":"jquery.inputmask","url":"git://github.com/RobinHerbots/jquery.inputmask.git"},{"name":"jquery.mosaicflow","url":"git://github.com/sapegin/jquery.mosaicflow"},{"name":"jquery.retina","url":"git://github.com/iloveitaly/jQuery-Retina-Display-Plugin.git"},{"name":"jquery.loadmask.spin","url":"git://github.com/iloveitaly/jquery.loadmask.spin.git"},{"name":"jquery-manifest","url":"git://github.com/jstayton/jquery-manifest"},{"name":"jquery.fixedheadertable","url":"git://github.com/markmalek/Fixed-Header-Table.git"},{"name":"jquery-filterer","url":"git://github.com/joelcox/jquery-filterer.git"},{"name":"easyfacebook.jquery.js","url":"git://github.com/EtienneDion/easyfacebook.jquery.js.git"},{"name":"jquery-impromptu","url":"git://github.com/trentrichardson/jQuery-Impromptu.git"},{"name":"jquery.taboverride","url":"git://github.com/wjbryant/jquery.taboverride"},{"name":"jquery.fullscreenBackground","url":"git://github.com/Gaya/Fullscreen-Background-jQuery-plugin.git"},{"name":"jquery-ias","url":"git://github.com/webcreate/infinite-ajax-scroll"},{"name":"jquery-htmlclean","url":"git://github.com/components/jquery-htmlclean.git"},{"name":"jquery.slideShow","url":"git://github.com/appleboy/jquery.slideShow.git"},{"name":"jquery.loadfeed","url":"git://github.com/choage/jQuery.loadFeed.git"},{"name":"jquery.three","url":"git://github.com/makesites/jquery-three.git"},{"name":"jquery.extendedinput.js","url":"git://github.com/Wolfr/jquery.extendedinput.git"},{"name":"bolster.jquerypp","url":"git://github.com/bolster/jquerypp.git"},{"name":"jquery-keyfilter","url":"git://github.com/akzhan/jquery-keyfilter.git"},{"name":"jquery-dragEvents","url":"git://github.com/icholy/dragEvents.jq.js.git"},{"name":"jquery.decodeEntities","url":"git://github.com/michael-lawrence/jquery.decodeEntities.git"},{"name":"jquery-once","url":"git://github.com/RobLoach/jquery-once.git"},{"name":"jquery-ui-touch-punch-working","url":"git://github.com/yeco/jquery-ui-touch-punch.git"},{"name":"jquery.neotabs.js","url":"git://github.com/PascalPrecht/jquery.neotabs.js"},{"name":"jquery-ajax-progress","url":"git://github.com/englercj/jquery-ajax-progress.git"},{"name":"jquery-ajaxmask","url":"git://github.com/kevbook/jquery-ajaxmask.git"},{"name":"jquery-skim","url":"git://github.com/vormplus/jQuery-Skim.git"},{"name":"jquery-smooth-scrolling","url":"git://github.com/mathiasbynens/jquery-smooth-scrolling.git"},{"name":"jquery.tokko.js","url":"git://github.com/bebraw/jquery.tokko.js"},{"name":"jquery-details","url":"git://github.com/mathiasbynens/jquery-details.git"},{"name":"jquery.ut-sticker","url":"git://github.com/urturn/jquery.ut-sticker.git"},{"name":"jquery.couch","url":"git://github.com/vkurchatkin/jquery.couch"},{"name":"jquery-fitmaps","url":"git://github.com/suderman/jquery.fitmaps.git"},{"name":"jquery-store","url":"git://github.com/medialize/jQuery-store.git"},{"name":"jquery-indexeddb","url":"git://github.com/axemclion/jquery-indexeddb.git"},{"name":"jquery.contenteditable","url":"git://github.com/makesites/jquery-contenteditable.git"},{"name":"jquery-ui.daterange","url":"git://github.com/layerssss/jquery-ui.daterange.git"},{"name":"jquery.throttle","url":"git://github.com/wangshijun2010/jquery.throttle.git"},{"name":"jquery.loadHtml","url":"git://github.com/anasnakawa/jquery.loadHtml.git"},{"name":"jquery.combine","url":"git://github.com/seriema/jquery.combine.git"},{"name":"jquery.finger","url":"git://github.com/ngryman/jquery.finger"},{"name":"jquery.outbound-analytics","url":"git://github.com/gmurphey/jquery.outbound-analytics"},{"name":"jquery.toc","url":"git://github.com/ndabas/toc"},{"name":"jquery.sidebar","url":"git://github.com/sideroad/jquery.sidebar.git"},{"name":"jquery.tipFiveThree","url":"git://github.com/gocom/jquery.tipfivethree.git"},{"name":"jquery-interdependencies","url":"git://github.com/miohtama/jquery-interdependencies.git"},{"name":"jquery.textareaAutogrow","url":"git://github.com/Fleshgrinder/jquery.textareaAutogrow.git"},{"name":"iframe-auto-height-jquery-plugin","url":"git://github.com/Sly777/Iframe-Height-Jquery-Plugin"},{"name":"jquery.hurl","url":"git://github.com/makesites/jquery-hurl.git"},{"name":"jquery.pub-sub-validate","url":"git://github.com/wixo/jquery.pub-sub-validate.git"},{"name":"jquery.rdio","url":"git://github.com/rdio/jquery.rdio.js.git"},{"name":"jquery.periodical.ajax","url":"git://github.com/rscarvalho/periodicalAjax.git"},{"name":"jquery-rdfquery","url":"git://github.com/components/jquery-rdfquery.git"},{"name":"jqueryservice","url":"git://github.com/stephenway/jquery-service.git"},{"name":"jquery.foobar","url":"git://github.com/makesites/jquery-foobar.git"},{"name":"jquery-lineup","url":"git://github.com/mach3/jquery-lineup"},{"name":"jquery-ajax-goodies","url":"git://github.com/fantactuka/jquery-ajax-goodies.git"},{"name":"jquery-tinytimer","url":"git://github.com/odyniec/jQuery-tinyTimer.git"},{"name":"jquery-maskmoney","url":"git://github.com/plentz/jquery-maskmoney"},{"name":"jquery-inputevent","url":"git://github.com/dodo/jquery-inputevent.git"},{"name":"jquery.selectalize","url":"git://github.com/unfold/jquery.selectalize"},{"name":"jquery-sieve","url":"git://github.com/rmm5t/jquery-sieve.git"},{"name":"jquery-styledform","url":"git://github.com/jaitsu87/jQuery-StyledForm"},{"name":"jquery.fly","url":"git://github.com/matjaz/jquery.fly.git"},{"name":"jquery.pep","url":"git://github.com/briangonzalez/jquery.pep.js.git"},{"name":"jquery.checkalize","url":"git://github.com/unfold/jquery.checkalize"},{"name":"jquery-gholiday","url":"git://github.com/chris4403/gholiday.git"},{"name":"jqueryp","url":"git://github.com/Ensighten/jqueryp.git"},{"name":"jquery.trueresize","url":"git://github.com/jfroffice/jquery.trueresize.git"},{"name":"jquery.backbone.hijax","url":"git://github.com/michael-lawrence/jquery.backbone.hijax.git"},{"name":"jquery.imageFallback","url":"git://github.com/michael-lawrence/jquery.imageFallback.git"},{"name":"jquery.existence","url":"git://github.com/seriema/jquery.existence.git"},{"name":"jquery.reverse","url":"git://github.com/michael-lawrence/jquery.reverse.git"},{"name":"jquery-selectBox","url":"git://github.com/marcj/jquery-selectBox.git"},{"name":"jquery.ui.montjquery.ui.monthpicker","url":"git://github.com/thebrowser/jquery.ui.monthpicker.git"},{"name":"jquery.panzoom","url":"git://github.com/timmywil/jquery.panzoom.git"},{"name":"jquery-combobox","url":"git://github.com/jslayer/jquery-combobox.git"},{"name":"jquery.render","url":"git://github.com/sideroad/jquery.render.git"},{"name":"jquery-maptack","url":"git://github.com/jimmyhillis/jquery-maptack"},{"name":"strictjquery","url":"git://github.com/devinrhode2/StrictjQuery.js.git"},{"name":"jquery.expanding-textareas","url":"git://github.com/kbrs/ExpandingTextareas.git"},{"name":"jquery.floatingmessage","url":"git://github.com/sideroad/jquery.floatingmessage.git"},{"name":"jquery.slidawall","url":"git://github.com/makesites/jquery-slidawall.git"},{"name":"jquery.removeClassWithPrefix","url":"git://github.com/michael-lawrence/jquery.removeClassWithPrefix.git"},{"name":"jquery.pluginTemplate","url":"git://github.com/michael-lawrence/jquery.pluginTemplate.git"},{"name":"jquery.accordion","url":"git://github.com/matoilic/jquery.accordion.git"},{"name":"jquery-icon-insert","url":"git://github.com/stephenway/jquery-icon-insert.git"},{"name":"jquery.replaceEntities","url":"git://github.com/michael-lawrence/jquery.replaceEntities.git"},{"name":"jquery-m","url":"git://github.com/meetup/jquery.git"},{"name":"jquery.BlackAndWhite","url":"git://github.com/GianlucaGuarini/jQuery.BlackAndWhite.git"},{"name":"jquery.theCombo.js","url":"git://github.com/lagden/theCombo.git"},{"name":"jquery.payment","url":"git://github.com/stripe/jquery.payment.git"},{"name":"jquery.herotabs","url":"git://github.com/simonsmith/jquery.herotabs.git"},{"name":"jquery.shapeshift","url":"git://github.com/McPants/jquery.shapeshift.git"},{"name":"jquery-reveal","url":"git://github.com/VitalikL/reveal.git"},{"name":"jquery-sheetrock","url":"git://github.com/chriszarate/sheetrock"},{"name":"jquery.bind-first","url":"git://github.com/private-face/jquery.bind-first.git"},{"name":"eduardocasas-jquery.filestyle","url":"git://github.com/eduardocasas/jquery_filestyle.git"},{"name":"jquery-loader","url":"git://github.com/monkeymonk/jquery.loader.js.git"},{"name":"jquery-placeholder2","url":"git://github.com/jgallen23/jquery-placeholder.git"},{"name":"jquery-bbq-deparam","url":"git://github.com/nexxTM/jquery-deparam.git"},{"name":"jquery-tinyscroller","url":"git://github.com/Takazudo/jQuery.tinyscroller.git"},{"name":"jquery.autocomplete","url":"git://github.com/julien-c/jQueryAutocompletePlugin.git"},{"name":"jquery-hoverlight","url":"git://github.com/sunliwen/jquery-hoverlight.git"},{"name":"jqueryui-l2l","url":"git://github.com/krampstudio/jquerui-l2l.git"},{"name":"jquery.scrollwatch","url":"git://github.com/cobbweb/jquery.scrollwatch.git"},{"name":"jquery-noselect","url":"git://github.com/mathiasbynens/jquery-noselect.git"},{"name":"jquery-esthetic","url":"git://github.com/johannestroeger/bower-jquery-esthetic.git"},{"name":"dt-jquery","url":"git://github.com:dt-bower/dt-jquery.git"},{"name":"jquery-watcher","url":"git://github.com/jacobrelkin/jquery-watcher.git"},{"name":"jquery.formstyler","url":"git://github.com/Dimox/formStyler.git"},{"name":"jquery.editable","url":"git://github.com/shokai/jQuery.editable.git"},{"name":"jquery-leanmodal","url":"git://github.com/FinelySliced/leanModal.js.git"},{"name":"jquery.html5Loader","url":"git://github.com/GianlucaGuarini/jquery.html5loader.git"},{"name":"jquery-maskedinputs-fork","url":"git://github.com/sergiovilar/jquery.maskedinput.git"},{"name":"jquery-oninput","url":"git://github.com/mathiasbynens/jquery-oninput.git"},{"name":"jquery-textext","url":"git://github.com/alexgorbatchev/jquery-textext.git"},{"name":"bacon-jquery-bindings","url":"git://github.com/raimohanska/bacon-jquery-bindings"},{"name":"jquery.theCover.js","url":"git://github.com/lagden/theCover.git"},{"name":"geonames-jquery-plugin","url":"git://github.com:alchemy-fr/GeonamesServer-jQuery-Plugin.git"},{"name":"jquery-alakazam","url":"git://github.com/jasonhowmans/jquery-alakazam.git"},{"name":"ed.jquery.toggler","url":"git://github.com/erskinedesign/ed.jquery.toggler.js.git"},{"name":"jquery.expandBox","url":"git://bitbucket.org:harobed/jquery.expandbox.git"},{"name":"jquery-textrange","url":"git://github.com/dwieeb/jquery-textrange.git"},{"name":"jquery-power-plugin","url":"git://github.com/3den/jquery-power-plugin.git"},{"name":"jquery.classList","url":"git://github.com/mzgol/jquery.classList.git"},{"name":"jquery-seeThru","url":"git://github.com/m90/jquery-seeThru.git"},{"name":"jquery-polypage","url":"git://github.com/andykent/polypage.git"},{"name":"jquery-visibility","url":"git://github.com/mathiasbynens/jquery-visibility.git"},{"name":"jquery-class","url":"git://github.com/iamdenny/jquery-class.git"},{"name":"jquery.pwstrength","url":"git://github.com/matoilic/jquery.pwstrength.git"},{"name":"jquery-truncate","url":"git://github.com/pathable/truncate.git"},{"name":"ed.jquery.plugin.template","url":"git://github.com/erskinedesign/ed.jquery.plugin.template.js.git"},{"name":"jquery-custom-data-attributes","url":"git://github.com/mathiasbynens/jquery-custom-data-attributes.git"},{"name":"jquery-scrollfollow","url":"git://github.com/jackncoke/jquery-scrollfollow.git"},{"name":"jquery-before-after","url":"git://github.com/bencorlett/jquery-before-after.git"},{"name":"jquery-transition-guarantee","url":"git://github.com/tuxracer/jquery-transition-guarantee.git"},{"name":"jquery-loader-plugin","url":"git://github.com/mimiz/jquery-loader-plugin.git"},{"name":"jquery-ui.datarange.git","url":"git://github.com/layerssss/jquery-ui.datarange.git"}] diff --git a/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/137301264716848618 b/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/137301264716848618 new file mode 100644 index 000000000..8a8d961a8 --- /dev/null +++ b/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/137301264716848618 @@ -0,0 +1,13 @@ +POST /packages +host: bower.herokuapp.com +content-type: application/x-www-form-urlencoded; charset=utf-8 +accept: application/json + +201 HTTP/1.1 +content-type: text/html;charset=utf-8 +server: thin 1.3.1 codename Triple Espresso +x-frame-options: sameorigin +x-xss-protection: 1; mode=block +content-length: 0 +connection: keep-alive + From 34527c839542cdb751c260949d93e9369bb5db2c Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Fri, 5 Jul 2013 10:49:53 +0100 Subject: [PATCH 0080/1021] [tests] fix breaking test --- packages/bower-registry-client/test/Client.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index f480103a0..2846146ff 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -62,8 +62,8 @@ describe('RegistryClient', function () { expect(this.registry._config.timeout).to.equal(this.timeoutVal); }); - xit('should set default strictSsl config', function () { - expect(this.registry._config.strictSsl).to.be.ok; + it('should set default strictSsl config', function () { + expect(this.registry._config.strictSsl).to.be.false; }); }); From 22e969fb59bde442264a25a4edf7d00800520ca8 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Fri, 5 Jul 2013 10:52:25 +0100 Subject: [PATCH 0081/1021] fix npm module name meh.. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index fed9610a5..d4c16424f 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -33,7 +33,7 @@ "grunt-contrib-jshint": "~0.6.0", "grunt-simple-mocha": "~0.4.0", "chai": "~1.7.2", - "reply": "~0.3.0" + "replay": "~1.7.0" }, "scripts": { "test": "grunt build --verbose" From a461fa9137a25e9cf4f8d9c685012c09f622beb5 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Fri, 5 Jul 2013 10:54:39 +0100 Subject: [PATCH 0082/1021] move fixture --- .../fixtures/replay}/bower.herokuapp.com-443/137301211087471681 | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/bower-registry-client/{fixtures => test/fixtures/replay}/bower.herokuapp.com-443/137301211087471681 (100%) diff --git a/packages/bower-registry-client/fixtures/bower.herokuapp.com-443/137301211087471681 b/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/137301211087471681 similarity index 100% rename from packages/bower-registry-client/fixtures/bower.herokuapp.com-443/137301211087471681 rename to packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/137301211087471681 From d0f005a6f1b4e251934fdde88e207ee388697c81 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Fri, 5 Jul 2013 10:54:51 +0100 Subject: [PATCH 0083/1021] adjust fixtures path --- packages/bower-registry-client/test/Client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 2846146ff..8e3881607 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -4,7 +4,7 @@ var RegistryClient = require('../Client'), replay.mode = 'replay'; -replay.fixtures = __dirname + '/fixtures/replay'; +replay.fixtures = __dirname + '/test/fixtures/replay'; describe('RegistryClient', function () { From e36370b08006e322358af81273b83a0f4522372c Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Fri, 5 Jul 2013 11:51:15 +0100 Subject: [PATCH 0084/1021] removes fixtures --- .../bower.herokuapp.com-443/137301211087471681 | 13 ------------- .../bower.herokuapp.com-443/13730125556166981 | 13 ------------- .../bower.herokuapp.com-443/137301264716848618 | 13 ------------- 3 files changed, 39 deletions(-) delete mode 100644 packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/137301211087471681 delete mode 100644 packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/13730125556166981 delete mode 100644 packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/137301264716848618 diff --git a/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/137301211087471681 b/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/137301211087471681 deleted file mode 100644 index 687923656..000000000 --- a/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/137301211087471681 +++ /dev/null @@ -1,13 +0,0 @@ -POST /packages -host: bower.herokuapp.com -content-type: application/x-www-form-urlencoded; charset=utf-8 -accept: application/json - -406 HTTP/1.1 -content-type: text/html;charset=utf-8 -server: thin 1.3.1 codename Triple Espresso -x-frame-options: sameorigin -x-xss-protection: 1; mode=block -content-length: 0 -connection: keep-alive - diff --git a/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/13730125556166981 b/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/13730125556166981 deleted file mode 100644 index 851a296be..000000000 --- a/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/13730125556166981 +++ /dev/null @@ -1,13 +0,0 @@ -GET /packages/search/jquery -host: bower.herokuapp.com -accept: application/json - -200 HTTP/1.1 -content-type: text/html;charset=utf-8 -server: thin 1.3.1 codename Triple Espresso -x-frame-options: sameorigin -x-xss-protection: 1; mode=block -content-length: 27548 -connection: keep-alive - -[{"name":"jquery","url":"git://github.com/components/jquery.git"},{"name":"jquery-ui","url":"git://github.com/components/jqueryui"},{"name":"jquery.cookie","url":"git://github.com/carhartl/jquery-cookie.git"},{"name":"jquery-placeholder","url":"git://github.com/mathiasbynens/jquery-placeholder.git"},{"name":"jasmine-jquery","url":"git://github.com/velesin/jasmine-jquery"},{"name":"jquery-file-upload","url":"git://github.com/blueimp/jQuery-File-Upload.git"},{"name":"jquery-waypoints","url":"git://github.com/imakewebthings/jquery-waypoints.git"},{"name":"jquery-pjax","url":"git://github.com/defunkt/jquery-pjax.git"},{"name":"jquery.scrollTo","url":"git://github.com/flesler/jquery.scrollTo.git"},{"name":"jquery.ui","url":"git://github.com/jquery/jquery-ui.git"},{"name":"jquery.validation","url":"git://github.com/jzaefferer/jquery-validation.git"},{"name":"jquery.sticky","url":"git://github.com/yatskevich/sticky.git"},{"name":"jquery-mousewheel","url":"git://github.com/brandonaaron/jquery-mousewheel.git"},{"name":"jquery.transit","url":"git://github.com/rstacruz/jquery.transit.git"},{"name":"jquery-form","url":"git://github.com/malsup/form.git"},{"name":"jquery-autosize","url":"git://github.com/jackmoore/autosize.git"},{"name":"jquery-masonry","url":"git://github.com/desandro/masonry"},{"name":"jquery-timeago","url":"git://github.com/rmm5t/jquery-timeago.git"},{"name":"jquery.tablesorter","url":"git://github.com/Mottie/tablesorter.git"},{"name":"jquery-color","url":"git://github.com/jquery/jquery-color.git"},{"name":"jquery-easing","url":"git://github.com/rajkissu/jquery-easing.git"},{"name":"jquery-migrate","url":"git://github.com/appleboy/jquery-migrate.git"},{"name":"jqueryui-touch-punch","url":"git://github.com/furf/jquery-ui-touch-punch.git"},{"name":"chai-jquery","url":"git://github.com/chaijs/chai-jquery.git"},{"name":"jquery-mobile","url":"git://github.com/jquery/jquery-mobile.git"},{"name":"jquery-minicolors","url":"git://github.com/claviska/jquery-miniColors.git"},{"name":"jquery-filedrop","url":"git://github.com/weixiyen/jquery-filedrop.git"},{"name":"jquery.cycle","url":"git://github.com/kertal/cycle"},{"name":"jquery-powertip","url":"git://github.com/stevenbenner/jquery-powertip.git"},{"name":"jquery-nicescroll","url":"git://github.com/inuyaksa/jquery.nicescroll.git"},{"name":"jquery-ui-touch-punch","url":"git://github.com/functino/jquery-ui-touch-punch.git"},{"name":"jquery.stellar","url":"git://github.com/markdalgleish/stellar.js.git"},{"name":"jquery.colorbox","url":"git://github.com/jackmoore/colorbox.git"},{"name":"jquery.watermark","url":"git://github.com/chiefy/jQuery-Watermark"},{"name":"jquery.maskedinput","url":"git://github.com/gustavohenke/jquery.maskedinput"},{"name":"jqjquery-wysibb","url":"git://github.com/wbb/WysiBB.git"},{"name":"jquery-serialize-object","url":"git://github.com/macek/jquery-serialize-object.git"},{"name":"jquery.lazyload","url":"git://github.com/tuupola/jquery_lazyload.git"},{"name":"embedly-jquery","url":"git://github.com/embedly/embedly-jquery.git"},{"name":"jquery-mockjax","url":"git://github.com/appendto/jquery-mockjax"},{"name":"jquery.uniform","url":"git://github.com/pixelmatrix/uniform.git"},{"name":"jquery-tmpl","url":"git://github.com/jquery/jquery-tmpl.git"},{"name":"jquery.form","url":"git://github.com/chiefy/form.git"},{"name":"jqueryuibootstrap","url":"git://github.com/addyosmani/jquery-ui-bootstrap.git"},{"name":"jquery.smooth-scroll","url":"git://github.com/kswedberg/jquery-smooth-scroll.git"},{"name":"jquery.tools","url":"git://github.com/jquerytools/jquerytools.git"},{"name":"jquery-ui-bootstrap","url":"git://github.com/gustavohenke/jquery-ui-bootstrap"},{"name":"jquery-mobile-angular-adapter","url":"git://github.com/tigbro/jquery-mobile-angular-adapter.git"},{"name":"jquery.tagsinput","url":"git://github.com/xoxco/jQuery-Tags-Input.git"},{"name":"jquery-grill","url":"git://github.com/peterpajchl/jquery-grill.git"},{"name":"jquery-simpleweather","url":"git://github.com/monkeecreate/jquery.simpleWeather"},{"name":"jquery.atwho","url":"git://github.com/ichord/At.js.git"},{"name":"jquery-timepicker-jt","url":"git://github.com/jonthornton/jquery-timepicker.git"},{"name":"jquery.jscrollpane","url":"git://github.com/blittle/jscrollpane.git"},{"name":"jqueryjs","url":"git://github.com/bowerjs/jquery.git"},{"name":"jquery.localScroll","url":"git://github.com/flesler/jquery.localScroll.git"},{"name":"jquery-idletimer","url":"git://github.com/mikesherov/jquery-idletimer.git"},{"name":"jquery.event.swipe","url":"git://github.com/stephband/jquery.event.swipe.git"},{"name":"jquery.event.move","url":"git://github.com/stephband/jquery.event.move.git"},{"name":"jquery.serialScroll","url":"git://github.com/flesler/jquery.serialScroll.git"},{"name":"jquery.autoellipsis","url":"git://github.com/pvdspek/jquery.autoellipsis.git"},{"name":"jquery-cycle","url":"git://github.com/malsup/cycle.git"},{"name":"jquery-knob","url":"git://github.com/aterrien/jQuery-Knob"},{"name":"jquery-bridget","url":"git://github.com/desandro/jquery-bridget.git"},{"name":"jquery-tiny-pubsub","url":"git://github.com/wixo/jquery-tiny-pubsub.git"},{"name":"jquery-galleria","url":"git://github.com/aino/galleria.git"},{"name":"jquery.slimscroll","url":"git://github.com/rochal/jQuery-slimScroll/"},{"name":"jquery-hoverIntent","url":"git://github.com/briancherne/jquery-hoverIntent.git"},{"name":"jquery-autocomplete","url":"git://github.com/trendalytics/bower-jquery-autocomplete.git"},{"name":"jquerypp","url":"git://github.com/bitovi/jquerypp.git"},{"name":"cometd-javascript-jquery","url":"git://github.com/marksherretta/cometd-javascript-jquery.git"},{"name":"geonames-server-jquery-plugin","url":"git://github.com/alchemy-fr/GeonamesServer-jQuery-Plugin.git"},{"name":"jquery.flip","url":"git://github.com/roncioso/Flip-jQuery.git"},{"name":"jquery-validation.password","url":"git://github.com/jzaefferer/jquery-validation.password.git"},{"name":"jquery-whenall","url":"git://github.com/soundcloud/jquery-whenall"},{"name":"jquery.expander","url":"git://github.com/kswedberg/jquery-expander.git"},{"name":"wookmark-jquery","url":"git://github.com/GBKS/Wookmark-jQuery.git"},{"name":"jquery-ujs","url":"git://github.com/rails/jquery-ujs.git"},{"name":"jquery-drilldown","url":"git://github.com/Cinamonas/jquery-drilldown.git"},{"name":"jquery-resize","url":"git://github.com/cowboy/jquery-resize.git"},{"name":"jquery-modal","url":"git://github.com/kylefox/jquery-modal.git"},{"name":"jquery-timepicker","url":"git://github.com/fgelinas/timepicker.git"},{"name":"jquery-requestAnimationFrame","url":"git://github.com/gnarf37/jquery-requestAnimationFrame.git"},{"name":"jquery-touchswipe","url":"git://github.com/mattbryson/TouchSwipe-Jquery-Plugin.git"},{"name":"jquery-bgiframe","url":"git://github.com/brandonaaron/bgiframe.git"},{"name":"jquery-metadata","url":"git://github.com/jquery/jquery-metadata"},{"name":"jquery-bootstrap-scripting","url":"git://github.com/Nikku/jquery-bootstrap-scripting.git"},{"name":"jquery-backstretch","url":"git://github.com/srobbin/jquery-backstretch.git"},{"name":"spinjs-jquery","url":"git://gist.github.com/1290439.git"},{"name":"jquery-ellipsis","url":"git://github.com/STAR-ZERO/jquery-ellipsis.git"},{"name":"jquery-linkify","url":"git://github.com/maranomynet/linkify.git"},{"name":"jquery-nod","url":"git://github.com/casperin/nod.git"},{"name":"jquery-validation","url":"git://github.com/niftylettuce/jquery-validation.git"},{"name":"jquery-dragndrop","url":"git://github.com/Cinamonas/jquery-dragndrop.git"},{"name":"cometd-js-jquery","url":"git://github.com/askarby/cometd-js-jquery"},{"name":"jquery.animate-enhanced","url":"git://github.com/benbarnett/jQuery-Animate-Enhanced.git"},{"name":"jquery-cycle2","url":"git://github.com/malsup/cycle2.git"},{"name":"jquery-crop","url":"git://github.com/Cinamonas/jquery-crop.git"},{"name":"jquery-multiselect","url":"git://github.com/dio-el-claire/jquery-multiselect"},{"name":"jquery.shuffle","url":"git://github.com/caphun/jquery.shuffle.git"},{"name":"jquery-rotate","url":"git://github.com/schickling/jquery-rotate"},{"name":"jquery-overscroll","url":"git://github.com/azoff/Overscroll"},{"name":"jquery.customSelect","url":"git://github.com/adamcoulombe/jquery.customSelect.git"},{"name":"jquery-throttle-debounce","url":"git://github.com/cowboy/jquery-throttle-debounce.git"},{"name":"jquery-browser-selector","url":"git://github.com/schickling/jquery-browser-selector"},{"name":"jquery.videobackground","url":"git://github.com/georgepaterson/jquery-videobackground.git"},{"name":"jquery-serializeObject","url":"git://github.com/gillesruppert/jquery-serializeObject"},{"name":"jquery-address","url":"git://github.com/asual/jquery-address.git"},{"name":"jquery.atmosphere","url":"git://github.com/blittle/atmosphere.git"},{"name":"jquery-zclip","url":"git://github.com/patricklodder/jquery-zclip.git"},{"name":"jquery-oauthpopup","url":"git://github.com/MfgLabs/jquery-oauthpopup.git"},{"name":"jquery-cardify","url":"git://github.com/mverhaagen/cardify.git"},{"name":"jquery.DataTables","url":"git://github.com/UnityTeam/DataTables.git"},{"name":"jquery-extended-selectors","url":"git://github.com/keithclark/JQuery-Extended-Selectors.git"},{"name":"jquery-dropout-menu","url":"git://github.com/psirenny/jquery-dropout-menu.git"},{"name":"jquery-colorbox","url":"git://github.com/jackmoore/colorbox"},{"name":"bootstrap-jquery-tags","url":"git://github.com/sunliwen/bootstrap-jquery-tags.git"},{"name":"zepto-as-jquery","url":"git://github.com/pleasedontbelong/zepto.git"},{"name":"jquery-simulate","url":"git://github.com/jquery/jquery-simulate.git"},{"name":"jquery-simple-slider","url":"git://github.com/loopj/jquery-simple-slider.git"},{"name":"jquery.scrollorama","url":"git://github.com/johnpolacek/scrollorama.git"},{"name":"jquery.videoBG","url":"git://github.com/sydlawrence/jquery.videoBG.git"},{"name":"buster-jquery-assertions","url":"git://github.com/blittle/buster-jquery-assertions.git"},{"name":"jquery2","url":"git://github.com/iki/jquery2.git"},{"name":"jquery-jsonp","url":"git://github.com/jaubourg/jquery-jsonp.git"},{"name":"jquery.customInput","url":"git://github.com/bmatzner/jQuery-Custom-Input.git"},{"name":"jquery.socialshareprivacy","url":"git://github.com/patrickheck/socialshareprivacy.git"},{"name":"jquery.center.js","url":"git://github.com/bebraw/jquery.center.js"},{"name":"jquery-zoom","url":"git://github.com/jackmoore/zoom.git"},{"name":"jquery-marcopolo","url":"git://github.com/jstayton/jquery-marcopolo"},{"name":"jquery.blockUI","url":"git://github.com/malsup/blockui#~2.55.0-2013.01.23"},{"name":"jquery.easy-pie-chart","url":"git://github.com/rendro/easy-pie-chart.git"},{"name":"jquery.dform","url":"git://github.com/daffl/jquery.dform.git"},{"name":"jquery-localize","url":"git://github.com/davidchambers/jQuery.localize.git"},{"name":"jakobmattsson-jquery-elastic","url":"git://github.com/jakobmattsson/jquery-elastic"},{"name":"jquery.svg","url":"git://github.com/apendleton/jquery-svg.git"},{"name":"jquery-Mustache","url":"git://github.com/jonnyreeves/jquery-Mustache.git"},{"name":"jquery-transition","url":"git://github.com/peteboere/jquery-transition.git"},{"name":"jquery-prestige","url":"git://github.com/Munter/jquery-prestige.git"},{"name":"rxjs-jquery","url":"git://github.com/Reactive-Extensions/rxjs-jquery"},{"name":"jquery.ajax.fake","url":"git://github.com/anasnakawa/jquery.ajax.fake.git"},{"name":"jquery.backgroundSize","url":"git://github.com/louisremi/jquery.backgroundSize.js.git"},{"name":"jqueryui-amd","url":"git://github.com/jrburke/jqueryui-amd.git"},{"name":"jquery.tinymce","url":"git://github.com/rsilve/jquery.tinymce.git"},{"name":"jquery-number","url":"git://github.com/teamdf/jquery-number"},{"name":"zepto-replace-jquery","url":"git://github.com/iki/zepto-replace-jquery.git"},{"name":"jquery-image-uploader","url":"git://github.com/jdeniau/jquery-image-uploader.git"},{"name":"jquery.query.js","url":"git://github.com/plasticine/jquery.query.js.git"},{"name":"jquery-popover","url":"git://github.com/klaas4/jQuery.popover.git"},{"name":"jquery-grab-bag","url":"git://github.com/panayi/jquery-grab-bag.git"},{"name":"jqueryui-selectmenu","url":"git://github.com/pixeldrew/jqueryui-selectmenu.git"},{"name":"jquery.hotkeys","url":"git://github.com/tzuryby/jquery.hotkeys.git"},{"name":"jskit-jquery","url":"git://github.com/kctang/jskit-jquery.git"},{"name":"jquery.colorpicker","url":"git://github.com/vanderlee/colorpicker"},{"name":"jquery-mobile-events","url":"git://github.com/caseywebdev/jquery-mobile-events"},{"name":"jquery-sortable","url":"git://github.com/johnny/jquery-sortable.git"},{"name":"jquery-transform","url":"git://github.com/louisremi/jquery.transform.js.git"},{"name":"jquery-maskedinputs","url":"git://github.com/digitalBush/jquery.maskedinput.git"},{"name":"jquery-imagefit-plugin","url":"git://github.com/cbulock/jquery-imagefit-plugin.git"},{"name":"jquery.spinjs","url":"git://github.com/tdoherty/jQuery.SpinJS.git"},{"name":"jquery.unslider","url":"git://github.com/idiot/unslider.git"},{"name":"jquery-caret","url":"git://github.com/DrPheltRight/jquery-caret.git"},{"name":"jquery-hashchange","url":"git://github.com/cowboy/jquery-hashchange.git"},{"name":"jquery-ui-touch-punch-amd","url":"git://github.com/GeneralElectric/jquery-ui-touch-punch.git"},{"name":"jquery-dropkick","url":"git://github.com/JamieLottering/DropKick.git"},{"name":"jquery-async","url":"git://github.com/panayi/jquery-async.git"},{"name":"jquery.columnizer","url":"git://github.com/adamwulf/Columnizer-jQuery-Plugin.git"},{"name":"stacknav.jquery.js","url":"git://github.com/EtienneDion/stacknav.jquery.js.git"},{"name":"jquery.autotab","url":"git://github.com/map7/jquery.autotab"},{"name":"jquery.placeholder","url":"git://github.com/matoilic/jquery.placeholder.git"},{"name":"jquery-dropkick2","url":"git://github.com/changalberto/DropKick"},{"name":"jquery-simple-touch","url":"git://github.com/marcol/jquery-touch.git"},{"name":"quicksandpaginated.jquery.js","url":"git://github.com/EtienneDion/quicksandpaginated.jquery.js.git"},{"name":"jquery-relativeTime","url":"git://github.com/hiromitz/jquery-relativeTime.git"},{"name":"jquery-mobile-reset","url":"git://github.com/bhurlow/jqmobile-reset.git"},{"name":"jquery-selectboxit","url":"git://github.com/gfranko/jquery.selectBoxIt.js.git"},{"name":"jquery.iconfield","url":"git://github.com/yotamofek/jquery.iconfield.git"},{"name":"jquery-dragon","url":"git://github.com/jeremyckahn/dragon.git"},{"name":"dt-jquery2","url":"git://github.com/dt-bower/dt-jquery.git"},{"name":"jquery-boilerplate","url":"git://github.com/zenorocha/jquery-boilerplate"},{"name":"jquery.TubePlayer","url":"git://github.com/nirvanatikku/jQuery-TubePlayer-Plugin.git"},{"name":"inline-svg.jquery.js","url":"git://github.com/jswinarton/inline-svg.jquery.js.git"},{"name":"jquery.ut-image-panel","url":"git://github.com/urturn/jquery.ut-image-panel.git"},{"name":"jquery-popunder","url":"git://github.com/hpbuniat/jquery-popunder.git"},{"name":"requirejs-jquery","url":"git://github.com/jrburke/require-jquery.git"},{"name":"jquery.avgrund","url":"git://github.com/voronianski/jquery.avgrund.js.git"},{"name":"jquery.mobilemenu","url":"git://github.com/mattkersley/Responsive-Menu.git"},{"name":"jquery.tube","url":"git://github.com/inukshuk/jquery.tube.js.git"},{"name":"jquery-csspick","url":"git://github.com/oscarlgz/jquery-csspick.git"},{"name":"jquery.metadata","url":"git://github.com/jquery-orphans/jquery-metadata.git"},{"name":"jquery-modality","url":"git://github.com/Cinamonas/jquery-modality.git"},{"name":"jquery-md5","url":"git://github.com/placemarker/jQuery-MD5"},{"name":"jquery.inputmask","url":"git://github.com/RobinHerbots/jquery.inputmask.git"},{"name":"jquery.mosaicflow","url":"git://github.com/sapegin/jquery.mosaicflow"},{"name":"jquery.retina","url":"git://github.com/iloveitaly/jQuery-Retina-Display-Plugin.git"},{"name":"jquery.loadmask.spin","url":"git://github.com/iloveitaly/jquery.loadmask.spin.git"},{"name":"jquery-manifest","url":"git://github.com/jstayton/jquery-manifest"},{"name":"jquery.fixedheadertable","url":"git://github.com/markmalek/Fixed-Header-Table.git"},{"name":"jquery-filterer","url":"git://github.com/joelcox/jquery-filterer.git"},{"name":"easyfacebook.jquery.js","url":"git://github.com/EtienneDion/easyfacebook.jquery.js.git"},{"name":"jquery-impromptu","url":"git://github.com/trentrichardson/jQuery-Impromptu.git"},{"name":"jquery.taboverride","url":"git://github.com/wjbryant/jquery.taboverride"},{"name":"jquery.fullscreenBackground","url":"git://github.com/Gaya/Fullscreen-Background-jQuery-plugin.git"},{"name":"jquery-ias","url":"git://github.com/webcreate/infinite-ajax-scroll"},{"name":"jquery-htmlclean","url":"git://github.com/components/jquery-htmlclean.git"},{"name":"jquery.slideShow","url":"git://github.com/appleboy/jquery.slideShow.git"},{"name":"jquery.loadfeed","url":"git://github.com/choage/jQuery.loadFeed.git"},{"name":"jquery.three","url":"git://github.com/makesites/jquery-three.git"},{"name":"jquery.extendedinput.js","url":"git://github.com/Wolfr/jquery.extendedinput.git"},{"name":"bolster.jquerypp","url":"git://github.com/bolster/jquerypp.git"},{"name":"jquery-keyfilter","url":"git://github.com/akzhan/jquery-keyfilter.git"},{"name":"jquery-dragEvents","url":"git://github.com/icholy/dragEvents.jq.js.git"},{"name":"jquery.decodeEntities","url":"git://github.com/michael-lawrence/jquery.decodeEntities.git"},{"name":"jquery-once","url":"git://github.com/RobLoach/jquery-once.git"},{"name":"jquery-ui-touch-punch-working","url":"git://github.com/yeco/jquery-ui-touch-punch.git"},{"name":"jquery.neotabs.js","url":"git://github.com/PascalPrecht/jquery.neotabs.js"},{"name":"jquery-ajax-progress","url":"git://github.com/englercj/jquery-ajax-progress.git"},{"name":"jquery-ajaxmask","url":"git://github.com/kevbook/jquery-ajaxmask.git"},{"name":"jquery-skim","url":"git://github.com/vormplus/jQuery-Skim.git"},{"name":"jquery-smooth-scrolling","url":"git://github.com/mathiasbynens/jquery-smooth-scrolling.git"},{"name":"jquery.tokko.js","url":"git://github.com/bebraw/jquery.tokko.js"},{"name":"jquery-details","url":"git://github.com/mathiasbynens/jquery-details.git"},{"name":"jquery.ut-sticker","url":"git://github.com/urturn/jquery.ut-sticker.git"},{"name":"jquery.couch","url":"git://github.com/vkurchatkin/jquery.couch"},{"name":"jquery-fitmaps","url":"git://github.com/suderman/jquery.fitmaps.git"},{"name":"jquery-store","url":"git://github.com/medialize/jQuery-store.git"},{"name":"jquery-indexeddb","url":"git://github.com/axemclion/jquery-indexeddb.git"},{"name":"jquery.contenteditable","url":"git://github.com/makesites/jquery-contenteditable.git"},{"name":"jquery-ui.daterange","url":"git://github.com/layerssss/jquery-ui.daterange.git"},{"name":"jquery.throttle","url":"git://github.com/wangshijun2010/jquery.throttle.git"},{"name":"jquery.loadHtml","url":"git://github.com/anasnakawa/jquery.loadHtml.git"},{"name":"jquery.combine","url":"git://github.com/seriema/jquery.combine.git"},{"name":"jquery.finger","url":"git://github.com/ngryman/jquery.finger"},{"name":"jquery.outbound-analytics","url":"git://github.com/gmurphey/jquery.outbound-analytics"},{"name":"jquery.toc","url":"git://github.com/ndabas/toc"},{"name":"jquery.sidebar","url":"git://github.com/sideroad/jquery.sidebar.git"},{"name":"jquery.tipFiveThree","url":"git://github.com/gocom/jquery.tipfivethree.git"},{"name":"jquery-interdependencies","url":"git://github.com/miohtama/jquery-interdependencies.git"},{"name":"jquery.textareaAutogrow","url":"git://github.com/Fleshgrinder/jquery.textareaAutogrow.git"},{"name":"iframe-auto-height-jquery-plugin","url":"git://github.com/Sly777/Iframe-Height-Jquery-Plugin"},{"name":"jquery.hurl","url":"git://github.com/makesites/jquery-hurl.git"},{"name":"jquery.pub-sub-validate","url":"git://github.com/wixo/jquery.pub-sub-validate.git"},{"name":"jquery.rdio","url":"git://github.com/rdio/jquery.rdio.js.git"},{"name":"jquery.periodical.ajax","url":"git://github.com/rscarvalho/periodicalAjax.git"},{"name":"jquery-rdfquery","url":"git://github.com/components/jquery-rdfquery.git"},{"name":"jqueryservice","url":"git://github.com/stephenway/jquery-service.git"},{"name":"jquery.foobar","url":"git://github.com/makesites/jquery-foobar.git"},{"name":"jquery-lineup","url":"git://github.com/mach3/jquery-lineup"},{"name":"jquery-ajax-goodies","url":"git://github.com/fantactuka/jquery-ajax-goodies.git"},{"name":"jquery-tinytimer","url":"git://github.com/odyniec/jQuery-tinyTimer.git"},{"name":"jquery-maskmoney","url":"git://github.com/plentz/jquery-maskmoney"},{"name":"jquery-inputevent","url":"git://github.com/dodo/jquery-inputevent.git"},{"name":"jquery.selectalize","url":"git://github.com/unfold/jquery.selectalize"},{"name":"jquery-sieve","url":"git://github.com/rmm5t/jquery-sieve.git"},{"name":"jquery-styledform","url":"git://github.com/jaitsu87/jQuery-StyledForm"},{"name":"jquery.fly","url":"git://github.com/matjaz/jquery.fly.git"},{"name":"jquery.pep","url":"git://github.com/briangonzalez/jquery.pep.js.git"},{"name":"jquery.checkalize","url":"git://github.com/unfold/jquery.checkalize"},{"name":"jquery-gholiday","url":"git://github.com/chris4403/gholiday.git"},{"name":"jqueryp","url":"git://github.com/Ensighten/jqueryp.git"},{"name":"jquery.trueresize","url":"git://github.com/jfroffice/jquery.trueresize.git"},{"name":"jquery.backbone.hijax","url":"git://github.com/michael-lawrence/jquery.backbone.hijax.git"},{"name":"jquery.imageFallback","url":"git://github.com/michael-lawrence/jquery.imageFallback.git"},{"name":"jquery.existence","url":"git://github.com/seriema/jquery.existence.git"},{"name":"jquery.reverse","url":"git://github.com/michael-lawrence/jquery.reverse.git"},{"name":"jquery-selectBox","url":"git://github.com/marcj/jquery-selectBox.git"},{"name":"jquery.ui.montjquery.ui.monthpicker","url":"git://github.com/thebrowser/jquery.ui.monthpicker.git"},{"name":"jquery.panzoom","url":"git://github.com/timmywil/jquery.panzoom.git"},{"name":"jquery-combobox","url":"git://github.com/jslayer/jquery-combobox.git"},{"name":"jquery.render","url":"git://github.com/sideroad/jquery.render.git"},{"name":"jquery-maptack","url":"git://github.com/jimmyhillis/jquery-maptack"},{"name":"strictjquery","url":"git://github.com/devinrhode2/StrictjQuery.js.git"},{"name":"jquery.expanding-textareas","url":"git://github.com/kbrs/ExpandingTextareas.git"},{"name":"jquery.floatingmessage","url":"git://github.com/sideroad/jquery.floatingmessage.git"},{"name":"jquery.slidawall","url":"git://github.com/makesites/jquery-slidawall.git"},{"name":"jquery.removeClassWithPrefix","url":"git://github.com/michael-lawrence/jquery.removeClassWithPrefix.git"},{"name":"jquery.pluginTemplate","url":"git://github.com/michael-lawrence/jquery.pluginTemplate.git"},{"name":"jquery.accordion","url":"git://github.com/matoilic/jquery.accordion.git"},{"name":"jquery-icon-insert","url":"git://github.com/stephenway/jquery-icon-insert.git"},{"name":"jquery.replaceEntities","url":"git://github.com/michael-lawrence/jquery.replaceEntities.git"},{"name":"jquery-m","url":"git://github.com/meetup/jquery.git"},{"name":"jquery.BlackAndWhite","url":"git://github.com/GianlucaGuarini/jQuery.BlackAndWhite.git"},{"name":"jquery.theCombo.js","url":"git://github.com/lagden/theCombo.git"},{"name":"jquery.payment","url":"git://github.com/stripe/jquery.payment.git"},{"name":"jquery.herotabs","url":"git://github.com/simonsmith/jquery.herotabs.git"},{"name":"jquery.shapeshift","url":"git://github.com/McPants/jquery.shapeshift.git"},{"name":"jquery-reveal","url":"git://github.com/VitalikL/reveal.git"},{"name":"jquery-sheetrock","url":"git://github.com/chriszarate/sheetrock"},{"name":"jquery.bind-first","url":"git://github.com/private-face/jquery.bind-first.git"},{"name":"eduardocasas-jquery.filestyle","url":"git://github.com/eduardocasas/jquery_filestyle.git"},{"name":"jquery-loader","url":"git://github.com/monkeymonk/jquery.loader.js.git"},{"name":"jquery-placeholder2","url":"git://github.com/jgallen23/jquery-placeholder.git"},{"name":"jquery-bbq-deparam","url":"git://github.com/nexxTM/jquery-deparam.git"},{"name":"jquery-tinyscroller","url":"git://github.com/Takazudo/jQuery.tinyscroller.git"},{"name":"jquery.autocomplete","url":"git://github.com/julien-c/jQueryAutocompletePlugin.git"},{"name":"jquery-hoverlight","url":"git://github.com/sunliwen/jquery-hoverlight.git"},{"name":"jqueryui-l2l","url":"git://github.com/krampstudio/jquerui-l2l.git"},{"name":"jquery.scrollwatch","url":"git://github.com/cobbweb/jquery.scrollwatch.git"},{"name":"jquery-noselect","url":"git://github.com/mathiasbynens/jquery-noselect.git"},{"name":"jquery-esthetic","url":"git://github.com/johannestroeger/bower-jquery-esthetic.git"},{"name":"dt-jquery","url":"git://github.com:dt-bower/dt-jquery.git"},{"name":"jquery-watcher","url":"git://github.com/jacobrelkin/jquery-watcher.git"},{"name":"jquery.formstyler","url":"git://github.com/Dimox/formStyler.git"},{"name":"jquery.editable","url":"git://github.com/shokai/jQuery.editable.git"},{"name":"jquery-leanmodal","url":"git://github.com/FinelySliced/leanModal.js.git"},{"name":"jquery.html5Loader","url":"git://github.com/GianlucaGuarini/jquery.html5loader.git"},{"name":"jquery-maskedinputs-fork","url":"git://github.com/sergiovilar/jquery.maskedinput.git"},{"name":"jquery-oninput","url":"git://github.com/mathiasbynens/jquery-oninput.git"},{"name":"jquery-textext","url":"git://github.com/alexgorbatchev/jquery-textext.git"},{"name":"bacon-jquery-bindings","url":"git://github.com/raimohanska/bacon-jquery-bindings"},{"name":"jquery.theCover.js","url":"git://github.com/lagden/theCover.git"},{"name":"geonames-jquery-plugin","url":"git://github.com:alchemy-fr/GeonamesServer-jQuery-Plugin.git"},{"name":"jquery-alakazam","url":"git://github.com/jasonhowmans/jquery-alakazam.git"},{"name":"ed.jquery.toggler","url":"git://github.com/erskinedesign/ed.jquery.toggler.js.git"},{"name":"jquery.expandBox","url":"git://bitbucket.org:harobed/jquery.expandbox.git"},{"name":"jquery-textrange","url":"git://github.com/dwieeb/jquery-textrange.git"},{"name":"jquery-power-plugin","url":"git://github.com/3den/jquery-power-plugin.git"},{"name":"jquery.classList","url":"git://github.com/mzgol/jquery.classList.git"},{"name":"jquery-seeThru","url":"git://github.com/m90/jquery-seeThru.git"},{"name":"jquery-polypage","url":"git://github.com/andykent/polypage.git"},{"name":"jquery-visibility","url":"git://github.com/mathiasbynens/jquery-visibility.git"},{"name":"jquery-class","url":"git://github.com/iamdenny/jquery-class.git"},{"name":"jquery.pwstrength","url":"git://github.com/matoilic/jquery.pwstrength.git"},{"name":"jquery-truncate","url":"git://github.com/pathable/truncate.git"},{"name":"ed.jquery.plugin.template","url":"git://github.com/erskinedesign/ed.jquery.plugin.template.js.git"},{"name":"jquery-custom-data-attributes","url":"git://github.com/mathiasbynens/jquery-custom-data-attributes.git"},{"name":"jquery-scrollfollow","url":"git://github.com/jackncoke/jquery-scrollfollow.git"},{"name":"jquery-before-after","url":"git://github.com/bencorlett/jquery-before-after.git"},{"name":"jquery-transition-guarantee","url":"git://github.com/tuxracer/jquery-transition-guarantee.git"},{"name":"jquery-loader-plugin","url":"git://github.com/mimiz/jquery-loader-plugin.git"},{"name":"jquery-ui.datarange.git","url":"git://github.com/layerssss/jquery-ui.datarange.git"}] diff --git a/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/137301264716848618 b/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/137301264716848618 deleted file mode 100644 index 8a8d961a8..000000000 --- a/packages/bower-registry-client/test/fixtures/replay/bower.herokuapp.com-443/137301264716848618 +++ /dev/null @@ -1,13 +0,0 @@ -POST /packages -host: bower.herokuapp.com -content-type: application/x-www-form-urlencoded; charset=utf-8 -accept: application/json - -201 HTTP/1.1 -content-type: text/html;charset=utf-8 -server: thin 1.3.1 codename Triple Espresso -x-frame-options: sameorigin -x-xss-protection: 1; mode=block -content-length: 0 -connection: keep-alive - From c308d2c9ddfbe46b7cb35fbb9e0cc5333596750b Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Fri, 5 Jul 2013 11:51:28 +0100 Subject: [PATCH 0085/1021] adds nock fixture --- packages/bower-registry-client/test/Client.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 8e3881607..85da5d40c 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -1,10 +1,6 @@ var RegistryClient = require('../Client'), expect = require('chai').expect, - replay = require('replay'); - - -replay.mode = 'replay'; -replay.fixtures = __dirname + '/test/fixtures/replay'; + nock = require('nock'); describe('RegistryClient', function () { @@ -136,8 +132,17 @@ describe('RegistryClient', function () { describe('calling the register instance method with argument', function () { beforeEach(function () { - this.pkg = 'jquery'; - this.pkgUrl = 'git://github.com/components/jquery.git'; + nock('https://bower.herokuapp.com:443') + .post('/packages', 'name=test-ba&url=git%3A%2F%2Fgithub.com%2Ftest-ba%2Ftest-ba.git') + .reply(201, '', { 'content-type': 'text/html;charset=utf-8', + server: 'thin 1.3.1 codename Triple Espresso', + 'x-frame-options': 'sameorigin', + 'x-xss-protection': '1; mode=block', + 'content-length': '0', + connection: 'keep-alive' }); + + this.pkg = 'test-ba'; + this.pkgUrl = 'git://github.com/test-ba/test-ba.git'; }); it('should not return an error', function (done) { From 67b94cf52eee1f924a410e199257e0d77e7ec7f2 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Fri, 5 Jul 2013 11:53:08 +0100 Subject: [PATCH 0086/1021] sets nock as npm dependency --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index d4c16424f..9e7126604 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -33,7 +33,7 @@ "grunt-contrib-jshint": "~0.6.0", "grunt-simple-mocha": "~0.4.0", "chai": "~1.7.2", - "replay": "~1.7.0" + "nock": "~0.18.2" }, "scripts": { "test": "grunt build --verbose" From b2904bc6fba1754f86d674bdcbb6ab4d9e32f991 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Fri, 5 Jul 2013 12:36:36 +0100 Subject: [PATCH 0087/1021] [tests] mock search endpoint --- packages/bower-registry-client/test/Client.js | 22 +++++++++++++++++-- .../test/fixtures/search.json | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 packages/bower-registry-client/test/fixtures/search.json diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 85da5d40c..880473c2c 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -120,7 +120,7 @@ describe('RegistryClient', function () { describe('calling the lookup instance method without argument', function () { - it('should', function () { + it('should return an error and no result', function () { this.registry.lookup('', function (err, entry) { expect(err).to.not.be.null; expect(entry).to.be.undefined; @@ -174,11 +174,23 @@ describe('RegistryClient', function () { }); - //describe('calling the register instance method without argument', function () {}); + describe('calling the register instance method without arguments', function () { + it('should return an error and no result', function () { + this.registry.register('', '', function (err, entry) { + expect(err).to.not.be.null; + expect(entry).to.be.undefined; + }); + }); + }); describe('calling the search instance method with argument', function () { beforeEach(function () { + + nock('https://bower.herokuapp.com:443') + .get('/packages/search/jquery') + .replyWithFile(200, __dirname + '/fixtures/search.json'); + this.pkg = 'jquery'; this.pkgUrl = 'git://github.com/components/jquery.git'; }); @@ -219,6 +231,12 @@ describe('RegistryClient', function () { }); describe('calling the search instance method without argument', function () { + it('should return an error and no results', function () { + this.registry.register('', function (err, results) { + expect(err).to.not.be.null; + expect(results).to.be.undefined; + }); + }); }); }); diff --git a/packages/bower-registry-client/test/fixtures/search.json b/packages/bower-registry-client/test/fixtures/search.json new file mode 100644 index 000000000..2cbebc916 --- /dev/null +++ b/packages/bower-registry-client/test/fixtures/search.json @@ -0,0 +1 @@ +[{"name":"jquery","url":"git://github.com/components/jquery.git"},{"name":"jquery-ui","url":"git://github.com/components/jqueryui"},{"name":"jquery.cookie","url":"git://github.com/carhartl/jquery-cookie.git"},{"name":"jquery-placeholder","url":"git://github.com/mathiasbynens/jquery-placeholder.git"},{"name":"jasmine-jquery","url":"git://github.com/velesin/jasmine-jquery"},{"name":"jquery-file-upload","url":"git://github.com/blueimp/jQuery-File-Upload.git"},{"name":"jquery-waypoints","url":"git://github.com/imakewebthings/jquery-waypoints.git"},{"name":"jquery-pjax","url":"git://github.com/defunkt/jquery-pjax.git"},{"name":"jquery.scrollTo","url":"git://github.com/flesler/jquery.scrollTo.git"},{"name":"jquery.ui","url":"git://github.com/jquery/jquery-ui.git"},{"name":"jquery.validation","url":"git://github.com/jzaefferer/jquery-validation.git"},{"name":"jquery.sticky","url":"git://github.com/yatskevich/sticky.git"},{"name":"jquery-mousewheel","url":"git://github.com/brandonaaron/jquery-mousewheel.git"},{"name":"jquery.transit","url":"git://github.com/rstacruz/jquery.transit.git"},{"name":"jquery-form","url":"git://github.com/malsup/form.git"},{"name":"jquery-autosize","url":"git://github.com/jackmoore/autosize.git"},{"name":"jquery-masonry","url":"git://github.com/desandro/masonry"},{"name":"jquery-timeago","url":"git://github.com/rmm5t/jquery-timeago.git"},{"name":"jquery.tablesorter","url":"git://github.com/Mottie/tablesorter.git"},{"name":"jquery-color","url":"git://github.com/jquery/jquery-color.git"},{"name":"jquery-easing","url":"git://github.com/rajkissu/jquery-easing.git"},{"name":"jquery-migrate","url":"git://github.com/appleboy/jquery-migrate.git"},{"name":"jqueryui-touch-punch","url":"git://github.com/furf/jquery-ui-touch-punch.git"},{"name":"chai-jquery","url":"git://github.com/chaijs/chai-jquery.git"},{"name":"jquery-mobile","url":"git://github.com/jquery/jquery-mobile.git"},{"name":"jquery-minicolors","url":"git://github.com/claviska/jquery-miniColors.git"},{"name":"jquery.cycle","url":"git://github.com/kertal/cycle"},{"name":"jquery-filedrop","url":"git://github.com/weixiyen/jquery-filedrop.git"},{"name":"jquery-powertip","url":"git://github.com/stevenbenner/jquery-powertip.git"},{"name":"jquery-nicescroll","url":"git://github.com/inuyaksa/jquery.nicescroll.git"},{"name":"jquery-ui-touch-punch","url":"git://github.com/functino/jquery-ui-touch-punch.git"},{"name":"jquery.stellar","url":"git://github.com/markdalgleish/stellar.js.git"},{"name":"jquery.colorbox","url":"git://github.com/jackmoore/colorbox.git"},{"name":"jquery.watermark","url":"git://github.com/chiefy/jQuery-Watermark"},{"name":"jquery.maskedinput","url":"git://github.com/gustavohenke/jquery.maskedinput"},{"name":"jqjquery-wysibb","url":"git://github.com/wbb/WysiBB.git"},{"name":"jquery-serialize-object","url":"git://github.com/macek/jquery-serialize-object.git"},{"name":"jquery.lazyload","url":"git://github.com/tuupola/jquery_lazyload.git"},{"name":"embedly-jquery","url":"git://github.com/embedly/embedly-jquery.git"},{"name":"jquery-mockjax","url":"git://github.com/appendto/jquery-mockjax"},{"name":"jquery.uniform","url":"git://github.com/pixelmatrix/uniform.git"},{"name":"jquery-tmpl","url":"git://github.com/jquery/jquery-tmpl.git"},{"name":"jquery.form","url":"git://github.com/chiefy/form.git"},{"name":"jqueryuibootstrap","url":"git://github.com/addyosmani/jquery-ui-bootstrap.git"},{"name":"jquery.tools","url":"git://github.com/jquerytools/jquerytools.git"},{"name":"jquery.smooth-scroll","url":"git://github.com/kswedberg/jquery-smooth-scroll.git"},{"name":"jquery-mobile-angular-adapter","url":"git://github.com/tigbro/jquery-mobile-angular-adapter.git"},{"name":"jquery-ui-bootstrap","url":"git://github.com/gustavohenke/jquery-ui-bootstrap"},{"name":"jquery.tagsinput","url":"git://github.com/xoxco/jQuery-Tags-Input.git"},{"name":"jquery-grill","url":"git://github.com/peterpajchl/jquery-grill.git"},{"name":"jquery-simpleweather","url":"git://github.com/monkeecreate/jquery.simpleWeather"},{"name":"jquery.atwho","url":"git://github.com/ichord/At.js.git"},{"name":"jquery-timepicker-jt","url":"git://github.com/jonthornton/jquery-timepicker.git"},{"name":"jquery.jscrollpane","url":"git://github.com/blittle/jscrollpane.git"},{"name":"jquery.localScroll","url":"git://github.com/flesler/jquery.localScroll.git"},{"name":"jqueryjs","url":"git://github.com/bowerjs/jquery.git"},{"name":"jquery-idletimer","url":"git://github.com/mikesherov/jquery-idletimer.git"},{"name":"jquery.event.swipe","url":"git://github.com/stephband/jquery.event.swipe.git"},{"name":"jquery.event.move","url":"git://github.com/stephband/jquery.event.move.git"},{"name":"jquery.serialScroll","url":"git://github.com/flesler/jquery.serialScroll.git"},{"name":"jquery.autoellipsis","url":"git://github.com/pvdspek/jquery.autoellipsis.git"},{"name":"jquery-cycle","url":"git://github.com/malsup/cycle.git"},{"name":"jquery-bridget","url":"git://github.com/desandro/jquery-bridget.git"},{"name":"jquery-knob","url":"git://github.com/aterrien/jQuery-Knob"},{"name":"jquery-tiny-pubsub","url":"git://github.com/wixo/jquery-tiny-pubsub.git"},{"name":"jquery-galleria","url":"git://github.com/aino/galleria.git"},{"name":"jquery.slimscroll","url":"git://github.com/rochal/jQuery-slimScroll/"},{"name":"jquery-hoverIntent","url":"git://github.com/briancherne/jquery-hoverIntent.git"},{"name":"jquery-autocomplete","url":"git://github.com/trendalytics/bower-jquery-autocomplete.git"},{"name":"jquerypp","url":"git://github.com/bitovi/jquerypp.git"},{"name":"cometd-javascript-jquery","url":"git://github.com/marksherretta/cometd-javascript-jquery.git"},{"name":"jquery.expander","url":"git://github.com/kswedberg/jquery-expander.git"},{"name":"geonames-server-jquery-plugin","url":"git://github.com/alchemy-fr/GeonamesServer-jQuery-Plugin.git"},{"name":"jquery.flip","url":"git://github.com/roncioso/Flip-jQuery.git"},{"name":"jquery-validation.password","url":"git://github.com/jzaefferer/jquery-validation.password.git"},{"name":"jquery-whenall","url":"git://github.com/soundcloud/jquery-whenall"},{"name":"wookmark-jquery","url":"git://github.com/GBKS/Wookmark-jQuery.git"},{"name":"jquery-ujs","url":"git://github.com/rails/jquery-ujs.git"},{"name":"jquery-drilldown","url":"git://github.com/Cinamonas/jquery-drilldown.git"},{"name":"jquery-resize","url":"git://github.com/cowboy/jquery-resize.git"},{"name":"jquery-modal","url":"git://github.com/kylefox/jquery-modal.git"},{"name":"jquery-timepicker","url":"git://github.com/fgelinas/timepicker.git"},{"name":"jquery-requestAnimationFrame","url":"git://github.com/gnarf37/jquery-requestAnimationFrame.git"},{"name":"jquery-touchswipe","url":"git://github.com/mattbryson/TouchSwipe-Jquery-Plugin.git"},{"name":"jquery-bgiframe","url":"git://github.com/brandonaaron/bgiframe.git"},{"name":"jquery-metadata","url":"git://github.com/jquery/jquery-metadata"},{"name":"jquery-bootstrap-scripting","url":"git://github.com/Nikku/jquery-bootstrap-scripting.git"},{"name":"spinjs-jquery","url":"git://gist.github.com/1290439.git"},{"name":"jquery-backstretch","url":"git://github.com/srobbin/jquery-backstretch.git"},{"name":"jquery-ellipsis","url":"git://github.com/STAR-ZERO/jquery-ellipsis.git"},{"name":"jquery-linkify","url":"git://github.com/maranomynet/linkify.git"},{"name":"jquery-nod","url":"git://github.com/casperin/nod.git"},{"name":"jquery-validation","url":"git://github.com/niftylettuce/jquery-validation.git"},{"name":"jquery-dragndrop","url":"git://github.com/Cinamonas/jquery-dragndrop.git"},{"name":"cometd-js-jquery","url":"git://github.com/askarby/cometd-js-jquery"},{"name":"jquery-cycle2","url":"git://github.com/malsup/cycle2.git"},{"name":"jquery.animate-enhanced","url":"git://github.com/benbarnett/jQuery-Animate-Enhanced.git"},{"name":"jquery-crop","url":"git://github.com/Cinamonas/jquery-crop.git"},{"name":"jquery-multiselect","url":"git://github.com/dio-el-claire/jquery-multiselect"},{"name":"jquery.shuffle","url":"git://github.com/caphun/jquery.shuffle.git"},{"name":"jquery-rotate","url":"git://github.com/schickling/jquery-rotate"},{"name":"jquery-overscroll","url":"git://github.com/azoff/Overscroll"},{"name":"jquery.customSelect","url":"git://github.com/adamcoulombe/jquery.customSelect.git"},{"name":"jquery-throttle-debounce","url":"git://github.com/cowboy/jquery-throttle-debounce.git"},{"name":"jquery-browser-selector","url":"git://github.com/schickling/jquery-browser-selector"},{"name":"jquery.videobackground","url":"git://github.com/georgepaterson/jquery-videobackground.git"},{"name":"jquery-serializeObject","url":"git://github.com/gillesruppert/jquery-serializeObject"},{"name":"jquery-address","url":"git://github.com/asual/jquery-address.git"},{"name":"jquery.atmosphere","url":"git://github.com/blittle/atmosphere.git"},{"name":"jquery-zclip","url":"git://github.com/patricklodder/jquery-zclip.git"},{"name":"jquery-oauthpopup","url":"git://github.com/MfgLabs/jquery-oauthpopup.git"},{"name":"jquery.DataTables","url":"git://github.com/UnityTeam/DataTables.git"},{"name":"jquery-cardify","url":"git://github.com/mverhaagen/cardify.git"},{"name":"jquery-extended-selectors","url":"git://github.com/keithclark/JQuery-Extended-Selectors.git"},{"name":"jquery-dropout-menu","url":"git://github.com/psirenny/jquery-dropout-menu.git"},{"name":"jquery-colorbox","url":"git://github.com/jackmoore/colorbox"},{"name":"bootstrap-jquery-tags","url":"git://github.com/sunliwen/bootstrap-jquery-tags.git"},{"name":"zepto-as-jquery","url":"git://github.com/pleasedontbelong/zepto.git"},{"name":"jquery-simulate","url":"git://github.com/jquery/jquery-simulate.git"},{"name":"jquery-simple-slider","url":"git://github.com/loopj/jquery-simple-slider.git"},{"name":"jquery.scrollorama","url":"git://github.com/johnpolacek/scrollorama.git"},{"name":"jquery.videoBG","url":"git://github.com/sydlawrence/jquery.videoBG.git"},{"name":"buster-jquery-assertions","url":"git://github.com/blittle/buster-jquery-assertions.git"},{"name":"jquery2","url":"git://github.com/iki/jquery2.git"},{"name":"jquery.center.js","url":"git://github.com/bebraw/jquery.center.js"},{"name":"jquery-jsonp","url":"git://github.com/jaubourg/jquery-jsonp.git"},{"name":"jquery.customInput","url":"git://github.com/bmatzner/jQuery-Custom-Input.git"},{"name":"jquery.socialshareprivacy","url":"git://github.com/patrickheck/socialshareprivacy.git"},{"name":"jquery-zoom","url":"git://github.com/jackmoore/zoom.git"},{"name":"jquery-marcopolo","url":"git://github.com/jstayton/jquery-marcopolo"},{"name":"jquery.easy-pie-chart","url":"git://github.com/rendro/easy-pie-chart.git"},{"name":"jquery.blockUI","url":"git://github.com/malsup/blockui#~2.55.0-2013.01.23"},{"name":"jquery-localize","url":"git://github.com/davidchambers/jQuery.localize.git"},{"name":"jquery.dform","url":"git://github.com/daffl/jquery.dform.git"},{"name":"jakobmattsson-jquery-elastic","url":"git://github.com/jakobmattsson/jquery-elastic"},{"name":"jquery.svg","url":"git://github.com/apendleton/jquery-svg.git"},{"name":"jquery-Mustache","url":"git://github.com/jonnyreeves/jquery-Mustache.git"},{"name":"jquery-transition","url":"git://github.com/peteboere/jquery-transition.git"},{"name":"jquery-prestige","url":"git://github.com/Munter/jquery-prestige.git"},{"name":"rxjs-jquery","url":"git://github.com/Reactive-Extensions/rxjs-jquery"},{"name":"jquery.ajax.fake","url":"git://github.com/anasnakawa/jquery.ajax.fake.git"},{"name":"jquery.backgroundSize","url":"git://github.com/louisremi/jquery.backgroundSize.js.git"},{"name":"jqueryui-amd","url":"git://github.com/jrburke/jqueryui-amd.git"},{"name":"jquery.tinymce","url":"git://github.com/rsilve/jquery.tinymce.git"},{"name":"jquery-number","url":"git://github.com/teamdf/jquery-number"},{"name":"zepto-replace-jquery","url":"git://github.com/iki/zepto-replace-jquery.git"},{"name":"jquery.query.js","url":"git://github.com/plasticine/jquery.query.js.git"},{"name":"jquery-image-uploader","url":"git://github.com/jdeniau/jquery-image-uploader.git"},{"name":"jquery-popover","url":"git://github.com/klaas4/jQuery.popover.git"},{"name":"jquery-grab-bag","url":"git://github.com/panayi/jquery-grab-bag.git"},{"name":"jqueryui-selectmenu","url":"git://github.com/pixeldrew/jqueryui-selectmenu.git"},{"name":"jskit-jquery","url":"git://github.com/kctang/jskit-jquery.git"},{"name":"jquery.hotkeys","url":"git://github.com/tzuryby/jquery.hotkeys.git"},{"name":"jquery.colorpicker","url":"git://github.com/vanderlee/colorpicker"},{"name":"jquery.spinjs","url":"git://github.com/tdoherty/jQuery.SpinJS.git"},{"name":"jquery-mobile-events","url":"git://github.com/caseywebdev/jquery-mobile-events"},{"name":"jquery-transform","url":"git://github.com/louisremi/jquery.transform.js.git"},{"name":"jquery-maskedinputs","url":"git://github.com/digitalBush/jquery.maskedinput.git"},{"name":"jquery-sortable","url":"git://github.com/johnny/jquery-sortable.git"},{"name":"jquery-imagefit-plugin","url":"git://github.com/cbulock/jquery-imagefit-plugin.git"},{"name":"jquery.unslider","url":"git://github.com/idiot/unslider.git"},{"name":"jquery-caret","url":"git://github.com/DrPheltRight/jquery-caret.git"},{"name":"jquery-hashchange","url":"git://github.com/cowboy/jquery-hashchange.git"},{"name":"jquery-ui-touch-punch-amd","url":"git://github.com/GeneralElectric/jquery-ui-touch-punch.git"},{"name":"jquery-dropkick","url":"git://github.com/JamieLottering/DropKick.git"},{"name":"jquery-async","url":"git://github.com/panayi/jquery-async.git"},{"name":"jquery.columnizer","url":"git://github.com/adamwulf/Columnizer-jQuery-Plugin.git"},{"name":"stacknav.jquery.js","url":"git://github.com/EtienneDion/stacknav.jquery.js.git"},{"name":"jquery.autotab","url":"git://github.com/map7/jquery.autotab"},{"name":"jquery.placeholder","url":"git://github.com/matoilic/jquery.placeholder.git"},{"name":"jquery-dropkick2","url":"git://github.com/changalberto/DropKick"},{"name":"jquery-simple-touch","url":"git://github.com/marcol/jquery-touch.git"},{"name":"quicksandpaginated.jquery.js","url":"git://github.com/EtienneDion/quicksandpaginated.jquery.js.git"},{"name":"jquery-mobile-reset","url":"git://github.com/bhurlow/jqmobile-reset.git"},{"name":"jquery-relativeTime","url":"git://github.com/hiromitz/jquery-relativeTime.git"},{"name":"jquery-selectboxit","url":"git://github.com/gfranko/jquery.selectBoxIt.js.git"},{"name":"dt-jquery2","url":"git://github.com/dt-bower/dt-jquery.git"},{"name":"jquery.iconfield","url":"git://github.com/yotamofek/jquery.iconfield.git"},{"name":"jquery-dragon","url":"git://github.com/jeremyckahn/dragon.git"},{"name":"jquery-boilerplate","url":"git://github.com/zenorocha/jquery-boilerplate"},{"name":"jquery.TubePlayer","url":"git://github.com/nirvanatikku/jQuery-TubePlayer-Plugin.git"},{"name":"jquery.avgrund","url":"git://github.com/voronianski/jquery.avgrund.js.git"},{"name":"requirejs-jquery","url":"git://github.com/jrburke/require-jquery.git"},{"name":"jquery-popunder","url":"git://github.com/hpbuniat/jquery-popunder.git"},{"name":"jquery.ut-image-panel","url":"git://github.com/urturn/jquery.ut-image-panel.git"},{"name":"inline-svg.jquery.js","url":"git://github.com/jswinarton/inline-svg.jquery.js.git"},{"name":"jquery.mobilemenu","url":"git://github.com/mattkersley/Responsive-Menu.git"},{"name":"jquery.tube","url":"git://github.com/inukshuk/jquery.tube.js.git"},{"name":"jquery-csspick","url":"git://github.com/oscarlgz/jquery-csspick.git"},{"name":"jquery.metadata","url":"git://github.com/jquery-orphans/jquery-metadata.git"},{"name":"jquery-modality","url":"git://github.com/Cinamonas/jquery-modality.git"},{"name":"jquery.loadmask.spin","url":"git://github.com/iloveitaly/jquery.loadmask.spin.git"},{"name":"jquery-md5","url":"git://github.com/placemarker/jQuery-MD5"},{"name":"jquery.mosaicflow","url":"git://github.com/sapegin/jquery.mosaicflow"},{"name":"jquery.inputmask","url":"git://github.com/RobinHerbots/jquery.inputmask.git"},{"name":"jquery.retina","url":"git://github.com/iloveitaly/jQuery-Retina-Display-Plugin.git"},{"name":"jquery-manifest","url":"git://github.com/jstayton/jquery-manifest"},{"name":"jquery-filterer","url":"git://github.com/joelcox/jquery-filterer.git"},{"name":"jquery.fixedheadertable","url":"git://github.com/markmalek/Fixed-Header-Table.git"},{"name":"easyfacebook.jquery.js","url":"git://github.com/EtienneDion/easyfacebook.jquery.js.git"},{"name":"jquery-impromptu","url":"git://github.com/trentrichardson/jQuery-Impromptu.git"},{"name":"jquery.taboverride","url":"git://github.com/wjbryant/jquery.taboverride"},{"name":"jquery.fullscreenBackground","url":"git://github.com/Gaya/Fullscreen-Background-jQuery-plugin.git"},{"name":"jquery-htmlclean","url":"git://github.com/components/jquery-htmlclean.git"},{"name":"jquery-ias","url":"git://github.com/webcreate/infinite-ajax-scroll"},{"name":"jquery.slideShow","url":"git://github.com/appleboy/jquery.slideShow.git"},{"name":"jquery.loadfeed","url":"git://github.com/choage/jQuery.loadFeed.git"},{"name":"jquery.extendedinput.js","url":"git://github.com/Wolfr/jquery.extendedinput.git"},{"name":"jquery.three","url":"git://github.com/makesites/jquery-three.git"},{"name":"jquery-keyfilter","url":"git://github.com/akzhan/jquery-keyfilter.git"},{"name":"bolster.jquerypp","url":"git://github.com/bolster/jquerypp.git"},{"name":"jquery.decodeEntities","url":"git://github.com/michael-lawrence/jquery.decodeEntities.git"},{"name":"jquery-once","url":"git://github.com/RobLoach/jquery-once.git"},{"name":"jquery-dragEvents","url":"git://github.com/icholy/dragEvents.jq.js.git"},{"name":"jquery-ui-touch-punch-working","url":"git://github.com/yeco/jquery-ui-touch-punch.git"},{"name":"jquery-details","url":"git://github.com/mathiasbynens/jquery-details.git"},{"name":"jquery.neotabs.js","url":"git://github.com/PascalPrecht/jquery.neotabs.js"},{"name":"jquery-ajax-progress","url":"git://github.com/englercj/jquery-ajax-progress.git"},{"name":"jquery-ajaxmask","url":"git://github.com/kevbook/jquery-ajaxmask.git"},{"name":"jquery-skim","url":"git://github.com/vormplus/jQuery-Skim.git"},{"name":"jquery-smooth-scrolling","url":"git://github.com/mathiasbynens/jquery-smooth-scrolling.git"},{"name":"jquery.tokko.js","url":"git://github.com/bebraw/jquery.tokko.js"},{"name":"jquery.couch","url":"git://github.com/vkurchatkin/jquery.couch"},{"name":"jquery-fitmaps","url":"git://github.com/suderman/jquery.fitmaps.git"},{"name":"jquery.ut-sticker","url":"git://github.com/urturn/jquery.ut-sticker.git"},{"name":"jquery-indexeddb","url":"git://github.com/axemclion/jquery-indexeddb.git"},{"name":"jquery-store","url":"git://github.com/medialize/jQuery-store.git"},{"name":"jquery.contenteditable","url":"git://github.com/makesites/jquery-contenteditable.git"},{"name":"jquery.combine","url":"git://github.com/seriema/jquery.combine.git"},{"name":"jquery.throttle","url":"git://github.com/wangshijun2010/jquery.throttle.git"},{"name":"jquery.loadHtml","url":"git://github.com/anasnakawa/jquery.loadHtml.git"},{"name":"jquery-ui.daterange","url":"git://github.com/layerssss/jquery-ui.daterange.git"},{"name":"jquery.outbound-analytics","url":"git://github.com/gmurphey/jquery.outbound-analytics"},{"name":"jquery.toc","url":"git://github.com/ndabas/toc"},{"name":"jquery.finger","url":"git://github.com/ngryman/jquery.finger"},{"name":"jquery.sidebar","url":"git://github.com/sideroad/jquery.sidebar.git"},{"name":"jquery.tipFiveThree","url":"git://github.com/gocom/jquery.tipfivethree.git"},{"name":"jquery.textareaAutogrow","url":"git://github.com/Fleshgrinder/jquery.textareaAutogrow.git"},{"name":"iframe-auto-height-jquery-plugin","url":"git://github.com/Sly777/Iframe-Height-Jquery-Plugin"},{"name":"jquery-interdependencies","url":"git://github.com/miohtama/jquery-interdependencies.git"},{"name":"jquery.rdio","url":"git://github.com/rdio/jquery.rdio.js.git"},{"name":"jquery.hurl","url":"git://github.com/makesites/jquery-hurl.git"},{"name":"jquery.pub-sub-validate","url":"git://github.com/wixo/jquery.pub-sub-validate.git"},{"name":"jquery-rdfquery","url":"git://github.com/components/jquery-rdfquery.git"},{"name":"jqueryservice","url":"git://github.com/stephenway/jquery-service.git"},{"name":"jquery.periodical.ajax","url":"git://github.com/rscarvalho/periodicalAjax.git"},{"name":"jquery-lineup","url":"git://github.com/mach3/jquery-lineup"},{"name":"jquery-tinytimer","url":"git://github.com/odyniec/jQuery-tinyTimer.git"},{"name":"jquery-maskmoney","url":"git://github.com/plentz/jquery-maskmoney"},{"name":"jquery.foobar","url":"git://github.com/makesites/jquery-foobar.git"},{"name":"jquery-ajax-goodies","url":"git://github.com/fantactuka/jquery-ajax-goodies.git"},{"name":"jquery-inputevent","url":"git://github.com/dodo/jquery-inputevent.git"},{"name":"jquery.pep","url":"git://github.com/briangonzalez/jquery.pep.js.git"},{"name":"jquery.fly","url":"git://github.com/matjaz/jquery.fly.git"},{"name":"jquery-styledform","url":"git://github.com/jaitsu87/jQuery-StyledForm"},{"name":"jquery.selectalize","url":"git://github.com/unfold/jquery.selectalize"},{"name":"jquery-sieve","url":"git://github.com/rmm5t/jquery-sieve.git"},{"name":"jquery.checkalize","url":"git://github.com/unfold/jquery.checkalize"},{"name":"jquery.trueresize","url":"git://github.com/jfroffice/jquery.trueresize.git"},{"name":"jquery-gholiday","url":"git://github.com/chris4403/gholiday.git"},{"name":"jquery.imageFallback","url":"git://github.com/michael-lawrence/jquery.imageFallback.git"},{"name":"jqueryp","url":"git://github.com/Ensighten/jqueryp.git"},{"name":"jquery.backbone.hijax","url":"git://github.com/michael-lawrence/jquery.backbone.hijax.git"},{"name":"jquery-selectBox","url":"git://github.com/marcj/jquery-selectBox.git"},{"name":"jquery-combobox","url":"git://github.com/jslayer/jquery-combobox.git"},{"name":"jquery.panzoom","url":"git://github.com/timmywil/jquery.panzoom.git"},{"name":"jquery.ui.montjquery.ui.monthpicker","url":"git://github.com/thebrowser/jquery.ui.monthpicker.git"},{"name":"jquery.existence","url":"git://github.com/seriema/jquery.existence.git"},{"name":"jquery.reverse","url":"git://github.com/michael-lawrence/jquery.reverse.git"},{"name":"jquery.render","url":"git://github.com/sideroad/jquery.render.git"},{"name":"strictjquery","url":"git://github.com/devinrhode2/StrictjQuery.js.git"},{"name":"jquery-maptack","url":"git://github.com/jimmyhillis/jquery-maptack"},{"name":"jquery.expanding-textareas","url":"git://github.com/kbrs/ExpandingTextareas.git"},{"name":"jquery.floatingmessage","url":"git://github.com/sideroad/jquery.floatingmessage.git"},{"name":"jquery.removeClassWithPrefix","url":"git://github.com/michael-lawrence/jquery.removeClassWithPrefix.git"},{"name":"jquery.replaceEntities","url":"git://github.com/michael-lawrence/jquery.replaceEntities.git"},{"name":"jquery.accordion","url":"git://github.com/matoilic/jquery.accordion.git"},{"name":"jquery.slidawall","url":"git://github.com/makesites/jquery-slidawall.git"},{"name":"jquery-icon-insert","url":"git://github.com/stephenway/jquery-icon-insert.git"},{"name":"jquery.pluginTemplate","url":"git://github.com/michael-lawrence/jquery.pluginTemplate.git"},{"name":"jquery-m","url":"git://github.com/meetup/jquery.git"},{"name":"jquery.BlackAndWhite","url":"git://github.com/GianlucaGuarini/jQuery.BlackAndWhite.git"},{"name":"jquery.herotabs","url":"git://github.com/simonsmith/jquery.herotabs.git"},{"name":"jquery.payment","url":"git://github.com/stripe/jquery.payment.git"},{"name":"jquery.theCombo.js","url":"git://github.com/lagden/theCombo.git"},{"name":"jquery.shapeshift","url":"git://github.com/McPants/jquery.shapeshift.git"},{"name":"jquery.bind-first","url":"git://github.com/private-face/jquery.bind-first.git"},{"name":"jquery-sheetrock","url":"git://github.com/chriszarate/sheetrock"},{"name":"jquery-reveal","url":"git://github.com/VitalikL/reveal.git"},{"name":"jquery.formstyler","url":"git://github.com/Dimox/formStyler.git"},{"name":"jquery-loader","url":"git://github.com/monkeymonk/jquery.loader.js.git"},{"name":"jquery-placeholder2","url":"git://github.com/jgallen23/jquery-placeholder.git"},{"name":"jquery-bbq-deparam","url":"git://github.com/nexxTM/jquery-deparam.git"},{"name":"eduardocasas-jquery.filestyle","url":"git://github.com/eduardocasas/jquery_filestyle.git"},{"name":"jquery-hoverlight","url":"git://github.com/sunliwen/jquery-hoverlight.git"},{"name":"jquery.autocomplete","url":"git://github.com/julien-c/jQueryAutocompletePlugin.git"},{"name":"jquery-noselect","url":"git://github.com/mathiasbynens/jquery-noselect.git"},{"name":"jqueryui-l2l","url":"git://github.com/krampstudio/jquerui-l2l.git"},{"name":"jquery-tinyscroller","url":"git://github.com/Takazudo/jQuery.tinyscroller.git"},{"name":"jquery.scrollwatch","url":"git://github.com/cobbweb/jquery.scrollwatch.git"},{"name":"jquery-watcher","url":"git://github.com/jacobrelkin/jquery-watcher.git"},{"name":"jquery.editable","url":"git://github.com/shokai/jQuery.editable.git"},{"name":"dt-jquery","url":"git://github.com:dt-bower/dt-jquery.git"},{"name":"jquery-leanmodal","url":"git://github.com/FinelySliced/leanModal.js.git"},{"name":"jquery-esthetic","url":"git://github.com/johannestroeger/bower-jquery-esthetic.git"},{"name":"jquery-truncate","url":"git://github.com/pathable/truncate.git"},{"name":"jquery.theCover.js","url":"git://github.com/lagden/theCover.git"},{"name":"geonames-jquery-plugin","url":"git://github.com:alchemy-fr/GeonamesServer-jQuery-Plugin.git"},{"name":"jquery.html5Loader","url":"git://github.com/GianlucaGuarini/jquery.html5loader.git"},{"name":"jquery-maskedinputs-fork","url":"git://github.com/sergiovilar/jquery.maskedinput.git"},{"name":"jquery-oninput","url":"git://github.com/mathiasbynens/jquery-oninput.git"},{"name":"ed.jquery.toggler","url":"git://github.com/erskinedesign/ed.jquery.toggler.js.git"},{"name":"jquery-textext","url":"git://github.com/alexgorbatchev/jquery-textext.git"},{"name":"bacon-jquery-bindings","url":"git://github.com/raimohanska/bacon-jquery-bindings"},{"name":"jquery-class","url":"git://github.com/iamdenny/jquery-class.git"},{"name":"jquery-alakazam","url":"git://github.com/jasonhowmans/jquery-alakazam.git"},{"name":"jquery-power-plugin","url":"git://github.com/3den/jquery-power-plugin.git"},{"name":"jquery.expandBox","url":"git://bitbucket.org:harobed/jquery.expandbox.git"},{"name":"jquery-polypage","url":"git://github.com/andykent/polypage.git"},{"name":"jquery-visibility","url":"git://github.com/mathiasbynens/jquery-visibility.git"},{"name":"jquery-seeThru","url":"git://github.com/m90/jquery-seeThru.git"},{"name":"jquery-textrange","url":"git://github.com/dwieeb/jquery-textrange.git"},{"name":"jquery.classList","url":"git://github.com/mzgol/jquery.classList.git"},{"name":"jquery.pwstrength","url":"git://github.com/matoilic/jquery.pwstrength.git"},{"name":"jquery-custom-data-attributes","url":"git://github.com/mathiasbynens/jquery-custom-data-attributes.git"},{"name":"jquery-mavis","url":"git://github.com/smallhadroncollider/mavis.git"},{"name":"ed.jquery.plugin.template","url":"git://github.com/erskinedesign/ed.jquery.plugin.template.js.git"},{"name":"jquery-dotdotdot","url":"git://github.com/FrDH/jQuery.dotdotdot.git"},{"name":"jquery-before-after","url":"git://github.com/bencorlett/jquery-before-after.git"},{"name":"jquery-scrollfollow","url":"git://github.com/jackncoke/jquery-scrollfollow.git"},{"name":"jquery-test123123","url":"git://github.com/components/jquery-test123123.git"},{"name":"jquery-ui.datarange.git","url":"git://github.com/layerssss/jquery-ui.datarange.git"},{"name":"jquery-loader-plugin","url":"git://github.com/mimiz/jquery-loader-plugin.git"},{"name":"jquery-transition-guarantee","url":"git://github.com/tuxracer/jquery-transition-guarantee.git"}] From ee4e003c2d425c7e2f40b0605d29d8988a2adca4 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Fri, 5 Jul 2013 12:50:08 +0100 Subject: [PATCH 0088/1021] [tests] fix method call --- packages/bower-registry-client/test/Client.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 880473c2c..89eb3765b 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -186,7 +186,6 @@ describe('RegistryClient', function () { describe('calling the search instance method with argument', function () { beforeEach(function () { - nock('https://bower.herokuapp.com:443') .get('/packages/search/jquery') .replyWithFile(200, __dirname + '/fixtures/search.json'); @@ -232,7 +231,7 @@ describe('RegistryClient', function () { describe('calling the search instance method without argument', function () { it('should return an error and no results', function () { - this.registry.register('', function (err, results) { + this.registry.search('', function (err, results) { expect(err).to.not.be.null; expect(results).to.be.undefined; }); From 0b592f86d0dee974d08372360a2e1427f9112a8b Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Fri, 5 Jul 2013 12:50:25 +0100 Subject: [PATCH 0089/1021] [tests] tidy up nock call --- packages/bower-registry-client/test/Client.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 89eb3765b..404faaf87 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -2,7 +2,6 @@ var RegistryClient = require('../Client'), expect = require('chai').expect, nock = require('nock'); - describe('RegistryClient', function () { beforeEach(function () { @@ -134,12 +133,7 @@ describe('RegistryClient', function () { beforeEach(function () { nock('https://bower.herokuapp.com:443') .post('/packages', 'name=test-ba&url=git%3A%2F%2Fgithub.com%2Ftest-ba%2Ftest-ba.git') - .reply(201, '', { 'content-type': 'text/html;charset=utf-8', - server: 'thin 1.3.1 codename Triple Espresso', - 'x-frame-options': 'sameorigin', - 'x-xss-protection': '1; mode=block', - 'content-length': '0', - connection: 'keep-alive' }); + .reply(201); this.pkg = 'test-ba'; this.pkgUrl = 'git://github.com/test-ba/test-ba.git'; From 82278037ec8919eee0bc0db62fbfddd033928c35 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Fri, 5 Jul 2013 13:08:42 +0100 Subject: [PATCH 0090/1021] [tests] adds comments and clearCache tests --- packages/bower-registry-client/test/Client.js | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 404faaf87..4837cf0db 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -93,6 +93,10 @@ describe('RegistryClient', function () { }); + + // + // lookup + // describe('calling the lookup instance method with argument', function () { it('should not return an error', function () { @@ -128,6 +132,10 @@ describe('RegistryClient', function () { }); + + // + // register + // describe('calling the register instance method with argument', function () { beforeEach(function () { @@ -177,6 +185,10 @@ describe('RegistryClient', function () { }); }); + + // + // search + // describe('calling the search instance method with argument', function () { beforeEach(function () { @@ -232,4 +244,30 @@ describe('RegistryClient', function () { }); }); + + // + // clearCache + // + describe('called the clearCache instance method with argument', function () { + + beforeEach(function () { + this.pkg = 'jquery'; + }); + + it('should not return an error', function () { + this.registry.clearCache(this.pkg, function (err) { + expect(err).to.be.null; + }); + }); + }); + + describe('called the clearCache instance method without argument', function () { + + it('should not return any errors and remove all cache items', function () { + this.registry.clearCache(function (err) { + expect(err).to.be.null; + }); + }); + }); + }); From 9cfa3e5002a2ce6e68832b778fa0ea0e6d885580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 6 Jul 2013 13:48:53 +0100 Subject: [PATCH 0091/1021] Changes to the reset & clear runtime cache. Minor tweak to the grunt file. --- packages/bower-registry-client/Client.js | 14 ++++++++++---- packages/bower-registry-client/Gruntfile.js | 7 ++----- packages/bower-registry-client/lib/list.js | 6 +++--- packages/bower-registry-client/lib/lookup.js | 4 ++-- packages/bower-registry-client/lib/search.js | 6 +++--- packages/bower-registry-client/lib/util/Cache.js | 8 +++++++- packages/bower-registry-client/package.json | 2 +- packages/bower-registry-client/test/Client.js | 8 ++++++-- packages/bower-registry-client/test/core/list.js | 6 +++--- packages/bower-registry-client/test/core/lookup.js | 6 +++--- packages/bower-registry-client/test/core/search.js | 6 +++--- 11 files changed, 43 insertions(+), 30 deletions(-) diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js index 6ac2be424..f362c6f31 100644 --- a/packages/bower-registry-client/Client.js +++ b/packages/bower-registry-client/Client.js @@ -1,6 +1,7 @@ var os = require('os'); var path = require('path'); var methods = require('./lib'); +var Cache = require('./lib/util/Cache'); function RegistryClient(config) { config = config || {}; @@ -65,10 +66,15 @@ RegistryClient.prototype.clearCache = function (name, callback) { this.search.clearCache.call(this, name, callback); this.list.clearCache.call(this, callback); }; -RegistryClient.prototype.clearRuntimeCache = function () { - this.lookup.cleanRuntimeCache.call(this); - this.search.cleanRuntimeCache.call(this); - this.list.cleanRuntimeCache.call(this); + +RegistryClient.prototype.resetCache = function (name, callback) { + this.lookup.resetCache.call(this, name, callback); + this.search.resetCache.call(this, name, callback); + this.list.resetCache.call(this, callback); +}; + +RegistryClient.clearRuntimeCache = function () { + Cache.clearRuntimeCache(); }; // ----------------------------- diff --git a/packages/bower-registry-client/Gruntfile.js b/packages/bower-registry-client/Gruntfile.js index 1cdba105a..162a9a579 100644 --- a/packages/bower-registry-client/Gruntfile.js +++ b/packages/bower-registry-client/Gruntfile.js @@ -39,7 +39,6 @@ module.exports = function (grunt) { }, src: ['test/runner.js'] } - }, @@ -51,8 +50,6 @@ module.exports = function (grunt) { }); // Default task. - grunt.registerTask('default', 'jshint'); - grunt.registerTask('test', 'simplemocha:full'); - grunt.registerTask('build', ['jshint', 'simplemocha:build']); - + grunt.registerTask('test', ['simplemocha:full']); + grunt.registerTask('default', ['jshint', 'test']); }; diff --git a/packages/bower-registry-client/lib/list.js b/packages/bower-registry-client/lib/list.js index 74eb18284..df554cf63 100644 --- a/packages/bower-registry-client/lib/list.js +++ b/packages/bower-registry-client/lib/list.js @@ -60,7 +60,7 @@ function list(callback) { }, function (err) { // Clear runtime cache, keeping the persistent data // in files for future offline usage - clearRuntimeCache(); + resetCache(); // If some of the registry entries failed, error out if (err) { @@ -158,7 +158,7 @@ function clearCache(callback) { }, callback); } -function clearRuntimeCache() { +function resetCache() { var remote; for (remote in this._listCache) { @@ -168,6 +168,6 @@ function clearRuntimeCache() { list.initCache = initCache; list.clearCache = clearCache; -list.clearRuntimeCache = clearRuntimeCache; +list.resetCache = resetCache; module.exports = list; diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index edf85b13a..ea0ae696f 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -171,7 +171,7 @@ function clearCache(name, callback) { } } -function clearRuntimeCache() { +function resetCache() { var remote; for (remote in this._lookupCache) { @@ -181,6 +181,6 @@ function clearRuntimeCache() { lookup.initCache = initCache; lookup.clearCache = clearCache; -lookup.clearRuntimeCache = clearRuntimeCache; +lookup.resetCache = resetCache; module.exports = lookup; diff --git a/packages/bower-registry-client/lib/search.js b/packages/bower-registry-client/lib/search.js index e0ff7a29b..d0262d26e 100644 --- a/packages/bower-registry-client/lib/search.js +++ b/packages/bower-registry-client/lib/search.js @@ -67,7 +67,7 @@ function search(name, callback) { }, function (err) { // Clear runtime cache, keeping the persistent data // in files for future offline usage - clearRuntimeCache(); + resetCache(); // If some of the registry entries failed, error out if (err) { @@ -173,7 +173,7 @@ function clearCache(name, callback) { }, callback); } -function clearRuntimeCache() { +function resetCache() { var remote; for (remote in this._searchCache) { @@ -183,6 +183,6 @@ function clearRuntimeCache() { search.initCache = initCache; search.clearCache = clearCache; -search.clearRuntimeCache = clearRuntimeCache; +search.resetCache = resetCache; module.exports = search; diff --git a/packages/bower-registry-client/lib/util/Cache.js b/packages/bower-registry-client/lib/util/Cache.js index 909d279ff..f40330700 100644 --- a/packages/bower-registry-client/lib/util/Cache.js +++ b/packages/bower-registry-client/lib/util/Cache.js @@ -148,10 +148,16 @@ Cache.prototype.clear = function (callback) { }); }; -Cache.prototype.reset = function () { +Cache.prototype.reset = function (callback) { this._cache.reset(); }; +Cache.clearRuntimeCache = function () { + this._cache.reset(); +}; + +//------------------------------- + Cache.prototype._hasExpired = function (json) { var expires = json.expires; diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 9e7126604..ad2c25faa 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -36,6 +36,6 @@ "nock": "~0.18.2" }, "scripts": { - "test": "grunt build --verbose" + "test": "grunt test" } } diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 4837cf0db..d0a934234 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -83,8 +83,12 @@ describe('RegistryClient', function () { expect(RegistryClient.prototype).to.have.ownProperty('clearCache'); }); - it('should have a clearRuntimeCache prototype method', function () { - expect(RegistryClient.prototype).to.have.ownProperty('clearRuntimeCache'); + it('should have a resetCache prototype method', function () { + expect(RegistryClient.prototype).to.have.ownProperty('resetCache'); + }); + + it('should have a clearRuntimeCache static method', function () { + expect(RegistryClient).to.have.ownProperty('clearRuntimeCache'); }); it('should have a _initCache prototype method', function () { diff --git a/packages/bower-registry-client/test/core/list.js b/packages/bower-registry-client/test/core/list.js index cb4c955fe..1bb32b296 100644 --- a/packages/bower-registry-client/test/core/list.js +++ b/packages/bower-registry-client/test/core/list.js @@ -19,9 +19,9 @@ describe('list module', function () { expect(typeof list.clearCache === 'function').to.be.ok; }); - it('should expose a ClearRuntimeCache method', function () { - expect(list.clearCache).to.be.ok; - expect(typeof list.clearCache === 'function').to.be.ok; + it('should expose a resetCache method', function () { + expect(list.resetCache).to.be.ok; + expect(typeof list.resetCache === 'function').to.be.ok; }); }); diff --git a/packages/bower-registry-client/test/core/lookup.js b/packages/bower-registry-client/test/core/lookup.js index 122754867..22c4a4482 100644 --- a/packages/bower-registry-client/test/core/lookup.js +++ b/packages/bower-registry-client/test/core/lookup.js @@ -19,9 +19,9 @@ describe('lookup module', function () { expect(typeof lookup.clearCache === 'function').to.be.ok; }); - it('should expose a ClearRuntimeCache method', function () { - expect(lookup.clearCache).to.be.ok; - expect(typeof lookup.clearCache === 'function').to.be.ok; + it('should expose a resetCache method', function () { + expect(lookup.resetCache).to.be.ok; + expect(typeof lookup.resetCache === 'function').to.be.ok; }); }); diff --git a/packages/bower-registry-client/test/core/search.js b/packages/bower-registry-client/test/core/search.js index d0227d00e..bf213bf1b 100644 --- a/packages/bower-registry-client/test/core/search.js +++ b/packages/bower-registry-client/test/core/search.js @@ -19,9 +19,9 @@ describe('search module', function () { expect(typeof search.clearCache === 'function').to.be.ok; }); - it('should expose a clearRuntimeCache method', function () { - expect(search.clearRuntimeCache).to.be.ok; - expect(typeof search.clearRuntimeCache === 'function').to.be.ok; + it('should expose a resetCache method', function () { + expect(search.resetCache).to.be.ok; + expect(typeof search.resetCache === 'function').to.be.ok; }); }); From d0eb3e760f40d8911b6c57706cb626ab05ecea8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 6 Jul 2013 13:55:59 +0100 Subject: [PATCH 0092/1021] Bump rc version. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index ad2c25faa..6b662cbb0 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.0.0-rc7", + "version": "0.0.0-rc8", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From c1393786948418c3646b71e0b58c8750f3b2dd84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 6 Jul 2013 14:09:11 +0100 Subject: [PATCH 0093/1021] Add comment. --- packages/bower-registry-client/lib/util/Cache.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/bower-registry-client/lib/util/Cache.js b/packages/bower-registry-client/lib/util/Cache.js index f40330700..206af18b5 100644 --- a/packages/bower-registry-client/lib/util/Cache.js +++ b/packages/bower-registry-client/lib/util/Cache.js @@ -153,6 +153,9 @@ Cache.prototype.reset = function (callback) { }; Cache.clearRuntimeCache = function () { + // Note that _cache refers to the static _cache variable + // that holds other caches per dir! + // Do not confuse it with the instance cache this._cache.reset(); }; From e78ef493a1a7bc290843551984c14e6b5f4eed68 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Sat, 6 Jul 2013 14:28:16 +0100 Subject: [PATCH 0094/1021] [tests] don't test for private methods --- packages/bower-registry-client/test/Client.js | 12 ------------ .../bower-registry-client/test/core/util/Cache.js | 13 ------------- 2 files changed, 25 deletions(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index d0a934234..22b361793 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -25,14 +25,6 @@ describe('RegistryClient', function () { expect(this.registry instanceof RegistryClient).to.be.ok; }); - it('should set properties correctly', function () { - expect(this.registry).to.have.ownProperty('_config'); - expect(this.registry).to.have.ownProperty('_cache'); - expect(this.registry).to.have.ownProperty('_lookupCache'); - expect(this.registry).to.have.ownProperty('_searchCache'); - expect(this.registry).to.have.ownProperty('_listCache'); - }); - it('should set default registry config', function () { expect(this.registry._config.registry).to.deep.equal(this.conf); }); @@ -91,10 +83,6 @@ describe('RegistryClient', function () { expect(RegistryClient).to.have.ownProperty('clearRuntimeCache'); }); - it('should have a _initCache prototype method', function () { - expect(RegistryClient.prototype).to.have.ownProperty('_initCache'); - }); - }); diff --git a/packages/bower-registry-client/test/core/util/Cache.js b/packages/bower-registry-client/test/core/util/Cache.js index 4842da6eb..34280282f 100644 --- a/packages/bower-registry-client/test/core/util/Cache.js +++ b/packages/bower-registry-client/test/core/util/Cache.js @@ -15,11 +15,6 @@ describe('Cache', function () { expect(this.cache instanceof Cache).to.be.ok; }); - it('should set properties correctly', function () { - expect(this.cache).to.have.ownProperty('_cache'); - expect(this.cache).to.have.ownProperty('_options'); - }); - it('should inherit LRU cache methods', function () { var self = this, lruMethods = [ @@ -56,14 +51,6 @@ describe('Cache', function () { expect(Cache.prototype).to.have.ownProperty('reset'); }); - it('should have a reset _hasExpired method', function () { - expect(Cache.prototype).to.have.ownProperty('_hasExpired'); - }); - - it('should have a reset _getFile method', function () { - expect(Cache.prototype).to.have.ownProperty('_getFile'); - }); - }); }); From a585e96fdfc5c398203085d4dce76a0742cb9c04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 6 Jul 2013 14:39:13 +0100 Subject: [PATCH 0095/1021] Improve clear runtime cache. --- packages/bower-registry-client/lib/util/Cache.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/bower-registry-client/lib/util/Cache.js b/packages/bower-registry-client/lib/util/Cache.js index 206af18b5..26da10317 100644 --- a/packages/bower-registry-client/lib/util/Cache.js +++ b/packages/bower-registry-client/lib/util/Cache.js @@ -148,7 +148,7 @@ Cache.prototype.clear = function (callback) { }); }; -Cache.prototype.reset = function (callback) { +Cache.prototype.reset = function () { this._cache.reset(); }; @@ -156,6 +156,13 @@ Cache.clearRuntimeCache = function () { // Note that _cache refers to the static _cache variable // that holds other caches per dir! // Do not confuse it with the instance cache + + // Clear cache of each directory + this._cache.forEach(function (cache) { + cache.reset(); + }); + + // Clear root cache this._cache.reset(); }; From 6a1bb88c3b95e8fcc1a61e865e6146c66e9db787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 6 Jul 2013 14:39:24 +0100 Subject: [PATCH 0096/1021] Update README. --- packages/bower-registry-client/README.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index 1b4bbd75a..e2746c287 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -116,20 +116,34 @@ registry.clearCache(function (err) { ``` -#### .clearRuntimeCache() +#### .resetCache() -Clears the in-memory cache used to speed up the module. +Clears the in-memory cache used to speed up the instance. Note that in most cases, you don't need to clear the runtime cache since it has self expiration times. Might be useful if you use this module in long-living programs. ```js +registry.resetCache(); +``` + +#### #clearRuntimeCache() + +Clears the in-memory cache used to speed up the whole module. +This clears the static in-memory cache as well as in-memory cache used by instances. + +Note that in some situations, the instances in-memory cache might not be cleared so +you should not rely on it. Instead, you should create new instances after calling this +method. -registry.clearRuntimeCache(); +```js + +RegistryClient.clearRuntimeCache(); ``` + ## License -Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). \ No newline at end of file +Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). From e298f74310eb1bea6130f6d5bed9fb6dde592e1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 6 Jul 2013 14:55:43 +0100 Subject: [PATCH 0097/1021] Improve sentence. --- packages/bower-registry-client/README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index e2746c287..225eb305a 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -133,12 +133,10 @@ registry.resetCache(); Clears the in-memory cache used to speed up the whole module. This clears the static in-memory cache as well as in-memory cache used by instances. -Note that in some situations, the instances in-memory cache might not be cleared so -you should not rely on it. Instead, you should create new instances after calling this -method. +Note that in edge cases, some instance's in-memory cache might not have been cleared. +If that's a problem, you should create fresh instances instead. ```js - RegistryClient.clearRuntimeCache(); ``` From ce89d9fbe034f51b2e78ceaedcf392232e73d63e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 6 Jul 2013 21:53:04 +0100 Subject: [PATCH 0098/1021] Initial commit. --- packages/bower-config/.editorconfig | 8 +++ packages/bower-config/.gitignore | 6 ++ packages/bower-config/.jshintrc | 61 +++++++++++++++++ packages/bower-config/.travis.yml | 4 ++ packages/bower-config/LICENSE | 19 ++++++ packages/bower-config/README.md | 60 +++++++++++++++++ packages/bower-config/lib/Config.js | 87 +++++++++++++++++++++++++ packages/bower-config/lib/util/paths.js | 35 ++++++++++ packages/bower-config/lib/util/rc.js | 29 +++++++++ packages/bower-config/package.json | 34 ++++++++++ packages/bower-config/test/test.js | 0 11 files changed, 343 insertions(+) create mode 100644 packages/bower-config/.editorconfig create mode 100644 packages/bower-config/.gitignore create mode 100644 packages/bower-config/.jshintrc create mode 100644 packages/bower-config/.travis.yml create mode 100644 packages/bower-config/LICENSE create mode 100644 packages/bower-config/README.md create mode 100644 packages/bower-config/lib/Config.js create mode 100644 packages/bower-config/lib/util/paths.js create mode 100644 packages/bower-config/lib/util/rc.js create mode 100644 packages/bower-config/package.json create mode 100644 packages/bower-config/test/test.js diff --git a/packages/bower-config/.editorconfig b/packages/bower-config/.editorconfig new file mode 100644 index 000000000..ba4428907 --- /dev/null +++ b/packages/bower-config/.editorconfig @@ -0,0 +1,8 @@ +root = true + +[*] + +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 diff --git a/packages/bower-config/.gitignore b/packages/bower-config/.gitignore new file mode 100644 index 000000000..1743854da --- /dev/null +++ b/packages/bower-config/.gitignore @@ -0,0 +1,6 @@ +node_modules +npm-debug.log + +test/assets/github-test-package +test/assets/github-test-package-copy +test/assets/temp diff --git a/packages/bower-config/.jshintrc b/packages/bower-config/.jshintrc new file mode 100644 index 000000000..52c609091 --- /dev/null +++ b/packages/bower-config/.jshintrc @@ -0,0 +1,61 @@ +{ + "predef": [ + "console", + "describe", + "it", + "after", + "afterEach", + "before", + "beforeEach" + ], + + "indent": 4, + "node": true, + "devel": true, + + "bitwise": false, + "curly": false, + "eqeqeq": true, + "forin": false, + "immed": true, + "latedef": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": true, + "plusplus": false, + "regexp": false, + "undef": true, + "unused": true, + "quotmark": "single", + "strict": false, + "trailing": true, + + "asi": false, + "boss": true, + "debug": false, + "eqnull": true, + "es5": false, + "esnext": false, + "evil": false, + "expr": false, + "funcscope": false, + "globalstrict": false, + "iterator": false, + "lastsemic": false, + "laxbreak": true, + "laxcomma": false, + "loopfunc": true, + "multistr": false, + "onecase": true, + "regexdash": false, + "scripturl": false, + "smarttabs": false, + "shadow": false, + "sub": false, + "supernew": true, + "validthis": false, + + "nomen": false, + "white": true +} diff --git a/packages/bower-config/.travis.yml b/packages/bower-config/.travis.yml new file mode 100644 index 000000000..df63076b8 --- /dev/null +++ b/packages/bower-config/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.10" + - "0.8" diff --git a/packages/bower-config/LICENSE b/packages/bower-config/LICENSE new file mode 100644 index 000000000..13e8246fd --- /dev/null +++ b/packages/bower-config/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012 Twitter and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md new file mode 100644 index 000000000..65ca82796 --- /dev/null +++ b/packages/bower-config/README.md @@ -0,0 +1,60 @@ +# bower-config [![Build Status](https://secure.travis-ci.org/bower/config.png?branch=master)](http://travis-ci.org/bower/config) + +The Bower config reader and writer. + + +## Usage + +#### .load() + +Loads the bower configuration from the configuration files. + + +#### .get(key) + +Returns a configuration value by `key`. +Keys with dots are supported to access deep values. + + +#### .set(key, value) + +Sets a configuration value for `key`. +Keys with dots are supported to access deep values. + +#### .save(where, callback) + +Saves changes to `where`. +The `where` argument can be a path to a configuration file or: + +- `local` to save it in the configured current working directory (defaulting to `process.cwd`) +- `user` to save it in the configuration file located in the home directory + + +#### .toObject() + +Returns a deep copy of the underlying configuration object. + + +#### #create(cwd) + +Obtains a instance where `cwd` is the current working directory (defaults to `process.cwd`); + +```js +var config = require('bower-config').create(); +// You can also specify a working directory +var config2 = require('bower-config).create(./some/path'); +``` + + +#### #read(cwd) + +Alias for: + +```js +var configObject = (new Config(cwd)).load().toJson(); +``` + + +## License + +Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js new file mode 100644 index 000000000..8ade0887f --- /dev/null +++ b/packages/bower-config/lib/Config.js @@ -0,0 +1,87 @@ +var os = require('os'); +var path = require('path'); +var mout = require('mout'); +var rc = require('./util/rc'); +var paths = require('./util/paths'); + +// Guess proxy defined in the env +var proxy = process.env.HTTP_PROXY + || process.env.http_proxy + || null; + +var httpsProxy = process.env.HTTPS_PROXY + || process.env.https_proxy + || process.env.HTTP_PROXY + || process.env.http_proxy + || null; + +//------------- + +function Config(cwd) { + this._cwd = cwd || process.cwd(); + this._config = {}; +} + +Config.prototype.load = function () { + var runtimeConfig; + + runtimeConfig = rc('bower', { + 'cwd': this._cwd, + 'directory': 'bower_components', + 'registry': 'https://bower.herokuapp.com', + 'shorthand-resolver': 'git://github.com/{{owner}}/{{package}}.git', + 'tmp': os.tmpdir ? os.tmpdir() : os.tmpDir(), + 'proxy': proxy, + 'https-proxy': httpsProxy, + 'ca': null, + 'strict-ssl': true, + 'user-agent': 'node/' + process.version + ' ' + process.platform + ' ' + process.arch, + 'git': 'git', + 'color': true, + 'interactive': false, + 'storage': { + packages: path.join(paths.cache, 'packages'), + links: path.join(paths.data, 'links'), + completion: path.join(paths.data, 'completion'), + registry: path.join(paths.cache, 'registry'), + git: path.join(paths.data, 'git') + } + }, this._cwd); + + // Generate config based on the rc, making every key camelCase + this._config = {}; + mout.object.forOwn(runtimeConfig, function (value, key) { + key = key.replace(/_/g, '-'); + this._config[mout.string.camelCase(key)] = value; + }, this); + + return this; +}; + +Config.prototype.get = function (key) { + +}; + +Config.prototype.set = function (key, value) { + + return this; +}; + +Config.prototype.save = function (where, callback) { + +}; + +Config.prototype.toJson = function () { + return mout.lang.deepClone(this._config); +}; + +Config.create = function (cwd) { + return new Config(cwd); +}; + +Config.read = function (cwd) { + var config = new Config(cwd); + return config.load().toJson(); +}; + +module.exports = Config; diff --git a/packages/bower-config/lib/util/paths.js b/packages/bower-config/lib/util/paths.js new file mode 100644 index 000000000..7a8393f04 --- /dev/null +++ b/packages/bower-config/lib/util/paths.js @@ -0,0 +1,35 @@ +var os = require('os'); +var path = require('path'); +var osenv = require('osenv'); + +// Assume XDG defaults +// See: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html +var paths = { + config: process.env.XDG_CONFIG_HOME, + data: process.env.XDG_DATA_HOME, + cache: process.env.XDG_DATA_CACHE +}; + +// Guess some needed properties based on the user OS +var temp = os.tmpdir ? os.tmpdir() : os.tmpDir(); +var home = osenv.home(); +var base; + +// Fallbacks for windows +if (process.platform === 'win32') { + base = path.resolve(process.env.APPDATA || home || temp); + base = path.join(base, 'bower_new'); + + paths.config = paths.config || path.join(base, 'config'); + paths.data = paths.data || path.join(base, 'data'); + paths.cache = paths.cache || path.join(base, 'cache'); +// Fallbacks for other operating systems +} else { + base = path.resolve(home || temp); + + paths.config = paths.config || path.join(base, '.config/bower_new'); + paths.data = paths.data || path.join(base, '.local/share/bower_new'); + paths.cache = paths.cache || path.join(base, '.cache/bower_new'); +} + +module.exports = paths; diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js new file mode 100644 index 000000000..487c99a28 --- /dev/null +++ b/packages/bower-config/lib/util/rc.js @@ -0,0 +1,29 @@ +var path = require('path'); +var optimist = require('optimist'); +var osenv = require('osenv'); +var mout = require('mout'); +var cc = require('rc/lib/utils'); + +var win = process.platform === 'win32'; +var home = osenv.home(); + +function rc(name, defaults, cwd, argv) { + defaults = defaults || {}; + cwd = cwd || process.cwd(); + argv = argv || optimist.argv; + + return mout.object.deepMixIn.apply(null, [ + defaults, + win ? {} : cc.json(path.join('/etc', name, 'config')), + win ? {} : cc.json(path.join('/etc', name + 'rc')), + cc.json(path.join(home, '.config', name, 'config')), + cc.json(path.join(home, '.config', name)), + cc.json(path.join(home, '.' + name, 'config')), + cc.json(path.join(home, '.' + name + 'rc')), + cc.json(path.join(cwd, '.' + name + 'rc')), + cc.env(name + '_'), + typeof argv.config !== 'object' ? {} : argv.config + ]); +} + +module.exports = rc; diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json new file mode 100644 index 000000000..6388447c2 --- /dev/null +++ b/packages/bower-config/package.json @@ -0,0 +1,34 @@ +{ + "name": "bower-config", + "version": "0.0.0-rc.1", + "description": "The Bower config reader and writer.", + "author": "Twitter", + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/bower/config/blob/master/LICENSE" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/bower/config.git" + }, + "main": "lib/Config", + "homepage": "http://bower.io", + "engines": { + "node": ">=0.8.0" + }, + "dependencies": { + "mout": "~0.6.0", + "rc": "~0.3.0", + "osenv": "0.0.3", + "optimist": "~0.6.0" + }, + "devDependencies": { + "mocha": "~1.12.0", + "expect.js": "~0.2.0" + }, + "scripts": { + "test": "mocha -R spec" + } +} diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js new file mode 100644 index 000000000..e69de29bb From 6c56581c155baae87131ab47ab2476ea5b510b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 6 Jul 2013 21:55:16 +0100 Subject: [PATCH 0099/1021] Typo. --- packages/bower-config/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index 65ca82796..43622352a 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -42,7 +42,7 @@ Obtains a instance where `cwd` is the current working directory (defaults to `pr ```js var config = require('bower-config').create(); // You can also specify a working directory -var config2 = require('bower-config).create(./some/path'); +var config2 = require('bower-config').create(./some/path'); ``` From 2bf16ad88b07114ca5eab32cf1a70f9a0b199af1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 6 Jul 2013 21:55:43 +0100 Subject: [PATCH 0100/1021] Fix rc name and update mocha. --- packages/bower-json/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 380856912..e0c4f851b 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,6 +1,6 @@ { "name": "bower-json", - "version": "0.0.0-rc1", + "version": "0.0.0-rc.1", "description": "Read bower.json files with semantics, normalisation, defaults and validation.", "author": "Twitter", "licenses": [ @@ -21,7 +21,7 @@ "graceful-fs": "~1.2.2" }, "devDependencies": { - "mocha": "~1.8.2", + "mocha": "~1.12.0", "expect.js": "~0.2.0" }, "scripts": { From ad4ec1477864066cc293c36da88c95c6f2205251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 6 Jul 2013 21:55:53 +0100 Subject: [PATCH 0101/1021] Add editor config. --- packages/bower-json/.editorconfig | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 packages/bower-json/.editorconfig diff --git a/packages/bower-json/.editorconfig b/packages/bower-json/.editorconfig new file mode 100644 index 000000000..ba4428907 --- /dev/null +++ b/packages/bower-json/.editorconfig @@ -0,0 +1,8 @@ +root = true + +[*] + +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 From 6741d99681c239465946620d4ef2b5e65fb41a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 6 Jul 2013 21:56:53 +0100 Subject: [PATCH 0102/1021] Fix rc version and update mocha. --- packages/bower-registry-client/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 6b662cbb0..ecc3aedd0 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.0.0-rc8", + "version": "0.0.0-rc.8", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ @@ -26,7 +26,7 @@ "mkdirp": "~0.3.5" }, "devDependencies": { - "mocha": "~1.8.2", + "mocha": "~1.12.0", "expect.js": "~0.2.0", "grunt": "~0.4.1", "grunt-contrib-watch": "~0.4.4", From 80f35725e6be615f8112b8106c70ff17c7c62e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 6 Jul 2013 22:31:05 +0100 Subject: [PATCH 0103/1021] Require relatively. --- packages/bower-config/lib/util/rc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 487c99a28..586e3744f 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -2,7 +2,7 @@ var path = require('path'); var optimist = require('optimist'); var osenv = require('osenv'); var mout = require('mout'); -var cc = require('rc/lib/utils'); +var cc = require('../../node_modules/rc/lib/utils'); // This is ugly! var win = process.platform === 'win32'; var home = osenv.home(); From f406cfcebb7a5b20bd40861a32a4c3b22512e037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 6 Jul 2013 22:40:37 +0100 Subject: [PATCH 0104/1021] Change from toJson to toObject. --- packages/bower-config/lib/Config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index 8ade0887f..d9b98b336 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -71,7 +71,7 @@ Config.prototype.save = function (where, callback) { }; -Config.prototype.toJson = function () { +Config.prototype.toObject = function () { return mout.lang.deepClone(this._config); }; @@ -81,7 +81,7 @@ Config.create = function (cwd) { Config.read = function (cwd) { var config = new Config(cwd); - return config.load().toJson(); + return config.load().toObject(); }; module.exports = Config; From 2fdfa64b1398410573607eaa17e24263090889c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Sat, 6 Jul 2013 22:42:16 +0100 Subject: [PATCH 0105/1021] Typo. --- packages/bower-config/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index 43622352a..462c791b4 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -42,7 +42,7 @@ Obtains a instance where `cwd` is the current working directory (defaults to `pr ```js var config = require('bower-config').create(); // You can also specify a working directory -var config2 = require('bower-config').create(./some/path'); +var config2 = require('bower-config').create('./some/path'); ``` From 686e401368987c47280d848e324289dd10bac990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 7 Jul 2013 02:24:54 +0100 Subject: [PATCH 0106/1021] Add del. --- packages/bower-config/README.md | 9 ++++++++- packages/bower-config/lib/Config.js | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index 43622352a..b3578e749 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -19,7 +19,14 @@ Keys with dots are supported to access deep values. #### .set(key, value) Sets a configuration value for `key`. -Keys with dots are supported to access deep values. +Keys with dots are supported to set deep values. + + +#### .del(key) + +Removes configuration named `key`. +Keys with dots are supported to delete deep keys. + #### .save(where, callback) diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index d9b98b336..a1c14a32e 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -67,6 +67,11 @@ Config.prototype.set = function (key, value) { return this; }; +Config.prototype.del = function (key, value) { + + return this; +}; + Config.prototype.save = function (where, callback) { }; From 4085af023aea601619646165a470e9a13c497844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 7 Jul 2013 02:25:13 +0100 Subject: [PATCH 0107/1021] Typo. --- packages/bower-config/lib/util/paths.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/paths.js b/packages/bower-config/lib/util/paths.js index 7a8393f04..9b5926192 100644 --- a/packages/bower-config/lib/util/paths.js +++ b/packages/bower-config/lib/util/paths.js @@ -7,7 +7,7 @@ var osenv = require('osenv'); var paths = { config: process.env.XDG_CONFIG_HOME, data: process.env.XDG_DATA_HOME, - cache: process.env.XDG_DATA_CACHE + cache: process.env.XDG_CACHE_HOME }; // Guess some needed properties based on the user OS From e152ab6cf2665065d8ed1a229e0b66eca926c0bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 7 Jul 2013 02:26:06 +0100 Subject: [PATCH 0108/1021] Use our own rc implementation. --- packages/bower-config/lib/util/rc.js | 79 ++++++++++++++++++++++++---- packages/bower-config/package.json | 7 +-- 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 586e3744f..9a5574213 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -1,8 +1,10 @@ var path = require('path'); +var fs = require('graceful-fs'); var optimist = require('optimist'); var osenv = require('osenv'); var mout = require('mout'); -var cc = require('../../node_modules/rc/lib/utils'); // This is ugly! +var rimraf = require('rimraf'); +var paths = require('./paths'); var win = process.platform === 'win32'; var home = osenv.home(); @@ -14,16 +16,75 @@ function rc(name, defaults, cwd, argv) { return mout.object.deepMixIn.apply(null, [ defaults, - win ? {} : cc.json(path.join('/etc', name, 'config')), - win ? {} : cc.json(path.join('/etc', name + 'rc')), - cc.json(path.join(home, '.config', name, 'config')), - cc.json(path.join(home, '.config', name)), - cc.json(path.join(home, '.' + name, 'config')), - cc.json(path.join(home, '.' + name + 'rc')), - cc.json(path.join(cwd, '.' + name + 'rc')), - cc.env(name + '_'), + win ? {} : json(path.join('/etc', name + 'rc')), + json(path.join(home, '.' + name + 'rc')), + json(path.join(paths.config, name + 'rc')), + json(find('.' + name + 'rc', cwd)), + env(name + '_'), typeof argv.config !== 'object' ? {} : argv.config ]); } +function parse(content, file) { + try { + return JSON.parse(content); + } catch (e) { + // If we got an error, remove the file + if (file) { + try { + rimraf.sync(file); + } catch (e) {} + } + } + + return null; +} + +function json(file) { + var content; + + try { + content = fs.readFileSync(file); + } catch (err) { + return null; + } + + return parse(content, file); +} + +function env(prefix) { + var obj = {}; + var prefixLength = prefix.length; + + mout.object.forOwn(process.env, function (value, key) { + if (mout.string.startsWith(key, prefix)) { + obj[key.substr(prefixLength)] = value; + } + }); + + return obj; +} + +function find(filename, dir) { + var walk = function (filename, dir) { + var file = path.join(dir, filename); + var parent = path.dirname(dir); + + try { + fs.statSync(file); + return file; + } catch (err) { + // Check if we hit the root + if (parent === dir) { + return null; + } + + return walk(filename, parent); + } + }; + + dir = dir || process.cwd(); + return walk(filename, dir); +} + module.exports = rc; diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 6388447c2..0de9e348e 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.0.0-rc.1", + "version": "0.0.0-rc.2", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ @@ -20,9 +20,10 @@ }, "dependencies": { "mout": "~0.6.0", - "rc": "~0.3.0", "osenv": "0.0.3", - "optimist": "~0.6.0" + "optimist": "~0.6.0", + "graceful-fs": "~1.2.2", + "rimraf": "~2.2.0" }, "devDependencies": { "mocha": "~1.12.0", From a65caa62b30db7ec5bb500dc2c0f1a339ff50811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 7 Jul 2013 02:38:43 +0100 Subject: [PATCH 0109/1021] Add name validation. --- packages/bower-json/lib/json.js | 11 ++++++++++- packages/bower-json/lib/util/createError.js | 8 ++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 packages/bower-json/lib/util/createError.js diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index 34ca37a4a..32e00992d 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -1,5 +1,6 @@ var fs = require('graceful-fs'); var path = require('path'); +var createError = require('./util/createError'); function read(file, callback) { fs.readFile(file, function (err, contents) { @@ -21,7 +22,15 @@ function read(file, callback) { function parse(json, callback) { // Apply normalisation and validation here // If something is invalid, the error.code should be EINVALID - callback(null, json); + process.nextTick(function () { + if (!json.name) { + return callback(createError('No name property set', 'EINVALID')); + } + + // TODO: !! + + return callback(null, json); + }); } function find(folder, callback) { diff --git a/packages/bower-json/lib/util/createError.js b/packages/bower-json/lib/util/createError.js new file mode 100644 index 000000000..8e9a4168a --- /dev/null +++ b/packages/bower-json/lib/util/createError.js @@ -0,0 +1,8 @@ +function createError(msg, code) { + var err = new Error(msg); + err.code = code; + + return err; +} + +module.exports = createError; From 829dccc1b64adc2f7160230f64f8f674955cbf9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 7 Jul 2013 02:38:53 +0100 Subject: [PATCH 0110/1021] Bump rc version. --- packages/bower-json/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index e0c4f851b..9a1826411 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,6 +1,6 @@ { "name": "bower-json", - "version": "0.0.0-rc.1", + "version": "0.0.0-rc.2", "description": "Read bower.json files with semantics, normalisation, defaults and validation.", "author": "Twitter", "licenses": [ From 8e3fef90966705e376cb9240c1fd3804ef0ec1fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 7 Jul 2013 02:50:47 +0100 Subject: [PATCH 0111/1021] Sort deps. --- packages/bower-config/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 0de9e348e..bb5ca541f 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -19,15 +19,15 @@ "node": ">=0.8.0" }, "dependencies": { + "graceful-fs": "~1.2.2", "mout": "~0.6.0", - "osenv": "0.0.3", "optimist": "~0.6.0", - "graceful-fs": "~1.2.2", + "osenv": "0.0.3", "rimraf": "~2.2.0" }, "devDependencies": { - "mocha": "~1.12.0", - "expect.js": "~0.2.0" + "expect.js": "~0.2.0", + "mocha": "~1.12.0" }, "scripts": { "test": "mocha -R spec" From 21ebc226e4fa85a06cad974fba2e03cfaa75eedf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 7 Jul 2013 02:51:04 +0100 Subject: [PATCH 0112/1021] Sort deps. --- packages/bower-registry-client/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index ecc3aedd0..61550d30c 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -26,13 +26,13 @@ "mkdirp": "~0.3.5" }, "devDependencies": { - "mocha": "~1.12.0", + "chai": "~1.7.2", "expect.js": "~0.2.0", "grunt": "~0.4.1", "grunt-contrib-watch": "~0.4.4", "grunt-contrib-jshint": "~0.6.0", "grunt-simple-mocha": "~0.4.0", - "chai": "~1.7.2", + "mocha": "~1.12.0", "nock": "~0.18.2" }, "scripts": { From bf9e8048ff32da80af21273f3cf7a9dc86b0b21b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 7 Jul 2013 02:51:55 +0100 Subject: [PATCH 0113/1021] Sort deps. --- packages/bower-json/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 9a1826411..01ff222a5 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -21,8 +21,8 @@ "graceful-fs": "~1.2.2" }, "devDependencies": { - "mocha": "~1.12.0", - "expect.js": "~0.2.0" + "expect.js": "~0.2.0", + "mocha": "~1.12.0" }, "scripts": { "test": "mocha -R spec" From 09a0eb26d1a0032e8d3b66c7d8cfbf09a01d9290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 7 Jul 2013 03:00:18 +0100 Subject: [PATCH 0114/1021] Improve sentence. --- packages/bower-registry-client/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index 225eb305a..399b59a37 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -133,7 +133,7 @@ registry.resetCache(); Clears the in-memory cache used to speed up the whole module. This clears the static in-memory cache as well as in-memory cache used by instances. -Note that in edge cases, some instance's in-memory cache might not have been cleared. +Note that in edge cases, some instance's in-memory cache might be skipped. If that's a problem, you should create fresh instances instead. ```js From 606f15fec5f4ad8c7f71a333f7490fff26ce5519 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Mon, 8 Jul 2013 14:23:55 +0100 Subject: [PATCH 0115/1021] [tests] basic offline check --- packages/bower-registry-client/test/Client.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 22b361793..789bb7c6c 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -19,7 +19,7 @@ describe('RegistryClient', function () { describe('Constructor', function () { - describe('instantiating a client without custom options', function () { + describe('instantiating a client', function () { it('should provide an instance of RegistryClient', function () { expect(this.registry instanceof RegistryClient).to.be.ok; @@ -85,6 +85,23 @@ describe('RegistryClient', function () { }); + describe('instantiating a client with custom options', function () { + + describe('offline', function () { + + it('should not return search results ', function () { + this.registry._config.offline = true; + + this.registry.search('jquery', function (err, results) { + expect(err).to.be.null; + expect(results.length).to.equal(0); + }); + }); + + }); + + }); + // // lookup From b1ad187d1b0fd7fc08fca430f3390be5164450d8 Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Mon, 8 Jul 2013 11:12:40 -0700 Subject: [PATCH 0116/1021] Fix typos. --- packages/bower-json/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index 4da36c6ab..10f4beb9c 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -8,8 +8,8 @@ Read `bower.json` files with semantics, normalisation, defaults and validation. #### .read(file, callback) Reads `file` and applies normalisation, defaults and validation according to the `bower.json` spec. -If the passed `file` does not exists, the callback is called with `error.code` equal to `ENOENT`. -If the passed `file` contents are not a valid JSON, the callback is called with `error.code` equal to `EMALFORMED`. +If the passed `file` does not exist, the callback is called with `error.code` equal to `ENOENT`. +If the passed `file` contents are not valid JSON, the callback is called with `error.code` equal to `EMALFORMED`. If the `json` does not comply with the `bower.json` spec, the callback is called with `error.code` equal to `EINVALID`. ```js From 8e5bdc6b2b8f1fcd0627b59d0b211dce99d16d98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 9 Jul 2013 21:00:39 +0100 Subject: [PATCH 0117/1021] BC change. --- packages/bower-config/lib/Config.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index a1c14a32e..5c142aff0 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -48,6 +48,11 @@ Config.prototype.load = function () { } }, this._cwd); + // Some backwards compatible things.. + runtimeConfig['shorthand-resolver'] = runtimeConfig['shorthand-resolver'] + .replace(/\{\{\{/g, '{{') + .replace(/\}\}\}/g, '}}'); + // Generate config based on the rc, making every key camelCase this._config = {}; mout.object.forOwn(runtimeConfig, function (value, key) { From 1c5529691b3d4c82869dae512892a7e7c86d8fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 9 Jul 2013 21:00:58 +0100 Subject: [PATCH 0118/1021] Bump rc version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index bb5ca541f..f7d439243 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.0.0-rc.2", + "version": "0.1.0-rc.1", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From a2753bb27de05f8841557e67a0524ef475f9635c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 9 Jul 2013 21:01:19 +0100 Subject: [PATCH 0119/1021] Bump rc version. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 61550d30c..2fd636b9b 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.0.0-rc.8", + "version": "0.1.0-rc.1", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From 1397c3248d73153c18f38ac63d5444a316f71a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 9 Jul 2013 21:01:53 +0100 Subject: [PATCH 0120/1021] Bump rc version. --- packages/bower-json/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 01ff222a5..3e4b81416 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,6 +1,6 @@ { "name": "bower-json", - "version": "0.0.0-rc.2", + "version": "0.1.0-rc.1", "description": "Read bower.json files with semantics, normalisation, defaults and validation.", "author": "Twitter", "licenses": [ From ccc9907034aa409acfc1673bd1c680cef5153992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 9 Jul 2013 23:36:15 +0100 Subject: [PATCH 0121/1021] Change from bower_new to bower. --- packages/bower-config/lib/util/paths.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/bower-config/lib/util/paths.js b/packages/bower-config/lib/util/paths.js index 9b5926192..92ecd5ff8 100644 --- a/packages/bower-config/lib/util/paths.js +++ b/packages/bower-config/lib/util/paths.js @@ -18,7 +18,7 @@ var base; // Fallbacks for windows if (process.platform === 'win32') { base = path.resolve(process.env.APPDATA || home || temp); - base = path.join(base, 'bower_new'); + base = path.join(base, 'bower'); paths.config = paths.config || path.join(base, 'config'); paths.data = paths.data || path.join(base, 'data'); @@ -27,9 +27,9 @@ if (process.platform === 'win32') { } else { base = path.resolve(home || temp); - paths.config = paths.config || path.join(base, '.config/bower_new'); - paths.data = paths.data || path.join(base, '.local/share/bower_new'); - paths.cache = paths.cache || path.join(base, '.cache/bower_new'); + paths.config = paths.config || path.join(base, '.config/bower'); + paths.data = paths.data || path.join(base, '.local/share/bower'); + paths.cache = paths.cache || path.join(base, '.cache/bower'); } module.exports = paths; From 4b4b2333771003e72ffc66c71271aae2b51172ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 9 Jul 2013 23:38:15 +0100 Subject: [PATCH 0122/1021] Bump rc version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index f7d439243..c3c295714 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.1.0-rc.1", + "version": "0.1.0-rc.2", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 01a6ae61d2ea1bf18be448c5ea66e723ef6dabdd Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Wed, 10 Jul 2013 14:53:48 +0100 Subject: [PATCH 0123/1021] replace chai with expect.js --- packages/bower-registry-client/package.json | 1 - packages/bower-registry-client/test/Client.js | 40 +++++++++---------- .../test/core/util/Cache.js | 12 +++--- .../test/core/util/createError.js | 4 +- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 2fd636b9b..71bf9fa10 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -26,7 +26,6 @@ "mkdirp": "~0.3.5" }, "devDependencies": { - "chai": "~1.7.2", "expect.js": "~0.2.0", "grunt": "~0.4.1", "grunt-contrib-watch": "~0.4.4", diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 789bb7c6c..8608da28e 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -1,5 +1,5 @@ var RegistryClient = require('../Client'), - expect = require('chai').expect, + expect = require('expect.js'), nock = require('nock'); describe('RegistryClient', function () { @@ -26,19 +26,19 @@ describe('RegistryClient', function () { }); it('should set default registry config', function () { - expect(this.registry._config.registry).to.deep.equal(this.conf); + expect(this.registry._config.registry).to.eql(this.conf); }); it('should set default search config', function () { - expect(this.registry._config.registry.search[0]).to.equal(this.uri); + expect(this.registry._config.registry.search[0]).to.eql(this.uri); }); it('should set default register config', function () { - expect(this.registry._config.registry.register).to.equal(this.uri); + expect(this.registry._config.registry.register).to.eql(this.uri); }); it('should set default publish config', function () { - expect(this.registry._config.registry.publish).to.equal(this.uri); + expect(this.registry._config.registry.publish).to.eql(this.uri); }); it('should set default cache path config', function () { @@ -46,7 +46,7 @@ describe('RegistryClient', function () { }); it('should set default timeout config', function () { - expect(this.registry._config.timeout).to.equal(this.timeoutVal); + expect(this.registry._config.timeout).to.eql(this.timeoutVal); }); it('should set default strictSsl config', function () { @@ -56,31 +56,31 @@ describe('RegistryClient', function () { }); it('should have a lookup prototype method', function () { - expect(RegistryClient.prototype).to.have.ownProperty('lookup'); + expect(RegistryClient.prototype).to.have.property('lookup'); }); it('should have a search prototype method', function () { - expect(RegistryClient.prototype).to.have.ownProperty('search'); + expect(RegistryClient.prototype).to.have.property('search'); }); it('should have a list prototype method', function () { - expect(RegistryClient.prototype).to.have.ownProperty('list'); + expect(RegistryClient.prototype).to.have.property('list'); }); it('should have a register prototype method', function () { - expect(RegistryClient.prototype).to.have.ownProperty('register'); + expect(RegistryClient.prototype).to.have.property('register'); }); it('should have a clearCache prototype method', function () { - expect(RegistryClient.prototype).to.have.ownProperty('clearCache'); + expect(RegistryClient.prototype).to.have.property('clearCache'); }); it('should have a resetCache prototype method', function () { - expect(RegistryClient.prototype).to.have.ownProperty('resetCache'); + expect(RegistryClient.prototype).to.have.property('resetCache'); }); it('should have a clearRuntimeCache static method', function () { - expect(RegistryClient).to.have.ownProperty('clearRuntimeCache'); + expect(RegistryClient).to.have.property('clearRuntimeCache'); }); }); @@ -94,7 +94,7 @@ describe('RegistryClient', function () { this.registry.search('jquery', function (err, results) { expect(err).to.be.null; - expect(results.length).to.equal(0); + expect(results.length).to.eql(0); }); }); @@ -117,14 +117,14 @@ describe('RegistryClient', function () { it('should return entry type', function () { this.registry.lookup('jquery', function (err, entry) { expect(err).to.be.null; - expect(entry.type).to.equal('alias'); + expect(entry.type).to.eql('alias'); }); }); it('should return entry url ', function () { this.registry.lookup('jquery', function (err, entry) { expect(err).to.be.null; - expect(entry.url).to.equal('git://github.com/components/jquery.git'); + expect(entry.url).to.eql('git://github.com/components/jquery.git'); }); }); @@ -168,7 +168,7 @@ describe('RegistryClient', function () { this.registry.register(this.pkg, this.pkgUrl, function (err, entry) { expect(err).to.be.null; - expect(entry.name).to.equal(self.pkg); + expect(entry.name).to.eql(self.pkg); done(); }); }); @@ -178,7 +178,7 @@ describe('RegistryClient', function () { this.registry.register(this.pkg, this.pkgUrl, function (err, entry) { expect(err).to.be.null; - expect(entry.url).to.equal(self.pkgUrl); + expect(entry.url).to.eql(self.pkgUrl); done(); }); }); @@ -222,7 +222,7 @@ describe('RegistryClient', function () { this.registry.search(this.pkg, function (err, results) { results.forEach(function (entry) { if (entry.name === self.pkg) { - expect(entry.name).to.equal(self.pkg); + expect(entry.name).to.eql(self.pkg); done(); } }); @@ -235,7 +235,7 @@ describe('RegistryClient', function () { this.registry.search(this.pkg, function (err, results) { results.forEach(function (entry) { if (entry.name === self.pkg) { - expect(entry.url).to.equal(self.pkgUrl); + expect(entry.url).to.eql(self.pkgUrl); done(); } }); diff --git a/packages/bower-registry-client/test/core/util/Cache.js b/packages/bower-registry-client/test/core/util/Cache.js index 34280282f..6dc4b3237 100644 --- a/packages/bower-registry-client/test/core/util/Cache.js +++ b/packages/bower-registry-client/test/core/util/Cache.js @@ -24,7 +24,7 @@ describe('Cache', function () { ]; lruMethods.forEach(function (method) { - expect(self.cache._cache).to.have.ownProperty(method); + expect(self.cache._cache).to.have.property(method); }); }); @@ -32,23 +32,23 @@ describe('Cache', function () { }); it('should have a get prototype method', function () { - expect(Cache.prototype).to.have.ownProperty('get'); + expect(Cache.prototype).to.have.property('get'); }); it('should have a set prototype method', function () { - expect(Cache.prototype).to.have.ownProperty('set'); + expect(Cache.prototype).to.have.property('set'); }); it('should have a del prototype method', function () { - expect(Cache.prototype).to.have.ownProperty('del'); + expect(Cache.prototype).to.have.property('del'); }); it('should have a clear prototype method', function () { - expect(Cache.prototype).to.have.ownProperty('clear'); + expect(Cache.prototype).to.have.property('clear'); }); it('should have a reset prototype method', function () { - expect(Cache.prototype).to.have.ownProperty('reset'); + expect(Cache.prototype).to.have.property('reset'); }); }); diff --git a/packages/bower-registry-client/test/core/util/createError.js b/packages/bower-registry-client/test/core/util/createError.js index c91a97e2c..98029bc83 100644 --- a/packages/bower-registry-client/test/core/util/createError.js +++ b/packages/bower-registry-client/test/core/util/createError.js @@ -22,11 +22,11 @@ describe('createError', function () { }); it('should return an Error with message', function () { - expect(this.err.message).to.equal('message'); + expect(this.err.message).to.eql('message'); }); it('should return an Error with code', function () { - expect(this.err.code).to.equal(500); + expect(this.err.code).to.eql(500); }); }); From d43c9f006bf48d6032c33a16cce3c5e706471cd6 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Wed, 10 Jul 2013 15:01:18 +0100 Subject: [PATCH 0124/1021] fix module references --- packages/bower-registry-client/test/core/index.js | 2 +- packages/bower-registry-client/test/core/list.js | 2 +- packages/bower-registry-client/test/core/lookup.js | 2 +- packages/bower-registry-client/test/core/register.js | 2 +- packages/bower-registry-client/test/core/search.js | 2 +- packages/bower-registry-client/test/core/util/Cache.js | 2 +- packages/bower-registry-client/test/core/util/createError.js | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/bower-registry-client/test/core/index.js b/packages/bower-registry-client/test/core/index.js index 923a7fb3a..d9eaf1ab4 100644 --- a/packages/bower-registry-client/test/core/index.js +++ b/packages/bower-registry-client/test/core/index.js @@ -1,5 +1,5 @@ var index = require('../../lib/index'), - expect = require('chai').expect; + expect = require('expect.js'); describe('index module', function () { diff --git a/packages/bower-registry-client/test/core/list.js b/packages/bower-registry-client/test/core/list.js index 1bb32b296..752709e54 100644 --- a/packages/bower-registry-client/test/core/list.js +++ b/packages/bower-registry-client/test/core/list.js @@ -1,5 +1,5 @@ var list = require('../../lib/list'), - expect = require('chai').expect; + expect = require('expect.js'); describe('list module', function () { diff --git a/packages/bower-registry-client/test/core/lookup.js b/packages/bower-registry-client/test/core/lookup.js index 22c4a4482..3dfc0cb50 100644 --- a/packages/bower-registry-client/test/core/lookup.js +++ b/packages/bower-registry-client/test/core/lookup.js @@ -1,5 +1,5 @@ var lookup = require('../../lib/lookup'), - expect = require('chai').expect; + expect = require('expect.js'); describe('lookup module', function () { diff --git a/packages/bower-registry-client/test/core/register.js b/packages/bower-registry-client/test/core/register.js index 42ea303ce..85e430e03 100644 --- a/packages/bower-registry-client/test/core/register.js +++ b/packages/bower-registry-client/test/core/register.js @@ -1,5 +1,5 @@ var register = require('../../lib/register'), - expect = require('chai').expect; + expect = require('expect.js'); describe('register module', function () { diff --git a/packages/bower-registry-client/test/core/search.js b/packages/bower-registry-client/test/core/search.js index bf213bf1b..a44eb3e8e 100644 --- a/packages/bower-registry-client/test/core/search.js +++ b/packages/bower-registry-client/test/core/search.js @@ -1,5 +1,5 @@ var search = require('../../lib/search'), - expect = require('chai').expect; + expect = require('expect.js'); describe('search module', function () { diff --git a/packages/bower-registry-client/test/core/util/Cache.js b/packages/bower-registry-client/test/core/util/Cache.js index 6dc4b3237..c097ef60a 100644 --- a/packages/bower-registry-client/test/core/util/Cache.js +++ b/packages/bower-registry-client/test/core/util/Cache.js @@ -1,5 +1,5 @@ var Cache = require('../../../lib/util/Cache'), - expect = require('chai').expect; + expect = require('expect.js'); describe('Cache', function () { diff --git a/packages/bower-registry-client/test/core/util/createError.js b/packages/bower-registry-client/test/core/util/createError.js index 98029bc83..10affa9d3 100644 --- a/packages/bower-registry-client/test/core/util/createError.js +++ b/packages/bower-registry-client/test/core/util/createError.js @@ -1,5 +1,5 @@ var createError = require('../../../lib/util/createError'), - expect = require('chai').expect; + expect = require('expect.js'); describe('createError', function () { From 35b0c49da59415a5f659594d7ebdc68c91ddaf78 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Wed, 10 Jul 2013 15:46:52 +0100 Subject: [PATCH 0125/1021] clarify cache docs --- packages/bower-registry-client/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index 399b59a37..bbcb5d14f 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -30,7 +30,7 @@ Available constructor options: Note that `force` and `offline` are mutually exclusive. -The cache will speedup operations such as `lookup` and `info`. +The cache will speedup operations such as `list`, `lookup` and `search`. Different operations may have different cache expiration times. From 0cdbe998cb06d7aff43ff414a4ef638f4fef55c6 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Wed, 10 Jul 2013 17:14:24 +0100 Subject: [PATCH 0126/1021] [tests] adds cache test --- packages/bower-registry-client/test/Client.js | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 8608da28e..9405dbd01 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -1,4 +1,5 @@ var RegistryClient = require('../Client'), + fs = require('fs'), expect = require('expect.js'), nock = require('nock'); @@ -100,6 +101,44 @@ describe('RegistryClient', function () { }); + describe('cache', function () { + + beforeEach(function () { + nock('https://bower.herokuapp.com:443') + .get('/packages/search/jquery') + .replyWithFile(200, __dirname + '/fixtures/search.json'); + + this.client = new RegistryClient({ + cache: __dirname + '/cache', + strictSsl: false + }); + + }); + + it('should fill cache', function (done) { + + var cacheDir = this.client._config.cache; + var host = 'bower.herokuapp.com'; + var method = 'search'; + var pkg = 'jquery'; + var self = this; + + var path = cacheDir + '/' + host + '/' + method + '/' + pkg; + + self.client.search(pkg, function (err, results) { + expect(err).to.be.null; + expect(results.length).to.eql(334); + + fs.exists(path, function (exists) { + expect(exists).to.be.true; + done(); + }); + }); + + }); + + it.skip('should read results from cache', function () { }); + }); }); From 9a6fdaa42bb295a40cc1720f79d33dddb54f1a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 10 Jul 2013 20:39:02 +0100 Subject: [PATCH 0127/1021] Do not remove invalid files, throw instead. --- packages/bower-config/lib/util/rc.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 9a5574213..33ecb09f7 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -3,7 +3,6 @@ var fs = require('graceful-fs'); var optimist = require('optimist'); var osenv = require('osenv'); var mout = require('mout'); -var rimraf = require('rimraf'); var paths = require('./paths'); var win = process.platform === 'win32'; @@ -26,15 +25,20 @@ function rc(name, defaults, cwd, argv) { } function parse(content, file) { + var error; + try { return JSON.parse(content); } catch (e) { - // If we got an error, remove the file if (file) { - try { - rimraf.sync(file); - } catch (e) {} + error = new Error('Unable to parse ' + file + ': ' + e.message); + } else { + error = new Error('Unable to parse rc config: ' + e.message); } + + error.details = content; + error.code = 'EMALFORMED'; + throw error; } return null; From 415e79b523f34f7564574d2c48261c7be51bc9cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 10 Jul 2013 20:39:30 +0100 Subject: [PATCH 0128/1021] Bump rc version. --- packages/bower-config/package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index c3c295714..eb66158b4 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.1.0-rc.2", + "version": "0.1.0-rc.3", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ @@ -22,8 +22,7 @@ "graceful-fs": "~1.2.2", "mout": "~0.6.0", "optimist": "~0.6.0", - "osenv": "0.0.3", - "rimraf": "~2.2.0" + "osenv": "0.0.3" }, "devDependencies": { "expect.js": "~0.2.0", From 2841942899ef3467ce8ec56a475399f62d85499a Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Thu, 11 Jul 2013 10:33:47 +0100 Subject: [PATCH 0129/1021] more cache related tests --- packages/bower-registry-client/test/Client.js | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 9405dbd01..520c66d4d 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -113,23 +113,28 @@ describe('RegistryClient', function () { strictSsl: false }); + this.cacheDir = this.client._config.cache; + this.host = 'bower.herokuapp.com'; + this.method = 'search'; + this.pkg = 'jquery'; + + this.path = this.cacheDir + '/' + this.host + '/' + this.method + '/' + this.pkg; }); - it('should fill cache', function (done) { + afterEach(function () { + //this.client.clearCache(); + }); - var cacheDir = this.client._config.cache; - var host = 'bower.herokuapp.com'; - var method = 'search'; - var pkg = 'jquery'; + it('should fill cache', function (done) { var self = this; - var path = cacheDir + '/' + host + '/' + method + '/' + pkg; - - self.client.search(pkg, function (err, results) { + // fill cache + self.client.search(self.pkg, function (err, results) { expect(err).to.be.null; expect(results.length).to.eql(334); - fs.exists(path, function (exists) { + // check for cache existance + fs.exists(self.path, function (exists) { expect(exists).to.be.true; done(); }); @@ -137,7 +142,20 @@ describe('RegistryClient', function () { }); - it.skip('should read results from cache', function () { }); + it('should read results from cache', function (done) { + var self = this; + + self.client.search(self.pkg, function (err, results) { + expect(err).to.be.null; + expect(results.length).to.eql(334); + + fs.exists(self.path, function (exists) { + expect(exists).to.be.true; + done(); + }); + }); + }); + }); }); From d3412e7de62a59549d2dffc785323c5e2ac86e25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 13 Jul 2013 22:35:23 +0100 Subject: [PATCH 0130/1021] Stupid typos, I was drunk when I did that. --- packages/bower-registry-client/Client.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js index f362c6f31..959f56eab 100644 --- a/packages/bower-registry-client/Client.js +++ b/packages/bower-registry-client/Client.js @@ -1,5 +1,6 @@ var os = require('os'); var path = require('path'); +var async = require('async'); var methods = require('./lib'); var Cache = require('./lib/util/Cache'); @@ -62,15 +63,19 @@ RegistryClient.prototype.list = methods.list; RegistryClient.prototype.register = methods.register; RegistryClient.prototype.clearCache = function (name, callback) { - this.lookup.clearCache.call(this, name, callback); - this.search.clearCache.call(this, name, callback); - this.list.clearCache.call(this, callback); + async.parallel([ + this.lookup.clearCache.bind(this, name), + this.search.clearCache.bind(this, name), + this.list.clearCache.bind(this) + ], callback); }; -RegistryClient.prototype.resetCache = function (name, callback) { - this.lookup.resetCache.call(this, name, callback); - this.search.resetCache.call(this, name, callback); - this.list.resetCache.call(this, callback); +RegistryClient.prototype.resetCache = function (name) { + this.lookup.resetCache.call(this, name); + this.search.resetCache.call(this, name); + this.list.resetCache.call(this); + + return this; }; RegistryClient.clearRuntimeCache = function () { From ff99fae9284f4b59a5797ec63b9b65d34626060a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 13 Jul 2013 23:07:19 +0100 Subject: [PATCH 0131/1021] Bump rc version. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 71bf9fa10..380191cee 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.1.0-rc.1", + "version": "0.1.0-rc.2", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From e423e9ffbaed05d5494da757e96c3ca6414c69ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 14 Jul 2013 17:21:17 +0100 Subject: [PATCH 0132/1021] Upgrade deps. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index eb66158b4..13a6308be 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -19,7 +19,7 @@ "node": ">=0.8.0" }, "dependencies": { - "graceful-fs": "~1.2.2", + "graceful-fs": "~2.0.0", "mout": "~0.6.0", "optimist": "~0.6.0", "osenv": "0.0.3" From a9e497f878d19a8d658b644ac7e0a914684af821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 14 Jul 2013 17:21:29 +0100 Subject: [PATCH 0133/1021] Upgrade deps. --- packages/bower-registry-client/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 380191cee..91f6700bc 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -19,10 +19,10 @@ }, "dependencies": { "async": "~0.2.8", - "graceful-fs": "~1.2.2", + "graceful-fs": "~2.0.0", "lru-cache": "~2.3.0", - "request": "~2.21.0", - "rimraf": "~2.1.4", + "request": "~2.22.0", + "rimraf": "~2.2.0", "mkdirp": "~0.3.5" }, "devDependencies": { From d2d959f45540a79cf667ae406ec4ec2962ef4da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 14 Jul 2013 17:21:45 +0100 Subject: [PATCH 0134/1021] Upgrade deps. --- packages/bower-json/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 3e4b81416..79467f95b 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -18,7 +18,7 @@ "node": ">=0.8.0" }, "dependencies": { - "graceful-fs": "~1.2.2" + "graceful-fs": "~2.0.0" }, "devDependencies": { "expect.js": "~0.2.0", From 7f997d4b59d00f14223347d909cd217b0e373994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 15 Jul 2013 00:30:08 +0100 Subject: [PATCH 0135/1021] Force camelCase. --- packages/bower-json/.jshintrc | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/bower-json/.jshintrc b/packages/bower-json/.jshintrc index 52c609091..eae6f9cf4 100644 --- a/packages/bower-json/.jshintrc +++ b/packages/bower-json/.jshintrc @@ -30,6 +30,7 @@ "quotmark": "single", "strict": false, "trailing": true, + "camelcase": true, "asi": false, "boss": true, From b3055067d8189017d67d3b16e0e2795f5eb721e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 15 Jul 2013 00:30:18 +0100 Subject: [PATCH 0136/1021] Force camelCase. --- packages/bower-registry-client/.jshintrc | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/bower-registry-client/.jshintrc b/packages/bower-registry-client/.jshintrc index 1669bec7f..50467983f 100644 --- a/packages/bower-registry-client/.jshintrc +++ b/packages/bower-registry-client/.jshintrc @@ -30,6 +30,7 @@ "quotmark": "single", "strict": false, "trailing": true, + "camelcase": true, "asi": false, "boss": true, From 554ee0126357645e2562cea8fccf9189fd77aa25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 15 Jul 2013 00:30:27 +0100 Subject: [PATCH 0137/1021] Force camelCase. --- packages/bower-config/.jshintrc | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/bower-config/.jshintrc b/packages/bower-config/.jshintrc index 52c609091..eae6f9cf4 100644 --- a/packages/bower-config/.jshintrc +++ b/packages/bower-config/.jshintrc @@ -30,6 +30,7 @@ "quotmark": "single", "strict": false, "trailing": true, + "camelcase": true, "asi": false, "boss": true, From d9df06644e2a2e96e8c0d7e9ab32fba77ee56d29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 15 Jul 2013 00:30:44 +0100 Subject: [PATCH 0138/1021] Initial commit. --- packages/bower-endpoint-parser/.editorconfig | 8 ++ packages/bower-endpoint-parser/.gitignore | 2 + packages/bower-endpoint-parser/.jshintrc | 61 +++++++++++ packages/bower-endpoint-parser/.travis.yml | 4 + packages/bower-endpoint-parser/LICENSE | 19 ++++ packages/bower-endpoint-parser/README.md | 100 +++++++++++++++++++ packages/bower-endpoint-parser/index.js | 88 ++++++++++++++++ packages/bower-endpoint-parser/package.json | 27 +++++ packages/bower-endpoint-parser/test/test.js | 1 + 9 files changed, 310 insertions(+) create mode 100644 packages/bower-endpoint-parser/.editorconfig create mode 100644 packages/bower-endpoint-parser/.gitignore create mode 100644 packages/bower-endpoint-parser/.jshintrc create mode 100644 packages/bower-endpoint-parser/.travis.yml create mode 100644 packages/bower-endpoint-parser/LICENSE create mode 100644 packages/bower-endpoint-parser/README.md create mode 100644 packages/bower-endpoint-parser/index.js create mode 100644 packages/bower-endpoint-parser/package.json create mode 100644 packages/bower-endpoint-parser/test/test.js diff --git a/packages/bower-endpoint-parser/.editorconfig b/packages/bower-endpoint-parser/.editorconfig new file mode 100644 index 000000000..ba4428907 --- /dev/null +++ b/packages/bower-endpoint-parser/.editorconfig @@ -0,0 +1,8 @@ +root = true + +[*] + +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 diff --git a/packages/bower-endpoint-parser/.gitignore b/packages/bower-endpoint-parser/.gitignore new file mode 100644 index 000000000..1b6c50d99 --- /dev/null +++ b/packages/bower-endpoint-parser/.gitignore @@ -0,0 +1,2 @@ +/node_modules +/npm-debug.* \ No newline at end of file diff --git a/packages/bower-endpoint-parser/.jshintrc b/packages/bower-endpoint-parser/.jshintrc new file mode 100644 index 000000000..50467983f --- /dev/null +++ b/packages/bower-endpoint-parser/.jshintrc @@ -0,0 +1,61 @@ +{ + "predef": [ + "console", + "describe", + "it", + "after", + "afterEach", + "before", + "beforeEach" + ], + + "indent": 4, + "node": true, + "devel": true, + + "bitwise": false, + "curly": false, + "eqeqeq": true, + "forin": false, + "immed": true, + "latedef": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": true, + "plusplus": false, + "regexp": false, + "undef": true, + "unused": true, + "quotmark": "single", + "strict": false, + "trailing": true, + "camelcase": true, + + "asi": false, + "boss": true, + "debug": false, + "eqnull": true, + "esnext": false, + "evil": false, + "expr": true, + "funcscope": false, + "globalstrict": false, + "iterator": false, + "lastsemic": false, + "laxbreak": true, + "laxcomma": false, + "loopfunc": true, + "multistr": false, + "onecase": true, + "regexdash": false, + "scripturl": false, + "smarttabs": false, + "shadow": false, + "sub": false, + "supernew": true, + "validthis": false, + + "nomen": false, + "white": true +} diff --git a/packages/bower-endpoint-parser/.travis.yml b/packages/bower-endpoint-parser/.travis.yml new file mode 100644 index 000000000..df63076b8 --- /dev/null +++ b/packages/bower-endpoint-parser/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.10" + - "0.8" diff --git a/packages/bower-endpoint-parser/LICENSE b/packages/bower-endpoint-parser/LICENSE new file mode 100644 index 000000000..13e8246fd --- /dev/null +++ b/packages/bower-endpoint-parser/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012 Twitter and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/bower-endpoint-parser/README.md b/packages/bower-endpoint-parser/README.md new file mode 100644 index 000000000..98cb9e4f9 --- /dev/null +++ b/packages/bower-endpoint-parser/README.md @@ -0,0 +1,100 @@ +# bower-endpoint-parser [![Build Status](https://secure.travis-ci.org/bower/endpoint-parser.png?branch=master)](http://travis-ci.org/bower/endpoint-parser) + +Little module that helps with endpoints parsing. + + +## API + +### .decompose(endpoint) + +Decomposes a endpoint into `name`, `source` and `target`. + +```js +var endpointParser = require('bower-endpoint-parser'); + +endpointParser.decompose('jquery#~2.0.0'); +// { name: '', source: 'jquery', target: '~2.0.0' } + +endpointParser.decompose('backbone=backbone-amd#~1.0.0'); +// { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' } + +endpointParser.decompose('http://twitter.github.io/bootstrap/assets/bootstrap.zip'); +// { name: '', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' } + +endpointParser.decompose('bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip'); +// { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' } +``` + +### .compose(decEndpoint) + +Inverse of `compose()`. +Takes a decomposed endpoint and composes it back into a string. + +```js +var endpointParser = require('bower-endpoint-parser'); + +endpointParser.compose({ name: '', source: 'jquery', target: '~2.0.0' }); +// jquery=~2.0.0 + +endpointParser.compose({ name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }); +// backbone=backbone-amd#~1.0.0 + +endpointParser.compose({ name: '', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }); +// http://twitter.github.io/bootstrap/assets/bootstrap.zip + +endpointParser.compose({ name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }); +// bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip +``` + +### .json2decomposed(key, value) + +Similar to `decompose()` but specially designed to be used when parsing `bower.json` dependencies. +For instance, in a `bower.json` like this: + +```js +{ + name: "foo", + "version": "0.1.0", + "dependencies": { + "jquery": "~1.9.1", + "backbone": "backbone-amd#~1.0.0", + "bootstrap": "http://twitter.github.io/bootstrap/assets/bootstrap" + } +} +``` + +You would call `json2decomposed` like so: + +``` +endpointParser.json2decomposed('jquery', '~1.9.1'); +// { name: 'jquery', source: 'jquery', target: '~1.9.1' } + +endpointParser.json2decomposed('backbone', 'backbone-amd#~1.0.0'); +// { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' } + +endpointParser.json2decomposed('bootstrap', 'http://twitter.github.io/bootstrap/assets/bootstrap'); +// { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' } +``` + +### .decomposed2json(decEndpoint) + +Inverse of `json2decomposed()`. +Takes a decomposed endpoint and composes it to an object. + +```js +var endpointParser = require('bower-endpoint-parser'); + +endpointParser.decomposed2json({ name: '', source: 'jquery', target: '~2.0.0' }); +// { jquery: '~2.0.0' } + +endpointParser.decomposed2json({ name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }); +// { backbone: 'backbone-amd#~2.0.0' } + +endpointParser.decomposed2json({ name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }); +// { backbone: 'http://twitter.github.io/bootstrap/assets/bootstrap' } +``` + + +## License + +Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). diff --git a/packages/bower-endpoint-parser/index.js b/packages/bower-endpoint-parser/index.js new file mode 100644 index 000000000..d4c83eed9 --- /dev/null +++ b/packages/bower-endpoint-parser/index.js @@ -0,0 +1,88 @@ +function decompose(endpoint) { + var regExp = /^(?:([\w\-]|(?:[\w\.\-]+[\w\-])?)=)?([^\|#]+)(?:#(.*))?$/; + var matches = endpoint.match(regExp); + var target; + var error; + + if (!matches) { + error = new Error('Invalid endpoint: ' + endpoint); + error.code = 'EINVEND'; + throw error; + } + + target = matches[3]; + + return { + name: matches[1] || '', + source: matches[2], + target: !target || target === 'latest' ? '*' : target + }; +} + +function compose(decEndpoint) { + var composed = ''; + + if (decEndpoint.name) { + composed += decEndpoint.name + '='; + } + + composed += decEndpoint.source; + + if (!isWildcard(decEndpoint.target)) { + composed += '#' + decEndpoint.target; + } + + return composed; +} + +function json2decomposed(key, value) { + var endpoint = key + '='; + var split = value.split('#'); + + // If # was found, the source was specified + if (split.length > 1) { + endpoint += split[0] + '#' + split[1]; + // If value has a /, it's probably a source + } else if (value.indexOf('/') !== -1) { + endpoint += value + '#*'; + // Otherwise use the key as the source + } else { + endpoint += key + '#' + split[0]; + } + + return decompose(endpoint); +} + +function decomposed2json(decEndpoint) { + var error; + var key = decEndpoint.name; + var value = ''; + var ret = {}; + + if (!key) { + error = new Error('Decomposed endpoint must have a name'); + error.code = 'EINVEND'; + throw error; + } + + if (decEndpoint.source !== decEndpoint.name) { + value += decEndpoint.source + '#'; + } + + if (!isWildcard(decEndpoint.target)) { + value += decEndpoint.target; + } + + ret[key] = value; + + return ret; +} + +function isWildcard(target) { + return !target || target === '*' || target === 'latest'; +} + +module.exports.decompose = decompose; +module.exports.compose = compose; +module.exports.json2decomposed = json2decomposed; +module.exports.decomposed2json = decomposed2json; diff --git a/packages/bower-endpoint-parser/package.json b/packages/bower-endpoint-parser/package.json new file mode 100644 index 000000000..f80795c64 --- /dev/null +++ b/packages/bower-endpoint-parser/package.json @@ -0,0 +1,27 @@ +{ + "name": "bower-endpoint-parser", + "version": "0.1.0-rc.1", + "description": "Little module that helps with endpoints parsing.", + "author": "Twitter", + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/bower/endpoint-parser/blob/master/LICENSE" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/bower/endpoint-parser.git" + }, + "main": "index.js", + "engines": { + "node": ">=0.8.0" + }, + "devDependencies": { + "expect.js": "~0.2.0", + "mocha": "~1.12.0" + }, + "scripts": { + "test": "npm test" + } +} diff --git a/packages/bower-endpoint-parser/test/test.js b/packages/bower-endpoint-parser/test/test.js new file mode 100644 index 000000000..0ffdd02fc --- /dev/null +++ b/packages/bower-endpoint-parser/test/test.js @@ -0,0 +1 @@ +// TODO \ No newline at end of file From aa76d492346dbdfe2cb5f680b97671fd8a41254f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 15 Jul 2013 00:33:34 +0100 Subject: [PATCH 0139/1021] Improve README. --- packages/bower-endpoint-parser/README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/bower-endpoint-parser/README.md b/packages/bower-endpoint-parser/README.md index 98cb9e4f9..2946a321f 100644 --- a/packages/bower-endpoint-parser/README.md +++ b/packages/bower-endpoint-parser/README.md @@ -27,7 +27,7 @@ endpointParser.decompose('bootstrap=http://twitter.github.io/bootstrap/assets/bo ### .compose(decEndpoint) -Inverse of `compose()`. +Inverse of `decompose()`. Takes a decomposed endpoint and composes it back into a string. ```js @@ -65,7 +65,7 @@ For instance, in a `bower.json` like this: You would call `json2decomposed` like so: -``` +```js endpointParser.json2decomposed('jquery', '~1.9.1'); // { name: 'jquery', source: 'jquery', target: '~1.9.1' } @@ -79,21 +79,23 @@ endpointParser.json2decomposed('bootstrap', 'http://twitter.github.io/bootstrap/ ### .decomposed2json(decEndpoint) Inverse of `json2decomposed()`. -Takes a decomposed endpoint and composes it to an object. +Takes a decomposed endpoint and composes it to be saved to `bower.json`. ```js var endpointParser = require('bower-endpoint-parser'); -endpointParser.decomposed2json({ name: '', source: 'jquery', target: '~2.0.0' }); +endpointParser.decomposed2json({ name: 'jquery', source: 'jquery', target: '~2.0.0' }); // { jquery: '~2.0.0' } endpointParser.decomposed2json({ name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }); // { backbone: 'backbone-amd#~2.0.0' } endpointParser.decomposed2json({ name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }); -// { backbone: 'http://twitter.github.io/bootstrap/assets/bootstrap' } +// { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' } ``` +This function throws an exception if the `name` from the decomposed endpoint is empty. + ## License From 4366d6a8c7248b4feecfab249e39c315d84efb33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 15 Jul 2013 00:35:59 +0100 Subject: [PATCH 0140/1021] Fix test script, wtf! --- packages/bower-endpoint-parser/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-endpoint-parser/package.json b/packages/bower-endpoint-parser/package.json index f80795c64..7c77b17da 100644 --- a/packages/bower-endpoint-parser/package.json +++ b/packages/bower-endpoint-parser/package.json @@ -22,6 +22,6 @@ "mocha": "~1.12.0" }, "scripts": { - "test": "npm test" + "test": "mocha -R spec" } } From aa4ebb07f8b50b9f9738f3a195b19dfb173dbb2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 15 Jul 2013 00:36:56 +0100 Subject: [PATCH 0141/1021] Fix title. --- packages/bower-endpoint-parser/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-endpoint-parser/README.md b/packages/bower-endpoint-parser/README.md index 2946a321f..bb1fb9ee8 100644 --- a/packages/bower-endpoint-parser/README.md +++ b/packages/bower-endpoint-parser/README.md @@ -1,4 +1,4 @@ -# bower-endpoint-parser [![Build Status](https://secure.travis-ci.org/bower/endpoint-parser.png?branch=master)](http://travis-ci.org/bower/endpoint-parser) +# endpoint-parser [![Build Status](https://secure.travis-ci.org/bower/endpoint-parser.png?branch=master)](http://travis-ci.org/bower/endpoint-parser) Little module that helps with endpoints parsing. From 16e7872a8225f267ab4089ac01afe2f8b42b5b2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 15 Jul 2013 00:42:47 +0100 Subject: [PATCH 0142/1021] Typo. --- packages/bower-endpoint-parser/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-endpoint-parser/README.md b/packages/bower-endpoint-parser/README.md index bb1fb9ee8..2d42451c4 100644 --- a/packages/bower-endpoint-parser/README.md +++ b/packages/bower-endpoint-parser/README.md @@ -34,7 +34,7 @@ Takes a decomposed endpoint and composes it back into a string. var endpointParser = require('bower-endpoint-parser'); endpointParser.compose({ name: '', source: 'jquery', target: '~2.0.0' }); -// jquery=~2.0.0 +// jquery#~2.0.0 endpointParser.compose({ name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }); // backbone=backbone-amd#~1.0.0 From 71e1a8666d625d72c8d8a26fb2d6feb5b6aec92e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 15 Jul 2013 22:29:23 +0100 Subject: [PATCH 0143/1021] Add tests and made some changes. --- packages/bower-endpoint-parser/index.js | 13 +- packages/bower-endpoint-parser/package.json | 3 +- packages/bower-endpoint-parser/test/test.js | 127 +++++++++++++++++++- 3 files changed, 137 insertions(+), 6 deletions(-) diff --git a/packages/bower-endpoint-parser/index.js b/packages/bower-endpoint-parser/index.js index d4c83eed9..ce9981d74 100644 --- a/packages/bower-endpoint-parser/index.js +++ b/packages/bower-endpoint-parser/index.js @@ -41,7 +41,7 @@ function json2decomposed(key, value) { // If # was found, the source was specified if (split.length > 1) { - endpoint += split[0] + '#' + split[1]; + endpoint += (split[0] || key) + '#' + split[1]; // If value has a /, it's probably a source } else if (value.indexOf('/') !== -1) { endpoint += value + '#*'; @@ -65,12 +65,17 @@ function decomposed2json(decEndpoint) { throw error; } + // Add source only if different than the name if (decEndpoint.source !== decEndpoint.name) { - value += decEndpoint.source + '#'; + value += decEndpoint.source; } - if (!isWildcard(decEndpoint.target)) { - value += decEndpoint.target; + // If value is empty, we append the target always + if (!value) { + value += isWildcard(decEndpoint.target) ? '*' : decEndpoint.target; + // Otherwise append only if not a wildcard + } else if (!isWildcard(decEndpoint.target)) { + value += '#' + decEndpoint.target; } ret[key] = value; diff --git a/packages/bower-endpoint-parser/package.json b/packages/bower-endpoint-parser/package.json index 7c77b17da..30887522f 100644 --- a/packages/bower-endpoint-parser/package.json +++ b/packages/bower-endpoint-parser/package.json @@ -19,7 +19,8 @@ }, "devDependencies": { "expect.js": "~0.2.0", - "mocha": "~1.12.0" + "mocha": "~1.12.0", + "mout": "~0.6.0" }, "scripts": { "test": "mocha -R spec" diff --git a/packages/bower-endpoint-parser/test/test.js b/packages/bower-endpoint-parser/test/test.js index 0ffdd02fc..c0335f4eb 100644 --- a/packages/bower-endpoint-parser/test/test.js +++ b/packages/bower-endpoint-parser/test/test.js @@ -1 +1,126 @@ -// TODO \ No newline at end of file +var expect = require('expect.js'); +var mout = require('mout'); +var endpointParser = require('../'); + +describe('endpoint-parser', function () { + describe('.decompose', function () { + it('should decompose endpoints correctly', function () { + var suite = { + 'jquery#~2.0.0': { name: '', source: 'jquery', target: '~2.0.0' }, + 'jquery#*': { name: '', source: 'jquery', target: '*' }, + 'jquery#latest': { name: '', source: 'jquery', target: '*' }, + 'jquery#3dc50c62fe2d2d01afc58e7ad42236a35acff4d8': { name: '', source: 'jquery', target: '3dc50c62fe2d2d01afc58e7ad42236a35acff4d8' }, + 'jquery#master': { name: '', source: 'jquery', target: 'master' }, + 'backbone=backbone-amd#~1.0.0': { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }, + 'backbone=backbone-amd#latest': { name: 'backbone', source: 'backbone-amd', target: '*' }, + 'backbone=backbone-amd#*': { name: 'backbone', source: 'backbone-amd', target: '*' }, + 'http://twitter.github.io/bootstrap/assets/bootstrap.zip': { name: '', source: 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', target: '*' }, + 'bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip': { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', target: '*' }, + 'bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip#latest': { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', target: '*' } + }; + + mout.object.forOwn(suite, function (decEndpoint, endpoint) { + expect(endpointParser.decompose(endpoint)).to.eql(decEndpoint); + }); + }); + }); + + describe('.compose', function () { + it('should compose endpoints correctly', function () { + var suite = { + 'jquery#~2.0.0': { name: '', source: 'jquery', target: '~2.0.0' }, + 'jquery': [{ name: '', source: 'jquery', target: '*' }, { name: '', source: 'jquery', target: 'latest' }, { name: '', source: 'jquery', target: '' }], + 'jquery#3dc50c62fe2d2d01afc58e7ad42236a35acff4d8': { name: '', source: 'jquery', target: '3dc50c62fe2d2d01afc58e7ad42236a35acff4d8' }, + 'jquery#master': { name: '', source: 'jquery', target: 'master' }, + 'backbone=backbone-amd#~1.0.0': { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }, + 'backbone=backbone-amd': [{ name: 'backbone', source: 'backbone-amd', target: '*' }, { name: 'backbone', source: 'backbone-amd', target: '*' }, { name: 'backbone', source: 'backbone-amd', target: '' }], + 'http://twitter.github.io/bootstrap/assets/bootstrap.zip': { name: '', source: 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', target: '*' }, + 'bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip': { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', target: '*' } + }; + + mout.object.forOwn(suite, function (decEndpoints, endpoint) { + decEndpoints = mout.lang.toArray(decEndpoints); + decEndpoints.forEach(function (decEndpoint) { + expect(endpointParser.compose(decEndpoint)).to.equal(endpoint); + }); + }); + }); + }); + + describe('.json2decomposed', function () { + it('should decompose json endpoints correctly', function () { + var dependencies = { + jquery: '~1.9.1', + foo: 'latest', + bar: '*', + baz: '#~0.2.0', + backbone: 'backbone-amd#~1.0.0', + backbone2: 'backbone=backbone-amd#~1.0.0', + bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap', + bootstrap2: 'http://twitter.github.io/bootstrap/assets/bootstrap#*' + + }; + var expected = [ + { name: 'jquery', source: 'jquery', target: '~1.9.1' }, + { name: 'foo', source: 'foo', target: '*' }, + { name: 'bar', source: 'bar', target: '*' }, + { name: 'baz', source: 'baz', target: '~0.2.0' }, + { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }, + { name: 'backbone2', source: 'backbone=backbone-amd', target: '~1.0.0' }, + { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }, + { name: 'bootstrap2', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' } + ]; + var x = 0; + + mout.object.forOwn(dependencies, function (value, key) { + expect(endpointParser.json2decomposed(key, value)).to.eql(expected[x]); + x += 1; + }); + }); + }); + + describe('.decomposed2json', function () { + it('should compose endpoints to json correctly', function () { + var decEndpoints = [ + { name: 'jquery', source: 'jquery', target: '~1.9.1' }, + { name: 'foo', source: 'foo', target: 'latest' }, + { name: 'bar', source: 'bar', target: '*' }, + { name: 'baz', source: 'baz', target: '' }, + { name: 'jqueryx', source: 'jquery', target: '~1.9.1' }, + { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }, + { name: 'backbone', source: 'backbone=backbone-amd', target: '~1.0.0' }, + { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '' }, + { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' } + ]; + var expected = [ + { jquery: '~1.9.1' }, + { foo: '*' }, + { bar: '*' }, + { baz: '*' }, + { jqueryx: 'jquery#~1.9.1' }, + { backbone: 'backbone-amd#~1.0.0' }, + { backbone : 'backbone=backbone-amd#~1.0.0' }, + { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' }, + { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' } + ]; + var x = 0; + + decEndpoints.forEach(function (decEndpoint) { + expect(endpointParser.decomposed2json(decEndpoint)).to.eql(expected[x]); + x += 1; + }); + }); + + it('should throw an error if name is empty', function () { + try { + endpointParser.decomposed2json({ name: '', source: 'jquery', target: '*' }); + } catch (e) { + expect(e.code).to.equal('EINVEND'); + expect(e.message).to.contain('must have a name'); + return; + } + + throw new Error('Should have failed'); + }); + }); +}); \ No newline at end of file From a006bfeb24991069c2047f4a95587731f8e82ba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 16 Jul 2013 07:09:20 +0100 Subject: [PATCH 0144/1021] Fix git@ endpoints not being interpreted as sources. --- packages/bower-endpoint-parser/index.js | 8 ++++++-- packages/bower-endpoint-parser/test/test.js | 19 +++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/packages/bower-endpoint-parser/index.js b/packages/bower-endpoint-parser/index.js index ce9981d74..a26437b49 100644 --- a/packages/bower-endpoint-parser/index.js +++ b/packages/bower-endpoint-parser/index.js @@ -42,8 +42,8 @@ function json2decomposed(key, value) { // If # was found, the source was specified if (split.length > 1) { endpoint += (split[0] || key) + '#' + split[1]; - // If value has a /, it's probably a source - } else if (value.indexOf('/') !== -1) { + // Check if value looks like a source + } else if (isSource(value)) { endpoint += value + '#*'; // Otherwise use the key as the source } else { @@ -87,6 +87,10 @@ function isWildcard(target) { return !target || target === '*' || target === 'latest'; } +function isSource(value) { + return value.indexOf('/') !== -1 || value.indexOf('@') !== -1; +} + module.exports.decompose = decompose; module.exports.compose = compose; module.exports.json2decomposed = json2decomposed; diff --git a/packages/bower-endpoint-parser/test/test.js b/packages/bower-endpoint-parser/test/test.js index c0335f4eb..87d8059d5 100644 --- a/packages/bower-endpoint-parser/test/test.js +++ b/packages/bower-endpoint-parser/test/test.js @@ -57,8 +57,9 @@ describe('endpoint-parser', function () { backbone: 'backbone-amd#~1.0.0', backbone2: 'backbone=backbone-amd#~1.0.0', bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap', - bootstrap2: 'http://twitter.github.io/bootstrap/assets/bootstrap#*' - + bootstrap2: 'http://twitter.github.io/bootstrap/assets/bootstrap#*', + ssh: 'git@example.com', + git: 'git://example.com' }; var expected = [ { name: 'jquery', source: 'jquery', target: '~1.9.1' }, @@ -68,7 +69,9 @@ describe('endpoint-parser', function () { { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }, { name: 'backbone2', source: 'backbone=backbone-amd', target: '~1.0.0' }, { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }, - { name: 'bootstrap2', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' } + { name: 'bootstrap2', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }, + { name: 'ssh', source: 'git@example.com', target: '*' }, + { name: 'git', source: 'git://example.com', target: '*' } ]; var x = 0; @@ -90,7 +93,9 @@ describe('endpoint-parser', function () { { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }, { name: 'backbone', source: 'backbone=backbone-amd', target: '~1.0.0' }, { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '' }, - { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' } + { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }, + { name: 'ssh', source: 'git@example.com', target: '*' }, + { name: 'git', source: 'git://example.com', target: '*' } ]; var expected = [ { jquery: '~1.9.1' }, @@ -101,7 +106,9 @@ describe('endpoint-parser', function () { { backbone: 'backbone-amd#~1.0.0' }, { backbone : 'backbone=backbone-amd#~1.0.0' }, { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' }, - { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' } + { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' }, + { ssh: 'git@example.com' }, + { git: 'git://example.com' } ]; var x = 0; @@ -123,4 +130,4 @@ describe('endpoint-parser', function () { throw new Error('Should have failed'); }); }); -}); \ No newline at end of file +}); From cddba641511424829aef75c53a07715ae911f67b Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Tue, 16 Jul 2013 16:10:03 +0100 Subject: [PATCH 0145/1021] call next instead of done --- packages/bower-registry-client/test/Client.js | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 520c66d4d..26205d4ed 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -125,7 +125,7 @@ describe('RegistryClient', function () { //this.client.clearCache(); }); - it('should fill cache', function (done) { + it('should fill cache', function (next) { var self = this; // fill cache @@ -136,13 +136,13 @@ describe('RegistryClient', function () { // check for cache existance fs.exists(self.path, function (exists) { expect(exists).to.be.true; - done(); + next(); }); }); }); - it('should read results from cache', function (done) { + it('should read results from cache', function (next) { var self = this; self.client.search(self.pkg, function (err, results) { @@ -151,7 +151,7 @@ describe('RegistryClient', function () { fs.exists(self.path, function (exists) { expect(exists).to.be.true; - done(); + next(); }); }); }); @@ -213,30 +213,30 @@ describe('RegistryClient', function () { this.pkgUrl = 'git://github.com/test-ba/test-ba.git'; }); - it('should not return an error', function (done) { + it('should not return an error', function (next) { this.registry.register(this.pkg, this.pkgUrl, function (err) { expect(err).to.be.null; - done(); + next(); }); }); - it('should return entry name', function (done) { + it('should return entry name', function (next) { var self = this; this.registry.register(this.pkg, this.pkgUrl, function (err, entry) { expect(err).to.be.null; expect(entry.name).to.eql(self.pkg); - done(); + next(); }); }); - it('should return entry url', function (done) { + it('should return entry url', function (next) { var self = this; this.registry.register(this.pkg, this.pkgUrl, function (err, entry) { expect(err).to.be.null; expect(entry.url).to.eql(self.pkgUrl); - done(); + next(); }); }); @@ -266,34 +266,34 @@ describe('RegistryClient', function () { this.pkgUrl = 'git://github.com/components/jquery.git'; }); - it('should not return an error', function (done) { + it('should not return an error', function (next) { this.registry.search(this.pkg, function (err) { expect(err).to.be.null; - done(); + next(); }); }); - it('should return entry name', function (done) { + it('should return entry name', function (next) { var self = this; this.registry.search(this.pkg, function (err, results) { results.forEach(function (entry) { if (entry.name === self.pkg) { expect(entry.name).to.eql(self.pkg); - done(); + next(); } }); }); }); - it('should return entry url', function (done) { + it('should return entry url', function (next) { var self = this; this.registry.search(this.pkg, function (err, results) { results.forEach(function (entry) { if (entry.name === self.pkg) { expect(entry.url).to.eql(self.pkgUrl); - done(); + next(); } }); }); From b17beaccf1007ddc4b17454129b6342c9d67bf22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 16 Jul 2013 19:52:24 +0100 Subject: [PATCH 0146/1021] Add timeout config. --- packages/bower-config/lib/Config.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index 5c142aff0..a03d2aca5 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -5,6 +5,7 @@ var rc = require('./util/rc'); var paths = require('./util/paths'); // Guess proxy defined in the env +/*jshint camelcase: false*/ var proxy = process.env.HTTP_PROXY || process.env.http_proxy || null; @@ -14,6 +15,7 @@ var httpsProxy = process.env.HTTPS_PROXY || process.env.HTTP_PROXY || process.env.http_proxy || null; +/*jshint camelcase: true*/ //------------- @@ -33,6 +35,7 @@ Config.prototype.load = function () { 'tmp': os.tmpdir ? os.tmpdir() : os.tmpDir(), 'proxy': proxy, 'https-proxy': httpsProxy, + 'timeout': 60000, 'ca': null, 'strict-ssl': true, 'user-agent': 'node/' + process.version + ' ' + process.platform + ' ' + process.arch, @@ -64,21 +67,21 @@ Config.prototype.load = function () { }; Config.prototype.get = function (key) { - + // TODO }; Config.prototype.set = function (key, value) { - + // TODO return this; }; Config.prototype.del = function (key, value) { - + // TODO return this; }; Config.prototype.save = function (where, callback) { - + // TODO }; Config.prototype.toObject = function () { From 87569617ae574bb1c6be87b573ff2573ac6504de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 16 Jul 2013 19:52:32 +0100 Subject: [PATCH 0147/1021] Add spec link. --- packages/bower-config/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index 9914dc5f3..7e3f39f43 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -1,6 +1,7 @@ # bower-config [![Build Status](https://secure.travis-ci.org/bower/config.png?branch=master)](http://travis-ci.org/bower/config) The Bower config reader and writer. +The config spec can be read [here](https://docs.google.com/document/d/1APq7oA9tNao1UYWyOm8dKqlRP2blVkROYLZ2fLIjtWc/). ## Usage From 430a2ea2f64e0a7f4386411437f1803ebe30b474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 16 Jul 2013 19:52:46 +0100 Subject: [PATCH 0148/1021] Bump rc. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 13a6308be..94c8dbcde 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.1.0-rc.3", + "version": "0.1.0-rc.4", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 6f7f10b2f7ec2bf0c117ceb4a766b286793689d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Tue, 16 Jul 2013 20:03:16 +0100 Subject: [PATCH 0149/1021] Update README.md --- packages/bower-config/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index 7e3f39f43..96d81ed3e 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -1,6 +1,6 @@ # bower-config [![Build Status](https://secure.travis-ci.org/bower/config.png?branch=master)](http://travis-ci.org/bower/config) -The Bower config reader and writer. +The Bower config reader and writer. The config spec can be read [here](https://docs.google.com/document/d/1APq7oA9tNao1UYWyOm8dKqlRP2blVkROYLZ2fLIjtWc/). From 12c90bae048444ffc103d36155d7fe811ab603d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Thu, 18 Jul 2013 08:13:10 +0100 Subject: [PATCH 0150/1021] Another README typo. --- packages/bower-endpoint-parser/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-endpoint-parser/README.md b/packages/bower-endpoint-parser/README.md index 2d42451c4..c996c3279 100644 --- a/packages/bower-endpoint-parser/README.md +++ b/packages/bower-endpoint-parser/README.md @@ -53,7 +53,7 @@ For instance, in a `bower.json` like this: ```js { - name: "foo", + "name": "foo", "version": "0.1.0", "dependencies": { "jquery": "~1.9.1", From 4a94858ed1ae16f3a98780e2ef7b0d0aead0abfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Thu, 18 Jul 2013 19:29:11 +0100 Subject: [PATCH 0151/1021] Update editorconfig. --- packages/bower-endpoint-parser/.editorconfig | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/bower-endpoint-parser/.editorconfig b/packages/bower-endpoint-parser/.editorconfig index ba4428907..779f99a12 100644 --- a/packages/bower-endpoint-parser/.editorconfig +++ b/packages/bower-endpoint-parser/.editorconfig @@ -1,8 +1,12 @@ root = true [*] - -end_of_line = lf -insert_final_newline = true indent_style = space indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false From 147e24d835a6c13690239be55380f064c7f8a759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Thu, 18 Jul 2013 19:29:22 +0100 Subject: [PATCH 0152/1021] Update editorconfig. --- packages/bower-config/.editorconfig | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/bower-config/.editorconfig b/packages/bower-config/.editorconfig index ba4428907..779f99a12 100644 --- a/packages/bower-config/.editorconfig +++ b/packages/bower-config/.editorconfig @@ -1,8 +1,12 @@ root = true [*] - -end_of_line = lf -insert_final_newline = true indent_style = space indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false From f55e6138a5b109f27aa4ba3c69caa93114bf8137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Thu, 18 Jul 2013 19:29:30 +0100 Subject: [PATCH 0153/1021] Remove git config. --- packages/bower-config/lib/Config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index a03d2aca5..e8e1d1359 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -39,7 +39,6 @@ Config.prototype.load = function () { 'ca': null, 'strict-ssl': true, 'user-agent': 'node/' + process.version + ' ' + process.platform + ' ' + process.arch, - 'git': 'git', 'color': true, 'interactive': false, 'storage': { From 4e8c9078f71367cffb997cdd1177c09895453aa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Thu, 18 Jul 2013 19:30:13 +0100 Subject: [PATCH 0154/1021] Update editorconfig. --- packages/bower-registry-client/.editorconfig | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/bower-registry-client/.editorconfig b/packages/bower-registry-client/.editorconfig index ba4428907..779f99a12 100644 --- a/packages/bower-registry-client/.editorconfig +++ b/packages/bower-registry-client/.editorconfig @@ -1,8 +1,12 @@ root = true [*] - -end_of_line = lf -insert_final_newline = true indent_style = space indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false From 8d3aff5ff1cc18d03b528ca8f50a950db68db475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Thu, 18 Jul 2013 19:30:27 +0100 Subject: [PATCH 0155/1021] Update editorconfig. --- packages/bower-json/.editorconfig | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/bower-json/.editorconfig b/packages/bower-json/.editorconfig index ba4428907..779f99a12 100644 --- a/packages/bower-json/.editorconfig +++ b/packages/bower-json/.editorconfig @@ -1,8 +1,12 @@ root = true [*] - -end_of_line = lf -insert_final_newline = true indent_style = space indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false From 882bf7b020460f66804634de7441c72306afd198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Thu, 18 Jul 2013 19:31:52 +0100 Subject: [PATCH 0156/1021] Bump rc version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 94c8dbcde..ffbba986a 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.1.0-rc.4", + "version": "0.1.0-rc.5", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 08c9e2dde3f76e4db418473acb64d206042758db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 20 Jul 2013 19:48:42 +0100 Subject: [PATCH 0157/1021] CS. --- packages/bower-registry-client/test/Client.js | 67 +++++++------------ .../bower-registry-client/test/core/index.js | 4 -- .../bower-registry-client/test/core/list.js | 4 -- .../bower-registry-client/test/core/lookup.js | 4 -- .../test/core/register.js | 4 -- .../bower-registry-client/test/core/search.js | 4 -- .../test/core/util/Cache.js | 7 -- 7 files changed, 23 insertions(+), 71 deletions(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 26205d4ed..d7bcf2885 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -4,7 +4,6 @@ var RegistryClient = require('../Client'), nock = require('nock'); describe('RegistryClient', function () { - beforeEach(function () { this.uri = 'https://bower.herokuapp.com'; this.timeoutVal = 5000; @@ -19,9 +18,7 @@ describe('RegistryClient', function () { }); describe('Constructor', function () { - describe('instantiating a client', function () { - it('should provide an instance of RegistryClient', function () { expect(this.registry instanceof RegistryClient).to.be.ok; }); @@ -51,9 +48,8 @@ describe('RegistryClient', function () { }); it('should set default strictSsl config', function () { - expect(this.registry._config.strictSsl).to.be.false; + expect(this.registry._config.strictSsl).to.be(false); }); - }); it('should have a lookup prototype method', function () { @@ -83,26 +79,21 @@ describe('RegistryClient', function () { it('should have a clearRuntimeCache static method', function () { expect(RegistryClient).to.have.property('clearRuntimeCache'); }); - }); describe('instantiating a client with custom options', function () { - describe('offline', function () { - it('should not return search results ', function () { this.registry._config.offline = true; this.registry.search('jquery', function (err, results) { - expect(err).to.be.null; + expect(err).to.be(null); expect(results.length).to.eql(0); }); }); - }); describe('cache', function () { - beforeEach(function () { nock('https://bower.herokuapp.com:443') .get('/packages/search/jquery') @@ -122,7 +113,7 @@ describe('RegistryClient', function () { }); afterEach(function () { - //this.client.clearCache(); + this.client.clearCache(); }); it('should fill cache', function (next) { @@ -130,12 +121,12 @@ describe('RegistryClient', function () { // fill cache self.client.search(self.pkg, function (err, results) { - expect(err).to.be.null; + expect(err).to.be(null); expect(results.length).to.eql(334); - // check for cache existance + // check for cache existence fs.exists(self.path, function (exists) { - expect(exists).to.be.true; + expect(exists).to.be(true); next(); }); }); @@ -146,16 +137,15 @@ describe('RegistryClient', function () { var self = this; self.client.search(self.pkg, function (err, results) { - expect(err).to.be.null; + expect(err).to.be(null); expect(results.length).to.eql(334); fs.exists(self.path, function (exists) { - expect(exists).to.be.true; + expect(exists).to.be(true); next(); }); }); }); - }); }); @@ -164,38 +154,34 @@ describe('RegistryClient', function () { // lookup // describe('calling the lookup instance method with argument', function () { - it('should not return an error', function () { this.registry.lookup('jquery', function (err) { - expect(err).to.be.null; + expect(err).to.be(null); }); }); it('should return entry type', function () { this.registry.lookup('jquery', function (err, entry) { - expect(err).to.be.null; + expect(err).to.be(null); expect(entry.type).to.eql('alias'); }); }); it('should return entry url ', function () { this.registry.lookup('jquery', function (err, entry) { - expect(err).to.be.null; + expect(err).to.be(null); expect(entry.url).to.eql('git://github.com/components/jquery.git'); }); }); - }); describe('calling the lookup instance method without argument', function () { - it('should return an error and no result', function () { this.registry.lookup('', function (err, entry) { - expect(err).to.not.be.null; - expect(entry).to.be.undefined; + expect(err).to.not.be(null); + expect(entry).to.be(undefined); }); }); - }); @@ -203,7 +189,6 @@ describe('RegistryClient', function () { // register // describe('calling the register instance method with argument', function () { - beforeEach(function () { nock('https://bower.herokuapp.com:443') .post('/packages', 'name=test-ba&url=git%3A%2F%2Fgithub.com%2Ftest-ba%2Ftest-ba.git') @@ -215,7 +200,7 @@ describe('RegistryClient', function () { it('should not return an error', function (next) { this.registry.register(this.pkg, this.pkgUrl, function (err) { - expect(err).to.be.null; + expect(err).to.be(null); next(); }); }); @@ -224,7 +209,7 @@ describe('RegistryClient', function () { var self = this; this.registry.register(this.pkg, this.pkgUrl, function (err, entry) { - expect(err).to.be.null; + expect(err).to.be(null); expect(entry.name).to.eql(self.pkg); next(); }); @@ -234,19 +219,18 @@ describe('RegistryClient', function () { var self = this; this.registry.register(this.pkg, this.pkgUrl, function (err, entry) { - expect(err).to.be.null; + expect(err).to.be(null); expect(entry.url).to.eql(self.pkgUrl); next(); }); }); - }); describe('calling the register instance method without arguments', function () { it('should return an error and no result', function () { this.registry.register('', '', function (err, entry) { - expect(err).to.not.be.null; - expect(entry).to.be.undefined; + expect(err).to.not.be(null); + expect(entry).to.be(undefined); }); }); }); @@ -256,7 +240,6 @@ describe('RegistryClient', function () { // search // describe('calling the search instance method with argument', function () { - beforeEach(function () { nock('https://bower.herokuapp.com:443') .get('/packages/search/jquery') @@ -268,7 +251,7 @@ describe('RegistryClient', function () { it('should not return an error', function (next) { this.registry.search(this.pkg, function (err) { - expect(err).to.be.null; + expect(err).to.be(null); next(); }); }); @@ -298,14 +281,13 @@ describe('RegistryClient', function () { }); }); }); - }); describe('calling the search instance method without argument', function () { it('should return an error and no results', function () { this.registry.search('', function (err, results) { - expect(err).to.not.be.null; - expect(results).to.be.undefined; + expect(err).to.not.be(null); + expect(results).to.be(undefined); }); }); }); @@ -315,25 +297,22 @@ describe('RegistryClient', function () { // clearCache // describe('called the clearCache instance method with argument', function () { - beforeEach(function () { this.pkg = 'jquery'; }); it('should not return an error', function () { this.registry.clearCache(this.pkg, function (err) { - expect(err).to.be.null; + expect(err).to.be(null); }); }); }); describe('called the clearCache instance method without argument', function () { - it('should not return any errors and remove all cache items', function () { this.registry.clearCache(function (err) { - expect(err).to.be.null; + expect(err).to.be(null); }); }); }); - }); diff --git a/packages/bower-registry-client/test/core/index.js b/packages/bower-registry-client/test/core/index.js index d9eaf1ab4..ef101a831 100644 --- a/packages/bower-registry-client/test/core/index.js +++ b/packages/bower-registry-client/test/core/index.js @@ -2,9 +2,7 @@ var index = require('../../lib/index'), expect = require('expect.js'); describe('index module', function () { - describe('requiring the index module', function () { - it('should expose a lookup method', function () { expect(index.lookup).to.be.ok; }); @@ -20,7 +18,5 @@ describe('index module', function () { it('should expose a search method', function () { expect(index.search).to.be.ok; }); - }); - }); diff --git a/packages/bower-registry-client/test/core/list.js b/packages/bower-registry-client/test/core/list.js index 752709e54..82de4ab7a 100644 --- a/packages/bower-registry-client/test/core/list.js +++ b/packages/bower-registry-client/test/core/list.js @@ -2,9 +2,7 @@ var list = require('../../lib/list'), expect = require('expect.js'); describe('list module', function () { - describe('requiring the list module', function () { - it('should expose a list method', function () { expect(typeof list === 'function').to.be.ok; }); @@ -23,7 +21,5 @@ describe('list module', function () { expect(list.resetCache).to.be.ok; expect(typeof list.resetCache === 'function').to.be.ok; }); - }); - }); diff --git a/packages/bower-registry-client/test/core/lookup.js b/packages/bower-registry-client/test/core/lookup.js index 3dfc0cb50..a8f26d3e4 100644 --- a/packages/bower-registry-client/test/core/lookup.js +++ b/packages/bower-registry-client/test/core/lookup.js @@ -2,9 +2,7 @@ var lookup = require('../../lib/lookup'), expect = require('expect.js'); describe('lookup module', function () { - describe('requiring the lookup module', function () { - it('should expose a lookup method', function () { expect(typeof lookup === 'function').to.be.ok; }); @@ -23,7 +21,5 @@ describe('lookup module', function () { expect(lookup.resetCache).to.be.ok; expect(typeof lookup.resetCache === 'function').to.be.ok; }); - }); - }); diff --git a/packages/bower-registry-client/test/core/register.js b/packages/bower-registry-client/test/core/register.js index 85e430e03..36e14095b 100644 --- a/packages/bower-registry-client/test/core/register.js +++ b/packages/bower-registry-client/test/core/register.js @@ -2,13 +2,9 @@ var register = require('../../lib/register'), expect = require('expect.js'); describe('register module', function () { - describe('requiring the register module', function () { - it('should expose a register method', function () { expect(typeof register === 'function').to.be.ok; }); - }); - }); diff --git a/packages/bower-registry-client/test/core/search.js b/packages/bower-registry-client/test/core/search.js index a44eb3e8e..49a613d63 100644 --- a/packages/bower-registry-client/test/core/search.js +++ b/packages/bower-registry-client/test/core/search.js @@ -2,9 +2,7 @@ var search = require('../../lib/search'), expect = require('expect.js'); describe('search module', function () { - describe('requiring the search module', function () { - it('should expose a search method', function () { expect(typeof search === 'function').to.be.ok; }); @@ -23,7 +21,5 @@ describe('search module', function () { expect(search.resetCache).to.be.ok; expect(typeof search.resetCache === 'function').to.be.ok; }); - }); - }); diff --git a/packages/bower-registry-client/test/core/util/Cache.js b/packages/bower-registry-client/test/core/util/Cache.js index c097ef60a..2ce74c9ed 100644 --- a/packages/bower-registry-client/test/core/util/Cache.js +++ b/packages/bower-registry-client/test/core/util/Cache.js @@ -2,15 +2,12 @@ var Cache = require('../../../lib/util/Cache'), expect = require('expect.js'); describe('Cache', function () { - beforeEach(function () { this.cache = new Cache(); }); describe('Constructor', function () { - describe('instantiating cache', function () { - it('should provide an instance of RegistryClient', function () { expect(this.cache instanceof Cache).to.be.ok; }); @@ -26,9 +23,7 @@ describe('Cache', function () { lruMethods.forEach(function (method) { expect(self.cache._cache).to.have.property(method); }); - }); - }); it('should have a get prototype method', function () { @@ -50,7 +45,5 @@ describe('Cache', function () { it('should have a reset prototype method', function () { expect(Cache.prototype).to.have.property('reset'); }); - }); - }); From f606eda18d7bced2ba8254775f1129a843645658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 20 Jul 2013 19:49:13 +0100 Subject: [PATCH 0158/1021] Add replay to requests. --- packages/bower-registry-client/lib/list.js | 5 +++-- packages/bower-registry-client/lib/lookup.js | 5 +++-- packages/bower-registry-client/lib/register.js | 5 +++-- packages/bower-registry-client/lib/search.js | 5 +++-- packages/bower-registry-client/package.json | 1 + 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/bower-registry-client/lib/list.js b/packages/bower-registry-client/lib/list.js index df554cf63..0b7634257 100644 --- a/packages/bower-registry-client/lib/list.js +++ b/packages/bower-registry-client/lib/list.js @@ -2,6 +2,7 @@ var path = require('path'); var url = require('url'); var async = require('async'); var request = require('request'); +var replay = require('request-replay'); var Cache = require('./util/Cache'); var createError = require('./util/createError'); @@ -90,7 +91,7 @@ function doRequest(index, config, callback) { headers['User-Agent'] = config.userAgent; } - request.get(requestUrl, { + replay(request.get(requestUrl, { proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, ca: config.ca.search[index], strictSSL: config.strictSsl, @@ -114,7 +115,7 @@ function doRequest(index, config, callback) { } callback(null, body); - }); + })); } function getMaxAge() { diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index ea0ae696f..cf54bf93a 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -2,6 +2,7 @@ var path = require('path'); var url = require('url'); var async = require('async'); var request = require('request'); +var replay = require('request-replay'); var createError = require('./util/createError'); var Cache = require('./util/Cache'); @@ -81,7 +82,7 @@ function doRequest(name, index, config, callback) { headers['User-Agent'] = config.userAgent; } - request.get(requestUrl, { + replay(request.get(requestUrl, { proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, ca: config.ca.search[index], strictSSL: config.strictSsl, @@ -113,7 +114,7 @@ function doRequest(name, index, config, callback) { type: 'alias', url: body.url }); - }); + })); } function getMaxAge(entry) { diff --git a/packages/bower-registry-client/lib/register.js b/packages/bower-registry-client/lib/register.js index 286375003..dbaa5c1e7 100644 --- a/packages/bower-registry-client/lib/register.js +++ b/packages/bower-registry-client/lib/register.js @@ -1,5 +1,6 @@ var parseUrl = require('url').parse; var request = require('request'); +var replay = require('request-replay'); var createError = require('./util/createError'); function register(name, url, callback) { @@ -12,7 +13,7 @@ function register(name, url, callback) { headers['User-Agent'] = config.userAgent; } - request.post({ + replay(request.post({ url: requestUrl, proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, ca: config.ca.register, @@ -48,7 +49,7 @@ function register(name, url, callback) { name: name, url: url }); - }); + })); } module.exports = register; diff --git a/packages/bower-registry-client/lib/search.js b/packages/bower-registry-client/lib/search.js index d0262d26e..cb58fd964 100644 --- a/packages/bower-registry-client/lib/search.js +++ b/packages/bower-registry-client/lib/search.js @@ -2,6 +2,7 @@ var path = require('path'); var url = require('url'); var async = require('async'); var request = require('request'); +var replay = require('request-replay'); var Cache = require('./util/Cache'); var createError = require('./util/createError'); @@ -97,7 +98,7 @@ function doRequest(name, index, config, callback) { headers['User-Agent'] = config.userAgent; } - request.get(requestUrl, { + replay(request.get(requestUrl, { proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, ca: config.ca.search[index], strictSSL: config.strictSsl, @@ -121,7 +122,7 @@ function doRequest(name, index, config, callback) { } callback(null, body); - }); + })); } function getMaxAge() { diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 91f6700bc..58c16ee1c 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -22,6 +22,7 @@ "graceful-fs": "~2.0.0", "lru-cache": "~2.3.0", "request": "~2.22.0", + "request-replay": "~0.1.0", "rimraf": "~2.2.0", "mkdirp": "~0.3.5" }, From c85c38cde3a1382a093b7e25b4995996be09dbeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 20 Jul 2013 19:49:41 +0100 Subject: [PATCH 0159/1021] Bump rc version. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 58c16ee1c..c5607d486 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.1.0-rc.2", + "version": "0.1.0-rc.3", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From b50017cad41bd8b664eeabda737da0182c42253f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 20 Jul 2013 20:18:39 +0100 Subject: [PATCH 0160/1021] Initial commit. --- packages/bower-logger/.editorconfig | 12 ++ packages/bower-logger/.gitignore | 2 + packages/bower-logger/.jshintrc | 62 +++++++ packages/bower-logger/.travis.yml | 4 + packages/bower-logger/LICENSE | 19 ++ packages/bower-logger/README.md | 73 ++++++++ packages/bower-logger/lib/Logger.js | 84 +++++++++ packages/bower-logger/package.json | 27 +++ packages/bower-logger/test/test.js | 262 ++++++++++++++++++++++++++++ 9 files changed, 545 insertions(+) create mode 100644 packages/bower-logger/.editorconfig create mode 100644 packages/bower-logger/.gitignore create mode 100644 packages/bower-logger/.jshintrc create mode 100644 packages/bower-logger/.travis.yml create mode 100644 packages/bower-logger/LICENSE create mode 100644 packages/bower-logger/README.md create mode 100644 packages/bower-logger/lib/Logger.js create mode 100644 packages/bower-logger/package.json create mode 100644 packages/bower-logger/test/test.js diff --git a/packages/bower-logger/.editorconfig b/packages/bower-logger/.editorconfig new file mode 100644 index 000000000..779f99a12 --- /dev/null +++ b/packages/bower-logger/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/packages/bower-logger/.gitignore b/packages/bower-logger/.gitignore new file mode 100644 index 000000000..1b6c50d99 --- /dev/null +++ b/packages/bower-logger/.gitignore @@ -0,0 +1,2 @@ +/node_modules +/npm-debug.* \ No newline at end of file diff --git a/packages/bower-logger/.jshintrc b/packages/bower-logger/.jshintrc new file mode 100644 index 000000000..eae6f9cf4 --- /dev/null +++ b/packages/bower-logger/.jshintrc @@ -0,0 +1,62 @@ +{ + "predef": [ + "console", + "describe", + "it", + "after", + "afterEach", + "before", + "beforeEach" + ], + + "indent": 4, + "node": true, + "devel": true, + + "bitwise": false, + "curly": false, + "eqeqeq": true, + "forin": false, + "immed": true, + "latedef": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": true, + "plusplus": false, + "regexp": false, + "undef": true, + "unused": true, + "quotmark": "single", + "strict": false, + "trailing": true, + "camelcase": true, + + "asi": false, + "boss": true, + "debug": false, + "eqnull": true, + "es5": false, + "esnext": false, + "evil": false, + "expr": false, + "funcscope": false, + "globalstrict": false, + "iterator": false, + "lastsemic": false, + "laxbreak": true, + "laxcomma": false, + "loopfunc": true, + "multistr": false, + "onecase": true, + "regexdash": false, + "scripturl": false, + "smarttabs": false, + "shadow": false, + "sub": false, + "supernew": true, + "validthis": false, + + "nomen": false, + "white": true +} diff --git a/packages/bower-logger/.travis.yml b/packages/bower-logger/.travis.yml new file mode 100644 index 000000000..2ca91f289 --- /dev/null +++ b/packages/bower-logger/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.10" + - "0.8" \ No newline at end of file diff --git a/packages/bower-logger/LICENSE b/packages/bower-logger/LICENSE new file mode 100644 index 000000000..13e8246fd --- /dev/null +++ b/packages/bower-logger/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012 Twitter and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/bower-logger/README.md b/packages/bower-logger/README.md new file mode 100644 index 000000000..4c5d10c1a --- /dev/null +++ b/packages/bower-logger/README.md @@ -0,0 +1,73 @@ +# bower-logger [![Build Status](https://secure.travis-ci.org/bower/logger.png?branch=master)](http://travis-ci.org/bower/logger) + +The logger used in the various architecture components of Bower. + + +## Usage + +### .error(id, message, data) + +Alias to `.log('error', id. message, data); + + +### .conflict(id, message, data) + +Alias to `.log('conflict', id. message, data); + + +#### .warn(id, message, data) + +Alias to `.log('warn', id. message, data); + + +#### .action(id, message, data) + +Alias to `.log('action', id. message, data); + + +#### .info(id, message, data) + +Alias to `.log('info', id. message, data); + + +#### .debug(id, message, data) + +Alias to `.log('debug', id. message, data); + + +#### .log(level, id, message, data) + +Emits a `log` event, with an object like so: + +```js +logger.log('warn', 'foo', 'bar', { dog: 'loves cat' }) +{ + level: 'warn', + id: 'foo', + message: 'bar', + data: { + dog: 'loves cat' + } +} +``` + +#### .pipe(logger) + +Pipes all logger events to another logger. +Basically all events emitted with `.emit()` will get piped. + + +#### .geminate() + +Creates a new logger that pipes events to the parent logger. +Alias for `(new Logger()).pipe(logger)`. + + +#### .intercept(fn) + +Intercepts `log` events, calling `fn` before listeners of the instance. + + +## License + +Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). diff --git a/packages/bower-logger/lib/Logger.js b/packages/bower-logger/lib/Logger.js new file mode 100644 index 000000000..649288f81 --- /dev/null +++ b/packages/bower-logger/lib/Logger.js @@ -0,0 +1,84 @@ +var EventEmitter = require('events').EventEmitter; +var util = require('util'); + +var slice = Array.prototype.slice; + +function Logger() { + this._interceptors = []; + this._piped = []; +} + +util.inherits(Logger, EventEmitter); + +Logger.prototype.intercept = function (fn) { + this._interceptors.push(fn); + return this; +}; + +Logger.prototype.emit = function () { + var ret; + var args = slice.call(arguments); + + // Run interceptors before + if (args[0] === 'log') { + this._interceptors.forEach(function (interceptor) { + interceptor.apply(this, args.slice(1)); + }); + } + + ret = EventEmitter.prototype.emit.apply(this, args); + + // Pipe + this._piped.forEach(function (emitter) { + emitter.emit.apply(emitter, args); + }); + + return ret; +}; + +Logger.prototype.pipe = function (emitter) { + this._piped.push(emitter); + + return emitter; +}; + +Logger.prototype.geminate = function () { + var logger = new Logger(); + + logger.pipe(this); + return logger; +}; + +Logger.prototype.log = function (level, id, message, data) { + var log = { + level: level, + id: id, + message: message, + data: data || {} + }; + + // Emit log + this.emit('log', log); + + return this; +}; + +// ------------------ + +Logger.LEVELS = { + 'error': 5, + 'conflict': 4, + 'warn': 3, + 'action': 2, + 'info': 1, + 'debug': 0 +}; + +// Add helpful log methods +Object.keys(Logger.LEVELS).forEach(function (level) { + Logger.prototype[level] = function (id, message, data) { + this.log(level, id, message, data); + }; +}); + +module.exports = Logger; diff --git a/packages/bower-logger/package.json b/packages/bower-logger/package.json new file mode 100644 index 000000000..ce4f52185 --- /dev/null +++ b/packages/bower-logger/package.json @@ -0,0 +1,27 @@ +{ + "name": "bower-logger", + "version": "0.1.0-rc.1", + "description": "The logger used in the various architecture components of Bower.", + "author": "Twitter", + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/bower/logger/blob/master/LICENSE" + } + ], + "repository": { + "type": "git", + "url": "git://github.com/bower/logger.git" + }, + "main": "lib/Logger", + "engines": { + "node": ">=0.8.0" + }, + "devDependencies": { + "expect.js": "~0.2.0", + "mocha": "~1.12.0" + }, + "scripts": { + "test": "mocha -R spec" + } +} diff --git a/packages/bower-logger/test/test.js b/packages/bower-logger/test/test.js new file mode 100644 index 000000000..1bc1c8f91 --- /dev/null +++ b/packages/bower-logger/test/test.js @@ -0,0 +1,262 @@ +var expect = require('expect.js'); +var EventEmitter = require('events').EventEmitter; +var Logger = require('../'); + +describe('Logger', function () { + var logger; + + beforeEach(function () { + logger = new Logger(); + }); + + describe('.constructor', function () { + it('should provide an instance of Logger', function () { + expect(logger instanceof Logger).to.be(true); + }); + + it('should provide an instance of EventEmitter', function () { + expect(logger instanceof EventEmitter).to.be(true); + }); + + it('should have prototype methods', function () { + var methods = [ + 'intercept', 'pipe', 'geminate', 'log' + ]; + + methods.forEach(function (method) { + expect(logger).to.have.property(method); + }); + }); + }); + + describe('events', function () { + var logData = { + foo: 'bar', + baz: 'string' + }; + + it('should pass through {}', function (next) { + logger.on('log', function (log) { + expect(log.data).to.eql({}); + next(); + }); + logger.info(); + }); + + it('should pass through logData', function (next) { + logger.on('log', function (log) { + expect(log.data).to.eql(logData); + next(); + }); + logger.info('foo', 'message', logData); + }); + + it('should emit error event', function (next) { + logger.on('log', function (log) { + expect(log.level).to.eql('error'); + expect(log.id).to.eql('foo'); + expect(log.message).to.eql('error message'); + expect(log.data).to.eql({}); + next(); + }); + logger.error('foo', 'error message'); + }); + + it('should emit conflict event', function (next) { + logger.on('log', function (log) { + expect(log.level).to.eql('conflict'); + expect(log.id).to.eql('foo'); + expect(log.message).to.eql('conflict message'); + expect(log.data).to.eql({}); + next(); + }); + logger.conflict('foo', 'conflict message'); + }); + + it('should emit warn event', function (next) { + logger.on('log', function (log) { + expect(log.level).to.eql('warn'); + expect(log.id).to.eql('foo'); + expect(log.message).to.eql('warn message'); + expect(log.data).to.eql({}); + next(); + }); + logger.warn('foo', 'warn message'); + }); + + it('should emit action event', function (next) { + logger.on('log', function (log) { + expect(log.level).to.eql('action'); + expect(log.id).to.eql('foo'); + expect(log.message).to.eql('action message'); + expect(log.data).to.eql({}); + next(); + }); + logger.action('foo', 'action message'); + }); + + it('should emit info event', function (next) { + logger.on('log', function (log) { + expect(log.level).to.eql('info'); + expect(log.id).to.eql('foo'); + expect(log.message).to.eql('info message'); + expect(log.data).to.eql({}); + next(); + }); + logger.info('foo', 'info message'); + }); + + it('should emit debug event', function (next) { + logger.on('log', function (log) { + expect(log.level).to.eql('debug'); + expect(log.id).to.eql('foo'); + expect(log.message).to.eql('debug message'); + expect(log.data).to.eql({}); + next(); + }); + logger.debug('foo', 'debug message'); + }); + }); + + describe('.intercept', function () { + it('should add the function and call it when a log occurs', function (next) { + var called; + var data = { + 'some': 'thing' + }; + + logger.intercept(function (log) { + called = true; + + expect(log).to.eql({ + level: 'warn', + id: 'foo', + message: 'bar', + data: data + }); + expect(log.data).to.equal(data); + }); + + logger.log('warn', 'foo', 'bar', data); + + expect(called).to.be(true); + next(); + }); + + it('should call the interceptors by order before emitting the event', function (next) { + var called = []; + + logger.intercept(function () { + called.push(1); + }); + logger.intercept(function () { + called.push(2); + }); + + logger.log('warn', 'foo', 'bar'); + + expect(called).to.eql([1, 2]); + next(); + }); + + it('should call the interceptors along the chain', function (next) { + var called = []; + var childLogger = logger.geminate(); + + childLogger.intercept(function () { + called.push(1); + }); + logger.intercept(function () { + called.push(3); + }); + + childLogger.on('log', function () { + called.push(2); + }); + logger.on('log', function () { + called.push(4); + }); + + childLogger.log('warn', 'foo', 'bar'); + + expect(called).to.eql([1, 2, 3, 4]); + next(); + }); + }); + + describe('.pipe', function () { + it('should return the passed emitter', function () { + var otherEmitter = new EventEmitter(); + expect(logger.pipe(otherEmitter)).to.equal(otherEmitter); + }); + + it('should pipe log events to another emitter', function (next) { + var otherEmitter = new EventEmitter(); + var data = { + 'some': 'thing' + }; + var piped; + + logger.pipe(otherEmitter); + + otherEmitter.on('log', function (log) { + piped = true; + expect(log).to.eql({ + level: 'warn', + id: 'foo', + message: 'bar', + data: data + }); + }); + + logger.log('warn', 'foo', 'bar', data); + + expect(piped).to.be(true); + next(); + }); + }); + + describe('.geminate', function () { + it('should return a new logger instance', function () { + var newLogger = logger.geminate(); + + expect(newLogger).to.be.an(Logger); + expect(newLogger).to.be.an(EventEmitter); + expect(newLogger).to.not.be.equal(logger); + }); + + it('should pipe the new logger events to the original logger', function (next) { + var piped = []; + var childLogger = logger.geminate(); + var data = { + 'some': 'thing' + }; + + childLogger.on('log', function (log) { + piped.push(1); + expect(log).to.eql({ + level: 'warn', + id: 'foo', + message: 'bar', + data: data + }); + expect(log.data).to.equal(data); + }); + + logger.on('log', function (log) { + piped.push(2); + expect(log).to.eql({ + level: 'warn', + id: 'foo', + message: 'bar', + data: data + }); + expect(log.data).to.equal(data); + }); + + childLogger.log('warn', 'foo', 'bar', data); + expect(piped).to.eql([1, 2]); + next(); + }); + }); +}); From 56cdae67c3b563c87aa3bcba27afef04ccfe3355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 20 Jul 2013 20:21:00 +0100 Subject: [PATCH 0161/1021] Document log levels --- packages/bower-logger/README.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/bower-logger/README.md b/packages/bower-logger/README.md index 4c5d10c1a..ec121f805 100644 --- a/packages/bower-logger/README.md +++ b/packages/bower-logger/README.md @@ -15,27 +15,27 @@ Alias to `.log('error', id. message, data); Alias to `.log('conflict', id. message, data); -#### .warn(id, message, data) +### .warn(id, message, data) Alias to `.log('warn', id. message, data); -#### .action(id, message, data) +### .action(id, message, data) Alias to `.log('action', id. message, data); -#### .info(id, message, data) +### .info(id, message, data) Alias to `.log('info', id. message, data); -#### .debug(id, message, data) +### .debug(id, message, data) Alias to `.log('debug', id. message, data); -#### .log(level, id, message, data) +### .log(level, id, message, data) Emits a `log` event, with an object like so: @@ -51,23 +51,30 @@ logger.log('warn', 'foo', 'bar', { dog: 'loves cat' }) } ``` -#### .pipe(logger) + +### .pipe(logger) Pipes all logger events to another logger. Basically all events emitted with `.emit()` will get piped. -#### .geminate() +### .geminate() Creates a new logger that pipes events to the parent logger. Alias for `(new Logger()).pipe(logger)`. -#### .intercept(fn) +### .intercept(fn) Intercepts `log` events, calling `fn` before listeners of the instance. +### #LEVELS + +A static property that contains an object where keys are the recognized log levels and values their importance. +The higher the importance, the more important the level is. + + ## License Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). From 4d0d4ca6ea190fe9b1648b9851f5cea7f7c4d516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 20 Jul 2013 20:22:30 +0100 Subject: [PATCH 0162/1021] README typos. --- packages/bower-logger/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/bower-logger/README.md b/packages/bower-logger/README.md index ec121f805..76f478a1d 100644 --- a/packages/bower-logger/README.md +++ b/packages/bower-logger/README.md @@ -7,32 +7,32 @@ The logger used in the various architecture components of Bower. ### .error(id, message, data) -Alias to `.log('error', id. message, data); +Alias to `.log('error', id. message, data)` ### .conflict(id, message, data) -Alias to `.log('conflict', id. message, data); +Alias to `.log('conflict', id. message, data)` ### .warn(id, message, data) -Alias to `.log('warn', id. message, data); +Alias to `.log('warn', id. message, data)` ### .action(id, message, data) -Alias to `.log('action', id. message, data); +Alias to `.log('action', id. message, data)` ### .info(id, message, data) -Alias to `.log('info', id. message, data); +Alias to `.log('info', id. message, data)` ### .debug(id, message, data) -Alias to `.log('debug', id. message, data); +Alias to `.log('debug', id. message, data)` ### .log(level, id, message, data) From eb801e66aec04f9bd3606385ead19d25194fd75f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 20 Jul 2013 22:05:07 +0100 Subject: [PATCH 0163/1021] Remove replay from register. --- packages/bower-registry-client/lib/register.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/bower-registry-client/lib/register.js b/packages/bower-registry-client/lib/register.js index dbaa5c1e7..286375003 100644 --- a/packages/bower-registry-client/lib/register.js +++ b/packages/bower-registry-client/lib/register.js @@ -1,6 +1,5 @@ var parseUrl = require('url').parse; var request = require('request'); -var replay = require('request-replay'); var createError = require('./util/createError'); function register(name, url, callback) { @@ -13,7 +12,7 @@ function register(name, url, callback) { headers['User-Agent'] = config.userAgent; } - replay(request.post({ + request.post({ url: requestUrl, proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, ca: config.ca.register, @@ -49,7 +48,7 @@ function register(name, url, callback) { name: name, url: url }); - })); + }); } module.exports = register; From eeb0c22d902e3c4e4574175976ffdd5915aa71e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 20 Jul 2013 22:05:36 +0100 Subject: [PATCH 0164/1021] Integrate logger. --- packages/bower-registry-client/Client.js | 3 +- packages/bower-registry-client/README.md | 3 +- packages/bower-registry-client/lib/list.js | 35 ++++++++++++-------- packages/bower-registry-client/lib/lookup.js | 30 +++++++++++------ packages/bower-registry-client/lib/search.js | 32 +++++++++++------- 5 files changed, 64 insertions(+), 39 deletions(-) diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js index 959f56eab..cd5885359 100644 --- a/packages/bower-registry-client/Client.js +++ b/packages/bower-registry-client/Client.js @@ -4,9 +4,10 @@ var async = require('async'); var methods = require('./lib'); var Cache = require('./lib/util/Cache'); -function RegistryClient(config) { +function RegistryClient(config, logger) { config = config || {}; this._config = config; + this._logger = logger; // Parse config // Registry diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index bbcb5d14f..16cb0b704 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -8,9 +8,10 @@ This module allows you to easily interact with the Bower server API. ```js var RegistryClient = require('bower-registry-client'); -var registry = new RegistryClient(options); +var registry = new RegistryClient(options, logger); ``` +The `logger` is optional and is expected to be an instance of the bower [logger](https://github.com/bower/logger). Available constructor options: - `cache`: the cache folder to use for some operations; using null will disable persistent cache (defaults to OS temp folder) diff --git a/packages/bower-registry-client/lib/list.js b/packages/bower-registry-client/lib/list.js index 0b7634257..34545440d 100644 --- a/packages/bower-registry-client/lib/list.js +++ b/packages/bower-registry-client/lib/list.js @@ -19,8 +19,7 @@ function list(callback) { return callback(null, []); } - // Lookup package in series in each registry - // endpoint until we got the data + // List packages in series in each registry async.doUntil(function (next) { var remote = url.parse(registry[index]); var listCache = that._listCache[remote.host]; @@ -34,7 +33,7 @@ function list(callback) { // Add each result results.forEach(function (result) { - addResult(data, result); + addResult.call(that, data, result); }); next(); @@ -42,7 +41,7 @@ function list(callback) { } // Otherwise make a request to always obtain fresh data - doRequest(index, that._config, function (err, results) { + doRequest.call(that, index, function (err, results) { if (err || !results) { return next(err); } @@ -56,7 +55,7 @@ function list(callback) { listCache.set('list', results, getMaxAge(), next); }); }, function () { - // Until the data is unknown or there's still registries to test + // Until there's still registries to test return index++ < total; }, function (err) { // Clear runtime cache, keeping the persistent data @@ -82,20 +81,22 @@ function addResult(accumulated, result) { } } -function doRequest(index, config, callback) { - var requestUrl = config.registry.search[index] + '/packages'; +function doRequest(index, callback) { + var requestUrl = this._config.registry.search[index] + '/packages'; var remote = url.parse(requestUrl); var headers = {}; + var that = this; + var req; - if (config.userAgent) { - headers['User-Agent'] = config.userAgent; + if (this._config.userAgent) { + headers['User-Agent'] = this._config.userAgent; } - replay(request.get(requestUrl, { - proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, - ca: config.ca.search[index], - strictSSL: config.strictSsl, - timeout: config.timeout, + req = replay(request.get(requestUrl, { + proxy: remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, + ca: this._config.ca.search[index], + strictSSL: this._config.strictSsl, + timeout: this._config.timeout, json: true }, function (err, response, body) { // If there was an internal error (e.g. timeout) @@ -116,6 +117,12 @@ function doRequest(index, config, callback) { callback(null, body); })); + + if (this._logger) { + req.on('replay', function (nr, error) { + that._logger.debug('retry', 'Retrying request to ' + this._source + ' because it failed with ' + error.code); + }); + } } function getMaxAge() { diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index cf54bf93a..bc6570b4f 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -35,7 +35,7 @@ function lookup(name, callback) { return next(err); } - doRequest(name, index, that._config, function (err, entry) { + doRequest.call(that, name, index, function (err, entry) { if (err || !entry) { return next(err); } @@ -49,7 +49,7 @@ function lookup(name, callback) { // Otherwise, we totally bypass the cache and // make only the request } else { - doRequest(name, index, that._config, function (err, entry) { + doRequest.call(that, name, index, function (err, entry) { if (err || !entry) { return next(err); } @@ -73,20 +73,22 @@ function lookup(name, callback) { }); } -function doRequest(name, index, config, callback) { - var requestUrl = config.registry.search[index] + '/packages/' + encodeURIComponent(name); +function doRequest(name, index, callback) { + var requestUrl = this._config.registry.search[index] + '/packages/' + encodeURIComponent(name); var remote = url.parse(requestUrl); var headers = {}; + var req; + var that = this; - if (config.userAgent) { - headers['User-Agent'] = config.userAgent; + if (this._config.userAgent) { + headers['User-Agent'] = this._config.userAgent; } - replay(request.get(requestUrl, { - proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, - ca: config.ca.search[index], - strictSSL: config.strictSsl, - timeout: config.timeout, + req = replay(request.get(requestUrl, { + proxy: remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, + ca: this._config.ca.search[index], + strictSSL: this._config.strictSsl, + timeout: this._config.timeout, json: true }, function (err, response, body) { // If there was an internal error (e.g. timeout) @@ -115,6 +117,12 @@ function doRequest(name, index, config, callback) { url: body.url }); })); + + if (this._logger) { + req.on('replay', function (nr, error) { + that._logger.debug('retry', 'Retrying request to ' + this._source + ' because it failed with ' + error.code); + }); + } } function getMaxAge(entry) { diff --git a/packages/bower-registry-client/lib/search.js b/packages/bower-registry-client/lib/search.js index cb58fd964..454f0c9a3 100644 --- a/packages/bower-registry-client/lib/search.js +++ b/packages/bower-registry-client/lib/search.js @@ -41,7 +41,7 @@ function search(name, callback) { // Add each result results.forEach(function (result) { - addResult(data, result); + addResult.call(that, data, result); }); next(); @@ -49,14 +49,14 @@ function search(name, callback) { } // Otherwise make a request to always obtain fresh data - doRequest(name, index, that._config, function (err, results) { + doRequest.call(that, name, index, function (err, results) { if (err || !results || !results.length) { return next(err); } // Add each result results.forEach(function (result) { - addResult(data, result); + addResult.call(that, data, result); }); // Store in cache for future offline usage @@ -89,20 +89,22 @@ function addResult(accumulated, result) { } } -function doRequest(name, index, config, callback) { - var requestUrl = config.registry.search[index] + '/packages/search/' + encodeURIComponent(name); +function doRequest(name, index, callback) { + var requestUrl = this._config.registry.search[index] + '/packages/search/' + encodeURIComponent(name); var remote = url.parse(requestUrl); var headers = {}; + var that = this; + var req; - if (config.userAgent) { - headers['User-Agent'] = config.userAgent; + if (this._config.userAgent) { + headers['User-Agent'] = this._config.userAgent; } - replay(request.get(requestUrl, { - proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, - ca: config.ca.search[index], - strictSSL: config.strictSsl, - timeout: config.timeout, + req = replay(request.get(requestUrl, { + proxy: remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, + ca: this._config.ca.search[index], + strictSSL: this._config.strictSsl, + timeout: this._config.timeout, json: true }, function (err, response, body) { // If there was an internal error (e.g. timeout) @@ -123,6 +125,12 @@ function doRequest(name, index, config, callback) { callback(null, body); })); + + if (this._logger) { + req.on('replay', function (nr, error) { + that._logger.debug('retry', 'Retrying request to ' + this._source + ' because it failed with ' + error.code); + }); + } } function getMaxAge() { From 4221ddbb359a7aefebef05949e1804fbc61e49c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 20 Jul 2013 22:06:34 +0100 Subject: [PATCH 0165/1021] Bump rc. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index c5607d486..024edff74 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.1.0-rc.3", + "version": "0.1.0-rc.4", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From 86dbea7ddb87f1f2b5d05825dff3d4e7d3302055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 20 Jul 2013 23:18:09 +0100 Subject: [PATCH 0166/1021] Update reps. --- packages/bower-registry-client/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 024edff74..2de1ee467 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -29,11 +29,11 @@ "devDependencies": { "expect.js": "~0.2.0", "grunt": "~0.4.1", - "grunt-contrib-watch": "~0.4.4", + "grunt-contrib-watch": "~0.5.0", "grunt-contrib-jshint": "~0.6.0", "grunt-simple-mocha": "~0.4.0", "mocha": "~1.12.0", - "nock": "~0.18.2" + "nock": "~0.22.0" }, "scripts": { "test": "grunt test" From f26ea32897f2c7d96634f055819d5a664463d487 Mon Sep 17 00:00:00 2001 From: Cormac Flynn Date: Tue, 23 Jul 2013 15:41:22 +0200 Subject: [PATCH 0167/1021] Endpoints with backslashes should be recognized as sources --- packages/bower-endpoint-parser/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-endpoint-parser/index.js b/packages/bower-endpoint-parser/index.js index a26437b49..8efd79b41 100644 --- a/packages/bower-endpoint-parser/index.js +++ b/packages/bower-endpoint-parser/index.js @@ -88,7 +88,7 @@ function isWildcard(target) { } function isSource(value) { - return value.indexOf('/') !== -1 || value.indexOf('@') !== -1; + return value.indexOf('/') !== -1 || value.indexOf('\\') !== -1 || value.indexOf('@') !== -1; } module.exports.decompose = decompose; From d09f78801cb96f1eac97e67f0073a5861a9d9880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Berg=C3=A9?= Date: Tue, 23 Jul 2013 18:00:21 +0200 Subject: [PATCH 0168/1021] fix search in multiple registries --- packages/bower-registry-client/lib/search.js | 2 +- packages/bower-registry-client/test/Client.js | 58 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/packages/bower-registry-client/lib/search.js b/packages/bower-registry-client/lib/search.js index 454f0c9a3..cfcd06e71 100644 --- a/packages/bower-registry-client/lib/search.js +++ b/packages/bower-registry-client/lib/search.js @@ -64,7 +64,7 @@ function search(name, callback) { }); }, function () { // Until the data is unknown or there's still registries to test - return index++ < total; + return ++index === total; }, function (err) { // Clear runtime cache, keeping the persistent data // in files for future offline usage diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index d7bcf2885..ae9e7313d 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -283,6 +283,64 @@ describe('RegistryClient', function () { }); }); + describe('calling the seratch instance method with two registries', function () { + beforeEach(function () { + nock('https://bower.herokuapp.com:443') + .get('/packages/search/jquery') + .reply(200, [ + { + name: 'jquery', + url: 'git://github.com/components/jquery.git' + } + ]); + + nock('http://custom-registry.com') + .get('/packages/search/jquery') + .reply(200, []); + + this.pkg = 'jquery'; + this.pkgUrl = 'git://github.com/components/jquery.git'; + this.registry._config.registry.search = [ + 'https://bower.herokuapp.com', + 'http://custom-registry.com' + ]; + }); + + afterEach(function () { + this.registry._config.registry.search = ['https://bower.herokuapp.com']; + }); + + it('should return entry name', function (next) { + var self = this; + + this.registry.search(this.pkg, function (err, results) { + if (! results.length) return next(false); + + results.forEach(function (entry) { + if (entry.name === self.pkg) { + expect(entry.name).to.eql(self.pkg); + next(); + } + }); + }); + }); + + it('should return entry url', function (next) { + var self = this; + + this.registry.search(this.pkg, function (err, results) { + if (! results.length) return next(false); + + results.forEach(function (entry) { + if (entry.name === self.pkg) { + expect(entry.url).to.eql(self.pkgUrl); + next(); + } + }); + }); + }); + }); + describe('calling the search instance method without argument', function () { it('should return an error and no results', function () { this.registry.search('', function (err, results) { From d4f2ced6a34de6f34506b3deafcc4d5cf9ab74cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 23 Jul 2013 21:01:30 +0100 Subject: [PATCH 0169/1021] Add paths tests, simply with regexp. --- packages/bower-endpoint-parser/index.js | 2 +- packages/bower-endpoint-parser/test/test.js | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/bower-endpoint-parser/index.js b/packages/bower-endpoint-parser/index.js index 8efd79b41..f499eee33 100644 --- a/packages/bower-endpoint-parser/index.js +++ b/packages/bower-endpoint-parser/index.js @@ -88,7 +88,7 @@ function isWildcard(target) { } function isSource(value) { - return value.indexOf('/') !== -1 || value.indexOf('\\') !== -1 || value.indexOf('@') !== -1; + return (/[\/\\@]/).test(value); } module.exports.decompose = decompose; diff --git a/packages/bower-endpoint-parser/test/test.js b/packages/bower-endpoint-parser/test/test.js index 87d8059d5..7c15f53af 100644 --- a/packages/bower-endpoint-parser/test/test.js +++ b/packages/bower-endpoint-parser/test/test.js @@ -59,7 +59,9 @@ describe('endpoint-parser', function () { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap', bootstrap2: 'http://twitter.github.io/bootstrap/assets/bootstrap#*', ssh: 'git@example.com', - git: 'git://example.com' + git: 'git://example.com', + path: '/foo', + winpath: 'c:\\foo' }; var expected = [ { name: 'jquery', source: 'jquery', target: '~1.9.1' }, @@ -71,7 +73,9 @@ describe('endpoint-parser', function () { { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }, { name: 'bootstrap2', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }, { name: 'ssh', source: 'git@example.com', target: '*' }, - { name: 'git', source: 'git://example.com', target: '*' } + { name: 'git', source: 'git://example.com', target: '*' }, + { name: 'path', source: '/foo', target: '*' }, + { name: 'winpath', source: 'c:\\foo', target: '*' } ]; var x = 0; From 057b18e4befb89d1b7d15fd6666788123eac0696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 23 Jul 2013 21:01:51 +0100 Subject: [PATCH 0170/1021] Bump to 0.1.0 --- packages/bower-endpoint-parser/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-endpoint-parser/package.json b/packages/bower-endpoint-parser/package.json index 30887522f..8ac459c06 100644 --- a/packages/bower-endpoint-parser/package.json +++ b/packages/bower-endpoint-parser/package.json @@ -1,6 +1,6 @@ { "name": "bower-endpoint-parser", - "version": "0.1.0-rc.1", + "version": "0.1.0", "description": "Little module that helps with endpoints parsing.", "author": "Twitter", "licenses": [ From e1aa43147d27df362c1ec0b474ebe7371a24a47e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 23 Jul 2013 22:49:58 +0100 Subject: [PATCH 0171/1021] Minor tweaks. --- packages/bower-registry-client/Client.js | 32 +++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js index cd5885359..39b9b07a1 100644 --- a/packages/bower-registry-client/Client.js +++ b/packages/bower-registry-client/Client.js @@ -1,25 +1,36 @@ var os = require('os'); var path = require('path'); var async = require('async'); +var deepExtend = require('deep-extend'); var methods = require('./lib'); var Cache = require('./lib/util/Cache'); function RegistryClient(config, logger) { + var bowerRegistry = 'https://bower.herokuapp.com'; + config = config || {}; this._config = config; this._logger = logger; // Parse config // Registry - config.registry = config.registry || 'https://bower.herokuapp.com'; + config.registry = config.registry || bowerRegistry; if (typeof config.registry === 'string') { config.registry = { search: [config.registry], register: config.registry, publish: config.registry }; - } else if (!Array.isArray(config.registry.search)) { - config.registry.search = [config.registry.search]; + } else { + config.registry = deepExtend({ + search: bowerRegistry, + register: bowerRegistry, + publish: bowerRegistry + }, config.registry); + + if (!Array.isArray(config.registry.search)) { + config.registry.search = [config.registry.search]; + } } // Ensure that every registry endpoint does not end with / @@ -30,14 +41,18 @@ function RegistryClient(config, logger) { config.registry.publish = config.registry.publish.replace(/\/+$/, ''); // CA - if (!config.ca || typeof config.ca === 'string') { + if (typeof config.ca === 'string') { config.ca = { search: [config.ca], register: config.ca, publish: config.ca }; - } else if (!Array.isArray(config.ca.search)) { - config.ca.search = [config.ca.search]; + } else { + config.ca = config.ca || {}; + + if (config.ca.search && !Array.isArray(config.ca.search)) { + config.ca.search = [config.ca.search]; + } } // Cache @@ -64,6 +79,11 @@ RegistryClient.prototype.list = methods.list; RegistryClient.prototype.register = methods.register; RegistryClient.prototype.clearCache = function (name, callback) { + if (typeof name === 'function') { + callback = name; + name = null; + } + async.parallel([ this.lookup.clearCache.bind(this, name), this.search.clearCache.bind(this, name), From 15dca65bd1d055d3d077073bd873202467807e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 23 Jul 2013 22:50:40 +0100 Subject: [PATCH 0172/1021] Set timeout to 60sec. --- packages/bower-registry-client/Client.js | 2 +- packages/bower-registry-client/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js index 39b9b07a1..e4ef89b8a 100644 --- a/packages/bower-registry-client/Client.js +++ b/packages/bower-registry-client/Client.js @@ -62,7 +62,7 @@ function RegistryClient(config, logger) { // Timeout if (typeof config.timeout !== 'number') { - config.timeout = 5000; + config.timeout = 60000; } // Strict ssl diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index 16cb0b704..dcf9712a0 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -25,7 +25,7 @@ Available constructor options: - `httpsProxy`: the proxy to use for https requests (defaults to null) - `strictSsl`: whether or not to do SSL key validation when making requests via https (defaults to true). - `userAgent`: the user agent to use for the requests (defaults to null) -- `timeout`: the timeout for the requests to finish (defaults to 5000) +- `timeout`: the timeout for the requests to finish (defaults to 60000) - `force`: If set to true, cache will be bypassed and remotes will always be hit (defaults to false). - `offline`: If set to true, only the cache will be used (defaults to false). From b38c3a5035eb619b87a1992ad49f0b63e532c2e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 23 Jul 2013 22:51:07 +0100 Subject: [PATCH 0173/1021] Add missing dep. --- packages/bower-registry-client/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 2de1ee467..643365af1 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -19,6 +19,7 @@ }, "dependencies": { "async": "~0.2.8", + "deep-extend": "~0.2.5", "graceful-fs": "~2.0.0", "lru-cache": "~2.3.0", "request": "~2.22.0", From ce0984573bbb7ea887d59308f1766841ee586fe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 23 Jul 2013 22:55:00 +0100 Subject: [PATCH 0174/1021] Fix tests. --- packages/bower-registry-client/Client.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js index e4ef89b8a..717ef95b7 100644 --- a/packages/bower-registry-client/Client.js +++ b/packages/bower-registry-client/Client.js @@ -48,9 +48,11 @@ function RegistryClient(config, logger) { publish: config.ca }; } else { - config.ca = config.ca || {}; + config.ca = deepExtend({ + search: [] + }, config.ca); - if (config.ca.search && !Array.isArray(config.ca.search)) { + if (!Array.isArray(config.ca.search)) { config.ca.search = [config.ca.search]; } } From c87fe7c26528b273a47367c2d8aea3cc2789dfcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 23 Jul 2013 22:56:17 +0100 Subject: [PATCH 0175/1021] Fix lookup bug for multiple registries. Improve and fix tests. --- packages/bower-registry-client/lib/lookup.js | 2 +- packages/bower-registry-client/test/Client.js | 212 +++++++++++++----- 2 files changed, 159 insertions(+), 55 deletions(-) diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index bc6570b4f..ed0ba38dc 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -62,7 +62,7 @@ function lookup(name, callback) { } }, function () { // Until the data is unknown or there's still registries to test - return !!data || index++ < total; + return !!data || ++index === total; }, function (err) { // If some of the registry entries failed, error out if (err) { diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index ae9e7313d..05a0f64da 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -8,7 +8,8 @@ describe('RegistryClient', function () { this.uri = 'https://bower.herokuapp.com'; this.timeoutVal = 5000; this.registry = new RegistryClient({ - strictSsl: false + strictSsl: false, + timeout: this.timeoutVal }); this.conf = { search: [this.uri], @@ -83,12 +84,13 @@ describe('RegistryClient', function () { describe('instantiating a client with custom options', function () { describe('offline', function () { - it('should not return search results ', function () { + it('should not return search results ', function (next) { this.registry._config.offline = true; this.registry.search('jquery', function (err, results) { expect(err).to.be(null); expect(results.length).to.eql(0); + next(); }); }); }); @@ -112,8 +114,8 @@ describe('RegistryClient', function () { this.path = this.cacheDir + '/' + this.host + '/' + this.method + '/' + this.pkg; }); - afterEach(function () { - this.client.clearCache(); + afterEach(function (next) { + this.client.clearCache(next); }); it('should fill cache', function (next) { @@ -154,37 +156,118 @@ describe('RegistryClient', function () { // lookup // describe('calling the lookup instance method with argument', function () { - it('should not return an error', function () { + beforeEach(function () { + nock('https://bower.herokuapp.com:443') + .get('/packages/jquery') + .reply(200, { + name: 'jquery', + url: 'git://github.com/components/jquery.git' + }); + + this.registry._config.force = true; + }); + + it('should not return an error', function (next) { this.registry.lookup('jquery', function (err) { expect(err).to.be(null); + next(); }); }); - it('should return entry type', function () { + it('should return entry type', function (next) { this.registry.lookup('jquery', function (err, entry) { expect(err).to.be(null); expect(entry.type).to.eql('alias'); + next(); }); }); - it('should return entry url ', function () { + it('should return entry url ', function (next) { this.registry.lookup('jquery', function (err, entry) { expect(err).to.be(null); expect(entry.url).to.eql('git://github.com/components/jquery.git'); }); + next(); + }); + }); + + describe('calling the lookup instance method with three registries', function () { + beforeEach(function () { + nock('https://bower.herokuapp.com:443') + .get('/packages/jquery') + .reply(404); + + nock('http://custom-registry.com') + .get('/packages/jquery') + .reply(200, { + name: 'jquery', + url: 'git://github.com/foo/bar' + }); + + nock('http://custom-registry2.com') + .get('/packages/jquery') + .reply(200, { + name: 'jquery', + url: 'git://github.com/foo/baz' + }); + + this.registry = new RegistryClient({ + strictSsl: false, + force: true, + registry: { + search: [ + 'https://bower.herokuapp.com', + 'http://custom-registry.com', + 'http://custom-registry2.com' + ] + } + }); + }); + + it('should return entry type', function (next) { + this.registry.lookup('jquery', function (err, entry) { + expect(err).to.be(null); + expect(entry).to.be.an('object'); + expect(entry.type).to.eql('alias'); + next(); + }); + }); + + it('should return entry url ', function (next) { + this.registry.lookup('jquery', function (err, entry) { + expect(err).to.be(null); + expect(entry).to.be.an('object'); + expect(entry.url).to.eql('git://github.com/foo/bar'); + next(); + }); + }); + + it('should respect order', function (next) { + this.registry._config.registry.search = [ + 'https://bower.herokuapp.com', + 'http://custom-registry2.com', + 'http://custom-registry.com' + ]; + + this.registry.lookup('jquery', function (err, entry) { + expect(err).to.be(null); + expect(entry).to.be.an('object'); + expect(entry.url).to.eql('git://github.com/foo/baz'); + next(); + }); }); }); describe('calling the lookup instance method without argument', function () { - it('should return an error and no result', function () { + it('should return an error and no result', function (next) { this.registry.lookup('', function (err, entry) { - expect(err).to.not.be(null); + expect(err).to.be.an(Error); expect(entry).to.be(undefined); + next(); }); }); }); - // // register // @@ -227,10 +310,17 @@ describe('RegistryClient', function () { }); describe('calling the register instance method without arguments', function () { - it('should return an error and no result', function () { + beforeEach(function () { + nock('https://bower.herokuapp.com:443') + .post('/packages', 'name=&url=') + .reply(400); + }); + + it('should return an error and no result', function (next) { this.registry.register('', '', function (err, entry) { - expect(err).to.not.be(null); + expect(err).to.be.an(Error); expect(entry).to.be(undefined); + next(); }); }); }); @@ -247,6 +337,8 @@ describe('RegistryClient', function () { this.pkg = 'jquery'; this.pkgUrl = 'git://github.com/components/jquery.git'; + + this.registry._config.force = true; }); it('should not return an error', function (next) { @@ -260,12 +352,12 @@ describe('RegistryClient', function () { var self = this; this.registry.search(this.pkg, function (err, results) { - results.forEach(function (entry) { - if (entry.name === self.pkg) { - expect(entry.name).to.eql(self.pkg); - next(); - } + var found = results.some(function (entry) { + return entry.name === self.pkg; }); + + expect(found).to.be(true); + next(); }); }); @@ -273,55 +365,56 @@ describe('RegistryClient', function () { var self = this; this.registry.search(this.pkg, function (err, results) { - results.forEach(function (entry) { - if (entry.name === self.pkg) { - expect(entry.url).to.eql(self.pkgUrl); - next(); - } + var found = results.some(function (entry) { + return entry.url === self.pkgUrl; }); + + expect(found).to.be(true); + next(); }); }); }); - describe('calling the seratch instance method with two registries', function () { + describe('calling the search instance method with two registries', function () { beforeEach(function () { nock('https://bower.herokuapp.com:443') + .get('/packages/search/jquery') + .reply(200, []); + + nock('http://custom-registry.com') .get('/packages/search/jquery') .reply(200, [ { name: 'jquery', - url: 'git://github.com/components/jquery.git' + url: 'git://github.com/bar/foo.git' } ]); - nock('http://custom-registry.com') - .get('/packages/search/jquery') - .reply(200, []); - this.pkg = 'jquery'; - this.pkgUrl = 'git://github.com/components/jquery.git'; - this.registry._config.registry.search = [ - 'https://bower.herokuapp.com', - 'http://custom-registry.com' - ]; - }); - - afterEach(function () { - this.registry._config.registry.search = ['https://bower.herokuapp.com']; + this.pkgUrl = 'git://github.com/bar/foo.git'; + + this.registry = new RegistryClient({ + strictSsl: false, + force: true, + registry: { + search: [ + 'https://bower.herokuapp.com', + 'http://custom-registry.com' + ] + } + }); }); it('should return entry name', function (next) { var self = this; this.registry.search(this.pkg, function (err, results) { - if (! results.length) return next(false); - - results.forEach(function (entry) { - if (entry.name === self.pkg) { - expect(entry.name).to.eql(self.pkg); - next(); - } + var found = results.some(function (entry) { + return entry.name === self.pkg; }); + + expect(found).to.be(true); + next(); }); }); @@ -329,23 +422,32 @@ describe('RegistryClient', function () { var self = this; this.registry.search(this.pkg, function (err, results) { - if (! results.length) return next(false); + if (! results.length) { + return next(new Error('Result expected')); + } - results.forEach(function (entry) { - if (entry.name === self.pkg) { - expect(entry.url).to.eql(self.pkgUrl); - next(); - } + var found = results.some(function (entry) { + return entry.url === self.pkgUrl; }); + + expect(found).to.be(true); + next(); }); }); }); describe('calling the search instance method without argument', function () { - it('should return an error and no results', function () { + beforeEach(function () { + nock('https://bower.herokuapp.com:443') + .get('/packages/search/') + .reply(404); + }); + + it('should return an error and no results', function (next) { this.registry.search('', function (err, results) { - expect(err).to.not.be(null); + expect(err).to.be.an(Error); expect(results).to.be(undefined); + next(); }); }); }); @@ -359,17 +461,19 @@ describe('RegistryClient', function () { this.pkg = 'jquery'; }); - it('should not return an error', function () { + it('should not return an error', function (next) { this.registry.clearCache(this.pkg, function (err) { expect(err).to.be(null); + next(); }); }); }); describe('called the clearCache instance method without argument', function () { - it('should not return any errors and remove all cache items', function () { + it('should not return any errors and remove all cache items', function (next) { this.registry.clearCache(function (err) { expect(err).to.be(null); + next(); }); }); }); From 10b410d46f15663d8464e8a1b35928f3e557944c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 23 Jul 2013 23:16:43 +0100 Subject: [PATCH 0176/1021] Fix multiple registries in the list method. --- packages/bower-registry-client/lib/list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/lib/list.js b/packages/bower-registry-client/lib/list.js index 34545440d..70cc2a211 100644 --- a/packages/bower-registry-client/lib/list.js +++ b/packages/bower-registry-client/lib/list.js @@ -56,7 +56,7 @@ function list(callback) { }); }, function () { // Until there's still registries to test - return index++ < total; + return ++index === total; }, function (err) { // Clear runtime cache, keeping the persistent data // in files for future offline usage From c846b24ebbe9ba87f12861539e1b9be7f9898b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 24 Jul 2013 09:00:53 +0100 Subject: [PATCH 0177/1021] Bump rc. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 643365af1..a71e8a12f 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.1.0-rc.4", + "version": "0.1.0-rc.5", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From f8c13f939c5971ebf0d880ccde685aec29752726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Thu, 25 Jul 2013 22:06:42 +0100 Subject: [PATCH 0178/1021] Changes to the api. - Read now accepts directories and finds the bower json to read inside - Add normalise and validate methods - Add options to the parse and read methods to enable/disable normalisation and validation. --- packages/bower-json/lib/json.js | 107 ++++++++++++--- packages/bower-json/package.json | 1 + .../test/pkg-bower-json-invalid/bower.json | 2 +- .../test/pkg-bower-json-malformed/bower.json | 1 + .../bower-json/test/pkg-bower-json/bower.json | 5 +- .../test/pkg-component-json/component.json | 2 +- packages/bower-json/test/test.js | 126 +++++++++++++++--- 7 files changed, 203 insertions(+), 41 deletions(-) create mode 100644 packages/bower-json/test/pkg-bower-json-malformed/bower.json diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index 32e00992d..1be9c3361 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -1,38 +1,103 @@ var fs = require('graceful-fs'); var path = require('path'); +var deepExtend = require('deep-extend'); var createError = require('./util/createError'); -function read(file, callback) { - fs.readFile(file, function (err, contents) { - if (err) return callback(err); +function read(file, options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } - var json; - - try { - json = JSON.parse(contents.toString()); - } catch (err) { - err.code = 'EMALFORMED'; + // Check if file is a directory + fs.stat(file, function (err, stat) { + if (err) { return callback(err); } - parse(json, callback); - }); -} + // It's a directory, so we find the json inside it + if (stat.isDirectory()) { + return find(file, function (err, file) { + if (err) { + return callback(err); + } -function parse(json, callback) { - // Apply normalisation and validation here - // If something is invalid, the error.code should be EINVALID - process.nextTick(function () { - if (!json.name) { - return callback(createError('No name property set', 'EINVALID')); + read(file, options, callback); + }); } - // TODO: !! + // Otherwise read it + fs.readFile(file, function (err, contents) { + var json; + + if (err) { + return callback(err); + } + + try { + json = JSON.parse(contents.toString()); + } catch (err) { + err.code = 'EMALFORMED'; + return callback(err); + } + + // Parse it + try { + json = parse(json, options); + } catch (err) { + return callback(err); + } - return callback(null, json); + callback(null, json, file); + }); }); } +function parse(json, options) { + options = deepExtend({ + normalize: false, + validate: true, + clone: false + }, options || {}); + + // Clone + if (options.clone) { + json = deepExtend({}, json); + } + + // Validate + if (options.validate) { + validate(json); + } + + // Normalize + if (options.normalize) { + normalize(json); + } + + return json; +} + +function validate(json) { + if (!json.name) { + throw createError('No name property set', 'EINVALID'); + } + + // TODO + + return json; +} + +function normalize(json) { + if (typeof json.main === 'string') { + json.main = json.main.split(','); + } + + // TODO + + return json; +} + function find(folder, callback) { var file = path.resolve(path.join(folder, 'bower.json')); @@ -54,4 +119,6 @@ function find(folder, callback) { module.exports = read; module.exports.read = read; module.exports.parse = parse; +module.exports.validate = validate; +module.exports.normalize = normalize; module.exports.find = find; diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 79467f95b..f7e273afa 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -18,6 +18,7 @@ "node": ">=0.8.0" }, "dependencies": { + "deep-extend": "~0.2.5", "graceful-fs": "~2.0.0" }, "devDependencies": { diff --git a/packages/bower-json/test/pkg-bower-json-invalid/bower.json b/packages/bower-json/test/pkg-bower-json-invalid/bower.json index 81750b96f..0967ef424 100644 --- a/packages/bower-json/test/pkg-bower-json-invalid/bower.json +++ b/packages/bower-json/test/pkg-bower-json-invalid/bower.json @@ -1 +1 @@ -{ \ No newline at end of file +{} diff --git a/packages/bower-json/test/pkg-bower-json-malformed/bower.json b/packages/bower-json/test/pkg-bower-json-malformed/bower.json new file mode 100644 index 000000000..98232c64f --- /dev/null +++ b/packages/bower-json/test/pkg-bower-json-malformed/bower.json @@ -0,0 +1 @@ +{ diff --git a/packages/bower-json/test/pkg-bower-json/bower.json b/packages/bower-json/test/pkg-bower-json/bower.json index 099c57f8c..d5d0d3858 100644 --- a/packages/bower-json/test/pkg-bower-json/bower.json +++ b/packages/bower-json/test/pkg-bower-json/bower.json @@ -1,4 +1,5 @@ { "name": "some-pkg", - "version": "0.0.0" -} \ No newline at end of file + "version": "0.0.0", + "main": "foo.js" +} diff --git a/packages/bower-json/test/pkg-component-json/component.json b/packages/bower-json/test/pkg-component-json/component.json index 099c57f8c..e42186aff 100644 --- a/packages/bower-json/test/pkg-component-json/component.json +++ b/packages/bower-json/test/pkg-component-json/component.json @@ -1,4 +1,4 @@ { "name": "some-pkg", "version": "0.0.0" -} \ No newline at end of file +} diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index 79105db5a..ad9025cc4 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -5,7 +5,9 @@ var bowerJson = require('../lib/json'); describe('.find', function () { it('should find the bower.json file', function (done) { bowerJson.find(__dirname + '/pkg-bower-json', function (err, file) { - if (err) return done(err); + if (err) { + return done(err); + } expect(file).to.equal(path.resolve(__dirname + '/pkg-bower-json/bower.json')); done(); @@ -14,7 +16,9 @@ describe('.find', function () { it('should fallback to the component.json file', function (done) { bowerJson.find(__dirname + '/pkg-component-json', function (err, file) { - if (err) return done(err); + if (err) { + return done(err); + } expect(file).to.equal(path.resolve(__dirname + '/pkg-component-json/component.json')); done(); @@ -41,7 +45,7 @@ describe('.read', function () { }); it('should give error if when reading an invalid json', function (done) { - bowerJson.read(__dirname + '/pkg-bower-json-invalid/bower.json', function (err) { + bowerJson.read(__dirname + '/pkg-bower-json-malformed/bower.json', function (err) { expect(err).to.be.an(Error); expect(err.code).to.equal('EMALFORMED'); done(); @@ -50,30 +54,118 @@ describe('.read', function () { it('should read the file and give an object', function (done) { bowerJson.read(__dirname + '/pkg-bower-json/bower.json', function (err, json) { - if (err) return done(err); + if (err) { + return done(err); + } expect(json).to.be.an('object'); expect(json.name).to.equal('some-pkg'); expect(json.version).to.equal('0.0.0'); + done(); }); }); - it.skip('should validate the returned object'); -}); + it('should give the json file that was read', function (done) { + bowerJson.read(__dirname + '/pkg-bower-json', function (err, json, file) { + if (err) { + return done(err); + } -describe('.parse', function () { - it('should parse an object, giving a parsed object', function (done) { - var json = { - name: 'foo', - version: '0.0.0' - }; - - bowerJson.parse(json, function (err, retJson) { - expect(json).to.eql(retJson); + + expect(file).to.equal(__dirname + '/pkg-bower-json/bower.json'); done(); }); }); - it.skip('should validate the passed object'); -}); \ No newline at end of file + it('should find for a json file if a directory is given', function (done) { + bowerJson.read(__dirname + '/pkg-component-json', function (err, json, file) { + if (err) { + return done(err); + } + + expect(json).to.be.an('object'); + expect(json.name).to.equal('some-pkg'); + expect(json.version).to.equal('0.0.0'); + expect(file).to.equal(path.resolve(__dirname + '/pkg-component-json/component.json')); + done(); + }); + }); + + it('should validate the returned object unless validate is false', function (done) { + bowerJson.read(__dirname + '/pkg-bower-json-invalid/bower.json', function (err) { + expect(err).to.be.an(Error); + expect(err.message).to.contain('name'); + + bowerJson.read(__dirname + '/pkg-bower-json-invalid/bower.json', { validate: false }, function (err) { + done(err); + }); + }); + }); + + it('should normalize the returned object if normalize is true', function (done) { + bowerJson.read(__dirname + '/pkg-bower-json/bower.json', function (err, json) { + if (err) { + return done(err); + } + + expect(json.main).to.equal('foo.js'); + + bowerJson.read(__dirname + '/pkg-bower-json/bower.json', { normalize: true }, function (err, json) { + if (err) { + return done(err); + } + + expect(json.main).to.eql(['foo.js']); + done(); + }); + }); + }); +}); + +describe('.parse', function () { + it('should return the same object, unless clone is true', function () { + var json = { name: 'foo' }; + + expect(bowerJson.parse(json)).to.equal(json); + expect(bowerJson.parse(json, { clone: true })).to.not.equal(json); + expect(bowerJson.parse(json, { clone: true })).to.eql(json); + }); + + it('should validate the passed object, unless validate is false', function () { + expect(function () { + bowerJson.parse({}); + }).to.throwException(/name/); + + expect(function () { + bowerJson.parse({}, { validate: false }); + }).to.not.throwException(); + }); + + it('should not normalize the passed object unless normalize is true', function () { + var json = { name: 'foo', main: 'foo.js' }; + + bowerJson.parse(json); + expect(json.main).to.eql('foo.js'); + + bowerJson.parse(json, { normalize: true }); + expect(json.main).to.eql(['foo.js']); + }); +}); + +describe('.validate', function () { + it('should validate the name property', function () { + expect(function () { + bowerJson.validate({}); + }).to.throwException(/name/); + }); +}); + +describe('.normalize', function () { + it('should normalize the main property', function () { + var json = { name: 'foo', main: 'foo.js' }; + + bowerJson.normalize(json); + expect(json.main).to.eql(['foo.js']); + }); +}); From 125fb598d57a32e1617c7410e6136e84763c3a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Thu, 25 Jul 2013 22:19:09 +0100 Subject: [PATCH 0179/1021] Adjust README to the api changes. --- packages/bower-json/README.md | 71 +++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index 10f4beb9c..1bd26cc8b 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -5,13 +5,17 @@ Read `bower.json` files with semantics, normalisation, defaults and validation. ## Usage -#### .read(file, callback) +#### .read(file, options, callback) Reads `file` and applies normalisation, defaults and validation according to the `bower.json` spec. If the passed `file` does not exist, the callback is called with `error.code` equal to `ENOENT`. If the passed `file` contents are not valid JSON, the callback is called with `error.code` equal to `EMALFORMED`. If the `json` does not comply with the `bower.json` spec, the callback is called with `error.code` equal to `EINVALID`. +If `file` is a directory, `find()` will be used to search for the json file. +The `options` argument is optional and can be omitted. These options will be passed to `parse` method. + + ```js var bowerJson = require('bower-json'); @@ -28,10 +32,17 @@ bowerJson.read('/path/to/bower.json', function (err, json) { ``` -#### .parse(json, callback) +#### .parse(json, options) + +Parses an object. Useful when you want to apply normalisation and validation directly to an object. +If the `json` does not comply with the `bower.json` spec, an error is thrown with `error.code` equal to `EINVALID`. + +The `options` arguments is optional and can be omitted. Available options: + +- validate: Apply validation defaults to `true` +- normalize: Apply normalisation, defaults to `false` +- clone: clone, use and return the passed in `json` object instead of using it directly, defaults to `false` -Parses an object. Useful when you want to apply normalisation, defaults and validation directly to an object. -If the `json` does not comply with the `bower.json` spec, the callback is called with `error.code` equal to `EINVALID`. ```js var bowerJson = require('bower-json'); @@ -41,15 +52,51 @@ var json = { version: '0.0.1' }; -bowerJson.parse(json, function (err, json) { - if (err) { - console.error('There was an error parsing the object'); - console.error(err.message); - return; - } +try { + bowerJson.parse(json); +} catch (e) { + console.error('There was an error parsing the object'); + console.error(err.message); +} +``` - console.log('Parsed: ', json); -}); + +#### .validate(json) + +Validates the passed `json` object. +Throws an error with `error.code` equal to `EINVALID` if it does not comply with the spec. + + +```js +var bowerJson = require('bower-json'); + +var json = { + name: 'my-package', + version: '0.0.1' +}; + +try { + bowerJson.validate(json); +} catch (e) { + console.error('There was an error validating the object'); + console.error(err.message); +} +``` + + +#### .normalize(json) + +```js +var bowerJson = require('bower-json'); + +var json = { + name: 'my-package', + version: '0.0.1', + main: 'foo.js,bar.js' +}; + +bowerJson.nornalize(json); +json.main // ['foo.js', 'bar.js'] ``` From 95a09c546374fd632e407a11e7b8fc37353b3af2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Thu, 25 Jul 2013 23:31:33 +0100 Subject: [PATCH 0180/1021] Fix README typos as suggested. --- packages/bower-json/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index 1bd26cc8b..de4a29018 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -39,7 +39,7 @@ If the `json` does not comply with the `bower.json` spec, an error is thrown wit The `options` arguments is optional and can be omitted. Available options: -- validate: Apply validation defaults to `true` +- validate: Apply validation, defaults to `true` - normalize: Apply normalisation, defaults to `false` - clone: clone, use and return the passed in `json` object instead of using it directly, defaults to `false` @@ -54,7 +54,7 @@ var json = { try { bowerJson.parse(json); -} catch (e) { +} catch (err) { console.error('There was an error parsing the object'); console.error(err.message); } @@ -77,7 +77,7 @@ var json = { try { bowerJson.validate(json); -} catch (e) { +} catch (err) { console.error('There was an error validating the object'); console.error(err.message); } From ec904eb8a436e4ad9745f034cf310bf524c95d39 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Fri, 26 Jul 2013 16:02:42 +0100 Subject: [PATCH 0181/1021] adds list tests [#4] --- packages/bower-registry-client/test/Client.js | 108 +++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 05a0f64da..0973043e5 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -4,6 +4,7 @@ var RegistryClient = require('../Client'), nock = require('nock'); describe('RegistryClient', function () { + beforeEach(function () { this.uri = 'https://bower.herokuapp.com'; this.timeoutVal = 5000; @@ -19,6 +20,7 @@ describe('RegistryClient', function () { }); describe('Constructor', function () { + describe('instantiating a client', function () { it('should provide an instance of RegistryClient', function () { expect(this.registry instanceof RegistryClient).to.be.ok; @@ -83,10 +85,11 @@ describe('RegistryClient', function () { }); describe('instantiating a client with custom options', function () { + describe('offline', function () { + it('should not return search results ', function (next) { this.registry._config.offline = true; - this.registry.search('jquery', function (err, results) { expect(err).to.be(null); expect(results.length).to.eql(0); @@ -452,6 +455,109 @@ describe('RegistryClient', function () { }); }); + // + // list + // + describe('calling the list instance method', function () { + beforeEach(function () { + nock('https://bower.herokuapp.com:443') + .get('/packages') + .reply(200, [], {}); + + this.registry._config.force = true; + }); + + it('should not return an error', function (next) { + this.registry.list(function (err) { + expect(err).to.be(null); + next(); + }); + }); + + it('should return results array', function (next) { + var self = this; + + this.registry.list(function (err, results) { + expect(results).to.be.an('array'); + next(); + }); + }); + + }); + + describe('calling the list instance method with two registries', function () { + beforeEach(function () { + nock('https://bower.herokuapp.com:443') + .get('/packages') + .reply(200, []); + + nock('http://custom-registry.com') + .get('/packages') + .reply(200, [ + { + name: 'jquery', + url: 'git://github.com/bar/foo.git' + } + ]); + + this.registry = new RegistryClient({ + strictSsl: false, + force: true, + registry: { + search: [ + 'https://bower.herokuapp.com', + 'http://custom-registry.com' + ] + } + }); + }); + + it('should return entry name', function (next) { + var self = this; + + this.registry.list(function (err, results) { + var found = results.some(function (entry) { + return entry.name === self.pkg; + }); + + expect(found).to.be(true); + next(); + }); + }); + + it('should return entry url', function (next) { + var self = this; + + this.registry.list(function (err, results) { + if (! results.length) { + return next(new Error('Result expected')); + } + + var found = results.some(function (entry) { + return entry.url === self.pkgUrl; + }); + + expect(found).to.be(true); + next(); + }); + }); + }); + + describe('calling the list instance method', function () { + + beforeEach(function () { + nock('https://bower.herokuapp.com:443') + .get('/packages') + .reply(200, [], {}); + }); + + it('should return an error and no results', function (next) { + this.registry.list(function (err) { + expect(err).to.be(null); + next(); + }); + }); + }); // // clearCache From d3e627493910d4af38f3b1bf43e1adeea0d79af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 27 Jul 2013 11:25:38 +0100 Subject: [PATCH 0182/1021] Remove unused var. --- packages/bower-registry-client/test/Client.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 0973043e5..a82602f89 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -4,7 +4,6 @@ var RegistryClient = require('../Client'), nock = require('nock'); describe('RegistryClient', function () { - beforeEach(function () { this.uri = 'https://bower.herokuapp.com'; this.timeoutVal = 5000; @@ -20,7 +19,6 @@ describe('RegistryClient', function () { }); describe('Constructor', function () { - describe('instantiating a client', function () { it('should provide an instance of RegistryClient', function () { expect(this.registry instanceof RegistryClient).to.be.ok; @@ -85,9 +83,7 @@ describe('RegistryClient', function () { }); describe('instantiating a client with custom options', function () { - describe('offline', function () { - it('should not return search results ', function (next) { this.registry._config.offline = true; this.registry.search('jquery', function (err, results) { @@ -475,8 +471,6 @@ describe('RegistryClient', function () { }); it('should return results array', function (next) { - var self = this; - this.registry.list(function (err, results) { expect(results).to.be.an('array'); next(); From 774ad1e2ffbac8189df67defb18baeff9c53e9ef Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Sat, 27 Jul 2013 20:43:25 +0100 Subject: [PATCH 0183/1021] remove inline jshint rule this setting is covered by local node:true setting --- packages/bower-registry-client/Gruntfile.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/bower-registry-client/Gruntfile.js b/packages/bower-registry-client/Gruntfile.js index 162a9a579..11042a5d4 100644 --- a/packages/bower-registry-client/Gruntfile.js +++ b/packages/bower-registry-client/Gruntfile.js @@ -1,5 +1,3 @@ -/*global module:false*/ - module.exports = function (grunt) { 'use strict'; From 0dc5052e366a35bc9d868d445f05f1f1c25b1b54 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Sat, 27 Jul 2013 20:44:16 +0100 Subject: [PATCH 0184/1021] Close GH-9: adds grunt. --- packages/bower-json/.travis.yml | 4 ++- packages/bower-json/Gruntfile.js | 53 ++++++++++++++++++++++++++++++++ packages/bower-json/package.json | 8 +++-- 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 packages/bower-json/Gruntfile.js diff --git a/packages/bower-json/.travis.yml b/packages/bower-json/.travis.yml index 2ca91f289..7ab092601 100644 --- a/packages/bower-json/.travis.yml +++ b/packages/bower-json/.travis.yml @@ -1,4 +1,6 @@ +before_script: + - npm install -g grunt-cli language: node_js node_js: - "0.10" - - "0.8" \ No newline at end of file + - "0.8" diff --git a/packages/bower-json/Gruntfile.js b/packages/bower-json/Gruntfile.js new file mode 100644 index 000000000..7f8e1f52f --- /dev/null +++ b/packages/bower-json/Gruntfile.js @@ -0,0 +1,53 @@ +module.exports = function (grunt) { + + 'use strict'; + + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-simple-mocha'); + + // Project configuration. + grunt.initConfig({ + + jshint: { + files: [ + 'Gruntfile.js', + 'lib/**/*.js', + 'test/**/*.js' + ], + options: { + jshintrc: '.jshintrc' + } + }, + + simplemocha: { + options: { + reporter: 'spec' + }, + full: { src: ['test/test.js'] }, + short: { + options: { + reporter: 'dot' + }, + src: ['test/test.js'] + }, + build: { + options: { + reporter: 'tap' + }, + src: ['test/test.js'] + } + }, + + + watch: { + files: ['<%= jshint.files %>'], + tasks: ['jshint', 'simplemocha:short'] + } + + }); + + // Default task. + grunt.registerTask('test', ['simplemocha:full']); + grunt.registerTask('default', ['jshint', 'test']); +}; diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index f7e273afa..ad6c44714 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -23,9 +23,13 @@ }, "devDependencies": { "expect.js": "~0.2.0", - "mocha": "~1.12.0" + "mocha": "~1.12.0", + "grunt": "~0.4.1", + "grunt-contrib-watch": "~0.4.4", + "grunt-contrib-jshint": "~0.6.0", + "grunt-simple-mocha": "~0.4.0" }, "scripts": { - "test": "mocha -R spec" + "test": "grunt test" } } From 5e2abb8a333f97c07b8fceb50452546469e2a6a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 27 Jul 2013 22:21:21 +0100 Subject: [PATCH 0185/1021] Add .file property to errors throw in read(). --- packages/bower-json/lib/json.js | 12 +++++++++--- packages/bower-json/test/test.js | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index 1be9c3361..781357644 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -37,6 +37,7 @@ function read(file, options, callback) { try { json = JSON.parse(contents.toString()); } catch (err) { + err.file = path.resolve(file); err.code = 'EMALFORMED'; return callback(err); } @@ -45,6 +46,7 @@ function read(file, options, callback) { try { json = parse(json, options); } catch (err) { + err.file = path.resolve(file); return callback(err); } @@ -99,15 +101,19 @@ function normalize(json) { } function find(folder, callback) { - var file = path.resolve(path.join(folder, 'bower.json')); + var file = path.join(folder, 'bower.json'); fs.exists(file, function (exists) { - if (exists) return callback(null, file); + if (exists) { + return callback(null, file); + } file = path.resolve(path.join(folder, 'component.json')); fs.exists(file, function (exists) { - if (exists) return callback(null, file); + if (exists) { + return callback(null, file); + } var err = new Error('Neither bower.json nor component.json were found in ' + folder); err.code = 'ENOENT'; diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index ad9025cc4..8dd86206a 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -48,6 +48,7 @@ describe('.read', function () { bowerJson.read(__dirname + '/pkg-bower-json-malformed/bower.json', function (err) { expect(err).to.be.an(Error); expect(err.code).to.equal('EMALFORMED'); + expect(err.file).to.equal(path.resolve(__dirname + '/pkg-bower-json-malformed/bower.json')); done(); }); }); @@ -96,6 +97,7 @@ describe('.read', function () { bowerJson.read(__dirname + '/pkg-bower-json-invalid/bower.json', function (err) { expect(err).to.be.an(Error); expect(err.message).to.contain('name'); + expect(err.file).to.equal(path.resolve(__dirname + '/pkg-bower-json-invalid/bower.json')); bowerJson.read(__dirname + '/pkg-bower-json-invalid/bower.json', { validate: false }, function (err) { done(err); From 4cfa94d304647638748d16ca64806bdba47d1cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 27 Jul 2013 22:26:17 +0100 Subject: [PATCH 0186/1021] Bump to 0.2.0. --- packages/bower-json/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index ad6c44714..7401b77a8 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,6 +1,6 @@ { "name": "bower-json", - "version": "0.1.0-rc.1", + "version": "0.2.0", "description": "Read bower.json files with semantics, normalisation, defaults and validation.", "author": "Twitter", "licenses": [ From 897e0f1ba662dca4c9b036ed80446c9337bcbe75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 27 Jul 2013 22:28:56 +0100 Subject: [PATCH 0187/1021] Bump to 0.1.0. --- packages/bower-logger/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-logger/package.json b/packages/bower-logger/package.json index ce4f52185..92d51dc8a 100644 --- a/packages/bower-logger/package.json +++ b/packages/bower-logger/package.json @@ -1,6 +1,6 @@ { "name": "bower-logger", - "version": "0.1.0-rc.1", + "version": "0.1.0", "description": "The logger used in the various architecture components of Bower.", "author": "Twitter", "licenses": [ From f0d29cb7558249c38758725d7754764c48babf27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 27 Jul 2013 22:30:51 +0100 Subject: [PATCH 0188/1021] Bump to 0.1.0. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index a71e8a12f..a46b3fca2 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.1.0-rc.5", + "version": "0.1.0", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From 9269fcb8a7b3b3051af7b9a5090f2829359aab04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 28 Jul 2013 02:57:24 +0100 Subject: [PATCH 0189/1021] Add normalisation, fixes #5. Refactor a lot of code. --- packages/bower-config/README.md | 10 ++- packages/bower-config/lib/Config.js | 84 ++++++++-------------- packages/bower-config/lib/util/defaults.js | 41 +++++++++++ packages/bower-config/lib/util/expand.js | 53 ++++++++++++++ packages/bower-config/lib/util/rc.js | 1 + 5 files changed, 132 insertions(+), 57 deletions(-) create mode 100644 packages/bower-config/lib/util/defaults.js create mode 100644 packages/bower-config/lib/util/expand.js diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index 96d81ed3e..e9f4ef5f8 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -40,7 +40,9 @@ The `where` argument can be a path to a configuration file or: #### .toObject() -Returns a deep copy of the underlying configuration object. +Returns a deep copy of the underlying configuration object. +The returned configuration is normalised. +The object keys will be camelCase. #### #create(cwd) @@ -63,6 +65,12 @@ var configObject = (new Config(cwd)).load().toJson(); ``` +#### #normalise(config) + +Returns a new normalised config object based on `config`. +Object keys will be converted to camelCase. + + ## License Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index e8e1d1359..e66108eb7 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -1,23 +1,7 @@ -var os = require('os'); -var path = require('path'); var mout = require('mout'); var rc = require('./util/rc'); -var paths = require('./util/paths'); - -// Guess proxy defined in the env -/*jshint camelcase: false*/ -var proxy = process.env.HTTP_PROXY - || process.env.http_proxy - || null; - -var httpsProxy = process.env.HTTPS_PROXY - || process.env.https_proxy - || process.env.HTTP_PROXY - || process.env.http_proxy - || null; -/*jshint camelcase: true*/ - -//------------- +var defaults = require('./util/defaults'); +var expand = require('./util/expand'); function Config(cwd) { this._cwd = cwd || process.cwd(); @@ -25,43 +9,7 @@ function Config(cwd) { } Config.prototype.load = function () { - var runtimeConfig; - - runtimeConfig = rc('bower', { - 'cwd': this._cwd, - 'directory': 'bower_components', - 'registry': 'https://bower.herokuapp.com', - 'shorthand-resolver': 'git://github.com/{{owner}}/{{package}}.git', - 'tmp': os.tmpdir ? os.tmpdir() : os.tmpDir(), - 'proxy': proxy, - 'https-proxy': httpsProxy, - 'timeout': 60000, - 'ca': null, - 'strict-ssl': true, - 'user-agent': 'node/' + process.version + ' ' + process.platform + ' ' + process.arch, - 'color': true, - 'interactive': false, - 'storage': { - packages: path.join(paths.cache, 'packages'), - links: path.join(paths.data, 'links'), - completion: path.join(paths.data, 'completion'), - registry: path.join(paths.cache, 'registry'), - git: path.join(paths.data, 'git') - } - }, this._cwd); - - // Some backwards compatible things.. - runtimeConfig['shorthand-resolver'] = runtimeConfig['shorthand-resolver'] - .replace(/\{\{\{/g, '{{') - .replace(/\}\}\}/g, '}}'); - - // Generate config based on the rc, making every key camelCase - this._config = {}; - mout.object.forOwn(runtimeConfig, function (value, key) { - key = key.replace(/_/g, '-'); - this._config[mout.string.camelCase(key)] = value; - }, this); - + this._config = rc('bower', defaults, this._cwd); return this; }; @@ -84,7 +32,10 @@ Config.prototype.save = function (where, callback) { }; Config.prototype.toObject = function () { - return mout.lang.deepClone(this._config); + var config = mout.lang.deepClone(this._config); + + config = Config.normalise(config); + return config; }; Config.create = function (cwd) { @@ -96,4 +47,25 @@ Config.read = function (cwd) { return config.load().toObject(); }; +Config.normalise = function (rawConfig) { + var config = {}; + + // Mix in defaults and raw config + mout.object.deepMixIn(config, expand(defaults), expand(rawConfig)); + + // Some backwards compatible things.. + config.shorthandResolver = config.shorthandResolver + .replace(/\{\{\{/g, '{{') + .replace(/\}\}\}/g, '}}'); + + // Ensure that every registry endpoint does not end with / + config.registry.search = config.registry.search.map(function (url) { + return url.replace(/\/+$/, ''); + }); + config.registry.register = config.registry.register.replace(/\/+$/, ''); + config.registry.publish = config.registry.publish.replace(/\/+$/, ''); + + return config; +}; + module.exports = Config; diff --git a/packages/bower-config/lib/util/defaults.js b/packages/bower-config/lib/util/defaults.js new file mode 100644 index 000000000..6536f95ef --- /dev/null +++ b/packages/bower-config/lib/util/defaults.js @@ -0,0 +1,41 @@ +var os = require('os'); +var path = require('path'); +var paths = require('./paths'); + +// Guess proxy defined in the env +/*jshint camelcase: false*/ +var proxy = process.env.HTTP_PROXY + || process.env.http_proxy + || null; + +var httpsProxy = process.env.HTTPS_PROXY + || process.env.https_proxy + || process.env.HTTP_PROXY + || process.env.http_proxy + || null; +/*jshint camelcase: true*/ + +var defaults = { + 'cwd': process.cwd(), + 'directory': 'bower_components', + 'registry': 'https://bower.herokuapp.com', + 'shorthand-resolver': 'git://github.com/{{owner}}/{{package}}.git', + 'tmp': os.tmpdir ? os.tmpdir() : os.tmpDir(), + 'proxy': proxy, + 'https-proxy': httpsProxy, + 'timeout': 60000, + 'ca': { search: [] }, + 'strict-ssl': true, + 'user-agent': 'node/' + process.version + ' ' + process.platform + ' ' + process.arch, + 'color': true, + 'interactive': false, + 'storage': { + packages: path.join(paths.cache, 'packages'), + links: path.join(paths.data, 'links'), + completion: path.join(paths.data, 'completion'), + registry: path.join(paths.cache, 'registry'), + git: path.join(paths.data, 'git') + } +}; + +module.exports = defaults; diff --git a/packages/bower-config/lib/util/expand.js b/packages/bower-config/lib/util/expand.js new file mode 100644 index 000000000..6a4a114d6 --- /dev/null +++ b/packages/bower-config/lib/util/expand.js @@ -0,0 +1,53 @@ +var mout = require('mout'); + +function camelCase(config) { + var camelCased = {}; + + // Camel case + mout.object.forOwn(config, function (value, key) { + // Ignore null values + if (value == null) { + return; + } + + key = mout.string.camelCase(key.replace(/_/g, '-')); + camelCased[key] = mout.lang.isPlainObject(value) ? camelCase(value) : value; + }); + + return camelCased; +} + +function expand(config) { + config = camelCase(config); + + // Expand some properties + // Registry + if (typeof config.registry === 'string') { + config.registry = { + search: [config.registry], + register: config.registry, + publish: config.registry + }; + } else if (config.registry) { + if (!Array.isArray(config.registry.search)) { + config.registry.search = [config.registry.search]; + } + } + + // CA + if (typeof config.ca === 'string') { + config.ca = { + search: [config.ca], + register: config.ca, + publish: config.ca + }; + } else if (config.ca) { + if (!Array.isArray(config.ca.search)) { + config.ca.search = [config.ca.search]; + } + } + + return config; +} + +module.exports = expand; diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 33ecb09f7..b4c09907a 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -15,6 +15,7 @@ function rc(name, defaults, cwd, argv) { return mout.object.deepMixIn.apply(null, [ defaults, + { cwd: cwd }, win ? {} : json(path.join('/etc', name + 'rc')), json(path.join(home, '.' + name + 'rc')), json(path.join(paths.config, name + 'rc')), From 64b5f9af78a6582e1cc00ed140a95db41977bcbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 28 Jul 2013 02:58:08 +0100 Subject: [PATCH 0190/1021] Bump to 0.2.0 rc1. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index ffbba986a..b3a1ace1f 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.1.0-rc.5", + "version": "0.2.0-rc.1", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 634ce6829a099161c70f1e88b618954546e8d4fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 28 Jul 2013 03:03:39 +0100 Subject: [PATCH 0191/1021] Use bower-config to normalise the config object. --- packages/bower-registry-client/Client.js | 68 ++------------------- packages/bower-registry-client/README.md | 2 +- packages/bower-registry-client/package.json | 2 +- 3 files changed, 7 insertions(+), 65 deletions(-) diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js index 717ef95b7..a30a403e3 100644 --- a/packages/bower-registry-client/Client.js +++ b/packages/bower-registry-client/Client.js @@ -1,75 +1,17 @@ -var os = require('os'); -var path = require('path'); var async = require('async'); -var deepExtend = require('deep-extend'); +var Config = require('bower-config'); var methods = require('./lib'); var Cache = require('./lib/util/Cache'); function RegistryClient(config, logger) { - var bowerRegistry = 'https://bower.herokuapp.com'; - - config = config || {}; - this._config = config; this._logger = logger; + this._config = Config.normalise(config); - // Parse config - // Registry - config.registry = config.registry || bowerRegistry; - if (typeof config.registry === 'string') { - config.registry = { - search: [config.registry], - register: config.registry, - publish: config.registry - }; - } else { - config.registry = deepExtend({ - search: bowerRegistry, - register: bowerRegistry, - publish: bowerRegistry - }, config.registry); - - if (!Array.isArray(config.registry.search)) { - config.registry.search = [config.registry.search]; - } - } - - // Ensure that every registry endpoint does not end with / - config.registry.search = config.registry.search.map(function (url) { - return url.replace(/\/+$/, ''); - }); - config.registry.register = config.registry.register.replace(/\/+$/, ''); - config.registry.publish = config.registry.publish.replace(/\/+$/, ''); - - // CA - if (typeof config.ca === 'string') { - config.ca = { - search: [config.ca], - register: config.ca, - publish: config.ca - }; - } else { - config.ca = deepExtend({ - search: [] - }, config.ca); - - if (!Array.isArray(config.ca.search)) { - config.ca.search = [config.ca.search]; - } + // Cache defaults to storage registry + if (!Object.prototype.hasOwnProperty.call(this._config, 'cache')) { + this._config.cache = this._config.storage.registry; } - // Cache - if (!config.cache) { - config.cache = path.join(os.tmpdir ? os.tmpdir() : os.tmpDir(), 'bower-registry'); - } - - // Timeout - if (typeof config.timeout !== 'number') { - config.timeout = 60000; - } - - // Strict ssl - config.strictSsl = config.strictSsl == null ? true : !!config.strictSsl; - // Init the cache this._initCache(); } diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index dcf9712a0..6896e2703 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -14,7 +14,7 @@ var registry = new RegistryClient(options, logger); The `logger` is optional and is expected to be an instance of the bower [logger](https://github.com/bower/logger). Available constructor options: -- `cache`: the cache folder to use for some operations; using null will disable persistent cache (defaults to OS temp folder) +- `cache`: the cache folder to use for some operations; using null will disable persistent cache (defaults to bower registry cache folder) - `registry.search`: an array of registry search endpoints (defaults to the Bower server) - `registry.register`: the endpoint to use when registering packages (defaults to the Bower server) - `registry.publish`: the endpoint to use when publishing packages (defaults to the Bower server) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index a46b3fca2..2a21e6ac2 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "async": "~0.2.8", - "deep-extend": "~0.2.5", + "bower-config": "~0.2.0-rc.1", "graceful-fs": "~2.0.0", "lru-cache": "~2.3.0", "request": "~2.22.0", From f027cc6a3eb2840a8b17ba2b051282e4def31a28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 28 Jul 2013 03:03:56 +0100 Subject: [PATCH 0192/1021] Bump version. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 2a21e6ac2..02c08251a 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.1.0", + "version": "0.1.1", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From 03b4467173b257d71e8ae2bcd59f9343e1270cde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 28 Jul 2013 03:20:09 +0100 Subject: [PATCH 0193/1021] Update deps. --- packages/bower-registry-client/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 02c08251a..428069adb 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -19,10 +19,10 @@ }, "dependencies": { "async": "~0.2.8", - "bower-config": "~0.2.0-rc.1", + "bower-config": "~0.2.0", "graceful-fs": "~2.0.0", "lru-cache": "~2.3.0", - "request": "~2.22.0", + "request": "~2.25.0", "request-replay": "~0.1.0", "rimraf": "~2.2.0", "mkdirp": "~0.3.5" From ed0c93aec399bd187421b2f98504f852c926a4ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 28 Jul 2013 18:21:24 +0100 Subject: [PATCH 0194/1021] Add trim to everything. --- packages/bower-endpoint-parser/index.js | 45 ++++--- packages/bower-endpoint-parser/test/test.js | 141 ++++++++++++++++---- 2 files changed, 140 insertions(+), 46 deletions(-) diff --git a/packages/bower-endpoint-parser/index.js b/packages/bower-endpoint-parser/index.js index f499eee33..76ccd6e45 100644 --- a/packages/bower-endpoint-parser/index.js +++ b/packages/bower-endpoint-parser/index.js @@ -1,4 +1,5 @@ function decompose(endpoint) { + // Note that we allow spaces in targets and sources but they are trimmed var regExp = /^(?:([\w\-]|(?:[\w\.\-]+[\w\-])?)=)?([^\|#]+)(?:#(.*))?$/; var matches = endpoint.match(regExp); var target; @@ -14,8 +15,8 @@ function decompose(endpoint) { return { name: matches[1] || '', - source: matches[2], - target: !target || target === 'latest' ? '*' : target + source: (matches[2]).trim(), + target: !target || target === 'latest' ? '*' : target.trim() }; } @@ -23,31 +24,31 @@ function compose(decEndpoint) { var composed = ''; if (decEndpoint.name) { - composed += decEndpoint.name + '='; + composed += decEndpoint.name.trim() + '='; } - composed += decEndpoint.source; + composed += decEndpoint.source.trim(); if (!isWildcard(decEndpoint.target)) { - composed += '#' + decEndpoint.target; + composed += '#' + decEndpoint.target.trim(); } return composed; } function json2decomposed(key, value) { - var endpoint = key + '='; + var endpoint = key.trim() + '='; var split = value.split('#'); // If # was found, the source was specified if (split.length > 1) { - endpoint += (split[0] || key) + '#' + split[1]; + endpoint += (split[0] || key).trim() + '#' + split[1].trim(); // Check if value looks like a source } else if (isSource(value)) { - endpoint += value + '#*'; + endpoint += value.trim() + '#*'; // Otherwise use the key as the source } else { - endpoint += key + '#' + split[0]; + endpoint += key.trim() + '#' + split[0].trim(); } return decompose(endpoint); @@ -55,36 +56,44 @@ function json2decomposed(key, value) { function decomposed2json(decEndpoint) { var error; - var key = decEndpoint.name; + var name = decEndpoint.name.trim(); + var source = decEndpoint.source.trim(); + var target = decEndpoint.target.trim(); var value = ''; var ret = {}; - if (!key) { + if (!name) { error = new Error('Decomposed endpoint must have a name'); error.code = 'EINVEND'; throw error; } // Add source only if different than the name - if (decEndpoint.source !== decEndpoint.name) { - value += decEndpoint.source; + if (source !== name) { + value += source; } // If value is empty, we append the target always if (!value) { - value += isWildcard(decEndpoint.target) ? '*' : decEndpoint.target; + value += isWildcard(target) ? '*' : target; // Otherwise append only if not a wildcard - } else if (!isWildcard(decEndpoint.target)) { - value += '#' + decEndpoint.target; + } else if (!isWildcard(target)) { + value += '#' + target; } - ret[key] = value; + ret[name] = value; return ret; } function isWildcard(target) { - return !target || target === '*' || target === 'latest'; + if (!target) { + return true; + } + + target = target.trim(); + + return target === '*' || target === 'latest'; } function isSource(value) { diff --git a/packages/bower-endpoint-parser/test/test.js b/packages/bower-endpoint-parser/test/test.js index 7c15f53af..6f6610ef0 100644 --- a/packages/bower-endpoint-parser/test/test.js +++ b/packages/bower-endpoint-parser/test/test.js @@ -23,6 +23,12 @@ describe('endpoint-parser', function () { expect(endpointParser.decompose(endpoint)).to.eql(decEndpoint); }); }); + + it('should trim sources and targets', function () { + var decEndpoint = endpointParser.decompose('foo= source # ~1.0.2 '); + expect(decEndpoint.source).to.equal('source'); + expect(decEndpoint.target).to.equal('~1.0.2'); + }); }); describe('.compose', function () { @@ -45,9 +51,50 @@ describe('endpoint-parser', function () { }); }); }); + + it('should trim values', function () { + expect(endpointParser.compose({ + name: ' foo ', + source: ' bar ', + target: ' ~1.0.2 ' + })).to.equal('foo=bar#~1.0.2'); + + expect(endpointParser.compose({ + name: ' foo ', + source: ' foo ', + target: ' ~1.0.2 ' + })).to.equal('foo=foo#~1.0.2'); + + expect(endpointParser.compose({ + name: ' foo ', + source: ' foo ', + target: ' * ' + })).to.equal('foo=foo'); + + expect(endpointParser.compose({ + name: ' foo ', + source: ' foo ', + target: ' * ' + })).to.equal('foo=foo'); + }); }); describe('.json2decomposed', function () { + var expected = [ + { name: 'jquery', source: 'jquery', target: '~1.9.1' }, + { name: 'foo', source: 'foo', target: '*' }, + { name: 'bar', source: 'bar', target: '*' }, + { name: 'baz', source: 'baz', target: '~0.2.0' }, + { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }, + { name: 'backbone2', source: 'backbone=backbone-amd', target: '~1.0.0' }, + { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }, + { name: 'bootstrap2', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }, + { name: 'ssh', source: 'git@example.com', target: '*' }, + { name: 'git', source: 'git://example.com', target: '*' }, + { name: 'path', source: '/foo', target: '*' }, + { name: 'winpath', source: 'c:\\foo', target: '*' } + ]; + it('should decompose json endpoints correctly', function () { var dependencies = { jquery: '~1.9.1', @@ -63,20 +110,29 @@ describe('endpoint-parser', function () { path: '/foo', winpath: 'c:\\foo' }; - var expected = [ - { name: 'jquery', source: 'jquery', target: '~1.9.1' }, - { name: 'foo', source: 'foo', target: '*' }, - { name: 'bar', source: 'bar', target: '*' }, - { name: 'baz', source: 'baz', target: '~0.2.0' }, - { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }, - { name: 'backbone2', source: 'backbone=backbone-amd', target: '~1.0.0' }, - { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }, - { name: 'bootstrap2', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }, - { name: 'ssh', source: 'git@example.com', target: '*' }, - { name: 'git', source: 'git://example.com', target: '*' }, - { name: 'path', source: '/foo', target: '*' }, - { name: 'winpath', source: 'c:\\foo', target: '*' } - ]; + var x = 0; + + mout.object.forOwn(dependencies, function (value, key) { + expect(endpointParser.json2decomposed(key, value)).to.eql(expected[x]); + x += 1; + }); + }); + + it('should trim values', function () { + var dependencies = { + ' jquery ': ' ~1.9.1 ', + ' foo ': ' latest ', + ' bar ': ' * ', + ' baz ': '# ~0.2.0 ', + ' backbone ': ' backbone-amd#~1.0.0 ', + ' backbone2 ': ' backbone=backbone-amd # ~1.0.0 ', + ' bootstrap ': ' http://twitter.github.io/bootstrap/assets/bootstrap', + ' bootstrap2 ': ' http://twitter.github.io/bootstrap/assets/bootstrap # *', + ' ssh ': ' git@example.com ', + ' git ': ' git://example.com ', + ' path ': ' /foo ', + ' winpath ': ' c:\\foo ' + }; var x = 0; mout.object.forOwn(dependencies, function (value, key) { @@ -87,6 +143,20 @@ describe('endpoint-parser', function () { }); describe('.decomposed2json', function () { + var expected = [ + { jquery: '~1.9.1' }, + { foo: '*' }, + { bar: '*' }, + { baz: '*' }, + { jqueryx: 'jquery#~1.9.1' }, + { backbone: 'backbone-amd#~1.0.0' }, + { backbone : 'backbone=backbone-amd#~1.0.0' }, + { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' }, + { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' }, + { ssh: 'git@example.com' }, + { git: 'git://example.com' } + ]; + it('should compose endpoints to json correctly', function () { var decEndpoints = [ { name: 'jquery', source: 'jquery', target: '~1.9.1' }, @@ -101,18 +171,27 @@ describe('endpoint-parser', function () { { name: 'ssh', source: 'git@example.com', target: '*' }, { name: 'git', source: 'git://example.com', target: '*' } ]; - var expected = [ - { jquery: '~1.9.1' }, - { foo: '*' }, - { bar: '*' }, - { baz: '*' }, - { jqueryx: 'jquery#~1.9.1' }, - { backbone: 'backbone-amd#~1.0.0' }, - { backbone : 'backbone=backbone-amd#~1.0.0' }, - { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' }, - { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' }, - { ssh: 'git@example.com' }, - { git: 'git://example.com' } + var x = 0; + + decEndpoints.forEach(function (decEndpoint) { + expect(endpointParser.decomposed2json(decEndpoint)).to.eql(expected[x]); + x += 1; + }); + }); + + it('should trim values', function () { + var decEndpoints = [ + { name: ' jquery ', source: ' jquery ', target: ' ~1.9.1 ' }, + { name: 'foo', source: ' foo', target: ' latest ' }, + { name: 'bar', source: 'bar ', target: ' * ' }, + { name: 'baz ', source: 'baz', target: ' ' }, + { name: ' jqueryx ', source: ' jquery ', target: ' ~1.9.1 ' }, + { name: ' backbone ', source: ' backbone-amd ', target: ' ~1.0.0 ' }, + { name: ' backbone ', source: ' backbone=backbone-amd ', target: ' ~1.0.0 ' }, + { name: ' bootstrap ', source: ' http://twitter.github.io/bootstrap/assets/bootstrap ', target: ' ' }, + { name: ' bootstrap ', source: ' http://twitter.github.io/bootstrap/assets/bootstrap ', target: ' * ' }, + { name: ' ssh ', source: ' git@example.com ', target: ' * ' }, + { name: ' git ', source: ' git://example.com ', target: ' * ' } ]; var x = 0; @@ -125,13 +204,19 @@ describe('endpoint-parser', function () { it('should throw an error if name is empty', function () { try { endpointParser.decomposed2json({ name: '', source: 'jquery', target: '*' }); + throw new Error('Should have failed'); } catch (e) { expect(e.code).to.equal('EINVEND'); expect(e.message).to.contain('must have a name'); - return; } - throw new Error('Should have failed'); + try { + endpointParser.decomposed2json({ name: ' ', source: 'jquery', target: '*' }); + throw new Error('Should have failed'); + } catch (e) { + expect(e.code).to.equal('EINVEND'); + expect(e.message).to.contain('must have a name'); + } }); }); }); From 05b94d1d15339f2da53e48caf0a58d6ab372d9eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 28 Jul 2013 18:48:31 +0100 Subject: [PATCH 0195/1021] Add more tests and fix stuff. --- packages/bower-endpoint-parser/index.js | 62 +++++++++++++-------- packages/bower-endpoint-parser/test/test.js | 32 +++++++++++ 2 files changed, 70 insertions(+), 24 deletions(-) diff --git a/packages/bower-endpoint-parser/index.js b/packages/bower-endpoint-parser/index.js index 76ccd6e45..14ca9d005 100644 --- a/packages/bower-endpoint-parser/index.js +++ b/packages/bower-endpoint-parser/index.js @@ -11,44 +11,60 @@ function decompose(endpoint) { throw error; } - target = matches[3]; + target = trim(matches[3]); return { - name: matches[1] || '', - source: (matches[2]).trim(), - target: !target || target === 'latest' ? '*' : target.trim() + name: trim(matches[1]), + source: trim(matches[2]), + target: isWildcard(target) ? '*' : target }; } function compose(decEndpoint) { + var name = trim(decEndpoint.name); + var source = trim(decEndpoint.source); + var target = trim(decEndpoint.target); var composed = ''; - if (decEndpoint.name) { - composed += decEndpoint.name.trim() + '='; + if (name) { + composed += name + '='; } - composed += decEndpoint.source.trim(); + composed += source; - if (!isWildcard(decEndpoint.target)) { - composed += '#' + decEndpoint.target.trim(); + if (!isWildcard(target)) { + composed += '#' + target; } return composed; } function json2decomposed(key, value) { - var endpoint = key.trim() + '='; - var split = value.split('#'); + var endpoint; + var split; + var error; + + key = trim(key); + value = trim(value); + + if (!key) { + error = new Error('The key must be specified'); + error.code = 'EINVEND'; + throw error; + } + + endpoint = key + '='; + split = value.split('#').map(trim); // If # was found, the source was specified if (split.length > 1) { - endpoint += (split[0] || key).trim() + '#' + split[1].trim(); + endpoint += (split[0] || key) + '#' + split[1]; // Check if value looks like a source } else if (isSource(value)) { - endpoint += value.trim() + '#*'; + endpoint += value + '#*'; // Otherwise use the key as the source } else { - endpoint += key.trim() + '#' + split[0].trim(); + endpoint += key + '#' + split[0]; } return decompose(endpoint); @@ -56,9 +72,9 @@ function json2decomposed(key, value) { function decomposed2json(decEndpoint) { var error; - var name = decEndpoint.name.trim(); - var source = decEndpoint.source.trim(); - var target = decEndpoint.target.trim(); + var name = trim(decEndpoint.name); + var source = trim(decEndpoint.source); + var target = trim(decEndpoint.target); var value = ''; var ret = {}; @@ -86,14 +102,12 @@ function decomposed2json(decEndpoint) { return ret; } -function isWildcard(target) { - if (!target) { - return true; - } - - target = target.trim(); +function trim(str) { + return str ? str.trim() : ''; +} - return target === '*' || target === 'latest'; +function isWildcard(target) { + return !target || target === '*' || target === 'latest'; } function isSource(value) { diff --git a/packages/bower-endpoint-parser/test/test.js b/packages/bower-endpoint-parser/test/test.js index 6f6610ef0..47a23e8da 100644 --- a/packages/bower-endpoint-parser/test/test.js +++ b/packages/bower-endpoint-parser/test/test.js @@ -28,6 +28,14 @@ describe('endpoint-parser', function () { var decEndpoint = endpointParser.decompose('foo= source # ~1.0.2 '); expect(decEndpoint.source).to.equal('source'); expect(decEndpoint.target).to.equal('~1.0.2'); + + decEndpoint = endpointParser.decompose('foo= source # latest'); + expect(decEndpoint.source).to.equal('source'); + expect(decEndpoint.target).to.equal('*'); + + decEndpoint = endpointParser.decompose('foo= source # *'); + expect(decEndpoint.source).to.equal('source'); + expect(decEndpoint.target).to.equal('*'); }); }); @@ -76,6 +84,12 @@ describe('endpoint-parser', function () { source: ' foo ', target: ' * ' })).to.equal('foo=foo'); + + expect(endpointParser.compose({ + name: ' ', + source: ' foo ', + target: '' + })).to.equal('foo'); }); }); @@ -140,6 +154,24 @@ describe('endpoint-parser', function () { x += 1; }); }); + + it('should error out if key is not specified', function () { + try { + endpointParser.json2decomposed(null); + throw new Error('Should have failed'); + } catch (e) { + expect(e.code).to.equal('EINVEND'); + expect(e.message).to.contain('key must be specified'); + } + + try { + endpointParser.json2decomposed(''); + throw new Error('Should have failed'); + } catch (e) { + expect(e.code).to.equal('EINVEND'); + expect(e.message).to.contain('key must be specified'); + } + }); }); describe('.decomposed2json', function () { From 766dcd0dd502f2bf0d3a3c446f3f5c717a0fe76b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 29 Jul 2013 23:14:27 +0100 Subject: [PATCH 0196/1021] Bump version. --- packages/bower-endpoint-parser/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-endpoint-parser/package.json b/packages/bower-endpoint-parser/package.json index 8ac459c06..7a473b044 100644 --- a/packages/bower-endpoint-parser/package.json +++ b/packages/bower-endpoint-parser/package.json @@ -1,6 +1,6 @@ { "name": "bower-endpoint-parser", - "version": "0.1.0", + "version": "0.2.0", "description": "Little module that helps with endpoints parsing.", "author": "Twitter", "licenses": [ From 82d16fbfde06a35f0325aeb1958f3d766520d46a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Fri, 2 Aug 2013 08:25:35 +0100 Subject: [PATCH 0197/1021] Change timeout to 30sec. --- packages/bower-config/lib/util/defaults.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/defaults.js b/packages/bower-config/lib/util/defaults.js index 6536f95ef..2bb57c774 100644 --- a/packages/bower-config/lib/util/defaults.js +++ b/packages/bower-config/lib/util/defaults.js @@ -23,7 +23,7 @@ var defaults = { 'tmp': os.tmpdir ? os.tmpdir() : os.tmpDir(), 'proxy': proxy, 'https-proxy': httpsProxy, - 'timeout': 60000, + 'timeout': 30000, 'ca': { search: [] }, 'strict-ssl': true, 'user-agent': 'node/' + process.version + ' ' + process.platform + ' ' + process.arch, From e8f3e3b88a0c3925e088f2079176392786ad036f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 2 Aug 2013 21:09:54 +0100 Subject: [PATCH 0198/1021] Set timeout default value to 30sec. --- packages/bower-config/lib/util/defaults.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/defaults.js b/packages/bower-config/lib/util/defaults.js index 6536f95ef..2bb57c774 100644 --- a/packages/bower-config/lib/util/defaults.js +++ b/packages/bower-config/lib/util/defaults.js @@ -23,7 +23,7 @@ var defaults = { 'tmp': os.tmpdir ? os.tmpdir() : os.tmpDir(), 'proxy': proxy, 'https-proxy': httpsProxy, - 'timeout': 60000, + 'timeout': 30000, 'ca': { search: [] }, 'strict-ssl': true, 'user-agent': 'node/' + process.version + ' ' + process.platform + ' ' + process.arch, From 3ed9b3ec3982ca7e1ae12ebb7123a79309c71199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 2 Aug 2013 21:10:10 +0100 Subject: [PATCH 0199/1021] Fix default values being mutated. --- packages/bower-config/lib/util/rc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index b4c09907a..308668497 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -14,6 +14,7 @@ function rc(name, defaults, cwd, argv) { argv = argv || optimist.argv; return mout.object.deepMixIn.apply(null, [ + {}, defaults, { cwd: cwd }, win ? {} : json(path.join('/etc', name + 'rc')), From ea7ae5698a63ed2f300722713bbe68b6ea0bc983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 2 Aug 2013 21:10:31 +0100 Subject: [PATCH 0200/1021] Do not set undefined values in array. --- packages/bower-config/lib/util/expand.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-config/lib/util/expand.js b/packages/bower-config/lib/util/expand.js index 6a4a114d6..f3a3865d6 100644 --- a/packages/bower-config/lib/util/expand.js +++ b/packages/bower-config/lib/util/expand.js @@ -29,7 +29,7 @@ function expand(config) { publish: config.registry }; } else if (config.registry) { - if (!Array.isArray(config.registry.search)) { + if (config.registry.search && !Array.isArray(config.registry.search)) { config.registry.search = [config.registry.search]; } } @@ -42,7 +42,7 @@ function expand(config) { publish: config.ca }; } else if (config.ca) { - if (!Array.isArray(config.ca.search)) { + if (config.ca.search && !Array.isArray(config.ca.search)) { config.ca.search = [config.ca.search]; } } From 8b699c58aeae344132f0bd6d1292467ecbb8bf27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 2 Aug 2013 21:12:54 +0100 Subject: [PATCH 0201/1021] Bump rc version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index b3a1ace1f..51425eb23 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.2.0-rc.1", + "version": "0.2.0-rc.2", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 39f1f8aff5f0dc2dc3a4f70431f9fb7d03892edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 3 Aug 2013 12:38:21 +0100 Subject: [PATCH 0202/1021] Improve retry error messages. Also fixed "undefined" being printed as the url. --- packages/bower-registry-client/lib/list.js | 9 ++++++--- packages/bower-registry-client/lib/lookup.js | 9 ++++++--- packages/bower-registry-client/lib/search.js | 9 ++++++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/bower-registry-client/lib/list.js b/packages/bower-registry-client/lib/list.js index 70cc2a211..6234d0bb2 100644 --- a/packages/bower-registry-client/lib/list.js +++ b/packages/bower-registry-client/lib/list.js @@ -82,11 +82,12 @@ function addResult(accumulated, result) { } function doRequest(index, callback) { + var req; + var msg; var requestUrl = this._config.registry.search[index] + '/packages'; var remote = url.parse(requestUrl); var headers = {}; var that = this; - var req; if (this._config.userAgent) { headers['User-Agent'] = this._config.userAgent; @@ -119,8 +120,10 @@ function doRequest(index, callback) { })); if (this._logger) { - req.on('replay', function (nr, error) { - that._logger.debug('retry', 'Retrying request to ' + this._source + ' because it failed with ' + error.code); + req.on('replay', function (replay) { + msg = 'Request to ' + requestUrl + ' failed with ' + replay.error.code + ', '; + msg += 'retrying in ' + (replay.delay / 1000).toFixed(1) + 's'; + that._logger.warn('retry', msg); }); } } diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index ed0ba38dc..7303bc2c2 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -74,10 +74,11 @@ function lookup(name, callback) { } function doRequest(name, index, callback) { + var req; + var msg; var requestUrl = this._config.registry.search[index] + '/packages/' + encodeURIComponent(name); var remote = url.parse(requestUrl); var headers = {}; - var req; var that = this; if (this._config.userAgent) { @@ -119,8 +120,10 @@ function doRequest(name, index, callback) { })); if (this._logger) { - req.on('replay', function (nr, error) { - that._logger.debug('retry', 'Retrying request to ' + this._source + ' because it failed with ' + error.code); + req.on('replay', function (replay) { + msg = 'Request to ' + requestUrl + ' failed with ' + replay.error.code + ', '; + msg += 'retrying in ' + (replay.delay / 1000).toFixed(1) + 's'; + that._logger.warn('retry', msg); }); } } diff --git a/packages/bower-registry-client/lib/search.js b/packages/bower-registry-client/lib/search.js index cfcd06e71..9b2144318 100644 --- a/packages/bower-registry-client/lib/search.js +++ b/packages/bower-registry-client/lib/search.js @@ -90,11 +90,12 @@ function addResult(accumulated, result) { } function doRequest(name, index, callback) { + var req; + var msg; var requestUrl = this._config.registry.search[index] + '/packages/search/' + encodeURIComponent(name); var remote = url.parse(requestUrl); var headers = {}; var that = this; - var req; if (this._config.userAgent) { headers['User-Agent'] = this._config.userAgent; @@ -127,8 +128,10 @@ function doRequest(name, index, callback) { })); if (this._logger) { - req.on('replay', function (nr, error) { - that._logger.debug('retry', 'Retrying request to ' + this._source + ' because it failed with ' + error.code); + req.on('replay', function (replay) { + msg = 'Request to ' + requestUrl + ' failed with ' + replay.error.code + ', '; + msg += 'retrying in ' + (replay.delay / 1000).toFixed(1) + 's'; + that._logger.warn('retry', msg); }); } } From c21bde192be628d97cf8f975fdea5369f4a8f071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 3 Aug 2013 12:44:07 +0100 Subject: [PATCH 0203/1021] Fix failing test. --- packages/bower-registry-client/test/Client.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index a82602f89..6e6c5cee2 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -84,13 +84,16 @@ describe('RegistryClient', function () { describe('instantiating a client with custom options', function () { describe('offline', function () { - it('should not return search results ', function (next) { - this.registry._config.offline = true; - this.registry.search('jquery', function (err, results) { - expect(err).to.be(null); - expect(results.length).to.eql(0); - next(); - }); + it('should not return search results if cache is empty', function (next) { + // TODO: this test should be made individually for search, list and lookup + this.registry.clearCache(function () { + this.registry._config.offline = true; + this.registry.search('jquery', function (err, results) { + expect(err).to.be(null); + expect(results.length).to.eql(0); + next(); + }); + }.bind(this)); }); }); From c63d88d987ce7ae2111343a8da61c03ea82b97a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 3 Aug 2013 12:44:18 +0100 Subject: [PATCH 0204/1021] Bump version. --- packages/bower-registry-client/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 428069adb..49e5e69ee 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.1.1", + "version": "0.1.2", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ @@ -23,7 +23,7 @@ "graceful-fs": "~2.0.0", "lru-cache": "~2.3.0", "request": "~2.25.0", - "request-replay": "~0.1.0", + "request-replay": "~0.2.0", "rimraf": "~2.2.0", "mkdirp": "~0.3.5" }, From 8da47dcd0008a76d96acd40a5b2c8bf7ca851f56 Mon Sep 17 00:00:00 2001 From: Nick Heiner Date: Mon, 5 Aug 2013 14:10:57 +0100 Subject: [PATCH 0205/1021] Close GH-10: Find .bower.json if it exists. --- packages/bower-json/lib/json.js | 28 +++++++++++-------- .../test/pkg-dot-bower-json/.bower.json | 5 ++++ packages/bower-json/test/test.js | 13 ++++++++- 3 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 packages/bower-json/test/pkg-dot-bower-json/.bower.json diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index 781357644..236dda73b 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -3,6 +3,8 @@ var path = require('path'); var deepExtend = require('deep-extend'); var createError = require('./util/createError'); +var possibleJsons = ['bower.json', 'component.json', '.bower.json']; + function read(file, options, callback) { if (typeof options === 'function') { callback = options; @@ -101,25 +103,27 @@ function normalize(json) { } function find(folder, callback) { - var file = path.join(folder, 'bower.json'); - fs.exists(file, function (exists) { - if (exists) { - return callback(null, file); - } + function findRec(fileNames) { + var err; + var fileName; - file = path.resolve(path.join(folder, 'component.json')); + if (!fileNames.length) { + err = createError('bower-json: None of "' + possibleJsons.join('", "') + '" were found in ' + folder, 'ENOENT'); + return callback(err); + } - fs.exists(file, function (exists) { + fileName = path.resolve(path.join(folder, fileNames[0])); + fs.exists(fileName, function(exists) { if (exists) { - return callback(null, file); + return callback(null, fileName); } - var err = new Error('Neither bower.json nor component.json were found in ' + folder); - err.code = 'ENOENT'; - callback(err); + findRec(fileNames.slice(1)); }); - }); + } + + findRec(possibleJsons); } module.exports = read; diff --git a/packages/bower-json/test/pkg-dot-bower-json/.bower.json b/packages/bower-json/test/pkg-dot-bower-json/.bower.json new file mode 100644 index 000000000..d475c459a --- /dev/null +++ b/packages/bower-json/test/pkg-dot-bower-json/.bower.json @@ -0,0 +1,5 @@ +{ + "name": "some-installed-pkg", + "version": "0.0.1", + "main": "bar.js" +} diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index 8dd86206a..bd77c8f0b 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -25,11 +25,22 @@ describe('.find', function () { }); }); + it('should fallback to the .bower.json file', function(done) { + bowerJson.find(__dirname + '/pkg-dot-bower-json', function(err, file) { + if (err) { + return done(err); + } + + expect(file).to.equal(path.resolve(__dirname + '/pkg-dot-bower-json/.bower.json')); + done(); + }); + }) + it('should error if no component.json / bower.json is found', function (done) { bowerJson.find(__dirname, function (err) { expect(err).to.be.an(Error); expect(err.code).to.equal('ENOENT'); - expect(err.message).to.equal('Neither bower.json nor component.json were found in ' + __dirname); + expect(err.message).to.equal('bower-json: None of "bower.json", "component.json", ".bower.json" were found in ' + __dirname); done(); }); }); From 990e87de1fc948084f44ea25d2671f15b57f15aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 5 Aug 2013 14:16:53 +0100 Subject: [PATCH 0206/1021] Tweaks to the last PR. --- packages/bower-json/lib/json.js | 33 ++++++++++++++++---------------- packages/bower-json/test/test.js | 10 +++++----- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index 236dda73b..45f879392 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -103,27 +103,26 @@ function normalize(json) { } function find(folder, callback) { + findRec(folder, possibleJsons, callback); +} - function findRec(fileNames) { - var err; - var fileName; - - if (!fileNames.length) { - err = createError('bower-json: None of "' + possibleJsons.join('", "') + '" were found in ' + folder, 'ENOENT'); - return callback(err); - } - - fileName = path.resolve(path.join(folder, fileNames[0])); - fs.exists(fileName, function(exists) { - if (exists) { - return callback(null, fileName); - } +function findRec(folder, files, callback) { + var err; + var file; - findRec(fileNames.slice(1)); - }); + if (!files.length) { + err = createError('None of ' + possibleJsons.join(', ') + ' were found in ' + folder, 'ENOENT'); + return callback(err); } - findRec(possibleJsons); + file = path.resolve(path.join(folder, files[0])); + fs.exists(file, function (exists) { + if (exists) { + return callback(null, file); + } + + findRec(folder, files.slice(1), callback); + }); } module.exports = read; diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index bd77c8f0b..7e9065c02 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -25,8 +25,8 @@ describe('.find', function () { }); }); - it('should fallback to the .bower.json file', function(done) { - bowerJson.find(__dirname + '/pkg-dot-bower-json', function(err, file) { + it('should fallback to the .bower.json file', function (done) { + bowerJson.find(__dirname + '/pkg-dot-bower-json', function (err, file) { if (err) { return done(err); } @@ -34,13 +34,13 @@ describe('.find', function () { expect(file).to.equal(path.resolve(__dirname + '/pkg-dot-bower-json/.bower.json')); done(); }); - }) + }); - it('should error if no component.json / bower.json is found', function (done) { + it('should error if no component.json / bower.json / .bower.json is found', function (done) { bowerJson.find(__dirname, function (err) { expect(err).to.be.an(Error); expect(err.code).to.equal('ENOENT'); - expect(err.message).to.equal('bower-json: None of "bower.json", "component.json", ".bower.json" were found in ' + __dirname); + expect(err.message).to.equal('None of bower.json, component.json, .bower.json were found in ' + __dirname); done(); }); }); From d0929896cf4632c2fb4e7715714bd0dff44b41e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 5 Aug 2013 14:22:41 +0100 Subject: [PATCH 0207/1021] Update README. --- packages/bower-json/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index de4a29018..1e1944f93 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -103,7 +103,7 @@ json.main // ['foo.js', 'bar.js'] #### .find(folder, callback) Finds the `json` filename inside a folder. -Checks if a `bower.json` exists, falling back to the deprecated `component.json`. +Checks if a `bower.json` exists, falling back to `component.json` (deprecated) and `.bower.json`. If no file was found, the callback is called with a `error.code` of `ENOENT`. ```js From 606426993601624b636d2a72a77cdbe2dc6cf9f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 5 Aug 2013 14:22:51 +0100 Subject: [PATCH 0208/1021] Bump version. --- packages/bower-json/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 7401b77a8..fbe6e2d37 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,6 +1,6 @@ { "name": "bower-json", - "version": "0.2.0", + "version": "0.3.0", "description": "Read bower.json files with semantics, normalisation, defaults and validation.", "author": "Twitter", "licenses": [ From 0b3b7efccf7cba39f5782202f60d3b6c30b7e8b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 5 Aug 2013 23:36:11 +0100 Subject: [PATCH 0209/1021] Minor improvement. --- packages/bower-registry-client/Client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js index a30a403e3..4d6ddb69a 100644 --- a/packages/bower-registry-client/Client.js +++ b/packages/bower-registry-client/Client.js @@ -9,7 +9,7 @@ function RegistryClient(config, logger) { // Cache defaults to storage registry if (!Object.prototype.hasOwnProperty.call(this._config, 'cache')) { - this._config.cache = this._config.storage.registry; + this._config.cache = this._config.storage ? this._config.storage.registry : null; } // Init the cache From ee4158e90b09eb174667db0137b2da4eefea06e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 5 Aug 2013 23:38:19 +0100 Subject: [PATCH 0210/1021] Append the username when using the temporary folder. --- packages/bower-config/lib/util/paths.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/paths.js b/packages/bower-config/lib/util/paths.js index 92ecd5ff8..3b87a036d 100644 --- a/packages/bower-config/lib/util/paths.js +++ b/packages/bower-config/lib/util/paths.js @@ -11,7 +11,8 @@ var paths = { }; // Guess some needed properties based on the user OS -var temp = os.tmpdir ? os.tmpdir() : os.tmpDir(); +var user = (osenv.user() || 'unkown').replace(/\\/g, '-'); +var temp = path.join(os.tmpdir ? os.tmpdir() : os.tmpDir(), user); var home = osenv.home(); var base; From 68124dfdbe2a053d881ae02d63d9c18cdf680518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 5 Aug 2013 23:39:15 +0100 Subject: [PATCH 0211/1021] Bum version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 51425eb23..967e71ac8 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.2.0-rc.2", + "version": "0.3.0", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 12efc85baf3875cfe794c1f153286a88e202c99a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 5 Aug 2013 23:40:52 +0100 Subject: [PATCH 0212/1021] Bump version. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 49e5e69ee..6d597519f 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.1.2", + "version": "0.1.3", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From 14ef86456f8e6b401b0daf230cb2b389cc5f88dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 6 Aug 2013 00:02:31 +0100 Subject: [PATCH 0213/1021] Typo. --- packages/bower-config/lib/util/paths.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/paths.js b/packages/bower-config/lib/util/paths.js index 3b87a036d..e7fc2b138 100644 --- a/packages/bower-config/lib/util/paths.js +++ b/packages/bower-config/lib/util/paths.js @@ -11,7 +11,7 @@ var paths = { }; // Guess some needed properties based on the user OS -var user = (osenv.user() || 'unkown').replace(/\\/g, '-'); +var user = (osenv.user() || 'unknown').replace(/\\/g, '-'); var temp = path.join(os.tmpdir ? os.tmpdir() : os.tmpDir(), user); var home = osenv.home(); var base; From bc4a0f448b1d2b9f2ace83643a29336591d40280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 6 Aug 2013 00:02:54 +0100 Subject: [PATCH 0214/1021] Bump version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 967e71ac8..2b0f62610 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.3.0", + "version": "0.3.1", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From cf85177c7fdbcdba80363a06d600bcdf56918d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Tue, 6 Aug 2013 09:12:13 +0100 Subject: [PATCH 0215/1021] DRY. --- packages/bower-config/lib/util/defaults.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/bower-config/lib/util/defaults.js b/packages/bower-config/lib/util/defaults.js index 2bb57c774..506da066c 100644 --- a/packages/bower-config/lib/util/defaults.js +++ b/packages/bower-config/lib/util/defaults.js @@ -10,9 +10,8 @@ var proxy = process.env.HTTP_PROXY var httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy - || process.env.HTTP_PROXY - || process.env.http_proxy - || null; + || proxy; + /*jshint camelcase: true*/ var defaults = { From e2c67fa25a2498ab1dd9aa32a71c980827affc80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 7 Aug 2013 08:28:50 +0100 Subject: [PATCH 0216/1021] Use a known user agent by default when a proxy. --- packages/bower-config/lib/util/defaults.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/bower-config/lib/util/defaults.js b/packages/bower-config/lib/util/defaults.js index 506da066c..1ea84ffeb 100644 --- a/packages/bower-config/lib/util/defaults.js +++ b/packages/bower-config/lib/util/defaults.js @@ -11,9 +11,14 @@ var proxy = process.env.HTTP_PROXY var httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy || proxy; - /*jshint camelcase: true*/ +// Use a well known user agent (in this case, curl) when using a proxy, +// to avoid potential filtering on many corporate proxies with blank or unknown agents +var userAgent = !proxy && !httpsProxy + ? 'node/' + process.version + ' ' + process.platform + ' ' + process.arch + : 'curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5'; + var defaults = { 'cwd': process.cwd(), 'directory': 'bower_components', @@ -25,7 +30,7 @@ var defaults = { 'timeout': 30000, 'ca': { search: [] }, 'strict-ssl': true, - 'user-agent': 'node/' + process.version + ' ' + process.platform + ' ' + process.arch, + 'user-agent': userAgent, 'color': true, 'interactive': false, 'storage': { From 8dbd79d49b88bae19bf3047e925126b7af2c7e16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 7 Aug 2013 08:29:40 +0100 Subject: [PATCH 0217/1021] Bump version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 2b0f62610..caa9e2a5f 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.3.1", + "version": "0.3.2", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 16063955465480e82224be51e17a243a9c3d264e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 11 Aug 2013 14:45:55 +0100 Subject: [PATCH 0218/1021] Close GH-12: Ignore component(1) files.. --- packages/bower-json/lib/json.js | 28 +++++++++---- packages/bower-json/lib/util/isComponent.js | 41 +++++++++++++++++++ packages/bower-json/package.json | 3 +- .../test/pkg-component(1)-json/component.json | 14 +++++++ packages/bower-json/test/test.js | 9 ++++ 5 files changed, 87 insertions(+), 8 deletions(-) create mode 100644 packages/bower-json/lib/util/isComponent.js create mode 100644 packages/bower-json/test/pkg-component(1)-json/component.json diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index 45f879392..be753d244 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -1,6 +1,7 @@ var fs = require('graceful-fs'); var path = require('path'); var deepExtend = require('deep-extend'); +var isComponent = require('./util/isComponent'); var createError = require('./util/createError'); var possibleJsons = ['bower.json', 'component.json', '.bower.json']; @@ -102,14 +103,15 @@ function normalize(json) { return json; } -function find(folder, callback) { - findRec(folder, possibleJsons, callback); -} - -function findRec(folder, files, callback) { +function find(folder, files, callback) { var err; var file; + if (typeof files === 'function') { + callback = files; + files = possibleJsons; + } + if (!files.length) { err = createError('None of ' + possibleJsons.join(', ') + ' were found in ' + folder, 'ENOENT'); return callback(err); @@ -117,11 +119,23 @@ function findRec(folder, files, callback) { file = path.resolve(path.join(folder, files[0])); fs.exists(file, function (exists) { - if (exists) { + if (!exists) { + return find(folder, files.slice(1), callback); + } + + if (files[0] !== 'component.json') { return callback(null, file); } - findRec(folder, files.slice(1), callback); + // If the file is component.json, check it it's a component(1) file + // If it is, we ignore it and keep searching + isComponent(file, function (is) { + if (is) { + return find(folder, files.slice(1), callback); + } + + callback(null, file); + }); }); } diff --git a/packages/bower-json/lib/util/isComponent.js b/packages/bower-json/lib/util/isComponent.js new file mode 100644 index 000000000..021120658 --- /dev/null +++ b/packages/bower-json/lib/util/isComponent.js @@ -0,0 +1,41 @@ +var fs = require('graceful-fs'); +var intersect = require('intersect'); + +// Function to check if a file is a component(1) file +function isComponent(file, callback) { + fs.readFile(file, function (err, contents) { + var json; + var keys; + var common; + + // If an error occurs while reading the file, we ignore it + if (err) { + return callback(false); + } + + try { + json = JSON.parse(contents.toString()); + } catch (err) { + return callback(false); + } + + // Attempt to find specific things from the component(1) spec + // Note that we don't parse the dependencies property because at any point + // we can allow / to specify directories + // Bellow only some clearly not ambiguous properties are checked + keys = Object.keys(json); + common = intersect(keys, [ + 'repo', + 'development', + 'local', + 'remotes', + 'paths', + 'demo' + ]); + + // If none were found, than it's a valid component.json bower file + callback(common.length ? true : false); + }); +} + +module.exports = isComponent; diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index fbe6e2d37..d5d242527 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -19,7 +19,8 @@ }, "dependencies": { "deep-extend": "~0.2.5", - "graceful-fs": "~2.0.0" + "graceful-fs": "~2.0.0", + "intersect": "~0.0.3" }, "devDependencies": { "expect.js": "~0.2.0", diff --git a/packages/bower-json/test/pkg-component(1)-json/component.json b/packages/bower-json/test/pkg-component(1)-json/component.json new file mode 100644 index 000000000..a79407e9e --- /dev/null +++ b/packages/bower-json/test/pkg-component(1)-json/component.json @@ -0,0 +1,14 @@ +{ + "name": "route", + "repo": "apily/route", + "version": "0.0.1", + "description": "Route component", + "keywords": ["router", "route"], + "scripts": ["index.js"], + "dependencies": {}, + "development": { + "component/assert": "*", + "visionmedia/mocha": "*" + }, + "license": "MIT" +} diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index 7e9065c02..8befab368 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -25,6 +25,15 @@ describe('.find', function () { }); }); + it('should not fallback to the component.json file if it\'s a component(1) file', function (done) { + bowerJson.find(__dirname + '/pkg-component(1)-json', function (err) { + expect(err).to.be.an(Error); + expect(err.code).to.equal('ENOENT'); + expect(err.message).to.equal('None of bower.json, component.json, .bower.json were found in ' + __dirname + '/pkg-component(1)-json'); + done(); + }); + }); + it('should fallback to the .bower.json file', function (done) { bowerJson.find(__dirname + '/pkg-dot-bower-json', function (err, file) { if (err) { From dfb18b305d3895abe33f80759e1a6ffbfe589a79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 11 Aug 2013 14:46:33 +0100 Subject: [PATCH 0219/1021] Bump version. --- packages/bower-json/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index d5d242527..92a50363a 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,6 +1,6 @@ { "name": "bower-json", - "version": "0.3.0", + "version": "0.4.0", "description": "Read bower.json files with semantics, normalisation, defaults and validation.", "author": "Twitter", "licenses": [ From 9f2207eb1f3c1fb7a31ae816d74ec610887eb6aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 11 Aug 2013 18:24:13 +0100 Subject: [PATCH 0220/1021] Change git folder to empty (was not being used anyway). --- packages/bower-config/lib/util/defaults.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/defaults.js b/packages/bower-config/lib/util/defaults.js index 1ea84ffeb..e52adb812 100644 --- a/packages/bower-config/lib/util/defaults.js +++ b/packages/bower-config/lib/util/defaults.js @@ -38,7 +38,7 @@ var defaults = { links: path.join(paths.data, 'links'), completion: path.join(paths.data, 'completion'), registry: path.join(paths.cache, 'registry'), - git: path.join(paths.data, 'git') + empty: path.join(paths.data, 'empty') // Empty dir, used in GIT_TEMPLATE_DIR among others } }; From 89510f40d31807ae196ad904d50cd05cd2fcc201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sun, 11 Aug 2013 18:24:25 +0100 Subject: [PATCH 0221/1021] Bump version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index caa9e2a5f..db3ae41ba 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.3.2", + "version": "0.3.3", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From cb649830a0c4a0fcf2a3eb12f115aac9e21d3a1a Mon Sep 17 00:00:00 2001 From: Salehen Shovon Rahman Date: Wed, 14 Aug 2013 08:35:00 +0100 Subject: [PATCH 0222/1021] Close GH-7: Empty .bowerrc files should not throw an error.. --- packages/bower-config/lib/util/rc.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 308668497..f794ed061 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -29,6 +29,10 @@ function rc(name, defaults, cwd, argv) { function parse(content, file) { var error; + if (!content.trim().length) { + return {}; + } + try { return JSON.parse(content); } catch (e) { From 846b8fb57e1ae79d89ae59f3cd66f71c88480957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 14 Aug 2013 08:36:54 +0100 Subject: [PATCH 0223/1021] Bump version --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index db3ae41ba..2c43ca235 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.3.3", + "version": "0.3.4", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From fb084fa4cdffabf93ee77827972f82873228123c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 14 Aug 2013 09:10:08 +0100 Subject: [PATCH 0224/1021] Cast buffer to string. --- packages/bower-config/lib/util/rc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index f794ed061..9f434eb9e 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -54,7 +54,7 @@ function json(file) { var content; try { - content = fs.readFileSync(file); + content = fs.readFileSync(file).toString(); } catch (err) { return null; } From 9cb09feb65a8699ada21e1acddc174c6211ad3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 14 Aug 2013 09:10:24 +0100 Subject: [PATCH 0225/1021] Bump version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 2c43ca235..6897b8e02 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.3.4", + "version": "0.3.5", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 7dba46df9b04dcc1bc39eac86655fbac86dd9e74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 16 Aug 2013 09:30:40 +0100 Subject: [PATCH 0226/1021] Temp folder is now suffixed with the user and "bower". --- packages/bower-config/lib/util/defaults.js | 3 +-- packages/bower-config/lib/util/paths.js | 8 +++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/bower-config/lib/util/defaults.js b/packages/bower-config/lib/util/defaults.js index e52adb812..ef9612b05 100644 --- a/packages/bower-config/lib/util/defaults.js +++ b/packages/bower-config/lib/util/defaults.js @@ -1,4 +1,3 @@ -var os = require('os'); var path = require('path'); var paths = require('./paths'); @@ -24,7 +23,7 @@ var defaults = { 'directory': 'bower_components', 'registry': 'https://bower.herokuapp.com', 'shorthand-resolver': 'git://github.com/{{owner}}/{{package}}.git', - 'tmp': os.tmpdir ? os.tmpdir() : os.tmpDir(), + 'tmp': paths.tmp, 'proxy': proxy, 'https-proxy': httpsProxy, 'timeout': 30000, diff --git a/packages/bower-config/lib/util/paths.js b/packages/bower-config/lib/util/paths.js index e7fc2b138..24130784d 100644 --- a/packages/bower-config/lib/util/paths.js +++ b/packages/bower-config/lib/util/paths.js @@ -12,13 +12,13 @@ var paths = { // Guess some needed properties based on the user OS var user = (osenv.user() || 'unknown').replace(/\\/g, '-'); -var temp = path.join(os.tmpdir ? os.tmpdir() : os.tmpDir(), user); +var tmp = path.join(os.tmpdir ? os.tmpdir() : os.tmpDir(), user); var home = osenv.home(); var base; // Fallbacks for windows if (process.platform === 'win32') { - base = path.resolve(process.env.APPDATA || home || temp); + base = path.resolve(process.env.APPDATA || home || tmp); base = path.join(base, 'bower'); paths.config = paths.config || path.join(base, 'config'); @@ -26,11 +26,13 @@ if (process.platform === 'win32') { paths.cache = paths.cache || path.join(base, 'cache'); // Fallbacks for other operating systems } else { - base = path.resolve(home || temp); + base = path.resolve(home || tmp); paths.config = paths.config || path.join(base, '.config/bower'); paths.data = paths.data || path.join(base, '.local/share/bower'); paths.cache = paths.cache || path.join(base, '.cache/bower'); } +paths.tmp = path.resolve(path.join(tmp, 'bower')); + module.exports = paths; From 0de9cc82f664fe2d4fd95f31e6cbe99b3cb21a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Fri, 16 Aug 2013 09:43:39 +0100 Subject: [PATCH 0227/1021] Bump version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 6897b8e02..a9747e6d5 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.3.5", + "version": "0.4.0", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 1f4e5cadd26b8f74d5924746bb2a867d01e52562 Mon Sep 17 00:00:00 2001 From: Andre Cruz Date: Sun, 18 Aug 2013 13:07:51 +0100 Subject: [PATCH 0228/1021] Generate a fake user instead of using 'unknown'. --- packages/bower-config/lib/util/paths.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/paths.js b/packages/bower-config/lib/util/paths.js index 24130784d..566ba7261 100644 --- a/packages/bower-config/lib/util/paths.js +++ b/packages/bower-config/lib/util/paths.js @@ -1,6 +1,12 @@ var os = require('os'); var path = require('path'); var osenv = require('osenv'); +var crypto = require('crypto'); + +function generateFakeUser() { + var uid = process.pid + '-' + Date.now() + '-' + Math.floor(Math.random() * 1000000); + return crypto.createHash('md5').update(uid).digest('hex'); +} // Assume XDG defaults // See: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html @@ -11,7 +17,7 @@ var paths = { }; // Guess some needed properties based on the user OS -var user = (osenv.user() || 'unknown').replace(/\\/g, '-'); +var user = (osenv.user() || generateFakeUser()).replace(/\\/g, '-'); var tmp = path.join(os.tmpdir ? os.tmpdir() : os.tmpDir(), user); var home = osenv.home(); var base; From 71037cb482e8752fb89feec06538f1d70604563b Mon Sep 17 00:00:00 2001 From: Andre Cruz Date: Sun, 18 Aug 2013 13:08:43 +0100 Subject: [PATCH 0229/1021] Bump version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index a9747e6d5..f8ca973e7 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.4.0", + "version": "0.4.1", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From b1d8c3c1e353086e935336520d588922ad2139f1 Mon Sep 17 00:00:00 2001 From: Andre Cruz Date: Sun, 18 Aug 2013 17:28:35 +0100 Subject: [PATCH 0230/1021] Interactive is now set to auto (null). --- packages/bower-config/lib/util/defaults.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/defaults.js b/packages/bower-config/lib/util/defaults.js index ef9612b05..c742cbd09 100644 --- a/packages/bower-config/lib/util/defaults.js +++ b/packages/bower-config/lib/util/defaults.js @@ -31,7 +31,7 @@ var defaults = { 'strict-ssl': true, 'user-agent': userAgent, 'color': true, - 'interactive': false, + 'interactive': null, 'storage': { packages: path.join(paths.cache, 'packages'), links: path.join(paths.data, 'links'), From 6b6dc8311aa6baa7418d1eafe43305331749bb07 Mon Sep 17 00:00:00 2001 From: Andre Cruz Date: Sun, 18 Aug 2013 17:29:00 +0100 Subject: [PATCH 0231/1021] Bump version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index f8ca973e7..f4ded2f21 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.4.1", + "version": "0.4.2", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 64fc295ecccf564da850262ac06429c600eead36 Mon Sep 17 00:00:00 2001 From: Andre Cruz Date: Mon, 19 Aug 2013 00:33:40 +0100 Subject: [PATCH 0232/1021] Add prompt(). --- packages/bower-logger/README.md | 42 +++++++++++++ packages/bower-logger/lib/Logger.js | 50 ++++++++++++++++ packages/bower-logger/test/test.js | 92 +++++++++++++++++++++++++++++ 3 files changed, 184 insertions(+) diff --git a/packages/bower-logger/README.md b/packages/bower-logger/README.md index 76f478a1d..2d35f83d7 100644 --- a/packages/bower-logger/README.md +++ b/packages/bower-logger/README.md @@ -52,6 +52,48 @@ logger.log('warn', 'foo', 'bar', { dog: 'loves cat' }) ``` +### .prompt(prompts, callback) + +Emits a `prompt` event with an array of `prompts` with a `callback`. +`prompts` can be an object or an array of objects. The `callback` will be called with an +the answer or an object of answers (if prompts was only one or an array respectively). +The `callback` is guaranteed to run only once. + +```js +logger.on('prompt', function (prompts, callback) { + // "prompts" is always an array of prompts + // Call "callback" with an object of answers when done + + // In this example, we will use the inquirer module to do the + // prompting for us + inquirer(prompts, function (answers) { + callback(answers); + }); +}) + +logger.prompt({ + type: 'input' // Can be 'input', 'confirm' or 'password' + message: 'Type something', + validate: function (value) { + if (value !== 'I am awesome') { + return 'You must type "I am awesome"' + } + + return true; + } +}, function (err, answer) { + // Error will only happen on unsupported 'type' + if (err) { + return console.error(err.message); + } + + console.log(answer); +}); + + +``` + + ### .pipe(logger) Pipes all logger events to another logger. diff --git a/packages/bower-logger/lib/Logger.js b/packages/bower-logger/lib/Logger.js index 649288f81..a182db543 100644 --- a/packages/bower-logger/lib/Logger.js +++ b/packages/bower-logger/lib/Logger.js @@ -63,8 +63,58 @@ Logger.prototype.log = function (level, id, message, data) { return this; }; +Logger.prototype.prompt = function (prompts, callback) { + var fn; + var one; + var invalid; + var runned; + var error; + var validPrompts = Logger._validPrompts; + + if (!Array.isArray(prompts)) { + prompts.name = 'prompt'; + prompts = [prompts]; + one = true; + } + + // Validate prompt types + invalid = prompts.some(function (prompt) { + return validPrompts.indexOf(prompt.type) === -1; + }); + + if (invalid) { + error = new Error('Unknown prompt type'); + error.code = 'ENOTSUP'; + return callback(error); + } + + fn = function (answers) { + // Run callback only once + if (runned) { + return; + } + + runned = true; + + // If only one prompt was requested, resolve with its answer + if (one) { + answers = answers.prompt; + } + + callback(null, answers); + }; + + this.emit('prompt', prompts, fn); +}; + // ------------------ +Logger._validPrompts = [ + 'input', + 'confirm', + 'password' +]; + Logger.LEVELS = { 'error': 5, 'conflict': 4, diff --git a/packages/bower-logger/test/test.js b/packages/bower-logger/test/test.js index 1bc1c8f91..cc69ba265 100644 --- a/packages/bower-logger/test/test.js +++ b/packages/bower-logger/test/test.js @@ -259,4 +259,96 @@ describe('Logger', function () { next(); }); }); + + describe('.prompt', function () { + it('should only allow calling the callback once', function () { + var calls = 0; + + logger + .once('prompt', function (prompts, callback) { + callback('bar'); + callback('bar'); + }) + .prompt({ + type: 'input', + message: 'foo' + }, function () { + calls += 1; + }); + + expect(calls).to.equal(1); + }); + + it('should accept a prompt', function (next) { + logger + .once('prompt', function (prompts, callback) { + callback({ + prompt: 'bar' + }); + }) + .prompt({ + type: 'input', + message: 'foo' + }, function (err, answer) { + expect(err).to.not.be.ok(); + expect(answer).to.equal('bar'); + next(); + }); + }); + + it('should accept several prompts', function (next) { + logger + .once('prompt', function (prompts, callback) { + callback({ + foo: 'bar', + foz: 'baz' + }); + }) + .prompt([ + { + name: 'foo', + type: 'input', + message: 'foo' + }, + { + name: 'foz', + type: 'confirm', + message: 'foz' + } + ], function (err, answer) { + expect(err).to.not.be.ok(); + expect(answer.foo).to.equal('bar'); + expect(answer.foz).to.equal('baz'); + + logger + .once('prompt', function (prompts, callback) { + callback({ + foo: 'bar' + }); + }) + .prompt([ + { + name: 'foo', + type: 'input', + message: 'foo' + } + ], function (err, answer) { + expect(err).to.not.be.ok(); + expect(answer.foo).to.equal('bar'); + next(); + }); + }); + }); + + it('should error on invalid prompt type', function (next) { + logger.prompt({ + type: 'xxx', + message: 'foo' + }, function (err) { + expect(err).to.be.an(Error); + expect(err.code).to.be('ENOTSUP'); + next(); + }); + }); + }); }); From 1d7342573b1c136ed74408c6041de6a3d456ec2e Mon Sep 17 00:00:00 2001 From: Andre Cruz Date: Mon, 19 Aug 2013 00:43:41 +0100 Subject: [PATCH 0233/1021] Bump version. --- packages/bower-logger/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-logger/package.json b/packages/bower-logger/package.json index 92d51dc8a..7dc4ddad4 100644 --- a/packages/bower-logger/package.json +++ b/packages/bower-logger/package.json @@ -1,6 +1,6 @@ { "name": "bower-logger", - "version": "0.1.0", + "version": "0.2.0", "description": "The logger used in the various architecture components of Bower.", "author": "Twitter", "licenses": [ From 1713e5e2eb56d59921d29c76fa0ccbe51ebf4997 Mon Sep 17 00:00:00 2001 From: Andre Cruz Date: Mon, 19 Aug 2013 00:57:07 +0100 Subject: [PATCH 0234/1021] Minor improvement in argv.config parsing. --- packages/bower-config/lib/util/rc.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 9f434eb9e..401ea866a 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -9,10 +9,17 @@ var win = process.platform === 'win32'; var home = osenv.home(); function rc(name, defaults, cwd, argv) { + var argvConfig; + defaults = defaults || {}; cwd = cwd || process.cwd(); argv = argv || optimist.argv; + // Parse --config.foo=false + argvConfig = mout.object.map(argv.config || {}, function (value) { + return value === 'false' ? false : value; + }); + return mout.object.deepMixIn.apply(null, [ {}, defaults, @@ -22,7 +29,7 @@ function rc(name, defaults, cwd, argv) { json(path.join(paths.config, name + 'rc')), json(find('.' + name + 'rc', cwd)), env(name + '_'), - typeof argv.config !== 'object' ? {} : argv.config + argvConfig ]); } From 3dfd7a9ab134d5b94c386d042ef1bc9506aadf76 Mon Sep 17 00:00:00 2001 From: Andre Cruz Date: Mon, 19 Aug 2013 00:57:39 +0100 Subject: [PATCH 0235/1021] Bump version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index f4ded2f21..d6d4b483b 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.4.2", + "version": "0.4.3", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 032f7719969e2876dac8106723c90621fc0bd8f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Mon, 19 Aug 2013 09:01:45 +0100 Subject: [PATCH 0236/1021] Simplify. --- packages/bower-logger/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/bower-logger/README.md b/packages/bower-logger/README.md index 2d35f83d7..524f98107 100644 --- a/packages/bower-logger/README.md +++ b/packages/bower-logger/README.md @@ -66,9 +66,7 @@ logger.on('prompt', function (prompts, callback) { // In this example, we will use the inquirer module to do the // prompting for us - inquirer(prompts, function (answers) { - callback(answers); - }); + inquirer(prompts, callback); }) logger.prompt({ From 794ca573b8ff1811b5b06fa95367e3c0b8e545a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 20 Aug 2013 00:41:15 +0100 Subject: [PATCH 0237/1021] Trim answers automatically. --- packages/bower-logger/lib/Logger.js | 9 +++++++++ packages/bower-logger/test/test.js | 21 +++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/bower-logger/lib/Logger.js b/packages/bower-logger/lib/Logger.js index a182db543..8e95fa983 100644 --- a/packages/bower-logger/lib/Logger.js +++ b/packages/bower-logger/lib/Logger.js @@ -94,6 +94,15 @@ Logger.prototype.prompt = function (prompts, callback) { return; } + // Trim answers automatically + Object.keys(answers).forEach(function (key) { + var value = answers[key]; + + if (typeof value === 'string') { + answers[key] = answers[key].trim(); + } + }); + runned = true; // If only one prompt was requested, resolve with its answer diff --git a/packages/bower-logger/test/test.js b/packages/bower-logger/test/test.js index cc69ba265..ae92fec0e 100644 --- a/packages/bower-logger/test/test.js +++ b/packages/bower-logger/test/test.js @@ -266,8 +266,8 @@ describe('Logger', function () { logger .once('prompt', function (prompts, callback) { - callback('bar'); - callback('bar'); + callback({ prompt: 'bar' }); + callback({ prompt: 'foo' }); }) .prompt({ type: 'input', @@ -350,5 +350,22 @@ describe('Logger', function () { next(); }); }); + + it('should trim the answers', function (next) { + logger + .once('prompt', function (prompts, callback) { + callback({ + prompt: ' bar ' + }); + }) + .prompt({ + type: 'input', + message: 'foo' + }, function (err, answer) { + expect(err).to.not.be.ok(); + expect(answer).to.equal('bar'); + next(); + }); + }); }); }); From 02b6a21276bce67bbc523242a1c728b93293117e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 20 Aug 2013 00:42:17 +0100 Subject: [PATCH 0238/1021] Bump version. --- packages/bower-logger/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-logger/package.json b/packages/bower-logger/package.json index 7dc4ddad4..6c2dc7fa4 100644 --- a/packages/bower-logger/package.json +++ b/packages/bower-logger/package.json @@ -1,6 +1,6 @@ { "name": "bower-logger", - "version": "0.2.0", + "version": "0.2.1", "description": "The logger used in the various architecture components of Bower.", "author": "Twitter", "licenses": [ From dd39a25dd0cc8418dbce112cf3cdbb45e1bcdee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 20 Aug 2013 01:02:39 +0100 Subject: [PATCH 0239/1021] Update deps. --- packages/bower-registry-client/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 6d597519f..5ba7cd81f 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -19,10 +19,10 @@ }, "dependencies": { "async": "~0.2.8", - "bower-config": "~0.2.0", + "bower-config": "~0.4.3", "graceful-fs": "~2.0.0", "lru-cache": "~2.3.0", - "request": "~2.25.0", + "request": "~2.27.0", "request-replay": "~0.2.0", "rimraf": "~2.2.0", "mkdirp": "~0.3.5" From 0f2981803036b1340a3b7b3a93c0f17ab3d0b21a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 20 Aug 2013 01:03:01 +0100 Subject: [PATCH 0240/1021] Bump version. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 5ba7cd81f..7f4afa845 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.1.3", + "version": "0.1.4", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From 52938202bd593677d08cbfc7ca79caf33518822a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 20 Aug 2013 21:48:26 +0100 Subject: [PATCH 0241/1021] Fix target not being added if source does not look like a source. --- packages/bower-endpoint-parser/index.js | 6 +++--- packages/bower-endpoint-parser/test/test.js | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/bower-endpoint-parser/index.js b/packages/bower-endpoint-parser/index.js index 14ca9d005..68a8eabeb 100644 --- a/packages/bower-endpoint-parser/index.js +++ b/packages/bower-endpoint-parser/index.js @@ -92,9 +92,9 @@ function decomposed2json(decEndpoint) { // If value is empty, we append the target always if (!value) { value += isWildcard(target) ? '*' : target; - // Otherwise append only if not a wildcard - } else if (!isWildcard(target)) { - value += '#' + target; + // Otherwise append only if not a wildcard or source does not look like a source + } else if (!isWildcard(target) || !isSource(source)) { + value += '#' + (target || '*'); } ret[name] = value; diff --git a/packages/bower-endpoint-parser/test/test.js b/packages/bower-endpoint-parser/test/test.js index 47a23e8da..94b0ecf2b 100644 --- a/packages/bower-endpoint-parser/test/test.js +++ b/packages/bower-endpoint-parser/test/test.js @@ -181,6 +181,8 @@ describe('endpoint-parser', function () { { bar: '*' }, { baz: '*' }, { jqueryx: 'jquery#~1.9.1' }, + { jqueryy: 'jquery-x#*' }, + { jqueryy: 'jquery-x#*' }, { backbone: 'backbone-amd#~1.0.0' }, { backbone : 'backbone=backbone-amd#~1.0.0' }, { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' }, @@ -196,6 +198,8 @@ describe('endpoint-parser', function () { { name: 'bar', source: 'bar', target: '*' }, { name: 'baz', source: 'baz', target: '' }, { name: 'jqueryx', source: 'jquery', target: '~1.9.1' }, + { name: 'jqueryy', source: 'jquery-x', target: '' }, + { name: 'jqueryy', source: 'jquery-x', target: '*' }, { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }, { name: 'backbone', source: 'backbone=backbone-amd', target: '~1.0.0' }, { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '' }, @@ -218,6 +222,8 @@ describe('endpoint-parser', function () { { name: 'bar', source: 'bar ', target: ' * ' }, { name: 'baz ', source: 'baz', target: ' ' }, { name: ' jqueryx ', source: ' jquery ', target: ' ~1.9.1 ' }, + { name: ' jqueryy ', source: ' jquery-x ', target: ' ' }, + { name: ' jqueryy ', source: ' jquery-x ', target: ' * ' }, { name: ' backbone ', source: ' backbone-amd ', target: ' ~1.0.0 ' }, { name: ' backbone ', source: ' backbone=backbone-amd ', target: ' ~1.0.0 ' }, { name: ' bootstrap ', source: ' http://twitter.github.io/bootstrap/assets/bootstrap ', target: ' ' }, From 78bbf1f04ff74a86bdf7f7d6a68106f668bedbd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Tue, 20 Aug 2013 21:48:55 +0100 Subject: [PATCH 0242/1021] Bump version. --- packages/bower-endpoint-parser/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-endpoint-parser/package.json b/packages/bower-endpoint-parser/package.json index 7a473b044..e0d8039aa 100644 --- a/packages/bower-endpoint-parser/package.json +++ b/packages/bower-endpoint-parser/package.json @@ -1,6 +1,6 @@ { "name": "bower-endpoint-parser", - "version": "0.2.0", + "version": "0.2.1", "description": "Little module that helps with endpoints parsing.", "author": "Twitter", "licenses": [ From d954a54017f16cf933a6da2c12f43b1a0e71b549 Mon Sep 17 00:00:00 2001 From: Alex Whitman Date: Wed, 21 Aug 2013 09:30:07 +0100 Subject: [PATCH 0243/1021] Handle nesting in environment variables Nested configuration variables can now be specified by environment variable. Levels are split by '__' (double underscore). Single underscores are converted to '-'. `bower_foo__bar-baz` -> `foo.bar-baz` --- packages/bower-config/lib/util/rc.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 401ea866a..358b0a9e1 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -75,7 +75,12 @@ function env(prefix) { mout.object.forOwn(process.env, function (value, key) { if (mout.string.startsWith(key, prefix)) { - obj[key.substr(prefixLength)] = value; + var parsedKey = key + .substr(prefixLength) + .replace(/__/g, '.') + .replace(/_/g, '-') + .toLowerCase(); + mout.object.set(obj, parsedKey, value); } }); From 6db6fcc414aac7d93a5748dc96766dcaa7f899e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 21 Aug 2013 18:45:46 +0100 Subject: [PATCH 0244/1021] Small tweaks to last PR. --- packages/bower-config/lib/util/rc.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 358b0a9e1..5cedd1884 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -73,13 +73,16 @@ function env(prefix) { var obj = {}; var prefixLength = prefix.length; + prefix = prefix.toLowerCase(); + mout.object.forOwn(process.env, function (value, key) { + key = key.toLowerCase(); + if (mout.string.startsWith(key, prefix)) { var parsedKey = key .substr(prefixLength) - .replace(/__/g, '.') - .replace(/_/g, '-') - .toLowerCase(); + .replace(/__/g, '.') // __ are used for nesting + .replace(/_/g, '-'); // _ is used as a - separator mout.object.set(obj, parsedKey, value); } }); From 860d70551ff20a78074ba96e79425f8324fa9f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 21 Aug 2013 18:46:05 +0100 Subject: [PATCH 0245/1021] Bump version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index d6d4b483b..812706b0c 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.4.3", + "version": "0.4.4", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 12cde3ddcea5600738490983c826490391c8363e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 21 Aug 2013 18:48:21 +0100 Subject: [PATCH 0246/1021] Doc typo. --- packages/bower-config/lib/util/rc.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 5cedd1884..454b1a46d 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -81,8 +81,8 @@ function env(prefix) { if (mout.string.startsWith(key, prefix)) { var parsedKey = key .substr(prefixLength) - .replace(/__/g, '.') // __ are used for nesting - .replace(/_/g, '-'); // _ is used as a - separator + .replace(/__/g, '.') // __ is used for nesting + .replace(/_/g, '-'); // _ is used as a - separator mout.object.set(obj, parsedKey, value); } }); From ed8ac01f078c5f9a88a06b87332f114a00bb625d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 28 Aug 2013 08:20:55 +0100 Subject: [PATCH 0247/1021] Do not crash if home is not set. --- packages/bower-config/lib/util/rc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 454b1a46d..54088eac5 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -25,7 +25,7 @@ function rc(name, defaults, cwd, argv) { defaults, { cwd: cwd }, win ? {} : json(path.join('/etc', name + 'rc')), - json(path.join(home, '.' + name + 'rc')), + !home ? {} : json(path.join(home, '.' + name + 'rc')), json(path.join(paths.config, name + 'rc')), json(find('.' + name + 'rc', cwd)), env(name + '_'), From a899cb48b388d57a491bf5ac1f94350038a6f615 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 28 Aug 2013 08:21:13 +0100 Subject: [PATCH 0248/1021] Bump version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 812706b0c..86e37f4af 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.4.4", + "version": "0.4.5", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From be95169c1b283868e24d6fe799353740aff443d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Thu, 29 Aug 2013 19:50:46 +0100 Subject: [PATCH 0249/1021] Add DEFAULT_REGISTRY, #6. --- packages/bower-config/lib/Config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index e66108eb7..d9796cf57 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -68,4 +68,6 @@ Config.normalise = function (rawConfig) { return config; }; +Config.DEFAULT_REGISTRY = defaults.registry; + module.exports = Config; From 1099e786dfa9a9cf8724a3875778d7920ca52b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Thu, 29 Aug 2013 19:51:13 +0100 Subject: [PATCH 0250/1021] Bump version. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 86e37f4af..9a42bb6e5 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.4.5", + "version": "0.5.0", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 041290e1c79872bfec7de81695ebc22f5cf95ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 28 Sep 2013 00:54:33 +0100 Subject: [PATCH 0251/1021] Append a truncated hash to prevent case issues in case insensitive fs. --- .../bower-registry-client/lib/util/Cache.js | 6 +++++- packages/bower-registry-client/lib/util/md5.js | 7 +++++++ packages/bower-registry-client/test/Client.js | 17 +++++++++-------- .../bower-registry-client/test/core/index.js | 4 ++-- .../bower-registry-client/test/core/list.js | 4 ++-- .../bower-registry-client/test/core/lookup.js | 4 ++-- .../bower-registry-client/test/core/register.js | 4 ++-- .../bower-registry-client/test/core/search.js | 4 ++-- .../test/core/util/Cache.js | 4 ++-- .../test/core/util/createError.js | 4 ++-- packages/bower-registry-client/test/runner.js | 1 - 11 files changed, 35 insertions(+), 24 deletions(-) create mode 100644 packages/bower-registry-client/lib/util/md5.js diff --git a/packages/bower-registry-client/lib/util/Cache.js b/packages/bower-registry-client/lib/util/Cache.js index 26da10317..c490b9182 100644 --- a/packages/bower-registry-client/lib/util/Cache.js +++ b/packages/bower-registry-client/lib/util/Cache.js @@ -3,6 +3,7 @@ var path = require('path'); var async = require('async'); var mkdirp = require('mkdirp'); var LRU = require('lru-cache'); +var md5 = require('./md5'); function Cache(dir, options) { options = options || {}; @@ -180,7 +181,10 @@ Cache.prototype._hasExpired = function (json) { }; Cache.prototype._getFile = function (key) { - return path.join(this._dir, encodeURIComponent(key)); + // Append a truncated md5 to the end of the file to solve case issues + // on case insensitive file systems + // See: https://github.com/bower/bower/issues/859 + return path.join(this._dir, encodeURIComponent(key) + '_' + md5(key).substr(0, 5)); }; Cache._cache = new LRU({ diff --git a/packages/bower-registry-client/lib/util/md5.js b/packages/bower-registry-client/lib/util/md5.js new file mode 100644 index 000000000..dbc920b04 --- /dev/null +++ b/packages/bower-registry-client/lib/util/md5.js @@ -0,0 +1,7 @@ +var crypto = require('crypto'); + +function md5(contents) { + return crypto.createHash('md5').update(contents).digest('hex'); +} + +module.exports = md5; diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 6e6c5cee2..1c396b93a 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -1,7 +1,8 @@ -var RegistryClient = require('../Client'), - fs = require('fs'), - expect = require('expect.js'), - nock = require('nock'); +var RegistryClient = require('../Client'); +var fs = require('fs'); +var expect = require('expect.js'); +var md5 = require('../lib/util/md5'); +var nock = require('nock'); describe('RegistryClient', function () { beforeEach(function () { @@ -113,7 +114,7 @@ describe('RegistryClient', function () { this.method = 'search'; this.pkg = 'jquery'; - this.path = this.cacheDir + '/' + this.host + '/' + this.method + '/' + this.pkg; + this.path = this.cacheDir + '/' + this.host + '/' + this.method + '/' + this.pkg + '_' + md5(this.pkg).substr(0, 5); }); afterEach(function (next) { @@ -261,10 +262,10 @@ describe('RegistryClient', function () { }); describe('calling the lookup instance method without argument', function () { - it('should return an error and no result', function (next) { + it('should return no result', function (next) { this.registry.lookup('', function (err, entry) { - expect(err).to.be.an(Error); - expect(entry).to.be(undefined); + expect(err).to.not.be.ok(); + expect(entry).to.not.be.ok(); next(); }); }); diff --git a/packages/bower-registry-client/test/core/index.js b/packages/bower-registry-client/test/core/index.js index ef101a831..1536a5140 100644 --- a/packages/bower-registry-client/test/core/index.js +++ b/packages/bower-registry-client/test/core/index.js @@ -1,5 +1,5 @@ -var index = require('../../lib/index'), - expect = require('expect.js'); +var index = require('../../lib/index'); +var expect = require('expect.js'); describe('index module', function () { describe('requiring the index module', function () { diff --git a/packages/bower-registry-client/test/core/list.js b/packages/bower-registry-client/test/core/list.js index 82de4ab7a..39f92e047 100644 --- a/packages/bower-registry-client/test/core/list.js +++ b/packages/bower-registry-client/test/core/list.js @@ -1,5 +1,5 @@ -var list = require('../../lib/list'), - expect = require('expect.js'); +var list = require('../../lib/list'); +var expect = require('expect.js'); describe('list module', function () { describe('requiring the list module', function () { diff --git a/packages/bower-registry-client/test/core/lookup.js b/packages/bower-registry-client/test/core/lookup.js index a8f26d3e4..e730698ab 100644 --- a/packages/bower-registry-client/test/core/lookup.js +++ b/packages/bower-registry-client/test/core/lookup.js @@ -1,5 +1,5 @@ -var lookup = require('../../lib/lookup'), - expect = require('expect.js'); +var lookup = require('../../lib/lookup'); +var expect = require('expect.js'); describe('lookup module', function () { describe('requiring the lookup module', function () { diff --git a/packages/bower-registry-client/test/core/register.js b/packages/bower-registry-client/test/core/register.js index 36e14095b..1180b8afb 100644 --- a/packages/bower-registry-client/test/core/register.js +++ b/packages/bower-registry-client/test/core/register.js @@ -1,5 +1,5 @@ -var register = require('../../lib/register'), - expect = require('expect.js'); +var register = require('../../lib/register'); +var expect = require('expect.js'); describe('register module', function () { describe('requiring the register module', function () { diff --git a/packages/bower-registry-client/test/core/search.js b/packages/bower-registry-client/test/core/search.js index 49a613d63..8a6285d47 100644 --- a/packages/bower-registry-client/test/core/search.js +++ b/packages/bower-registry-client/test/core/search.js @@ -1,5 +1,5 @@ -var search = require('../../lib/search'), - expect = require('expect.js'); +var search = require('../../lib/search'); +var expect = require('expect.js'); describe('search module', function () { describe('requiring the search module', function () { diff --git a/packages/bower-registry-client/test/core/util/Cache.js b/packages/bower-registry-client/test/core/util/Cache.js index 2ce74c9ed..702957f65 100644 --- a/packages/bower-registry-client/test/core/util/Cache.js +++ b/packages/bower-registry-client/test/core/util/Cache.js @@ -1,5 +1,5 @@ -var Cache = require('../../../lib/util/Cache'), - expect = require('expect.js'); +var Cache = require('../../../lib/util/Cache'); +var expect = require('expect.js'); describe('Cache', function () { beforeEach(function () { diff --git a/packages/bower-registry-client/test/core/util/createError.js b/packages/bower-registry-client/test/core/util/createError.js index 10affa9d3..a01031daa 100644 --- a/packages/bower-registry-client/test/core/util/createError.js +++ b/packages/bower-registry-client/test/core/util/createError.js @@ -1,5 +1,5 @@ -var createError = require('../../../lib/util/createError'), - expect = require('expect.js'); +var createError = require('../../../lib/util/createError'); +var expect = require('expect.js'); describe('createError', function () { diff --git a/packages/bower-registry-client/test/runner.js b/packages/bower-registry-client/test/runner.js index 8c1b6a195..9481f8579 100644 --- a/packages/bower-registry-client/test/runner.js +++ b/packages/bower-registry-client/test/runner.js @@ -6,4 +6,3 @@ require('./core/list'); require('./core/index'); require('./core/util/Cache'); require('./core/util/createError'); - From ab7e7ac12aa2e837753d93e153dfb678e88f02de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Sat, 28 Sep 2013 15:11:01 +0100 Subject: [PATCH 0252/1021] Bump version. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 7f4afa845..7086555e5 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.1.4", + "version": "0.1.5", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From b87b8ea931a388510e852bc55420f17423a07e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 30 Sep 2013 02:33:06 +0100 Subject: [PATCH 0253/1021] Install linked package dependencies, closes #673. Also add a "unlink" alias to "uninstall". --- lib/commands/link.js | 8 +++- lib/commands/list.js | 6 ++- lib/core/Project.js | 65 +++++++++++++++---------------- lib/index.js | 1 + lib/renderers/StandardRenderer.js | 6 +++ templates/json/help-link.json | 2 +- 6 files changed, 51 insertions(+), 37 deletions(-) diff --git a/lib/commands/link.js b/lib/commands/link.js index 3a10f96c9..80f40e28e 100644 --- a/lib/commands/link.js +++ b/lib/commands/link.js @@ -46,6 +46,7 @@ function linkTo(name, localName, config) { var src; var dst; var logger = new Logger(); + var project = new Project(config, logger); config = mout.object.deepFillIn(config || {}, defaultConfig); @@ -59,10 +60,15 @@ function linkTo(name, localName, config) { .then(function () { return createLink(src, dst); }) + // Install linked package deps .then(function () { + return project.update([localName]); + }) + .then(function (installed) { return { src: src, - dst: dst + dst: dst, + installed: installed }; }) .done(function (result) { diff --git a/lib/commands/list.js b/lib/commands/list.js index 59eaee95f..50ab97270 100644 --- a/lib/commands/list.js +++ b/lib/commands/list.js @@ -87,9 +87,11 @@ function checkVersions(project, tree, logger) { var nodes = []; var repository = project.getPackageRepository(); - // Gather all nodes + // Gather all nodes, ignoring linked nodes project.walkTree(tree, function (node) { - nodes.push(node); + if (!node.linked) { + nodes.push(node); + } }, true); if (nodes.length) { diff --git a/lib/core/Project.js b/lib/core/Project.js index 9a99c1dce..7a08a4b0b 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -54,12 +54,6 @@ Project.prototype.install = function (decEndpoints, options) { } else { resolved[name] = node; } - - // Ignore linked dependencies because it's too complex to parse them - // Note that this might change in the future: #673 - if (node.linked) { - return false; - } }); // Add decomposed endpoints as targets @@ -128,13 +122,14 @@ Project.prototype.update = function (names, options) { if (!names) { // Mark each root dependency as targets that.walkTree(tree, function (node) { - // Ignore linked extraneous because - // we don't know their real sources - if (node.extraneous && node.linked) { - return false; + // We don't know the real source of linked packages + // Instead we read its dependencies + if (node.linked) { + targets.push.apply(targets, mout.object.values(node.dependencies)); + } else { + targets.push(node); } - targets.push(node); return false; }, true); // Otherwise, selectively update the specified ones @@ -151,14 +146,15 @@ Project.prototype.update = function (names, options) { // Add packages whose names are specified to be updated that.walkTree(tree, function (node, name) { - // Ignore linked extraneous because - // we don't know their real source - if (node.extraneous && node.linked) { - return false; - } - if (names.indexOf(name) !== -1) { - targets.push(node); + // We don't know the real source of linked packages + // Instead we read its dependencies + if (node.linked) { + targets.push.apply(targets, mout.object.values(node.dependencies)); + } else { + targets.push(node); + } + return false; } }, true); @@ -172,12 +168,6 @@ Project.prototype.update = function (names, options) { } else { resolved[name] = node; } - - // Ignore linked dependencies because it's too complex to parse them - // Note that this might change in the future: #673 - if (node.linked) { - return false; - } }, true); } @@ -448,7 +438,6 @@ Project.prototype._analyse = function () { .spread(function (json, installed, links) { var root; var jsonCopy = mout.lang.deepClone(json); - var flattened = mout.object.mixIn({}, installed, links); root = { name: json.name, @@ -459,6 +448,8 @@ Project.prototype._analyse = function () { root: true }; + mout.object.mixIn(installed, links); + // Mix direct extraneous as dependencies // (dependencies installed without --save/--save-dev) jsonCopy.dependencies = jsonCopy.dependencies || {}; @@ -470,32 +461,37 @@ Project.prototype._analyse = function () { // The _direct propery is saved by the manager when .newly is specified if (!isSaved && pkgMeta._direct) { decEndpoint.extraneous = true; - jsonCopy.dependencies[key] = (pkgMeta._originalSource || pkgMeta._source) + '#' + pkgMeta._target; + + if (decEndpoint.linked) { + jsonCopy.dependencies[key] = pkgMeta.version || '*'; + } else { + jsonCopy.dependencies[key] = (pkgMeta._originalSource || pkgMeta._source) + '#' + pkgMeta._target; + } } }); // Restore the original dependencies cross-references, // that is, the parent-child relationships - this._restoreNode(root, flattened, 'dependencies'); + this._restoreNode(root, installed, 'dependencies'); // Do the same for the dev dependencies if (!this._options.production) { - this._restoreNode(root, flattened, 'devDependencies'); + this._restoreNode(root, installed, 'devDependencies'); } // Restore the rest of the extraneous (not installed directly) - mout.object.forOwn(flattened, function (decEndpoint, name) { + mout.object.forOwn(installed, function (decEndpoint, name) { if (!decEndpoint.dependants) { decEndpoint.extraneous = true; - this._restoreNode(decEndpoint, flattened, 'dependencies'); + this._restoreNode(decEndpoint, installed, 'dependencies'); // Note that it has no dependants, just dependencies! root.dependencies[name] = decEndpoint; } }, this); // Remove root from the flattened tree - delete flattened[json.name]; + delete installed[json.name]; - return [json, root, flattened]; + return [json, root, installed]; }.bind(this)); }; @@ -736,7 +732,7 @@ Project.prototype._restoreNode = function (node, flattened, jsonKey) { node.dependencies = node.dependencies || {}; node.dependants = node.dependants || {}; - // Only process deps that are yet processed + // Only process deps that are not yet processed deps = mout.object.filter(node.pkgMeta[jsonKey], function (value, key) { return !node.dependencies[key]; }); @@ -793,6 +789,9 @@ Project.prototype._restoreNode = function (node, flattened, jsonKey) { // Do the same for the incompatible local package if (local && restored !== local) { + local.dependants = local.dependants || {}; + local.dependants[node.name] = node; + this._restoreNode(local, flattened, 'dependencies'); } }, this); diff --git a/lib/index.js b/lib/index.js index 37c9c181b..c32e579eb 100644 --- a/lib/index.js +++ b/lib/index.js @@ -6,6 +6,7 @@ var PackageRepository = require('./core/PackageRepository'); var abbreviations = abbrev(expandNames(commands)); abbreviations.i = 'install'; abbreviations.rm = 'uninstall'; +abbreviations.unlink = 'uninstall'; abbreviations.ls = 'list'; function expandNames(obj, prefix, stack) { diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index 69b5d7a8a..1448d02ae 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -221,6 +221,11 @@ StandardRenderer.prototype._link = function (data) { level: 'info', message: data.dst + ' > ' + data.src }); + + // Print also a tree of the installed packages + if (data.installed) { + this._install(data.installed); + } }; StandardRenderer.prototype._register = function (data) { @@ -463,6 +468,7 @@ StandardRenderer.prototype._tree2archy = function (node) { StandardRenderer._wideCommands = [ 'install', 'update', + 'link', 'info', 'home', 'register' diff --git a/templates/json/help-link.json b/templates/json/help-link.json index 01cab4359..eb674c6b3 100644 --- a/templates/json/help-link.json +++ b/templates/json/help-link.json @@ -1,6 +1,6 @@ { "command": "link", - "description": "The link functionality allows developers to easily test their packages.\nLinking is a two-step process.\n\nUsing 'bower link' in a project folder will create a global link.\nThen, in some other package, 'bower link ' will create a link in the components folder pointing to the previously created link.\n\nThis allows to easily test a package because changes will be reflected immediately.\nPlease note that bower will not fetch the linked package dependencies.\n\nBower will overwrite the link when installing/updating.", + "description": "The link functionality allows developers to easily test their packages.\nLinking is a two-step process.\n\nUsing 'bower link' in a project folder will create a global link.\nThen, in some other package, 'bower link ' will create a link in the components folder pointing to the previously created link.\n\nThis allows to easily test a package because changes will be reflected immediately.\nWhen the link is no longer necessary, simply remove it with 'bower uninstall '.", "usage": [ "link []", "link [] []" From 194a09f21d4bdd63214461b86d193d30ea2ce463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cruz?= Date: Mon, 30 Sep 2013 18:25:54 +0100 Subject: [PATCH 0254/1021] Some fixes. --- lib/commands/uninstall.js | 14 ++++++++++++-- lib/core/Project.js | 7 ++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/commands/uninstall.js b/lib/commands/uninstall.js index f1f15c36c..22e006236 100644 --- a/lib/commands/uninstall.js +++ b/lib/commands/uninstall.js @@ -48,6 +48,7 @@ function clean(project, names, removed) { return project.getTree() .spread(function (tree, flattened) { var nodes = []; + var dependantsCounter = {}; // Grab the nodes of each specified name mout.object.forOwn(flattened, function (node) { @@ -56,9 +57,18 @@ function clean(project, names, removed) { } }); - // Filter out those that have dependants + // Walk the down the tree, gathering dependants of the packages + project.walkTree(tree, function (node, nodeName) { + if (names.indexOf(nodeName) !== -1) { + dependantsCounter[nodeName] = dependantsCounter[nodeName] || 0; + dependantsCounter[nodeName] += node.nrDependants; + } + }, true); + + + // Filter out those that have no dependants nodes = nodes.filter(function (node) { - return !node.nrDependants; + return !dependantsCounter[node.endpoint.name]; }); // Are we done? diff --git a/lib/core/Project.js b/lib/core/Project.js index 7a08a4b0b..da8788cbb 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -351,7 +351,7 @@ Project.prototype.walkTree = function (node, fn, onlyOnce) { while (queue.length) { node = queue.shift(); - result = fn(node, node.name); + result = fn(node, node.endpoint ? node.endpoint.name : node.name); // Abort traversal if result is false if (result === false) { @@ -782,16 +782,13 @@ Project.prototype._restoreNode = function (node, flattened, jsonKey) { // Cross reference node.dependencies[key] = restored; restored.dependants = restored.dependants || {}; - restored.dependants[node.name] = node; + restored.dependants[node.name] = mout.object.mixIn({}, node); // We need to clone due to shared objects in the manager! // Call restore for this dependency this._restoreNode(restored, flattened, 'dependencies'); // Do the same for the incompatible local package if (local && restored !== local) { - local.dependants = local.dependants || {}; - local.dependants[node.name] = node; - this._restoreNode(local, flattened, 'dependencies'); } }, this); From 14dc86e9ea2d70f4d91e7bb53263631d2284a9ae Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Mon, 21 Oct 2013 15:14:08 +0100 Subject: [PATCH 0255/1021] Add the 'moduleType' property to bower init --- lib/commands/init.js | 7 +++++++ lib/renderers/JsonRenderer.js | 9 +++++++++ package.json | 2 +- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/commands/init.js b/lib/commands/init.js index 7796ad620..47a56a01d 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -201,6 +201,12 @@ function promptUser(logger, json) { 'default': json.main, 'type': 'input' }, + { + 'name': 'moduleType', + 'message': 'what types of modules does this package expose?', + 'type': 'checkbox', + 'choices': ['amd', 'es6', 'globals', 'node'] + }, { 'name': 'keywords', 'message': 'keywords', @@ -251,6 +257,7 @@ function promptUser(logger, json) { json.version = answers.version; json.description = answers.description; json.main = answers.main; + json.moduleType = answers.moduleType; json.keywords = toArray(answers.keywords); json.authors = toArray(answers.authors, ','); json.license = answers.license; diff --git a/lib/renderers/JsonRenderer.js b/lib/renderers/JsonRenderer.js index 2554a84de..d8f6643c1 100644 --- a/lib/renderers/JsonRenderer.js +++ b/lib/renderers/JsonRenderer.js @@ -88,6 +88,9 @@ JsonRenderer.prototype.prompt = function (prompts) { case 'password': funcName = prompt.type; break; + case 'checkbox': + funcName = 'prompt'; + break; default: promise = promise.then(function () { throw createError('Unknown prompt type', 'ENOTSUP'); @@ -105,6 +108,12 @@ JsonRenderer.prototype.prompt = function (prompts) { answers[prompt.name] = answer; }); }); + + if (prompt.type === 'checkbox') { + promise = promise.then(function () { + answers[prompt.name] = answers[prompt.name].split(','); + }); + } }); return promise.then(function () { diff --git a/package.json b/package.json index 0d94a796f..463eca75d 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "bower-config": "~0.5.0", "bower-endpoint-parser": "~0.2.0", "bower-json": "~0.4.0", - "bower-logger": "~0.2.1", + "bower-logger": "~0.2.2", "bower-registry-client": "~0.1.4", "cardinal": "~0.4.0", "chalk": "~0.2.0", From bc6428536c63083230623f46e0c9a862ca63114e Mon Sep 17 00:00:00 2001 From: Jarrett Drouillard Date: Thu, 5 Dec 2013 15:47:07 -0500 Subject: [PATCH 0256/1021] Mentions updates in `bower list -h` command --- templates/json/help-list.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/json/help-list.json b/templates/json/help-list.json index 2e6a7c02a..a183f5c39 100644 --- a/templates/json/help-list.json +++ b/templates/json/help-list.json @@ -1,6 +1,6 @@ { "command": "list", - "description": "List local packages.", + "description": "List local packages - and possible updates.", "usage": [ "list []" ], From e84f71cd378767b7731a3cbaf03a6d46c497ffd6 Mon Sep 17 00:00:00 2001 From: Pascal Hartig Date: Thu, 5 Dec 2013 13:01:51 -0800 Subject: [PATCH 0257/1021] Basic usage tracking with insight The user is prompted with a question whether he would like to provide usage data on the first start, when run in interactive mode. The current implementation tracks calls to `install`, `info`, `search` and `uninstall` when run with at least one parameter. Fixes #260 Closes gh-796. --- bin/bower | 118 ++++++++++++++++++++------------------ lib/commands/info.js | 4 ++ lib/commands/install.js | 5 ++ lib/commands/register.js | 6 ++ lib/commands/search.js | 4 ++ lib/commands/uninstall.js | 6 ++ lib/config.js | 6 ++ lib/util/analytics.js | 61 ++++++++++++++++++++ package.json | 3 +- 9 files changed, 155 insertions(+), 58 deletions(-) create mode 100644 lib/util/analytics.js diff --git a/bin/bower b/bin/bower index f3d48f537..50afc035b 100755 --- a/bin/bower +++ b/bin/bower @@ -11,6 +11,7 @@ var bower = require('../lib'); var pkg = require(path.join(__dirname, '..', 'package.json')); var cli = require('../lib/util/cli'); var rootCheck = require('../lib/util/rootCheck'); +var analytics = require('../lib/util/analytics'); // -------- @@ -69,71 +70,74 @@ while (options.argv.remain.length) { options.argv.remain.pop(); } -// Execute the command -commandFunc = command && mout.object.get(bower.commands, command); -command = command && command.replace(/\./g, ' '); - -// If no command was specified, show bower help -// Do the same if the command is unknown -if (!commandFunc) { - logger = bower.commands.help(); - command = 'help'; -// If the user requested help, show the command's help -// Do the same if the actual command is a group of other commands (e.g.: cache) -} else if (options.help || !commandFunc.line) { - logger = bower.commands.help(command); - command = 'help'; -// Call the line method -} else { - logger = commandFunc.line(process.argv); +// Ask for Insights on first run. +analytics.setup().then(function () { + // Execute the command + commandFunc = command && mout.object.get(bower.commands, command); + command = command && command.replace(/\./g, ' '); - // If the method failed to interpret the process arguments - // show the command help - if (!logger) { + // If no command was specified, show bower help + // Do the same if the command is unknown + if (!commandFunc) { + logger = bower.commands.help(); + command = 'help'; + // If the user requested help, show the command's help + // Do the same if the actual command is a group of other commands (e.g.: cache) + } else if (options.help || !commandFunc.line) { logger = bower.commands.help(command); command = 'help'; + // Call the line method + } else { + logger = commandFunc.line(process.argv); + + // If the method failed to interpret the process arguments + // show the command help + if (!logger) { + logger = bower.commands.help(command); + command = 'help'; + } } -} -// Get the renderer and configure it with the executed command -renderer = cli.getRenderer(command, logger.json, bower.config); + // Get the renderer and configure it with the executed command + renderer = cli.getRenderer(command, logger.json, bower.config); + + logger + .on('end', function (data) { + if (!bower.config.silent) { + renderer.end(data); + } + }) + .on('error', function (err) { + if (levels.error >= loglevel) { + renderer.error(err); + } + + process.exit(1); + }) + .on('log', function (log) { + if (levels[log.level] >= loglevel) { + renderer.log(log); + } + }) + .on('prompt', function (prompt, callback) { + renderer.prompt(prompt) + .then(function (answer) { + callback(answer); + }); + }); -logger -.on('end', function (data) { - if (!bower.config.silent) { - renderer.end(data); - } -}) -.on('error', function (err) { - if (levels.error >= loglevel) { - renderer.error(err); + // Warn if HOME is not SET + if (!osenv.home()) { + logger.warn('no-home', 'HOME not set, user configuration will not be loaded'); } - process.exit(1); -}) -.on('log', function (log) { - if (levels[log.level] >= loglevel) { - renderer.log(log); - } -}) -.on('prompt', function (prompt, callback) { - renderer.prompt(prompt) - .then(function (answer) { - callback(answer); + // Check for newer version of Bower + notifier = updateNotifier({ + packageName: pkg.name, + packageVersion: pkg.version }); -}); - -// Warn if HOME is not SET -if (!osenv.home()) { - logger.warn('no-home', 'HOME not set, user configuration will not be loaded'); -} -// Check for newer version of Bower -notifier = updateNotifier({ - packageName: pkg.name, - packageVersion: pkg.version + if (notifier.update && levels.info >= loglevel) { + renderer.updateNotice(notifier.update); + } }); - -if (notifier.update && levels.info >= loglevel) { - renderer.updateNotice(notifier.update); -} diff --git a/lib/commands/info.js b/lib/commands/info.js index 67573c9a3..e9cf2dfe3 100644 --- a/lib/commands/info.js +++ b/lib/commands/info.js @@ -4,17 +4,21 @@ var Logger = require('bower-logger'); var endpointParser = require('bower-endpoint-parser'); var PackageRepository = require('../core/PackageRepository'); var cli = require('../util/cli'); +var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); function info(endpoint, property, config) { var repository; var decEndpoint; + var tracker; var logger = new Logger(); config = mout.object.deepFillIn(config || {}, defaultConfig); repository = new PackageRepository(config, logger); + tracker = new Tracker(config); decEndpoint = endpointParser.decompose(endpoint); + tracker.trackDecomposedEndpoints('info', [decEndpoint]); Q.all([ getPkgMeta(repository, decEndpoint, property), diff --git a/lib/commands/install.js b/lib/commands/install.js index 665a92604..46594fbb5 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -3,25 +3,30 @@ var Logger = require('bower-logger'); var endpointParser = require('bower-endpoint-parser'); var Project = require('../core/Project'); var cli = require('../util/cli'); +var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); function install(endpoints, options, config) { var project; var decEndpoints; + var tracker; var logger = new Logger(); options = options || {}; config = mout.object.deepFillIn(config || {}, defaultConfig); project = new Project(config, logger); + tracker = new Tracker(config); // Convert endpoints to decomposed endpoints endpoints = endpoints || []; decEndpoints = endpoints.map(function (endpoint) { return endpointParser.decompose(endpoint); }); + tracker.trackDecomposedEndpoints('install', decEndpoints); project.install(decEndpoints, options) .done(function (installed) { + tracker.trackPackages('installed', installed); logger.emit('end', installed); }, function (error) { logger.emit('error', error); diff --git a/lib/commands/register.js b/lib/commands/register.js index 06c520894..f7e254257 100644 --- a/lib/commands/register.js +++ b/lib/commands/register.js @@ -4,6 +4,7 @@ var chalk = require('chalk'); var PackageRepository = require('../core/PackageRepository'); var Logger = require('bower-logger'); var Config = require('bower-config'); +var Tracker = require('../util/analytics').Tracker; var cli = require('../util/cli'); var createError = require('../util/createError'); var defaultConfig = require('../config'); @@ -12,11 +13,13 @@ var GitHubResolver = require('../core/resolvers/GitHubResolver'); function register(name, url, config) { var repository; var registryClient; + var tracker; var logger = new Logger(); var force; config = mout.object.deepFillIn(config || {}, defaultConfig); force = config.force; + tracker = new Tracker(config); // Bypass any cache config.offline = false; @@ -42,6 +45,8 @@ function register(name, url, config) { } } + tracker.track('register'); + // Attempt to resolve the package referenced by the URL to ensure // everything is ok before registering repository = new PackageRepository(config, logger); @@ -81,6 +86,7 @@ function register(name, url, config) { return Q.nfcall(registryClient.register.bind(registryClient), name, url); }) .done(function (result) { + tracker.track('registered'); logger.emit('end', result); }, function (error) { logger.emit('error', error); diff --git a/lib/commands/search.js b/lib/commands/search.js index 960f9c13d..c42b362ae 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -3,17 +3,20 @@ var Q = require('q'); var Logger = require('bower-logger'); var RegistryClient = require('bower-registry-client'); var cli = require('../util/cli'); +var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); function search(name, config) { var registryClient; var promise; + var tracker; var logger = new Logger(); config = mout.object.deepFillIn(config || {}, defaultConfig); config.cache = config.storage.registry; registryClient = new RegistryClient(config, logger); + tracker = new Tracker(config); // If no name was specified, list all packages if (!name) { @@ -25,6 +28,7 @@ function search(name, config) { promise .done(function (results) { + tracker.track('searched', name); logger.emit('end', results); }, function (error) { logger.emit('error', error); diff --git a/lib/commands/uninstall.js b/lib/commands/uninstall.js index f1f15c36c..6fce590ff 100644 --- a/lib/commands/uninstall.js +++ b/lib/commands/uninstall.js @@ -3,15 +3,20 @@ var Logger = require('bower-logger'); var Q = require('q'); var Project = require('../core/Project'); var cli = require('../util/cli'); +var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); function uninstall(names, options, config) { var project; + var tracker; var logger = new Logger(); options = options || {}; config = mout.object.deepFillIn(config || {}, defaultConfig); project = new Project(config, logger); + tracker = new Tracker(config); + + tracker.trackNames('uninstall', names); project.getTree() .spread(function (tree, flattened) { @@ -35,6 +40,7 @@ function uninstall(names, options, config) { }) .done(function (uninstalled) { logger.emit('end', uninstalled); + tracker.trackNames('uninstalled', Object.keys(uninstalled)); }, function (error) { logger.emit('error', error); }); diff --git a/lib/config.js b/lib/config.js index 3ba217986..1a665c6b8 100644 --- a/lib/config.js +++ b/lib/config.js @@ -12,6 +12,12 @@ if (config.interactive == null) { config.interactive = process.bin === 'bower' && tty.isatty(1); } +// If `analytics` hasn't been explicitly set, we disable +// it when ran programatically. +if (config.analytics == null) { + config.analytics = config.interactive; +} + // Merge common CLI options into the config mout.object.mixIn(config, cli.readOptions({ force: { type: Boolean, shorthand: 'f' }, diff --git a/lib/util/analytics.js b/lib/util/analytics.js new file mode 100644 index 000000000..023858b65 --- /dev/null +++ b/lib/util/analytics.js @@ -0,0 +1,61 @@ +var Q = require('q'); +var Insight = require('insight'); +var mout = require('mout'); +var config = require('../config'); +var pkg = require('../../package.json'); + +var analytics = module.exports; +var insight; + +// Initializes the application-wide insight singleton and asks for the +// permission on the CLI during the first run. +analytics.setup = function setup() { + var deferred = Q.defer(); + insight = new Insight({ + trackingCode: 'UA-43531210-1', + packageName: pkg.name, + packageVersion: pkg.version + }); + + // Display the ask prompt only if it hasn't been answered before + // and the current session is interactive. + if (insight.optOut === undefined && config.interactive) { + insight.askPermission(null, deferred.resolve); + } else { + deferred.resolve(); + } + + return deferred.promise; +}; + +var Tracker = analytics.Tracker = function Tracker(config) { + if (!config.analytics) { + this.track = function noop() {}; + } +}; + +Tracker.prototype.track = function track() { + if (!insight) { + throw new Error('You must call analytics.setup() prior to tracking.'); + } + insight.track.apply(insight, arguments); +}; + +Tracker.prototype.trackDecomposedEndpoints = function trackDecomposedEndpoints(command, endpoints) { + endpoints.forEach(function (endpoint) { + this.track(command, endpoint.source, endpoint.target); + }.bind(this)); +}; + +Tracker.prototype.trackPackages = function trackPackages(command, packages) { + mout.object.forOwn(packages, function (package) { + var meta = package.pkgMeta; + this.track(command, meta.name, meta.version); + }.bind(this)); +}; + +Tracker.prototype.trackNames = function trackNames(command, names) { + names.forEach(function (name) { + this.track(command, name); + }.bind(this)); +}; diff --git a/package.json b/package.json index 148a28b6a..1f1fb976a 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,8 @@ "tmp": "~0.0.20", "update-notifier": "~0.1.3", "which": "~1.0.5", - "p-throttler": "~0.0.1" + "p-throttler": "~0.0.1", + "insight": "~0.2.0" }, "devDependencies": { "expect.js": "~0.2.0", From c385c08e2fee72b278cbf373925cee01c6bc5bf7 Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Fri, 6 Dec 2013 22:11:00 +0000 Subject: [PATCH 0258/1021] Close GH-2: Add checkbox prompt. --- packages/bower-logger/lib/Logger.js | 11 +++++++++-- packages/bower-logger/test/test.js | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/packages/bower-logger/lib/Logger.js b/packages/bower-logger/lib/Logger.js index 8e95fa983..7c4dff10a 100644 --- a/packages/bower-logger/lib/Logger.js +++ b/packages/bower-logger/lib/Logger.js @@ -99,7 +99,13 @@ Logger.prototype.prompt = function (prompts, callback) { var value = answers[key]; if (typeof value === 'string') { - answers[key] = answers[key].trim(); + answers[key] = value.trim(); + } else if (Array.isArray(value)) { + answers[key] = value.map(function (item) { + if (typeof item === 'string') { + return item.trim(); + } + }); } }); @@ -121,7 +127,8 @@ Logger.prototype.prompt = function (prompts, callback) { Logger._validPrompts = [ 'input', 'confirm', - 'password' + 'password', + 'checkbox' ]; Logger.LEVELS = { diff --git a/packages/bower-logger/test/test.js b/packages/bower-logger/test/test.js index ae92fec0e..54f394fab 100644 --- a/packages/bower-logger/test/test.js +++ b/packages/bower-logger/test/test.js @@ -367,5 +367,23 @@ describe('Logger', function () { next(); }); }); + + it('should trim multiple response answers', function (next) { + logger + .once('prompt', function (prompts, callback) { + callback({ + prompt: [' bar ', ' foo', 'baz '] + }); + }) + .prompt({ + type: 'checkbox', + message: 'foo' + }, function (err, answer) { + expect(err).to.not.be.ok(); + expect(answer).to.eql(['bar', 'foo', 'baz']); + next(); + }); + }); + }); }); From ea559592b536a5ac003bc8cb89746843f673f480 Mon Sep 17 00:00:00 2001 From: Fredrik Forsmo Date: Sat, 7 Dec 2013 11:17:12 +0100 Subject: [PATCH 0259/1021] Updated readme with correct jQuery example script tag The example script tag has `jquery/index.js` but jQuery have `jquery.js` as main file, so the readme should have the correct main file in the example. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 30c3c5c27..405cea720 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ The easiest approach is to use Bower statically, just reference the package's installed components manually using a `script` tag: ```html - + ``` For more complex projects, you'll probably want to concatenate your scripts or From faf1c266696c6d0c84cf06cca39c651d5db44d36 Mon Sep 17 00:00:00 2001 From: xiaojue Date: Wed, 11 Dec 2013 15:17:08 +0800 Subject: [PATCH 0260/1021] add headers for request to fix userAgent not work. --- packages/bower-registry-client/lib/list.js | 1 + packages/bower-registry-client/lib/lookup.js | 1 + packages/bower-registry-client/lib/register.js | 1 + packages/bower-registry-client/lib/search.js | 1 + 4 files changed, 4 insertions(+) diff --git a/packages/bower-registry-client/lib/list.js b/packages/bower-registry-client/lib/list.js index 6234d0bb2..4790da23d 100644 --- a/packages/bower-registry-client/lib/list.js +++ b/packages/bower-registry-client/lib/list.js @@ -96,6 +96,7 @@ function doRequest(index, callback) { req = replay(request.get(requestUrl, { proxy: remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, ca: this._config.ca.search[index], + headers:headers, strictSSL: this._config.strictSsl, timeout: this._config.timeout, json: true diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index 7303bc2c2..718117599 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -87,6 +87,7 @@ function doRequest(name, index, callback) { req = replay(request.get(requestUrl, { proxy: remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, + headers:headers, ca: this._config.ca.search[index], strictSSL: this._config.strictSsl, timeout: this._config.timeout, diff --git a/packages/bower-registry-client/lib/register.js b/packages/bower-registry-client/lib/register.js index 286375003..25133fa68 100644 --- a/packages/bower-registry-client/lib/register.js +++ b/packages/bower-registry-client/lib/register.js @@ -15,6 +15,7 @@ function register(name, url, callback) { request.post({ url: requestUrl, proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, + headers:headers, ca: config.ca.register, strictSSL: config.strictSsl, timeout: config.timeout, diff --git a/packages/bower-registry-client/lib/search.js b/packages/bower-registry-client/lib/search.js index 9b2144318..4804ac467 100644 --- a/packages/bower-registry-client/lib/search.js +++ b/packages/bower-registry-client/lib/search.js @@ -103,6 +103,7 @@ function doRequest(name, index, callback) { req = replay(request.get(requestUrl, { proxy: remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, + headers:headers, ca: this._config.ca.search[index], strictSSL: this._config.strictSsl, timeout: this._config.timeout, From 4b2235aef2bb1fba420a415b6a95ca359ba8711f Mon Sep 17 00:00:00 2001 From: xiaojue Date: Wed, 11 Dec 2013 18:32:13 +0800 Subject: [PATCH 0261/1021] add userAgent test --- packages/bower-registry-client/test/Client.js | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 1c396b93a..bae6bbfa6 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -3,6 +3,7 @@ var fs = require('fs'); var expect = require('expect.js'); var md5 = require('../lib/util/md5'); var nock = require('nock'); +var http = require('http'); describe('RegistryClient', function () { beforeEach(function () { @@ -581,4 +582,32 @@ describe('RegistryClient', function () { }); }); }); + + // + // test userAgent + // + describe('add a custom userAgent with argument',function(){ + this.timeout(5000); + it('should send custom userAgent to the server',function(next){ + var self = this; + this.ua = ''; + this.server = http.createServer(function (req, res) { + self.ua = req.headers['user-agent']; + res.writeHeader(200,{ + 'Content-Type':'application/json' + }); + res.end('{"name":"jquery","url":"git://github.com/components/jquery.git"}'); + self.server.close(); + }); + this.server.listen('7777', '127.0.0.1'); + this.registry = new RegistryClient({ + userAgent:'test agent', + registry:'http://127.0.0.1:7777' + }); + this.registry.search('jquery', function (err,result) { + expect(self.ua).to.be('test agent'); + next(); + }); + }); + }); }); From 597853cd6c9d61a9d66c924c317059384e785fe1 Mon Sep 17 00:00:00 2001 From: Sven Lito Date: Wed, 11 Dec 2013 10:43:50 +0000 Subject: [PATCH 0262/1021] bump version --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 7086555e5..fce4ec2f1 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.1.5", + "version": "0.1.6", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From 52aa87c145d03d9b44f8c5be68b4d6250fcc231c Mon Sep 17 00:00:00 2001 From: Erwann Mest Date: Mon, 16 Dec 2013 22:16:17 +0100 Subject: [PATCH 0263/1021] Update docs about private repo. refs #897 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 405cea720..d07ff93e1 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,8 @@ bower install =# Where `` can be any one of the following: * A name that maps to a package registered with Bower, e.g, `jquery`. ‡ -* A remote Git endpoint, e.g., `git://github.com/someone/some-package.git`. Can be - public or private. ‡ +* A public remote Git endpoint, e.g., ```git://github.com/someone/some-package.git```. ‡ +* A private Git repository, e.g., ```https://github.com/someone/some-package.git```. If the protocol is https, a prompt will ask for the credentials. ssh can also be used, e.g., ```git@github.com:someone/some-package.git``` and can authenticate with the user's ssh public/private keys. ‡ * A local endpoint, i.e., a folder that's a Git repository. ‡ * A shorthand endpoint, e.g., `someone/some-package` (defaults to GitHub). ‡ * A URL to a file, including `zip` and `tar` files. Its contents will be From 634ed4a341e2cb5cc21741672bbe12c4e35736a4 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sun, 22 Dec 2013 02:36:52 +0100 Subject: [PATCH 0264/1021] Add note about setting custom install dir Closes #845 --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 405cea720..98164440b 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,18 @@ Using `bower list` will show all the packages that are installed locally. others (e.g., you're building a web app), you should always [check installed packages into source control](http://addyosmani.com/blog/checking-in-front-end-dependencies/). + +### Custom install directory + +A custom install location can be set in a .bowerrc file using the `directory` property. The .bowerrc file should be a sibling of your project's bower.json. + +```json +{ + "directory": "public/bower_components" +} +``` + + ### Finding packages To search for packages registered with Bower: From bccfd7bbbba1e71ad89c913069edfdbba7937d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E5=9F=B9=E5=85=AC?= Date: Tue, 24 Dec 2013 15:03:03 +0800 Subject: [PATCH 0265/1021] fix a bug. --- packages/bower-registry-client/lib/lookup.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index 718117599..989e5ff9d 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -114,10 +114,14 @@ function doRequest(name, index, callback) { return callback(createError('Response of request to ' + requestUrl + ' is not a valid json', 'EINVRES')); } - callback(null, { - type: 'alias', - url: body.url - }); + var data; + if (body.url) { + data = { + type: 'alias', + url: body.url + }; + } + callback(null, data); })); if (this._logger) { From b11ef97b7d2f3e9adfa6420b3f26d5b309f0b529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Wed, 25 Dec 2013 23:33:40 +0000 Subject: [PATCH 0266/1021] Forgot to return promise, fixes #1023 --- lib/commands/prune.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/commands/prune.js b/lib/commands/prune.js index 1743a8034..439b52346 100644 --- a/lib/commands/prune.js +++ b/lib/commands/prune.js @@ -33,7 +33,7 @@ function clean(project, removed) { }); // Uninstall extraneous - project.uninstall(names) + return project.uninstall(names) .then(function (uninstalled) { // Are we done? if (!mout.object.size(uninstalled)) { From 237022baaef84ec00f7237fca8076754c3b7a2a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E5=9F=B9=E5=85=AC?= Date: Thu, 26 Dec 2013 08:08:29 +0800 Subject: [PATCH 0267/1021] add a test. add a test 'calling the lookup instance method with two registries, and the first missing', and adjust the test sequence. --- packages/bower-registry-client/test/Client.js | 69 ++++++++++++++++--- 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index bae6bbfa6..013a6a3a0 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -195,6 +195,65 @@ describe('RegistryClient', function () { }); }); + describe('calling the lookup instance method without argument', function () { + it('should return no result', function (next) { + this.registry.lookup('', function (err, entry) { + expect(err).to.not.be.ok(); + expect(entry).to.not.be.ok(); + next(); + }); + }); + }); + + describe('calling the lookup instance method with two registries, and the first missing.', function () { + beforeEach(function () { + nock('http://custom-registry.com') + .get('/packages/jquery') + .reply(200, { + "error": { + "message": "missing", + "stack": "Error: missing" + } + }); + + nock('http://custom-registry2.com') + .get('/packages/jquery') + .reply(200, { + name: 'jquery', + url: 'git://github.com/foo/baz' + }); + + this.registry = new RegistryClient({ + strictSsl: false, + force: true, + registry: { + search: [ + 'http://custom-registry.com', + 'http://custom-registry2.com' + ] + } + }); + }); + + it('should return entry type', function (next) { + this.registry.lookup('jquery', function (err, entry) { + expect(err).to.be(null); + expect(entry).to.be.an('object'); + expect(entry.type).to.eql('alias'); + next(); + }); + }); + + it('should return entry url ', function (next) { + this.registry.lookup('jquery', function (err, entry) { + expect(err).to.be(null); + expect(entry).to.be.an('object'); + expect(entry.url).to.eql('git://github.com/foo/baz'); + next(); + }); + }); + }); + describe('calling the lookup instance method with three registries', function () { beforeEach(function () { nock('https://bower.herokuapp.com:443') @@ -262,16 +321,6 @@ describe('RegistryClient', function () { }); }); - describe('calling the lookup instance method without argument', function () { - it('should return no result', function (next) { - this.registry.lookup('', function (err, entry) { - expect(err).to.not.be.ok(); - expect(entry).to.not.be.ok(); - next(); - }); - }); - }); - // // register // From 40dbb0ffaf1f4d0238c6bc51bf2c2cb491d79828 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 31 Dec 2013 04:54:57 +0100 Subject: [PATCH 0268/1021] Ignore prerelease versions if possible, fixes #1017 --- lib/util/semver.js | 8 ++--- test/core/resolvers/gitResolver.js | 49 ++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/lib/util/semver.js b/lib/util/semver.js index 124ab0f5e..d0a195357 100644 --- a/lib/util/semver.js +++ b/lib/util/semver.js @@ -20,11 +20,11 @@ function maxSatisfying(versions, range, strictMatch) { } } - // When strict match is enabled and range is *, - // give priority to non-pre-releases - // We do this by filtering every pre-release version range = typeof range === 'string' ? range.trim() : range; - if (strictMatch && (!range || range === '*')) { + + // When strict match is enabled give priority to non-pre-releases + // We do this by filtering every pre-release version + if (strictMatch) { filteredVersions = versions.map(function (version) { return !isPreRelease(version) ? version : null; }); diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index b2ddcc32e..e0b220297 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -481,6 +481,31 @@ describe('GitResolver', function () { .done(); }); + it('should resolve "0.1.*" to the latest version if a repository has valid semver tags, ignoring pre-releases', function (next) { + var resolver; + + GitResolver.refs = function () { + return Q.resolve([ + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.1.0', + 'cccccccccccccccccccccccccccccccccccccccc refs/tags/v0.1.1', + 'dddddddddddddddddddddddddddddddddddddddd refs/tags/0.1.2-rc.1' // Should ignore release candidates + ]); + }; + + resolver = create('foo'); + resolver._findResolution('0.1.*') + .then(function (resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: 'v0.1.1', + commit: 'cccccccccccccccccccccccccccccccccccccccc' + }); + next(); + }) + .done(); + }); + it('should resolve "*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { var resolver; @@ -505,6 +530,30 @@ describe('GitResolver', function () { .done(); }); + it('should resolve "0.1.*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { + var resolver; + + GitResolver.refs = function () { + return Q.resolve([ + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.1.0-rc.1', + 'cccccccccccccccccccccccccccccccccccccccc refs/tags/0.1.0-rc.2' + ]); + }; + + resolver = create('foo'); + resolver._findResolution('0.1.*') + .then(function (resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: '0.1.0-rc.2', + commit: 'cccccccccccccccccccccccccccccccccccccccc' + }); + next(); + }) + .done(); + }); + it('should resolve to the latest version that matches a range/version', function (next) { var resolver; From f3cca3483d1b93abb3adfba80e4bb9072f0e92e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ramiro=20G=C3=B3mez?= Date: Thu, 2 Jan 2014 19:12:52 +0100 Subject: [PATCH 0269/1021] Changed to uppercase S as shorthand for save Before the help showed lowercase s '-s' as the option to save installed packages, which doesn't work. --- templates/json/help-uninstall.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/json/help-uninstall.json b/templates/json/help-uninstall.json index b4c4a1979..95cc44d39 100644 --- a/templates/json/help-uninstall.json +++ b/templates/json/help-uninstall.json @@ -11,7 +11,7 @@ "description": "Show this help message" }, { - "shorthand": "-s", + "shorthand": "-S", "flag": "--save", "description": "Save installed packages into the project's bower.json dependencies" }, From 729ef0190e7ccc9fc7a69204b066de5eac82e183 Mon Sep 17 00:00:00 2001 From: Joshua Clanton Date: Wed, 8 Jan 2014 18:43:36 +0100 Subject: [PATCH 0270/1021] Note that commit hashes are valid versions Closes #870 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 40540d4a0..da85acf21 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,9 @@ Where `` can be any one of the following: ‡ These types of `` might have versions available. You can specify a [semver](http://semver.org/) compatible version to fetch a specific release, and lock the package to that version. You can also use ranges to specify a range of versions. +If you are using a package that is a git endpoint, you may use any tag, commit SHA, +or branch name as a version. For example: `#`. Using branches is not +recommended because the HEAD does not reference a fixed commit SHA. All package contents are installed in the `bower_components` directory by default. You should **never** directly modify the contents of this directory. From 3044c16ce151e4bdaf512dc25671ed2002823342 Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Tue, 14 Jan 2014 13:10:23 +0000 Subject: [PATCH 0271/1021] Enable Q long stack traces when in verbose mode --- bin/bower | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/bower b/bin/bower index 50afc035b..31ae6c95c 100755 --- a/bin/bower +++ b/bin/bower @@ -2,6 +2,7 @@ process.bin = process.title = 'bower'; +var Q = require('q'); var path = require('path'); var mout = require('mout'); var updateNotifier = require('update-notifier'); @@ -44,6 +45,7 @@ if (bower.config.silent) { loglevel = levels.error; } else if (bower.config.verbose) { loglevel = -Infinity; + Q.longStackSupport = true; } else if (bower.config.quiet) { loglevel = levels.warn; } else { From 10d2d566a340251e76cbf8b8025f9501008ce1e6 Mon Sep 17 00:00:00 2001 From: Ahmad Nassri Date: Wed, 15 Jan 2014 17:46:43 -0500 Subject: [PATCH 0272/1021] WIP working off trunk and maybe tags, not fully tested, not fully ready for PR --- Gruntfile.js | 4 +- lib/core/resolverFactory.js | 22 + lib/core/resolvers/SvnRemoteResolver.js | 92 ++ lib/core/resolvers/SvnResolver.js | 356 ++++++++ lib/core/resolvers/index.js | 1 + test/core/resolvers/svnResolver.js | 1106 +++++++++++++++++++++++ test/packages-svn.js | 195 ++++ test/packages-svn.json | 79 ++ test/test.js | 1 + 9 files changed, 1854 insertions(+), 2 deletions(-) create mode 100644 lib/core/resolvers/SvnRemoteResolver.js create mode 100644 lib/core/resolvers/SvnResolver.js create mode 100644 test/core/resolvers/svnResolver.js create mode 100644 test/packages-svn.js create mode 100644 test/packages-svn.json diff --git a/Gruntfile.js b/Gruntfile.js index 400ee8519..75f42c80f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -21,10 +21,10 @@ module.exports = function (grunt) { }, exec: { assets: { - command: 'node test/packages.js' + command: 'node test/packages.js && node test/packages-svn.js' }, 'assets-force': { - command: 'node test/packages.js --force' + command: 'node test/packages.js --force && node test/packages-svn.js --force' }, cover: { command: 'node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- -R dot test/test.js' diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index f2568951f..0743bb219 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -45,6 +45,13 @@ function getConstructor(source, config, registryClient) { }); } + // Bzr case: svn, svn+ssh + if (/^svn(\+ssh)?:\/\//i.test(source)) { + return Q.fcall(function () { + return [resolvers.Svn, source]; + }); + } + // URL case if (/^https?:\/\//i.exec(source)) { return Q.fcall(function () { @@ -71,6 +78,21 @@ function getConstructor(source, config, registryClient) { throw new Error('Not a Git repository'); }) + + // If not, check if source is a valid Subversion repository + .fail(function () { + return Q.nfcall(fs.stat, path.join(absolutePath, '.svn')) + .then(function (stats) { + if (stats.isDirectory()) { + return function () { + return Q.resolve([resolvers.Svn, absolutePath]); + }; + } + + throw new Error('Not a Subversion repository'); + }); + }) + // If not, check if source is a valid file/folder .fail(function () { return Q.nfcall(fs.stat, absolutePath) diff --git a/lib/core/resolvers/SvnRemoteResolver.js b/lib/core/resolvers/SvnRemoteResolver.js new file mode 100644 index 000000000..e41a9f42b --- /dev/null +++ b/lib/core/resolvers/SvnRemoteResolver.js @@ -0,0 +1,92 @@ +var util = require('util'); +var url = require('url'); +var mout = require('mout'); +var SvnResolver = require('./SvnResolver'); +var cmd = require('../../util/cmd'); + +function SvnRemoteResolver(decEndpoint, config, logger) { + SvnResolver.call(this, decEndpoint, config, logger); + + if (!mout.string.startsWith(this._source, 'http://')) { + // force use http urls + this._source = this._source.replace('svn://', 'http://'); + + // Trim trailing slashes + this._source = this._source.replace(/\/+$/, ''); + } +} + +util.inherits(SvnRemoteResolver, SvnResolver); +mout.object.mixIn(SvnRemoteResolver, SvnResolver); + +SvnRemoteResolver.prototype._checkout = function () { + var promise; + var timer; + var reporter; + var that = this; + var resolution = this._resolution; + var info = resolution.type; + + if (resolution.type !== 'trunk') { + info += ' ' + resolution.tag || resolution.branch || resolution.commit + } + + this._logger.action('checkout', info, { + resolution: resolution, + to: this._tempDir + }); + + switch (resolution.type) { + case 'revision': + promise = cmd('svn', ['checkout', '-r ' + resolution.commit, this._source, this._tempDir]); + break; + + case 'trunk': + promise = cmd('svn', ['checkout', this._source + '/trunk', this._tempDir]); + break + + default: + promise = cmd('svn', ['checkout', this._source + '/' + resolution.type + 's', this._tempDir]); + } + + // Throttle the progress reporter to 1 time each sec + reporter = mout.fn.throttle(function (data) { + var lines; + + lines = data.split(/[\r\n]+/); + lines.forEach(function (line) { + if (/\d{1,3}\%/.test(line)) { + // TODO: There are some strange chars that appear once in a while (\u001b[K) + // Trim also those? + that._logger.info('progress', line.trim()); + } + }); + }, 1000); + + // Start reporting progress after a few seconds + timer = setTimeout(function () { + promise.progress(reporter); + }, 8000); + + return promise + // Add additional proxy information to the error if necessary + .fail(function (err) { + throw err; + }) + // Clear timer at the end + .fin(function () { + clearTimeout(timer); + reporter.cancel(); + }); +}; + +SvnRemoteResolver.prototype._findResolution = function (target) { + // Override this function to include a meaningful message related to proxies + // if necessary + return SvnResolver.prototype._findResolution.call(this, target) + .fail(function (err) { + throw err; + }); +}; + +module.exports = SvnRemoteResolver; diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js new file mode 100644 index 000000000..9661e222b --- /dev/null +++ b/lib/core/resolvers/SvnResolver.js @@ -0,0 +1,356 @@ +var util = require('util'); +var path = require('path'); +var Q = require('q'); +var rimraf = require('rimraf'); +var which = require('which'); +var LRU = require('lru-cache'); +var mout = require('mout'); +var Resolver = require('./Resolver'); +var semver = require('../../util/semver'); +var createError = require('../../util/createError'); +var cmd = require('../../util/cmd'); + +var hasSvn; + +// Check if svn is installed +try { + which.sync('svn'); + hasSvn = true; +} catch (ex) { + hasSvn = false; +} + +function SvnResolver(decEndpoint, config, logger) { + Resolver.call(this, decEndpoint, config, logger); + + if (!hasSvn) { + throw createError('svn is not installed or not in the PATH', 'ENOSVN'); + } +} + +util.inherits(SvnResolver, Resolver); +mout.object.mixIn(SvnResolver, Resolver); + +// ----------------- + +SvnResolver.prototype._hasNew = function (canonicalDir, pkgMeta) { + var oldResolution = pkgMeta._resolution || {}; + + return this._findResolution() + .then(function (resolution) { + // Check if resolution types are different + if (oldResolution.type !== resolution.type) { + return true; + } + + // If resolved to a version, there is new content if the tags are not equal + if (resolution.type === 'version' && semver.neq(resolution.tag, oldResolution.tag)) { + return true; + } + + // As last check, we compare both commit hashes + return resolution.commit !== oldResolution.commit; + }); +}; + +SvnResolver.prototype._resolve = function () { + var that = this; + + return this._findResolution() + .then(function () { + return that._checkout() + // Always run cleanup after checkout to ensure that .svn is removed! + // If it's not removed, problems might arise when the "tmp" module attempts + // to delete the temporary folder + .fin(function () { + return that._cleanup(); + }); + }); +}; + +// ----------------- + +// Abstract functions that should be implemented by concrete git resolvers +SvnResolver.prototype._checkout = function () { + throw new Error('_checkout not implemented'); +}; + +// ----------------- + +SvnResolver.prototype._findResolution = function (target) { + var err; + var self = this.constructor; + var that = this; + + target = target || this._target || '*'; + + // Target is a revision, so it's a stale target (not a moving target) + // There's nothing to do in this case + if ((/^r\d+/).test(target)) { + target = target.split('r'); + + this._resolution = { type: 'revision', commit: target[1] }; + return Q.resolve(this._resolution); + } + + // Target trunk + if (target === 'trunk') { + this._resolution = { type: 'trunk' }; + return Q.resolve(this._resolution); + } + + // Target is a range/version + if (semver.validRange(target)) { + return self.versions(this._source, true) + .then(function (versions) { + var versionsArr, + version, + index; + + versionsArr = versions.map(function (obj) { return obj.version; }); + + // If there are no tags and target is *, + // fallback to the latest revision + if (!versions.length && target === '*') { + return that._findResolution('trunk'); + } + + versionsArr = versions.map(function (obj) { return obj.version; }); + // Find a satisfying version, enabling strict match so that pre-releases + // have lower priority over normal ones when target is * + index = semver.maxSatisfyingIndex(versionsArr, target, true); + + if (index !== -1) { + version = versions[index]; + return that._resolution = { type: 'tag', tag: version.tag, commit: version.commit }; + } + + // Check if there's an exact branch/tag with this name as last resort + return Q.all([ + self.branches(that._source), + self.tags(that._source) + ]) + .spread(function (branches, tags) { + // Use hasOwn because a branch/tag could have a name like "hasOwnProperty" + if (mout.object.hasOwn(tags, target)) { + return that._resolution = { type: 'tag', tag: target, commit: tags[target] }; + } + if (mout.object.hasOwn(branches, target)) { + return that._resolution = { type: 'branch', branch: target, commit: branches[target] }; + } + + throw createError('No tag found that was able to satisfy ' + target, 'ENORESTARGET', { + details: !versions.length ? + 'No versions found in ' + that._source : + 'Available versions: ' + versions.map(function (version) { return version.version; }).join(', ') + }); + }); + }); + } + + // Otherwise, target is either a tag or a branch + return Q.all([ + self.branches(that._source), + self.tags(that._source) + ]) + .spread(function (branches, tags) { + // Use hasOwn because a branch/tag could have a name like "hasOwnProperty" + if (mout.object.hasOwn(tags, target)) { + return that._resolution = { type: 'tag', tag: target, commit: tags[target] }; + } + if (mout.object.hasOwn(branches, target)) { + return that._resolution = { type: 'branch', branch: target, commit: branches[target] }; + } + + branches = Object.keys(branches); + tags = Object.keys(tags); + + err = createError('Tag/branch ' + target + ' does not exist', 'ENORESTARGET'); + err.details = !tags.length ? + 'No tags found in ' + that._source : + 'Available tags: ' + tags.join(', '); + err.details += '\n'; + err.details += !branches.length ? + 'No branches found in ' + that._source : + 'Available branches: ' + branches.join(', '); + + throw err; + }); +}; + +SvnResolver.prototype._cleanup = function () { + var svnFolder = path.join(this._tempDir, '.svn'); + + return Q.nfcall(rimraf, svnFolder); +}; + +SvnResolver.prototype._savePkgMeta = function (meta) { + var version; + + if (this._resolution.type === 'revision') { + version = semver.clean(this._resolution.tag); + + // Warn if the package meta version is different than the resolved one + if (typeof meta.version === 'string' && semver.neq(meta.version, version)) { + this._logger.warn('mismatch', 'Version declared in the json (' + meta.version + ') is different than the resolved one (' + version + ')', { + resolution: this._resolution, + pkgMeta: meta + }); + } + + // Ensure package meta version is the same as the resolution + meta.version = version; + } else { + // If resolved to a target that is not a version, + // remove the version from the meta + delete meta.version; + } + + // Save version/tag/commit in the release + // Note that we can't store branches because _release is supposed to be + // an unique id of this ref. + meta._release = version || + this._resolution.tag || + this._resolution.branch || + this._resolution.commit; + + // Save resolution to be used in hasNew later + meta._resolution = this._resolution; + + return Resolver.prototype._savePkgMeta.call(this, meta); +}; + +// ------------------------------ + +SvnResolver.versions = function (source, extra) { + var value = this._cache.versions.get(source); + + if (value) { + return Q.resolve(value) + .then(function () { + var versions = this._cache.versions.get(source); + + // If no extra information was requested, + // resolve simply with the versions + if (!extra) { + versions = versions.map(function (version) { + return version.version; + }); + } + + return versions; + }.bind(this)); + } + + value = this.tags(source) + .then(function (tags) { + var tag; + var version; + var versions = []; + + // For each tag + for (tag in tags) { + version = semver.clean(tag); + if (version) { + versions.push({ version: version, tag: tag, commit: tags[tag] }); + } + } + + // Sort them by DESC order + versions.sort(function (a, b) { + return semver.rcompare(a.version, b.version); + }); + + this._cache.versions.set(source, versions); + + // Call the function again to keep it DRY + return this.versions(source, extra); + }.bind(this)); + + // Store the promise to be reused until it resolves + // to a specific value + this._cache.versions.set(source, value); + + return value; +}; + +SvnResolver.tags = function (source) { + var value = this._cache.tags.get(source); + + if (value) { + return Q.resolve(value); + } + + value = cmd('svn', ['list', source + '/tags']) + .spread(function (stout) { + var tags = []; + + var lines = stout.toString() + .trim() + .replace(/\/+/g, '') + .split(/[\r\n]+/); + + // For each line in the refs, match only the tags + lines.forEach(function (tag) { + tags[tag] = tag; + }); + + this._cache.tags.set(source, tags); + + return tags; + }.bind(this)); + + // Store the promise to be reused until it resolves + // to a specific value + this._cache.tags.set(source, value); + + return value; +}; + +SvnResolver.branches = function (source) { + var value = this._cache.branches.get(source); + + if (value) { + return Q.resolve(value); + } + + value = cmd('svn', ['list', source + '/branches']) + .spread(function (stout) { + var branches = []; + + var lines = stout.toString() + .trim() + .replace(/\/+/g, '') + .split(/[\r\n]+/); + + // For each line in the refs, match only the tags + lines.forEach(function (branch) { + branches[branch] = branch; + }); + + this._cache.branches.set(source, branches); + + return branches; + }.bind(this)); + + // Store the promise to be reused until it resolves + // to a specific value + this._cache.branches.set(source, value); + + return value; +}; + +SvnResolver.clearRuntimeCache = function () { + // Reset cache for branches, tags, etc + mout.object.forOwn(SvnResolver._cache, function (lru) { + lru.reset(); + }); +}; + +SvnResolver._cache = { + branches: new LRU({ max: 50, maxAge: 5 * 60 * 1000 }), + tags: new LRU({ max: 50, maxAge: 5 * 60 * 1000 }), + versions: new LRU({ max: 50, maxAge: 5 * 60 * 1000 }) +}; + +module.exports = SvnResolver; diff --git a/lib/core/resolvers/index.js b/lib/core/resolvers/index.js index ef6498d81..ec64a215d 100644 --- a/lib/core/resolvers/index.js +++ b/lib/core/resolvers/index.js @@ -2,6 +2,7 @@ module.exports = { GitFs: require('./GitFsResolver'), GitRemote: require('./GitRemoteResolver'), GitHub: require('./GitHubResolver'), + Svn: require('./SvnRemoteResolver'), Fs: require('./FsResolver'), Url: require('./UrlResolver') }; diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js new file mode 100644 index 000000000..0214e54a9 --- /dev/null +++ b/test/core/resolvers/svnResolver.js @@ -0,0 +1,1106 @@ +var expect = require('expect.js'); +var util = require('util'); +var path = require('path'); +var fs = require('graceful-fs'); +var chmodr = require('chmodr'); +var rimraf = require('rimraf'); +var mkdirp = require('mkdirp'); +var Q = require('q'); +var mout = require('mout'); +var Logger = require('bower-logger'); +var copy = require('../../../lib/util/copy'); +var SvnResolver = require('../../../lib/core/resolvers/SvnResolver'); +var defaultConfig = require('../../../lib/config'); + +describe('SvnResolver', function () { + var tempDir = path.resolve(__dirname, '../../assets/tmp'); + var testPackage = path.resolve(__dirname, '../../assets/package-svn'); + var originaltags = SvnResolver.tags; + var logger; + + before(function () { + logger = new Logger(); + }); + + afterEach(function () { + logger.removeAllListeners(); + }); + + function clearResolverRuntimeCache() { + SvnResolver.tags = originaltags; + SvnResolver.clearRuntimeCache(); + } + + function create(decEndpoint, config) { + if (typeof decEndpoint === 'string') { + decEndpoint = { source: decEndpoint }; + } + + return new SvnResolver(decEndpoint, config || defaultConfig, logger); + } + + describe('misc', function () { + it.skip('should error out if svn is not installed'); + it.skip('should setup svn template dir to an empty folder'); + }); + + describe('.hasNew', function () { + before(function () { + mkdirp.sync(tempDir); + }); + + afterEach(function (next) { + clearResolverRuntimeCache(); + rimraf(path.join(tempDir, '.bower.json'), next); + }); + + after(function (next) { + rimraf(tempDir, next); + }); + + + it('should be true when the resolution type is different', function (next) { + var resolver; + + fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + name: 'foo', + version: '0.0.0', + _resolution: { + type: 'version', + tag: '0.0.0', + commit: 123 + } + })); + SvnResolver.tags = function () { + return Q.resolve({ + 'boo': 123 // same commit hash on purpose + }); + }; + + resolver = create('foo'); + resolver.hasNew(tempDir) + .then(function (hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); + }); + + it('should be true when a higher version for a range is available', function (next) { + var resolver; + + fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + name: 'foo', + version: '1.0.0', + _resolution: { + type: 'version', + tag: '1.0.0', + commit: 3 + } + })); + SvnResolver.tags = function () { + return Q.resolve({ + '1.0.0': 2, + '1.0.1': 2 // same commit hash on purpose + }); + }; + + resolver = create('foo'); + resolver.hasNew(tempDir) + .then(function (hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); + }); + + it('should be true when a resolved to a lower version of a range', function (next) { + var resolver; + + fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + name: 'foo', + version: '1.0.1', + _resolution: { + type: 'version', + tag: '1.0.1', + commit: 3 + } + })); + SvnResolver.tags = function () { + return Q.resolve({ + '1.0.0': 2 + }); + }; + + resolver = create('foo'); + resolver.hasNew(tempDir) + .then(function (hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); + }); + + it('should be false when resolved to the same tag (with same commit hash) for a given range', function (next) { + var resolver; + + fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + name: 'foo', + version: '1.0.1', + _resolution: { + type: 'version', + tag: '1.0.1', + commit: 2 + } + })); + SvnResolver.tags = function () { + return Q.resolve({ + '1.0.0': 1, + '1.0.1': 2 + }); + }; + + resolver = create('foo'); + resolver.hasNew(tempDir) + .then(function (hasNew) { + expect(hasNew).to.be(false); + next(); + }) + .done(); + }); + + it('should be true when resolved to the same tag (with different commit hash) for a given range', function (next) { + var resolver; + + fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + name: 'foo', + version: '1.0.1', + _resolution: { + type: 'version', + tag: '1.0.1', + commit: 3 + } + })); + SvnResolver.tags = function () { + return Q.resolve({ + '1.0.0': 2, + '1.0.1': 4 + }); + }; + + resolver = create('foo'); + resolver.hasNew(tempDir) + .then(function (hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); + }); + + + it('should be false when targeting commit hashes', function (next) { + var resolver; + + fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + name: 'foo', + _resolution: { + type: 'revno', + commit: 1 + } + })); + SvnResolver.tags = function () { + return Q.resolve({ + '1.0.0': 2 + }); + }; + + resolver = create('foo'); + resolver.hasNew(tempDir) + .then(function (hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); + }); + }); + + describe('._resolve', function () { + afterEach(clearResolverRuntimeCache); + + it('should call the necessary functions by the correct order', function (next) { + var resolver; + + function DummyResolver() { + SvnResolver.apply(this, arguments); + this._stack = []; + } + + util.inherits(DummyResolver, SvnResolver); + mout.object.mixIn(DummyResolver, SvnResolver); + + DummyResolver.prototype.getStack = function () { + return this._stack; + }; + + DummyResolver.tags = function () { + return Q.resolve({ + '1.0.0': 1 + }); + }; + + DummyResolver.prototype.resolve = function () { + this._stack = []; + return SvnResolver.prototype.resolve.apply(this, arguments); + }; + + DummyResolver.prototype._findResolution = function () { + this._stack.push('before _findResolution'); + return SvnResolver.prototype._findResolution.apply(this, arguments) + .then(function (val) { + this._stack.push('after _findResolution'); + return val; + }.bind(this)); + }; + + DummyResolver.prototype._checkout = function () { + this._stack.push('before _checkout'); + return Q.resolve() + .then(function (val) { + this._stack.push('after _checkout'); + return val; + }.bind(this)); + }; + + DummyResolver.prototype._cleanup = function () { + this._stack.push('before _cleanup'); + return SvnResolver.prototype._cleanup.apply(this, arguments) + .then(function (val) { + this._stack.push('after _cleanup'); + return val; + }.bind(this)); + }; + + resolver = new DummyResolver({ source: 'foo', target: '1.0.0' }, defaultConfig, logger); + + resolver.resolve() + .then(function () { + expect(resolver.getStack()).to.eql([ + 'before _findResolution', + 'after _findResolution', + 'before _checkout', + 'after _checkout', + 'before _cleanup', + 'after _cleanup' + ]); + next(); + }) + .done(); + }); + + }); + + describe('._findResolution', function () { + afterEach(clearResolverRuntimeCache); + + it('should resolve to an object', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({}); + }; + + resolver = create('foo'); + resolver._findResolution('*') + .then(function (resolution) { + expect(resolution).to.be.an('object'); + next(); + }) + .done(); + }); + + it('should resolve "*" to the latest revno if a repository has no valid semver tags', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({ + 'some-tag': 1 + }); + }; + + resolver = create('foo'); + resolver._findResolution('*') + .then(function (resolution) { + expect(resolution).to.eql({ + type: 'revno', + commit: '-1' + }); + next(); + }) + .done(); + }); + + it('should resolve "*" to the latest version if a repository has valid semver tags, ignoring pre-releases', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({ + '0.1.0': 1, + 'v0.1.1': 2, + '0.2.0-rc.1': 3 // Should ignore release candidates + }); + }; + + resolver = create('foo'); + resolver._findResolution('*') + .then(function (resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: 'v0.1.1', + commit: 2 + }); + next(); + }) + .done(); + }); + + it('should resolve "*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({ + '0.1.0-rc.1': 1, + '0.1.0-rc.2': 2 + }); + }; + + resolver = create('foo'); + resolver._findResolution('*') + .then(function (resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: '0.1.0-rc.2', + commit: 2 + }); + next(); + }) + .done(); + }); + + it('should resolve to the latest version that matches a range/version', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({ + '0.1.0': 1, + 'v0.1.1': 2, + '0.2.0': 3, + 'v0.2.1': 4 + }); + }; + + resolver = create('foo'); + resolver._findResolution('~0.2.0') + .then(function (resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: 'v0.2.1', + commit: 4 + }); + next(); + }) + .done(); + }); + + it('should resolve to a tag even if target is a range that does not exist', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({ + '1.0': 1 + }); + }; + + resolver = create('foo'); + resolver._findResolution('1.0') + .then(function (resolution) { + expect(resolution).to.eql({ + type: 'tag', + tag: '1.0', + commit: 1 + }); + next(); + }) + .done(); + }); + + it('should resolve to the latest pre-release version that matches a range/version', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({ + '0.1.0': 1, + 'v0.1.1': 2, + '0.2.0': 3, + 'v0.2.1-rc.1': 4 + }); + }; + + resolver = create('foo'); + resolver._findResolution('~0.2.1') + .then(function (resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: 'v0.2.1-rc.1', + commit: 4 + }); + next(); + }) + .done(); + }); + + it('should resolve to the exact version if exists', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({ + '0.8.1' : 1, + '0.8.1+build.1': 2, + '0.8.1+build.2': 3, + '0.8.1+build.3': 4 + }); + }; + + resolver = create('foo'); + resolver._findResolution('0.8.1+build.2') + .then(function (resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: '0.8.1+build.2', + commit: 3 + }); + next(); + }) + .done(); + }); + + it('should fail to resolve if none of the versions matched a range/version', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({ + '0.1.0': 1, + 'v0.1.1': 2 + }); + }; + + resolver = create('foo'); + resolver._findResolution('~0.2.0') + .then(function () { + next(new Error('Should have failed')); + }, function (err) { + expect(err).to.be.an(Error); + expect(err.message).to.match(/was able to satisfy ~0.2.0/i); + expect(err.details).to.match(/available versions: 0\.1\.1, 0\.1\.0/i); + expect(err.code).to.equal('ENORESTARGET'); + next(); + }) + .done(); + }); + + it('should fail to resolve if there are no versions to match a range/version', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({ + 'foo': 1 + }); + }; + + resolver = create('foo'); + + resolver._findResolution('~0.2.0') + .then(function () { + next(new Error('Should have failed')); + }, function (err) { + expect(err).to.be.an(Error); + expect(err.message).to.match(/was able to satisfy ~0.2.0/i); + expect(err.details).to.match(/no versions found in foo/i); + expect(err.code).to.equal('ENORESTARGET'); + next(); + }) + .done(); + }); + + it('should resolve to the specified revno', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({ + 'some-tag': 1 + }); + }; + + resolver = create('foo'); + resolver._findResolution('revno:1') + .then(function (resolution) { + expect(resolution).to.eql({ + type: 'revno', + commit: 1 + }); + next(); + }) + .done(); + }); + + it('should resolve to the specified tag if it exists', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({ + 'some-tag': 1 + }); + }; + + resolver = create('foo'); + resolver._findResolution('some-tag') + .then(function (resolution) { + expect(resolution).to.eql({ + type: 'tag', + tag: 'some-tag', + commit: 1 + }); + next(); + }) + .done(); + }); + + it('should fail to resolve to the specified tag if it doesn\'t exists', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({ + 'some-tag': 2 + }); + }; + + resolver = create('foo'); + resolver._findResolution('some-branch') + .then(function () { + next(new Error('Should have failed')); + }, function (err) { + expect(err).to.be.an(Error); + expect(err.message).to.match(/target some-branch does not exist/i); + expect(err.details).to.match(/available tags: some-tag/i); + expect(err.code).to.equal('ENORESTARGET'); + next(); + }) + .done(); + }); + }); + + describe('._cleanup', function () { + beforeEach(function () { + mkdirp.sync(tempDir); + }); + + afterEach(function (next) { + clearResolverRuntimeCache(); + // Need to chmodr before removing..at least on windows + // because .svn has some read only files + chmodr(tempDir, 0777, function () { + rimraf(tempDir, next); + }); + }); + + it('should remove the .svn folder from the temp dir', function (next) { + var resolver = create('foo'); + var dst = path.join(tempDir, '.svn'); + + this.timeout(30000); // Give some time to copy + + // Copy .svn folder to the tempDir + copy.copyDir(path.resolve(__dirname, '../../assets/package-svn/.svn'), dst, { + mode: 0777 + }) + .then(function () { + resolver._tempDir = tempDir; + + return resolver._cleanup() + .then(function () { + expect(fs.existsSync(dst)).to.be(false); + next(); + }); + }) + .done(); + }); + + it('should not fail if .svn does not exist for some reason', function (next) { + var resolver = create('foo'); + var dst = path.join(tempDir, '.svn'); + + resolver._tempDir = tempDir; + + resolver._cleanup() + .then(function () { + expect(fs.existsSync(dst)).to.be(false); + next(); + }) + .done(); + }); + + it('should sill run even if _checkout fails for some reason', function (next) { + var resolver = create('foo'); + var called = false; + + SvnResolver.tags = function () { + return Q.resolve({ + '1.0.0': 1 + }); + }; + + resolver._tempDir = tempDir; + resolver._checkout = function () { + return Q.reject(new Error('Some error')); + }; + + resolver._cleanup = function () { + called = true; + return SvnResolver.prototype._cleanup.apply(this, arguments); + }; + + resolver.resolve() + .then(function () { + next(new Error('Should have failed')); + }, function () { + expect(called).to.be(true); + next(); + }) + .done(); + }); + }); + + describe('._savePkgMeta', function () { + before(function () { + mkdirp.sync(tempDir); + }); + + afterEach(function (next) { + rimraf(path.join(tempDir, '.bower.json'), next); + }); + + after(function (next) { + rimraf(tempDir, next); + }); + + it('should save the resolution to the .bower.json to be used later by .hasNew', function (next) { + var resolver = create('foo'); + + resolver._resolution = { type: 'version', tag: '0.0.1' }; + resolver._tempDir = tempDir; + + resolver._savePkgMeta({ name: 'foo', version: '0.0.1' }) + .then(function () { + return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); + }) + .then(function (contents) { + var json = JSON.parse(contents.toString()); + + expect(json._resolution).to.eql(resolver._resolution); + next(); + }) + .done(); + }); + + it('should save the release in the package meta', function (next) { + var resolver = create('foo'); + var metaFile = path.join(tempDir, '.bower.json'); + + // Test with type 'version' + resolver._resolution = { type: 'version', tag: '0.0.1', commit: '1' }; + resolver._tempDir = tempDir; + + resolver._savePkgMeta({ name: 'foo', version: '0.0.1' }) + .then(function () { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function (contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('0.0.1'); + }) + // Test with type 'version' + build metadata + .then(function () { + resolver._resolution = { type: 'version', tag: '0.0.1+build.5', commit: '1' }; + return resolver._savePkgMeta({ name: 'foo' }); + }) + .then(function () { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function (contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('0.0.1+build.5'); + }) + // Test with type 'tag' + .then(function () { + resolver._resolution = { type: 'tag', tag: '0.0.1', commit: '1' }; + return resolver._savePkgMeta({ name: 'foo' }); + }) + .then(function () { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function (contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('0.0.1'); + }) + // Test with type 'branch' + // In this case, it should be the commit + .then(function () { + resolver._resolution = { type: 'branch', branch: 'foo', commit: '1' }; + return resolver._savePkgMeta({ name: 'foo' }); + }) + .then(function () { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function (contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('1'); + }) + // Test with type 'commit' + .then(function () { + resolver._resolution = { type: 'commit', commit: '1' }; + return resolver._savePkgMeta({ name: 'foo' }); + }) + .then(function () { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function (contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('1'); + next(); + }) + .done(); + }); + + it('should add the version to the package meta if not present and resolution is a version', function (next) { + var resolver = create('foo'); + + resolver._resolution = { type: 'version', tag: 'v0.0.1' }; + resolver._tempDir = tempDir; + + resolver._savePkgMeta({ name: 'foo' }) + .then(function () { + return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); + }) + .then(function (contents) { + var json = JSON.parse(contents.toString()); + expect(json.version).to.equal('0.0.1'); + + next(); + }) + .done(); + }); + + it('should remove the version from the package meta if resolution is not a version', function (next) { + var resolver = create('foo'); + + resolver._resolution = { type: 'commit', commit: '1' }; + resolver._tempDir = tempDir; + + resolver._savePkgMeta({ name: 'foo', version: '0.0.1' }) + .then(function () { + return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); + }) + .then(function (contents) { + var json = JSON.parse(contents.toString()); + expect(json).to.not.have.property('version'); + + next(); + }) + .done(); + }); + + it('should warn if the resolution version is different than the package meta version', function (next) { + var resolver = create('foo'); + var notified = false; + + resolver._resolution = { type: 'version', tag: '0.0.1' }; + resolver._tempDir = tempDir; + + logger.on('log', function (log) { + expect(log).to.be.an('object'); + + if (log.level === 'warn' && log.id === 'mismatch') { + expect(log.message).to.match(/\(0\.0\.0\).*different.*\(0\.0\.1\)/); + notified = true; + } + }); + + resolver._savePkgMeta({ name: 'foo', version: '0.0.0' }) + .then(function () { + return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); + }) + .then(function (contents) { + var json = JSON.parse(contents.toString()); + expect(json.version).to.equal('0.0.1'); + expect(notified).to.be(true); + + next(); + }) + .done(); + }); + + it('should not warn if the resolution version and the package meta version are the same', function (next) { + var resolver = create('foo'); + var notified = false; + + resolver._resolution = { type: 'version', tag: 'v0.0.1' }; + resolver._tempDir = tempDir; + + resolver._savePkgMeta({ name: 'foo', version: '0.0.1' }) + .then(function () { + return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); + }, null) + .then(function (contents) { + var json = JSON.parse(contents.toString()); + expect(json.version).to.equal('0.0.1'); + expect(notified).to.be(false); + + next(); + }) + .done(); + }); + }); + + describe('#clearRuntimeCache', function () { + // Use a class that inherit the SvnResolver to see if it uses + // late binding when clearing the cache + function CustomSvnResolver() {} + util.inherits(CustomSvnResolver, SvnResolver); + mout.object.mixIn(CustomSvnResolver, SvnResolver); + + + it('should clear tags cache', function () { + CustomSvnResolver._cache.tags.set('foo', {}); + CustomSvnResolver.clearRuntimeCache(); + expect(CustomSvnResolver._cache.tags.has('foo')).to.be(false); + }); + + it('should clear versions cache', function () { + CustomSvnResolver._cache.versions.set('foo', {}); + CustomSvnResolver.clearRuntimeCache(); + expect(CustomSvnResolver._cache.versions.has('foo')).to.be(false); + }); + }); + + describe('#versions', function () { + afterEach(clearResolverRuntimeCache); + + it('should resolve to an empty array if no tags are found', function (next) { + SvnResolver.tags = function () { + return Q.resolve({}); + }; + + SvnResolver.versions('foo') + .then(function (versions) { + expect(versions).to.be.an('array'); + expect(versions).to.eql([]); + next(); + }) + .done(); + }); + + it('should resolve to an empty array if no valid semver tags', function (next) { + SvnResolver.tags = function () { + return Q.resolve({ + 'foo': 1, + 'bar': 2, + 'baz': 3 + }); + }; + + SvnResolver.versions('foo') + .then(function (versions) { + expect(versions).to.be.an('array'); + expect(versions).to.eql([]); + next(); + }) + .done(); + }); + + it('should resolve to an array of versions, ignoring invalid semver tags', function (next) { + SvnResolver.tags = function () { + return Q.resolve({ + '0.2.1': 1, + 'v0.1.1': 2, + '0.1.0': 3, + 'invalid': 4, // invalid + '/': 5, // invalid + '': 6 // invalid + }); + }; + + SvnResolver.versions('foo', true) + .then(function (versions) { + expect(versions).to.eql([ + { version: '0.2.1', tag: '0.2.1', commit: 1 }, + { version: '0.1.1', tag: 'v0.1.1', commit: 2 }, + { version: '0.1.0', tag: '0.1.0', commit: 3 } + ]); + }) + .then(function () { + return SvnResolver.versions('foo'); + }) + .then(function (versions) { + expect(versions).to.eql(['0.2.1', '0.1.1', '0.1.0']); + next(); + }) + .done(); + }); + + it('should order the versions according to the semver spec', function (next) { + SvnResolver.tags = function () { + return Q.resolve({ + '0.1.0': 1, + '0.1.1+build.11': 2, + '0.1.1+build.100': 3, + '0.1.1-rc.22': 4, + '0.1.1-rc.200': 5, + '0.1.1': 6, + 'v0.2.1': 7 + }); + }; + + SvnResolver.versions('foo', true) + .then(function (versions) { + expect(versions).to.eql([ + { version: '0.2.1', tag: 'v0.2.1', commit: '7' }, + { version: '0.1.1+build.11', tag: '0.1.1+build.11', commit: '2' }, + { version: '0.1.1+build.100', tag: '0.1.1+build.100', commit: '3' }, + { version: '0.1.1', tag: '0.1.1', commit: '6' }, + { version: '0.1.1-rc.200', tag: '0.1.1-rc.200', commit: '5' }, + { version: '0.1.1-rc.22', tag: '0.1.1-rc.22', commit: '4' }, + { version: '0.1.0', tag: '0.1.0', commit: '1' } + ]); + next(); + }) + .done(); + }); + + it('should cache the result for each source', function (next) { + SvnResolver.tags = function (source) { + if (source === 'foo') { + return Q.resolve({ + '0.2.1': 123, + '0.1.0': 456 + }); + } + + return Q.resolve({ + '0.3.1': 7, + '0.3.0': 8 + }); + + }; + + SvnResolver.versions('foo') + .then(function (versions) { + expect(versions).to.eql(['0.2.1', '0.1.0']); + + return SvnResolver.versions('bar'); + }) + .then(function (versions) { + expect(versions).to.eql(['0.3.1', '0.3.0']); + + + // Manipulate the cache and check if it resolves for the cached ones + SvnResolver._cache.versions.get('foo').splice(1, 1); + SvnResolver._cache.versions.get('bar').splice(1, 1); + + return SvnResolver.versions('foo'); + }) + .then(function (versions) { + expect(versions).to.eql(['0.2.1']); + + return SvnResolver.versions('bar'); + }) + .then(function (versions) { + expect(versions).to.eql(['0.3.1']); + next(); + }) + .done(); + }); + + it('should work if requested in parallel for the same source', function (next) { + SvnResolver.tags = function () { + return Q.resolve({ + '0.2.1': 123, + '0.1.0': 456 + }); + }; + + Q.all([ + SvnResolver.versions('foo'), + SvnResolver.versions('foo') + ]) + .spread(function (versions1, versions2) { + expect(versions1).to.eql(['0.2.1', '0.1.0']); + expect(versions2).to.eql(versions1); + + next(); + }) + .done(); + }); + }); + + // remote resolver tests + describe('.constructor', function () { + it('should guess the name from the path', function () { + var resolver; + + resolver = create('file://' + testPackage); + expect(resolver.getName()).to.equal('package-svn'); + + resolver = create('lp:~stephen-stewart/+junk/bower-test-package'); + expect(resolver.getName()).to.equal('bower-test-package'); + + }); + }); + describe('.resolve', function () { + + it('should checkout correctly if resolution is a tag', function (next) { + var resolver = create({ source: 'file://' + testPackage, target: '~0.0.1' }); + + resolver.resolve() + .then(function (dir) { + expect(dir).to.be.a('string'); + + var files = fs.readdirSync(dir); + + expect(files).to.contain('foo'); + expect(files).to.contain('bar'); + expect(files).to.not.contain('baz'); + + next(); + }) + .done(); + }); + + it('should checkout correctly if resolution is a commit', function (next) { + var resolver = create({ source: 'file://' + testPackage, target: 'revno:1' }); + + resolver.resolve() + .then(function (dir) { + expect(dir).to.be.a('string'); + + var files = fs.readdirSync(dir); + + expect(files).to.not.contain('foo'); + expect(files).to.not.contain('bar'); + expect(files).to.not.contain('baz'); + expect(files).to.contain('.master'); + next(); + }) + .done(); + }); + + }); +}); diff --git a/test/packages-svn.js b/test/packages-svn.js new file mode 100644 index 000000000..47567d999 --- /dev/null +++ b/test/packages-svn.js @@ -0,0 +1,195 @@ +var fs = require('graceful-fs'); +var path = require('path'); +var Q = require('q'); +var semver = require('semver'); +var mout = require('mout'); +var rimraf = require('rimraf'); +var mkdirp = require('mkdirp'); +var chalk = require('chalk'); +var cmd = require('../lib/util/cmd'); +var packages = require('./packages-svn.json'); +var nopt = require('nopt'); + +var options = nopt({ + 'force': Boolean +}, { + 'f': '--force' +}); + +var env = {}; + +// Preserve the original environment +mout.object.mixIn(env, process.env); + +function ensurePackage(admin, dir) { + var promise; + + // If force is specified, delete folder + if (options.force) { + promise = Q.nfcall(rimraf, dir) + .then(function () { + throw new Error(); + }); + // Otherwise check if .svn is already created + } else { + promise = Q.nfcall(fs.stat, path.join(dir, '.svn')); + } + + // Only create if stat failed + return promise.fail(function () { + // Create dir + return Q.nfcall(mkdirp, dir) + // Init svn repo + .then(cmd.bind(null, 'svnadmin', ['create', admin])) + // checkout the repo + .then(cmd.bind(null, 'svn', ['checkout', 'file://' + admin, dir])) + // create directory structure + .then(cmd.bind(null, 'svn', ['mkdir', 'trunk'], { cwd: dir })) + .then(cmd.bind(null, 'svn', ['mkdir', 'tags'], { cwd: dir })) + .then(cmd.bind(null, 'svn', ['mkdir', 'branches'], { cwd: dir })) + // Commit + .then(function () { + return cmd('svn', ['commit', '-m"Initial commit."'], { + cwd: dir, + env: env + }); + }) + .then(function () { + return dir; + }); + }); +} + +function checkRelease(dir, release) { + if (semver.valid(release)) { + return cmd('svn', ['list', 'tags'], { cwd: dir }) + .spread(function (stdout) { + return stdout.split(/\s*\r*\n\s*/).some(function (tag) { + return semver.clean(tag) === release; + }); + }); + } + + return cmd('svn', ['list', 'branches'], { cwd: dir }) + .spread(function (stdout) { + return stdout.split(/\s*\r*\n\s*/).some(function (branch) { + branch = branch.trim().replace(/^\*?\s*/, ''); + return branch === release; + }); + }); +} + +function createRelease(admin, dir, release, files) { + // checkout the repo + return cmd('svn', ['checkout', 'file://' + admin, dir]) + // Attempt to delete branch, ignoring the error + .then(function () { + return cmd('svn', ['delete', dir + '/branches/' + release], { cwd: dir }) + .fail(function () {}); + }) + // Attempt to delete tag, ignoring the error + .then(function () { + cmd('svn', ['delete', dir + '/tags/' + release], { cwd: dir }) + .fail(function (err) {}); + }) + // Create files + .then(function () { + var promise; + var promises = []; + + mout.object.forOwn(files, function (contents, name) { + name = path.join(dir + '/trunk', name); + + // Convert contents to JSON if they are not a string + if (typeof contents !== 'string') { + contents = JSON.stringify(contents, null, ' '); + } + + promise = Q.nfcall(mkdirp, path.dirname(name)) + .then(function () { + return Q.nfcall(fs.writeFile, name, contents); + }); + + promises.push(promise); + }); + + return Q.all(promises); + }) + // Stage files + .then(cmd.bind(null, 'svn', ['add', '--force', '.'], { cwd: dir })) + // create tag + .then(function () { + if (!semver.valid(release)) { + return; + } + + return cmd('svn', ['copy', dir + '/trunk', dir + '/tags/' + release], { cwd: dir }); + }) + // create branch + .then(function () { + if (!semver.valid(release)) { + return; + } + + return cmd('svn', ['copy', dir + '/trunk', dir + '/branches/' + release], { cwd: dir }); + }) + // commit all + .then(function () { + return cmd('svn', ['commit', '-m"SVN Setup'], { + cwd: dir, + env: env + }); + }); +} + +var promises = []; + +// Process packages.json +mout.object.forOwn(packages, function (pkg, name) { + var promise; + var admin = path.join(__dirname, 'assets', name, 'admin'); + var dir = path.join(__dirname, 'assets', name, 'repo'); + + // Ensure package is created + promise = ensurePackage(admin, dir); + + promise = promise.fail(function (err) { + console.log('Failed to create ' + name); + console.log(err.message); + }); + + mout.object.forOwn(pkg, function (files, release) { + // Check if the release already exists + promise = promise.then(checkRelease.bind(null, dir, release)) + .then(function (exists) { + // Skip it if already created + if (exists) { + return console.log(chalk.cyan('> ') + 'Package ' + name + '#' + release + ' already created'); + } + + // Create it based on the metadata + return createRelease(admin, dir, release, files) + .then(function () { + console.log(chalk.green('> ') + 'Package ' + name + '#' + release + ' successfully created'); + }); + }) + .fail(function (err) { + console.log(chalk.red('> ') + 'Failed to create ' + name + '#' + release); + console.log(err.message.trim()); + if (err.details) { + console.log(err.details.trim()); + } + console.log(err.stack); + }); + }); + + promises.push(promise); +}); + +Q.allSettled(promises, function (results) { + results.forEach(function (result) { + if (result.state !== 'fulfilled') { + process.exit(1); + } + }); +}); diff --git a/test/packages-svn.json b/test/packages-svn.json new file mode 100644 index 000000000..1738cbeb0 --- /dev/null +++ b/test/packages-svn.json @@ -0,0 +1,79 @@ +{ + "package-svn": { + "0.0.1": { + "README.md": "", + "foo": "foo" + }, + "0.0.1": { + "README.md": "", + "foo": "foo" + }, + "0.0.2": { + "README.md": "", + "foo": "foo", + "bar": "bar" + }, + "0.1.0": { + "README.md": "", + "foo": "foo", + "bar": "bar", + "baz": "baz" + }, + "0.1.1": { + "README.md": "", + "foo": "foo", + "bar": "bar", + "baz": "baz", + "more/more-foo": "more-foo" + }, + "0.2.0": { + "README.md": "", + "foo": "foo", + "bar": "bar", + "baz": "baz", + "more/more-foo": "more-foo", + "test/test.js": "some tests", + "component.json": { + "name": "a", + "version": "0.2.0", + "ignore": [ + "test/" + ] + } + }, + "0.2.1": { + "README.md": "", + "foo": "foo", + "bar": "bar", + "baz": "baz", + "more/more-foo": "more-foo", + "test/test.js": "some tests", + "bower.json": { + "name": "a", + "version": "0.2.0", + "ignore": [ + "test/" + ] + } + }, + "0.2.2": { + "README.md": "", + "foo": "foo", + "bar": "bar", + "baz": "baz", + "more/more-foo": "more-foo", + "more/docs/doc.html": "doc", + "more/assets/styles.css": "css", + "bower.json": { + "name": "a", + "version": "0.2.2", + "ignore": [ + "test/", + "more/docs", + "more/assets/", + "baz/" + ] + } + } + } +} diff --git a/test/test.js b/test/test.js index f020f6435..3a6f8cf45 100644 --- a/test/test.js +++ b/test/test.js @@ -12,6 +12,7 @@ require('./core/resolvers/gitResolver'); require('./core/resolvers/gitFsResolver'); require('./core/resolvers/gitRemoteResolver'); require('./core/resolvers/gitHubResolver'); +require('./core/resolvers/svnResolver'); require('./core/resolverFactory'); require('./core/resolveCache'); require('./core/packageRepository'); From ce0b18045bf5903dc5d2a4a2514e4951fea51af8 Mon Sep 17 00:00:00 2001 From: Ahmad Nassri Date: Wed, 15 Jan 2014 20:15:27 -0500 Subject: [PATCH 0273/1021] jshint fixes --- lib/core/resolvers/SvnRemoteResolver.js | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/lib/core/resolvers/SvnRemoteResolver.js b/lib/core/resolvers/SvnRemoteResolver.js index e41a9f42b..86caa71c7 100644 --- a/lib/core/resolvers/SvnRemoteResolver.js +++ b/lib/core/resolvers/SvnRemoteResolver.js @@ -1,5 +1,4 @@ var util = require('util'); -var url = require('url'); var mout = require('mout'); var SvnResolver = require('./SvnResolver'); var cmd = require('../../util/cmd'); @@ -28,7 +27,7 @@ SvnRemoteResolver.prototype._checkout = function () { var info = resolution.type; if (resolution.type !== 'trunk') { - info += ' ' + resolution.tag || resolution.branch || resolution.commit + info += ' ' + resolution.tag || resolution.branch || resolution.commit; } this._logger.action('checkout', info, { @@ -36,17 +35,12 @@ SvnRemoteResolver.prototype._checkout = function () { to: this._tempDir }); - switch (resolution.type) { - case 'revision': - promise = cmd('svn', ['checkout', '-r ' + resolution.commit, this._source, this._tempDir]); - break; - - case 'trunk': - promise = cmd('svn', ['checkout', this._source + '/trunk', this._tempDir]); - break - - default: - promise = cmd('svn', ['checkout', this._source + '/' + resolution.type + 's', this._tempDir]); + if (resolution.type === 'revision') { + promise = cmd('svn', ['checkout', '-r ' + resolution.commit, this._source, this._tempDir]); + } else if (resolution.type === 'trunk') { + promise = cmd('svn', ['checkout', this._source + '/trunk', this._tempDir]); + } else { + promise = cmd('svn', ['checkout', this._source + '/' + resolution.type + 's/' + (resolution.tag || resolution.branch), this._tempDir]); } // Throttle the progress reporter to 1 time each sec From 6eb8bb62416acf1506fb29152bb2787df6ec69d7 Mon Sep 17 00:00:00 2001 From: Ahmad Nassri Date: Wed, 15 Jan 2014 22:37:47 -0500 Subject: [PATCH 0274/1021] fully functional now to prove it with some proper tests --- lib/core/resolverFactory.js | 4 +- lib/core/resolvers/GitResolver.js | 4 +- lib/core/resolvers/SvnRemoteResolver.js | 25 +++------ lib/core/resolvers/SvnResolver.js | 72 +++++++++++++++++-------- 4 files changed, 59 insertions(+), 46 deletions(-) diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index 0743bb219..a605eec78 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -45,7 +45,7 @@ function getConstructor(source, config, registryClient) { }); } - // Bzr case: svn, svn+ssh + // SVN case: svn, svn+ssh if (/^svn(\+ssh)?:\/\//i.test(source)) { return Q.fcall(function () { return [resolvers.Svn, source]; @@ -78,7 +78,6 @@ function getConstructor(source, config, registryClient) { throw new Error('Not a Git repository'); }) - // If not, check if source is a valid Subversion repository .fail(function () { return Q.nfcall(fs.stat, path.join(absolutePath, '.svn')) @@ -92,7 +91,6 @@ function getConstructor(source, config, registryClient) { throw new Error('Not a Subversion repository'); }); }) - // If not, check if source is a valid file/folder .fail(function () { return Q.nfcall(fs.stat, absolutePath) diff --git a/lib/core/resolvers/GitResolver.js b/lib/core/resolvers/GitResolver.js index 0cc456a38..d6fdb4380 100644 --- a/lib/core/resolvers/GitResolver.js +++ b/lib/core/resolvers/GitResolver.js @@ -302,15 +302,13 @@ GitResolver.tags = function (source) { value = this.refs(source) .then(function (refs) { - var tags = []; + var tags = {}; // For each line in the refs, match only the tags refs.forEach(function (line) { var match = line.match(/^([a-f0-9]{40})\s+refs\/tags\/(\S+)/); - var tag; if (match && !mout.string.endsWith(match[2], '^{}')) { - tag = match[2]; tags[match[2]] = match[1]; } }); diff --git a/lib/core/resolvers/SvnRemoteResolver.js b/lib/core/resolvers/SvnRemoteResolver.js index 86caa71c7..204538291 100644 --- a/lib/core/resolvers/SvnRemoteResolver.js +++ b/lib/core/resolvers/SvnRemoteResolver.js @@ -6,41 +6,32 @@ var cmd = require('../../util/cmd'); function SvnRemoteResolver(decEndpoint, config, logger) { SvnResolver.call(this, decEndpoint, config, logger); - if (!mout.string.startsWith(this._source, 'http://')) { - // force use http urls - this._source = this._source.replace('svn://', 'http://'); - - // Trim trailing slashes - this._source = this._source.replace(/\/+$/, ''); - } + this._source = SvnResolver.sourceUrl(this._source); } util.inherits(SvnRemoteResolver, SvnResolver); mout.object.mixIn(SvnRemoteResolver, SvnResolver); +// ----------------- + SvnRemoteResolver.prototype._checkout = function () { var promise; var timer; var reporter; var that = this; var resolution = this._resolution; - var info = resolution.type; - - if (resolution.type !== 'trunk') { - info += ' ' + resolution.tag || resolution.branch || resolution.commit; - } - this._logger.action('checkout', info, { + this._logger.action('checkout', resolution.tag || resolution.branch || resolution.commit, { resolution: resolution, to: this._tempDir }); - if (resolution.type === 'revision') { - promise = cmd('svn', ['checkout', '-r ' + resolution.commit, this._source, this._tempDir]); - } else if (resolution.type === 'trunk') { + if (resolution.type === 'version') { + promise = cmd('svn', ['checkout', this._source + '/trunk', '-r' + resolution.commit, this._tempDir]); + } else if (resolution.type === 'branch' && resolution.branch === 'trunk') { promise = cmd('svn', ['checkout', this._source + '/trunk', this._tempDir]); } else { - promise = cmd('svn', ['checkout', this._source + '/' + resolution.type + 's/' + (resolution.tag || resolution.branch), this._tempDir]); + promise = cmd('svn', ['checkout', this._source + '/' + resolution.type + (resolution.type === 'branch' ? 'es/' : 's/') + (resolution.tag || resolution.branch), this._tempDir]); } // Throttle the progress reporter to 1 time each sec diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js index 9661e222b..137d97a61 100644 --- a/lib/core/resolvers/SvnResolver.js +++ b/lib/core/resolvers/SvnResolver.js @@ -84,18 +84,15 @@ SvnResolver.prototype._findResolution = function (target) { target = target || this._target || '*'; + // clean the source variable + this._source = SvnResolver.sourceUrl(this._source); + // Target is a revision, so it's a stale target (not a moving target) // There's nothing to do in this case if ((/^r\d+/).test(target)) { target = target.split('r'); - this._resolution = { type: 'revision', commit: target[1] }; - return Q.resolve(this._resolution); - } - - // Target trunk - if (target === 'trunk') { - this._resolution = { type: 'trunk' }; + this._resolution = { type: 'commit', commit: target[1] }; return Q.resolve(this._resolution); } @@ -110,7 +107,7 @@ SvnResolver.prototype._findResolution = function (target) { versionsArr = versions.map(function (obj) { return obj.version; }); // If there are no tags and target is *, - // fallback to the latest revision + // fallback to the latest commit on trunk if (!versions.length && target === '*') { return that._findResolution('trunk'); } @@ -119,10 +116,9 @@ SvnResolver.prototype._findResolution = function (target) { // Find a satisfying version, enabling strict match so that pre-releases // have lower priority over normal ones when target is * index = semver.maxSatisfyingIndex(versionsArr, target, true); - if (index !== -1) { version = versions[index]; - return that._resolution = { type: 'tag', tag: version.tag, commit: version.commit }; + return that._resolution = { type: 'version', tag: version.tag, commit: version.commit }; } // Check if there's an exact branch/tag with this name as last resort @@ -187,7 +183,7 @@ SvnResolver.prototype._cleanup = function () { SvnResolver.prototype._savePkgMeta = function (meta) { var version; - if (this._resolution.type === 'revision') { + if (this._resolution.type === 'version') { version = semver.clean(this._resolution.tag); // Warn if the package meta version is different than the resolved one @@ -211,7 +207,6 @@ SvnResolver.prototype._savePkgMeta = function (meta) { // an unique id of this ref. meta._release = version || this._resolution.tag || - this._resolution.branch || this._resolution.commit; // Save resolution to be used in hasNew later @@ -223,6 +218,9 @@ SvnResolver.prototype._savePkgMeta = function (meta) { // ------------------------------ SvnResolver.versions = function (source, extra) { + // clean the source variable + source = SvnResolver.sourceUrl(source); + var value = this._cache.versions.get(source); if (value) { @@ -275,24 +273,31 @@ SvnResolver.versions = function (source, extra) { }; SvnResolver.tags = function (source) { + // clean the source variable + source = SvnResolver.sourceUrl(source); + var value = this._cache.tags.get(source); if (value) { return Q.resolve(value); } - value = cmd('svn', ['list', source + '/tags']) + value = cmd('svn', ['list', source + '/tags', '--verbose']) .spread(function (stout) { - var tags = []; + var tags = {}; var lines = stout.toString() .trim() - .replace(/\/+/g, '') .split(/[\r\n]+/); // For each line in the refs, match only the tags - lines.forEach(function (tag) { - tags[tag] = tag; + lines.forEach(function (line) { + + var match = line.match(/\s+([0-9]+)\s.+\s([a-z0-9.]+)\//i); + + if (match && match[2] !== '.') { + tags[match[2]] = match[1]; + } }); this._cache.tags.set(source, tags); @@ -308,24 +313,34 @@ SvnResolver.tags = function (source) { }; SvnResolver.branches = function (source) { + // clean the source variable + source = SvnResolver.sourceUrl(source); + var value = this._cache.branches.get(source); if (value) { return Q.resolve(value); } - value = cmd('svn', ['list', source + '/branches']) + value = cmd('svn', ['list', source + '/branches', '--verbose']) .spread(function (stout) { - var branches = []; + // trunk is a branch! + var branches = { + 'trunk': '*' + }; var lines = stout.toString() .trim() - .replace(/\/+/g, '') .split(/[\r\n]+/); - // For each line in the refs, match only the tags - lines.forEach(function (branch) { - branches[branch] = branch; + // For each line in the refs, match only the banches + lines.forEach(function (line) { + + var match = line.match(/\s+([0-9]+)\s.+\s([a-z0-9.]+)\//i); + + if (match && match[2] !== '.') { + branches[match[2]] = match[1]; + } }); this._cache.branches.set(source, branches); @@ -347,6 +362,17 @@ SvnResolver.clearRuntimeCache = function () { }); }; +// source url cleaning utility function +// reason: the constructor is not called when using commands such as "list" +SvnResolver.sourceUrl = function (source) { + if (!mout.string.startsWith(source, 'http://')) { + // force use http urls + return source.replace('svn://', 'http://').replace(/\/+$/, ''); + } + + return source; +}; + SvnResolver._cache = { branches: new LRU({ max: 50, maxAge: 5 * 60 * 1000 }), tags: new LRU({ max: 50, maxAge: 5 * 60 * 1000 }), From 0c7b09c2379922d2619c1f948b95a1e7adba976d Mon Sep 17 00:00:00 2001 From: Kenneth Lee Date: Thu, 16 Jan 2014 19:18:27 +0000 Subject: [PATCH 0275/1021] created svn tests in resolver factory --- test/core/resolverFactory.js | 73 ++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 0f953fc33..ef59c5d3c 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -339,6 +339,79 @@ describe('resolverFactory', function () { .done(); }); + it('should recognize svn remote endpoints correctly', function (next) { + var promise = Q.resolve(); + var endpoints; + + endpoints = { + // svn: + 'svn://hostname.com/user/project': 'http://hostname.com/user/project', + 'svn://hostname.com/user/project/': 'http://hostname.com/user/project', + + // svn@: + 'svn://svn@hostname.com:user/project': 'http://svn@hostname.com:user/project', + 'svn://svn@hostname.com:user/project/': 'http://svn@hostname.com:user/project', + + // svn+http + 'svn+http://hostname.com/project/blah': 'http://hostname.com/project/blah', + 'svn+http://hostname.com/project/blah/': 'http://hostname.com/project/blah', + 'svn+http://user@hostname.com/project/blah': 'http://user@hostname.com/project/blah', + 'svn+http://user@hostname.com/project/blah/': 'http://user@hostname.com/project/blah', + + // svn+https + 'svn+https://hostname.com/project/blah': 'https://hostname.com/project/blah', + 'svn+https://hostname.com/project/blah/': 'https://hostname.com/project/blah', + 'svn+https://user@hostname.com/project/blah': 'https://user@hostname.com/project/blah', + 'svn+https://user@hostname.com/project/blah/': 'https://user@hostname.com/project/blah', + + // svn+ssh + 'svn+ssh://hostname.com/project/blah': 'svn+ssh://hostname.com/project/blah', + 'svn+ssh://hostname.com/project/blah/': 'svn+ssh://hostname.com/project/blah', + 'svn+ssh://user@hostname.com/project/blah': 'svn+ssh://user@hostname.com/project/blah', + 'svn+ssh://user@hostname.com/project/blah/': 'svn+ssh://user@hostname.com/project/blah' + }; + + mout.object.forOwn(endpoints, function (value, key) { + // Test without name and target + promise = promise.then(function () { + return callFactory({ source: key }); + }) + .then(function (resolver) { + expect(resolver).to.be.a(resolvers.Svn); + expect(resolver).to.not.be(resolvers.GitHub); + expect(resolver.getSource()).to.equal(value); + expect(resolver.getTarget()).to.equal('*'); + }); + + // Test with target + promise = promise.then(function () { + return callFactory({ source: key, target: 'commit-ish' }); + }) + .then(function (resolver) { + expect(resolver).to.be.a(resolvers.Svn); + expect(resolver).to.not.be(resolvers.GitHub); + expect(resolver.getSource()).to.equal(value); + expect(resolver.getTarget()).to.equal('commit-ish'); + }); + + // Test with name + promise = promise.then(function () { + return callFactory({ name: 'foo', source: key }); + }) + .then(function (resolver) { + expect(resolver).to.be.a(resolvers.Svn); + expect(resolver).to.not.be(resolvers.GitHub); + expect(resolver.getSource()).to.equal(value); + expect(resolver.getName()).to.equal('foo'); + expect(resolver.getTarget()).to.equal('*'); + }); + }); + + promise + .then(next.bind(next, null)) + .done(); + }); + it('should recognize local fs files/folder endpoints correctly', function (next) { var promise = Q.resolve(); var endpoints; From 820834111b22e587a861296c9a44ef6371866a6c Mon Sep 17 00:00:00 2001 From: Kenneth Lee Date: Thu, 16 Jan 2014 19:35:52 +0000 Subject: [PATCH 0276/1021] fixed svn+xxxxx protocol --- lib/core/resolverFactory.js | 4 ++-- lib/core/resolvers/SvnResolver.js | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index a605eec78..6cdf7535a 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -45,8 +45,8 @@ function getConstructor(source, config, registryClient) { }); } - // SVN case: svn, svn+ssh - if (/^svn(\+ssh)?:\/\//i.test(source)) { + // SVN case: svn, svn+ssh, svn+http, svn+https + if (/^svn(\+(ssh|https?))?:\/\//i.test(source)) { return Q.fcall(function () { return [resolvers.Svn, source]; }); diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js index 137d97a61..20e8f353d 100644 --- a/lib/core/resolvers/SvnResolver.js +++ b/lib/core/resolvers/SvnResolver.js @@ -365,12 +365,10 @@ SvnResolver.clearRuntimeCache = function () { // source url cleaning utility function // reason: the constructor is not called when using commands such as "list" SvnResolver.sourceUrl = function (source) { - if (!mout.string.startsWith(source, 'http://')) { - // force use http urls - return source.replace('svn://', 'http://').replace(/\/+$/, ''); - } - - return source; + return source + .replace(/^svn\+(https?):\/\//i, '$1://') // Change svn+http or svn+https to http(s) + .replace('svn://', 'http://') // Change svn to http + .replace(/\/+$/, ''); // Remove trailing slashes }; SvnResolver._cache = { From d27c36c70c2edd41d5105e6cff89270d5b86ed26 Mon Sep 17 00:00:00 2001 From: Kenneth Lee Date: Thu, 16 Jan 2014 19:52:02 +0000 Subject: [PATCH 0277/1021] fixed the gitResolver tags and associated test --- test/core/resolvers/gitResolver.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index b2ddcc32e..92e477a38 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -1167,21 +1167,21 @@ describe('GitResolver', function () { describe('#tags', function () { afterEach(clearResolverRuntimeCache); - it('should resolve to an empty array if no tags are found', function (next) { + it('should resolve to an empty hash if no tags are found', function (next) { GitResolver.refs = function () { return Q.resolve([]); }; GitResolver.tags('foo') .then(function (tags) { - expect(tags).to.be.an('array'); - expect(tags).to.eql([]); + expect(tags).to.be.an('object'); + expect(tags).to.eql({}); next(); }) .done(); }); - it('should resolve to an array of tags', function (next) { + it('should resolve to an hash of tags', function (next) { GitResolver.refs = function () { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', From 53f563ec085e790c86529327030cfa1d9ac80294 Mon Sep 17 00:00:00 2001 From: Kenneth Lee Date: Thu, 16 Jan 2014 20:07:04 +0000 Subject: [PATCH 0278/1021] added svn+file for local file system checkouts --- lib/core/resolverFactory.js | 4 ++-- lib/core/resolvers/SvnResolver.js | 2 +- test/core/resolverFactory.js | 6 +++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index 6cdf7535a..2e01b017e 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -45,8 +45,8 @@ function getConstructor(source, config, registryClient) { }); } - // SVN case: svn, svn+ssh, svn+http, svn+https - if (/^svn(\+(ssh|https?))?:\/\//i.test(source)) { + // SVN case: svn, svn+ssh, svn+http, svn+https, svn+file + if (/^svn(\+(ssh|https?|file))?:\/\//i.test(source)) { return Q.fcall(function () { return [resolvers.Svn, source]; }); diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js index 20e8f353d..bc484e10a 100644 --- a/lib/core/resolvers/SvnResolver.js +++ b/lib/core/resolvers/SvnResolver.js @@ -366,7 +366,7 @@ SvnResolver.clearRuntimeCache = function () { // reason: the constructor is not called when using commands such as "list" SvnResolver.sourceUrl = function (source) { return source - .replace(/^svn\+(https?):\/\//i, '$1://') // Change svn+http or svn+https to http(s) + .replace(/^svn\+(https?|file):\/\//i, '$1://') // Change svn+http or svn+https or svn+file to http(s), file respectively .replace('svn://', 'http://') // Change svn to http .replace(/\/+$/, ''); // Remove trailing slashes }; diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index ef59c5d3c..ee733ae35 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -368,7 +368,11 @@ describe('resolverFactory', function () { 'svn+ssh://hostname.com/project/blah': 'svn+ssh://hostname.com/project/blah', 'svn+ssh://hostname.com/project/blah/': 'svn+ssh://hostname.com/project/blah', 'svn+ssh://user@hostname.com/project/blah': 'svn+ssh://user@hostname.com/project/blah', - 'svn+ssh://user@hostname.com/project/blah/': 'svn+ssh://user@hostname.com/project/blah' + 'svn+ssh://user@hostname.com/project/blah/': 'svn+ssh://user@hostname.com/project/blah', + + // svn+file + 'svn+file:///project/blah': 'file:///project/blah', + 'svn+file:///project/blah/': 'file:///project/blah' }; mout.object.forOwn(endpoints, function (value, key) { From 9f9a7c6b389427beb1e6c0b10b80f8ce992575d5 Mon Sep 17 00:00:00 2001 From: Ahmad Nassri Date: Thu, 16 Jan 2014 23:57:54 -0500 Subject: [PATCH 0279/1021] updating README with Subversion info --- README.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index da85acf21..d001a5415 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,9 @@ Where `` can be any one of the following: * A public remote Git endpoint, e.g., ```git://github.com/someone/some-package.git```. ‡ * A private Git repository, e.g., ```https://github.com/someone/some-package.git```. If the protocol is https, a prompt will ask for the credentials. ssh can also be used, e.g., ```git@github.com:someone/some-package.git``` and can authenticate with the user's ssh public/private keys. ‡ * A local endpoint, i.e., a folder that's a Git repository. ‡ +* A public remote Subversion endpoint, e.g., ```svn+http://package.googlecode.com/svn/```. ‡ +* A private Subversion repository, e.g., ```svn+ssh://package.googlecode.com/svn/```. ‡ +* A local endpoint, i.e., a folder that's an Subversion repository, e.g., ```svn+file:///path/to/svn/```. ‡ * A shorthand endpoint, e.g., `someone/some-package` (defaults to GitHub). ‡ * A URL to a file, including `zip` and `tar` files. Its contents will be extracted. @@ -69,10 +72,14 @@ Where `` can be any one of the following: ‡ These types of `` might have versions available. You can specify a [semver](http://semver.org/) compatible version to fetch a specific release, and lock the package to that version. You can also use ranges to specify a range of versions. + If you are using a package that is a git endpoint, you may use any tag, commit SHA, or branch name as a version. For example: `#`. Using branches is not recommended because the HEAD does not reference a fixed commit SHA. +If you are using a package that is a subversion endpoint, you may use any tag, revision number, +or branch name as a version. For example: `#`. + All package contents are installed in the `bower_components` directory by default. You should **never** directly modify the contents of this directory. @@ -85,7 +92,7 @@ packages into source control](http://addyosmani.com/blog/checking-in-front-end-d ### Custom install directory -A custom install location can be set in a .bowerrc file using the `directory` property. The .bowerrc file should be a sibling of your project's bower.json. +A custom install location can be set in a `.bowerrc` file using the `directory` property. The .bowerrc file should be a sibling of your project's bower.json. ```json { @@ -200,7 +207,7 @@ The `bower.json` defines several options: Bower to ignore when installing your package. * `dependencies` [hash]: Packages your package depends upon in production. * `devDependencies` [hash]: Development dependencies. -* `private` [boolean]: Set to true if you want to keep the package private and +* `private` [boolean]: Set to true if you want to keep the package private and do not want to register the package in future. ```json @@ -386,8 +393,9 @@ Thanks for assistance and contributions: [@visionmedia](https://github.com/visionmedia), [@wagenet](https://github.com/wagenet), [@wibblymat](https://github.com/wibblymat), -[@wycats](https://github.com/wycats) - +[@wycats](https://github.com/wycats), +[@ahmadnassri](https://github.com/ahmadnassri) +[@ahmadnassri](https://github.com/kennethklee) ## License From c498e9437e2bfb78ee1f2342b6632dcd05201858 Mon Sep 17 00:00:00 2001 From: Ahmad Nassri Date: Fri, 17 Jan 2014 13:59:10 -0500 Subject: [PATCH 0280/1021] merging SvnResolver with SvnRemoteResolver --- lib/core/resolvers/SvnRemoteResolver.js | 77 ------------------------- lib/core/resolvers/SvnResolver.js | 52 ++++++++++++++++- lib/core/resolvers/index.js | 2 +- 3 files changed, 51 insertions(+), 80 deletions(-) delete mode 100644 lib/core/resolvers/SvnRemoteResolver.js diff --git a/lib/core/resolvers/SvnRemoteResolver.js b/lib/core/resolvers/SvnRemoteResolver.js deleted file mode 100644 index 204538291..000000000 --- a/lib/core/resolvers/SvnRemoteResolver.js +++ /dev/null @@ -1,77 +0,0 @@ -var util = require('util'); -var mout = require('mout'); -var SvnResolver = require('./SvnResolver'); -var cmd = require('../../util/cmd'); - -function SvnRemoteResolver(decEndpoint, config, logger) { - SvnResolver.call(this, decEndpoint, config, logger); - - this._source = SvnResolver.sourceUrl(this._source); -} - -util.inherits(SvnRemoteResolver, SvnResolver); -mout.object.mixIn(SvnRemoteResolver, SvnResolver); - -// ----------------- - -SvnRemoteResolver.prototype._checkout = function () { - var promise; - var timer; - var reporter; - var that = this; - var resolution = this._resolution; - - this._logger.action('checkout', resolution.tag || resolution.branch || resolution.commit, { - resolution: resolution, - to: this._tempDir - }); - - if (resolution.type === 'version') { - promise = cmd('svn', ['checkout', this._source + '/trunk', '-r' + resolution.commit, this._tempDir]); - } else if (resolution.type === 'branch' && resolution.branch === 'trunk') { - promise = cmd('svn', ['checkout', this._source + '/trunk', this._tempDir]); - } else { - promise = cmd('svn', ['checkout', this._source + '/' + resolution.type + (resolution.type === 'branch' ? 'es/' : 's/') + (resolution.tag || resolution.branch), this._tempDir]); - } - - // Throttle the progress reporter to 1 time each sec - reporter = mout.fn.throttle(function (data) { - var lines; - - lines = data.split(/[\r\n]+/); - lines.forEach(function (line) { - if (/\d{1,3}\%/.test(line)) { - // TODO: There are some strange chars that appear once in a while (\u001b[K) - // Trim also those? - that._logger.info('progress', line.trim()); - } - }); - }, 1000); - - // Start reporting progress after a few seconds - timer = setTimeout(function () { - promise.progress(reporter); - }, 8000); - - return promise - // Add additional proxy information to the error if necessary - .fail(function (err) { - throw err; - }) - // Clear timer at the end - .fin(function () { - clearTimeout(timer); - reporter.cancel(); - }); -}; - -SvnRemoteResolver.prototype._findResolution = function (target) { - // Override this function to include a meaningful message related to proxies - // if necessary - return SvnResolver.prototype._findResolution.call(this, target) - .fail(function (err) { - throw err; - }); -}; - -module.exports = SvnRemoteResolver; diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js index bc484e10a..c1f81ca9d 100644 --- a/lib/core/resolvers/SvnResolver.js +++ b/lib/core/resolvers/SvnResolver.js @@ -70,9 +70,57 @@ SvnResolver.prototype._resolve = function () { // ----------------- -// Abstract functions that should be implemented by concrete git resolvers SvnResolver.prototype._checkout = function () { - throw new Error('_checkout not implemented'); + var promise; + var timer; + var reporter; + var that = this; + var resolution = this._resolution; + + this._source = SvnResolver.sourceUrl(this._source); + + this._logger.action('checkout', resolution.tag || resolution.branch || resolution.commit, { + resolution: resolution, + to: this._tempDir + }); + + if (resolution.type === 'version') { + promise = cmd('svn', ['checkout', this._source + '/trunk', '-r' + resolution.commit, this._tempDir]); + } else if (resolution.type === 'branch' && resolution.branch === 'trunk') { + promise = cmd('svn', ['checkout', this._source + '/trunk', this._tempDir]); + } else { + promise = cmd('svn', ['checkout', this._source + '/' + resolution.type + (resolution.type === 'branch' ? 'es/' : 's/') + (resolution.tag || resolution.branch), this._tempDir]); + } + + // Throttle the progress reporter to 1 time each sec + reporter = mout.fn.throttle(function (data) { + var lines; + + lines = data.split(/[\r\n]+/); + lines.forEach(function (line) { + if (/\d{1,3}\%/.test(line)) { + // TODO: There are some strange chars that appear once in a while (\u001b[K) + // Trim also those? + that._logger.info('progress', line.trim()); + } + }); + }, 1000); + + // Start reporting progress after a few seconds + timer = setTimeout(function () { + promise.progress(reporter); + }, 8000); + + return promise + // Add additional proxy information to the error if necessary + .fail(function (err) { + throw err; + }) + // Clear timer at the end + .fin(function () { + clearTimeout(timer); + reporter.cancel(); + }); }; // ----------------- diff --git a/lib/core/resolvers/index.js b/lib/core/resolvers/index.js index ec64a215d..01bc18fb3 100644 --- a/lib/core/resolvers/index.js +++ b/lib/core/resolvers/index.js @@ -2,7 +2,7 @@ module.exports = { GitFs: require('./GitFsResolver'), GitRemote: require('./GitRemoteResolver'), GitHub: require('./GitHubResolver'), - Svn: require('./SvnRemoteResolver'), + Svn: require('./SvnResolver'), Fs: require('./FsResolver'), Url: require('./UrlResolver') }; From 3b98e4962a630681237ad44b3668eda298a7776e Mon Sep 17 00:00:00 2001 From: Ahmad Nassri Date: Sun, 19 Jan 2014 13:09:49 -0500 Subject: [PATCH 0281/1021] final working version, with unit tests update README with examples --- README.md | 2 +- lib/core/resolvers/SvnResolver.js | 40 ++++++++++++++-------------- test/core/resolverFactory.js | 6 ++--- test/core/resolvers/svnResolver.js | 42 +++++++++++++++++------------- 4 files changed, 47 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index d001a5415..36b29cf96 100644 --- a/README.md +++ b/README.md @@ -395,7 +395,7 @@ Thanks for assistance and contributions: [@wibblymat](https://github.com/wibblymat), [@wycats](https://github.com/wycats), [@ahmadnassri](https://github.com/ahmadnassri) -[@ahmadnassri](https://github.com/kennethklee) +[@kennethklee](https://github.com/kennethklee) ## License diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js index c1f81ca9d..aab19728a 100644 --- a/lib/core/resolvers/SvnResolver.js +++ b/lib/core/resolvers/SvnResolver.js @@ -33,6 +33,15 @@ mout.object.mixIn(SvnResolver, Resolver); // ----------------- +SvnResolver.getSource = function (source) { + var uri = this._source || source; + + return uri + .replace(/^svn\+(https?|file):\/\//i, '$1://') // Change svn+http or svn+https or svn+file to http(s), file respectively + .replace('svn://', 'http://') // Change svn to http + .replace(/\/+$/, ''); // Remove trailing slashes +}; + SvnResolver.prototype._hasNew = function (canonicalDir, pkgMeta) { var oldResolution = pkgMeta._resolution || {}; @@ -77,19 +86,21 @@ SvnResolver.prototype._checkout = function () { var that = this; var resolution = this._resolution; - this._source = SvnResolver.sourceUrl(this._source); + this.source = SvnResolver.getSource(this._source); this._logger.action('checkout', resolution.tag || resolution.branch || resolution.commit, { resolution: resolution, to: this._tempDir }); - if (resolution.type === 'version') { + if (resolution.type === 'commit') { promise = cmd('svn', ['checkout', this._source + '/trunk', '-r' + resolution.commit, this._tempDir]); } else if (resolution.type === 'branch' && resolution.branch === 'trunk') { promise = cmd('svn', ['checkout', this._source + '/trunk', this._tempDir]); + } else if (resolution.type === 'branch') { + promise = cmd('svn', ['checkout', this._source + '/branches/' + resolution.branch, this._tempDir]); } else { - promise = cmd('svn', ['checkout', this._source + '/' + resolution.type + (resolution.type === 'branch' ? 'es/' : 's/') + (resolution.tag || resolution.branch), this._tempDir]); + promise = cmd('svn', ['checkout', this._source + '/tags/' + resolution.tag, this._tempDir]); } // Throttle the progress reporter to 1 time each sec @@ -132,8 +143,7 @@ SvnResolver.prototype._findResolution = function (target) { target = target || this._target || '*'; - // clean the source variable - this._source = SvnResolver.sourceUrl(this._source); + this._source = SvnResolver.getSource(this._source); // Target is a revision, so it's a stale target (not a moving target) // There's nothing to do in this case @@ -209,7 +219,7 @@ SvnResolver.prototype._findResolution = function (target) { branches = Object.keys(branches); tags = Object.keys(tags); - err = createError('Tag/branch ' + target + ' does not exist', 'ENORESTARGET'); + err = createError('target ' + target + ' does not exist', 'ENORESTARGET'); err.details = !tags.length ? 'No tags found in ' + that._source : 'Available tags: ' + tags.join(', '); @@ -266,8 +276,7 @@ SvnResolver.prototype._savePkgMeta = function (meta) { // ------------------------------ SvnResolver.versions = function (source, extra) { - // clean the source variable - source = SvnResolver.sourceUrl(source); + source = SvnResolver.getSource(source); var value = this._cache.versions.get(source); @@ -321,8 +330,7 @@ SvnResolver.versions = function (source, extra) { }; SvnResolver.tags = function (source) { - // clean the source variable - source = SvnResolver.sourceUrl(source); + source = SvnResolver.getSource(source); var value = this._cache.tags.get(source); @@ -361,8 +369,7 @@ SvnResolver.tags = function (source) { }; SvnResolver.branches = function (source) { - // clean the source variable - source = SvnResolver.sourceUrl(source); + source = SvnResolver.getSource(source); var value = this._cache.branches.get(source); @@ -410,15 +417,6 @@ SvnResolver.clearRuntimeCache = function () { }); }; -// source url cleaning utility function -// reason: the constructor is not called when using commands such as "list" -SvnResolver.sourceUrl = function (source) { - return source - .replace(/^svn\+(https?|file):\/\//i, '$1://') // Change svn+http or svn+https or svn+file to http(s), file respectively - .replace('svn://', 'http://') // Change svn to http - .replace(/\/+$/, ''); // Remove trailing slashes -}; - SvnResolver._cache = { branches: new LRU({ max: 50, maxAge: 5 * 60 * 1000 }), tags: new LRU({ max: 50, maxAge: 5 * 60 * 1000 }), diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index ee733ae35..90d49f26e 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -383,7 +383,7 @@ describe('resolverFactory', function () { .then(function (resolver) { expect(resolver).to.be.a(resolvers.Svn); expect(resolver).to.not.be(resolvers.GitHub); - expect(resolver.getSource()).to.equal(value); + expect(resolvers.Svn.getSource(resolver.getSource())).to.equal(value); expect(resolver.getTarget()).to.equal('*'); }); @@ -394,7 +394,7 @@ describe('resolverFactory', function () { .then(function (resolver) { expect(resolver).to.be.a(resolvers.Svn); expect(resolver).to.not.be(resolvers.GitHub); - expect(resolver.getSource()).to.equal(value); + expect(resolvers.Svn.getSource(resolver.getSource())).to.equal(value); expect(resolver.getTarget()).to.equal('commit-ish'); }); @@ -405,7 +405,7 @@ describe('resolverFactory', function () { .then(function (resolver) { expect(resolver).to.be.a(resolvers.Svn); expect(resolver).to.not.be(resolvers.GitHub); - expect(resolver.getSource()).to.equal(value); + expect(resolvers.Svn.getSource(resolver.getSource())).to.equal(value); expect(resolver.getName()).to.equal('foo'); expect(resolver.getTarget()).to.equal('*'); }); diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index 0214e54a9..bfd3f12e1 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -14,7 +14,8 @@ var defaultConfig = require('../../../lib/config'); describe('SvnResolver', function () { var tempDir = path.resolve(__dirname, '../../assets/tmp'); - var testPackage = path.resolve(__dirname, '../../assets/package-svn'); + var testPackage = path.resolve(__dirname, '../../assets/package-svn/repo'); + var testPackageAdmin = path.resolve(__dirname, '../../assets/package-svn/admin'); var originaltags = SvnResolver.tags; var logger; @@ -71,12 +72,19 @@ describe('SvnResolver', function () { commit: 123 } })); + SvnResolver.tags = function () { return Q.resolve({ 'boo': 123 // same commit hash on purpose }); }; + SvnResolver.branches = function () { + return Q.resolve({ + 'trunk': '*' + }); + }; + resolver = create('foo'); resolver.hasNew(tempDir) .then(function (hasNew) { @@ -98,6 +106,7 @@ describe('SvnResolver', function () { commit: 3 } })); + SvnResolver.tags = function () { return Q.resolve({ '1.0.0': 2, @@ -204,7 +213,7 @@ describe('SvnResolver', function () { fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ name: 'foo', _resolution: { - type: 'revno', + type: 'commit', commit: 1 } })); @@ -318,7 +327,7 @@ describe('SvnResolver', function () { .done(); }); - it('should resolve "*" to the latest revno if a repository has no valid semver tags', function (next) { + it('should resolve "*" to the trunk if a repository has no valid semver tags', function (next) { var resolver; SvnResolver.tags = function () { @@ -331,8 +340,9 @@ describe('SvnResolver', function () { resolver._findResolution('*') .then(function (resolution) { expect(resolution).to.eql({ - type: 'revno', - commit: '-1' + type: 'branch', + branch: 'trunk', + commit: '*' }); next(); }) @@ -531,7 +541,7 @@ describe('SvnResolver', function () { .done(); }); - it('should resolve to the specified revno', function (next) { + it('should resolve to the specified commit', function (next) { var resolver; SvnResolver.tags = function () { @@ -541,10 +551,10 @@ describe('SvnResolver', function () { }; resolver = create('foo'); - resolver._findResolution('revno:1') + resolver._findResolution('r1') .then(function (resolution) { expect(resolution).to.eql({ - type: 'revno', + type: 'commit', commit: 1 }); next(); @@ -619,7 +629,7 @@ describe('SvnResolver', function () { this.timeout(30000); // Give some time to copy // Copy .svn folder to the tempDir - copy.copyDir(path.resolve(__dirname, '../../assets/package-svn/.svn'), dst, { + copy.copyDir(path.resolve(__dirname, '../../assets/package-svn/repo/.svn'), dst, { mode: 0777 }) .then(function () { @@ -1057,17 +1067,16 @@ describe('SvnResolver', function () { var resolver; resolver = create('file://' + testPackage); - expect(resolver.getName()).to.equal('package-svn'); - - resolver = create('lp:~stephen-stewart/+junk/bower-test-package'); - expect(resolver.getName()).to.equal('bower-test-package'); + expect(resolver.getName()).to.equal('repo'); + resolver = create('svn+http://yii.googlecode.com/svn'); + expect(resolver.getName()).to.equal('svn'); }); }); describe('.resolve', function () { it('should checkout correctly if resolution is a tag', function (next) { - var resolver = create({ source: 'file://' + testPackage, target: '~0.0.1' }); + var resolver = create({ source: 'file://' + testPackageAdmin, target: '0.0.1' }); resolver.resolve() .then(function (dir) { @@ -1077,15 +1086,13 @@ describe('SvnResolver', function () { expect(files).to.contain('foo'); expect(files).to.contain('bar'); - expect(files).to.not.contain('baz'); - next(); }) .done(); }); it('should checkout correctly if resolution is a commit', function (next) { - var resolver = create({ source: 'file://' + testPackage, target: 'revno:1' }); + var resolver = create({ source: 'file://' + testPackageAdmin, target: 'r1' }); resolver.resolve() .then(function (dir) { @@ -1096,7 +1103,6 @@ describe('SvnResolver', function () { expect(files).to.not.contain('foo'); expect(files).to.not.contain('bar'); expect(files).to.not.contain('baz'); - expect(files).to.contain('.master'); next(); }) .done(); From ea60442fd6b86b14be725c0c4908063d7ccc2125 Mon Sep 17 00:00:00 2001 From: Ahmad Nassri Date: Sun, 19 Jan 2014 13:22:09 -0500 Subject: [PATCH 0282/1021] fixing failed travis test --- test/core/resolvers/svnResolver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index bfd3f12e1..a1c9eee38 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -1085,7 +1085,7 @@ describe('SvnResolver', function () { var files = fs.readdirSync(dir); expect(files).to.contain('foo'); - expect(files).to.contain('bar'); + expect(files).to.not.contain('bar'); next(); }) .done(); From c1f992b11f142222dc768cfc1fbbdcce7efa6960 Mon Sep 17 00:00:00 2001 From: Sebastian Seilund Date: Sun, 10 Nov 2013 18:24:50 -0800 Subject: [PATCH 0283/1021] Added bower version command --- lib/commands/index.js | 3 +- lib/commands/version.js | 140 +++++++++++++++++++++++++++++++ templates/json/help-version.json | 14 ++++ templates/json/help.json | 3 +- 4 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 lib/commands/version.js create mode 100644 templates/json/help-version.json diff --git a/lib/commands/index.js b/lib/commands/index.js index 57522a112..6e38aeae6 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -13,5 +13,6 @@ module.exports = { register: require('./register'), search: require('./search'), update: require('./update'), - uninstall: require('./uninstall') + uninstall: require('./uninstall'), + version: require('./version') }; diff --git a/lib/commands/version.js b/lib/commands/version.js new file mode 100644 index 000000000..5bf80d4ce --- /dev/null +++ b/lib/commands/version.js @@ -0,0 +1,140 @@ +var mout = require('mout'); +var semver = require('semver'); +var Logger = require('bower-logger'); +var which = require('which'); +var fs = require('fs'); +var path = require('path'); +var Q = require('q'); +var execFile = require('child_process').execFile; +var Project = require('../core/Project'); +var cli = require('../util/cli'); +var defaultConfig = require('../config'); +var createError = require('../util/createError'); + +function version(versionArg, options, config) { + var project; + var logger = new Logger(); + + config = mout.object.deepFillIn(config || {}, defaultConfig); + project = new Project(config, logger); + + bump(project, versionArg, options.message) + .done(function () { + logger.emit('end'); + }, function (error) { + logger.emit('error', error); + }); + + return logger; +} + +function bump(project, versionArg, message) { + var newVersion; + var doGitCommit = false; + + return checkGit() + .then(function (hasGit) { + doGitCommit = hasGit; + }) + .then(project.getJson.bind(project)) + .then(function (json) { + newVersion = getNewVersion(json.version, versionArg); + json.version = newVersion; + }) + .then(project.saveJson.bind(project)) + .then(function () { + if (doGitCommit) { + return gitCommitAndTag(newVersion, message); + } + }) + .then(function () { + console.log('v' + newVersion); + }); +} + +function getNewVersion(currentVersion, versionArg) { + var newVersion = semver.valid(versionArg); + if (!newVersion) { + newVersion = semver.inc(currentVersion, versionArg); + } + if (!newVersion) { + throw createError('Invalid version argument: `' + versionArg + '`. Usage: `bower version [ | major | minor | patch]`', 'EINVALIDVERSION'); + } + if (currentVersion === newVersion) { + throw createError('Version not changed', 'EVERSIONNOTCHANGED'); + } + return newVersion; +} + +function checkGit() { + var gitDir = path.join(process.cwd(), '.git'); + return Q.nfcall(fs.stat, gitDir) + .then(function (stat) { + if (stat.isDirectory()) { + return checkGitStatus(); + } + return false; + }, function () { + //Ignore not found .git directory + return false; + }); +} + +function checkGitStatus() { + return Q.nfcall(which, 'git') + .fail(function (err) { + err.code = 'ENOGIT'; + throw err; + }) + .then(function () { + return Q.nfcall(execFile, 'git', ['status', '--porcelain'], {env: process.env}); + }) + .then(function (value) { + var stdout = value[0]; + var lines = filterModifiedStatusLines(stdout); + if (lines.length) { + throw createError('Git working directory not clean.\n' + lines.join('\n'), 'EWORKINGDIRECTORYDIRTY'); + } + return true; + }); +} + +function filterModifiedStatusLines(stdout) { + return stdout.trim().split('\n') + .filter(function (line) { + return line.trim() && !line.match(/^\?\? /); + }).map(function (line) { + return line.trim(); + }); +} + +function gitCommitAndTag(newVersion, message) { + message = message || 'v' + newVersion; + message = message.replace(/%s/g, newVersion); + return Q.nfcall(execFile, 'git', ['add', 'bower.json'], {env: process.env}) + .then(function () { + return Q.nfcall(execFile, 'git', ['commit', '-m', message], {env: process.env}); + }) + .then(function () { + return Q.nfcall(execFile, 'git', ['tag', newVersion, '-am', message], {env: process.env}); + }); +} + +// ------------------- + +version.line = function (argv) { + var options = version.options(argv); + return version(options.argv.remain[1], options); +}; + +version.options = function (argv) { + return cli.readOptions({ + 'message': { type: String, shorthand: 'm'} + }, argv); +}; + +version.completion = function () { + // TODO: +}; + +module.exports = version; \ No newline at end of file diff --git a/templates/json/help-version.json b/templates/json/help-version.json new file mode 100644 index 000000000..605ef200f --- /dev/null +++ b/templates/json/help-version.json @@ -0,0 +1,14 @@ +{ + "command": "version", + "description": "Run this in a package directory to bump the version and write the new data back to the bower.json file.\n\nThe newversion argument should be a valid semver string, or a valid second argument to semver.inc (one of \"build\", \"patch\", \"minor\", or \"major\"). In the second case, the existing version will be incremented\nby 1 in the specified field.\n\nIf run in a git repo, it will also create a version commit and tag, and fail if the repo is not clean.\n\nIf supplied with --message (shorthand: -m) config option, bower will use it as a commit message when creating a version commit. If the message config contains %s then that will be replaced with the resulting\nversion number. For example:\n\n bower version patch -m \"Upgrade to %s for reasons\"", + "usage": [ + "version [ | major | minor | patch]" + ], + "options": [ + { + "shorthand": "-m", + "flag": "--message", + "description": "Custom git commit and tag message" + } + ] +} diff --git a/templates/json/help.json b/templates/json/help.json index 45a3a2f73..258f5c5e7 100644 --- a/templates/json/help.json +++ b/templates/json/help.json @@ -16,7 +16,8 @@ "register": "Register a package", "search": "Search for a package by name", "update": "Update a local package", - "uninstall": "Remove a local package" + "uninstall": "Remove a local package", + "version": "Bump a package version" }, "options": [ { From 84a24b76c7aedb9359610ea5975c3548bed77804 Mon Sep 17 00:00:00 2001 From: Paul Irish Date: Mon, 20 Jan 2014 13:34:05 -0800 Subject: [PATCH 0284/1021] bower team --- README.md | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index da85acf21..f79edefa6 100644 --- a/README.md +++ b/README.md @@ -349,11 +349,17 @@ review the [guidelines for contributing](CONTRIBUTING.md). * [Pull requests](CONTRIBUTING.md#pull-requests) -## Authors +## Bower Team + +### Core team -* [@fat](https://github.com/fat) -* [@maccman](https://github.com/maccman) * [@satazor](https://github.com/satazor) +* [@wibblymat](https://github.com/wibblymat) +* [@necolas](https://github.com/necolas) +* [@paulirish](https://github.com/paulirish) +* [@benschwarz](https://github.com/benschwarz) +* [@sindresorhus](https://github.com/sindresorhus) +* [@svnlto](https://github.com/svnlto) Thanks for assistance and contributions: @@ -373,21 +379,22 @@ Thanks for assistance and contributions: [@marcooliveira](https://github.com/marcooliveira), [@mklabs](https://github.com/mklabs), [@MrDHat](https://github.com/MrDHat), -[@necolas](https://github.com/necolas), -[@paulirish](https://github.com/paulirish), [@richo](https://github.com/richo), [@rvagg](https://github.com/rvagg), -[@sindresorhus](https://github.com/sindresorhus), +[@ryanflorence](https://github.com/ryanflorence), [@SlexAxton](https://github.com/SlexAxton), [@sstephenson](https://github.com/sstephenson), -[@svnlto](https://github.com/svnlto), [@tomdale](https://github.com/tomdale), [@uzquiano](https://github.com/uzquiano), [@visionmedia](https://github.com/visionmedia), [@wagenet](https://github.com/wagenet), -[@wibblymat](https://github.com/wibblymat), [@wycats](https://github.com/wycats) +### Bower Alumni + +* [@fat](https://github.com/fat) +* [@maccman](https://github.com/maccman) + ## License From 5eb29fa99c4a9c055dbf5f4496135012f21ac1d6 Mon Sep 17 00:00:00 2001 From: Paul Irish Date: Mon, 20 Jan 2014 13:44:06 -0800 Subject: [PATCH 0285/1021] Update CONTRIBUTING.md --- CONTRIBUTING.md | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f65d5d516..e98ed8848 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,29 @@ # Contributing to Bower -Please take a moment to review this document in order to make the contribution -process easy and effective for everyone involved. +Bower is a large community project with many different developers contributing at all levels to the project. We're **actively** looking for more contributors right now. (Jan 2014) + +## Casual Involvement +* Improve the bower.io site ([tickets](https://github.com/bower/bower.github.io/issues)) +* Move forward [bower.io redesign](https://github.com/bower/bower.github.io/issues/7) +* Attend team meetings +* Comment on issues and drive to resolution + +## High-impact Involvement + +* Maintaining the bower client. + * [Authoring client tests](https://github.com/bower/bower/issues/801) + * Read [Architecture doc](https://github.com/bower/bower/wiki/Rewrite-architecture) + * Triage, close, fix and resolve [issues](https://github.com/bower/bower/issues) +* Developing the [new registry server](https://github.com/bower/registry/tree/node_rewrite) + * Hooking in to Elastic Search rather than the in-memory search + * Getting bower/registry-client to talk to the new server without breaking backwards compatibility + * DevOps for the server + +## Team Meetings + +We meet on Monday at 1:00pm PST, 8:00pm UTC in #bower on Freenode. [The meeting notes](http://goo.gl/NJZ1o2). + +
Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, @@ -11,6 +33,8 @@ changes, and helping you finalize your pull requests. ## Using the issue tracker +* + The issue tracker is the preferred channel for [bug reports](#bugs), [features requests](#features) and [submitting pull requests](#pull-requests), but please respect the following restrictions: From a3e1c8695391ca36cc2bbc55c16d4e7ba5348729 Mon Sep 17 00:00:00 2001 From: Stephen Date: Mon, 27 Jan 2014 20:32:04 +0000 Subject: [PATCH 0286/1021] Update Team Meeting time to correct UTC --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e98ed8848..b59a947f0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,7 +21,7 @@ Bower is a large community project with many different developers contributing a ## Team Meetings -We meet on Monday at 1:00pm PST, 8:00pm UTC in #bower on Freenode. [The meeting notes](http://goo.gl/NJZ1o2). +We meet on Monday at 1:00pm PST, 9:00pm UTC in #bower on Freenode. [The meeting notes](http://goo.gl/NJZ1o2).
From e6cb497d1a60e07cf5778ec8c1531847c31993af Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Mon, 27 Jan 2014 21:00:57 +0000 Subject: [PATCH 0287/1021] Added a .bowerrc option to make bower install assume --save (#1040) --- lib/commands/install.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/commands/install.js b/lib/commands/install.js index 46594fbb5..8201c4bba 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -14,6 +14,9 @@ function install(endpoints, options, config) { options = options || {}; config = mout.object.deepFillIn(config || {}, defaultConfig); + if (options.save === undefined) { + options.save = config.defaultSave; + } project = new Project(config, logger); tracker = new Tracker(config); From 3dbddfba41af2e12cedb9d481b9a8fc07661bed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Berg=C3=A9?= Date: Mon, 27 Jan 2014 22:49:58 +0100 Subject: [PATCH 0288/1021] Fix reading versions from cache directory. When we write into directory we use encodeURIComponent, but when we read, we did nothing. Now we use decodeURIComponent to read the correct version and match the correct cache directory. --- lib/core/ResolveCache.js | 3 ++- test/core/resolveCache.js | 18 +++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/core/ResolveCache.js b/lib/core/ResolveCache.js index 0bf503dd8..6de8e1809 100644 --- a/lib/core/ResolveCache.js +++ b/lib/core/ResolveCache.js @@ -76,7 +76,7 @@ ResolveCache.prototype.retrieve = function (source, target) { } // Resolve with canonical dir and package meta - canonicalDir = path.join(dir, version); + canonicalDir = path.join(dir, encodeURIComponent(version)); return that._readPkgMeta(canonicalDir) .then(function (pkgMeta) { return [canonicalDir, pkgMeta]; @@ -346,6 +346,7 @@ ResolveCache.prototype._getVersions = function (sourceId) { .then(function (versions) { // Sort and cache in memory that._sortVersions(versions); + versions = versions.map(decodeURIComponent); that._cache.set(sourceId, versions); return [versions, false]; }, function (err) { diff --git a/test/core/resolveCache.js b/test/core/resolveCache.js index 5ebb82f99..127496452 100644 --- a/test/core/resolveCache.js +++ b/test/core/resolveCache.js @@ -529,6 +529,7 @@ describe('ResolveCache', function () { var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); var json = { name: 'foo' }; + var encoded; // Create some versions fs.mkdirSync(sourceDir); @@ -538,22 +539,25 @@ describe('ResolveCache', function () { fs.writeFileSync(path.join(sourceDir, '0.1.0', '.bower.json'), JSON.stringify(json, null, ' ')); json.version = '0.1.0+build.4'; - fs.mkdirSync(path.join(sourceDir, '0.1.0+build.4')); - fs.writeFileSync(path.join(sourceDir, '0.1.0+build.4', '.bower.json'), JSON.stringify(json, null, ' ')); + encoded = encodeURIComponent('0.1.0+build.4'); + fs.mkdirSync(path.join(sourceDir, encoded)); + fs.writeFileSync(path.join(sourceDir, encoded, '.bower.json'), JSON.stringify(json, null, ' ')); json.version = '0.1.0+build.5'; - fs.mkdirSync(path.join(sourceDir, '0.1.0+build.5')); - fs.writeFileSync(path.join(sourceDir, '0.1.0+build.5', '.bower.json'), JSON.stringify(json, null, ' ')); + encoded = encodeURIComponent('0.1.0+build.5'); + fs.mkdirSync(path.join(sourceDir, encoded)); + fs.writeFileSync(path.join(sourceDir, encoded, '.bower.json'), JSON.stringify(json, null, ' ')); json.version = '0.1.0+build.6'; - fs.mkdirSync(path.join(sourceDir, '0.1.0+build.6')); - fs.writeFileSync(path.join(sourceDir, '0.1.0+build.6', '.bower.json'), JSON.stringify(json, null, ' ')); + encoded = encodeURIComponent('0.1.0+build.6'); + fs.mkdirSync(path.join(sourceDir, encoded)); + fs.writeFileSync(path.join(sourceDir, encoded, '.bower.json'), JSON.stringify(json, null, ' ')); resolveCache.retrieve(source, '0.1.0+build.5') .spread(function (canonicalDir, pkgMeta) { expect(pkgMeta).to.be.an('object'); expect(pkgMeta.version).to.equal('0.1.0+build.5'); - expect(canonicalDir).to.equal(path.join(sourceDir, '0.1.0+build.5')); + expect(canonicalDir).to.equal(path.join(sourceDir, encodeURIComponent('0.1.0+build.5'))); next(); }) From 3ecc389e6632fb16efce39ecc02fbec2b489fb49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Berg=C3=A9?= Date: Mon, 27 Jan 2014 23:42:19 +0100 Subject: [PATCH 0289/1021] Fix concurrent renaming. We stock the renaming promise in cache to ensure that there is not concurrent renaming. --- lib/core/ResolveCache.js | 22 +++++++++++++++++----- test/core/resolveCache.js | 24 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/lib/core/ResolveCache.js b/lib/core/ResolveCache.js index 0bf503dd8..5730278a5 100644 --- a/lib/core/ResolveCache.js +++ b/lib/core/ResolveCache.js @@ -124,7 +124,18 @@ ResolveCache.prototype.store = function (canonicalDir, pkgMeta) { }) // Move the canonical to sourceId/target .then(function () { - return Q.nfcall(fs.rename, canonicalDir, dir) + // We store the renaming in cache. + var key = 'moving:' + dir; + var promise; + if (that._cache.has(key)) { + promise = that._cache.get(key); + } + else { + promise = Q.nfcall(fs.rename, canonicalDir, dir); + that._cache.set(key, promise); + } + + return promise .fail(function (err) { // If error is EXDEV it means that we are trying to rename // across different drives, so we copy and remove it instead @@ -132,10 +143,11 @@ ResolveCache.prototype.store = function (canonicalDir, pkgMeta) { throw err; } - return copy.copyDir(canonicalDir, dir) - .then(function () { - return Q.nfcall(rimraf, canonicalDir); - }); + return copy.copyDir(canonicalDir, dir); + }) + // To match all case, we remove the directory. + .then(function () { + return Q.nfcall(rimraf, canonicalDir); }); }); }) diff --git a/test/core/resolveCache.js b/test/core/resolveCache.js index 5ebb82f99..102879c52 100644 --- a/test/core/resolveCache.js +++ b/test/core/resolveCache.js @@ -310,6 +310,30 @@ describe('ResolveCache', function () { }) .done(); }); + + it('should be possible to store two package at same time', function (next) { + var store = resolveCache.store.bind(resolveCache, tempPackage, { + name: 'foo', + _source: 'foo', + _target: 'foo/bar' + }); + var store2 = resolveCache.store.bind(resolveCache, tempPackage2, { + name: 'foo', + _source: 'foo', + _target: 'foo/bar' + }); + + Q.all([store(), store2()]).then(function (dirs) { + var dir = dirs[0]; + expect(dir).to.equal(path.join(cacheDir, md5('foo'), 'foo%2Fbar')); + expect(fs.existsSync(dir)).to.be(true); + expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); + expect(fs.existsSync(tempPackage)).to.be(false); + expect(fs.existsSync(tempPackage2)).to.be(false); + + next(); + }).done(); + }); }); describe('.versions', function () { From d130c73e77d5cfb85d8f1d0301a59ffa276091f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Berg=C3=A9?= Date: Tue, 28 Jan 2014 12:23:21 +0100 Subject: [PATCH 0290/1021] Fix removing directory. --- lib/core/ResolveCache.js | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/lib/core/ResolveCache.js b/lib/core/ResolveCache.js index 5730278a5..f712fa1a9 100644 --- a/lib/core/ResolveCache.js +++ b/lib/core/ResolveCache.js @@ -108,24 +108,35 @@ ResolveCache.prototype.store = function (canonicalDir, pkgMeta) { release = that._getPkgRelease(pkgMeta); dir = path.join(that._dir, sourceId, release); - // Check if directory exists - return Q.nfcall(fs.stat, dir) - .then(function () { - // If it does exists, remove it - return Q.nfcall(rimraf, dir); - }, function (err) { - // If directory does not exists, ensure its basename - // is created - if (err.code === 'ENOENT') { - return Q.nfcall(mkdirp, path.dirname(dir)); - } + var checkExistingDirectory; + var key = 'moving:' + dir; + + if (! that._cache.has(key)) { + // Check if directory exists + checkExistingDirectory = Q.nfcall(fs.stat, dir) + .then(function () { + // If it does exists, remove it + return Q.nfcall(rimraf, dir); + }, function (err) { + // If directory does not exists, ensure its basename + // is created + if (err.code === 'ENOENT') { + return Q.nfcall(mkdirp, path.dirname(dir)); + } + + throw err; + }); + } + else { + var defer = Q.defer(); + defer.resolve(); + checkExistingDirectory = defer.promise; + } - throw err; - }) + return checkExistingDirectory // Move the canonical to sourceId/target .then(function () { // We store the renaming in cache. - var key = 'moving:' + dir; var promise; if (that._cache.has(key)) { promise = that._cache.get(key); From c9cf6d157bb4509ff9c17679bf7b569ae4cf0515 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 29 Jan 2014 12:39:34 +0100 Subject: [PATCH 0291/1021] readme - remove sourcegraph badge. not needed --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f79edefa6..7dd816d75 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bower -[![Build Status](https://secure.travis-ci.org/bower/bower.png?branch=master)](http://travis-ci.org/bower/bower) [![Views in the last 24 hours](https://sourcegraph.com/api/repos/github.com/bower/bower/counters/views-24h.png)](https://sourcegraph.com/github.com/bower/bower) +[![Build Status](https://secure.travis-ci.org/bower/bower.png?branch=master)](http://travis-ci.org/bower/bower) From d3ccc73796fa1809705d351c8eb4c454c8d81a61 Mon Sep 17 00:00:00 2001 From: reiz Date: Fri, 31 Jan 2014 14:54:35 +0100 Subject: [PATCH 0292/1021] Adding validation for package name Closes #15 --- packages/bower-json/lib/json.js | 18 ++++++++++++- packages/bower-json/test/test.js | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index be753d244..5e36770a4 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -88,7 +88,23 @@ function validate(json) { throw createError('No name property set', 'EINVALID'); } - // TODO + if (json.name.length > 50) { + throw createError('The name is too long. 50 character should be more than enough', 'EINVALID'); + } + + if (/[A-Z]/.test(json.name)) { + throw createError('The name contains upper case letters', 'EINVALID'); + } + + if (!/^[a-z]/.test(json.name)) { + throw createError('The name has to start with a lower case character from a to z', 'EINVALID'); + } + + if (!/[a-z]$/.test(json.name)) { + throw createError('The name has to end with a lower case character from a to z', 'EINVALID'); + } + + // TODO https://github.com/bower/bower.json-spec return json; } diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index 8befab368..256c1edd6 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -181,6 +181,49 @@ describe('.validate', function () { bowerJson.validate({}); }).to.throwException(/name/); }); + + it('should validate the name length', function () { + var json = { name: 'a_123456789_123456789_123456789_123456789_123456789_z' }; + expect(function () { + bowerJson.validate(json); + }).to.throwException(); + }); + it('should validate the name is lowercase', function () { + var json = { name: 'gruNt' }; + expect(function () { + bowerJson.validate(json); + }).to.throwException(); + }); + it('should validate the name starts with lowercase', function () { + var json = { name: 'Grunt' }; + expect(function () { + bowerJson.validate(json); + }).to.throwException(); + }); + it('should validate the name starts with lowercase', function () { + var json = { name: '.grunt' }; + expect(function () { + bowerJson.validate(json); + }).to.throwException(); + }); + it('should validate the name ends with lowercase', function () { + var json = { name: 'grunT' }; + expect(function () { + bowerJson.validate(json); + }).to.throwException(); + }); + it('should validate the name ends with lowercase', function () { + var json = { name: 'grun.' }; + expect(function () { + bowerJson.validate(json); + }).to.throwException(); + }); + it('should validate the name is valid', function () { + var json = { name: 'gru.n-t' }; + expect(function () { + bowerJson.validate(json); + }).to.not.throwException(); + }); }); describe('.normalize', function () { From fde7965bc96154d895bea405d0f450035ae41a1c Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Sat, 1 Feb 2014 21:43:50 -0500 Subject: [PATCH 0293/1021] Cache output of GitFsResolver.refs and GitRemoteResolver.refs, fixes #1083 --- lib/core/resolvers/GitFsResolver.js | 2 +- lib/core/resolvers/GitRemoteResolver.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core/resolvers/GitFsResolver.js b/lib/core/resolvers/GitFsResolver.js index 5fa71ed85..3f3e9438d 100644 --- a/lib/core/resolvers/GitFsResolver.js +++ b/lib/core/resolvers/GitFsResolver.js @@ -69,7 +69,7 @@ GitFsResolver.refs = function (source) { // Store the promise to be reused until it resolves // to a specific value - this._cache.refs.set(source); + this._cache.refs.set(source, value); return value; }; diff --git a/lib/core/resolvers/GitRemoteResolver.js b/lib/core/resolvers/GitRemoteResolver.js index 5486f60a2..1367ad06d 100644 --- a/lib/core/resolvers/GitRemoteResolver.js +++ b/lib/core/resolvers/GitRemoteResolver.js @@ -187,7 +187,7 @@ GitRemoteResolver.refs = function (source) { // Store the promise to be reused until it resolves // to a specific value - this._cache.refs.set(source); + this._cache.refs.set(source, value); return value; }; From 504f738cff744984a015286f42f2169b6cd13aec Mon Sep 17 00:00:00 2001 From: PatrickJS Date: Mon, 3 Feb 2014 02:09:46 -0800 Subject: [PATCH 0294/1021] update copyright year --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 13e8246fd..4d2229da5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2012 Twitter and other contributors +Copyright (c) 2014 Twitter and other contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in From 08af876e019578f194bfa37fbc63fe450c917b86 Mon Sep 17 00:00:00 2001 From: Patrick Kettner Date: Wed, 22 Jan 2014 14:07:23 -0500 Subject: [PATCH 0295/1021] add fallback support to dumb http servers --- lib/core/resolvers/GitRemoteResolver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/resolvers/GitRemoteResolver.js b/lib/core/resolvers/GitRemoteResolver.js index 5486f60a2..a840360aa 100644 --- a/lib/core/resolvers/GitRemoteResolver.js +++ b/lib/core/resolvers/GitRemoteResolver.js @@ -133,7 +133,7 @@ GitRemoteResolver.prototype._fastClone = function (resolution) { // When that happens, we mark this host and try again if (!GitRemoteResolver._noShallow.has(that._source) && err.details && - /(rpc failed|shallow)/i.test(err.details) + /(rpc failed|shallow|--depth)/i.test(err.details) ) { GitRemoteResolver._noShallow.set(that._host, true); return that._fastClone(resolution); From cd865e0a0a5ba0d158b9ab0ec60317a55b3afcee Mon Sep 17 00:00:00 2001 From: Paul Irish Date: Mon, 3 Feb 2014 22:13:38 -0800 Subject: [PATCH 0296/1021] update copyright year closes #1089 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7dd816d75..422937ed3 100644 --- a/README.md +++ b/README.md @@ -398,6 +398,6 @@ Thanks for assistance and contributions: ## License -Copyright 2012 Twitter, Inc. +Copyright (c) 2014 Twitter and other contributors Licensed under the MIT License From 926b9e0bfd181e3cf4457193241d1404ab896f4f Mon Sep 17 00:00:00 2001 From: gdi2290 Date: Tue, 4 Feb 2014 08:51:39 -0800 Subject: [PATCH 0297/1021] add load-grunt-tasks --- Gruntfile.js | 7 +++---- package.json | 3 ++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 400ee8519..3511c8542 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,4 +1,7 @@ module.exports = function (grunt) { + + require('load-grunt-tasks')(grunt); + grunt.initConfig({ jshint: { options: { @@ -36,10 +39,6 @@ module.exports = function (grunt) { } }); - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-simple-mocha'); - grunt.loadNpmTasks('grunt-exec'); grunt.registerTask('assets', ['exec:assets-force']); grunt.registerTask('test', ['jshint', 'exec:assets', 'simplemocha:full']); diff --git a/package.json b/package.json index 22df9d16c..409942048 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,8 @@ "mocha": "~1.12.0", "nock": "~0.22.0", "istanbul": "~0.1.42", - "proxyquire": "~0.5.0" + "proxyquire": "~0.5.0", + "load-grunt-tasks": "~0.3.0" }, "scripts": { "test": "grunt test" From c3e6199ecf14351be89821173ff54735d807ddc5 Mon Sep 17 00:00:00 2001 From: Luke Fender Date: Tue, 4 Feb 2014 14:15:54 -0500 Subject: [PATCH 0298/1021] fix error message --- lib/util/createLink.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util/createLink.js b/lib/util/createLink.js index b1027189a..f2c26d736 100644 --- a/lib/util/createLink.js +++ b/lib/util/createLink.js @@ -17,7 +17,7 @@ function createLink(src, dst, type) { .fail(function (error) { if (error.code === 'ENOENT') { throw createError('Failed to create link to ' + path.basename(src), 'ENOENT', { - details: src + ' doest not exists or points to a non-existent file' + details: src + ' does not exist or points to a non-existent file' }); } From aa655dadc4a94195149d1403bad3e4b71993a971 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 5 Feb 2014 17:07:19 +0100 Subject: [PATCH 0299/1021] readme - new bower search url --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 422937ed3..8cc64fdb4 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Bower runs over Git, and is package-agnostic. A packaged component can be made up of any type of asset, and use any type of transport (e.g., AMD, CommonJS, etc.). -[View all packages available through Bower's registry](http://sindresorhus.com/bower-components/). +[View all packages available through Bower's registry](http://bower.io/search/). ## Installing Bower From 33ed5402f474902c6ed659196a357b37d747b87b Mon Sep 17 00:00:00 2001 From: Chris Hiester Date: Wed, 5 Feb 2014 14:56:37 -0500 Subject: [PATCH 0300/1021] Fix misspelled message showing in console Change "dependants" to "dependencies" --- templates/std/conflict.std | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/std/conflict.std b/templates/std/conflict.std index d2268aeb3..f23fc8838 100644 --- a/templates/std/conflict.std +++ b/templates/std/conflict.std @@ -1,7 +1,7 @@ {{#yellow}}Unable to find a suitable version for {{name}}, please choose one:{{/yellow}} {{#condense}} {{#each picks}} - {{#magenta}}{{sum @index 1}}){{/magenta}} {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#white}}{{pkgMeta._release}}{{/white}}{{/if}}{{#if dependants}} and has {{#white}}{{dependants}}{{/white}} as dependants{{/if}} + {{#magenta}}{{sum @index 1}}){{/magenta}} {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#white}}{{pkgMeta._release}}{{/white}}{{/if}}{{#if dependants}} and has {{#white}}{{dependants}}{{/white}} as dependencies{{/if}} {{/each}} {{/condense}} {{#unless saveResolutions}} From 469b74ffb38d61454dba2d73beeb80c270bec20e Mon Sep 17 00:00:00 2001 From: Chris Hiester Date: Wed, 5 Feb 2014 20:23:46 -0500 Subject: [PATCH 0301/1021] Clarify package conflict message displayed in console --- templates/std/conflict.std | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/std/conflict.std b/templates/std/conflict.std index f23fc8838..86408589f 100644 --- a/templates/std/conflict.std +++ b/templates/std/conflict.std @@ -1,7 +1,7 @@ {{#yellow}}Unable to find a suitable version for {{name}}, please choose one:{{/yellow}} {{#condense}} {{#each picks}} - {{#magenta}}{{sum @index 1}}){{/magenta}} {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#white}}{{pkgMeta._release}}{{/white}}{{/if}}{{#if dependants}} and has {{#white}}{{dependants}}{{/white}} as dependencies{{/if}} + {{#magenta}}{{sum @index 1}}){{/magenta}} {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#white}}{{pkgMeta._release}}{{/white}}{{/if}}{{#if dependants}} and is required by {{#white}}{{dependants}}{{/white}} {{/if}} {{/each}} {{/condense}} {{#unless saveResolutions}} From 0f7a9e5a74822996344deb4a1f9a874c66631235 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 6 Feb 2014 19:05:56 +0100 Subject: [PATCH 0302/1021] bump deps --- package.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 409942048..b496dfcd3 100644 --- a/package.json +++ b/package.json @@ -34,41 +34,41 @@ "fstream-ignore": "~0.0.6", "glob": "~3.2.1", "graceful-fs": "~2.0.0", - "handlebars": "~1.0.11", - "inquirer": "~0.3.0", + "handlebars": "~1.3.0", + "inquirer": "~0.4.0", "junk": "~0.2.0", "mkdirp": "~0.3.5", - "mout": "~0.7.0", + "mout": "~0.9.0", "nopt": "~2.1.1", - "lru-cache": "~2.3.0", + "lru-cache": "~2.5.0", "open": "~0.0.3", - "osenv": "0.0.3", + "osenv": "~0.0.3", "promptly": "~0.2.0", - "q": "~0.9.2", - "request": "~2.27.0", + "q": "~1.0.0", + "request": "~2.33.0", "request-progress": "~0.3.0", "retry": "~0.6.0", "rimraf": "~2.2.0", - "semver": "~2.1.0", - "stringify-object": "~0.1.4", - "sudo-block": "~0.2.0", + "semver": "~2.2.1", + "stringify-object": "~0.2.0", + "sudo-block": "~0.3.0", "tar": "~0.1.17", "tmp": "~0.0.20", "update-notifier": "~0.1.3", "which": "~1.0.5", "p-throttler": "~0.0.1", - "insight": "~0.2.0" + "insight": "~0.3.0" }, "devDependencies": { "expect.js": "~0.2.0", "grunt": "~0.4.1", "grunt-simple-mocha": "~0.4.0", "grunt-contrib-watch": "~0.5.0", - "grunt-contrib-jshint": "~0.6.0", + "grunt-contrib-jshint": "~0.8.0", "grunt-exec": "~0.4.2", - "mocha": "~1.12.0", - "nock": "~0.22.0", - "istanbul": "~0.1.42", + "mocha": "*", + "nock": "~0.27.2", + "istanbul": "~0.2.4", "proxyquire": "~0.5.0", "load-grunt-tasks": "~0.3.0" }, From 8442373be9afc4e563ed881fd04a222e42aaf090 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 6 Feb 2014 19:13:55 +0100 Subject: [PATCH 0303/1021] use is-root instead of sudo-block since sudo-block isn't really used anyways --- lib/util/rootCheck.js | 6 +++--- package.json | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/util/rootCheck.js b/lib/util/rootCheck.js index 6b2ac5260..9f91b5131 100644 --- a/lib/util/rootCheck.js +++ b/lib/util/rootCheck.js @@ -1,6 +1,6 @@ /*jshint multistr:true*/ - -var sudoBlock = require('sudo-block'); +'use strict'; +var isRoot = require('is-root'); var createError = require('./createError'); var cli = require('./cli'); @@ -22,7 +22,7 @@ http://www.joyent.com/blog/installing-node-and-npm\n\ https://gist.github.com/isaacs/579814\n\n\ You can however run a command with sudo using --allow-root option'; - if (sudoBlock.isRoot) { + if (isRoot()) { renderer = cli.getRenderer('', false, config); renderer.error(createError('Cannot be run with sudo', 'ESUDO', { details : errorMsg })); process.exit(1); diff --git a/package.json b/package.json index b496dfcd3..c46df1078 100644 --- a/package.json +++ b/package.json @@ -51,13 +51,13 @@ "rimraf": "~2.2.0", "semver": "~2.2.1", "stringify-object": "~0.2.0", - "sudo-block": "~0.3.0", "tar": "~0.1.17", "tmp": "~0.0.20", "update-notifier": "~0.1.3", "which": "~1.0.5", "p-throttler": "~0.0.1", - "insight": "~0.3.0" + "insight": "~0.3.0", + "is-root": "~0.1.0" }, "devDependencies": { "expect.js": "~0.2.0", From b12a58632d34327cd11b9634c899f5c75c53d2ec Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 6 Feb 2014 19:25:03 +0100 Subject: [PATCH 0304/1021] upgrade chalk --- lib/renderers/StandardRenderer.js | 8 ++++++-- package.json | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index 42500937c..844a6f568 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -392,10 +392,14 @@ StandardRenderer.prototype._highlightJson = function (json) { return cardinal.highlight(stringifyObject(json, { indent: ' ' }), { theme: { String: { - _default: chalk.cyan + _default: function (str) { + return chalk.cyan(str); + } }, Identifier: { - _default: chalk.green + _default: function (str) { + return chalk.green(str); + } } }, json: true diff --git a/package.json b/package.json index c46df1078..433e337ac 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "bower-logger": "~0.2.2", "bower-registry-client": "~0.1.4", "cardinal": "~0.4.0", - "chalk": "~0.2.0", + "chalk": "~0.4.0", "chmodr": "~0.1.0", "decompress-zip": "~0.0.3", "fstream": "~0.1.22", From 1831e507fe4a6028519c3813f30a50a46ba31b93 Mon Sep 17 00:00:00 2001 From: Chris Gross Date: Fri, 2 Aug 2013 11:35:28 -0400 Subject: [PATCH 0305/1021] scripts/hooks functionality added --- HOOKS.md | 21 +++++++ lib/core/Manager.js | 9 ++- lib/core/Project.js | 71 +++++++++++++----------- lib/core/scripts.js | 96 ++++++++++++++++++++++++++++++++ package.json | 3 +- test/core/scripts.js | 128 +++++++++++++++++++++++++++++++++++++++++++ test/test.js | 1 + 7 files changed, 294 insertions(+), 35 deletions(-) create mode 100644 HOOKS.md create mode 100644 lib/core/scripts.js create mode 100644 test/core/scripts.js diff --git a/HOOKS.md b/HOOKS.md new file mode 100644 index 000000000..7022b7607 --- /dev/null +++ b/HOOKS.md @@ -0,0 +1,21 @@ +# Install and Uninstall Hooks + +Bower provides 3 separate hooks that can be used to trigger other automated tools during Bower usage. Importantly, these hooks are intended to allow external tools to help wire up the newly installed components into the parent project and other similar tasks. These hooks are not intended to provide a post-installation build step for component authors. As such, the configuration for these hooks is provided in the `.bowerrc` file in the parent project's directory. + +## Configuring + +In `.bowerrc` do: + +```js +{ + "scripts": { + "preinstall": "", + "postinstall": "", + "preuninstall": "" + } +} +``` + +The value of each script hook may contain a % character. When your script is called, the % will be replaced with a space-separated list of components being installed or uninstalled. + +Your script will also include an environment variable `BOWER_PID` containing the PID of the parent Bower process that triggered the script. This can be used to verify that a `preinstall` and `postinstall` steps are part of the same Bower process. \ No newline at end of file diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 2f6e9978b..c12c5fd1a 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -9,6 +9,7 @@ var PackageRepository = require('./PackageRepository'); var semver = require('../util/semver'); var copy = require('../util/copy'); var createError = require('../util/createError'); +var scripts = require('./scripts'); function Manager(config, logger) { this._config = config; @@ -108,7 +109,7 @@ Manager.prototype.resolve = function () { }.bind(this)); }; -Manager.prototype.install = function () { +Manager.prototype.install = function (json) { var componentsDir; var that = this; @@ -124,6 +125,9 @@ Manager.prototype.install = function () { componentsDir = path.join(this._config.cwd, this._config.directory); return Q.nfcall(mkdirp, componentsDir) + .then(function () { + return scripts.preinstall(that._config, that._logger, that._dissected, that._installed, json); + }) .then(function () { var promises = []; @@ -165,6 +169,9 @@ Manager.prototype.install = function () { return Q.all(promises); }) + .then(function () { + return scripts.postinstall(that._config, that._logger, that._dissected, that._installed, json); + }) .then(function () { // Sync up dissected dependencies and dependants // See: https://github.com/bower/bower/issues/879 diff --git a/lib/core/Project.js b/lib/core/Project.js index 9a99c1dce..4e44b403c 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -13,6 +13,7 @@ var md5 = require('../util/md5'); var createError = require('../util/createError'); var readJson = require('../util/readJson'); var validLink = require('../util/validLink'); +var scripts = require('./scripts'); function Project(config, logger) { // This is the only architecture component that ensures defaults @@ -524,7 +525,7 @@ Project.prototype._bootstrap = function (targets, resolved, incompatibles) { } }.bind(this)) // Install resolved ones - .then(this._manager.install.bind(this._manager)); + .then(this._manager.install.bind(this._manager, this._json)); }; Project.prototype._readJson = function () { @@ -677,43 +678,47 @@ Project.prototype._removePackages = function (packages) { var that = this; var promises = []; - mout.object.forOwn(packages, function (dir, name) { - var promise; + return scripts.preuninstall(that._config, that._logger, packages, that._installed, that._json) + .then(function () { - // Delete directory - if (!dir) { - promise = Q.resolve(); - that._logger.warn('not-installed', name, { - name: name - }); - } else { - promise = Q.nfcall(rimraf, dir); - that._logger.action('uninstall', name, { - name: name, - dir: dir - }); - } + mout.object.forOwn(packages, function (dir, name) { + var promise; - // Remove from json only if successfully deleted - if (that._options.save && that._json.dependencies) { - promise = promise - .then(function () { - delete that._json.dependencies[name]; - }); - } + // Delete directory + if (!dir) { + promise = Q.resolve(); + that._logger.warn('not-installed', name, { + name: name + }); + } else { + promise = Q.nfcall(rimraf, dir); + that._logger.action('uninstall', name, { + name: name, + dir: dir + }); + } - if (that._options.saveDev && that._json.devDependencies) { - promise = promise - .then(function () { - delete that._json.devDependencies[name]; - }); - } + // Remove from json only if successfully deleted + if (that._options.save && that._json.dependencies) { + promise = promise + .then(function () { + delete that._json.dependencies[name]; + }); + } - promises.push(promise); - }); + if (that._options.saveDev && that._json.devDependencies) { + promise = promise + .then(function () { + delete that._json.devDependencies[name]; + }); + } - return Q.all(promises) - // Save json + promises.push(promise); + }); + + return Q.all(promises); + + }) .then(function () { return that.saveJson(); }) diff --git a/lib/core/scripts.js b/lib/core/scripts.js new file mode 100644 index 000000000..0d5eeaba9 --- /dev/null +++ b/lib/core/scripts.js @@ -0,0 +1,96 @@ +var mout = require('mout'); +var cmd = require('../util/cmd'); +var Q = require('q'); +var shellquote = require('shell-quote'); + +var orderByDependencies = function (packages, installed, json) { + var ordered = []; + installed = mout.object.keys(installed); + + var depsSatisfied = function (packageName) { + return mout.array.difference(mout.object.keys(packages[packageName].dependencies), installed, ordered).length === 0; + }; + + var depsFromBowerJson = json && json.dependencies ? mout.object.keys(json.dependencies) : []; + var packageNames = mout.object.keys(packages); + + //get the list of the packages that are specified in bower.json in that order + //its nice to maintain that order for users + var desiredOrder = mout.array.intersection(depsFromBowerJson, packageNames); + //then add to the end any remaining packages that werent in bower.json + desiredOrder = desiredOrder.concat(mout.array.difference(packageNames, desiredOrder)); + + //the desired order isn't necessarily a correct dependency specific order + //so we ensure that below + var resolvedOne = true; + while (resolvedOne) { + + resolvedOne = false; + + for (var i = 0; i < desiredOrder.length; i++) { + var packageName = desiredOrder[i]; + if (depsSatisfied(packageName)) { + ordered.push(packageName); + mout.array.remove(desiredOrder, packageName); + //as soon as we resolve a package start the loop again + resolvedOne = true; + break; + } + } + + if (!resolvedOne && desiredOrder.length > 0) { + //if we're here then some package(s) doesn't have all its deps satisified + //so lets just jam those names on the end + ordered = ordered.concat(desiredOrder); + } + + } + + return ordered; +}; + +var run = function (cmdString, action, logger, config) { + logger.action(action, cmdString); + + //pass env + BOWER_PID so callees can identify a preinstall+postinstall from the same bower instance + var env = mout.object.mixIn({ 'BOWER_PID': process.pid }, process.env); + var args = shellquote.parse(cmdString, env); + var cmdName = args[0]; + mout.array.remove(args, cmdName); //no rest() in mout + + var options = { + cwd: config.cwd, + env: env + }; + + var promise = cmd(cmdName, args, options); + + promise.progress(function (progress) { + progress.split('\n').forEach(function (line) { + if (line) { + logger.action(action, line); + } + }); + }); + + return promise; +}; + +var hook = function (action, ordered, config, logger, packages, installed, json) { + if (mout.object.keys(packages).length === 0 || !config.scripts || !config.scripts[action]) { + /*jshint newcap: false */ + return Q(); + } + + var orderedPackages = ordered ? orderByDependencies(packages, installed, json) : mout.object.keys(packages); + var cmdString = mout.string.replace(config.scripts[action], '%', orderedPackages.join(' ')); + return run(cmdString, action, logger, config); +}; + +module.exports = { + preuninstall: mout.function.partial(hook, 'preuninstall', false), + preinstall: mout.function.partial(hook, 'preinstall', true), + postinstall: mout.function.partial(hook, 'postinstall', true), + //only exposed for test + _orderByDependencies: orderByDependencies +}; \ No newline at end of file diff --git a/package.json b/package.json index 433e337ac..2fd25f073 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,8 @@ "which": "~1.0.5", "p-throttler": "~0.0.1", "insight": "~0.3.0", - "is-root": "~0.1.0" + "is-root": "~0.1.0", + "shell-quote": "~1.4.1" }, "devDependencies": { "expect.js": "~0.2.0", diff --git a/test/core/scripts.js b/test/core/scripts.js new file mode 100644 index 000000000..20eb2813c --- /dev/null +++ b/test/core/scripts.js @@ -0,0 +1,128 @@ +var path = require('path'); +var bower = require('../../lib/index.js'); +var mkdirp = require('mkdirp'); +var rimraf = require('rimraf'); +var fs = require('fs'); +var expect = require('expect.js'); +var scripts = require('../../lib/core/scripts.js'); + +describe('scripts', function () { + + var tempDir = path.join(__dirname, '../assets/temp-scripts'); + var packageName = 'package-zip'; + var packageDir = path.join('..', packageName + '.zip'); + + var config = { + cwd: tempDir, + scripts: { + preinstall: 'touch preinstall_%', + postinstall: 'touch postinstall_%', + preuninstall: 'touch preuninstall_%' + } + }; + + before(function (next) { + mkdirp(tempDir, next); + }); + + after(function (next) { + rimraf(tempDir, next); + }); + + it('should run preinstall and postinstall hooks.', function (next) { + + bower.commands + .install([packageDir], undefined, config) + .on('end', function (installed) { + + expect(fs.existsSync(path.join(tempDir, 'preinstall_' + packageName))).to.be(true); + expect(fs.existsSync(path.join(tempDir, 'postinstall_' + packageName))).to.be(true); + + next(); + }); + + }); + + it('should run preuninstall hook.', function (next) { + + bower.commands + .uninstall([packageName], undefined, config) + .on('end', function (installed) { + + expect(fs.existsSync(path.join(tempDir, 'preuninstall_' + packageName))).to.be(true); + + next(); + }); + + }); + + it('should not break anything when no hooks configured.', function (next) { + + bower.commands + .uninstall([packageName], undefined, { cwd: tempDir }) + .on('end', function (installed) { + + //no exception then we're good + + next(); + }); + + }); + + it('should reorder packages by dependencies, while trying to maintain order from bower.json, correctly.', function () { + + var mockAngularUI = { dependencies: { + 'angular': '*' + }}; + var mockJQuery = { dependencies: { + }}; + var mockAngular = { dependencies: { + 'jquery': '*' + }}; + var mockMoment = { dependencies: { + }}; + var mockSelect2 = { dependencies: { + 'jquery': '*' + }}; + var mockBadPackage = { dependencies: { + 'something-not-installed': '*' + }}; + + var packages = { + 'select2': mockSelect2, + 'angular-ui': mockAngularUI, + 'jquery': mockJQuery, + 'bad-package': mockBadPackage, + 'angular': mockAngular, + 'moment': mockMoment + }; + var installed = []; + var mockBowerJson = { dependencies: { + 'jquery': '*', + 'select2': '*', + 'angular-ui': '*', + 'angular': '*', + 'moment': '*' + } }; + + var ordered = scripts._orderByDependencies(packages, installed, mockBowerJson); + expect(ordered).to.eql(['jquery', 'select2', 'angular', 'angular-ui', 'moment', 'bad-package']); + + }); + + it('should process scripts with quotes and vars in the cmd properly.', function (next) { + + config.scripts.preinstall = 'touch "$BOWER_PID %"'; + + bower.commands + .install([packageDir], undefined, config) + .on('end', function (installed) { + + expect(fs.existsSync(path.join(tempDir, process.pid + ' ' + packageName))).to.be(true); + + next(); + }); + + }); + +}); \ No newline at end of file diff --git a/test/test.js b/test/test.js index f020f6435..c4d1ca400 100644 --- a/test/test.js +++ b/test/test.js @@ -15,3 +15,4 @@ require('./core/resolvers/gitHubResolver'); require('./core/resolverFactory'); require('./core/resolveCache'); require('./core/packageRepository'); +require('./core/scripts'); \ No newline at end of file From ad31df09fb8e6f0b632a235f1f037425089f169f Mon Sep 17 00:00:00 2001 From: Sergey Tatarintsev Date: Sat, 8 Feb 2014 12:28:14 +0200 Subject: [PATCH 0306/1021] Allow circular dependencies to be installed --- lib/core/Manager.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 2f6e9978b..8ebda0d2e 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -194,11 +194,13 @@ Manager.prototype.install = function () { }.bind(this)); }; -Manager.prototype.toData = function (decEndpoint, extraKeys) { +Manager.prototype.toData = function (decEndpoint, extraKeys, upperDeps) { var names; var extra; var data = {}; + + upperDeps = upperDeps || []; data.endpoint = mout.object.pick(decEndpoint, ['name', 'source', 'target']); if (decEndpoint.canonicalDir) { @@ -221,7 +223,14 @@ Manager.prototype.toData = function (decEndpoint, extraKeys) { // by dependency names names = Object.keys(decEndpoint.dependencies).sort(); names.forEach(function (name) { - data.dependencies[name] = this.toData(decEndpoint.dependencies[name], extraKeys); + + // Prevent from infinite recursion when installing cyclic + // dependencies + if (!mout.array.contains(upperDeps, name)) { + data.dependencies[name] = this.toData(decEndpoint.dependencies[name], + extraKeys, + upperDeps.concat(decEndpoint.name)); + } }, this); } From 8016bd4e1fb6d9de5afaf0b4a63deb353133284a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Berg=C3=A9?= Date: Thu, 13 Feb 2014 16:30:39 +0100 Subject: [PATCH 0307/1021] Use `new Q()` shortcut. --- lib/core/ResolveCache.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/core/ResolveCache.js b/lib/core/ResolveCache.js index f712fa1a9..ed56ce613 100644 --- a/lib/core/ResolveCache.js +++ b/lib/core/ResolveCache.js @@ -128,9 +128,7 @@ ResolveCache.prototype.store = function (canonicalDir, pkgMeta) { }); } else { - var defer = Q.defer(); - defer.resolve(); - checkExistingDirectory = defer.promise; + checkExistingDirectory = new Q(); } return checkExistingDirectory From 83f1edb9da4e28c2d422a7a2404845458e5b7a27 Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Thu, 13 Feb 2014 15:49:25 -0800 Subject: [PATCH 0308/1021] Move @necolas out of core team --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d7b46d2e..4c805ef8f 100644 --- a/README.md +++ b/README.md @@ -362,7 +362,6 @@ review the [guidelines for contributing](CONTRIBUTING.md). * [@satazor](https://github.com/satazor) * [@wibblymat](https://github.com/wibblymat) -* [@necolas](https://github.com/necolas) * [@paulirish](https://github.com/paulirish) * [@benschwarz](https://github.com/benschwarz) * [@sindresorhus](https://github.com/sindresorhus) @@ -388,6 +387,7 @@ Thanks for assistance and contributions: [@marcooliveira](https://github.com/marcooliveira), [@mklabs](https://github.com/mklabs), [@MrDHat](https://github.com/MrDHat), +[@necolas](https://github.com/necolas), [@richo](https://github.com/richo), [@rvagg](https://github.com/rvagg), [@ryanflorence](https://github.com/ryanflorence), From 72578e49dd8a2a40adea6dec549d8748fe7666ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renan=20Gon=C3=A7alves?= Date: Mon, 17 Feb 2014 22:30:45 +0100 Subject: [PATCH 0309/1021] update changelog #1122 --- CHANGELOG.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ce1ab48b..4872bf4d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,24 @@ # Changelog -##1.2.8 - 2013-12-02 +## master + +- Add `moduleType` property to bower init ([#934](https://github.com/bower/bower/pull/934)) +- Fix prune command to log only after cleanup is completed ([#1023](https://github.com/bower/bower/issues/1023)) +- Fix git resolver to ignore pre-release versions ([#1017](https://github.com/bower/bower/issues/1017)) +- Fix shorthand flag for `save` option on `uninstall` command ([#1031](https://github.com/bower/bower/pull/1031)) +- Add `bower version` command ([#961](https://github.com/bower/bower/pull/961)) +- Make `--save` option default when using `bower install` commnand ([#1074](https://github.com/bower/bower/pull/1074)) +- Fix git resolver caching ([#1083](https://github.com/bower/bower/issues/1083)) +- Fix reading versions from cache directory ([#1076](https://github.com/bower/bower/pull/1076)) +- Add svn support ([#1055](https://github.com/bower/bower/pull/1055)) +- Allow circular dependencies to be installed ([#1104](https://github.com/bower/bower/pull/1104)) +- Add scripts/hooks support ([#718](https://github.com/bower/bower/pull/718)) + +_NOTE_: It's advisable that users use `--config.interactive=false` on automated scripts. + + +## 1.2.8 - 2013-12-02 - Fix absolute paths ending with / not going through the FsResolver, ([#898](https://github.com/bower/bower/issues/898)) - Allow query string parameters in package URLs - Swapped 'unzip' module for 'decompress-zip', and some other small unzipping fixes([#873](https://github.com/bower/bower/issues/873), [#896](https://github.com/bower/bower/issues/896)) @@ -10,7 +27,6 @@ - Fix a bug caused by a recent change to semver - ## 1.2.7 - 2013-09-29 - Do not swallow sync errors when using the programmatic API ([#849](https://github.com/bower/bower/issues/849)) From cc63a633b5da6afe2d817e88b483f447f72fd630 Mon Sep 17 00:00:00 2001 From: Michael McLellan Date: Tue, 18 Feb 2014 17:13:04 -0500 Subject: [PATCH 0310/1021] Suppress end output if quiet option is specified --- bin/bower | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/bower b/bin/bower index 31ae6c95c..9c332b412 100755 --- a/bin/bower +++ b/bin/bower @@ -105,7 +105,7 @@ analytics.setup().then(function () { logger .on('end', function (data) { - if (!bower.config.silent) { + if (!bower.config.silent && !bower.config.quiet) { renderer.end(data); } }) From 88dbbe7bc338487549fa095b05724a1fab8a5b54 Mon Sep 17 00:00:00 2001 From: Paul Irish Date: Mon, 24 Feb 2014 14:03:51 -0800 Subject: [PATCH 0311/1021] changelog. master --> canary. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4872bf4d6..f40832b7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog -## master +## 1.3.0 (canary) - Add `moduleType` property to bower init ([#934](https://github.com/bower/bower/pull/934)) - Fix prune command to log only after cleanup is completed ([#1023](https://github.com/bower/bower/issues/1023)) From 523cd421b3731dea274c4287a4d6d6704686b194 Mon Sep 17 00:00:00 2001 From: Paul Irish Date: Mon, 24 Feb 2014 14:05:01 -0800 Subject: [PATCH 0312/1021] changelog update for permalink. --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f40832b7c..7da6c0e54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # Changelog -## 1.3.0 (canary) +## master +#### Available in `bower-canary`'s 1.3.0 - Add `moduleType` property to bower init ([#934](https://github.com/bower/bower/pull/934)) - Fix prune command to log only after cleanup is completed ([#1023](https://github.com/bower/bower/issues/1023)) From 4450cce0e935c7fdc0845666aa5a1b20a07f7d2d Mon Sep 17 00:00:00 2001 From: Chris Rebert Date: Mon, 24 Feb 2014 14:35:36 -0800 Subject: [PATCH 0313/1021] spelling fixes in changelog --- CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7da6c0e54..6a4cf4ba0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ - Fix git resolver to ignore pre-release versions ([#1017](https://github.com/bower/bower/issues/1017)) - Fix shorthand flag for `save` option on `uninstall` command ([#1031](https://github.com/bower/bower/pull/1031)) - Add `bower version` command ([#961](https://github.com/bower/bower/pull/961)) -- Make `--save` option default when using `bower install` commnand ([#1074](https://github.com/bower/bower/pull/1074)) +- Make `--save` option default when using `bower install` command ([#1074](https://github.com/bower/bower/pull/1074)) - Fix git resolver caching ([#1083](https://github.com/bower/bower/issues/1083)) - Fix reading versions from cache directory ([#1076](https://github.com/bower/bower/pull/1076)) - Add svn support ([#1055](https://github.com/bower/bower/pull/1055)) @@ -23,7 +23,7 @@ _NOTE_: It's advisable that users use `--config.interactive=false` on automated - Fix absolute paths ending with / not going through the FsResolver, ([#898](https://github.com/bower/bower/issues/898)) - Allow query string parameters in package URLs - Swapped 'unzip' module for 'decompress-zip', and some other small unzipping fixes([#873](https://github.com/bower/bower/issues/873), [#896](https://github.com/bower/bower/issues/896)) -- Allow the root-check to be overidden when calling bower programmatically. +- Allow the root-check to be overridden when calling bower programmatically. - Fixed some bugs relating to packages with a very large dependency tree - Fix a bug caused by a recent change to semver @@ -106,7 +106,7 @@ _NOTE_: It's advisable that users run `bower cache clean`. - Ignore `component.json` if it looks like a component(1) file ([#556](https://github.com/bower/bower/issues/556)) - Fix multi-user usage on bower when it creates temporary directories to hold some files - Fix prompting causing an invalid JSON output when running commands with `--json` -- When running Bower commands programmatically, prompting is now disabled by default (see the updated progammatic [usage](https://github.com/bower/bower#programmatic-api) for more info) +- When running Bower commands programmatically, prompting is now disabled by default (see the updated programmatic [usage](https://github.com/bower/bower#programmatic-api) for more info) - Other minor improvements and fixes Fix for `#788` requires installed components to be re-installed. @@ -168,7 +168,7 @@ Fix for `#788` requires installed components to be re-installed. - Fix `Bower` not working when calling `.bat`/`.cmd` commands on Windows; it affected people using `Git portable` ([#626](https://github.com/bower/bower/issues/626)) - Fix `bower list --paths` not resolving all files to absolute paths when the `main` property contained multiple files ([660](https://github.com/bower/bower/issues/660)) - Fix `Bower` renaming `bower.json` and `component.json` files to `index.json` when it was the only file in the folder ([#674](https://github.com/bower/bower/issues/674)) -- Ignore symlinks when copying/extracting since they are not portable, specially accross different hard-drives ([#665](https://github.com/bower/bower/issues/665)) +- Ignore symlinks when copying/extracting since they are not portable, specially across different hard-drives ([#665](https://github.com/bower/bower/issues/665)) - Local file/dir endpoints are now exclusively referenced by an absolute path or relative path starting with `.` ([#666](https://github.com/bower/bower/issues/666)) - Linked packages `bower.json` files are now parsed, making `bower list` account linked packages dependencies ([#659](https://github.com/bower/bower/issues/659)) - Bower now fails to run with sudo unless `--allow-root` is passed ([#498](https://github.com/bower/bower/issues/498)) @@ -332,7 +332,7 @@ _NOTE_: The `components` folder will still be used if already created, making it ## 0.6.1 - 2012-11-22 - Fix uninstall when the project component.json has no deps saved ([#153](https://github.com/bower/bower/issues/153)) -- Fix uncaught errors when using file writter (they are now caught and reported) +- Fix uncaught errors when using file writer (they are now caught and reported) - Fix temporary directories not being deleted when an exception occurs ([#153](https://github.com/bower/bower/issues/140)) ## 0.6.0 - 2012-11-21 From 20c0e6e12be76211aefea7209a0433393b6559b6 Mon Sep 17 00:00:00 2001 From: Thomas Scholtes Date: Tue, 25 Feb 2014 19:53:50 +0100 Subject: [PATCH 0314/1021] Use same mout version as bower We don't need to load mout twice, which takes a lot of time. --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 9a42bb6e5..297f5f4ee 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "graceful-fs": "~2.0.0", - "mout": "~0.6.0", + "mout": "~0.9.0", "optimist": "~0.6.0", "osenv": "0.0.3" }, From 1f9a92e6adb774183853685ccbd83fc8d86aa5e2 Mon Sep 17 00:00:00 2001 From: Thomas Scholtes Date: Wed, 26 Feb 2014 15:38:10 +0100 Subject: [PATCH 0315/1021] Use the same version of bower-config as bower Make loading this package from bower faster. Used `>=` to specify version so it doesn't break that fast when bower starts using a version `>=0.6.0`. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index fce4ec2f1..c38a0a243 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "async": "~0.2.8", - "bower-config": "~0.4.3", + "bower-config": ">=0.5.0", "graceful-fs": "~2.0.0", "lru-cache": "~2.3.0", "request": "~2.27.0", From a5c49d89d58f455dd0d19a5671ef8fea7d5bb010 Mon Sep 17 00:00:00 2001 From: Thomas Scholtes Date: Thu, 27 Feb 2014 00:26:34 +0100 Subject: [PATCH 0316/1021] Use tilde to match bower-config version --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index c38a0a243..845e84350 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "async": "~0.2.8", - "bower-config": ">=0.5.0", + "bower-config": "~0.5.0", "graceful-fs": "~2.0.0", "lru-cache": "~2.3.0", "request": "~2.27.0", From b049bdb33f7b3e76b6b35c9315ea728387d49be6 Mon Sep 17 00:00:00 2001 From: jevakallio Date: Thu, 27 Feb 2014 17:31:01 +0200 Subject: [PATCH 0317/1021] Fix problem with dashes and underscores in branch/tag names --- lib/core/resolvers/SvnResolver.js | 59 +++++++++++++----------------- test/core/resolvers/svnResolver.js | 33 ++++++++++++++++- 2 files changed, 57 insertions(+), 35 deletions(-) diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js index aab19728a..1c0c8060f 100644 --- a/lib/core/resolvers/SvnResolver.js +++ b/lib/core/resolvers/SvnResolver.js @@ -340,25 +340,11 @@ SvnResolver.tags = function (source) { value = cmd('svn', ['list', source + '/tags', '--verbose']) .spread(function (stout) { - var tags = {}; - - var lines = stout.toString() - .trim() - .split(/[\r\n]+/); - - // For each line in the refs, match only the tags - lines.forEach(function (line) { - - var match = line.match(/\s+([0-9]+)\s.+\s([a-z0-9.]+)\//i); - - if (match && match[2] !== '.') { - tags[match[2]] = match[1]; - } - }); + var tags = SvnResolver.parseSubversionListOutput(stout.toString()); this._cache.tags.set(source, tags); - return tags; + }.bind(this)); // Store the promise to be reused until it resolves @@ -379,28 +365,14 @@ SvnResolver.branches = function (source) { value = cmd('svn', ['list', source + '/branches', '--verbose']) .spread(function (stout) { - // trunk is a branch! - var branches = { - 'trunk': '*' - }; - - var lines = stout.toString() - .trim() - .split(/[\r\n]+/); - - // For each line in the refs, match only the banches - lines.forEach(function (line) { + var branches = SvnResolver.parseSubversionListOutput(stout.toString()); - var match = line.match(/\s+([0-9]+)\s.+\s([a-z0-9.]+)\//i); - - if (match && match[2] !== '.') { - branches[match[2]] = match[1]; - } - }); + // trunk is a branch! + branches.trunk = '*'; this._cache.branches.set(source, branches); - return branches; + }.bind(this)); // Store the promise to be reused until it resolves @@ -410,6 +382,25 @@ SvnResolver.branches = function (source) { return value; }; +SvnResolver.parseSubversionListOutput = function (stout) { + + var entries = {}; + var lines = stout + .trim() + .split(/[\r\n]+/); + + // For each line in the refs, match only the branches + lines.forEach(function (line) { + var match = line.match(/\s+([0-9]+)\s.+\s([\w.$-]+)\//i); + + if (match && match[2] !== '.') { + entries[match[2]] = match[1]; + } + }); + + return entries; +}; + SvnResolver.clearRuntimeCache = function () { // Reset cache for branches, tags, etc mout.object.forOwn(SvnResolver._cache, function (lru) { diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index a1c9eee38..98c44c901 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -1061,6 +1061,34 @@ describe('SvnResolver', function () { }); }); + describe('#parseSubversionListOutput', function () { + + var list = [ + ' 12345 username Jan 1 12:34 ./', + ' 12346 username Feb 2 12:34 branch-name/', + ' 12347 username Mar 3 12:34 branch_name/', + ' 12348 username Apr 4 12:34 branch.1.2.3/', + ' 12349 username Jun 5 12:34 BranchName/' + ].join('\r\n'); + + it('should not include the . (dot)path', function () { + var actual = SvnResolver.parseSubversionListOutput(list); + + expect(actual).to.not.have.keys('.'); + }); + + it('should parse path names with alphanumerics, dashes, dots and underscores', function () { + var actual = SvnResolver.parseSubversionListOutput(list); + + expect(actual).to.eql({ + 'branch-name' : '12346', + 'branch_name' : '12347', + 'branch.1.2.3' : '12348', + 'BranchName' : '12349' + }); + }); + }); + // remote resolver tests describe('.constructor', function () { it('should guess the name from the path', function () { @@ -1107,6 +1135,9 @@ describe('SvnResolver', function () { }) .done(); }); - }); + + + + }); From 3d7b9f60da04229b9937cbe6a37645bee582489a Mon Sep 17 00:00:00 2001 From: Brian Donovan Date: Tue, 4 Mar 2014 15:38:46 -0800 Subject: [PATCH 0318/1021] Fix a typo in the regex trying to understand the command. This is almost certainly not trying to replace 's' characters in a command and is, instead, meant to check for nested properties on bower.commands that were not found in bower.abbreviations for some reason. The kicker is that bower.abbreviations already contains the full command names in addition to the shortened ones, so this code path ("Direct lookup") probably never actually results in finding anything and can probably safely be removed. --- bin/bower | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/bower b/bin/bower index 31ae6c95c..ac59806d6 100755 --- a/bin/bower +++ b/bin/bower @@ -62,7 +62,7 @@ while (options.argv.remain.length) { break; } - command = command.replace(/s/g, '.'); + command = command.replace(/\s/g, '.'); // Direct lookup if (mout.object.has(bower.commands, command)) { From 09bc1784e411ebf5743e8c0ba2251fdec78740fe Mon Sep 17 00:00:00 2001 From: Ahmad Nassri Date: Wed, 5 Mar 2014 13:51:43 -0500 Subject: [PATCH 0319/1021] Fixing svnResolver tests - duplicate 0.0.1 tag in json config - `svn list` return directory separator at the end of branch/tag names --- test/packages-svn.js | 4 ++-- test/packages-svn.json | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/test/packages-svn.js b/test/packages-svn.js index 47567d999..a862aab9c 100644 --- a/test/packages-svn.js +++ b/test/packages-svn.js @@ -64,7 +64,7 @@ function checkRelease(dir, release) { if (semver.valid(release)) { return cmd('svn', ['list', 'tags'], { cwd: dir }) .spread(function (stdout) { - return stdout.split(/\s*\r*\n\s*/).some(function (tag) { + return stdout.split(/\/\s*\r*\n\s*/).some(function (tag) { return semver.clean(tag) === release; }); }); @@ -72,7 +72,7 @@ function checkRelease(dir, release) { return cmd('svn', ['list', 'branches'], { cwd: dir }) .spread(function (stdout) { - return stdout.split(/\s*\r*\n\s*/).some(function (branch) { + return stdout.split(/\/\s*\r*\n\s*/).some(function (branch) { branch = branch.trim().replace(/^\*?\s*/, ''); return branch === release; }); diff --git a/test/packages-svn.json b/test/packages-svn.json index 1738cbeb0..ceb396290 100644 --- a/test/packages-svn.json +++ b/test/packages-svn.json @@ -1,9 +1,5 @@ { "package-svn": { - "0.0.1": { - "README.md": "", - "foo": "foo" - }, "0.0.1": { "README.md": "", "foo": "foo" From cea53ddd1f17ee741f86f1ae4d3cc5e8c80fd7e2 Mon Sep 17 00:00:00 2001 From: Ahmad Nassri Date: Thu, 6 Mar 2014 16:33:38 +0100 Subject: [PATCH 0320/1021] Remove Node 0.8 compatibility. Closes #1154 --- .travis.yml | 1 - package.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3d82b846e..9e5cd30fc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: node_js node_js: - "0.10" - - "0.8" before_script: - npm install grunt-cli -g diff --git a/package.json b/package.json index 2fd25f073..3f5f8d256 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "main": "lib", "homepage": "http://bower.io", "engines": { - "node": ">=0.8.0" + "node": ">=0.10.0" }, "dependencies": { "abbrev": "~1.0.4", From 76fcd341f615f32d50e6052a929ebb454fa056e3 Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Mon, 10 Mar 2014 21:27:56 +0000 Subject: [PATCH 0321/1021] Release 1.3.0 --- CHANGELOG.md | 10 +++++----- package.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a4cf4ba0..0c993a0a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,15 @@ # Changelog -## master -#### Available in `bower-canary`'s 1.3.0 +## 1.3.0 - 2014-03-10 +- **Removed support for node 0.8.** It may still work but we will no longer fix bugs for older versions of node. - Add `moduleType` property to bower init ([#934](https://github.com/bower/bower/pull/934)) - Fix prune command to log only after cleanup is completed ([#1023](https://github.com/bower/bower/issues/1023)) - Fix git resolver to ignore pre-release versions ([#1017](https://github.com/bower/bower/issues/1017)) - Fix shorthand flag for `save` option on `uninstall` command ([#1031](https://github.com/bower/bower/pull/1031)) - Add `bower version` command ([#961](https://github.com/bower/bower/pull/961)) -- Make `--save` option default when using `bower install` command ([#1074](https://github.com/bower/bower/pull/1074)) +- Add .bowerrc option to use `--save` by default when using `bower install` command ([#1074](https://github.com/bower/bower/pull/1074)) - Fix git resolver caching ([#1083](https://github.com/bower/bower/issues/1083)) - Fix reading versions from cache directory ([#1076](https://github.com/bower/bower/pull/1076)) - Add svn support ([#1055](https://github.com/bower/bower/pull/1055)) @@ -181,7 +181,7 @@ Fix for `#788` requires installed components to be re-installed. ## 1.0.0 - 2013-07-23 Total rewrite of bower. -The list bellow highlights the most important stuff. +The list bellow highlights the most important stuff. For a complete list of changes that this rewrite and release brings please read: https://github.com/bower/bower/wiki/Rewrite-state @@ -204,7 +204,7 @@ Non-backwards compatible changes: - `--map` and `--sources` from the list command were removed, use `--json` instead - Programmatic usage changed, specially the commands interface -Users upgrading from `bower-canary` and `bower@~0.x.x` should do a `bower cache clean`. +Users upgrading from `bower-canary` and `bower@~0.x.x` should do a `bower cache clean`. Additionally you may remove the `~/.bower` folder manually since it's no longer used. On Windows the folder is located in `AppData/bower`. diff --git a/package.json b/package.json index 3f5f8d256..e94cfded9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.2.8", + "version": "1.3.0", "description": "The browser package manager.", "author": "Twitter", "licenses": [ From dfae97a8d740f062852cd0655fdae37b056ffe09 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Tue, 11 Mar 2014 13:35:20 -0400 Subject: [PATCH 0322/1021] Don't turn on analytics on CI unless explicit --- lib/config.js | 3 ++- lib/util/analytics.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/config.js b/lib/config.js index 1a665c6b8..e3d315bdf 100644 --- a/lib/config.js +++ b/lib/config.js @@ -15,7 +15,8 @@ if (config.interactive == null) { // If `analytics` hasn't been explicitly set, we disable // it when ran programatically. if (config.analytics == null) { - config.analytics = config.interactive; + // Don't enable analytics on CI server unless explicitly configured. + config.analytics = config.interactive && !process.env.CI; } // Merge common CLI options into the config diff --git a/lib/util/analytics.js b/lib/util/analytics.js index 023858b65..87d1bf69e 100644 --- a/lib/util/analytics.js +++ b/lib/util/analytics.js @@ -18,8 +18,8 @@ analytics.setup = function setup() { }); // Display the ask prompt only if it hasn't been answered before - // and the current session is interactive. - if (insight.optOut === undefined && config.interactive) { + // and the current session is looking to configure the analytics. + if (insight.optOut === undefined && config.analytics) { insight.askPermission(null, deferred.resolve); } else { deferred.resolve(); From a19ad6663c7393fc1a97b3bb241f65851bc13352 Mon Sep 17 00:00:00 2001 From: Paul Irish Date: Tue, 11 Mar 2014 13:52:35 -0700 Subject: [PATCH 0323/1021] insight in changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c993a0a2..bd3175add 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ ## 1.3.0 - 2014-03-10 - **Removed support for node 0.8.** It may still work but we will no longer fix bugs for older versions of node. +- Add **Bower Insight** for opt-in analytics integration to help improve tool and gain insight on community trends + - Old overview of [Insight](https://github.com/yeoman/yeoman/wiki/Insight), [Issue #260](https://github.com/bower/bower/issues/260) + - Reporting to GA. Public Dashboard is in progress. + - [Turn off interactive mode](https://github.com/bower/bower/issues/1162) if you run Bower in a CI environment - Add `moduleType` property to bower init ([#934](https://github.com/bower/bower/pull/934)) - Fix prune command to log only after cleanup is completed ([#1023](https://github.com/bower/bower/issues/1023)) - Fix git resolver to ignore pre-release versions ([#1017](https://github.com/bower/bower/issues/1017)) From 6b9b2831497060fc90b3b484607b35f6c70d904d Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Tue, 11 Mar 2014 19:02:43 -0400 Subject: [PATCH 0324/1021] Add CI server configuration notes --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 4c805ef8f..ff11d7eeb 100644 --- a/README.md +++ b/README.md @@ -179,6 +179,11 @@ The current spec can be read [here](https://docs.google.com/document/d/1APq7oA9tNao1UYWyOm8dKqlRP2blVkROYLZ2fLIjtWc/edit#heading=h.4pzytc1f9j8k) in the `Configuration` section. +## Running on a continuous integration server + +Bower will skip some interactive and analytics operations if it finds a `CI` environmental variable set to `true`. You will find that the `CI` variable is already set for you on many continuous integration servers, e.g., [CircleCI](https://circleci.com/docs/environment-variables#basics) and [Travis-CI](http://docs.travis-ci.com/user/ci-environment/#Environment-variables). + +If you cannot set the `CI` flag, you may need to pass `--config.interactive=false` to the Bower CLI in your build scripts. ## Defining a package From 32a79c4fa158dcad7755fa8f528b1ff1508c09b0 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Tue, 11 Mar 2014 19:33:26 -0400 Subject: [PATCH 0325/1021] Add additional CI examples --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index ff11d7eeb..81ac3c0e9 100644 --- a/README.md +++ b/README.md @@ -183,8 +183,28 @@ in the `Configuration` section. Bower will skip some interactive and analytics operations if it finds a `CI` environmental variable set to `true`. You will find that the `CI` variable is already set for you on many continuous integration servers, e.g., [CircleCI](https://circleci.com/docs/environment-variables#basics) and [Travis-CI](http://docs.travis-ci.com/user/ci-environment/#Environment-variables). +You may try to set manually set `CI` variable manually before running your Bower commands. + +### Linux + +```bash +export CI=true +``` + +### Windows + +```bash +set CI=true +``` + +### Command line arguments + If you cannot set the `CI` flag, you may need to pass `--config.interactive=false` to the Bower CLI in your build scripts. +``` +bower install --config.interactive=false +``` + ## Defining a package You must create a `bower.json` in your project's root, and specify all of its From 630556f7fed05ac02b381e4089f346a50bb9e1ec Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Tue, 11 Mar 2014 23:39:39 +0000 Subject: [PATCH 0326/1021] Release 1.3.1 --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd3175add..70bce8997 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog +## 1.3.1 - 2014-03-10 +- No longer ask for permission to gather analytics when running on in a CI environment. + + ## 1.3.0 - 2014-03-10 - **Removed support for node 0.8.** It may still work but we will no longer fix bugs for older versions of node. diff --git a/package.json b/package.json index e94cfded9..7fcdab556 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.3.0", + "version": "1.3.1", "description": "The browser package manager.", "author": "Twitter", "licenses": [ From 2883a278ee8975765586bbb1203720037b8586c2 Mon Sep 17 00:00:00 2001 From: Ben Schwarz Date: Wed, 12 Mar 2014 10:58:41 +1100 Subject: [PATCH 0327/1021] Formatting tweaks to the CI section --- README.md | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 81ac3c0e9..3ceac8959 100644 --- a/README.md +++ b/README.md @@ -183,27 +183,11 @@ in the `Configuration` section. Bower will skip some interactive and analytics operations if it finds a `CI` environmental variable set to `true`. You will find that the `CI` variable is already set for you on many continuous integration servers, e.g., [CircleCI](https://circleci.com/docs/environment-variables#basics) and [Travis-CI](http://docs.travis-ci.com/user/ci-environment/#Environment-variables). -You may try to set manually set `CI` variable manually before running your Bower commands. +You may try to set manually set `CI` variable manually before running your Bower commands. On Mac or Linux, `export CI=true` and on Windows `set CI=true` -### Linux +### Interactive configuration -```bash -export CI=true -``` - -### Windows - -```bash -set CI=true -``` - -### Command line arguments - -If you cannot set the `CI` flag, you may need to pass `--config.interactive=false` to the Bower CLI in your build scripts. - -``` -bower install --config.interactive=false -``` +If for some reason you are unable to set the `CI` environment variable, you can alternately use the `--config.interactive=false` flag. (`bower install --config.interactive=false`) ## Defining a package From 9749a398c05a374d3cb9ec876ca9303b85de56dd Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Wed, 12 Mar 2014 18:36:40 +0100 Subject: [PATCH 0328/1021] Add --production switch to "prune" command --- lib/commands/list.js | 2 +- lib/commands/prune.js | 22 +++++++++++++--------- lib/commands/uninstall.js | 2 +- lib/core/Project.js | 4 +++- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/lib/commands/list.js b/lib/commands/list.js index 59eaee95f..5149f951b 100644 --- a/lib/commands/list.js +++ b/lib/commands/list.js @@ -21,7 +21,7 @@ function list(options, config) { config = mout.object.deepFillIn(config || {}, defaultConfig); project = new Project(config, logger); - project.getTree() + project.getTree(options) .spread(function (tree, flattened) { var baseDir = path.dirname(path.join(config.cwd, config.directory)); diff --git a/lib/commands/prune.js b/lib/commands/prune.js index 439b52346..0b77e8a81 100644 --- a/lib/commands/prune.js +++ b/lib/commands/prune.js @@ -4,14 +4,15 @@ var Project = require('../core/Project'); var cli = require('../util/cli'); var defaultConfig = require('../config'); -function prune(config) { +function prune(options, config) { var project; var logger = new Logger(); + options = options || {}; config = mout.object.deepFillIn(config || {}, defaultConfig); project = new Project(config, logger); - clean(project) + clean(project, options) .done(function (removed) { logger.emit('end', removed); }, function (error) { @@ -21,19 +22,19 @@ function prune(config) { return logger; } -function clean(project, removed) { +function clean(project, options, removed) { removed = removed || {}; // Continually call clean until there is no more extraneous // dependencies to remove - return project.getTree() + return project.getTree(options) .spread(function (tree, flattened, extraneous) { var names = extraneous.map(function (extra) { return extra.endpoint.name; }); // Uninstall extraneous - return project.uninstall(names) + return project.uninstall(names, options) .then(function (uninstalled) { // Are we done? if (!mout.object.size(uninstalled)) { @@ -42,19 +43,22 @@ function clean(project, removed) { // Not yet, recurse! mout.object.mixIn(removed, uninstalled); - return clean(project, removed); + return clean(project, options, removed); }); }); } // ------------------- -prune.line = function () { - return prune(); +prune.line = function (argv) { + var options = prune.options(argv); + return prune(options); }; prune.options = function (argv) { - return cli.readOptions(argv); + return cli.readOptions({ + 'production': { type: Boolean, shorthand: 'p' }, + }, argv); }; prune.completion = function () { diff --git a/lib/commands/uninstall.js b/lib/commands/uninstall.js index 6fce590ff..06f92f14f 100644 --- a/lib/commands/uninstall.js +++ b/lib/commands/uninstall.js @@ -18,7 +18,7 @@ function uninstall(names, options, config) { tracker.trackNames('uninstall', names); - project.getTree() + project.getTree(options) .spread(function (tree, flattened) { // Uninstall nodes return project.uninstall(names, options) diff --git a/lib/core/Project.js b/lib/core/Project.js index 4e44b403c..951289e26 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -307,7 +307,9 @@ Project.prototype.uninstall = function (names, options) { }); }; -Project.prototype.getTree = function () { +Project.prototype.getTree = function (options) { + this._options = options || {}; + return this._analyse() .spread(function (json, tree, flattened) { var extraneous = []; From 9895f8c71e4173635a90e23507b969b47c61b772 Mon Sep 17 00:00:00 2001 From: Andrey 'lolmaus' Mikhaylov Date: Fri, 14 Mar 2014 17:50:03 +0100 Subject: [PATCH 0329/1021] readme - links to the range syntax of version numbers closes #1172 --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ceac8959..9192c9613 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ Where `` can be any one of the following: ‡ These types of `` might have versions available. You can specify a [semver](http://semver.org/) compatible version to fetch a specific release, and lock the -package to that version. You can also use ranges to specify a range of versions. +package to that version. You can also specify a [range](https://github.com/isaacs/node-semver#ranges) of versions. If you are using a package that is a git endpoint, you may use any tag, commit SHA, or branch name as a version. For example: `#`. Using branches is not @@ -215,6 +215,8 @@ The `bower.json` defines several options: * `ignore` [array]: An array of paths not needed in production that you want Bower to ignore when installing your package. * `dependencies` [hash]: Packages your package depends upon in production. + Note that you can specify [ranges](https://github.com/isaacs/node-semver#ranges) + of versions for your dependencies. * `devDependencies` [hash]: Development dependencies. * `private` [boolean]: Set to true if you want to keep the package private and do not want to register the package in future. From bea533acf87903d4b411bfbaa7df93f852ef46a3 Mon Sep 17 00:00:00 2001 From: Chris Hiester Date: Mon, 24 Mar 2014 13:13:41 -0400 Subject: [PATCH 0330/1021] Improved conflict resolution message removed test-generated npm-debug.log fixed semver formatting in message --- templates/std/conflict-resolved.std | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/std/conflict-resolved.std b/templates/std/conflict-resolved.std index 52534cfe6..6d8049c6c 100644 --- a/templates/std/conflict-resolved.std +++ b/templates/std/conflict-resolved.std @@ -1,9 +1,9 @@ {{#yellow}}Please note that,{{/yellow}} {{#condense}} {{#each picks}} - {{#if dependants}}{{#white}}{{dependants}}{{/white}}{{else}}none{{/if}} depend on {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#white}}{{pkgMeta._release}}{{/white}}{{/if}} + {{#if dependants}}{{#white}}{{dependants}}{{/white}}{{else}}none{{/if}} depends on {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#white}}{{endpoint.name}}#{{pkgMeta._release}}{{/white}}{{/if}} {{/each}} {{/condense}} -Resort to using {{#cyan}}{{suitable.endpoint.name}}#{{resolution}}{{/cyan}} which resolved to {{#white}}{{suitable.pkgMeta._release}}{{/white}} +Resort to using {{#cyan}}{{suitable.endpoint.name}}#{{resolution}}{{/cyan}} which resolved to {{#white}}{{suitable.endpoint.name}}#{{suitable.pkgMeta._release}}{{/white}} Code incompatibilities may occur. From 6e73b5934e8cbef063478bbb9faf7269250d5eab Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Tue, 1 Apr 2014 13:26:35 +0100 Subject: [PATCH 0331/1021] Add 'unregister' feature --- packages/bower-registry-client/Client.js | 1 + packages/bower-registry-client/lib/index.js | 3 +- .../bower-registry-client/lib/register.js | 6 ++- .../bower-registry-client/lib/unregister.js | 50 +++++++++++++++++++ packages/bower-registry-client/package.json | 2 +- 5 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 packages/bower-registry-client/lib/unregister.js diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js index 4d6ddb69a..0b1ce9360 100644 --- a/packages/bower-registry-client/Client.js +++ b/packages/bower-registry-client/Client.js @@ -21,6 +21,7 @@ RegistryClient.prototype.lookup = methods.lookup; RegistryClient.prototype.search = methods.search; RegistryClient.prototype.list = methods.list; RegistryClient.prototype.register = methods.register; +RegistryClient.prototype.unregister = methods.unregister; RegistryClient.prototype.clearCache = function (name, callback) { if (typeof name === 'function') { diff --git a/packages/bower-registry-client/lib/index.js b/packages/bower-registry-client/lib/index.js index e1e980497..0a816d26c 100644 --- a/packages/bower-registry-client/lib/index.js +++ b/packages/bower-registry-client/lib/index.js @@ -2,5 +2,6 @@ module.exports = { lookup: require('./lookup'), list: require('./list'), register: require('./register'), - search: require('./search') + search: require('./search'), + unregister: require('./unregister') }; diff --git a/packages/bower-registry-client/lib/register.js b/packages/bower-registry-client/lib/register.js index 25133fa68..fb431894b 100644 --- a/packages/bower-registry-client/lib/register.js +++ b/packages/bower-registry-client/lib/register.js @@ -12,10 +12,14 @@ function register(name, url, callback) { headers['User-Agent'] = config.userAgent; } + if (config.accessToken) { + requestUrl += '?access_token=' + config.accessToken; + } + request.post({ url: requestUrl, proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, - headers:headers, + headers: headers, ca: config.ca.register, strictSSL: config.strictSsl, timeout: config.timeout, diff --git a/packages/bower-registry-client/lib/unregister.js b/packages/bower-registry-client/lib/unregister.js new file mode 100644 index 000000000..d20d30c6f --- /dev/null +++ b/packages/bower-registry-client/lib/unregister.js @@ -0,0 +1,50 @@ +var parseUrl = require('url').parse; +var request = require('request'); +var createError = require('./util/createError'); + +function unregister(name, callback) { + var config = this._config; + var requestUrl = config.registry.register + '/packages/' + name; + var remote = parseUrl(requestUrl); + var headers = {}; + + if (config.userAgent) { + headers['User-Agent'] = config.userAgent; + } + + if (config.accessToken) { + requestUrl += '?access_token=' + config.accessToken; + } + + console.log(requestUrl); + + request.del({ + url: requestUrl, + proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, + headers: headers, + ca: config.ca.register, + strictSSL: config.strictSsl, + timeout: config.timeout + }, function (err, response) { + // If there was an internal error (e.g. timeout) + if (err) { + return callback(createError('Request to ' + requestUrl + ' failed: ' + err.message, err.code)); + } + + // Forbidden + if (response.statusCode === 403) { + return callback(createError('Not authorized', 'EFORBIDDEN')); + } + + // Everything other than 204 is unknown + if (response.statusCode !== 204) { + return callback(createError('Unknown error: ' + response.statusCode + ', ' + response.body, 'EUNKNOWN')); + } + + callback(null, { + name: name + }); + }); +} + +module.exports = unregister; diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index fce4ec2f1..10d76b1b2 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.1.6", + "version": "0.2.0", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From 3397cf053c69912bf67161527dcbdb1b21017c3c Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Tue, 1 Apr 2014 15:29:35 +0100 Subject: [PATCH 0332/1021] Removed a debug line --- packages/bower-registry-client/lib/unregister.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/bower-registry-client/lib/unregister.js b/packages/bower-registry-client/lib/unregister.js index d20d30c6f..9d4930476 100644 --- a/packages/bower-registry-client/lib/unregister.js +++ b/packages/bower-registry-client/lib/unregister.js @@ -16,8 +16,6 @@ function unregister(name, callback) { requestUrl += '?access_token=' + config.accessToken; } - console.log(requestUrl); - request.del({ url: requestUrl, proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, From 9ebb1b17d1f74346240b147559fce067db634ccb Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Tue, 1 Apr 2014 15:57:08 +0100 Subject: [PATCH 0333/1021] Added tests and fixed code-style --- packages/bower-registry-client/.jshintrc | 2 +- packages/bower-registry-client/lib/list.js | 2 +- packages/bower-registry-client/lib/lookup.js | 2 +- packages/bower-registry-client/lib/search.js | 2 +- packages/bower-registry-client/test/Client.js | 91 +++++++++++++++++-- 5 files changed, 85 insertions(+), 14 deletions(-) diff --git a/packages/bower-registry-client/.jshintrc b/packages/bower-registry-client/.jshintrc index 50467983f..2be8506fd 100644 --- a/packages/bower-registry-client/.jshintrc +++ b/packages/bower-registry-client/.jshintrc @@ -26,7 +26,7 @@ "plusplus": false, "regexp": false, "undef": true, - "unused": true, + "unused": "vars", "quotmark": "single", "strict": false, "trailing": true, diff --git a/packages/bower-registry-client/lib/list.js b/packages/bower-registry-client/lib/list.js index 4790da23d..18fbc0753 100644 --- a/packages/bower-registry-client/lib/list.js +++ b/packages/bower-registry-client/lib/list.js @@ -96,7 +96,7 @@ function doRequest(index, callback) { req = replay(request.get(requestUrl, { proxy: remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, ca: this._config.ca.search[index], - headers:headers, + headers: headers, strictSSL: this._config.strictSsl, timeout: this._config.timeout, json: true diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index 989e5ff9d..c6cd6cf02 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -87,7 +87,7 @@ function doRequest(name, index, callback) { req = replay(request.get(requestUrl, { proxy: remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, - headers:headers, + headers: headers, ca: this._config.ca.search[index], strictSSL: this._config.strictSsl, timeout: this._config.timeout, diff --git a/packages/bower-registry-client/lib/search.js b/packages/bower-registry-client/lib/search.js index 4804ac467..3bbd8e7ae 100644 --- a/packages/bower-registry-client/lib/search.js +++ b/packages/bower-registry-client/lib/search.js @@ -103,7 +103,7 @@ function doRequest(name, index, callback) { req = replay(request.get(requestUrl, { proxy: remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, - headers:headers, + headers: headers, ca: this._config.ca.search[index], strictSSL: this._config.strictSsl, timeout: this._config.timeout, diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 013a6a3a0..63ce875a0 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -210,9 +210,9 @@ describe('RegistryClient', function () { nock('http://custom-registry.com') .get('/packages/jquery') .reply(200, { - "error": { - "message": "missing", - "stack": "Error: missing" + 'error': { + 'message': 'missing', + 'stack': 'Error: missing' } }); @@ -379,6 +379,77 @@ describe('RegistryClient', function () { }); + // + // unregister + // + describe('calling the unregister instance method with argument', function () { + beforeEach(function () { + this.pkg = 'testfoo'; + this.accessToken = '12345678'; + this.registry._config.accessToken = this.accessToken; + + nock('https://bower.herokuapp.com:443') + .delete('/packages/' + this.pkg + '?access_token=' + this.accessToken) + .reply(204); + }); + + it('should not return an error when valid', function (next) { + this.registry.unregister(this.pkg, function (err) { + expect(err).to.be(null); + next(); + }); + }); + + it('should return entry name', function (next) { + var self = this; + + this.registry.unregister(this.pkg, function (err, entry) { + expect(err).to.be(null); + expect(entry.name).to.eql(self.pkg); + next(); + }); + }); + }); + + describe('calling the unregister instance method with invalid token', function () { + beforeEach(function () { + this.pkg = 'testfoo'; + this.registry._config.accessToken = ''; + + nock('https://bower.herokuapp.com:443') + .delete('/packages/' + this.pkg) + .reply(403); + }); + + it('should return an error', function (next) { + this.registry.unregister(this.pkg, function (err, entry) { + expect(err).to.be.an(Error); + expect(entry).to.be(undefined); + next(); + }); + }); + }); + + describe('calling the unregister instance method with invalid package', function () { + beforeEach(function () { + this.notpkg = 'testbar'; + this.accessToken = '12345678'; + this.registry._config.accessToken = this.accessToken; + + nock('https://bower.herokuapp.com:443') + .delete('/packages/' + this.notpkg + '?access_token=' + this.accessToken) + .reply(404); + }); + + it('should return an error', function (next) { + this.registry.unregister(this.notpkg, function (err, entry) { + expect(err).to.be.an(Error); + expect(entry).to.be(undefined); + next(); + }); + }); + }); + // // search // @@ -635,25 +706,25 @@ describe('RegistryClient', function () { // // test userAgent // - describe('add a custom userAgent with argument',function(){ + describe('add a custom userAgent with argument', function () { this.timeout(5000); - it('should send custom userAgent to the server',function(next){ + it('should send custom userAgent to the server', function (next) { var self = this; this.ua = ''; this.server = http.createServer(function (req, res) { self.ua = req.headers['user-agent']; - res.writeHeader(200,{ - 'Content-Type':'application/json' + res.writeHeader(200, { + 'Content-Type': 'application/json' }); res.end('{"name":"jquery","url":"git://github.com/components/jquery.git"}'); self.server.close(); }); this.server.listen('7777', '127.0.0.1'); this.registry = new RegistryClient({ - userAgent:'test agent', - registry:'http://127.0.0.1:7777' + userAgent: 'test agent', + registry: 'http://127.0.0.1:7777' }); - this.registry.search('jquery', function (err,result) { + this.registry.search('jquery', function (err, result) { expect(self.ua).to.be('test agent'); next(); }); From 5b4d6f2feee3b65740d1eeb11936279397d72c5a Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Wed, 2 Apr 2014 12:55:00 +0100 Subject: [PATCH 0334/1021] Add node 0.11 to Travis, but allow it to fail. --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 9e5cd30fc..5c9fdd0b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,9 @@ language: node_js node_js: - "0.10" + - "0.11" +matrix: + allow_failures: + - node_js: "0.11" before_script: - npm install grunt-cli -g From 5a5cf31aba1c17cd6d44d63704566c038eefb940 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 6 Nov 2013 02:11:58 +0100 Subject: [PATCH 0335/1021] Make bower concurrent friendly, fixes #933 --- lib/core/ResolveCache.js | 62 +++++++++++++++++++++++---------------- package.json | 3 +- test/core/resolveCache.js | 52 ++++++++++++++++---------------- 3 files changed, 64 insertions(+), 53 deletions(-) diff --git a/lib/core/ResolveCache.js b/lib/core/ResolveCache.js index 6de8e1809..1103a9014 100644 --- a/lib/core/ResolveCache.js +++ b/lib/core/ResolveCache.js @@ -5,6 +5,7 @@ var Q = require('q'); var mkdirp = require('mkdirp'); var rimraf = require('rimraf'); var LRU = require('lru-cache'); +var lockFile = require('lockfile'); var semver = require('../util/semver'); var readJson = require('../util/readJson'); var copy = require('../util/copy'); @@ -18,6 +19,9 @@ function ResolveCache(config) { // - etc.. this._config = config; this._dir = this._config.storage.packages; + this._lockDir = this._config.storage.packages; + + mkdirp.sync(this._lockDir); // Cache is stored/retrieved statically to ensure singularity // among instances @@ -97,6 +101,7 @@ ResolveCache.prototype.store = function (canonicalDir, pkgMeta) { var sourceId; var release; var dir; + var pkgLock; var promise; var that = this; @@ -107,36 +112,41 @@ ResolveCache.prototype.store = function (canonicalDir, pkgMeta) { sourceId = md5(pkgMeta._source); release = that._getPkgRelease(pkgMeta); dir = path.join(that._dir, sourceId, release); + pkgLock = path.join(that._lockDir, sourceId + '-' + release + '.lock'); - // Check if directory exists + // Check if destination directory exists to prevent issuing lock at all times return Q.nfcall(fs.stat, dir) - .then(function () { - // If it does exists, remove it - return Q.nfcall(rimraf, dir); - }, function (err) { - // If directory does not exists, ensure its basename - // is created - if (err.code === 'ENOENT') { - return Q.nfcall(mkdirp, path.dirname(dir)); - } - - throw err; - }) - // Move the canonical to sourceId/target - .then(function () { - return Q.nfcall(fs.rename, canonicalDir, dir) - .fail(function (err) { - // If error is EXDEV it means that we are trying to rename - // across different drives, so we copy and remove it instead - if (err.code !== 'EXDEV') { - throw err; - } - - return copy.copyDir(canonicalDir, dir) - .then(function () { - return Q.nfcall(rimraf, canonicalDir); + .fail(function (err) { + var lockParams = { wait: 250, retries: 25, stale: 60000 }; + return Q.nfcall(lockFile.lock, pkgLock, lockParams).then(function () { + // Ensure other process didn't start copying files before lock was created + return Q.nfcall(fs.stat, dir) + .fail(function (err) { + // If stat fails, it is expected to return ENOENT + if (err.code !== 'ENOENT') { + throw err; + } + + // Create missing directory and copy files there + return Q.nfcall(mkdirp, path.dirname(dir)).then(function () { + return Q.nfcall(fs.rename, canonicalDir, dir) + .fail(function (err) { + // If error is EXDEV it means that we are trying to rename + // across different drives, so we copy and remove it instead + if (err.code !== 'EXDEV') { + throw err; + } + + return copy.copyDir(canonicalDir, dir); + }); + }); }); + }).finally(function () { + lockFile.unlockSync(pkgLock); }); + }).finally(function () { + // Ensure no tmp dir is left on disk. + return Q.nfcall(rimraf, canonicalDir); }); }) .then(function () { diff --git a/package.json b/package.json index 7fcdab556..c1be67e16 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,8 @@ "p-throttler": "~0.0.1", "insight": "~0.3.0", "is-root": "~0.1.0", - "shell-quote": "~1.4.1" + "shell-quote": "~1.4.1", + "lockfile": "~0.4.2" }, "devDependencies": { "expect.js": "~0.2.0", diff --git a/test/core/resolveCache.js b/test/core/resolveCache.js index 127496452..9164992fe 100644 --- a/test/core/resolveCache.js +++ b/test/core/resolveCache.js @@ -138,30 +138,6 @@ describe('ResolveCache', function () { .done(); }); - it('should overwrite if the exact same package source/version exists', function (next) { - var cachePkgDir = path.join(cacheDir, md5('foo'), '1.0.0-rc.blehhh'); - - mkdirp.sync(cachePkgDir); - fs.writeFileSync(path.join(cachePkgDir, '_bleh'), 'w00t'); - - resolveCache.store(tempPackage, { - name: 'foo', - version: '1.0.0-rc.blehhh', - _source: 'foo', - _target: '*' - }) - .then(function (dir) { - expect(dir).to.equal(cachePkgDir); - expect(fs.existsSync(dir)).to.be(true); - expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); - expect(fs.existsSync(tempPackage)).to.be(false); - expect(fs.existsSync(path.join(cachePkgDir, '_bleh'))).to.be(false); - - next(); - }) - .done(); - }); - it('should read the package meta if not present', function (next) { var pkgMeta = path.join(tempPackage, '.bower.json'); @@ -241,14 +217,14 @@ describe('ResolveCache', function () { resolveCache.store(tempPackage, { name: 'foo', - _source: 'foo', + _source: 'foobar', _target: 'some-branch' }) .then(function (dir) { // Ensure mock was called expect(hittedMock).to.be(true); - expect(dir).to.equal(path.join(cacheDir, md5('foo'), 'some-branch')); + expect(dir).to.equal(path.join(cacheDir, md5('foobar'), 'some-branch')); expect(fs.existsSync(dir)).to.be(true); expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); expect(fs.existsSync(tempPackage)).to.be(false); @@ -310,6 +286,30 @@ describe('ResolveCache', function () { }) .done(); }); + + it('should be possible to store two package at same time', function (next) { + var store = resolveCache.store.bind(resolveCache, tempPackage, { + name: 'foo', + _source: 'foo', + _target: 'foo/bar' + }); + var store2 = resolveCache.store.bind(resolveCache, tempPackage2, { + name: 'foo', + _source: 'foo', + _target: 'foo/bar' + }); + + Q.all([store(), store2()]).then(function (dirs) { + var dir = dirs[0]; + expect(dir).to.equal(path.join(cacheDir, md5('foo'), 'foo%2Fbar')); + expect(fs.existsSync(dir)).to.be(true); + expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); + expect(fs.existsSync(tempPackage)).to.be(false); + expect(fs.existsSync(tempPackage2)).to.be(false); + + next(); + }).done(); + }); }); describe('.versions', function () { From 98ea43eca9858bcdb797155b474f235af4461726 Mon Sep 17 00:00:00 2001 From: Ben Schwarz Date: Sat, 5 Apr 2014 16:03:25 +1100 Subject: [PATCH 0336/1021] Prepped 1.3.2 release --- CHANGELOG.md | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70bce8997..3422d1139 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.3.2 - 2014-04-05 +- Fix for concurrent naming [PR #1007](https://github.com/bower/bower/pull/1077) +- `link` now installs package dependencies [PR #891](https://github.com/bower/bower/pull/891) +- Improved conflict installation message [Commit](https://github.com/bower/bower/commit/bea533acf87903d4b411bfbaa7df93f852ef46a3) +- Add --production switch to "prune" command [PR #1168](https://github.com/bower/bower/pull/1168) ## 1.3.1 - 2014-03-10 - No longer ask for permission to gather analytics when running on in a CI environment. diff --git a/package.json b/package.json index 7fcdab556..45775197e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.3.1", + "version": "1.3.2", "description": "The browser package manager.", "author": "Twitter", "licenses": [ From 4812c380c4916a376187d696f76175a03ded9a90 Mon Sep 17 00:00:00 2001 From: shinnn Date: Sat, 5 Apr 2014 13:06:02 +0200 Subject: [PATCH 0337/1021] Add a validation for description length closes #17 --- packages/bower-json/lib/json.js | 6 +++++- packages/bower-json/package.json | 15 ++++++++------- packages/bower-json/test/test.js | 19 +++++++++++++++++++ 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index 5e36770a4..20fddf1d3 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -89,7 +89,7 @@ function validate(json) { } if (json.name.length > 50) { - throw createError('The name is too long. 50 character should be more than enough', 'EINVALID'); + throw createError('The name is too long. 50 characters should be more than enough', 'EINVALID'); } if (/[A-Z]/.test(json.name)) { @@ -103,6 +103,10 @@ function validate(json) { if (!/[a-z]$/.test(json.name)) { throw createError('The name has to end with a lower case character from a to z', 'EINVALID'); } + + if (json.description && json.description.length > 140) { + throw createError('The description is too long. 140 characters should be more than enough', 'EINVALID'); + } // TODO https://github.com/bower/bower.json-spec diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 92a50363a..b572b7b3d 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -20,15 +20,16 @@ "dependencies": { "deep-extend": "~0.2.5", "graceful-fs": "~2.0.0", - "intersect": "~0.0.3" + "intersect": "~0.1.0" }, "devDependencies": { - "expect.js": "~0.2.0", - "mocha": "~1.12.0", - "grunt": "~0.4.1", - "grunt-contrib-watch": "~0.4.4", - "grunt-contrib-jshint": "~0.6.0", - "grunt-simple-mocha": "~0.4.0" + "expect.js": "~0.3.1", + "mocha": "~1.18.2", + "grunt": "~0.4.4", + "grunt-contrib-watch": "~0.6.1", + "grunt-contrib-jshint": "~0.10.0", + "grunt-simple-mocha": "~0.4.0", + "underscore.string": "~2.3.3" }, "scripts": { "test": "grunt test" diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index 256c1edd6..c70758205 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -1,5 +1,6 @@ var path = require('path'); var expect = require('expect.js'); +var _s = require('underscore.string'); var bowerJson = require('../lib/json'); describe('.find', function () { @@ -224,6 +225,24 @@ describe('.validate', function () { bowerJson.validate(json); }).to.not.throwException(); }); + it('should validate the description length', function () { + var json = { + name: 'foo', + description: _s.repeat('æ', 141) + }; + expect(function () { + bowerJson.validate(json); + }).to.throwException(); + }); + it('should validate the description is valid', function () { + var json = { + name: 'foo', + description: _s.repeat('æ', 140) + }; + expect(function () { + bowerJson.validate(json); + }).to.not.throwException(); + }); }); describe('.normalize', function () { From 20aca45b39c9363d00a3ab94ff5a2ed5c92e178d Mon Sep 17 00:00:00 2001 From: Ben Schwarz Date: Sun, 6 Apr 2014 14:57:40 +1000 Subject: [PATCH 0338/1021] Revert "Merge pull request #1077 from neoziro/fix-concurrent-renaming" This reverts commit cd541c7a204a545a38996f98ac0bc5cc615f3ffa, reversing changes made to 3074711828cdbfe7a8660e5cdc72018bd50d2a05. --- lib/core/ResolveCache.js | 57 +++++++++++++-------------------------- test/core/resolveCache.js | 24 ----------------- 2 files changed, 18 insertions(+), 63 deletions(-) diff --git a/lib/core/ResolveCache.js b/lib/core/ResolveCache.js index 541245da9..6de8e1809 100644 --- a/lib/core/ResolveCache.js +++ b/lib/core/ResolveCache.js @@ -108,43 +108,23 @@ ResolveCache.prototype.store = function (canonicalDir, pkgMeta) { release = that._getPkgRelease(pkgMeta); dir = path.join(that._dir, sourceId, release); - var checkExistingDirectory; - var key = 'moving:' + dir; - - if (! that._cache.has(key)) { - // Check if directory exists - checkExistingDirectory = Q.nfcall(fs.stat, dir) - .then(function () { - // If it does exists, remove it - return Q.nfcall(rimraf, dir); - }, function (err) { - // If directory does not exists, ensure its basename - // is created - if (err.code === 'ENOENT') { - return Q.nfcall(mkdirp, path.dirname(dir)); - } - - throw err; - }); - } - else { - checkExistingDirectory = new Q(); - } - - return checkExistingDirectory - // Move the canonical to sourceId/target + // Check if directory exists + return Q.nfcall(fs.stat, dir) .then(function () { - // We store the renaming in cache. - var promise; - if (that._cache.has(key)) { - promise = that._cache.get(key); - } - else { - promise = Q.nfcall(fs.rename, canonicalDir, dir); - that._cache.set(key, promise); + // If it does exists, remove it + return Q.nfcall(rimraf, dir); + }, function (err) { + // If directory does not exists, ensure its basename + // is created + if (err.code === 'ENOENT') { + return Q.nfcall(mkdirp, path.dirname(dir)); } - return promise + throw err; + }) + // Move the canonical to sourceId/target + .then(function () { + return Q.nfcall(fs.rename, canonicalDir, dir) .fail(function (err) { // If error is EXDEV it means that we are trying to rename // across different drives, so we copy and remove it instead @@ -152,11 +132,10 @@ ResolveCache.prototype.store = function (canonicalDir, pkgMeta) { throw err; } - return copy.copyDir(canonicalDir, dir); - }) - // To match all case, we remove the directory. - .then(function () { - return Q.nfcall(rimraf, canonicalDir); + return copy.copyDir(canonicalDir, dir) + .then(function () { + return Q.nfcall(rimraf, canonicalDir); + }); }); }); }) diff --git a/test/core/resolveCache.js b/test/core/resolveCache.js index 37d6a8641..127496452 100644 --- a/test/core/resolveCache.js +++ b/test/core/resolveCache.js @@ -310,30 +310,6 @@ describe('ResolveCache', function () { }) .done(); }); - - it('should be possible to store two package at same time', function (next) { - var store = resolveCache.store.bind(resolveCache, tempPackage, { - name: 'foo', - _source: 'foo', - _target: 'foo/bar' - }); - var store2 = resolveCache.store.bind(resolveCache, tempPackage2, { - name: 'foo', - _source: 'foo', - _target: 'foo/bar' - }); - - Q.all([store(), store2()]).then(function (dirs) { - var dir = dirs[0]; - expect(dir).to.equal(path.join(cacheDir, md5('foo'), 'foo%2Fbar')); - expect(fs.existsSync(dir)).to.be(true); - expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); - expect(fs.existsSync(tempPackage)).to.be(false); - expect(fs.existsSync(tempPackage2)).to.be(false); - - next(); - }).done(); - }); }); describe('.versions', function () { From d031ab5cebeac136f0ca4a2d2dbd4d61b449f6e2 Mon Sep 17 00:00:00 2001 From: Ray Shan Date: Sat, 5 Apr 2014 23:00:38 -0700 Subject: [PATCH 0339/1021] Tweak insight tracking for `search` command - Tracking should be consistent with `info` command; tracking should register upon user calling the command, not when the command is completed - Vocabulary should be consistent with other tracking - if only tracking upon calling the command, should use the present tense of the verb without -"ed" This is an improvement for tracking and reporting consistency, please see https://github.com/bower/bower/issues/1164#issuecomment-39385297 --- lib/commands/search.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/commands/search.js b/lib/commands/search.js index c42b362ae..2de5f0338 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -17,6 +17,7 @@ function search(name, config) { registryClient = new RegistryClient(config, logger); tracker = new Tracker(config); + tracker.track('search', name); // If no name was specified, list all packages if (!name) { @@ -28,7 +29,6 @@ function search(name, config) { promise .done(function (results) { - tracker.track('searched', name); logger.emit('end', results); }, function (error) { logger.emit('error', error); From 5ce1b6a4c1b79cb3170e25ed1a0b2132dab88f7e Mon Sep 17 00:00:00 2001 From: Dmitry Mazuro Date: Sun, 6 Apr 2014 19:47:06 +0300 Subject: [PATCH 0340/1021] Use SVG version of travis build status badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9192c9613..6337ae9c7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bower -[![Build Status](https://secure.travis-ci.org/bower/bower.png?branch=master)](http://travis-ci.org/bower/bower) +[![Build Status](https://secure.travis-ci.org/bower/bower.svg?branch=master)](http://travis-ci.org/bower/bower) From bdaa359d11011dfea764f51bfcd1423e672878a3 Mon Sep 17 00:00:00 2001 From: Ben Schwarz Date: Mon, 7 Apr 2014 11:01:25 +1000 Subject: [PATCH 0341/1021] Update changelog with #1211, remove #1077 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3422d1139..584bbc372 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog ## 1.3.2 - 2014-04-05 -- Fix for concurrent naming [PR #1007](https://github.com/bower/bower/pull/1077) +- Fixes for concurrency issues [PR #1211](https://github.com/bower/bower/pull/1211) - `link` now installs package dependencies [PR #891](https://github.com/bower/bower/pull/891) - Improved conflict installation message [Commit](https://github.com/bower/bower/commit/bea533acf87903d4b411bfbaa7df93f852ef46a3) - Add --production switch to "prune" command [PR #1168](https://github.com/bower/bower/pull/1168) From 961d1775e57d4dc7dca0f50f243a4a3a243e7bd0 Mon Sep 17 00:00:00 2001 From: Eric Ferraiuolo Date: Sun, 6 Apr 2014 18:13:37 -0700 Subject: [PATCH 0342/1021] Squashed commit of the following: commit d5ab6721b6d0014b25ec7e5da2078627f0e794dd Author: Eric Ferraiuolo Date: Thu Feb 20 19:07:04 2014 -0500 Add YUI modules as a `moduleType` choice Closes gh-1129. --- lib/commands/init.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/commands/init.js b/lib/commands/init.js index 47a56a01d..bb98201bc 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -205,7 +205,7 @@ function promptUser(logger, json) { 'name': 'moduleType', 'message': 'what types of modules does this package expose?', 'type': 'checkbox', - 'choices': ['amd', 'es6', 'globals', 'node'] + 'choices': ['amd', 'es6', 'globals', 'node', 'yui'] }, { 'name': 'keywords', From 53fc25550bae17723803ff2b40decc78355e6688 Mon Sep 17 00:00:00 2001 From: Ben Schwarz Date: Mon, 7 Apr 2014 11:35:16 +1000 Subject: [PATCH 0343/1021] Added yui moduletype --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 584bbc372..7d459644e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## 1.3.2 - 2014-04-05 +- Added yui moduleType [PR #1129](https://github.com/bower/bower/pull/1129) - Fixes for concurrency issues [PR #1211](https://github.com/bower/bower/pull/1211) - `link` now installs package dependencies [PR #891](https://github.com/bower/bower/pull/891) - Improved conflict installation message [Commit](https://github.com/bower/bower/commit/bea533acf87903d4b411bfbaa7df93f852ef46a3) From 2fb697f452a4f1d91e2e6b06ba343e9c168d07af Mon Sep 17 00:00:00 2001 From: Alexandre MOTTET Date: Wed, 9 Apr 2014 13:44:22 +0000 Subject: [PATCH 0344/1021] Update private Subversion repository example in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6337ae9c7..fc2f0ab27 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ Where `` can be any one of the following: * A private Git repository, e.g., ```https://github.com/someone/some-package.git```. If the protocol is https, a prompt will ask for the credentials. ssh can also be used, e.g., ```git@github.com:someone/some-package.git``` and can authenticate with the user's ssh public/private keys. ‡ * A local endpoint, i.e., a folder that's a Git repository. ‡ * A public remote Subversion endpoint, e.g., ```svn+http://package.googlecode.com/svn/```. ‡ -* A private Subversion repository, e.g., ```svn+ssh://package.googlecode.com/svn/```. ‡ +* A private Subversion repository, e.g., ```svn+ssh://package.googlecode.com/svn/``` or ```svn+https://package.googlecode.com/svn/```. ‡ * A local endpoint, i.e., a folder that's an Subversion repository, e.g., ```svn+file:///path/to/svn/```. ‡ * A shorthand endpoint, e.g., `someone/some-package` (defaults to GitHub). ‡ * A URL to a file, including `zip` and `tar` files. Its contents will be From c21ba1e64c55f3ab7d33365af5009ae1670297e8 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Thu, 10 Apr 2014 08:02:18 +0800 Subject: [PATCH 0345/1021] Refer to spec; add description in sample; fix map order --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fc2f0ab27..0b84bed7f 100644 --- a/README.md +++ b/README.md @@ -207,7 +207,7 @@ You can interactively create a `bower.json` with the following command: bower init ``` -The `bower.json` defines several options: +The `bower.json` ([spec](https://github.com/bower/bower.json-spec)) defines several options, including: * `name` (required): The name of your package. * `version`: A semantic version number (see [semver](http://semver.org/)). @@ -224,6 +224,7 @@ The `bower.json` defines several options: ```json { "name": "my-project", + "description": "My project does XYZ...", "version": "1.0.0", "main": "path/to/main.css", "ignore": [ @@ -271,7 +272,7 @@ Bower also makes available a source mapping. This can be used by build tools to easily consume Bower packages. If you pass the `--paths` option to Bower's `list` command, you will get a -simple path-to-name mapping: +simple name-to-path mapping: ```json { From edf387363dc74cef138f7a3dcca305c0d361ed39 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Apr 2014 01:44:07 +0200 Subject: [PATCH 0346/1021] doc: Point to new official msysgit website --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0b84bed7f..5e66c5851 100644 --- a/README.md +++ b/README.md @@ -146,7 +146,7 @@ However, if you still want to run commands with sudo, use `--allow-root` option. #### A note for Windows users To use Bower on Windows, you must install -[msysgit](http://code.google.com/p/msysgit/) correctly. Be sure to check the +[msysgit](http://msysgit.github.io/) correctly. Be sure to check the option shown below: ![msysgit](http://f.cl.ly/items/2V2O3i1p3R2F1r2v0a12/mysgit.png) From 22eef989f6be33a2d3342a99d5e5252d7a3a162a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Apr 2014 05:39:29 +0200 Subject: [PATCH 0347/1021] Update dependencies in package.json to newest patches --- package.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 5f64f2e96..21032fa13 100644 --- a/package.json +++ b/package.json @@ -32,19 +32,19 @@ "decompress-zip": "~0.0.3", "fstream": "~0.1.22", "fstream-ignore": "~0.0.6", - "glob": "~3.2.1", + "glob": "~3.2.9", "graceful-fs": "~2.0.0", "handlebars": "~1.3.0", "inquirer": "~0.4.0", - "junk": "~0.2.0", + "junk": "~0.2.2", "mkdirp": "~0.3.5", - "mout": "~0.9.0", - "nopt": "~2.1.1", + "mout": "~0.9.1", + "nopt": "~2.1.2", "lru-cache": "~2.5.0", "open": "~0.0.3", "osenv": "~0.0.3", "promptly": "~0.2.0", - "q": "~1.0.0", + "q": "~1.0.1", "request": "~2.33.0", "request-progress": "~0.3.0", "retry": "~0.6.0", @@ -65,13 +65,13 @@ "expect.js": "~0.2.0", "grunt": "~0.4.1", "grunt-simple-mocha": "~0.4.0", - "grunt-contrib-watch": "~0.5.0", + "grunt-contrib-watch": "~0.5.3", "grunt-contrib-jshint": "~0.8.0", "grunt-exec": "~0.4.2", - "mocha": "*", + "mocha": "~1.18", "nock": "~0.27.2", "istanbul": "~0.2.4", - "proxyquire": "~0.5.0", + "proxyquire": "~0.5.3", "load-grunt-tasks": "~0.3.0" }, "scripts": { From 2167c7b6d4aa1566b7b51da95d1ebdb899d9b9c6 Mon Sep 17 00:00:00 2001 From: Thomas Scholtes Date: Mon, 24 Feb 2014 18:51:37 +0100 Subject: [PATCH 0348/1021] Loading commands on demand increases performance --- lib/commands/index.js | 71 +++++++++++++++++++++++++++++++++---------- lib/index.js | 2 +- 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/lib/commands/index.js b/lib/commands/index.js index 6e38aeae6..28094a3ab 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -1,18 +1,57 @@ +var Q = require('q'); +var Logger = require('bower-logger'); + +/** + * Require commands only when called. + * + * Running `commandFactory(id)` is equivalent to `require(id)`. Both calls return + * a command function. The difference is that `cmd = commandFactory()` and `cmd()` + * return as soon as possible and load and execute the command asynchronously. + */ +function lazyRequire(id) { + function command() { + var logger = new Logger(); + var commandArgs = arguments; + + Q.try(function () { + // call require asynchronously + return require(id).apply(undefined, commandArgs); + }) + .done(function (commandLogger) { + // forward to exposed logger + commandLogger.on('end', logger.emit.bind(logger, 'end')); + commandLogger.on('error', logger.emit.bind(logger, 'error')); + }, function (error) { + logger.emit('error', error); + }); + + return logger; + } + + function runFromArgv() { + return require(id).line.apply(undefined, arguments); + } + + command.line = runFromArgv; + return command; +} + + module.exports = { - cache: require('./cache'), - completion: require('./completion'), - help: require('./help'), - home: require('./home'), - info: require('./info'), - init: require('./init'), - install: require('./install'), - link: require('./link'), - list: require('./list'), - lookup: require('./lookup'), - prune: require('./prune'), - register: require('./register'), - search: require('./search'), - update: require('./update'), - uninstall: require('./uninstall'), - version: require('./version') + cache: lazyRequire('./cache'), + completion: lazyRequire('./completion'), + help: lazyRequire('./help'), + home: lazyRequire('./home'), + info: lazyRequire('./info'), + init: lazyRequire('./init'), + install: lazyRequire('./install'), + link: lazyRequire('./link'), + list: lazyRequire('./list'), + lookup: lazyRequire('./lookup'), + prune: lazyRequire('./prune'), + register: lazyRequire('./register'), + search: lazyRequire('./search'), + update: lazyRequire('./update'), + uninstall: lazyRequire('./uninstall'), + version: lazyRequire('./version') }; diff --git a/lib/index.js b/lib/index.js index c32e579eb..d0668398b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,7 +1,6 @@ var abbrev = require('abbrev'); var mout = require('mout'); var commands = require('./commands'); -var PackageRepository = require('./core/PackageRepository'); var abbreviations = abbrev(expandNames(commands)); abbreviations.i = 'install'; @@ -30,6 +29,7 @@ function clearRuntimeCache() { // Note that in edge cases, some architecture components instance's // in-memory cache might be skipped. // If that's a problem, you should create and fresh instances instead. + var PackageRepository = require('./core/PackageRepository'); PackageRepository.clearRuntimeCache(); } From e8c071304c4ed951d508a41d114e769666d7a02c Mon Sep 17 00:00:00 2001 From: Ahmad Nassri Date: Fri, 11 Apr 2014 09:00:41 -0400 Subject: [PATCH 0349/1021] using 'svn export' for efficiency. Closes #1224 --- lib/core/resolvers/SvnResolver.js | 28 ++----- test/core/resolvers/svnResolver.js | 113 ++--------------------------- 2 files changed, 15 insertions(+), 126 deletions(-) diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js index 1c0c8060f..866fad789 100644 --- a/lib/core/resolvers/SvnResolver.js +++ b/lib/core/resolvers/SvnResolver.js @@ -1,7 +1,5 @@ var util = require('util'); -var path = require('path'); var Q = require('q'); -var rimraf = require('rimraf'); var which = require('which'); var LRU = require('lru-cache'); var mout = require('mout'); @@ -67,19 +65,13 @@ SvnResolver.prototype._resolve = function () { return this._findResolution() .then(function () { - return that._checkout() - // Always run cleanup after checkout to ensure that .svn is removed! - // If it's not removed, problems might arise when the "tmp" module attempts - // to delete the temporary folder - .fin(function () { - return that._cleanup(); - }); + return that._export(); }); }; // ----------------- -SvnResolver.prototype._checkout = function () { +SvnResolver.prototype._export = function () { var promise; var timer; var reporter; @@ -88,19 +80,19 @@ SvnResolver.prototype._checkout = function () { this.source = SvnResolver.getSource(this._source); - this._logger.action('checkout', resolution.tag || resolution.branch || resolution.commit, { + this._logger.action('export', resolution.tag || resolution.branch || resolution.commit, { resolution: resolution, to: this._tempDir }); if (resolution.type === 'commit') { - promise = cmd('svn', ['checkout', this._source + '/trunk', '-r' + resolution.commit, this._tempDir]); + promise = cmd('svn', ['export', '--force', this._source + '/trunk', '-r' + resolution.commit, this._tempDir]); } else if (resolution.type === 'branch' && resolution.branch === 'trunk') { - promise = cmd('svn', ['checkout', this._source + '/trunk', this._tempDir]); + promise = cmd('svn', ['export', '--force', this._source + '/trunk', this._tempDir]); } else if (resolution.type === 'branch') { - promise = cmd('svn', ['checkout', this._source + '/branches/' + resolution.branch, this._tempDir]); + promise = cmd('svn', ['export', '--force', this._source + '/branches/' + resolution.branch, this._tempDir]); } else { - promise = cmd('svn', ['checkout', this._source + '/tags/' + resolution.tag, this._tempDir]); + promise = cmd('svn', ['export', '--force', this._source + '/tags/' + resolution.tag, this._tempDir]); } // Throttle the progress reporter to 1 time each sec @@ -232,12 +224,6 @@ SvnResolver.prototype._findResolution = function (target) { }); }; -SvnResolver.prototype._cleanup = function () { - var svnFolder = path.join(this._tempDir, '.svn'); - - return Q.nfcall(rimraf, svnFolder); -}; - SvnResolver.prototype._savePkgMeta = function (meta) { var version; diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index 98c44c901..ffbf74f41 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -2,13 +2,11 @@ var expect = require('expect.js'); var util = require('util'); var path = require('path'); var fs = require('graceful-fs'); -var chmodr = require('chmodr'); var rimraf = require('rimraf'); var mkdirp = require('mkdirp'); var Q = require('q'); var mout = require('mout'); var Logger = require('bower-logger'); -var copy = require('../../../lib/util/copy'); var SvnResolver = require('../../../lib/core/resolvers/SvnResolver'); var defaultConfig = require('../../../lib/config'); @@ -271,20 +269,11 @@ describe('SvnResolver', function () { }.bind(this)); }; - DummyResolver.prototype._checkout = function () { - this._stack.push('before _checkout'); + DummyResolver.prototype._export = function () { + this._stack.push('before _export'); return Q.resolve() .then(function (val) { - this._stack.push('after _checkout'); - return val; - }.bind(this)); - }; - - DummyResolver.prototype._cleanup = function () { - this._stack.push('before _cleanup'); - return SvnResolver.prototype._cleanup.apply(this, arguments) - .then(function (val) { - this._stack.push('after _cleanup'); + this._stack.push('after _export'); return val; }.bind(this)); }; @@ -296,10 +285,8 @@ describe('SvnResolver', function () { expect(resolver.getStack()).to.eql([ 'before _findResolution', 'after _findResolution', - 'before _checkout', - 'after _checkout', - 'before _cleanup', - 'after _cleanup' + 'before _export', + 'after _export' ]); next(); }) @@ -608,87 +595,6 @@ describe('SvnResolver', function () { }); }); - describe('._cleanup', function () { - beforeEach(function () { - mkdirp.sync(tempDir); - }); - - afterEach(function (next) { - clearResolverRuntimeCache(); - // Need to chmodr before removing..at least on windows - // because .svn has some read only files - chmodr(tempDir, 0777, function () { - rimraf(tempDir, next); - }); - }); - - it('should remove the .svn folder from the temp dir', function (next) { - var resolver = create('foo'); - var dst = path.join(tempDir, '.svn'); - - this.timeout(30000); // Give some time to copy - - // Copy .svn folder to the tempDir - copy.copyDir(path.resolve(__dirname, '../../assets/package-svn/repo/.svn'), dst, { - mode: 0777 - }) - .then(function () { - resolver._tempDir = tempDir; - - return resolver._cleanup() - .then(function () { - expect(fs.existsSync(dst)).to.be(false); - next(); - }); - }) - .done(); - }); - - it('should not fail if .svn does not exist for some reason', function (next) { - var resolver = create('foo'); - var dst = path.join(tempDir, '.svn'); - - resolver._tempDir = tempDir; - - resolver._cleanup() - .then(function () { - expect(fs.existsSync(dst)).to.be(false); - next(); - }) - .done(); - }); - - it('should sill run even if _checkout fails for some reason', function (next) { - var resolver = create('foo'); - var called = false; - - SvnResolver.tags = function () { - return Q.resolve({ - '1.0.0': 1 - }); - }; - - resolver._tempDir = tempDir; - resolver._checkout = function () { - return Q.reject(new Error('Some error')); - }; - - resolver._cleanup = function () { - called = true; - return SvnResolver.prototype._cleanup.apply(this, arguments); - }; - - resolver.resolve() - .then(function () { - next(new Error('Should have failed')); - }, function () { - expect(called).to.be(true); - next(); - }) - .done(); - }); - }); - describe('._savePkgMeta', function () { before(function () { mkdirp.sync(tempDir); @@ -1101,9 +1007,10 @@ describe('SvnResolver', function () { expect(resolver.getName()).to.equal('svn'); }); }); + describe('.resolve', function () { - it('should checkout correctly if resolution is a tag', function (next) { + it('should export correctly if resolution is a tag', function (next) { var resolver = create({ source: 'file://' + testPackageAdmin, target: '0.0.1' }); resolver.resolve() @@ -1119,7 +1026,7 @@ describe('SvnResolver', function () { .done(); }); - it('should checkout correctly if resolution is a commit', function (next) { + it('should export correctly if resolution is a commit', function (next) { var resolver = create({ source: 'file://' + testPackageAdmin, target: 'r1' }); resolver.resolve() @@ -1136,8 +1043,4 @@ describe('SvnResolver', function () { .done(); }); }); - - - - }); From bda53129179115f33dd40941842a118b7e8b8a2a Mon Sep 17 00:00:00 2001 From: Chris Hiester Date: Wed, 26 Mar 2014 15:39:43 -0400 Subject: [PATCH 0350/1021] clarified uniinstall warning message improved uninstall message edits to uninstall message revisions per conversation with core team fixed lint errors reverted mode changes reverted test.js mode change --- lib/core/Project.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core/Project.js b/lib/core/Project.js index 039cdfa58..a292c69e7 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -685,7 +685,7 @@ Project.prototype._removePackages = function (packages) { // Delete directory if (!dir) { promise = Q.resolve(); - that._logger.warn('not-installed', name, { + that._logger.warn('not-installed', '\'' + name + '\'' + ' cannot be uninstalled as it is not currently installed', { name: name }); } else { @@ -713,7 +713,7 @@ Project.prototype._removePackages = function (packages) { promises.push(promise); }); - + return Q.all(promises); }) From 0316fedd4c71b2914b9efd98904f6aa3e46e277e Mon Sep 17 00:00:00 2001 From: toshipon Date: Sun, 27 Oct 2013 12:16:14 +0900 Subject: [PATCH 0351/1021] Fix considering extended directory using .bowerrc --- lib/commands/list.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/commands/list.js b/lib/commands/list.js index 6445f7f86..d1d4dcdcd 100644 --- a/lib/commands/list.js +++ b/lib/commands/list.js @@ -23,8 +23,6 @@ function list(options, config) { project.getTree(options) .spread(function (tree, flattened) { - var baseDir = path.dirname(path.join(config.cwd, config.directory)); - // Relativize paths // Also normalize paths on windows project.walkTree(tree, function (node) { @@ -33,7 +31,7 @@ function list(options, config) { } if (options.relative) { - node.canonicalDir = path.relative(baseDir, node.canonicalDir); + node.canonicalDir = path.relative(config.cwd, node.canonicalDir); } if (options.paths) { node.canonicalDir = normalize(node.canonicalDir); @@ -48,7 +46,7 @@ function list(options, config) { } if (options.relative) { - node.canonicalDir = path.relative(baseDir, node.canonicalDir); + node.canonicalDir = path.relative(config.cwd, node.canonicalDir); } if (options.paths) { node.canonicalDir = normalize(node.canonicalDir); From 74d568b1e7ce532f164d0619b952614f03db6ff8 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 12 Apr 2014 21:11:17 +0200 Subject: [PATCH 0352/1021] Improve noninteractive loading performance 2x, fixes #1221 --- bin/bower | 21 ++++++++++++--------- lib/config.js | 8 ++++++-- lib/renderers/StandardRenderer.js | 5 +++-- lib/util/analytics.js | 27 ++++++++++++++++----------- 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/bin/bower b/bin/bower index 02465a453..0f1f7976f 100755 --- a/bin/bower +++ b/bin/bower @@ -5,7 +5,6 @@ process.bin = process.title = 'bower'; var Q = require('q'); var path = require('path'); var mout = require('mout'); -var updateNotifier = require('update-notifier'); var Logger = require('bower-logger'); var osenv = require('osenv'); var bower = require('../lib'); @@ -73,7 +72,7 @@ while (options.argv.remain.length) { } // Ask for Insights on first run. -analytics.setup().then(function () { +analytics.setup(bower.config).then(function () { // Execute the command commandFunc = command && mout.object.get(bower.commands, command); command = command && command.replace(/\./g, ' '); @@ -133,13 +132,17 @@ analytics.setup().then(function () { logger.warn('no-home', 'HOME not set, user configuration will not be loaded'); } - // Check for newer version of Bower - notifier = updateNotifier({ - packageName: pkg.name, - packageVersion: pkg.version - }); + if (bower.config.interactive) { + var updateNotifier = require('update-notifier'); + + // Check for newer version of Bower + notifier = updateNotifier({ + packageName: pkg.name, + packageVersion: pkg.version + }); - if (notifier.update && levels.info >= loglevel) { - renderer.updateNotice(notifier.update); + if (notifier.update && levels.info >= loglevel) { + renderer.updateNotice(notifier.update); + } } }); diff --git a/lib/config.js b/lib/config.js index e3d315bdf..b97fbbba8 100644 --- a/lib/config.js +++ b/lib/config.js @@ -9,14 +9,18 @@ delete config.json; // If interactive is auto (null), guess its value if (config.interactive == null) { - config.interactive = process.bin === 'bower' && tty.isatty(1); + config.interactive = ( + process.bin === 'bower' && + tty.isatty(1) && + !process.env.CI + ); } // If `analytics` hasn't been explicitly set, we disable // it when ran programatically. if (config.analytics == null) { // Don't enable analytics on CI server unless explicitly configured. - config.analytics = config.interactive && !process.env.CI; + config.analytics = config.interactive; } // Merge common CLI options into the config diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index c1e205287..c7c15e013 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -1,10 +1,8 @@ -var cardinal = require('cardinal'); var chalk = require('chalk'); var path = require('path'); var mout = require('mout'); var archy = require('archy'); var Q = require('q'); -var inquirer = require('inquirer'); var stringifyObject = require('stringify-object'); var os = require('os'); var pkg = require(path.join(__dirname, '../..', 'package.json')); @@ -106,6 +104,7 @@ StandardRenderer.prototype.prompt = function (prompts) { // Prompt deferred = Q.defer(); + var inquirer = require('inquirer'); inquirer.prompt(prompts, deferred.resolve); return deferred.promise; @@ -394,6 +393,8 @@ StandardRenderer.prototype._write = function (stream, str) { }; StandardRenderer.prototype._highlightJson = function (json) { + var cardinal = require('cardinal'); + return cardinal.highlight(stringifyObject(json, { indent: ' ' }), { theme: { String: { diff --git a/lib/util/analytics.js b/lib/util/analytics.js index 87d1bf69e..6638e410d 100644 --- a/lib/util/analytics.js +++ b/lib/util/analytics.js @@ -1,26 +1,31 @@ var Q = require('q'); -var Insight = require('insight'); var mout = require('mout'); -var config = require('../config'); -var pkg = require('../../package.json'); var analytics = module.exports; var insight; // Initializes the application-wide insight singleton and asks for the // permission on the CLI during the first run. -analytics.setup = function setup() { +analytics.setup = function setup(config) { var deferred = Q.defer(); - insight = new Insight({ - trackingCode: 'UA-43531210-1', - packageName: pkg.name, - packageVersion: pkg.version - }); // Display the ask prompt only if it hasn't been answered before // and the current session is looking to configure the analytics. - if (insight.optOut === undefined && config.analytics) { - insight.askPermission(null, deferred.resolve); + if (config.analytics) { + var Insight = require('insight'); + var pkg = require('../../package.json'); + + insight = new Insight({ + trackingCode: 'UA-43531210-1', + packageName: pkg.name, + packageVersion: pkg.version + }); + + if (insight.optOut === undefined) { + insight.askPermission(null, deferred.resolve); + } else { + deferred.resolve(); + } } else { deferred.resolve(); } From 42f02688291e8df8f0e382b26a903319f1028daf Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 12 Apr 2014 22:10:37 +0200 Subject: [PATCH 0353/1021] perf: Use the same mout version as bower --- packages/bower-endpoint-parser/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-endpoint-parser/package.json b/packages/bower-endpoint-parser/package.json index e0d8039aa..3ead8af87 100644 --- a/packages/bower-endpoint-parser/package.json +++ b/packages/bower-endpoint-parser/package.json @@ -20,7 +20,7 @@ "devDependencies": { "expect.js": "~0.2.0", "mocha": "~1.12.0", - "mout": "~0.6.0" + "mout": "~0.9.0" }, "scripts": { "test": "mocha -R spec" From 2d94018f12a018dd1d484cb181c77e9283bbf76b Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 12 Apr 2014 22:17:56 +0200 Subject: [PATCH 0354/1021] perf: Use only relevant parts of mout --- packages/bower-config/lib/Config.js | 7 ++++--- packages/bower-config/lib/util/expand.js | 10 ++++++---- packages/bower-config/lib/util/rc.js | 13 +++++++------ 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index d9796cf57..7e84bffe1 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -1,4 +1,5 @@ -var mout = require('mout'); +var lang = require('mout/lang'); +var object = require('mout/object'); var rc = require('./util/rc'); var defaults = require('./util/defaults'); var expand = require('./util/expand'); @@ -32,7 +33,7 @@ Config.prototype.save = function (where, callback) { }; Config.prototype.toObject = function () { - var config = mout.lang.deepClone(this._config); + var config = lang.deepClone(this._config); config = Config.normalise(config); return config; @@ -51,7 +52,7 @@ Config.normalise = function (rawConfig) { var config = {}; // Mix in defaults and raw config - mout.object.deepMixIn(config, expand(defaults), expand(rawConfig)); + object.deepMixIn(config, expand(defaults), expand(rawConfig)); // Some backwards compatible things.. config.shorthandResolver = config.shorthandResolver diff --git a/packages/bower-config/lib/util/expand.js b/packages/bower-config/lib/util/expand.js index f3a3865d6..6243f74bb 100644 --- a/packages/bower-config/lib/util/expand.js +++ b/packages/bower-config/lib/util/expand.js @@ -1,17 +1,19 @@ -var mout = require('mout'); +var object = require('mout/object'); +var lang = require('mout/lang'); +var string = require('mout/string'); function camelCase(config) { var camelCased = {}; // Camel case - mout.object.forOwn(config, function (value, key) { + object.forOwn(config, function (value, key) { // Ignore null values if (value == null) { return; } - key = mout.string.camelCase(key.replace(/_/g, '-')); - camelCased[key] = mout.lang.isPlainObject(value) ? camelCase(value) : value; + key = string.camelCase(key.replace(/_/g, '-')); + camelCased[key] = lang.isPlainObject(value) ? camelCase(value) : value; }); return camelCased; diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 54088eac5..8ab86c1be 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -2,7 +2,8 @@ var path = require('path'); var fs = require('graceful-fs'); var optimist = require('optimist'); var osenv = require('osenv'); -var mout = require('mout'); +var object = require('mout/object'); +var string = require('mout/string'); var paths = require('./paths'); var win = process.platform === 'win32'; @@ -16,11 +17,11 @@ function rc(name, defaults, cwd, argv) { argv = argv || optimist.argv; // Parse --config.foo=false - argvConfig = mout.object.map(argv.config || {}, function (value) { + argvConfig = object.map(argv.config || {}, function (value) { return value === 'false' ? false : value; }); - return mout.object.deepMixIn.apply(null, [ + return object.deepMixIn.apply(null, [ {}, defaults, { cwd: cwd }, @@ -75,15 +76,15 @@ function env(prefix) { prefix = prefix.toLowerCase(); - mout.object.forOwn(process.env, function (value, key) { + object.forOwn(process.env, function (value, key) { key = key.toLowerCase(); - if (mout.string.startsWith(key, prefix)) { + if (string.startsWith(key, prefix)) { var parsedKey = key .substr(prefixLength) .replace(/__/g, '.') // __ is used for nesting .replace(/_/g, '-'); // _ is used as a - separator - mout.object.set(obj, parsedKey, value); + object.set(obj, parsedKey, value); } }); From b6107a1198b50fb800f72056ba24d3495909e360 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 12 Apr 2014 22:23:12 +0200 Subject: [PATCH 0355/1021] Use only relevant parts of mout --- packages/bower-endpoint-parser/test/test.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/bower-endpoint-parser/test/test.js b/packages/bower-endpoint-parser/test/test.js index 94b0ecf2b..98e4653c5 100644 --- a/packages/bower-endpoint-parser/test/test.js +++ b/packages/bower-endpoint-parser/test/test.js @@ -1,5 +1,6 @@ var expect = require('expect.js'); -var mout = require('mout'); +var lang = require('mout/lang'); +var object = require('mout/object'); var endpointParser = require('../'); describe('endpoint-parser', function () { @@ -19,7 +20,7 @@ describe('endpoint-parser', function () { 'bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip#latest': { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', target: '*' } }; - mout.object.forOwn(suite, function (decEndpoint, endpoint) { + object.forOwn(suite, function (decEndpoint, endpoint) { expect(endpointParser.decompose(endpoint)).to.eql(decEndpoint); }); }); @@ -52,8 +53,8 @@ describe('endpoint-parser', function () { 'bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip': { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', target: '*' } }; - mout.object.forOwn(suite, function (decEndpoints, endpoint) { - decEndpoints = mout.lang.toArray(decEndpoints); + object.forOwn(suite, function (decEndpoints, endpoint) { + decEndpoints = lang.toArray(decEndpoints); decEndpoints.forEach(function (decEndpoint) { expect(endpointParser.compose(decEndpoint)).to.equal(endpoint); }); @@ -126,7 +127,7 @@ describe('endpoint-parser', function () { }; var x = 0; - mout.object.forOwn(dependencies, function (value, key) { + object.forOwn(dependencies, function (value, key) { expect(endpointParser.json2decomposed(key, value)).to.eql(expected[x]); x += 1; }); @@ -149,7 +150,7 @@ describe('endpoint-parser', function () { }; var x = 0; - mout.object.forOwn(dependencies, function (value, key) { + object.forOwn(dependencies, function (value, key) { expect(endpointParser.json2decomposed(key, value)).to.eql(expected[x]); x += 1; }); From ba33bb6aa4c0ff24b530711f01c76421e1d079ed Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 13 Apr 2014 01:45:41 +0200 Subject: [PATCH 0356/1021] Cache clean and cache list work again, fixes #1232 --- lib/commands/cache/index.js | 4 ---- lib/commands/index.js | 6 +++++- 2 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 lib/commands/cache/index.js diff --git a/lib/commands/cache/index.js b/lib/commands/cache/index.js deleted file mode 100644 index 2961b74c6..000000000 --- a/lib/commands/cache/index.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - clean: require('./clean'), - list: require('./list') -}; diff --git a/lib/commands/index.js b/lib/commands/index.js index 28094a3ab..0bd2cdb07 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -33,12 +33,16 @@ function lazyRequire(id) { } command.line = runFromArgv; + return command; } module.exports = { - cache: lazyRequire('./cache'), + cache: { + clean: lazyRequire('./cache/clean'), + list: lazyRequire('./cache/list') + }, completion: lazyRequire('./completion'), help: lazyRequire('./help'), home: lazyRequire('./home'), From ac95654409c6f32dc336b97e1f547e5cfd374e3c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 13 Apr 2014 00:04:19 +0200 Subject: [PATCH 0357/1021] Discourage using bower components statically, closes #1210 --- README.md | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 5e66c5851..200ed88ce 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ A custom install location can be set in a `.bowerrc` file using the `directory` ```json { - "directory": "public/bower_components" + "directory": "app/components" } ``` @@ -113,17 +113,9 @@ Using just `bower search` will list all packages in the registry. ### Using packages -The easiest approach is to use Bower statically, just reference the package's -installed components manually using a `script` tag: +We discourage using bower components statically for performance and security reasons (if component has an `upload.php` file that is not ignored, that can be easily exploited to do malicious stuff). -```html - -``` - -For more complex projects, you'll probably want to concatenate your scripts or -use a module loader. Bower is just a package manager, but there are plenty of -other tools -- such as [Sprockets](https://github.com/sstephenson/sprockets) -and [RequireJS](http://requirejs.org/) -- that will help you do this. +The best approach is to process components installed by bower with build tool (like [Grunt](http://gruntjs.com/) or [gulp](http://gulpjs.com/)), and serve them concatenated or using module loader (like [RequireJS](http://requirejs.org/)). ### Uninstalling packages From 3cb21d128f809c83337974fd9ef663944b36f0f4 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 18 Apr 2014 14:41:27 +0200 Subject: [PATCH 0358/1021] Forward all events from wrapped command, fixes #1232 --- lib/commands/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/commands/index.js b/lib/commands/index.js index 0bd2cdb07..a8660d95d 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -18,9 +18,8 @@ function lazyRequire(id) { return require(id).apply(undefined, commandArgs); }) .done(function (commandLogger) { - // forward to exposed logger - commandLogger.on('end', logger.emit.bind(logger, 'end')); - commandLogger.on('error', logger.emit.bind(logger, 'error')); + // Forward all events to exposed logger + commandLogger.pipe(logger); }, function (error) { logger.emit('error', error); }); From a91cb546f9e7e4196b3dd98a25e6c77c51884d91 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 22 Apr 2014 14:55:37 +0200 Subject: [PATCH 0359/1021] let npm sort dependencies --- package.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 21032fa13..c9115b553 100644 --- a/package.json +++ b/package.json @@ -36,13 +36,17 @@ "graceful-fs": "~2.0.0", "handlebars": "~1.3.0", "inquirer": "~0.4.0", + "insight": "~0.3.0", + "is-root": "~0.1.0", "junk": "~0.2.2", + "lockfile": "~0.4.2", + "lru-cache": "~2.5.0", "mkdirp": "~0.3.5", "mout": "~0.9.1", "nopt": "~2.1.2", - "lru-cache": "~2.5.0", "open": "~0.0.3", "osenv": "~0.0.3", + "p-throttler": "~0.0.1", "promptly": "~0.2.0", "q": "~1.0.1", "request": "~2.33.0", @@ -50,29 +54,25 @@ "retry": "~0.6.0", "rimraf": "~2.2.0", "semver": "~2.2.1", + "shell-quote": "~1.4.1", "stringify-object": "~0.2.0", "tar": "~0.1.17", "tmp": "~0.0.20", "update-notifier": "~0.1.3", - "which": "~1.0.5", - "p-throttler": "~0.0.1", - "insight": "~0.3.0", - "is-root": "~0.1.0", - "shell-quote": "~1.4.1", - "lockfile": "~0.4.2" + "which": "~1.0.5" }, "devDependencies": { "expect.js": "~0.2.0", "grunt": "~0.4.1", - "grunt-simple-mocha": "~0.4.0", - "grunt-contrib-watch": "~0.5.3", "grunt-contrib-jshint": "~0.8.0", + "grunt-contrib-watch": "~0.5.3", "grunt-exec": "~0.4.2", + "grunt-simple-mocha": "~0.4.0", + "istanbul": "~0.2.4", + "load-grunt-tasks": "~0.3.0", "mocha": "~1.18", "nock": "~0.27.2", - "istanbul": "~0.2.4", - "proxyquire": "~0.5.3", - "load-grunt-tasks": "~0.3.0" + "proxyquire": "~0.5.3" }, "scripts": { "test": "grunt test" From 90922a0ce06d88c5da46ca56bf10bda10e9500fc Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 22 Apr 2014 15:04:42 +0200 Subject: [PATCH 0360/1021] bump deps --- package.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index c9115b553..fe9ab25f2 100644 --- a/package.json +++ b/package.json @@ -20,16 +20,16 @@ }, "dependencies": { "abbrev": "~1.0.4", - "archy": "0.0.2", + "archy": "~0.0.2", "bower-config": "~0.5.0", "bower-endpoint-parser": "~0.2.0", "bower-json": "~0.4.0", "bower-logger": "~0.2.2", - "bower-registry-client": "~0.1.4", + "bower-registry-client": "~0.2.0", "cardinal": "~0.4.0", "chalk": "~0.4.0", "chmodr": "~0.1.0", - "decompress-zip": "~0.0.3", + "decompress-zip": "~0.0.6", "fstream": "~0.1.22", "fstream-ignore": "~0.0.6", "glob": "~3.2.9", @@ -38,18 +38,18 @@ "inquirer": "~0.4.0", "insight": "~0.3.0", "is-root": "~0.1.0", - "junk": "~0.2.2", + "junk": "~0.3.0", "lockfile": "~0.4.2", "lru-cache": "~2.5.0", "mkdirp": "~0.3.5", "mout": "~0.9.1", - "nopt": "~2.1.2", + "nopt": "~2.2.0", "open": "~0.0.3", "osenv": "~0.0.3", "p-throttler": "~0.0.1", "promptly": "~0.2.0", "q": "~1.0.1", - "request": "~2.33.0", + "request": "~2.34.0", "request-progress": "~0.3.0", "retry": "~0.6.0", "rimraf": "~2.2.0", @@ -58,21 +58,21 @@ "stringify-object": "~0.2.0", "tar": "~0.1.17", "tmp": "~0.0.20", - "update-notifier": "~0.1.3", + "update-notifier": "~0.1.8", "which": "~1.0.5" }, "devDependencies": { - "expect.js": "~0.2.0", - "grunt": "~0.4.1", - "grunt-contrib-jshint": "~0.8.0", - "grunt-contrib-watch": "~0.5.3", + "expect.js": "~0.3.1", + "grunt": "~0.4.4", + "grunt-contrib-jshint": "~0.10.0", + "grunt-contrib-watch": "~0.6.1", "grunt-exec": "~0.4.2", "grunt-simple-mocha": "~0.4.0", "istanbul": "~0.2.4", - "load-grunt-tasks": "~0.3.0", + "load-grunt-tasks": "~0.4.0", "mocha": "~1.18", - "nock": "~0.27.2", - "proxyquire": "~0.5.3" + "nock": "~0.28.2", + "proxyquire": "~0.6.0" }, "scripts": { "test": "grunt test" From ba554d5f45b06de43d57f80841e9fc2e98487b18 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 22 Apr 2014 15:07:33 +0200 Subject: [PATCH 0361/1021] use `opn` instead of `open` `open` is buggy on Linux https://github.com/sindresorhus/opn --- lib/commands/home.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/commands/home.js b/lib/commands/home.js index 7c5981f32..73cad5e82 100644 --- a/lib/commands/home.js +++ b/lib/commands/home.js @@ -1,7 +1,7 @@ var mout = require('mout'); var Logger = require('bower-logger'); var Project = require('../core/Project'); -var open = require('open'); +var open = require('opn'); var endpointParser = require('bower-endpoint-parser'); var cli = require('../util/cli'); var createError = require('../util/createError'); diff --git a/package.json b/package.json index fe9ab25f2..3a3284ef6 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "mkdirp": "~0.3.5", "mout": "~0.9.1", "nopt": "~2.2.0", - "open": "~0.0.3", + "opn": "~0.1.1", "osenv": "~0.0.3", "p-throttler": "~0.0.1", "promptly": "~0.2.0", From ff817dad0defd95888251af37c716f77b1492ffd Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 22 Apr 2014 15:13:27 +0200 Subject: [PATCH 0362/1021] various tweaks --- .editorconfig | 4 ++++ .travis.yml | 8 ++++---- Gruntfile.js | 16 ++++++++++++---- README.md | 8 ++++---- bin/bower | 5 ++--- package.json | 7 ++----- 6 files changed, 28 insertions(+), 20 deletions(-) diff --git a/.editorconfig b/.editorconfig index 4020877d6..dda07ce8d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,3 +13,7 @@ trim_trailing_whitespace = false [**.std] insert_final_newline = false + +[{package,bower}.json] +indent_style = space +indent_size = 2 diff --git a/.travis.yml b/.travis.yml index 5c9fdd0b7..cfa167bd1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,9 @@ language: node_js node_js: - - "0.10" - - "0.11" + - '0.10' + - '0.11' matrix: allow_failures: - - node_js: "0.11" + - node_js: '0.11' before_script: - - npm install grunt-cli -g + - npm install -g grunt-cli diff --git a/Gruntfile.js b/Gruntfile.js index 231efd97f..c3d435c86 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,5 +1,5 @@ +'use strict'; module.exports = function (grunt) { - require('load-grunt-tasks')(grunt); grunt.initConfig({ @@ -7,14 +7,23 @@ module.exports = function (grunt) { options: { jshintrc: '.jshintrc' }, - files: ['Gruntfile.js', 'bin/*', 'lib/**/*.js', 'test/**/*.js', '!test/assets/**/*', '!test/reports/**/*'] + files: [ + 'Gruntfile.js', + 'bin/*', + 'lib/**/*.js', + 'test/**/*.js', + '!test/assets/**/*', + '!test/reports/**/*' + ] }, simplemocha: { options: { reporter: 'spec', timeout: '5000' }, - full: { src: ['test/test.js'] }, + full: { + src: ['test/test.js'] + }, short: { options: { reporter: 'dot' @@ -39,7 +48,6 @@ module.exports = function (grunt) { } }); - grunt.registerTask('assets', ['exec:assets-force']); grunt.registerTask('test', ['jshint', 'exec:assets', 'simplemocha:full']); grunt.registerTask('cover', 'exec:cover'); diff --git a/README.md b/README.md index 200ed88ce..7da91145f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bower -[![Build Status](https://secure.travis-ci.org/bower/bower.svg?branch=master)](http://travis-ci.org/bower/bower) +[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) @@ -19,11 +19,11 @@ etc.). ## Installing Bower -Bower depends on [Node](http://nodejs.org/) and [npm](http://npmjs.org/). It's +Bower depends on [Node.js](http://nodejs.org/) and [npm](http://npmjs.org/). It's installed globally using npm: -``` -npm install -g bower +```sh +$ npm install -g bower ``` Also make sure that [git](http://git-scm.com/) is installed as some bower diff --git a/bin/bower b/bin/bower index 0f1f7976f..74755e4a7 100755 --- a/bin/bower +++ b/bin/bower @@ -1,4 +1,5 @@ #!/usr/bin/env node +'use strict'; process.bin = process.title = 'bower'; @@ -8,13 +9,11 @@ var mout = require('mout'); var Logger = require('bower-logger'); var osenv = require('osenv'); var bower = require('../lib'); -var pkg = require(path.join(__dirname, '..', 'package.json')); +var pkg = require('../package.json'); var cli = require('../lib/util/cli'); var rootCheck = require('../lib/util/rootCheck'); var analytics = require('../lib/util/analytics'); -// -------- - var options; var renderer; var loglevel; diff --git a/package.json b/package.json index 3a3284ef6..a87e9b85e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "bower", "version": "1.3.2", - "description": "The browser package manager.", + "description": "The browser package manager", "author": "Twitter", "licenses": [ { @@ -9,10 +9,7 @@ "url": "https://github.com/bower/bower/blob/master/LICENSE" } ], - "repository": { - "type": "git", - "url": "git://github.com/bower/bower.git" - }, + "repository": "bower/bower", "main": "lib", "homepage": "http://bower.io", "engines": { From 8288d2f38bbbaf842cb7e17cc6e8e0693391e62f Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 22 Apr 2014 15:28:29 +0200 Subject: [PATCH 0363/1021] readme improvements --- README.md | 103 +++++++++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index 7da91145f..9c65ab105 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,23 @@ -# Bower - -[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) +# Bower [![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) -Bower is a package manager for the web. It offers a generic, unopinionated -solution to the problem of **front-end package management**, while exposing the -package dependency model via an API that can be consumed by a more opinionated -build stack. There are no system wide dependencies, no dependencies are shared -between different apps, and the dependency tree is flat. +> A package manager for the web -Bower runs over Git, and is package-agnostic. A packaged component can be made -up of any type of asset, and use any type of transport (e.g., AMD, CommonJS, -etc.). +It offers a generic, unopinionated solution to the problem of **front-end package management**, while exposing the package dependency model via an API that can be consumed by a more opinionated build stack. There are no system wide dependencies, no dependencies are shared between different apps, and the dependency tree is flat. -[View all packages available through Bower's registry](http://bower.io/search/). +Bower runs over Git, and is package-agnostic. A packaged component can be made up of any type of asset, and use any type of transport (e.g., AMD, CommonJS, etc.). +[View all packages available through Bower's registry](http://bower.io/search/). -## Installing Bower -Bower depends on [Node.js](http://nodejs.org/) and [npm](http://npmjs.org/). It's -installed globally using npm: +## Install ```sh $ npm install -g bower ``` -Also make sure that [git](http://git-scm.com/) is installed as some bower +Bower depends on [Node.js](http://nodejs.org/) and [npm](http://npmjs.org/). Also make sure that [git](http://git-scm.com/) is installed as some bower packages require it to be fetched and installed. @@ -39,32 +30,39 @@ is just enough to get you started. Bower offers several ways to install packages: -#####Using the dependencies listed in the current directory's bower.json -``` -bower install +##### Using the dependencies listed in the current directory's bower.json + +```sh +$ bower install ``` + ##### Using a local or remote package + +```sh +$ bower install ``` -bower install -``` + ##### Using a specific version of a package + +```sh +$ bower install # ``` -bower install # -``` + ##### Using a different name and a specific version of a package -``` -bower install =# + +```sh +$ bower install =# ``` Where `` can be any one of the following: * A name that maps to a package registered with Bower, e.g, `jquery`. ‡ -* A public remote Git endpoint, e.g., ```git://github.com/someone/some-package.git```. ‡ -* A private Git repository, e.g., ```https://github.com/someone/some-package.git```. If the protocol is https, a prompt will ask for the credentials. ssh can also be used, e.g., ```git@github.com:someone/some-package.git``` and can authenticate with the user's ssh public/private keys. ‡ +* A public remote Git endpoint, e.g., `git://github.com/someone/some-package.git`. ‡ +* A private Git repository, e.g., `https://github.com/someone/some-package.git`. If the protocol is https, a prompt will ask for the credentials. ssh can also be used, e.g., `git@github.com:someone/some-package.git` and can authenticate with the user's ssh public/private keys. ‡ * A local endpoint, i.e., a folder that's a Git repository. ‡ -* A public remote Subversion endpoint, e.g., ```svn+http://package.googlecode.com/svn/```. ‡ -* A private Subversion repository, e.g., ```svn+ssh://package.googlecode.com/svn/``` or ```svn+https://package.googlecode.com/svn/```. ‡ -* A local endpoint, i.e., a folder that's an Subversion repository, e.g., ```svn+file:///path/to/svn/```. ‡ +* A public remote Subversion endpoint, e.g., `svn+http://package.googlecode.com/svn/`. ‡ +* A private Subversion repository, e.g., `svn+ssh://package.googlecode.com/svn/` or `svn+https://package.googlecode.com/svn/`. ‡ +* A local endpoint, i.e., a folder that's an Subversion repository, e.g., `svn+file:///path/to/svn/`. ‡ * A shorthand endpoint, e.g., `someone/some-package` (defaults to GitHub). ‡ * A URL to a file, including `zip` and `tar` files. Its contents will be extracted. @@ -105,8 +103,8 @@ A custom install location can be set in a `.bowerrc` file using the `directory` To search for packages registered with Bower: -``` -bower search [] +```sh +$ bower search [] ``` Using just `bower search` will list all packages in the registry. @@ -121,8 +119,8 @@ The best approach is to process components installed by bower with build tool (l To uninstall a locally installed package: -``` -bower uninstall +```sh +$ bower uninstall ``` @@ -151,16 +149,21 @@ path if needed. ### Using bower's cache Bower supports installing packages from its local cache (without internet connection), if the packages were installed before. + +```sh +$ bower install --offline ``` -bower install --offline -``` + The content of the cache can be listed with: + +```sh +$ bower cache list ``` -bower cache list -``` + The cache can be cleaned with: -``` -bower cache clean + +```sh +$ bower cache clean ``` ## Configuration @@ -195,8 +198,8 @@ release. You can interactively create a `bower.json` with the following command: -``` -bower init +```sh +$ bower init ``` The `bower.json` ([spec](https://github.com/bower/bower.json-spec)) defines several options, including: @@ -245,8 +248,8 @@ To register a new package: Then use the following command: -``` -bower register +```sh +$ bower register ``` The Bower registry does not have authentication or user management at this point @@ -336,23 +339,21 @@ not available for Windows users. This command will output a Bash / ZSH script to put into your `~/.bashrc`, `~/.bash_profile`, or `~/.zshrc` file. +```sh +$ bower completion >> ~/.bash_profile ``` -bower completion >> ~/.bash_profile -``` - -## Contact -Have a question? +## Support * [StackOverflow](http://stackoverflow.com/questions/tagged/bower) * [Mailinglist](http://groups.google.com/group/twitter-bower) - twitter-bower@googlegroups.com * [\#bower](http://webchat.freenode.net/?channels=bower) on Freenode -## Contributing to this project +## Contributing -Anyone and everyone is welcome to contribute. Please take a moment to +We welcome contributions of all kinds from anyone. Please take a moment to review the [guidelines for contributing](CONTRIBUTING.md). * [Bug reports](CONTRIBUTING.md#bugs) From ea3a0d64c11ab3c9a82dd56f2aab75cd43bc5cd9 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 22 Apr 2014 16:01:16 +0200 Subject: [PATCH 0364/1021] make jshint :) --- bin/bower | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/bower b/bin/bower index 74755e4a7..3ae0acb7d 100755 --- a/bin/bower +++ b/bin/bower @@ -4,7 +4,6 @@ process.bin = process.title = 'bower'; var Q = require('q'); -var path = require('path'); var mout = require('mout'); var Logger = require('bower-logger'); var osenv = require('osenv'); From 87faa4f108ecddea42e1457383929520c809b683 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 24 Apr 2014 20:31:22 +0200 Subject: [PATCH 0365/1021] Do not cache moving targets like branches, fixes #1242 --- lib/core/PackageRepository.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/core/PackageRepository.js b/lib/core/PackageRepository.js index 46327d947..902889d21 100644 --- a/lib/core/PackageRepository.js +++ b/lib/core/PackageRepository.js @@ -165,19 +165,26 @@ PackageRepository.clearRuntimeCache = function () { // --------------------- PackageRepository.prototype._resolve = function (resolver, logger) { + var that = this; + // Resolve the resolver return resolver.resolve() // Store in the cache .then(function (canonicalDir) { - return this._resolveCache.store(canonicalDir, resolver.getPkgMeta()); - }.bind(this)) + // We don't want to cache moving targets like branches + if (resolver._resolution && resolver._resolution.type === 'branch') { + return canonicalDir; + } else { + return that._resolveCache.store(canonicalDir, resolver.getPkgMeta()); + } + }) // Resolve promise with canonical dir and package meta .then(function (dir) { var pkgMeta = resolver.getPkgMeta(); logger.info('resolved', resolver.getSource() + (pkgMeta._release ? '#' + pkgMeta._release : '')); return [dir, pkgMeta, resolver.constructor.isTargetable()]; - }.bind(this)); + }); }; PackageRepository.prototype._extendLog = function (log, info) { From d83572803d16b29388b3be0582763b9135f67b8f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 24 Apr 2014 22:35:22 +0200 Subject: [PATCH 0366/1021] Bump, update changelog, update contributors --- CHANGELOG.md | 13 +++++++++++++ README.md | 1 + package.json | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d459644e..d0a30e7f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,26 @@ # Changelog +## 1.3.3 - 2014-04-24 + +- Do not cache moving targets like branches ([#1242](https://github.com/bower/bower/issues/1242)) +- Suppress output if --quiet option is specified ([#1124](https://github.com/bower/bower/pull/1124)) +- Use "svn export" for efficiency ([#1224](https://github.com/bower/bower/pull/1224)) +- Prevent loading insights and analytics on CI ([#1221](https://github.com/bower/bower/issues/1221)) +- Make "bower list" respect custom components directory ([#1237](https://github.com/bower/bower/issues/1237)) +- Improve non-interactive loading performance 2x ([#1238](https://github.com/bower/bower/issues/1238)) +- Load commands only on demand, improving performance ([#1232](https://github.com/bower/bower/pull/1232)) + ## 1.3.2 - 2014-04-05 + - Added yui moduleType [PR #1129](https://github.com/bower/bower/pull/1129) - Fixes for concurrency issues [PR #1211](https://github.com/bower/bower/pull/1211) - `link` now installs package dependencies [PR #891](https://github.com/bower/bower/pull/891) - Improved conflict installation message [Commit](https://github.com/bower/bower/commit/bea533acf87903d4b411bfbaa7df93f852ef46a3) - Add --production switch to "prune" command [PR #1168](https://github.com/bower/bower/pull/1168) + ## 1.3.1 - 2014-03-10 + - No longer ask for permission to gather analytics when running on in a CI environment. diff --git a/README.md b/README.md index 9c65ab105..caee069f9 100644 --- a/README.md +++ b/README.md @@ -371,6 +371,7 @@ review the [guidelines for contributing](CONTRIBUTING.md). * [@benschwarz](https://github.com/benschwarz) * [@sindresorhus](https://github.com/sindresorhus) * [@svnlto](https://github.com/svnlto) +* [@sheerun](https://github.com/sheerun) Thanks for assistance and contributions: diff --git a/package.json b/package.json index a87e9b85e..e83b16fba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.3.2", + "version": "1.3.3", "description": "The browser package manager", "author": "Twitter", "licenses": [ From ac29e24c1b22604014ba391f4c1490be8423be78 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 25 Apr 2014 02:09:10 +0200 Subject: [PATCH 0367/1021] Allow for short commit SHA, closes #990 --- lib/core/resolvers/GitResolver.js | 12 ++++++++++++ test/core/resolvers/gitResolver.js | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/lib/core/resolvers/GitResolver.js b/lib/core/resolvers/GitResolver.js index d6fdb4380..800e1c8d4 100644 --- a/lib/core/resolvers/GitResolver.js +++ b/lib/core/resolvers/GitResolver.js @@ -165,6 +165,18 @@ GitResolver.prototype._findResolution = function (target) { return that._resolution = { type: 'branch', branch: target, commit: branches[target] }; } + if ((/^[a-f0-9]{4,40}$/).test(target)) { + if (target.length < 12) { + that._logger.warn( + 'short-sha', + 'Consider using longer commit SHA to avoid conflicts' + ); + } + + that._resolution = { type: 'commit', commit: target }; + return that._resolution; + } + branches = Object.keys(branches); tags = Object.keys(tags); diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index b4810a612..501d5cedc 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -750,6 +750,27 @@ describe('GitResolver', function () { .done(); }); + it('should resolve to the specified short commit', function (next) { + var resolver; + + GitResolver.refs = function () { + return Q.resolve([ + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master' + ]); + }; + + resolver = create('foo'); + resolver._findResolution('bbbbbbb') + .then(function (resolution) { + expect(resolution).to.eql({ + type: 'commit', + commit: 'bbbbbbb' + }); + next(); + }) + .done(); + }); + it('should resolve to the specified tag if it exists', function (next) { var resolver; From b9de179fe84f27ffa661e5d1139a5519bdde3b44 Mon Sep 17 00:00:00 2001 From: Ben Schwarz Date: Sun, 4 May 2014 13:17:10 +1000 Subject: [PATCH 0368/1021] Add notes about what analytics are used for, who has access and how to disable --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index caee069f9..cf04f7fd0 100644 --- a/README.md +++ b/README.md @@ -343,6 +343,19 @@ This command will output a Bash / ZSH script to put into your `~/.bashrc`, $ bower completion >> ~/.bash_profile ``` +## Analytics + +Bower collects anonymous usage statistics in order to be able to improve bower, and to publically display package and command usage rankings. Data is tracked using Google Analytics and is made available to all bower team members. + +If you'd prefer to disable analytics in Bower altogether, then create either a local, or global `.bowerrc` file with `analytics = false`. + +```json +{ + "analytics": false +} +``` + + ## Support From eebe115b7881c903c1f6da9d5f0994765b60374d Mon Sep 17 00:00:00 2001 From: John Schulz Date: Sun, 4 May 2014 15:11:47 -0700 Subject: [PATCH 0369/1021] Mirror `npm version` format for git tags See https://github.com/bower/bower/pull/961#issuecomment-33981712 and https://github.com/bower/bower/pull/961#issuecomment-35591108 for more context. --- lib/commands/version.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/commands/version.js b/lib/commands/version.js index 5bf80d4ce..4d3c270cc 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -109,14 +109,15 @@ function filterModifiedStatusLines(stdout) { } function gitCommitAndTag(newVersion, message) { - message = message || 'v' + newVersion; + var tag = 'v' + newVersion; + message = message || tag; message = message.replace(/%s/g, newVersion); return Q.nfcall(execFile, 'git', ['add', 'bower.json'], {env: process.env}) .then(function () { return Q.nfcall(execFile, 'git', ['commit', '-m', message], {env: process.env}); }) .then(function () { - return Q.nfcall(execFile, 'git', ['tag', newVersion, '-am', message], {env: process.env}); + return Q.nfcall(execFile, 'git', ['tag', tag, '-am', message], {env: process.env}); }); } @@ -137,4 +138,4 @@ version.completion = function () { // TODO: }; -module.exports = version; \ No newline at end of file +module.exports = version; From 410bf4f0cd9547af9acdd6b7b72bc37acd6934e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Nikoli=C4=87?= Date: Wed, 7 May 2014 19:27:44 +0200 Subject: [PATCH 0370/1021] Improve CLI output for conflicts Replace white color with green. --- templates/std/conflict-resolved.std | 4 ++-- templates/std/conflict.std | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/std/conflict-resolved.std b/templates/std/conflict-resolved.std index 6d8049c6c..b6c26732f 100644 --- a/templates/std/conflict-resolved.std +++ b/templates/std/conflict-resolved.std @@ -1,9 +1,9 @@ {{#yellow}}Please note that,{{/yellow}} {{#condense}} {{#each picks}} - {{#if dependants}}{{#white}}{{dependants}}{{/white}}{{else}}none{{/if}} depends on {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#white}}{{endpoint.name}}#{{pkgMeta._release}}{{/white}}{{/if}} + {{#if dependants}}{{#green}}{{dependants}}{{/green}}{{else}}none{{/if}} depends on {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#green}}{{endpoint.name}}#{{pkgMeta._release}}{{/green}}{{/if}} {{/each}} {{/condense}} -Resort to using {{#cyan}}{{suitable.endpoint.name}}#{{resolution}}{{/cyan}} which resolved to {{#white}}{{suitable.endpoint.name}}#{{suitable.pkgMeta._release}}{{/white}} +Resort to using {{#cyan}}{{suitable.endpoint.name}}#{{resolution}}{{/cyan}} which resolved to {{#green}}{{suitable.endpoint.name}}#{{suitable.pkgMeta._release}}{{/green}} Code incompatibilities may occur. diff --git a/templates/std/conflict.std b/templates/std/conflict.std index 86408589f..2a16dd3f7 100644 --- a/templates/std/conflict.std +++ b/templates/std/conflict.std @@ -1,9 +1,9 @@ {{#yellow}}Unable to find a suitable version for {{name}}, please choose one:{{/yellow}} {{#condense}} {{#each picks}} - {{#magenta}}{{sum @index 1}}){{/magenta}} {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#white}}{{pkgMeta._release}}{{/white}}{{/if}}{{#if dependants}} and is required by {{#white}}{{dependants}}{{/white}} {{/if}} + {{#magenta}}{{sum @index 1}}){{/magenta}} {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#green}}{{pkgMeta._release}}{{/green}}{{/if}}{{#if dependants}} and is required by {{#green}}{{dependants}}{{/green}} {{/if}} {{/each}} {{/condense}} {{#unless saveResolutions}} Prefix the choice with ! to persist it to bower.json -{{/unless}} \ No newline at end of file +{{/unless}} From 3fb4f60192a7fe42d60c385fa30fade9212bbfcd Mon Sep 17 00:00:00 2001 From: Daniel Finnie Date: Sun, 11 May 2014 23:06:46 -0400 Subject: [PATCH 0371/1021] Fix Markdown typo in CONTRIBUTING.md --- CONTRIBUTING.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b59a947f0..9600ec166 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,8 +33,6 @@ changes, and helping you finalize your pull requests. ## Using the issue tracker -* - The issue tracker is the preferred channel for [bug reports](#bugs), [features requests](#features) and [submitting pull requests](#pull-requests), but please respect the following restrictions: From 5f0a3fe1c14d24c579090b3e4c3f6b7b92ba9b4b Mon Sep 17 00:00:00 2001 From: Mischa Dasberg Date: Tue, 13 May 2014 14:25:45 +0200 Subject: [PATCH 0372/1021] See: https://github.com/bower/bower/issues/1299 and https://github.com/bower/config/issues/17 --- packages/bower-config/lib/Config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index 7e84bffe1..c07833bf4 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -3,6 +3,7 @@ var object = require('mout/object'); var rc = require('./util/rc'); var defaults = require('./util/defaults'); var expand = require('./util/expand'); +var path = require('path'); function Config(cwd) { this._cwd = cwd || process.cwd(); @@ -11,6 +12,7 @@ function Config(cwd) { Config.prototype.load = function () { this._config = rc('bower', defaults, this._cwd); + this._config.tmp = path.resolve(this._config.tmp); return this; }; From a58b1ccfa52a3b95e437ba52b993780688d47637 Mon Sep 17 00:00:00 2001 From: thomasmulvaney Date: Tue, 20 May 2014 15:26:40 +0200 Subject: [PATCH 0373/1021] Update README.md Fixed sentence which had 'set manually' accidentally repeated. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf04f7fd0..8e5407fee 100644 --- a/README.md +++ b/README.md @@ -178,7 +178,7 @@ in the `Configuration` section. Bower will skip some interactive and analytics operations if it finds a `CI` environmental variable set to `true`. You will find that the `CI` variable is already set for you on many continuous integration servers, e.g., [CircleCI](https://circleci.com/docs/environment-variables#basics) and [Travis-CI](http://docs.travis-ci.com/user/ci-environment/#Environment-variables). -You may try to set manually set `CI` variable manually before running your Bower commands. On Mac or Linux, `export CI=true` and on Windows `set CI=true` +You may try to set the `CI` variable manually before running your Bower commands. On Mac or Linux, `export CI=true` and on Windows `set CI=true` ### Interactive configuration From 23fbbb51915d532a23ce0faafcc140663fbc008e Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Tue, 20 May 2014 14:46:41 +0100 Subject: [PATCH 0374/1021] Resolve a situation in which the install process gets into an infinite loop --- lib/core/Project.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/Project.js b/lib/core/Project.js index a292c69e7..70238ec2d 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -55,7 +55,7 @@ Project.prototype.install = function (decEndpoints, options) { } else { resolved[name] = node; } - }); + }, true); // Add decomposed endpoints as targets decEndpoints = decEndpoints || []; From 5dd6a3883a8f9c6dca655e3288c05f9ac8a2350c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 20 May 2014 23:47:47 +0200 Subject: [PATCH 0375/1021] Add info about unimplemented features, closes #11 --- packages/bower-config/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index e9f4ef5f8..fcc401217 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -11,25 +11,25 @@ The config spec can be read [here](https://docs.google.com/document/d/1APq7oA9tN Loads the bower configuration from the configuration files. -#### .get(key) +#### .get(key) - NOT YET IMPLEMENTED Returns a configuration value by `key`. Keys with dots are supported to access deep values. -#### .set(key, value) +#### .set(key, value) - NOT YET IMPLEMENTED Sets a configuration value for `key`. Keys with dots are supported to set deep values. -#### .del(key) +#### .del(key) - NOT YET IMPLEMENTED Removes configuration named `key`. Keys with dots are supported to delete deep keys. -#### .save(where, callback) +#### .save(where, callback) - NOT YET IMPLEMENTED Saves changes to `where`. The `where` argument can be a path to a configuration file or: From 44d23097009c4e63ed3df3254ed3e7d4cb60b073 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 21 May 2014 00:17:40 +0200 Subject: [PATCH 0376/1021] Bump version --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 297f5f4ee..a7d99f462 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.5.0", + "version": "0.5.1", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From adf59d78d73c40a0cb5e44cfb90aa847ef735e44 Mon Sep 17 00:00:00 2001 From: Nadeesha Cabral Date: Wed, 21 May 2014 12:22:13 +0530 Subject: [PATCH 0377/1021] Fixing minor syntax errors --- packages/bower-logger/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/bower-logger/README.md b/packages/bower-logger/README.md index 524f98107..c75d22716 100644 --- a/packages/bower-logger/README.md +++ b/packages/bower-logger/README.md @@ -7,32 +7,32 @@ The logger used in the various architecture components of Bower. ### .error(id, message, data) -Alias to `.log('error', id. message, data)` +Alias to `.log('error', id, message, data)` ### .conflict(id, message, data) -Alias to `.log('conflict', id. message, data)` +Alias to `.log('conflict', id, message, data)` ### .warn(id, message, data) -Alias to `.log('warn', id. message, data)` +Alias to `.log('warn', id, message, data)` ### .action(id, message, data) -Alias to `.log('action', id. message, data)` +Alias to `.log('action', id, message, data)` ### .info(id, message, data) -Alias to `.log('info', id. message, data)` +Alias to `.log('info', id, message, data)` ### .debug(id, message, data) -Alias to `.log('debug', id. message, data)` +Alias to `.log('debug', id, message, data)` ### .log(level, id, message, data) From b95d5f9f231a14ee1dc5d92b5bef447caed8d855 Mon Sep 17 00:00:00 2001 From: Mischa Dasberg Date: Wed, 21 May 2014 11:02:19 +0200 Subject: [PATCH 0378/1021] moved tmp resolve from load to normalize method --- packages/bower-config/lib/Config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index c07833bf4..7da02e916 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -12,7 +12,6 @@ function Config(cwd) { Config.prototype.load = function () { this._config = rc('bower', defaults, this._cwd); - this._config.tmp = path.resolve(this._config.tmp); return this; }; @@ -67,6 +66,7 @@ Config.normalise = function (rawConfig) { }); config.registry.register = config.registry.register.replace(/\/+$/, ''); config.registry.publish = config.registry.publish.replace(/\/+$/, ''); + config.tmp = path.resolve(config.tmp); return config; }; From 98c77ffe180582c2fe20a39a11b7c02be194215f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 21 May 2014 14:20:25 +0200 Subject: [PATCH 0379/1021] Bump to 0.2.1 --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index f3543b80b..94724221e 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.2.0", + "version": "0.2.1", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From 3c9082ece3de35b458879c587464888034b86c2d Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Mon, 2 Jun 2014 14:42:43 +0900 Subject: [PATCH 0380/1021] Update .jshintrc for JSHint v2.5.x --- packages/bower-json/.jshintrc | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/packages/bower-json/.jshintrc b/packages/bower-json/.jshintrc index eae6f9cf4..3c98d3c11 100644 --- a/packages/bower-json/.jshintrc +++ b/packages/bower-json/.jshintrc @@ -1,17 +1,8 @@ { - "predef": [ - "console", - "describe", - "it", - "after", - "afterEach", - "before", - "beforeEach" - ], - "indent": 4, "node": true, "devel": true, + "mocha": true, "bitwise": false, "curly": false, @@ -29,7 +20,6 @@ "unused": true, "quotmark": "single", "strict": false, - "trailing": true, "camelcase": true, "asi": false, @@ -51,12 +41,8 @@ "onecase": true, "regexdash": false, "scripturl": false, - "smarttabs": false, "shadow": false, "sub": false, "supernew": true, - "validthis": false, - - "nomen": false, - "white": true + "validthis": false } From f8523259061f84fcd65eac6960def1762c6c65af Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Mon, 2 Jun 2014 14:43:08 +0900 Subject: [PATCH 0381/1021] Update graceful-fs and mocha --- packages/bower-json/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index b572b7b3d..9192cdf93 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -19,12 +19,12 @@ }, "dependencies": { "deep-extend": "~0.2.5", - "graceful-fs": "~2.0.0", + "graceful-fs": "~3.0.0", "intersect": "~0.1.0" }, "devDependencies": { "expect.js": "~0.3.1", - "mocha": "~1.18.2", + "mocha": "~1.20.0", "grunt": "~0.4.4", "grunt-contrib-watch": "~0.6.1", "grunt-contrib-jshint": "~0.10.0", From 7138d3518e1b3ed2f1f7d5863d444218bd32fd18 Mon Sep 17 00:00:00 2001 From: Shinnosuke Watanabe Date: Mon, 2 Jun 2014 17:22:49 +0900 Subject: [PATCH 0382/1021] Fix CI setting to pass the test against Node v0.8 --- packages/bower-json/.travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/bower-json/.travis.yml b/packages/bower-json/.travis.yml index 7ab092601..9e6247c3e 100644 --- a/packages/bower-json/.travis.yml +++ b/packages/bower-json/.travis.yml @@ -1,4 +1,5 @@ -before_script: +before_install: + - npm install -g npm - npm install -g grunt-cli language: node_js node_js: From e9588279c81faad4324083daaddf8c752c82b4cf Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Mon, 2 Jun 2014 15:21:04 +0100 Subject: [PATCH 0383/1021] Updated changelog for v1.3.4 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0a30e7f9..27ff1b6b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 1.3.4 - 2014-06-02 + +- Resolve a situation in which the install process gets into an infinite loop ([#1169](https://github.com/bower/bower/issues/1169)) +- Improved CLI output for conflicts ([#1284](https://github.com/bower/bower/issues/1284)) +- Changed `bower version` to mirror the tag format of `npm version` ([#1278](https://github.com/bower/bower/issues/1278)) +- Allow short commit SHAs to be used ([#990](https://github.com/bower/bower/issues/990)) + ## 1.3.3 - 2014-04-24 - Do not cache moving targets like branches ([#1242](https://github.com/bower/bower/issues/1242)) From 6c2de4a35988d1522ec613417f62527c490f35ed Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Mon, 2 Jun 2014 15:22:18 +0100 Subject: [PATCH 0384/1021] 1.3.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e83b16fba..9af4ebcc7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.3.3", + "version": "1.3.4", "description": "The browser package manager", "author": "Twitter", "licenses": [ From a965b054006075d132ad09f8888d9dd7c0b35c68 Mon Sep 17 00:00:00 2001 From: Sergey Tatarintsev Date: Wed, 21 May 2014 18:33:21 +0400 Subject: [PATCH 0385/1021] Search compatible versions in fetching packages Previous version of code reported endpoints that does not have pckMeta (not downloaded) yet and does not have exactly equal targets as incompatible. This caused some package to be downloaded multiple times and caused conflict errors (#1147). This patch adds proper code for searching compatible version in currently fetching packages basing on targets. It also simplifies check for case when we have resolvedVersion and candidate's target is range. --- lib/core/Manager.js | 47 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 6bc4a6ddc..3e78f678c 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -795,6 +795,10 @@ Manager.prototype._areCompatible = function (candidate, resolved) { var resolvedVersion; var highestCandidate; var highestResolved; + var candidateIsRange = semver.validRange(candidate.target); + var resolvedIsRange = semver.validRange(resolved.target); + var candidateIsVersion = semver.valid(candidate.target); + var resolvedIsVersion = semver.valid(resolved.target); // Check if targets are equal if (candidate.target === resolved.target) { @@ -802,25 +806,46 @@ Manager.prototype._areCompatible = function (candidate, resolved) { } resolvedVersion = resolved.pkgMeta && resolved.pkgMeta.version; + // If there is no pkgMeta, resolvedVersion is downloading now + // Check based on target requirements if (!resolvedVersion) { + // If one of the targets is range and other is version, + // check version against the range + if (candidateIsVersion && resolvedIsRange) { + return semver.satisfies(candidate.target, resolved.target); + } + + if (resolvedIsVersion && candidateIsRange) { + return semver.satisfies(resolved.target, candidate.target); + } + + if (resolvedIsVersion && candidateIsVersion) { + return semver.eq(resolved.target, candidate.target); + } + + // If both targets are range, check that both have same + // higher cap + if (resolvedIsRange && candidateIsRange) { + highestCandidate = this._getCap(semver.toComparators(candidate.target), 'highest'); + highestResolved = this._getCap(semver.toComparators(resolved.target), 'highest'); + if (!highestResolved.version || !highestCandidate.version) { + return; + } + + return semver.eq(highestCandidate.version, highestResolved.version) && + highestCandidate.comparator === highestResolved.comparator; + } return false; } // If target is a version, compare against the resolved version - if (semver.valid(candidate.target)) { + if (candidateIsVersion) { return semver.eq(candidate.target, resolvedVersion); } - // If target is a range, check if the max versions of the range are the same - // and if the resolved version satisfies the candidate target - if (semver.validRange(candidate.target) && semver.validRange(resolved.target)) { - highestCandidate = this._getCap(semver.toComparators(candidate.target), 'highest'); - highestResolved = this._getCap(semver.toComparators(resolved.target), 'highest'); - - return highestCandidate.version && highestResolved.version && - semver.eq(highestCandidate.version, highestResolved.version) && - highestCandidate.comparator === highestResolved.comparator && - semver.satisfies(resolvedVersion, candidate.target); + // If target is a range, check if resolved version satisfies it + if (candidateIsRange) { + return semver.satisfies(resolvedVersion, candidate.target); } return false; From 034326c984658c15864ab7f846dbe91c5ad2c99f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 5 Jun 2014 23:52:48 +0200 Subject: [PATCH 0386/1021] Add some tests and documentation for #1310 --- lib/core/Manager.js | 63 +++++++++- test/core/Manager.js | 271 +++++++++++++++++++++++++++++++++++++++++++ test/test.js | 1 + 3 files changed, 332 insertions(+), 3 deletions(-) create mode 100644 test/core/Manager.js diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 3e78f678c..883813938 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -791,6 +791,20 @@ Manager.prototype._storeResolution = function (pick) { this._resolutions[name] = resolution; }; +/** + * Checks if some endpoint is compatible with already resolved target. + * + * It is used in two situations: + * * checks if resolved component matches dependency constraint + * * checks if not resolved component matches alredy fetched component + * + * If candidate matches already resolved component, it won't be downloaded. + * + * @param {Endpoint} candidate endpoint + * @param {Endpoint} resolved endpoint + * + * @return {Boolean} + */ Manager.prototype._areCompatible = function (candidate, resolved) { var resolvedVersion; var highestCandidate; @@ -826,10 +840,14 @@ Manager.prototype._areCompatible = function (candidate, resolved) { // If both targets are range, check that both have same // higher cap if (resolvedIsRange && candidateIsRange) { - highestCandidate = this._getCap(semver.toComparators(candidate.target), 'highest'); - highestResolved = this._getCap(semver.toComparators(resolved.target), 'highest'); + highestCandidate = + this._getCap(semver.toComparators(candidate.target), 'highest'); + highestResolved = + this._getCap(semver.toComparators(resolved.target), 'highest'); + + // This never happens, but you can't be sure without tests if (!highestResolved.version || !highestCandidate.version) { - return; + return false; } return semver.eq(highestCandidate.version, highestResolved.version) && @@ -851,6 +869,28 @@ Manager.prototype._areCompatible = function (candidate, resolved) { return false; }; +/** + * Gets highest/lowest version from set of comparators. + * + * The only thing that matters for this function is version number. + * Returned comparator is splitted to comparator and version parts. + * + * It is used to receive lowest / highest bound of toComparators result: + * semver.toComparators('~0.1.1') // => [ [ '>=0.1.1-0', '<0.2.0-0' ] ] + * + * Examples: + * + * _getCap([['>=2.1.1-0', '<2.2.0-0'], '<3.2.0'], 'highest') + * // => { comparator: '<', version: '3.2.0' } + * + * _getCap([['>=2.1.1-0', '<2.2.0-0'], '<3.2.0'], 'lowest') + * // => { comparator: '>=', version: '2.1.1-0' } + * + * @param {Array.} comparators + * @param {string} side, 'highest' (default) or 'lowest' + * + * @return {{ comparator: string, version: string }} + */ Manager.prototype._getCap = function (comparators, side) { var matches; var candidate; @@ -886,6 +926,23 @@ Manager.prototype._getCap = function (comparators, side) { return cap; }; +/** + * Filters out unique endpoints, comparing by name and then source. + * + * It leaves last matching endpoint. + * + * Examples: + * + * manager._uniquify([ + * { name: 'foo', source: 'google.com' }, + * { name: 'foo', source: 'facebook.com' } + * ]); + * // => { name: 'foo', source: 'facebook.com' } + * + * @param {Array.} decEndpoints + * @return {Array.} Filtered elements of decEndpoints + * + */ Manager.prototype._uniquify = function (decEndpoints) { var length = decEndpoints.length; diff --git a/test/core/Manager.js b/test/core/Manager.js new file mode 100644 index 000000000..06f6db34f --- /dev/null +++ b/test/core/Manager.js @@ -0,0 +1,271 @@ +var expect = require('expect.js'); +var path = require('path'); +var mout = require('mout'); +var rimraf = require('rimraf'); +var Logger = require('bower-logger'); +var Manager = require('../../lib/core/Manager'); +var defaultConfig = require('../../lib/config'); + +describe('Manager', function () { + var manager; + + var packagesCacheDir = + path.join(__dirname, '../assets/temp-resolve-cache'); + + var registryCacheDir = + path.join(__dirname, '../assets/temp-registry-cache'); + + after(function () { + rimraf.sync(registryCacheDir); + rimraf.sync(packagesCacheDir); + }); + + beforeEach(function (next) { + var logger = new Logger(); + + var config = mout.object.deepMixIn({}, defaultConfig, { + storage: { + packages: packagesCacheDir, + registry: registryCacheDir + } + }); + + manager = new Manager(config, logger); + + next(); + }); + + + describe('_areCompatible', function () { + describe('resolved is being fetched', function() { + + it('accepts endpoints with same targets', function () { + expect(manager._areCompatible( + { name: 'foo', target: 'xxx' }, + { name: 'bar', target: 'xxx' } + )).to.be(true); + }); + + it('rejects endpoints with different targets', function () { + expect(manager._areCompatible( + { name: 'foo', target: 'xxx' }, + { name: 'bar', target: 'yyy' } + )).to.be(false); + }); + + it('accepts with version and matching range', function () { + expect(manager._areCompatible( + { name: 'foo', target: '0.1.2' }, + { name: 'bar', target: '~0.1.0' } + )).to.be(true); + }); + + it('rejects with version and non-matching range', function () { + expect(manager._areCompatible( + { name: 'foo', target: '0.1.2' }, + { name: 'bar', target: '~0.1.3' } + )).to.be(false); + }); + + it('accepts with matching range and version', function () { + expect(manager._areCompatible( + { name: 'foo', target: '~0.1.0' }, + { name: 'bar', target: '0.1.2' } + )).to.be(true); + }); + + it('accepts with non-matching range and version', function () { + expect(manager._areCompatible( + { name: 'foo', target: '~0.1.3' }, + { name: 'bar', target: '0.1.2' } + )).to.be(false); + }); + + it('accepts with matching ranges', function () { + expect(manager._areCompatible( + { name: 'foo', target: '~0.1.0' }, + { name: 'bar', target: '~0.1.3' } + )).to.be(true); + }); + + it('rejects with non-matching ranges', function () { + expect(manager._areCompatible( + { name: 'foo', target: '~0.1.0' }, + { name: 'bar', target: '~0.2.3' } + )).to.be(false); + }); + + it('rejects with non-matching ranges', function () { + expect(manager._areCompatible( + { name: 'foo', target: '~0.1.0' }, + { name: 'bar', target: 'xxx' } + )).to.be(false); + }); + }); + + describe('resolved is already fetched', function () { + var resolved = { + name: 'foo', + target: '~1.2.1', + pkgMeta: { + version: '1.2.3' + } + }; + + it('accepts if the same version as resolved', function () { + expect(manager._areCompatible( + { name: 'foo', target: '1.2.3' }, + resolved + )).to.be(true); + }); + + it('rejects if different version than resolved', function () { + expect(manager._areCompatible( + { name: 'foo', target: '1.2.4' }, + resolved + )).to.be(false); + }); + + it('accepts if range matches resolved version', function () { + expect(manager._areCompatible( + { name: 'foo', target: '~1.2.1' }, + resolved + )).to.be(true); + }); + + it('rejects if range does not match', function () { + expect(manager._areCompatible( + { name: 'foo', target: '~1.2.4' }, + resolved + )).to.be(false); + }); + }); + }); + + describe('_getCap', function () { + it('finds highest bound', function () { + var highest = manager._getCap( + [['2.1.1-0', '<2.2.0-0'], '<3.2.0'], + 'highest' + ); + + expect(highest).to.eql({ + version: '3.2.0', + comparator: '<' + }); + }); + + it('finds lowest bound', function () { + var highest = manager._getCap( + [['2.1.1-0', '<2.2.0-0'], '<3.2.0'], + 'lowest' + ); + + expect(highest).to.eql({ + version: '2.1.1-0', + comparator: '' + }); + }); + + it('defaults to highest bound', function () { + var highest = manager._getCap( + ['1.0.0', '2.0.0'] + ); + + expect(highest).to.eql({ + version: '2.0.0', + comparator: '' + }); + }); + + + it('ignores non-semver elements', function () { + var highest = manager._getCap( + ['0.9', '>1.0.1', ['<1.0.0', 'lol']] + ); + + expect(highest).to.eql({ + version: '1.0.1', + comparator: '>' + }); + }); + + it('returns empty object if cap is not found', function () { + var highest = manager._getCap( + ['0.9'] // Not a semver + ); + + expect(highest).to.eql({}); + }); + }); + + describe('_uniquify', function () { + + it('leaves last unique element', function () { + var unique = manager._uniquify([ + { name: 'foo', id: 1 }, + { name: 'foo', id: 2 } + ]); + expect(unique).to.eql([ + { name: 'foo', id: 2 } + ]); + }); + + it('compares by name first', function () { + var unique = manager._uniquify([ + { name: 'foo', source: 'google.com' }, + { name: 'foo', source: 'facebook.com' } + ]); + + expect(unique).to.eql([ + { name: 'foo', source: 'facebook.com' } + ]); + }); + + it('compares by source if name is not available', function () { + var unique = manager._uniquify([ + { source: 'facebook.com' }, + { source: 'facebook.com' } + ]); + + expect(unique).to.eql([ + { source: 'facebook.com' } + ]); + }); + + it('leaves different targets intact', function() { + var unique = manager._uniquify([ + { source: 'facebook.com', target: 'a1b2c3' }, + { source: 'facebook.com', target: 'ffffff' } + ]); + + expect(unique).to.eql([ + { source: 'facebook.com', target: 'a1b2c3' }, + { source: 'facebook.com', target: 'ffffff' } + ]); + }); + + it('removes if same targets', function() { + var unique = manager._uniquify([ + { source: 'facebook.com', target: 'ffffff' }, + { source: 'facebook.com', target: 'ffffff' } + ]); + + expect(unique).to.eql([ + { source: 'facebook.com', target: 'ffffff' } + ]); + }); + + it('ignores other fields', function() { + var unique = manager._uniquify([ + { source: 'facebook.com', foo: 12 }, + { source: 'facebook.com', bar: 13 } + ]); + + expect(unique).to.eql([ + { source: 'facebook.com', bar: 13 } + ]); + }); + }); + +}); diff --git a/test/test.js b/test/test.js index f8576dc00..1a4a69d93 100644 --- a/test/test.js +++ b/test/test.js @@ -17,3 +17,4 @@ require('./core/resolverFactory'); require('./core/resolveCache'); require('./core/packageRepository'); require('./core/scripts'); +require('./core/Manager'); From a98a0b1ac224f20de38db69ff2f4664e3854981c Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Fri, 6 Jun 2014 11:31:37 +0100 Subject: [PATCH 0387/1021] Release 1.3.5 --- CHANGELOG.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27ff1b6b6..9dd3c4b11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## 1.3.5 - 2014-06-06 +- Search compatible versions in fetching packages ([#1147](https://github.com/bower/bower/issues/1147)) + ## 1.3.4 - 2014-06-02 - Resolve a situation in which the install process gets into an infinite loop ([#1169](https://github.com/bower/bower/issues/1169)) diff --git a/package.json b/package.json index 9af4ebcc7..c99e2ff6c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.3.4", + "version": "1.3.5", "description": "The browser package manager", "author": "Twitter", "licenses": [ From 2f02e49716d4a3ad9c9003c20971f2c73c50242d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 8 Jun 2014 18:46:39 +0200 Subject: [PATCH 0388/1021] Always ignore bower.json as said in spec --- lib/util/removeIgnores.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/util/removeIgnores.js b/lib/util/removeIgnores.js index 4cd24e9fc..9a0b5e463 100644 --- a/lib/util/removeIgnores.js +++ b/lib/util/removeIgnores.js @@ -17,6 +17,7 @@ function removeIgnores(dir, ignore) { }); reader.addIgnoreRules(ignore); + reader.addIgnoreRules(['!bower.json']); // Monkey patch applyIgnores such that we get hold of all ignored files applyIgnores = reader.applyIgnores; From f816a5b0da15666562ba91a75d6e2270ecc17b53 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 9 Jun 2014 03:09:22 +0200 Subject: [PATCH 0389/1021] Bump tmp version to 0.0.23, #988 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c99e2ff6c..4c1d1c74d 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "shell-quote": "~1.4.1", "stringify-object": "~0.2.0", "tar": "~0.1.17", - "tmp": "~0.0.20", + "tmp": "~0.0.23", "update-notifier": "~0.1.8", "which": "~1.0.5" }, From 4f838685d6ecd521a372cb87108ffbdfaad1dc6e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 9 Jun 2014 03:28:08 +0200 Subject: [PATCH 0390/1021] Bump to 0.5.2 --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index a7d99f462..52c260efc 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.5.1", + "version": "0.5.2", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 0a0a490a38a2e16b1ea6beddad7587ecdf86abf4 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 10 Jun 2014 22:18:26 +0200 Subject: [PATCH 0391/1021] bump deps --- package.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 4c1d1c74d..5309d2142 100644 --- a/package.json +++ b/package.json @@ -29,28 +29,28 @@ "decompress-zip": "~0.0.6", "fstream": "~0.1.22", "fstream-ignore": "~0.0.6", - "glob": "~3.2.9", - "graceful-fs": "~2.0.0", + "glob": "~4.0.2", + "graceful-fs": "~3.0.1", "handlebars": "~1.3.0", - "inquirer": "~0.4.0", + "inquirer": "~0.5.1", "insight": "~0.3.0", "is-root": "~0.1.0", "junk": "~0.3.0", "lockfile": "~0.4.2", "lru-cache": "~2.5.0", - "mkdirp": "~0.3.5", + "mkdirp": "~0.5.0", "mout": "~0.9.1", - "nopt": "~2.2.0", + "nopt": "~3.0.0", "opn": "~0.1.1", - "osenv": "~0.0.3", + "osenv": "~0.1.0", "p-throttler": "~0.0.1", "promptly": "~0.2.0", "q": "~1.0.1", - "request": "~2.34.0", + "request": "~2.36.0", "request-progress": "~0.3.0", "retry": "~0.6.0", "rimraf": "~2.2.0", - "semver": "~2.2.1", + "semver": "~2.3.0", "shell-quote": "~1.4.1", "stringify-object": "~0.2.0", "tar": "~0.1.17", @@ -67,9 +67,9 @@ "grunt-simple-mocha": "~0.4.0", "istanbul": "~0.2.4", "load-grunt-tasks": "~0.4.0", - "mocha": "~1.18", - "nock": "~0.28.2", - "proxyquire": "~0.6.0" + "mocha": "~1.20.1", + "nock": "~0.34.1", + "proxyquire": "~1.0.1" }, "scripts": { "test": "grunt test" From 745060f0b5aa76c3e49233a40b2bfd93d283049c Mon Sep 17 00:00:00 2001 From: Ray Shan Date: Fri, 13 Jun 2014 23:30:12 +0200 Subject: [PATCH 0392/1021] Close GH-1348: Updated Analytics section of readme.md with link to stats.bower.io. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8e5407fee..aadf2d921 100644 --- a/README.md +++ b/README.md @@ -345,9 +345,9 @@ $ bower completion >> ~/.bash_profile ## Analytics -Bower collects anonymous usage statistics in order to be able to improve bower, and to publically display package and command usage rankings. Data is tracked using Google Analytics and is made available to all bower team members. +Bower can collect anonymous usage statistics. This allows the community to improve Bower and publicly display insights into CLI usage and packages at [stats.bower.io](http://stats.bower.io). -If you'd prefer to disable analytics in Bower altogether, then create either a local, or global `.bowerrc` file with `analytics = false`. +Data is tracked using Google Analytics and instrumented via [Insight](https://github.com/yeoman/insight). It is made available to all bower team members. Tracking is opt-in upon initial usage. If you'd prefer to disable analytics altogether, you can manually opt-out, or create either a local, or global `.bowerrc` file with below flag: ```json { From a86087ed7cc0c7191b4946f6e18bdfb33d7a3de5 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 13 Jun 2014 23:32:05 +0200 Subject: [PATCH 0393/1021] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aadf2d921..57325177a 100644 --- a/README.md +++ b/README.md @@ -347,7 +347,7 @@ $ bower completion >> ~/.bash_profile Bower can collect anonymous usage statistics. This allows the community to improve Bower and publicly display insights into CLI usage and packages at [stats.bower.io](http://stats.bower.io). -Data is tracked using Google Analytics and instrumented via [Insight](https://github.com/yeoman/insight). It is made available to all bower team members. Tracking is opt-in upon initial usage. If you'd prefer to disable analytics altogether, you can manually opt-out, or create either a local, or global `.bowerrc` file with below flag: +Data is tracked using Google Analytics and instrumented via [Insight](https://github.com/yeoman/insight). It is made available to all bower team members. Tracking is opt-in upon initial usage. If you'd prefer to disable analytics altogether, you can manually opt-out, or create either a local, or global `.bowerrc` file with: ```json { From 1690dd4728c56803093428a61154300530f6cdd9 Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Sun, 25 Aug 2013 13:13:08 -0700 Subject: [PATCH 0394/1021] Warn users when installing package with missing properties. Fix for issue #694. Test case included. --- lib/core/resolvers/Resolver.js | 14 ++++++++++++-- test/core/resolvers/resolver.js | 26 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/core/resolvers/Resolver.js b/lib/core/resolvers/Resolver.js index ee17c32e6..ae70a8100 100644 --- a/lib/core/resolvers/Resolver.js +++ b/lib/core/resolvers/Resolver.js @@ -208,19 +208,29 @@ Resolver.prototype._applyPkgMeta = function (meta) { }; Resolver.prototype._savePkgMeta = function (meta) { + var that = this; var contents; // Store original source & target meta._source = this._source; meta._target = this._target; + ['main', 'ignore'].forEach(function (attr) { + if (meta[attr]) return; + + that._logger.log( + 'warn', 'invalid-meta', + (meta.name || 'component') + ' is missing "' + attr + '" entry in bower.json' + ); + }); + // Stringify contents contents = JSON.stringify(meta, null, 2); return Q.nfcall(fs.writeFile, path.join(this._tempDir, '.bower.json'), contents) .then(function () { - return this._pkgMeta = meta; - }.bind(this)); + return that._pkgMeta = meta; + }); }; module.exports = Resolver; diff --git a/test/core/resolvers/resolver.js b/test/core/resolvers/resolver.js index 7357f7a50..24ab1077a 100644 --- a/test/core/resolvers/resolver.js +++ b/test/core/resolvers/resolver.js @@ -784,6 +784,32 @@ describe('Resolver', function () { }) .done(); }); + + it('should warn user for missing attributes in bower.json', function (next) { + var resolver = create('fooooo'); + resolver._tempDir = tempDir; + var notifiedCount = 0; + logger.on('log', function (log) { + notifiedCount ++; + expect(log).to.be.an('object'); + expect(log.level).to.be('warn'); + if (notifiedCount === 1) { + expect(log.message).to.contain('bar is missing "main" entry in bower.json'); + } else { + expect(log.message).to.contain('bar is missing "ignore" entry in bower.json'); + } + }); + resolver._savePkgMeta({ name: 'bar' }); + expect(notifiedCount).to.be(2); + + resolver._savePkgMeta({ name: 'bar', main: 'foo' }); + expect(notifiedCount).to.be(3); + + // should not warn again + resolver._savePkgMeta({ name: 'bar', main: 'flart', ignore: 'blat' }); + expect(notifiedCount).to.be(3); + next(); + }); }); describe('#isTargetable', function () { From b8df18481fdf0ad80ec26adba83d3627d42d144e Mon Sep 17 00:00:00 2001 From: Martin Hansen Date: Tue, 18 Mar 2014 18:19:18 +0100 Subject: [PATCH 0395/1021] Ignore does now not apply to any file in main #547 --- lib/core/resolvers/Resolver.js | 2 +- lib/util/removeIgnores.js | 14 ++++++++++---- test/core/resolvers/resolver.js | 4 +++- test/packages.json | 4 ++++ 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/core/resolvers/Resolver.js b/lib/core/resolvers/Resolver.js index ae70a8100..f5dc47632 100644 --- a/lib/core/resolvers/Resolver.js +++ b/lib/core/resolvers/Resolver.js @@ -201,7 +201,7 @@ Resolver.prototype._applyPkgMeta = function (meta) { } // Otherwise remove them from the temp dir - return removeIgnores(this._tempDir, meta.ignore) + return removeIgnores(this._tempDir, meta) .then(function () { return meta; }); diff --git a/lib/util/removeIgnores.js b/lib/util/removeIgnores.js index 9a0b5e463..0bb04dc8c 100644 --- a/lib/util/removeIgnores.js +++ b/lib/util/removeIgnores.js @@ -4,20 +4,26 @@ var fstreamIgnore = require('fstream-ignore'); var mout = require('mout'); var Q = require('q'); -function removeIgnores(dir, ignore) { +function removeIgnores(dir, meta) { var reader; var applyIgnores; var deferred = Q.defer(); var ignored = []; - var nonIgnored = []; + var nonIgnored = ['bower.json']; + + // Don't ignore main files + nonIgnored = nonIgnored.concat(meta.main || []); + + nonIgnored = nonIgnored.map(function (file) { + return path.join(dir, file); + }); reader = fstreamIgnore({ path: dir, type: 'Directory' }); - reader.addIgnoreRules(ignore); - reader.addIgnoreRules(['!bower.json']); + reader.addIgnoreRules(meta.ignore); // Monkey patch applyIgnores such that we get hold of all ignored files applyIgnores = reader.applyIgnores; diff --git a/test/core/resolvers/resolver.js b/test/core/resolvers/resolver.js index 24ab1077a..9db7e439d 100644 --- a/test/core/resolvers/resolver.js +++ b/test/core/resolvers/resolver.js @@ -676,7 +676,7 @@ describe('Resolver', function () { .done(); }); - it('should remove files that match the ignore patterns', function (next) { + it('should remove files that match the ignore patterns excluding main files', function (next) { var resolver = create({ source: 'foo', name: 'foo' }); mkdirp.sync(tempDir); @@ -701,6 +701,8 @@ describe('Resolver', function () { expect(fs.existsSync(path.join(tempDir, 'foo'))).to.be(true); expect(fs.existsSync(path.join(tempDir, 'baz'))).to.be(true); expect(fs.existsSync(path.join(tempDir, 'test'))).to.be(false); + expect(fs.existsSync(path.join(tempDir, 'bower.json'))).to.be(true); + expect(fs.existsSync(path.join(tempDir, 'main.js'))).to.be(true); expect(fs.existsSync(path.join(tempDir, 'more/docs'))).to.be(false); expect(fs.existsSync(path.join(tempDir, 'more/assets'))).to.be(false); next(); diff --git a/test/packages.json b/test/packages.json index fe2a69fcd..ac4375bd7 100644 --- a/test/packages.json +++ b/test/packages.json @@ -62,12 +62,16 @@ "bar": "bar", "baz": "baz", "more/more-foo": "more-foo", + "main.js": "should not be ignored", "more/docs/doc.html": "doc", "more/assets/styles.css": "css", "bower.json": { "name": "a", "version": "0.2.2", + "main": "main.js", "ignore": [ + "bower.json", + "main.js", "test/", "more/docs", "more/assets/", From 5c839724016680f737fd51ebc07a514e2632d8bd Mon Sep 17 00:00:00 2001 From: Thomas Scholtes Date: Sun, 13 Apr 2014 17:50:29 +0200 Subject: [PATCH 0396/1021] Use promise interface for commands This commit changes the interface of the command functions exported by the files in `lib/commands`. The functions now return a promise and accept a logger as the first argument. This has several advantages * The promise style is consistent with the rest of the code. * It removes a lot of duplicate code. * The command factory does not need to proxy the logger object. --- lib/commands/cache/clean.js | 24 +++------- lib/commands/cache/list.js | 24 +++------- lib/commands/completion.js | 20 ++------ lib/commands/help.js | 36 +++++--------- lib/commands/home.js | 23 ++------- lib/commands/index.js | 69 +++++++++++++++------------ lib/commands/info.js | 25 +++------- lib/commands/init.js | 24 +++------- lib/commands/install.js | 18 ++----- lib/commands/link.js | 53 ++++++--------------- lib/commands/list.js | 21 +++------ lib/commands/lookup.js | 27 +++-------- lib/commands/prune.js | 17 ++----- lib/commands/register.js | 94 ++++++++++++++++--------------------- lib/commands/search.js | 29 +++--------- lib/commands/uninstall.js | 22 +++------ lib/commands/update.js | 18 ++----- lib/commands/version.js | 17 ++----- 18 files changed, 183 insertions(+), 378 deletions(-) diff --git a/lib/commands/cache/clean.js b/lib/commands/cache/clean.js index 411cfcabc..2bcd2844e 100644 --- a/lib/commands/cache/clean.js +++ b/lib/commands/cache/clean.js @@ -3,15 +3,13 @@ var path = require('path'); var mout = require('mout'); var Q = require('q'); var rimraf = require('rimraf'); -var Logger = require('bower-logger'); var endpointParser = require('bower-endpoint-parser'); var PackageRepository = require('../../core/PackageRepository'); var semver = require('../../util/semver'); var cli = require('../../util/cli'); var defaultConfig = require('../../config'); -function clean(endpoints, options, config) { - var logger = new Logger(); +function clean(logger, endpoints, options, config) { var decEndpoints; var names; @@ -33,21 +31,14 @@ function clean(endpoints, options, config) { }); } - Q.all([ + return Q.all([ clearPackages(decEndpoints, config, logger), clearLinks(names, config, logger), !names ? clearCompletion(config, logger) : null ]) .spread(function (entries) { return entries; - }) - .done(function (entries) { - logger.emit('end', entries); - }, function (error) { - logger.emit('error', error); }); - - return logger; } function clearPackages(decEndpoints, config, logger) { @@ -201,13 +192,10 @@ function clearCompletion(config, logger) { // ------------------- -clean.line = function (argv) { - var options = clean.options(argv); - return clean(options.argv.remain.slice(2), options); -}; - -clean.options = function (argv) { - return cli.readOptions(argv); +clean.line = function (logger, argv) { + var options = cli.readOptions(argv); + var endpoints = options.argv.remain.slice(2); + return clean(logger, endpoints, options); }; clean.completion = function () { diff --git a/lib/commands/cache/list.js b/lib/commands/cache/list.js index 49d0217d4..ed0441857 100644 --- a/lib/commands/cache/list.js +++ b/lib/commands/cache/list.js @@ -1,12 +1,10 @@ var mout = require('mout'); -var Logger = require('bower-logger'); var PackageRepository = require('../../core/PackageRepository'); var cli = require('../../util/cli'); var defaultConfig = require('../../config'); -function list(packages, options, config) { +function list(logger, packages, options, config) { var repository; - var logger = new Logger(); config = mout.object.deepFillIn(config || {}, defaultConfig); repository = new PackageRepository(config, logger); @@ -16,7 +14,7 @@ function list(packages, options, config) { packages = null; } - repository.list() + return repository.list() .then(function (entries) { if (packages) { // Filter entries according to the specified packages @@ -28,25 +26,15 @@ function list(packages, options, config) { } return entries; - }) - .done(function (entries) { - logger.emit('end', entries); - }, function (error) { - logger.emit('error', error); }); - - return logger; } // ------------------- -list.line = function (argv) { - var options = list.options(argv); - return list(options.argv.remain.slice(2), options); -}; - -list.options = function (argv) { - return cli.readOptions(argv); +list.line = function (logger, argv) { + var options = cli.readOptions(argv); + var packages = options.argv.remain.slice(2); + return list(logger, packages, options); }; list.completion = function () { diff --git a/lib/commands/completion.js b/lib/commands/completion.js index a8e16d0e1..4cc0017cd 100644 --- a/lib/commands/completion.js +++ b/lib/commands/completion.js @@ -1,27 +1,17 @@ -var Logger = require('bower-logger'); +var Q = require('q'); var cli = require('../util/cli'); function completion(config) { - var logger = new Logger(); - - process.nextTick(function () { - logger.emit('end'); - }); - - return logger; + return new Q(); } // ------------------- -completion.line = function (argv) { - var options = completion.options(argv); +completion.line = function (logger, argv) { + var options = cli.readOptions(argv); var name = options.argv.remain[1]; - return completion(name); -}; - -completion.options = function (argv) { - return cli.readOptions(argv); + return completion(logger, name); }; completion.completion = function () { diff --git a/lib/commands/help.js b/lib/commands/help.js index 0daf5c6cb..8edd38400 100644 --- a/lib/commands/help.js +++ b/lib/commands/help.js @@ -1,12 +1,11 @@ +var Q = require('q'); var path = require('path'); var fs = require('graceful-fs'); -var Logger = require('bower-logger'); var cli = require('../util/cli'); var createError = require('../util/createError'); -function help(name) { +function help(logger, name) { var json; - var logger = new Logger(); if (name) { json = path.resolve(__dirname, '../../templates/json/help-' + name.replace(/\s+/g, '/') + '.json'); @@ -14,35 +13,26 @@ function help(name) { json = path.resolve(__dirname, '../../templates/json/help.json'); } - fs.exists(json, function (exists) { + return Q.promise(function (resolve) { + fs.exists(json, resolve); + }) + .then(function (exists) { if (!exists) { - return logger.emit('error', createError('Unknown command: ' + name, 'EUNKOWNCMD', { + throw createError('Unknown command: ' + name, 'EUNKOWNCMD', { command: name - })); + }); } - try { - json = require(json); - } catch (error) { - return logger.emit('error', error); - } - - logger.emit('end', json); + return require(json); }); - - return logger; } // ------------------- -help.line = function (argv) { - var options = help.options(argv); - - return help(options.argv.remain.slice(1).join(' ')); -}; - -help.options = function (argv) { - return cli.readOptions(argv); +help.line = function (logger, argv) { + var options = cli.readOptions(argv); + var name = options.argv.remain.slice(1).join(' '); + return help(logger, name); }; help.completion = function () { diff --git a/lib/commands/home.js b/lib/commands/home.js index 73cad5e82..93a64bd18 100644 --- a/lib/commands/home.js +++ b/lib/commands/home.js @@ -1,5 +1,4 @@ var mout = require('mout'); -var Logger = require('bower-logger'); var Project = require('../core/Project'); var open = require('opn'); var endpointParser = require('bower-endpoint-parser'); @@ -7,11 +6,10 @@ var cli = require('../util/cli'); var createError = require('../util/createError'); var defaultConfig = require('../config'); -function home(name, config) { +function home(logger, name, config) { var project; var promise; var decEndpoint; - var logger = new Logger(); config = mout.object.deepFillIn(config || {}, defaultConfig); project = new Project(config, logger); @@ -37,7 +35,7 @@ function home(name, config) { } // Get homepage and open it - promise.then(function (pkgMeta) { + return promise.then(function (pkgMeta) { var homepage = pkgMeta.homepage; if (!homepage) { @@ -46,27 +44,16 @@ function home(name, config) { open(homepage); return homepage; - }) - .done(function (homepage) { - logger.emit('end', homepage); - }, function (error) { - logger.emit('error', error); }); - - return logger; } // ------------------- -home.line = function (argv) { - var options = home.options(argv); +home.line = function (logger, argv) { + var options = cli.readOptions(argv); var name = options.argv.remain[1]; - return home(name); -}; - -home.options = function (argv) { - return cli.readOptions(argv); + return home(logger, name); }; home.completion = function () { diff --git a/lib/commands/index.js b/lib/commands/index.js index a8660d95d..526c87612 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -8,18 +8,30 @@ var Logger = require('bower-logger'); * a command function. The difference is that `cmd = commandFactory()` and `cmd()` * return as soon as possible and load and execute the command asynchronously. */ -function lazyRequire(id) { +function commandFactory(id) { function command() { - var logger = new Logger(); - var commandArgs = arguments; + var commandArgs = [].slice.call(arguments); - Q.try(function () { - // call require asynchronously + return withLogger(function (logger) { + commandArgs.unshift(logger); return require(id).apply(undefined, commandArgs); - }) - .done(function (commandLogger) { - // Forward all events to exposed logger - commandLogger.pipe(logger); + }); + } + + function runFromArgv(argv) { + return withLogger(function (logger) { + return require(id).line.call(undefined, logger, argv); + }); + } + + function withLogger(func) { + var logger = new Logger(); + + Q.try(func, logger) + .done(function () { + var args = [].slice.call(arguments); + args.unshift('end'); + logger.emit.apply(logger, args); }, function (error) { logger.emit('error', error); }); @@ -27,34 +39,29 @@ function lazyRequire(id) { return logger; } - function runFromArgv() { - return require(id).line.apply(undefined, arguments); - } - command.line = runFromArgv; - return command; } module.exports = { cache: { - clean: lazyRequire('./cache/clean'), - list: lazyRequire('./cache/list') + clean: commandFactory('./cache/clean'), + list: commandFactory('./cache/list'), }, - completion: lazyRequire('./completion'), - help: lazyRequire('./help'), - home: lazyRequire('./home'), - info: lazyRequire('./info'), - init: lazyRequire('./init'), - install: lazyRequire('./install'), - link: lazyRequire('./link'), - list: lazyRequire('./list'), - lookup: lazyRequire('./lookup'), - prune: lazyRequire('./prune'), - register: lazyRequire('./register'), - search: lazyRequire('./search'), - update: lazyRequire('./update'), - uninstall: lazyRequire('./uninstall'), - version: lazyRequire('./version') + completion: commandFactory('./completion'), + help: commandFactory('./help'), + home: commandFactory('./home'), + info: commandFactory('./info'), + init: commandFactory('./init'), + install: commandFactory('./install'), + link: commandFactory('./link'), + list: commandFactory('./list'), + lookup: commandFactory('./lookup'), + prune: commandFactory('./prune'), + register: commandFactory('./register'), + search: commandFactory('./search'), + update: commandFactory('./update'), + uninstall: commandFactory('./uninstall'), + version: commandFactory('./version') }; diff --git a/lib/commands/info.js b/lib/commands/info.js index e9cf2dfe3..66f05e998 100644 --- a/lib/commands/info.js +++ b/lib/commands/info.js @@ -1,17 +1,15 @@ var mout = require('mout'); var Q = require('q'); -var Logger = require('bower-logger'); var endpointParser = require('bower-endpoint-parser'); var PackageRepository = require('../core/PackageRepository'); var cli = require('../util/cli'); var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); -function info(endpoint, property, config) { +function info(logger, endpoint, property, config) { var repository; var decEndpoint; var tracker; - var logger = new Logger(); config = mout.object.deepFillIn(config || {}, defaultConfig); repository = new PackageRepository(config, logger); @@ -20,7 +18,7 @@ function info(endpoint, property, config) { decEndpoint = endpointParser.decompose(endpoint); tracker.trackDecomposedEndpoints('info', [decEndpoint]); - Q.all([ + return Q.all([ getPkgMeta(repository, decEndpoint, property), decEndpoint.target === '*' && !property ? repository.versions(decEndpoint.source) : null ]) @@ -34,14 +32,7 @@ function info(endpoint, property, config) { } return pkgMeta; - }) - .done(function (result) { - logger.emit('end', result); - }, function (error) { - logger.emit('error', error); }); - - return logger; } function getPkgMeta(repository, decEndpoint, property) { @@ -62,20 +53,16 @@ function getPkgMeta(repository, decEndpoint, property) { // ------------------- -info.line = function (argv) { - var options = info.options(argv); +info.line = function (logger, argv) { + var options = cli.readOptions(argv); var pkg = options.argv.remain[1]; var property = options.argv.remain[2]; if (!pkg) { - return null; + return new Q(null); } - return info(pkg, property); -}; - -info.options = function (argv) { - return cli.readOptions(argv); + return info(logger, pkg, property); }; info.completion = function () { diff --git a/lib/commands/init.js b/lib/commands/init.js index bb98201bc..0131ef347 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -2,7 +2,6 @@ var mout = require('mout'); var fs = require('graceful-fs'); var path = require('path'); var Q = require('q'); -var Logger = require('bower-logger'); var endpointParser = require('bower-endpoint-parser'); var Project = require('../core/Project'); var defaultConfig = require('../config'); @@ -12,9 +11,8 @@ var cli = require('../util/cli'); var cmd = require('../util/cmd'); var createError = require('../util/createError'); -function init(config) { +function init(logger, config) { var project; - var logger = new Logger(); config = mout.object.deepFillIn(config || {}, defaultConfig); @@ -31,7 +29,7 @@ function init(config) { project = new Project(config, logger); // Start with existing JSON details - readJson(project, logger) + return readJson(project, logger) // Fill in defaults .then(setDefaults.bind(null, config)) // Now prompt user to make changes @@ -41,14 +39,7 @@ function init(config) { // Set dependencies based on the response .spread(setDependencies.bind(null, project)) // All done! - .spread(saveJson.bind(null, project, logger)) - .done(function (json) { - logger.emit('end', json); - }, function (error) { - logger.emit('error', error); - }); - - return logger; + .spread(saveJson.bind(null, project, logger)); } function readJson(project, logger) { @@ -329,12 +320,9 @@ function setDependencies(project, json, answers) { // ------------------- -init.line = function () { - return init(); -}; - -init.options = function (argv) { - return cli.readOptions(argv); +init.line = function (logger, argv) { + var options = cli.readOptions(argv); + return init(logger, options); }; init.completion = function () { diff --git a/lib/commands/install.js b/lib/commands/install.js index 8201c4bba..4bb19d1ff 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -1,16 +1,14 @@ var mout = require('mout'); -var Logger = require('bower-logger'); var endpointParser = require('bower-endpoint-parser'); var Project = require('../core/Project'); var cli = require('../util/cli'); var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); -function install(endpoints, options, config) { +function install(logger, endpoints, options, config) { var project; var decEndpoints; var tracker; - var logger = new Logger(); options = options || {}; config = mout.object.deepFillIn(config || {}, defaultConfig); @@ -27,22 +25,14 @@ function install(endpoints, options, config) { }); tracker.trackDecomposedEndpoints('install', decEndpoints); - project.install(decEndpoints, options) - .done(function (installed) { - tracker.trackPackages('installed', installed); - logger.emit('end', installed); - }, function (error) { - logger.emit('error', error); - }); - - return logger; + return project.install(decEndpoints, options); } // ------------------- -install.line = function (argv) { +install.line = function (logger, argv) { var options = install.options(argv); - return install(options.argv.remain.slice(1), options); + return install(logger, options.argv.remain.slice(1), options); }; install.options = function (argv) { diff --git a/lib/commands/link.js b/lib/commands/link.js index 80f40e28e..1f6be11d4 100644 --- a/lib/commands/link.js +++ b/lib/commands/link.js @@ -2,20 +2,26 @@ var path = require('path'); var rimraf = require('rimraf'); var mout = require('mout'); var Q = require('q'); -var Logger = require('bower-logger'); var Project = require('../core/Project'); var createLink = require('../util/createLink'); var cli = require('../util/cli'); var defaultConfig = require('../config'); -function linkSelf(config) { +function link(logger, name, localName) { + if (name) { + return linkTo(logger, name, localName); + } else { + return linkSelf(logger); + } +} + +function linkSelf(logger, config) { var project; - var logger = new Logger(); config = mout.object.deepFillIn(config || {}, defaultConfig); project = new Project(config, logger); - project.getJson() + return project.getJson() .then(function (json) { var src = config.cwd; var dst = path.join(config.storage.links, json.name); @@ -32,20 +38,12 @@ function linkSelf(config) { dst: dst }; }); - }) - .done(function (result) { - logger.emit('end', result); - }, function (error) { - logger.emit('error', error); }); - - return logger; } -function linkTo(name, localName, config) { +function linkTo(logger, name, localName, config) { var src; var dst; - var logger = new Logger(); var project = new Project(config, logger); config = mout.object.deepFillIn(config || {}, defaultConfig); @@ -55,7 +53,7 @@ function linkTo(name, localName, config) { dst = path.join(process.cwd(), config.directory, localName); // Delete destination folder if any - Q.nfcall(rimraf, dst) + return Q.nfcall(rimraf, dst) // Link locally .then(function () { return createLink(src, dst); @@ -70,37 +68,16 @@ function linkTo(name, localName, config) { dst: dst, installed: installed }; - }) - .done(function (result) { - logger.emit('end', result); - }, function (error) { - logger.emit('error', error); }); - - return logger; } // ------------------- -var link = { - linkTo: linkTo, - linkSelf: linkSelf -}; - -link.line = function (argv) { - var options = link.options(argv); +link.line = function (logger, argv) { + var options = cli.readOptions(argv); var name = options.argv.remain[1]; var localName = options.argv.remain[2]; - - if (name) { - return linkTo(name, localName); - } - - return linkSelf(); -}; - -link.options = function (argv) { - return cli.readOptions(argv); + return link(logger, name, localName); }; link.completion = function () { diff --git a/lib/commands/list.js b/lib/commands/list.js index d1d4dcdcd..dc5e73e65 100644 --- a/lib/commands/list.js +++ b/lib/commands/list.js @@ -1,15 +1,13 @@ var path = require('path'); var mout = require('mout'); var Q = require('q'); -var Logger = require('bower-logger'); var Project = require('../core/Project'); var semver = require('../util/semver'); var cli = require('../util/cli'); var defaultConfig = require('../config'); -function list(options, config) { +function list(logger, options, config) { var project; - var logger = new Logger(); options = options || {}; @@ -21,7 +19,9 @@ function list(options, config) { config = mout.object.deepFillIn(config || {}, defaultConfig); project = new Project(config, logger); - project.getTree(options) + logger.json = !!options.paths; + + return project.getTree(options) .spread(function (tree, flattened) { // Relativize paths // Also normalize paths on windows @@ -68,16 +68,7 @@ function list(options, config) { .then(function () { return tree; }); - }) - .done(function (value) { - logger.emit('end', value); - }, function (error) { - logger.emit('error', error); }); - - logger.json = !!options.paths; - - return logger; } function checkVersions(project, tree, logger) { @@ -162,9 +153,9 @@ function normalize(src) { // ------------------- -list.line = function (argv) { +list.line = function (logger, argv) { var options = list.options(argv); - return list(options); + return list(logger, options); }; list.options = function (argv) { diff --git a/lib/commands/lookup.js b/lib/commands/lookup.js index 5812f870e..962daf5f8 100644 --- a/lib/commands/lookup.js +++ b/lib/commands/lookup.js @@ -1,20 +1,18 @@ var mout = require('mout'); var Q = require('q'); -var Logger = require('bower-logger'); var RegistryClient = require('bower-registry-client'); var cli = require('../util/cli'); var defaultConfig = require('../config'); -function lookup(name, config) { +function lookup(logger, name, config) { var registryClient; - var logger = new Logger(); config = mout.object.deepFillIn(config || {}, defaultConfig); config.cache = config.storage.registry; registryClient = new RegistryClient(config, logger); - Q.nfcall(registryClient.lookup.bind(registryClient), name) + return Q.nfcall(registryClient.lookup.bind(registryClient), name) .then(function (entry) { // TODO: Handle entry.type.. for now it's only 'alias' // When we got published packages, this needs to be adjusted @@ -22,31 +20,20 @@ function lookup(name, config) { name: name, url: entry && entry.url }; - }) - .done(function (result) { - logger.emit('end', result); - }, function (error) { - logger.emit('error', error); }); - - return logger; } // ------------------- -lookup.line = function (argv) { - var options = lookup.options(argv); +lookup.line = function (logger, argv) { + var options = cli.readOptions(argv); var name = options.argv.remain[1]; if (!name) { - return null; + return new Q(null); + } else { + return lookup(logger, name); } - - return lookup(name); -}; - -lookup.options = function (argv) { - return cli.readOptions(argv); }; lookup.completion = function () { diff --git a/lib/commands/prune.js b/lib/commands/prune.js index 0b77e8a81..c3f9ddb41 100644 --- a/lib/commands/prune.js +++ b/lib/commands/prune.js @@ -1,25 +1,16 @@ var mout = require('mout'); -var Logger = require('bower-logger'); var Project = require('../core/Project'); var cli = require('../util/cli'); var defaultConfig = require('../config'); -function prune(options, config) { +function prune(logger, options, config) { var project; - var logger = new Logger(); options = options || {}; config = mout.object.deepFillIn(config || {}, defaultConfig); project = new Project(config, logger); - clean(project, options) - .done(function (removed) { - logger.emit('end', removed); - }, function (error) { - logger.emit('error', error); - }); - - return logger; + return clean(project, options); } function clean(project, options, removed) { @@ -50,9 +41,9 @@ function clean(project, options, removed) { // ------------------- -prune.line = function (argv) { +prune.line = function (logger, argv) { var options = prune.options(argv); - return prune(options); + return prune(logger, options); }; prune.options = function (argv) { diff --git a/lib/commands/register.js b/lib/commands/register.js index f7e254257..9ef1ee072 100644 --- a/lib/commands/register.js +++ b/lib/commands/register.js @@ -2,7 +2,6 @@ var mout = require('mout'); var Q = require('q'); var chalk = require('chalk'); var PackageRepository = require('../core/PackageRepository'); -var Logger = require('bower-logger'); var Config = require('bower-config'); var Tracker = require('../util/analytics').Tracker; var cli = require('../util/cli'); @@ -10,11 +9,10 @@ var createError = require('../util/createError'); var defaultConfig = require('../config'); var GitHubResolver = require('../core/resolvers/GitHubResolver'); -function register(name, url, config) { +function register(logger, name, url, config) { var repository; var registryClient; var tracker; - var logger = new Logger(); var force; config = mout.object.deepFillIn(config || {}, defaultConfig); @@ -28,11 +26,11 @@ function register(name, url, config) { // Trim name name = name.trim(); - process.nextTick(function () { + return Q.try(function () { // Verify name // TODO: Verify with the new spec regexp? if (!name) { - return logger.emit('error', createError('Please type a name', 'EINVNAME')); + throw createError('Please type a name', 'EINVNAME'); } // The public registry only allows git:// endpoints @@ -41,7 +39,7 @@ function register(name, url, config) { url = convertUrl(url, logger); if (!mout.string.startsWith(url, 'git://')) { - return logger.emit('error', createError('The registry only accepts URLs starting with git://', 'EINVFORMAT')); + throw createError('The registry only accepts URLs starting with git://', 'EINVFORMAT'); } } @@ -50,50 +48,42 @@ function register(name, url, config) { // Attempt to resolve the package referenced by the URL to ensure // everything is ok before registering repository = new PackageRepository(config, logger); - repository.fetch({ name: name, source: url, target: '*' }) - .spread(function (canonicalDir, pkgMeta) { - if (pkgMeta.private) { - throw createError('The package you are trying to register is marked as private', 'EPRIV'); - } + return repository.fetch({ name: name, source: url, target: '*' }); + }) + .spread(function (canonicalDir, pkgMeta) { + if (pkgMeta.private) { + throw createError('The package you are trying to register is marked as private', 'EPRIV'); + } - // If non interactive or user forced, bypass confirmation - if (!config.interactive || force) { - return true; - } + // If non interactive or user forced, bypass confirmation + if (!config.interactive || force) { + return true; + } - // Confirm if the user really wants to register - return Q.nfcall(logger.prompt.bind(logger), { - type: 'confirm', - message: 'Registering a package will make it installable via the registry (' + - chalk.cyan.underline(config.registry.register) + '), continue?', - default: true - }); - }) - .then(function (result) { - // If user response was negative, abort - if (!result) { - return; - } + // Confirm if the user really wants to register + return Q.nfcall(logger.prompt.bind(logger), { + type: 'confirm', + message: 'Registering a package will make it installable via the registry (' + + chalk.cyan.underline(config.registry.register) + '), continue?', + default: true + }); + }) + .then(function (result) { + // If user response was negative, abort + if (!result) { + return; + } - // Register - registryClient = repository.getRegistryClient(); - - logger.action('register', url, { - name: name, - url: url - }); - - return Q.nfcall(registryClient.register.bind(registryClient), name, url); - }) - .done(function (result) { - tracker.track('registered'); - logger.emit('end', result); - }, function (error) { - logger.emit('error', error); + // Register + registryClient = repository.getRegistryClient(); + + logger.action('register', url, { + name: name, + url: url }); - }); - return logger; + return Q.nfcall(registryClient.register.bind(registryClient), name, url); + }); } function convertUrl(url, logger) { @@ -114,20 +104,16 @@ function convertUrl(url, logger) { // ------------------- -register.line = function (argv) { - var options = register.options(argv); +register.line = function (logger, argv) { + var options = cli.readOptions(argv); var name = options.argv.remain[1]; var url = options.argv.remain[2]; if (!name || !url) { - return null; + return new Q(null); + } else { + return register(logger, name, url); } - - return register(name, url); -}; - -register.options = function (argv) { - return cli.readOptions(argv); }; register.completion = function () { diff --git a/lib/commands/search.js b/lib/commands/search.js index 2de5f0338..04937742e 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -1,16 +1,13 @@ var mout = require('mout'); var Q = require('q'); -var Logger = require('bower-logger'); var RegistryClient = require('bower-registry-client'); var cli = require('../util/cli'); var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); -function search(name, config) { +function search(logger, name, config) { var registryClient; - var promise; var tracker; - var logger = new Logger(); config = mout.object.deepFillIn(config || {}, defaultConfig); config.cache = config.storage.registry; @@ -21,31 +18,19 @@ function search(name, config) { // If no name was specified, list all packages if (!name) { - promise = Q.nfcall(registryClient.list.bind(registryClient)); + return Q.nfcall(registryClient.list.bind(registryClient)); // Otherwise search it } else { - promise = Q.nfcall(registryClient.search.bind(registryClient), name); + return Q.nfcall(registryClient.search.bind(registryClient), name); } - - promise - .done(function (results) { - logger.emit('end', results); - }, function (error) { - logger.emit('error', error); - }); - - return logger; } // ------------------- -search.line = function (argv) { - var options = search.options(argv); - return search(options.argv.remain.slice(1).join(' '), options); -}; - -search.options = function (argv) { - return cli.readOptions(argv); +search.line = function (logger, argv) { + var options = cli.readOptions(argv); + var name = options.argv.remain.slice(1).join(' '); + return search(logger, name, options); }; search.completion = function () { diff --git a/lib/commands/uninstall.js b/lib/commands/uninstall.js index 80648c8a3..a81d9f34d 100644 --- a/lib/commands/uninstall.js +++ b/lib/commands/uninstall.js @@ -1,15 +1,13 @@ var mout = require('mout'); -var Logger = require('bower-logger'); var Q = require('q'); var Project = require('../core/Project'); var cli = require('../util/cli'); var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); -function uninstall(names, options, config) { +function uninstall(logger, names, options, config) { var project; var tracker; - var logger = new Logger(); options = options || {}; config = mout.object.deepFillIn(config || {}, defaultConfig); @@ -18,7 +16,7 @@ function uninstall(names, options, config) { tracker.trackNames('uninstall', names); - project.getTree(options) + return project.getTree(options) .spread(function (tree, flattened) { // Uninstall nodes return project.uninstall(names, options) @@ -37,15 +35,7 @@ function uninstall(names, options, config) { // Clean them! return clean(project, children, uninstalled); }); - }) - .done(function (uninstalled) { - logger.emit('end', uninstalled); - tracker.trackNames('uninstalled', Object.keys(uninstalled)); - }, function (error) { - logger.emit('error', error); }); - - return logger; } function clean(project, names, removed) { @@ -109,15 +99,15 @@ function clean(project, names, removed) { // ------------------- -uninstall.line = function (argv) { +uninstall.line = function (logger, argv) { var options = uninstall.options(argv); var names = options.argv.remain.slice(1); if (!names.length) { - return null; + return new Q(null); + } else { + return uninstall(logger, names, options); } - - return uninstall(names, options); }; uninstall.options = function (argv) { diff --git a/lib/commands/update.js b/lib/commands/update.js index d31335321..2087a7007 100644 --- a/lib/commands/update.js +++ b/lib/commands/update.js @@ -1,12 +1,10 @@ var mout = require('mout'); -var Logger = require('bower-logger'); var Project = require('../core/Project'); var cli = require('../util/cli'); var defaultConfig = require('../config'); -function update(names, options, config) { +function update(logger, names, options, config) { var project; - var logger = new Logger(); options = options || {}; config = mout.object.deepFillIn(config || {}, defaultConfig); @@ -17,21 +15,15 @@ function update(names, options, config) { names = null; } - project.update(names, options) - .done(function (installed) { - logger.emit('end', installed); - }, function (error) { - logger.emit('error', error); - }); - - return logger; + return project.update(names, options); } // ------------------- -update.line = function (argv) { +update.line = function (logger, argv) { var options = update.options(argv); - return update(options.argv.remain.slice(1), options); + var names = options.argv.remain.slice(1); + return update(logger, names, options); }; update.options = function (argv) { diff --git a/lib/commands/version.js b/lib/commands/version.js index 4d3c270cc..8c262b421 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -1,6 +1,5 @@ var mout = require('mout'); var semver = require('semver'); -var Logger = require('bower-logger'); var which = require('which'); var fs = require('fs'); var path = require('path'); @@ -11,21 +10,13 @@ var cli = require('../util/cli'); var defaultConfig = require('../config'); var createError = require('../util/createError'); -function version(versionArg, options, config) { +function version(logger, versionArg, options, config) { var project; - var logger = new Logger(); config = mout.object.deepFillIn(config || {}, defaultConfig); project = new Project(config, logger); - bump(project, versionArg, options.message) - .done(function () { - logger.emit('end'); - }, function (error) { - logger.emit('error', error); - }); - - return logger; + return bump(project, versionArg, options.message); } function bump(project, versionArg, message) { @@ -123,9 +114,9 @@ function gitCommitAndTag(newVersion, message) { // ------------------- -version.line = function (argv) { +version.line = function (logger, argv) { var options = version.options(argv); - return version(options.argv.remain[1], options); + return version(logger, options.argv.remain[1], options); }; version.options = function (argv) { From e42d3d56208f52247b09499d6a3934b463f0cd82 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 20 Jun 2014 21:55:50 +0200 Subject: [PATCH 0397/1021] [#1329] Check if pkgMeta is undefined --- lib/core/Project.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/core/Project.js b/lib/core/Project.js index 70238ec2d..c74613d61 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -462,7 +462,8 @@ Project.prototype._analyse = function () { var isSaved = jsonCopy.dependencies[key] || jsonCopy.devDependencies[key]; // The _direct propery is saved by the manager when .newly is specified - if (!isSaved && pkgMeta._direct) { + // It may happen pkgMeta is undefined if package is uninstalled + if (!isSaved && pkgMeta && pkgMeta._direct) { decEndpoint.extraneous = true; if (decEndpoint.linked) { From 02e12e17d640070c6aad4c68875b6aabb8fde27e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 20 Jun 2014 22:58:57 +0200 Subject: [PATCH 0398/1021] Prepend # to ambiguous branch name, fixes bower/bower#1308 --- packages/bower-endpoint-parser/index.js | 10 +++++++++- packages/bower-endpoint-parser/test/test.js | 6 ++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/bower-endpoint-parser/index.js b/packages/bower-endpoint-parser/index.js index 68a8eabeb..05523941d 100644 --- a/packages/bower-endpoint-parser/index.js +++ b/packages/bower-endpoint-parser/index.js @@ -91,7 +91,15 @@ function decomposed2json(decEndpoint) { // If value is empty, we append the target always if (!value) { - value += isWildcard(target) ? '*' : target; + if (isWildcard(target)) { + value += '*'; + } else { + if (target.indexOf('/') !== -1) { + value += '#' + target; + } else { + value += target; + } + } // Otherwise append only if not a wildcard or source does not look like a source } else if (!isWildcard(target) || !isSource(source)) { value += '#' + (target || '*'); diff --git a/packages/bower-endpoint-parser/test/test.js b/packages/bower-endpoint-parser/test/test.js index 98e4653c5..084c410d2 100644 --- a/packages/bower-endpoint-parser/test/test.js +++ b/packages/bower-endpoint-parser/test/test.js @@ -189,7 +189,8 @@ describe('endpoint-parser', function () { { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' }, { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' }, { ssh: 'git@example.com' }, - { git: 'git://example.com' } + { git: 'git://example.com' }, + { ckeditor: '#full/4.3.3' } ]; it('should compose endpoints to json correctly', function () { @@ -206,7 +207,8 @@ describe('endpoint-parser', function () { { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '' }, { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }, { name: 'ssh', source: 'git@example.com', target: '*' }, - { name: 'git', source: 'git://example.com', target: '*' } + { name: 'git', source: 'git://example.com', target: '*' }, + { name: 'ckeditor', source: 'ckeditor', target: 'full/4.3.3' } ]; var x = 0; From 43d7a11ba8cd20d3a31aad72bd012b5b05faaf2f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 20 Jun 2014 23:01:20 +0200 Subject: [PATCH 0399/1021] Bump version to 0.2.2 --- packages/bower-endpoint-parser/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-endpoint-parser/package.json b/packages/bower-endpoint-parser/package.json index 3ead8af87..aa726064c 100644 --- a/packages/bower-endpoint-parser/package.json +++ b/packages/bower-endpoint-parser/package.json @@ -1,6 +1,6 @@ { "name": "bower-endpoint-parser", - "version": "0.2.1", + "version": "0.2.2", "description": "Little module that helps with endpoints parsing.", "author": "Twitter", "licenses": [ From 1d24e82276ec7a35a7058bf43a8e468d34cd7159 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 21 Jun 2014 00:33:51 +0200 Subject: [PATCH 0400/1021] [#931] Make --force always re-run installation --- lib/commands/install.js | 2 +- lib/core/Manager.js | 17 +++++++++++------ lib/core/Project.js | 9 +++++---- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/lib/commands/install.js b/lib/commands/install.js index 4bb19d1ff..20927bb04 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -25,7 +25,7 @@ function install(logger, endpoints, options, config) { }); tracker.trackDecomposedEndpoints('install', decEndpoints); - return project.install(decEndpoints, options); + return project.install(decEndpoints, options, config); } // ------------------- diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 883813938..42725d9f6 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -558,12 +558,8 @@ Manager.prototype._dissect = function () { var installedMeta = this._installed[name]; var dst; - // Analyse a few props - if (installedMeta && - installedMeta._target === decEndpoint.target && - installedMeta._originalSource === decEndpoint.source && - installedMeta._release === decEndpoint.pkgMeta._release - ) { + // Skip linked dependencies + if (decEndpoint.linked) { return false; } @@ -573,6 +569,15 @@ Manager.prototype._dissect = function () { return false; } + // Analyse a few props + if (installedMeta && + installedMeta._target === decEndpoint.target && + installedMeta._originalSource === decEndpoint.source && + installedMeta._release === decEndpoint.pkgMeta._release + ) { + return this._config.force; + } + return true; }, this); }.bind(this)) diff --git a/lib/core/Project.js b/lib/core/Project.js index c74613d61..493a27fc1 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -29,7 +29,7 @@ function Project(config, logger) { // ----------------- -Project.prototype.install = function (decEndpoints, options) { +Project.prototype.install = function (decEndpoints, options, config) { var that = this; var targets = []; var resolved = {}; @@ -41,6 +41,7 @@ Project.prototype.install = function (decEndpoints, options) { } this._options = options || {}; + this._config = config || {}; this._working = true; // Analyse the project @@ -48,10 +49,10 @@ Project.prototype.install = function (decEndpoints, options) { .spread(function (json, tree) { // Recover tree that.walkTree(tree, function (node, name) { - if (node.missing || node.different) { - targets.push(node); - } else if (node.incompatible) { + if (node.incompatible) { incompatibles.push(node); + } else if (node.missing || node.different || that._config.force) { + targets.push(node); } else { resolved[name] = node; } From 17bd60e3e9d78638a3fdfc03cfb090b1e269f6e7 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 22 Jun 2014 22:05:13 +0200 Subject: [PATCH 0401/1021] [#1356] Disable caching for local resources --- lib/core/PackageRepository.js | 13 +++++++----- lib/core/resolvers/Resolver.js | 20 +++++++++++++++++++ test/core/packageRepository.js | 36 +++++++++++++++++++++++++++++++++- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/lib/core/PackageRepository.js b/lib/core/PackageRepository.js index 902889d21..39018ee6f 100644 --- a/lib/core/PackageRepository.js +++ b/lib/core/PackageRepository.js @@ -46,7 +46,11 @@ PackageRepository.prototype.fetch = function (decEndpoint) { info.resolver = resolver; isTargetable = resolver.constructor.isTargetable; - // If force flag is used, bypass cache + if (resolver.isNotCacheable()) { + return that._resolve(resolver, logger); + } + + // If force flag is used, bypass cache, but write to cache anyway if (that._config.force) { logger.action('resolve', resolver.getSource() + '#' + resolver.getTarget()); return that._resolve(resolver, logger); @@ -171,12 +175,11 @@ PackageRepository.prototype._resolve = function (resolver, logger) { return resolver.resolve() // Store in the cache .then(function (canonicalDir) { - // We don't want to cache moving targets like branches - if (resolver._resolution && resolver._resolution.type === 'branch') { + if (resolver.isNotCacheable()) { return canonicalDir; - } else { - return that._resolveCache.store(canonicalDir, resolver.getPkgMeta()); } + + return that._resolveCache.store(canonicalDir, resolver.getPkgMeta()); }) // Resolve promise with canonical dir and package meta .then(function (dir) { diff --git a/lib/core/resolvers/Resolver.js b/lib/core/resolvers/Resolver.js index f5dc47632..4fa2072a9 100644 --- a/lib/core/resolvers/Resolver.js +++ b/lib/core/resolvers/Resolver.js @@ -114,6 +114,26 @@ Resolver.prototype.resolve = function () { }); }; +Resolver.prototype.isNotCacheable = function () { + // Bypass cache for local dependencies + if (this._source && + /^(?:file:[\/\\]{2})?\.?\.?[\/\\]/.test(this._source) + ) { + return true; + } + + // We don't want to cache moving targets like branches + if (this._pkgMeta && + this._pkgMeta._resolution && + this._pkgMeta._resolution.type === 'branch') + { + return true; + } + + return false; +}; + + // ----------------- // Abstract functions that must be implemented by concrete resolvers diff --git a/test/core/packageRepository.js b/test/core/packageRepository.js index d530e0970..d922d5a92 100644 --- a/test/core/packageRepository.js +++ b/test/core/packageRepository.js @@ -22,6 +22,7 @@ describe('PackageRepository', function () { var packagesCacheDir = path.join(__dirname, '../assets/temp-resolve-cache'); var registryCacheDir = path.join(__dirname, '../assets/temp-registry-cache'); var mockSource = 'file://' + testPackage; + var forceCaching = true; after(function () { rimraf.sync(registryCacheDir); @@ -51,6 +52,14 @@ describe('PackageRepository', function () { decEndpoint.source = mockSource; resolver = new resolvers.GitRemote(decEndpoint, _config, _logger); + + if (forceCaching) { + // Force to use cache even for local resources + resolver.isNotCacheable = function () { + return false; + }; + } + resolverFactoryHook(resolver); return Q.resolve(resolver); @@ -140,7 +149,7 @@ describe('PackageRepository', function () { }); it('should attempt to retrieve a resolved package from the resolve package', function (next) { - var called; + var called = false; var originalRetrieve = packageRepository._resolveCache.retrieve; packageRepository._resolveCache.retrieve = function (source) { @@ -161,6 +170,31 @@ describe('PackageRepository', function () { .done(); }); + it('should avoid using cache for local resources', function (next) { + forceCaching = false; + + var called = false; + var originalRetrieve = packageRepository._resolveCache.retrieve; + + packageRepository._resolveCache.retrieve = function (source) { + called = true; + expect(source).to.be(mockSource); + return originalRetrieve.apply(this, arguments); + }; + + packageRepository.fetch({ name: '', source: testPackage, target: '~0.1.0' }) + .spread(function (canonicalDir, pkgMeta) { + expect(called).to.be(false); + expect(fs.existsSync(canonicalDir)).to.be(true); + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta.name).to.be('package-a'); + expect(pkgMeta.version).to.be('0.1.1'); + forceCaching = true; + next(); + }) + .done(); + }); + it('should just call the resolver resolve method if no appropriate package was found in the resolve cache', function (next) { var called = []; From c6d2f633ea8929f6ed0c8a5341012b2501e8d1ac Mon Sep 17 00:00:00 2001 From: Andrew Butcher Date: Mon, 23 Jun 2014 23:40:30 -0400 Subject: [PATCH 0402/1021] Add bower install --save/--save-dev blurb to README.md. Closes #1321 --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 57325177a..54eae7300 100644 --- a/README.md +++ b/README.md @@ -261,6 +261,15 @@ There is no direct way to unregister a package yet. For now, you can [request a package be unregistered](https://github.com/bower/bower/issues/120). +### Maintaining dependencies + +Adding the `--save` option to Bower's `install` command will save installed +packages into the project's bower.json depencies. + +Similarly, passing `--save-dev` will save installed packages into the project's +bower.json devDependencies. + + ## Consuming a package Bower also makes available a source mapping. This can be used by build tools to From 1c09f9c82d10d112c52ac60de6fd5c28203b587c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 24 Jun 2014 11:16:07 +0200 Subject: [PATCH 0403/1021] Bump bower-config and endpoint-parser versions --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 5309d2142..caf31943f 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "dependencies": { "abbrev": "~1.0.4", "archy": "~0.0.2", - "bower-config": "~0.5.0", - "bower-endpoint-parser": "~0.2.0", + "bower-config": "~0.5.2", + "bower-endpoint-parser": "~0.2.2", "bower-json": "~0.4.0", "bower-logger": "~0.2.2", "bower-registry-client": "~0.2.0", From 442aa72ccc1575e213ed65aa522383650c2fb93a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 24 Jun 2014 11:39:44 +0200 Subject: [PATCH 0404/1021] [fixes 5c839724] Prevent command like "bower info" from crashing on render --- lib/commands/info.js | 2 +- lib/commands/lookup.js | 2 +- lib/commands/register.js | 2 +- lib/commands/uninstall.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/commands/info.js b/lib/commands/info.js index 66f05e998..3e238ecce 100644 --- a/lib/commands/info.js +++ b/lib/commands/info.js @@ -59,7 +59,7 @@ info.line = function (logger, argv) { var property = options.argv.remain[2]; if (!pkg) { - return new Q(null); + return new Q(); } return info(logger, pkg, property); diff --git a/lib/commands/lookup.js b/lib/commands/lookup.js index 962daf5f8..f4e61d0c2 100644 --- a/lib/commands/lookup.js +++ b/lib/commands/lookup.js @@ -30,7 +30,7 @@ lookup.line = function (logger, argv) { var name = options.argv.remain[1]; if (!name) { - return new Q(null); + return new Q(); } else { return lookup(logger, name); } diff --git a/lib/commands/register.js b/lib/commands/register.js index 9ef1ee072..5058f3b6a 100644 --- a/lib/commands/register.js +++ b/lib/commands/register.js @@ -110,7 +110,7 @@ register.line = function (logger, argv) { var url = options.argv.remain[2]; if (!name || !url) { - return new Q(null); + return new Q(); } else { return register(logger, name, url); } diff --git a/lib/commands/uninstall.js b/lib/commands/uninstall.js index a81d9f34d..1ceb76ad0 100644 --- a/lib/commands/uninstall.js +++ b/lib/commands/uninstall.js @@ -104,7 +104,7 @@ uninstall.line = function (logger, argv) { var names = options.argv.remain.slice(1); if (!names.length) { - return new Q(null); + return new Q(); } else { return uninstall(logger, names, options); } From 025cf916796f60f6cfbb0d96dc3c2881cf4a4d59 Mon Sep 17 00:00:00 2001 From: Andrew Butcher Date: Tue, 24 Jun 2014 09:25:25 -0400 Subject: [PATCH 0405/1021] README.md --save rewording suggested by @benschwarz for #1321 --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 54eae7300..d3683b2ed 100644 --- a/README.md +++ b/README.md @@ -263,11 +263,11 @@ package be unregistered](https://github.com/bower/bower/issues/120). ### Maintaining dependencies -Adding the `--save` option to Bower's `install` command will save installed -packages into the project's bower.json depencies. +Using `bower install pkgName --save` will add `pkgName` to your project's +bower.json `"depenencies"` array. -Similarly, passing `--save-dev` will save installed packages into the project's -bower.json devDependencies. +Similarly, using `bower install pkgName --save-dev` will add `pkgName` to your +project's bower.json `"devDependencies"` array. ## Consuming a package From 1177d2263fc63f37e6e2a8d86a7c0d116b49ea37 Mon Sep 17 00:00:00 2001 From: Greg Date: Fri, 27 Jun 2014 11:08:09 -0400 Subject: [PATCH 0406/1021] Add --version to --help --- templates/json/help.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/templates/json/help.json b/templates/json/help.json index 258f5c5e7..920a4802a 100644 --- a/templates/json/help.json +++ b/templates/json/help.json @@ -58,6 +58,10 @@ { "flag": "--allow-root", "description": "Allows running commands as root" + }, + { + "flag": "--version", + "description": "Output Bower version" } ] } From deb39b8f346b436ed87dc841e862bd02ff059c9c Mon Sep 17 00:00:00 2001 From: Tim Monks Date: Wed, 16 Apr 2014 17:03:27 -0700 Subject: [PATCH 0407/1021] Publish to coveralls.io from travis --- .travis.yml | 2 ++ Gruntfile.js | 6 +++++- README.md | 4 +++- lib/commands/index.js | 4 ++++ package.json | 3 ++- 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index cfa167bd1..13b27d5d7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,3 +7,5 @@ matrix: - node_js: '0.11' before_script: - npm install -g grunt-cli +script: + - grunt travis diff --git a/Gruntfile.js b/Gruntfile.js index c3d435c86..e64693fec 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -39,7 +39,10 @@ module.exports = function (grunt) { command: 'node test/packages.js --force && node test/packages-svn.js --force' }, cover: { - command: 'node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- -R dot test/test.js' + command: 'STRICT_REQUIRE=1 node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- -R dot test/test.js' + }, + coveralls: { + command: 'node node_modules/.bin/coveralls < test/reports/lcov.info' } }, watch: { @@ -51,5 +54,6 @@ module.exports = function (grunt) { grunt.registerTask('assets', ['exec:assets-force']); grunt.registerTask('test', ['jshint', 'exec:assets', 'simplemocha:full']); grunt.registerTask('cover', 'exec:cover'); + grunt.registerTask('travis', ['jshint', 'exec:assets', 'exec:cover', 'exec:coveralls']); grunt.registerTask('default', 'test'); }; diff --git a/README.md b/README.md index d3683b2ed..6cea2bcd8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# Bower [![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) +# Bower + +[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Coverage Status](https://coveralls.io/repos/bower/bower/badge.png?branch=feature%2Fintegration)](https://coveralls.io/r/bower/bower?branch=feature%2Fintegration) diff --git a/lib/commands/index.js b/lib/commands/index.js index 526c87612..fecf77b5f 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -9,6 +9,10 @@ var Logger = require('bower-logger'); * return as soon as possible and load and execute the command asynchronously. */ function commandFactory(id) { + if (process.env.STRICT_REQUIRE) { + require(id); + } + function command() { var commandArgs = [].slice.call(arguments); diff --git a/package.json b/package.json index caf31943f..d1c984a59 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,8 @@ "load-grunt-tasks": "~0.4.0", "mocha": "~1.20.1", "nock": "~0.34.1", - "proxyquire": "~1.0.1" + "proxyquire": "~1.0.1", + "coveralls": "~2.10.0" }, "scripts": { "test": "grunt test" From 192e5af797188937253cc821e69c3793031c0a2d Mon Sep 17 00:00:00 2001 From: Tim Monks Date: Thu, 17 Apr 2014 16:47:10 -0700 Subject: [PATCH 0408/1021] Add integration tests for bower commands --- .gitignore | 5 +-- Gruntfile.js | 3 +- package.json | 3 +- test/assets/resolve-cache/list-json-1.json | 16 ++++---- test/commands/index.js | 5 +++ test/commands/init.js | 48 ++++++++++++++++++++++ test/commands/install.js | 47 +++++++++++++++++++++ test/commands/uninstall.js | 48 ++++++++++++++++++++++ test/core/packageRepository.js | 6 +-- test/core/resolveCache.js | 8 ++-- test/core/resolverFactory.js | 4 +- test/core/resolvers/fsResolver.js | 8 ++-- test/core/resolvers/gitResolver.js | 2 +- test/core/resolvers/resolver.js | 2 +- test/core/resolvers/svnResolver.js | 2 +- test/core/resolvers/urlResolver.js | 2 +- test/core/scripts.js | 6 +-- test/helpers.js | 43 +++++++++++++++++++ test/test.js | 1 + 19 files changed, 226 insertions(+), 33 deletions(-) create mode 100644 test/commands/index.js create mode 100644 test/commands/init.js create mode 100644 test/commands/install.js create mode 100644 test/commands/uninstall.js create mode 100644 test/helpers.js diff --git a/.gitignore b/.gitignore index 4a75fd27c..ee50eb4be 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,10 @@ /node_modules /npm-debug.log -/test/assets/temp -/test/assets/temp2 -/test/assets/temp-resolve-cache /test/assets/package-*/ +/test/assets/temp-*/ /test/reports +/test/tmp/ /bower.json /component.json diff --git a/Gruntfile.js b/Gruntfile.js index e64693fec..a6d5b32c1 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -13,7 +13,8 @@ module.exports = function (grunt) { 'lib/**/*.js', 'test/**/*.js', '!test/assets/**/*', - '!test/reports/**/*' + '!test/reports/**/*', + '!test/tmp/**/*' ] }, simplemocha: { diff --git a/package.json b/package.json index d1c984a59..d75bab416 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,8 @@ "mocha": "~1.20.1", "nock": "~0.34.1", "proxyquire": "~1.0.1", - "coveralls": "~2.10.0" + "coveralls": "~2.10.0", + "node-uuid": "~1.4.1" }, "scripts": { "test": "grunt test" diff --git a/test/assets/resolve-cache/list-json-1.json b/test/assets/resolve-cache/list-json-1.json index 8490cdbc3..5bcc67e4a 100644 --- a/test/assets/resolve-cache/list-json-1.json +++ b/test/assets/resolve-cache/list-json-1.json @@ -1,51 +1,51 @@ [ { - "canonicalDir": "/test/assets/temp-resolve-cache/3668e6529b32a6d3e8931a68474e909d/0.2.0", + "canonicalDir": "/test/tmp/temp-resolve-cache/3668e6529b32a6d3e8931a68474e909d/0.2.0", "pkgMeta": { "name": "abc", "version": "0.2.0" } }, { - "canonicalDir": "/test/assets/temp-resolve-cache/77008abea14f06f199c2f481362b48d9/0.0.1", + "canonicalDir": "/test/tmp/temp-resolve-cache/77008abea14f06f199c2f481362b48d9/0.0.1", "pkgMeta": { "name": "foo", "version": "0.0.1" } }, { - "canonicalDir": "/test/assets/temp-resolve-cache/77008abea14f06f199c2f481362b48d9/0.1.0", + "canonicalDir": "/test/tmp/temp-resolve-cache/77008abea14f06f199c2f481362b48d9/0.1.0", "pkgMeta": { "name": "foo", "version": "0.1.0" } }, { - "canonicalDir": "/test/assets/temp-resolve-cache/3668e6529b32a6d3e8931a68474e909d/0.2.1", + "canonicalDir": "/test/tmp/temp-resolve-cache/3668e6529b32a6d3e8931a68474e909d/0.2.1", "pkgMeta": { "name": "foo", "version": "0.2.1" } }, { - "canonicalDir": "/test/assets/temp-resolve-cache/77008abea14f06f199c2f481362b48d9/aa", + "canonicalDir": "/test/tmp/temp-resolve-cache/77008abea14f06f199c2f481362b48d9/aa", "pkgMeta": { "name": "foo", "_target": "aa" } }, { - "canonicalDir": "/test/assets/temp-resolve-cache/77008abea14f06f199c2f481362b48d9/bar", + "canonicalDir": "/test/tmp/temp-resolve-cache/77008abea14f06f199c2f481362b48d9/bar", "pkgMeta": { "name": "foo", "_target": "bar" } }, { - "canonicalDir": "/test/assets/temp-resolve-cache/77008abea14f06f199c2f481362b48d9/foo", + "canonicalDir": "/test/tmp/temp-resolve-cache/77008abea14f06f199c2f481362b48d9/foo", "pkgMeta": { "name": "foo", "_target": "foo" } } -] \ No newline at end of file +] diff --git a/test/commands/index.js b/test/commands/index.js new file mode 100644 index 000000000..afef2f8d8 --- /dev/null +++ b/test/commands/index.js @@ -0,0 +1,5 @@ +describe('integration tests', function () { + require('./init'); + require('./install'); + require('./uninstall'); +}); diff --git a/test/commands/init.js b/test/commands/init.js new file mode 100644 index 000000000..ffe355769 --- /dev/null +++ b/test/commands/init.js @@ -0,0 +1,48 @@ +var path = require('path'); +var expect = require('expect.js'); +var fs = require('fs'); + +var helpers = require('../helpers'); +var bower = helpers.require('lib/index'); + +describe('bower init', function () { + + var tempDir = helpers.createTmpDir(); + var bowerJsonPath = path.join(tempDir, 'bower.json'); + + var config = { + cwd: tempDir, + interactive: true + }; + + it('generates bower.json file', function () { + var logger = bower.commands.init(config); + + return helpers.expectEvent(logger, 'prompt') + .spread(function (prompt, answer) { + answer({ + name: 'test-name', + version: 'test-version', + description: 'test-description', + moduleType: 'test-moduleType', + keywords: 'test-keyword', + authors: 'test-author', + license: 'test-license', + homepage: 'test-homepage', + private: true + }); + + return helpers.expectEvent(logger, 'prompt'); + }) + .spread(function (prompt, answer) { + answer({ + prompt: true + }); + + return helpers.expectEvent(logger, 'end'); + }) + .then(function () { + expect(fs.existsSync(bowerJsonPath)).to.be(true); + }); + }); +}); diff --git a/test/commands/install.js b/test/commands/install.js new file mode 100644 index 000000000..f4b80696c --- /dev/null +++ b/test/commands/install.js @@ -0,0 +1,47 @@ +var path = require('path'); +var expect = require('expect.js'); +var fs = require('fs'); + +var helpers = require('../helpers'); +var bower = helpers.require('lib/index'); + +describe('bower install', function () { + + var tempDir = helpers.createTmpDir(); + var bowerJsonPath = path.join(tempDir, 'bower_components', 'underscore', 'bower.json'); + + function bowerJson() { + return JSON.parse(fs.readFileSync(bowerJsonPath)); + } + + var config = { + cwd: tempDir, + interactive: true + }; + + it('does nothing if no bower.json is present', function () { + var logger = bower.commands.install([], undefined, config); + + return helpers.expectEvent(logger, 'end'); + }); + + it.skip('installs a package', function () { + this.timeout(10000); + var logger = bower.commands.install(['underscore'], undefined, config); + + return helpers.expectEvent(logger, 'end') + .then(function () { + expect(bowerJson()).to.have.key('name'); + }); + }); + + it.skip('installs package with --save flag', function () { + var logger = bower.commands.install(['underscore'], {save: true}, config); + + return helpers.expectEvent(logger, 'end') + .then(function () { + expect(bowerJson()).to.have.key('name'); + }); + }); + +}); diff --git a/test/commands/uninstall.js b/test/commands/uninstall.js new file mode 100644 index 000000000..decf3a70f --- /dev/null +++ b/test/commands/uninstall.js @@ -0,0 +1,48 @@ +var path = require('path'); +var expect = require('expect.js'); +var fs = require('fs'); + +var helpers = require('../helpers'); +var bower = helpers.require('lib/index'); + +describe('bower uninstall', function () { + + var tempDir = helpers.createTmpDir({ + 'bower.json': { + name: 'hello-world', + dependencies: { + 'underscore': '*' + } + } + }); + + var bowerJsonPath = path.join(tempDir, 'bower.json'); + + function bowerJson() { + return JSON.parse(fs.readFileSync(bowerJsonPath)); + } + + var config = { + cwd: tempDir, + interactive: true + }; + + it('does not remove anything from dependencies by default', function () { + var logger = bower.commands.uninstall(['underscore'], undefined, config); + + return helpers.expectEvent(logger, 'end') + .then(function () { + expect(bowerJson().dependencies).to.eql({ 'underscore': '*' }); + }); + }); + + it('removes dependency from bower.json if --save flag is used', function () { + var logger = bower.commands.uninstall(['underscore'], {save: true}, config); + + return helpers.expectEvent(logger, 'end') + .then(function () { + expect(bowerJson().dependencies).to.eql({}); + }); + }); + +}); diff --git a/test/core/packageRepository.js b/test/core/packageRepository.js index d922d5a92..36e6ef643 100644 --- a/test/core/packageRepository.js +++ b/test/core/packageRepository.js @@ -18,9 +18,9 @@ describe('PackageRepository', function () { var resolverFactoryHook; var resolverFactoryClearHook; var testPackage = path.resolve(__dirname, '../assets/package-a'); - var tempPackage = path.resolve(__dirname, '../assets/temp'); - var packagesCacheDir = path.join(__dirname, '../assets/temp-resolve-cache'); - var registryCacheDir = path.join(__dirname, '../assets/temp-registry-cache'); + var tempPackage = path.resolve(__dirname, '../tmp/temp-package'); + var packagesCacheDir = path.join(__dirname, '../tmp/temp-resolve-cache'); + var registryCacheDir = path.join(__dirname, '../tmp/temp-registry-cache'); var mockSource = 'file://' + testPackage; var forceCaching = true; diff --git a/test/core/resolveCache.js b/test/core/resolveCache.js index 9164992fe..a00fb4bb6 100644 --- a/test/core/resolveCache.js +++ b/test/core/resolveCache.js @@ -14,9 +14,9 @@ var md5 = require('../../lib/util/md5'); describe('ResolveCache', function () { var resolveCache; var testPackage = path.resolve(__dirname, '../assets/package-a'); - var tempPackage = path.resolve(__dirname, '../assets/temp'); - var tempPackage2 = path.resolve(__dirname, '../assets/temp2'); - var cacheDir = path.join(__dirname, '../assets/temp-resolve-cache'); + var tempPackage = path.resolve(__dirname, '../tmp/temp-package'); + var tempPackage2 = path.resolve(__dirname, '../tmp/temp2-package'); + var cacheDir = path.join(__dirname, '../tmp/temp-resolve-cache'); before(function (next) { // Delete cache folder @@ -908,7 +908,7 @@ describe('ResolveCache', function () { expect(entries).to.be.an('array'); expectedJson = fs.readFileSync(path.join(__dirname, '../assets/resolve-cache/list-json-1.json')); - expectedJson = expectedJson.toString(); + expectedJson = expectedJson.toString().trim(); mout.object.forOwn(entries, function (entry) { // Trim absolute bower path from json diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 90d49f26e..3c2bcf14a 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -421,7 +421,7 @@ describe('resolverFactory', function () { var endpoints; var temp; - tempSource = path.resolve(__dirname, '../assets/tmp'); + tempSource = path.resolve(__dirname, '../tmp/tmp'); mkdirp.sync(tempSource); fs.writeFileSync(path.join(tempSource, '.git'), 'foo'); fs.writeFileSync(path.join(tempSource, 'file.with.multiple.dots'), 'foo'); @@ -431,7 +431,7 @@ describe('resolverFactory', function () { // Absolute path to folder with .git file endpoints[tempSource] = tempSource; // Relative path to folder with .git file - endpoints[__dirname + '/../assets/tmp'] = tempSource; + endpoints[__dirname + '/../tmp/tmp'] = tempSource; // Absolute path to folder temp = path.resolve(__dirname, '../assets/test-temp-dir'); diff --git a/test/core/resolvers/fsResolver.js b/test/core/resolvers/fsResolver.js index 521fc0470..0705e214d 100644 --- a/test/core/resolvers/fsResolver.js +++ b/test/core/resolvers/fsResolver.js @@ -82,7 +82,7 @@ describe('FsResolver', function () { it('should resolve always to true (for now..)', function (next) { var resolver = create(testPackage); - tempSource = path.resolve(__dirname, '../../assets/tmp'); + tempSource = path.resolve(__dirname, '../../tmp/tmp'); mkdirp.sync(tempSource); fs.writeFileSync(path.join(tempSource, '.bower.json'), JSON.stringify({ name: 'test' @@ -161,7 +161,7 @@ describe('FsResolver', function () { it('should rename to index if source is a folder with just one file in it', function (next) { var resolver; - tempSource = path.resolve(__dirname, '../../assets/tmp'); + tempSource = path.resolve(__dirname, '../../tmp/tmp'); mkdirp.sync(tempSource); resolver = create(tempSource); @@ -181,7 +181,7 @@ describe('FsResolver', function () { it('should not rename to index if source is a folder with just bower.json/component.json file in it', function (next) { var resolver; - tempSource = path.resolve(__dirname, '../../assets/tmp'); + tempSource = path.resolve(__dirname, '../../tmp/tmp'); mkdirp.sync(tempSource); resolver = create(tempSource); @@ -235,7 +235,7 @@ describe('FsResolver', function () { var mode0777; var resolver; - tempSource = path.resolve(__dirname, '../../assets/temp'); + tempSource = path.resolve(__dirname, '../../tmp/temp-source'); resolver = create(tempSource); copy.copyFile(path.join(testPackage, 'foo'), tempSource) diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index 501d5cedc..58f7d8bf1 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -13,7 +13,7 @@ var GitResolver = require('../../../lib/core/resolvers/GitResolver'); var defaultConfig = require('../../../lib/config'); describe('GitResolver', function () { - var tempDir = path.resolve(__dirname, '../../assets/tmp'); + var tempDir = path.resolve(__dirname, '../../tmp/tmp'); var originalrefs = GitResolver.refs; var logger; diff --git a/test/core/resolvers/resolver.js b/test/core/resolvers/resolver.js index 9db7e439d..b5769aa55 100644 --- a/test/core/resolvers/resolver.js +++ b/test/core/resolvers/resolver.js @@ -13,7 +13,7 @@ var Resolver = require('../../../lib/core/resolvers/Resolver'); var defaultConfig = require('../../../lib/config'); describe('Resolver', function () { - var tempDir = path.resolve(__dirname, '../../assets/tmp'); + var tempDir = path.resolve(__dirname, '../../tmp/tmp'); var testPackage = path.resolve(__dirname, '../../assets/package-a'); var logger; var dirMode0777; diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index ffbf74f41..df3a46fb4 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -11,7 +11,7 @@ var SvnResolver = require('../../../lib/core/resolvers/SvnResolver'); var defaultConfig = require('../../../lib/config'); describe('SvnResolver', function () { - var tempDir = path.resolve(__dirname, '../../assets/tmp'); + var tempDir = path.resolve(__dirname, '../../tmp/tmp'); var testPackage = path.resolve(__dirname, '../../assets/package-svn/repo'); var testPackageAdmin = path.resolve(__dirname, '../../assets/package-svn/admin'); var originaltags = SvnResolver.tags; diff --git a/test/core/resolvers/urlResolver.js b/test/core/resolvers/urlResolver.js index d63ede72c..c150f9311 100644 --- a/test/core/resolvers/urlResolver.js +++ b/test/core/resolvers/urlResolver.js @@ -13,7 +13,7 @@ var defaultConfig = require('../../../lib/config'); describe('UrlResolver', function () { var testPackage = path.resolve(__dirname, '../../assets/package-a'); - var tempDir = path.resolve(__dirname, '../../assets/tmp'); + var tempDir = path.resolve(__dirname, '../../tmp/tmp'); var logger; before(function (next) { diff --git a/test/core/scripts.js b/test/core/scripts.js index 20eb2813c..a82733113 100644 --- a/test/core/scripts.js +++ b/test/core/scripts.js @@ -8,9 +8,9 @@ var scripts = require('../../lib/core/scripts.js'); describe('scripts', function () { - var tempDir = path.join(__dirname, '../assets/temp-scripts'); + var tempDir = path.join(__dirname, '../tmp/temp-scripts'); var packageName = 'package-zip'; - var packageDir = path.join('..', packageName + '.zip'); + var packageDir = path.join(__dirname, '../assets/' + packageName + '.zip'); var config = { cwd: tempDir, @@ -125,4 +125,4 @@ describe('scripts', function () { }); -}); \ No newline at end of file +}); diff --git a/test/helpers.js b/test/helpers.js new file mode 100644 index 000000000..fdb2a8cf7 --- /dev/null +++ b/test/helpers.js @@ -0,0 +1,43 @@ +var Q = require('q'); +var path = require('path'); +var mkdirp = require('mkdirp'); +var rimraf = require('rimraf'); +var uuid = require('node-uuid'); +var object = require('mout/object'); +var fs = require('fs'); + +exports.require = function (name) { + return require(path.join(__dirname, '../', name)); +}; + +exports.createTmpDir = function (files) { + var tempDir = path.join(__dirname, 'tmp/' + uuid.v4()); + + before(function (next) { + mkdirp(tempDir, next); + + if (files) { + object.forOwn(files, function (contents, filepath) { + if (typeof contents === 'object') { + contents = JSON.stringify(contents, null, ' '); + } + + fs.writeFileSync(path.join(tempDir, filepath), contents); + }); + } + }); + + after(function (next) { + rimraf(tempDir, next); + }); + + return tempDir; +}; + +exports.expectEvent = function (emitter, eventName) { + var deferred = Q.defer(); + emitter.once(eventName, function () { + deferred.resolve(arguments); + }); + return deferred.promise; +}; diff --git a/test/test.js b/test/test.js index 1a4a69d93..e5ebac128 100644 --- a/test/test.js +++ b/test/test.js @@ -18,3 +18,4 @@ require('./core/resolveCache'); require('./core/packageRepository'); require('./core/scripts'); require('./core/Manager'); +require('./commands/index.js'); From 232be333ad850bf1de22f3872bb079c425a142a0 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 8 Jun 2014 18:16:03 +0200 Subject: [PATCH 0409/1021] Add tests for removeIgnores utility --- lib/util/removeIgnores.js | 2 +- test/helpers.js | 12 ++++--- test/test.js | 1 + test/util/index.js | 3 ++ test/util/removeIgnores.js | 73 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 test/util/index.js create mode 100644 test/util/removeIgnores.js diff --git a/lib/util/removeIgnores.js b/lib/util/removeIgnores.js index 0bb04dc8c..1405bdb4b 100644 --- a/lib/util/removeIgnores.js +++ b/lib/util/removeIgnores.js @@ -23,7 +23,7 @@ function removeIgnores(dir, meta) { type: 'Directory' }); - reader.addIgnoreRules(meta.ignore); + reader.addIgnoreRules(meta.ignore || []); // Monkey patch applyIgnores such that we get hold of all ignored files applyIgnores = reader.applyIgnores; diff --git a/test/helpers.js b/test/helpers.js index fdb2a8cf7..43c47e296 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -13,8 +13,8 @@ exports.require = function (name) { exports.createTmpDir = function (files) { var tempDir = path.join(__dirname, 'tmp/' + uuid.v4()); - before(function (next) { - mkdirp(tempDir, next); + beforeEach(function () { + mkdirp.sync(tempDir); if (files) { object.forOwn(files, function (contents, filepath) { @@ -22,13 +22,15 @@ exports.createTmpDir = function (files) { contents = JSON.stringify(contents, null, ' '); } - fs.writeFileSync(path.join(tempDir, filepath), contents); + var fullPath = path.join(tempDir, filepath); + mkdirp.sync(path.dirname(fullPath)); + fs.writeFileSync(fullPath, contents); }); } }); - after(function (next) { - rimraf(tempDir, next); + afterEach(function () { + rimraf.sync(tempDir); }); return tempDir; diff --git a/test/test.js b/test/test.js index e5ebac128..04596c3ef 100644 --- a/test/test.js +++ b/test/test.js @@ -19,3 +19,4 @@ require('./core/packageRepository'); require('./core/scripts'); require('./core/Manager'); require('./commands/index.js'); +require('./util/index.js'); diff --git a/test/util/index.js b/test/util/index.js new file mode 100644 index 000000000..8cd973a8d --- /dev/null +++ b/test/util/index.js @@ -0,0 +1,3 @@ +describe('util', function () { + require('./removeIgnores'); +}); diff --git a/test/util/removeIgnores.js b/test/util/removeIgnores.js new file mode 100644 index 000000000..37914f74d --- /dev/null +++ b/test/util/removeIgnores.js @@ -0,0 +1,73 @@ +var expect = require('expect.js'); +var helpers = require('../helpers'); +var glob = require('glob'); +var Q = require('q'); + +var removeIgnores = require('../../lib/util/removeIgnores'); + +describe('removeIgnores', function () { + + var tempDir = helpers.createTmpDir({ + 'bower.json': {}, + 'index.js': 'Not to ignore', + 'node_modules/underscore/index.js': 'Should be ignored' + }); + + var ignoreTest = function(dir, meta, leftovers) { + var deferred = Q.defer(); + + removeIgnores(dir, meta).then(function() { + glob('**/*.*', { cwd: dir }, function(cb, files) { + expect(files).to.eql(leftovers); + deferred.resolve(); + }); + }); + + return deferred.promise; + }; + + it('removes all files in directory', function () { + return ignoreTest(tempDir, + { ignore: [ 'node_modules/**/*' ] }, + [ 'bower.json', 'index.js' ] + ); + }); + + it('removes whole directory', function () { + return ignoreTest(tempDir, + { ignore: [ 'node_modules/' ] }, + [ 'bower.json', 'index.js' ] + ); + }); + + it('removes whole directory (no ending slash)', function () { + return ignoreTest(tempDir, + { ignore: [ 'node_modules' ] }, + [ 'bower.json', 'index.js' ] + ); + }); + + it('removes all but one file', function() { + return ignoreTest(tempDir, + { ignore: [ '**/*', '!bower.json' ] }, + [ 'bower.json' ] + ); + }); + + it('refuses to ignore bower.json', function() { + return ignoreTest(tempDir, + { ignore: [ '**/*', '!index.js' ] }, + [ 'bower.json', 'index.js' ] + ); + }); + + it('removes all but one file deep down the tree', function() { + return ignoreTest(tempDir, + { ignore: [ '**/*', '!node_modules/underscore/index.js' ] }, + [ + 'bower.json', + 'node_modules/underscore/index.js' + ] + ); + }); +}); From d236a12b8fa3a88234c7d6f12ddc1066fc0aeecb Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 2 Jul 2014 12:28:48 +0100 Subject: [PATCH 0410/1021] Bump version to 1.3.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d75bab416..b155701bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.3.5", + "version": "1.3.6", "description": "The browser package manager", "author": "Twitter", "licenses": [ From 2fbc036e69fb0b7715245d6fb015e10d4f2e46b2 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 2 Jul 2014 14:04:01 +0100 Subject: [PATCH 0411/1021] Update the changelog --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dd3c4b11..107119874 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 1.3.6 - 2014-07-02 + +- [fix] Make --force always re-run installation (#931) +- [fix] Disable caching for local resources (#1356) +- [fix] Emit errors instead throwing them when using bower.commands API (#1297) +- [fix] Main files and bower.json are never ignored (#547) +- [fix] Check if pkgMeta is undefined during uninstall command (#1329) +- [fix] Make custom tmp dir and ignores play well with each other (#1299) +- Warn users when installing package with missing properties (#694) + ## 1.3.5 - 2014-06-06 - Search compatible versions in fetching packages ([#1147](https://github.com/bower/bower/issues/1147)) From 4af17f0e40cc8d81a772afb02817a4688a5c1a2a Mon Sep 17 00:00:00 2001 From: insanehong Date: Thu, 3 Jul 2014 12:34:04 +0900 Subject: [PATCH 0412/1021] Fixed bower list --paths` fails with TypeError, fixes #1383 --- lib/commands/list.js | 2 -- lib/renderers/StandardRenderer.js | 10 +++++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/commands/list.js b/lib/commands/list.js index dc5e73e65..02c93f7e6 100644 --- a/lib/commands/list.js +++ b/lib/commands/list.js @@ -19,8 +19,6 @@ function list(logger, options, config) { config = mout.object.deepFillIn(config || {}, defaultConfig); project = new Project(config, logger); - logger.json = !!options.paths; - return project.getTree(options) .spread(function (tree, flattened) { // Relativize paths diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index c7c15e013..86509e693 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -170,10 +170,14 @@ StandardRenderer.prototype._update = function (packages) { StandardRenderer.prototype._list = function (tree) { var cliTree; - tree.root = true; - cliTree = this._tree2archy(tree); + if (tree.pkgMeta) { + tree.root = true; + cliTree = archy(this._tree2archy(tree)); + } else { + cliTree = stringifyObject(tree, { indent: ' ' }) + '\n'; + } - this._write(process.stdout, archy(cliTree)); + this._write(process.stdout, cliTree); }; StandardRenderer.prototype._search = function (results) { From 9b81ddf4d51aa13e5b0350e73558d770f19a2b10 Mon Sep 17 00:00:00 2001 From: insanehong Date: Wed, 2 Jul 2014 23:58:20 +0900 Subject: [PATCH 0413/1021] It should shows an error when `bower install` failed, fixes #922 - reason no bower.json in current directory --- lib/core/Project.js | 6 ++++++ test/commands/install.js | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/core/Project.js b/lib/core/Project.js index 493a27fc1..c081dc41c 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -47,6 +47,12 @@ Project.prototype.install = function (decEndpoints, options, config) { // Analyse the project return this._analyse() .spread(function (json, tree) { + // It shows an error when issuing `bower install` + // and no bower.json is present in current directory + if(!that._jsonFile && decEndpoints.length === 0 ) { + throw createError('No bower.json present', 'ENOENT'); + } + // Recover tree that.walkTree(tree, function (node, name) { if (node.incompatible) { diff --git a/test/commands/install.js b/test/commands/install.js index f4b80696c..206b890ad 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -19,12 +19,6 @@ describe('bower install', function () { interactive: true }; - it('does nothing if no bower.json is present', function () { - var logger = bower.commands.install([], undefined, config); - - return helpers.expectEvent(logger, 'end'); - }); - it.skip('installs a package', function () { this.timeout(10000); var logger = bower.commands.install(['underscore'], undefined, config); From 83f4b7b699d827dc0ab021f4a41f14c512fcbee1 Mon Sep 17 00:00:00 2001 From: Vladimir Alaev Date: Thu, 12 Jun 2014 15:46:13 +0400 Subject: [PATCH 0414/1021] Fix callstack error when processing installed packages with circular dependencies --- lib/core/Project.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/core/Project.js b/lib/core/Project.js index c081dc41c..2399238b6 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -736,7 +736,7 @@ Project.prototype._removePackages = function (packages) { }); }; -Project.prototype._restoreNode = function (node, flattened, jsonKey) { +Project.prototype._restoreNode = function (node, flattened, jsonKey, processed) { var deps; // Do not restore if the node is missing @@ -746,10 +746,11 @@ Project.prototype._restoreNode = function (node, flattened, jsonKey) { node.dependencies = node.dependencies || {}; node.dependants = node.dependants || {}; + processed = processed || {}; // Only process deps that are not yet processed deps = mout.object.filter(node.pkgMeta[jsonKey], function (value, key) { - return !node.dependencies[key]; + return !processed[node.name + ':' + key]; }); mout.object.forOwn(deps, function (value, key) { @@ -796,15 +797,17 @@ Project.prototype._restoreNode = function (node, flattened, jsonKey) { // Cross reference node.dependencies[key] = restored; + processed[node.name + ':' + key] = true; + restored.dependants = restored.dependants || {}; restored.dependants[node.name] = mout.object.mixIn({}, node); // We need to clone due to shared objects in the manager! // Call restore for this dependency - this._restoreNode(restored, flattened, 'dependencies'); + this._restoreNode(restored, flattened, 'dependencies', processed); // Do the same for the incompatible local package if (local && restored !== local) { - this._restoreNode(local, flattened, 'dependencies'); + this._restoreNode(local, flattened, 'dependencies', processed); } }, this); }; From ecb16193998854af5b47039167e1e1e6eadb1f2c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 4 Jul 2014 12:58:03 +0100 Subject: [PATCH 0415/1021] Bump to 1.3.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b155701bc..0e295a8e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.3.6", + "version": "1.3.7", "description": "The browser package manager", "author": "Twitter", "licenses": [ From b6cf4e182648f375df4cda89568302a02d73dc6f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 4 Jul 2014 13:02:12 +0100 Subject: [PATCH 0416/1021] Update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 107119874..3aa8a0dd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.3.7 - 2014-07-04 + +- [fix] callstack error when processing installed packages with circular dependencies (#1349) +- [fix] Prevent bower list --paths` failing with TypeError (#1383) +- "bower install" fails if there's no bower.json in current directory (#922) + ## 1.3.6 - 2014-07-02 - [fix] Make --force always re-run installation (#931) From c4e9a0e3401d1235a85ce81a58c779952820bcc7 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sat, 5 Jul 2014 00:26:46 +0200 Subject: [PATCH 0417/1021] bump deps --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 0e295a8e7..578cba733 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "bower-logger": "~0.2.2", "bower-registry-client": "~0.2.0", "cardinal": "~0.4.0", - "chalk": "~0.4.0", + "chalk": "~0.5.0", "chmodr": "~0.1.0", "decompress-zip": "~0.0.6", "fstream": "~0.1.22", @@ -59,6 +59,7 @@ "which": "~1.0.5" }, "devDependencies": { + "coveralls": "~2.11.0", "expect.js": "~0.3.1", "grunt": "~0.4.4", "grunt-contrib-jshint": "~0.10.0", @@ -66,12 +67,11 @@ "grunt-exec": "~0.4.2", "grunt-simple-mocha": "~0.4.0", "istanbul": "~0.2.4", - "load-grunt-tasks": "~0.4.0", + "load-grunt-tasks": "~0.6.0", "mocha": "~1.20.1", - "nock": "~0.34.1", - "proxyquire": "~1.0.1", - "coveralls": "~2.10.0", - "node-uuid": "~1.4.1" + "nock": "~0.41.0", + "node-uuid": "~1.4.1", + "proxyquire": "~1.0.1" }, "scripts": { "test": "grunt test" From 09ecb80625b5ec8c5d82f7a3d2ff7fa8981b0b41 Mon Sep 17 00:00:00 2001 From: "Lucas, Justin" Date: Tue, 8 Jul 2014 11:39:14 -0700 Subject: [PATCH 0418/1021] Disable shallow clones for all repos except github.com --- lib/core/resolvers/GitHubResolver.js | 3 +++ lib/core/resolvers/GitRemoteResolver.js | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/core/resolvers/GitHubResolver.js b/lib/core/resolvers/GitHubResolver.js index 22e76d45c..8b3463931 100644 --- a/lib/core/resolvers/GitHubResolver.js +++ b/lib/core/resolvers/GitHubResolver.js @@ -35,6 +35,9 @@ function GitHubResolver(decEndpoint, config, logger) { if (this._config.proxy || this._config.httpsProxy) { this._source = this._source.replace('git://', 'https://'); } + + // Enable shallow clones for GitHub repos + this._shallowClone = true; } util.inherits(GitHubResolver, GitRemoteResolver); diff --git a/lib/core/resolvers/GitRemoteResolver.js b/lib/core/resolvers/GitRemoteResolver.js index cd3464cb3..3223c89b3 100644 --- a/lib/core/resolvers/GitRemoteResolver.js +++ b/lib/core/resolvers/GitRemoteResolver.js @@ -25,6 +25,9 @@ function GitRemoteResolver(decEndpoint, config, logger) { } else { this._host = url.parse(this._source).host; } + + // Disable shallow clones + this._shallowClone = false; } util.inherits(GitRemoteResolver, GitResolver); @@ -113,7 +116,7 @@ GitRemoteResolver.prototype._fastClone = function (resolution) { args = ['clone', this._source, '-b', branch, '--progress', '.']; // If the host does not support shallow clones, we don't use --depth=1 - if (!GitRemoteResolver._noShallow.get(this._host)) { + if (this._shallowClone && !GitRemoteResolver._noShallow.get(this._host)) { args.push('--depth', 1); } From b9abf32007967d7cacb2454731382cf62845fcc2 Mon Sep 17 00:00:00 2001 From: Steve Kenworthy Date: Wed, 9 Jul 2014 10:50:43 +0800 Subject: [PATCH 0419/1021] Fixed typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6cea2bcd8..a81c4085b 100644 --- a/README.md +++ b/README.md @@ -266,7 +266,7 @@ package be unregistered](https://github.com/bower/bower/issues/120). ### Maintaining dependencies Using `bower install pkgName --save` will add `pkgName` to your project's -bower.json `"depenencies"` array. +bower.json `"dependencies"` array. Similarly, using `bower install pkgName --save-dev` will add `pkgName` to your project's bower.json `"devDependencies"` array. From 9b5fa99d6a371598ec868fd83a4b8c0ba889da01 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 9 Jul 2014 16:15:47 +0200 Subject: [PATCH 0420/1021] bump update-notifier and simplify --- bin/bower | 5 ++--- lib/renderers/JsonRenderer.js | 2 -- lib/renderers/StandardRenderer.js | 5 ----- package.json | 2 +- templates/std/update-notice.std | 5 ----- 5 files changed, 3 insertions(+), 16 deletions(-) delete mode 100644 templates/std/update-notice.std diff --git a/bin/bower b/bin/bower index 3ae0acb7d..6a98d94db 100755 --- a/bin/bower +++ b/bin/bower @@ -19,7 +19,6 @@ var loglevel; var command; var commandFunc; var logger; -var notifier; var levels = Logger.LEVELS; options = cli.readOptions({ @@ -134,13 +133,13 @@ analytics.setup(bower.config).then(function () { var updateNotifier = require('update-notifier'); // Check for newer version of Bower - notifier = updateNotifier({ + var notifier = updateNotifier({ packageName: pkg.name, packageVersion: pkg.version }); if (notifier.update && levels.info >= loglevel) { - renderer.updateNotice(notifier.update); + notifier.notify(); } } }); diff --git a/lib/renderers/JsonRenderer.js b/lib/renderers/JsonRenderer.js index d8f6643c1..04a1ce00e 100644 --- a/lib/renderers/JsonRenderer.js +++ b/lib/renderers/JsonRenderer.js @@ -121,8 +121,6 @@ JsonRenderer.prototype.prompt = function (prompts) { }); }; -JsonRenderer.prototype.updateNotice = function () {}; - // ------------------------- JsonRenderer.prototype._stringify = function (log) { diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index 86509e693..279676963 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -110,11 +110,6 @@ StandardRenderer.prototype.prompt = function (prompts) { return deferred.promise; }; -StandardRenderer.prototype.updateNotice = function (data) { - var str = template.render('std/update-notice.std', data); - this._write(process.stderr, str); -}; - // ------------------------- StandardRenderer.prototype._help = function (data) { diff --git a/package.json b/package.json index 578cba733..8a97698e9 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "stringify-object": "~0.2.0", "tar": "~0.1.17", "tmp": "~0.0.23", - "update-notifier": "~0.1.8", + "update-notifier": "~0.2.0", "which": "~1.0.5" }, "devDependencies": { diff --git a/templates/std/update-notice.std b/templates/std/update-notice.std deleted file mode 100644 index 2407a5532..000000000 --- a/templates/std/update-notice.std +++ /dev/null @@ -1,5 +0,0 @@ -{{#red}}-----------------------------------------{{/red}} -Update available: {{#yellow}}{{latest}}{{/yellow}} {{#cyan}}(current: {{current}}){{/cyan}} -Run {{#yellow}}npm update -g {{name}}{{/yellow}} to update -{{#red}}-----------------------------------------{{/red}} - From 7dbf332a94b4379d281f0f18c3166c6980449d2f Mon Sep 17 00:00:00 2001 From: vladikoff Date: Fri, 11 Jul 2014 13:40:58 -0700 Subject: [PATCH 0421/1021] Fixes node-tmp update issue --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8a97698e9..dd76828c5 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "shell-quote": "~1.4.1", "stringify-object": "~0.2.0", "tar": "~0.1.17", - "tmp": "~0.0.23", + "tmp": "0.0.23", "update-notifier": "~0.2.0", "which": "~1.0.5" }, From 187f24de81e7e20bb921d9d3325c3b229fac2645 Mon Sep 17 00:00:00 2001 From: Paul Irish Date: Fri, 11 Jul 2014 13:47:27 -0700 Subject: [PATCH 0422/1021] Bump to 1.3.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dd76828c5..2c1c323f5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.3.7", + "version": "1.3.8", "description": "The browser package manager", "author": "Twitter", "licenses": [ From a45ea6e1d8672d3ae2ee893b9dd26bcd398c9eaa Mon Sep 17 00:00:00 2001 From: Paul Irish Date: Fri, 11 Jul 2014 14:16:42 -0700 Subject: [PATCH 0423/1021] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3aa8a0dd1..aadbb85f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.3.8 - 2014-7-11 + +- [fix] Lock down `tmp` package dep (#1403, #1407) + ## 1.3.7 - 2014-07-04 - [fix] callstack error when processing installed packages with circular dependencies (#1349) From cadcd37681271a8de20727f4101dd42e793f7cf2 Mon Sep 17 00:00:00 2001 From: Shu Uesugi Date: Sun, 13 Jul 2014 16:36:41 +0900 Subject: [PATCH 0424/1021] Fix typo on help-uninstall.json --- templates/json/help-uninstall.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/json/help-uninstall.json b/templates/json/help-uninstall.json index 95cc44d39..318f8999a 100644 --- a/templates/json/help-uninstall.json +++ b/templates/json/help-uninstall.json @@ -13,12 +13,12 @@ { "shorthand": "-S", "flag": "--save", - "description": "Save installed packages into the project's bower.json dependencies" + "description": "Remove uninstalled packages from the project's bower.json dependencies" }, { "shorthand": "-D", "flag": "--save-dev", - "description": "Save installed packages into the project's bower.json devDependencies" + "description": "Remove uninstalled packages from the project's bower.json devDependencies" } ] } From 85f1f808d3daad07ad823ea805f1db2f2e648743 Mon Sep 17 00:00:00 2001 From: David DeSandro Date: Mon, 14 Jul 2014 17:45:24 -0400 Subject: [PATCH 0425/1021] Remove content that can be now be found on bower.io + bower.json + custom install directory + bower search + using bower cache + .bowerrc + continuous integration server + interactive configuration + Defining a package + maintaining deps + consuming a package + programmatic api + assistance & contribution list Ref #1371 --- README.md | 315 +++--------------------------------------------------- 1 file changed, 15 insertions(+), 300 deletions(-) diff --git a/README.md b/README.md index a81c4085b..9b7149f52 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,13 @@ > A package manager for the web -It offers a generic, unopinionated solution to the problem of **front-end package management**, while exposing the package dependency model via an API that can be consumed by a more opinionated build stack. There are no system wide dependencies, no dependencies are shared between different apps, and the dependency tree is flat. +Bower offers a generic, unopinionated solution to the problem of **front-end package management**, while exposing the package dependency model via an API that can be consumed by a more opinionated build stack. There are no system wide dependencies, no dependencies are shared between different apps, and the dependency tree is flat. Bower runs over Git, and is package-agnostic. A packaged component can be made up of any type of asset, and use any type of transport (e.g., AMD, CommonJS, etc.). -[View all packages available through Bower's registry](http://bower.io/search/). +**View complete docs on [bower.io](http://bower.io)** +[View all packages available through Bower's registry](http://bower.io/search/). ## Install @@ -25,92 +26,24 @@ packages require it to be fetched and installed. ## Usage -Much more information is available via `bower help` once it's installed. This -is just enough to get you started. +See complete command line reference at [bower.io/docs/api/](http://bower.io/docs/api/) ### Installing packages and dependencies -Bower offers several ways to install packages: - -##### Using the dependencies listed in the current directory's bower.json - ```sh +# install dependencies listed in bower.json $ bower install -``` - -##### Using a local or remote package -```sh +# install a package $ bower install -``` - -##### Using a specific version of a package -```sh +# install specific version of a package $ bower install # -``` -##### Using a different name and a specific version of a package - -```sh -$ bower install =# +# install and save to bower.json dependencies +$ bower install --save ``` -Where `` can be any one of the following: - -* A name that maps to a package registered with Bower, e.g, `jquery`. ‡ -* A public remote Git endpoint, e.g., `git://github.com/someone/some-package.git`. ‡ -* A private Git repository, e.g., `https://github.com/someone/some-package.git`. If the protocol is https, a prompt will ask for the credentials. ssh can also be used, e.g., `git@github.com:someone/some-package.git` and can authenticate with the user's ssh public/private keys. ‡ -* A local endpoint, i.e., a folder that's a Git repository. ‡ -* A public remote Subversion endpoint, e.g., `svn+http://package.googlecode.com/svn/`. ‡ -* A private Subversion repository, e.g., `svn+ssh://package.googlecode.com/svn/` or `svn+https://package.googlecode.com/svn/`. ‡ -* A local endpoint, i.e., a folder that's an Subversion repository, e.g., `svn+file:///path/to/svn/`. ‡ -* A shorthand endpoint, e.g., `someone/some-package` (defaults to GitHub). ‡ -* A URL to a file, including `zip` and `tar` files. Its contents will be - extracted. - -‡ These types of `` might have versions available. You can specify a -[semver](http://semver.org/) compatible version to fetch a specific release, and lock the -package to that version. You can also specify a [range](https://github.com/isaacs/node-semver#ranges) of versions. - -If you are using a package that is a git endpoint, you may use any tag, commit SHA, -or branch name as a version. For example: `#`. Using branches is not -recommended because the HEAD does not reference a fixed commit SHA. - -If you are using a package that is a subversion endpoint, you may use any tag, revision number, -or branch name as a version. For example: `#`. - -All package contents are installed in the `bower_components` directory by default. -You should **never** directly modify the contents of this directory. - -Using `bower list` will show all the packages that are installed locally. - -**N.B.** If you aren't authoring a package that is intended to be consumed by -others (e.g., you're building a web app), you should always [check installed -packages into source control](http://addyosmani.com/blog/checking-in-front-end-dependencies/). - - -### Custom install directory - -A custom install location can be set in a `.bowerrc` file using the `directory` property. The .bowerrc file should be a sibling of your project's bower.json. - -```json -{ - "directory": "app/components" -} -``` - - -### Finding packages - -To search for packages registered with Bower: - -```sh -$ bower search [] -``` - -Using just `bower search` will list all packages in the registry. - ### Using packages We discourage using bower components statically for performance and security reasons (if component has an `upload.php` file that is not ignored, that can be easily exploited to do malicious stuff). @@ -125,17 +58,16 @@ To uninstall a locally installed package: $ bower uninstall ``` - -#### Warning +### prezto and oh-my-zsh users On `prezto` or `oh-my-zsh`, do not forget to `alias bower='noglob bower'` or `bower install jquery\#1.9.1` -#### Running commands with sudo +### Running commands with sudo Bower is a user command, there is no need to execute it with superuser permissions. However, if you still want to run commands with sudo, use `--allow-root` option. -#### A note for Windows users +### Windows users To use Bower on Windows, you must install [msysgit](http://msysgit.github.io/) correctly. Be sure to check the @@ -148,196 +80,9 @@ password, you should add the following environment variable: `GIT_SSH - C:\Program Files\TortoiseGit\bin\TortoisePlink.exe`. Adjust the `TortoisePlink` path if needed. -### Using bower's cache - -Bower supports installing packages from its local cache (without internet connection), if the packages were installed before. - -```sh -$ bower install --offline -``` - -The content of the cache can be listed with: - -```sh -$ bower cache list -``` - -The cache can be cleaned with: - -```sh -$ bower cache clean -``` - ## Configuration -Bower can be configured using JSON in a `.bowerrc` file. - -The current spec can be read -[here](https://docs.google.com/document/d/1APq7oA9tNao1UYWyOm8dKqlRP2blVkROYLZ2fLIjtWc/edit#heading=h.4pzytc1f9j8k) -in the `Configuration` section. - -## Running on a continuous integration server - -Bower will skip some interactive and analytics operations if it finds a `CI` environmental variable set to `true`. You will find that the `CI` variable is already set for you on many continuous integration servers, e.g., [CircleCI](https://circleci.com/docs/environment-variables#basics) and [Travis-CI](http://docs.travis-ci.com/user/ci-environment/#Environment-variables). - -You may try to set the `CI` variable manually before running your Bower commands. On Mac or Linux, `export CI=true` and on Windows `set CI=true` - -### Interactive configuration - -If for some reason you are unable to set the `CI` environment variable, you can alternately use the `--config.interactive=false` flag. (`bower install --config.interactive=false`) - -## Defining a package - -You must create a `bower.json` in your project's root, and specify all of its -dependencies. This is similar to Node's `package.json`, or Ruby's `Gemfile`, -and is useful for locking down a project's dependencies. - -*NOTE:* In versions of Bower before 0.9.0 the package metadata file was called -`component.json` rather than `bower.json`. This has changed to avoid a name -clash with another tool. You can still use `component.json` for now but it is -deprecated and the automatic fallback is likely to be removed in an upcoming -release. - -You can interactively create a `bower.json` with the following command: - -```sh -$ bower init -``` - -The `bower.json` ([spec](https://github.com/bower/bower.json-spec)) defines several options, including: - -* `name` (required): The name of your package. -* `version`: A semantic version number (see [semver](http://semver.org/)). -* `main` [string|array]: The primary endpoints of your package. -* `ignore` [array]: An array of paths not needed in production that you want - Bower to ignore when installing your package. -* `dependencies` [hash]: Packages your package depends upon in production. - Note that you can specify [ranges](https://github.com/isaacs/node-semver#ranges) - of versions for your dependencies. -* `devDependencies` [hash]: Development dependencies. -* `private` [boolean]: Set to true if you want to keep the package private and - do not want to register the package in future. - -```json -{ - "name": "my-project", - "description": "My project does XYZ...", - "version": "1.0.0", - "main": "path/to/main.css", - "ignore": [ - ".jshintrc", - "**/*.txt" - ], - "dependencies": { - "": "", - "": "", - "": "" - }, - "devDependencies": { - "": "" - } -} -``` - -### Registering packages - -To register a new package: - -* There **must** be a valid manifest JSON in the current working directory. -* Your package should use [semver](http://semver.org/) Git tags. -* Your package **must** be available at a Git endpoint (e.g., GitHub); remember - to push your Git tags! - -Then use the following command: - -```sh -$ bower register -``` - -The Bower registry does not have authentication or user management at this point -in time. It's on a first come, first served basis. Think of it like a URL -shortener. Now anyone can run `bower install `, and get your -library installed. - -There is no direct way to unregister a package yet. For now, you can [request a -package be unregistered](https://github.com/bower/bower/issues/120). - - -### Maintaining dependencies - -Using `bower install pkgName --save` will add `pkgName` to your project's -bower.json `"dependencies"` array. - -Similarly, using `bower install pkgName --save-dev` will add `pkgName` to your -project's bower.json `"devDependencies"` array. - - -## Consuming a package - -Bower also makes available a source mapping. This can be used by build tools to -easily consume Bower packages. - -If you pass the `--paths` option to Bower's `list` command, you will get a -simple name-to-path mapping: - -```json -{ - "backbone": "bower_components/backbone/index.js", - "jquery": "bower_components/jquery/index.js", - "underscore": "bower_components/underscore/index.js" -} -``` - -Alternatively, every command supports the `--json` option that makes bower -output JSON. Command result is outputted to `stdout` and error/logs to -`stderr`. - - -## Programmatic API - -Bower provides a powerful, programmatic API. All commands can be accessed -through the `bower.commands` object. - -```js -var bower = require('bower'); - -bower.commands -.install(['jquery'], { save: true }, { /* custom config */ }) -.on('end', function (installed) { - console.log(installed); -}); - -bower.commands -.search('jquery', {}) -.on('end', function (results) { - console.log(results); -}); -``` - -Commands emit four types of events: `log`, `prompt`, `end`, `error`. - -* `log` is emitted to report the state/progress of the command. -* `prompt` is emitted whenever the user needs to be prompted. -* `error` will only be emitted if something goes wrong. -* `end` is emitted when the command successfully ends. - -For a better of idea how this works, you may want to check out [our bin -file](https://github.com/bower/bower/blob/master/bin/bower). - -When using bower programmatically, prompting is disabled by default. Though you can enable it when calling commands with `interactive: true` in the config. -This requires you to listen for the `prompt` event and handle the prompting yourself. The easiest way is to use the [inquirer](https://npmjs.org/package/inquirer) npm module like so: - -```js -var inquirer = require('inquirer'); - -bower.commands -.install(['jquery'], { save: true }, { interactive: true }) -// .. -.on('prompt', function (prompts, callback) { - inquirer.prompt(prompts, callback); -}); -``` - +Bower can be configured using JSON in a `.bowerrc` file. Read over available options at [bower.io/docs/config](http://bower.io/docs/config). ## Completion (experimental) @@ -387,6 +132,8 @@ review the [guidelines for contributing](CONTRIBUTING.md). ## Bower Team +Bower is made by lots of people across the globe, contributions large and small. Our thanks to everyone who has played a part. + ### Core team * [@satazor](https://github.com/satazor) @@ -397,38 +144,6 @@ review the [guidelines for contributing](CONTRIBUTING.md). * [@svnlto](https://github.com/svnlto) * [@sheerun](https://github.com/sheerun) -Thanks for assistance and contributions: - -[@addyosmani](https://github.com/addyosmani), -[@ahmadnassri](https://github.com/ahmadnassri), -[@angus-c](https://github.com/angus-c), -[@borismus](https://github.com/borismus), -[@carsonmcdonald](https://github.com/carsonmcdonald), -[@chriseppstein](https://github.com/chriseppstein), -[@danwrong](https://github.com/danwrong), -[@davidmaxwaterman](https://github.com/davidmaxwaterman), -[@desandro](https://github.com/desandro), -[@hemanth](https://github.com/hemanth), -[@isaacs](https://github.com/isaacs), -[@josh](https://github.com/josh), -[@jrburke](https://github.com/jrburke), -[@kennethklee](https://github.com/kennethklee), -[@marcelombc](https://github.com/marcelombc), -[@marcooliveira](https://github.com/marcooliveira), -[@mklabs](https://github.com/mklabs), -[@MrDHat](https://github.com/MrDHat), -[@necolas](https://github.com/necolas), -[@richo](https://github.com/richo), -[@rvagg](https://github.com/rvagg), -[@ryanflorence](https://github.com/ryanflorence), -[@SlexAxton](https://github.com/SlexAxton), -[@sstephenson](https://github.com/sstephenson), -[@tomdale](https://github.com/tomdale), -[@uzquiano](https://github.com/uzquiano), -[@visionmedia](https://github.com/visionmedia), -[@wagenet](https://github.com/wagenet), -[@wycats](https://github.com/wycats) - ### Bower Alumni * [@fat](https://github.com/fat) From 7738248230a51e74c35a2e4283affa8f39453e2d Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 15 Jul 2014 01:50:32 +0200 Subject: [PATCH 0426/1021] lock down 0.0.x versions as `~` causes unexpected and non-semver behaviour on them. https://github.com/isaacs/node-semver --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 2c1c323f5..8df462319 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ }, "dependencies": { "abbrev": "~1.0.4", - "archy": "~0.0.2", + "archy": "0.0.2", "bower-config": "~0.5.2", "bower-endpoint-parser": "~0.2.2", "bower-json": "~0.4.0", @@ -26,9 +26,9 @@ "cardinal": "~0.4.0", "chalk": "~0.5.0", "chmodr": "~0.1.0", - "decompress-zip": "~0.0.6", + "decompress-zip": "0.0.6", "fstream": "~0.1.22", - "fstream-ignore": "~0.0.6", + "fstream-ignore": "0.0.6", "glob": "~4.0.2", "graceful-fs": "~3.0.1", "handlebars": "~1.3.0", @@ -43,7 +43,7 @@ "nopt": "~3.0.0", "opn": "~0.1.1", "osenv": "~0.1.0", - "p-throttler": "~0.0.1", + "p-throttler": "0.0.1", "promptly": "~0.2.0", "q": "~1.0.1", "request": "~2.36.0", From a5074eca7dfaf3f9106b60f9abc2904b3dc79625 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 15 Jul 2014 14:11:29 +0200 Subject: [PATCH 0427/1021] [doc] Encourage to always use --save option --- README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 9b7149f52..e6aaf7911 100644 --- a/README.md +++ b/README.md @@ -34,14 +34,11 @@ See complete command line reference at [bower.io/docs/api/](http://bower.io/docs # install dependencies listed in bower.json $ bower install -# install a package -$ bower install - -# install specific version of a package -$ bower install # - -# install and save to bower.json dependencies +# install a package and add it to bower.json $ bower install --save + +# install specific version of a package and add it to bower.json +$ bower install # --save ``` ### Using packages From 9cbd595cfdf63c1e7cfacce4f96247e109bca89b Mon Sep 17 00:00:00 2001 From: Ray Shan Date: Fri, 25 Jul 2014 00:21:53 -0700 Subject: [PATCH 0428/1021] analytics - bump insight to 0.4.1, supports OS/node/CLI tool version tracking --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8df462319..ada78cb3b 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "graceful-fs": "~3.0.1", "handlebars": "~1.3.0", "inquirer": "~0.5.1", - "insight": "~0.3.0", + "insight": "~0.4.1", "is-root": "~0.1.0", "junk": "~0.3.0", "lockfile": "~0.4.2", From 794744d5a3d84df90aebf94fcec4c6f39a050d7c Mon Sep 17 00:00:00 2001 From: MadLux Date: Wed, 30 Jul 2014 11:41:21 +0200 Subject: [PATCH 0429/1021] Added .zip MIME type (e.g. the default served by Windows/IIS) --- lib/util/extract.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/util/extract.js b/lib/util/extract.js index e5f77f7f4..a7a47eedf 100644 --- a/lib/util/extract.js +++ b/lib/util/extract.js @@ -23,6 +23,7 @@ extractors = { '.gz': extractGz, 'application/zip': extractZip, 'application/x-zip': extractZip, + 'application/x-zip-compressed': extractZip, 'application/x-tar': extractTar, 'application/x-tgz': extractTarGz, 'application/x-gzip': extractGz From 7a0a86d51c05f4f036d0e86af8c91080daf4ba04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kornel=20Lesi=C5=84ski?= Date: Wed, 23 Jul 2014 15:57:33 +0100 Subject: [PATCH 0430/1021] When tmp.js returns cleanup callback along with the tmp dir path, nfcall changes return type to an array --- lib/core/resolvers/Resolver.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core/resolvers/Resolver.js b/lib/core/resolvers/Resolver.js index 4fa2072a9..67a45f7bf 100644 --- a/lib/core/resolvers/Resolver.js +++ b/lib/core/resolvers/Resolver.js @@ -169,8 +169,8 @@ Resolver.prototype._createTempDir = function () { }); }.bind(this)) .then(function (dir) { - this._tempDir = dir; - return dir; + // nfcall may return multiple callback arguments as an array + return this._tempDir = Array.isArray(dir) ? dir[0] : dir; }.bind(this)); }; From a069d1e07d46b81c5a69e391506028f9b076b39d Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 6 Aug 2014 21:39:31 +0200 Subject: [PATCH 0431/1021] 1.3.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ada78cb3b..9a4108954 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.3.8", + "version": "1.3.9", "description": "The browser package manager", "author": "Twitter", "licenses": [ From 2a01f178da5f5ba643e697d0bee95a6c2b3719bf Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 6 Aug 2014 21:41:46 +0200 Subject: [PATCH 0432/1021] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aadbb85f7..959ef62d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.3.9 - 2014-08-06 + +- [fix] Handle `tmp` sometimes returning an array (#1434) + ## 1.3.8 - 2014-7-11 - [fix] Lock down `tmp` package dep (#1403, #1407) From ae3a0171439fb0a131fbedb82499d18b4cb7310e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bachelier?= Date: Fri, 8 Aug 2014 16:59:47 +0200 Subject: [PATCH 0433/1021] fix typo in README --- packages/bower-json/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index 1e1944f93..e17912428 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -95,7 +95,7 @@ var json = { main: 'foo.js,bar.js' }; -bowerJson.nornalize(json); +bowerJson.normalize(json); json.main // ['foo.js', 'bar.js'] ``` From cd893fec15561833014df8372efe4c688e45a84e Mon Sep 17 00:00:00 2001 From: thorn0 Date: Mon, 11 Aug 2014 17:07:07 +0300 Subject: [PATCH 0434/1021] Mention updates in the main help See #955. The same was done for `bower list -h`, but not for `bower help` AKA just `bower`. --- templates/json/help.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/json/help.json b/templates/json/help.json index 920a4802a..52e1265b5 100644 --- a/templates/json/help.json +++ b/templates/json/help.json @@ -10,7 +10,7 @@ "init": "Interactively create a bower.json file", "install": "Install a package locally", "link": "Symlink a package folder", - "list": "List local packages", + "list": "List local packages - and possible updates", "lookup": "Look up a package URL by name", "prune": "Removes local extraneous packages", "register": "Register a package", From 42db74b5228b6b7c7a8bdc260ae95655339755c4 Mon Sep 17 00:00:00 2001 From: Ray Shan Date: Mon, 11 Aug 2014 15:03:34 -0700 Subject: [PATCH 0435/1021] Update README.md --- packages/bower-json/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index e17912428..7b80c911f 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -2,6 +2,7 @@ Read `bower.json` files with semantics, normalisation, defaults and validation. +Install via [npm](https://www.npmjs.org/package/bower-json): `npm install --save bower-json` ## Usage From 5a8cecf4995dcb632d726eca29373100ef35a143 Mon Sep 17 00:00:00 2001 From: Ray Shan Date: Mon, 11 Aug 2014 17:56:54 -0700 Subject: [PATCH 0436/1021] Update README.md --- packages/bower-config/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index fcc401217..49febb495 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -1,8 +1,9 @@ # bower-config [![Build Status](https://secure.travis-ci.org/bower/config.png?branch=master)](http://travis-ci.org/bower/config) -The Bower config reader and writer. +The Bower config (`.bowerrc`) reader and writer. The config spec can be read [here](https://docs.google.com/document/d/1APq7oA9tNao1UYWyOm8dKqlRP2blVkROYLZ2fLIjtWc/). +Install via [npm](https://www.npmjs.org/package/bower-config): `npm install --save bower-config` ## Usage From 18b809314c28f7572f40239b7ca3de5410579e53 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 12 Aug 2014 11:06:11 +0200 Subject: [PATCH 0437/1021] Update README.md --- packages/bower-config/README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index 49febb495..f3bb1f3e0 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -1,9 +1,16 @@ # bower-config [![Build Status](https://secure.travis-ci.org/bower/config.png?branch=master)](http://travis-ci.org/bower/config) -The Bower config (`.bowerrc`) reader and writer. +> The Bower config (`.bowerrc`) reader and writer. + The config spec can be read [here](https://docs.google.com/document/d/1APq7oA9tNao1UYWyOm8dKqlRP2blVkROYLZ2fLIjtWc/). -Install via [npm](https://www.npmjs.org/package/bower-config): `npm install --save bower-config` + +## Install + +```sh +$ npm install --save bower-config +``` + ## Usage From f65af7a3085f7577c6fb78d0a98dd43a4f6ec87a Mon Sep 17 00:00:00 2001 From: Ray Shan Date: Tue, 12 Aug 2014 11:06:53 -0700 Subject: [PATCH 0438/1021] Update README.md --- packages/bower-logger/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/bower-logger/README.md b/packages/bower-logger/README.md index c75d22716..b83f85947 100644 --- a/packages/bower-logger/README.md +++ b/packages/bower-logger/README.md @@ -2,6 +2,12 @@ The logger used in the various architecture components of Bower. +Install + +```sh +npm install --save bower-logger +``` + ## Usage From b3f28fac64fe4f5ffa4066b21cc9f12eda134205 Mon Sep 17 00:00:00 2001 From: Ray Shan Date: Tue, 12 Aug 2014 11:08:42 -0700 Subject: [PATCH 0439/1021] Update README.md --- packages/bower-registry-client/README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index 6896e2703..c043a98a9 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -1,7 +1,12 @@ # bower-registry-client [![Build Status](https://secure.travis-ci.org/bower/registry-client.png?branch=master)](http://travis-ci.org/bower/registry-client) -This module allows you to easily interact with the Bower server API. +This module allows you to easily interact with the Bower registry server API. +Install + +```sh +npm install --save bower-registry-client +``` ## Usage From 5584d1062ecb1ce85cc28a0ae07f898c9701bf07 Mon Sep 17 00:00:00 2001 From: Ray Shan Date: Fri, 15 Aug 2014 16:26:23 -0700 Subject: [PATCH 0440/1021] Further simplify readme.md --- README.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/README.md b/README.md index e6aaf7911..c47c46d95 100644 --- a/README.md +++ b/README.md @@ -96,19 +96,6 @@ This command will output a Bash / ZSH script to put into your `~/.bashrc`, $ bower completion >> ~/.bash_profile ``` -## Analytics - -Bower can collect anonymous usage statistics. This allows the community to improve Bower and publicly display insights into CLI usage and packages at [stats.bower.io](http://stats.bower.io). - -Data is tracked using Google Analytics and instrumented via [Insight](https://github.com/yeoman/insight). It is made available to all bower team members. Tracking is opt-in upon initial usage. If you'd prefer to disable analytics altogether, you can manually opt-out, or create either a local, or global `.bowerrc` file with: - -```json -{ - "analytics": false -} -``` - - ## Support From fc13328e2ac1d104871d9ef30c0bf395c07ca379 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Tue, 19 Aug 2014 12:30:04 -0400 Subject: [PATCH 0441/1021] Adds an error message to errors. Fixes #16 This could be better if it could distinguish between server errors and actually unknown errors (known unknowns), but that would require the server to provide JSON errors. --- packages/bower-registry-client/lib/register.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/lib/register.js b/packages/bower-registry-client/lib/register.js index fb431894b..a80f29b6e 100644 --- a/packages/bower-registry-client/lib/register.js +++ b/packages/bower-registry-client/lib/register.js @@ -46,7 +46,7 @@ function register(name, url, callback) { // Everything other than 201 is unknown if (response.statusCode !== 201) { - return callback(createError('Unknown error: ' + response.statusCode, 'EUNKNOWN')); + return callback(createError('Unknown error: ' + response.statusCode + ' - ' + response.body, 'EUNKNOWN')); } callback(null, { From c4659f816f98ff5a14c0f01a3b76213eedbbbc0e Mon Sep 17 00:00:00 2001 From: Manuel Wiedenmann Date: Wed, 20 Aug 2014 14:26:42 +0200 Subject: [PATCH 0442/1021] expose bower version --- lib/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/index.js b/lib/index.js index d0668398b..d1cedd055 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,6 +1,7 @@ var abbrev = require('abbrev'); var mout = require('mout'); var commands = require('./commands'); +var pkg = require('../package.json'); var abbreviations = abbrev(expandNames(commands)); abbreviations.i = 'install'; @@ -34,6 +35,7 @@ function clearRuntimeCache() { } module.exports = { + version: pkg.version, commands: commands, config: require('./config'), abbreviations: abbreviations, From 254aba0995e8534f65da75c5163c911d69fe8d2f Mon Sep 17 00:00:00 2001 From: Ben Schwarz Date: Thu, 28 Aug 2014 20:28:22 +1000 Subject: [PATCH 0443/1021] Back concurrency down to 5 (from 50!) --- lib/util/cmd.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/util/cmd.js b/lib/util/cmd.js index 26adcaa82..aa59fad39 100644 --- a/lib/util/cmd.js +++ b/lib/util/cmd.js @@ -8,9 +8,12 @@ var createError = require('./createError'); // The concurrency limit here is kind of magic. You don't really gain a lot from // having a large number of commands spawned at once, so it isn't super -// important for this number to be large. However, it would still be nice to -// *know* how high this number can be, rather than having to guess low. -var throttler = new PThrottler(50); +// important for this number to be large. Reports have shown that much more than 5 +// or 10 cause issues for corporate networks, private repos or situations where +// internet bandwidth is limited. We're running with a concurrency of 5 until +// 1.4.X is released, at which time we'll move to what was discussed in #1262 +// https://github.com/bower/bower/pull/1262 +var throttler = new PThrottler(5); var winBatchExtensions; var winWhichCache; From 0b6f62977aa16c318b8259c2b65e7961603454de Mon Sep 17 00:00:00 2001 From: Crisoforo Gaspar Hernandez Date: Thu, 4 Sep 2014 14:18:00 -0500 Subject: [PATCH 0444/1021] Update the references to the issues and pulls in the CHANGELOG.md file --- CHANGELOG.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 959ef62d7..7f956d138 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,27 +2,28 @@ ## 1.3.9 - 2014-08-06 -- [fix] Handle `tmp` sometimes returning an array (#1434) +- [fix] Handle `tmp` sometimes returning an array ([#1434](https://github.com/bower/bower/pull/1434)) ## 1.3.8 - 2014-7-11 -- [fix] Lock down `tmp` package dep (#1403, #1407) +- [fix] Lock down `tmp` package dep ([#1403](https://github.com/bower/bower/pull/1403), [#1407](https://github.com/bower/bower/pull/1407)) ## 1.3.7 - 2014-07-04 -- [fix] callstack error when processing installed packages with circular dependencies (#1349) -- [fix] Prevent bower list --paths` failing with TypeError (#1383) -- "bower install" fails if there's no bower.json in current directory (#922) +- [fix] callstack error when processing installed packages with circular dependencies ([#1349](https://github.com/bower/bower/issues/1349)) +- [fix] Prevent bower list --paths` failing with TypeError ([#1383](https://github.com/bower/bower/issues/1383)) +- "bower install" fails if there's no bower.json in current directory ([#922](https://github.com/bower/bower/issues/922)) ## 1.3.6 - 2014-07-02 -- [fix] Make --force always re-run installation (#931) -- [fix] Disable caching for local resources (#1356) -- [fix] Emit errors instead throwing them when using bower.commands API (#1297) -- [fix] Main files and bower.json are never ignored (#547) -- [fix] Check if pkgMeta is undefined during uninstall command (#1329) -- [fix] Make custom tmp dir and ignores play well with each other (#1299) -- Warn users when installing package with missing properties (#694) +- [fix] Make --force always re-run installation ([#931](https://github.com/bower/bower/issues/931)) +- [fix] Disable caching for local resources ([#1356](https://github.com/bower/bower/issues/1356)) +- [fix] Emit errors instead throwing them when using bower.commands API ([#1297](https://github.com/bower/bower/issues/1297)) +- [fix] Main files and bower.json are never ignored ([#547](https://github.com/bower/bower/issues/547)) +- [fix] Check if pkgMeta is undefined during uninstall command ([#1329](https://github.com/bower/bower/issues/1329)) +- [fix] Make custom tmp dir and ignores play well with each other ([#1299](https://github.com/bower/bower/issues/1299)) +- Warn users when installing package with missing properties ([#694](https://github.com/bower/bower/issues/694)) + ## 1.3.5 - 2014-06-06 - Search compatible versions in fetching packages ([#1147](https://github.com/bower/bower/issues/1147)) From 06a8f2afab70d7c2c14fb90e02c4052006a94880 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 6 Sep 2014 01:29:09 +0200 Subject: [PATCH 0445/1021] Read .bowerrc from specified cwd, fixes #1301 --- lib/commands/cache/clean.js | 2 +- lib/commands/cache/list.js | 2 +- lib/commands/home.js | 3 +- lib/commands/info.js | 2 +- lib/commands/init.js | 2 +- lib/commands/install.js | 3 +- lib/commands/link.js | 8 +-- lib/commands/list.js | 2 +- lib/commands/lookup.js | 3 +- lib/commands/prune.js | 2 +- lib/commands/register.js | 2 +- lib/commands/search.js | 3 +- lib/commands/uninstall.js | 2 +- lib/commands/update.js | 3 +- lib/commands/version.js | 3 +- lib/config.js | 80 +++++++++++++-------- lib/core/Project.js | 2 +- lib/core/resolvers/GitResolver.js | 13 ++-- lib/index.js | 2 +- test/assets/test-temp-dir/test-exception.js | 2 +- test/assets/test-temp-dir/test.js | 2 +- test/commands/init.js | 8 ++- test/commands/install.js | 53 ++++++++++++-- test/commands/uninstall.js | 10 ++- test/core/Manager.js | 3 +- test/core/packageRepository.js | 2 +- test/core/resolveCache.js | 4 +- test/core/resolverFactory.js | 18 +++-- test/core/resolvers/fsResolver.js | 4 +- test/core/resolvers/gitFsResolver.js | 4 +- test/core/resolvers/gitHubResolver.js | 12 +--- test/core/resolvers/gitRemoteResolver.js | 4 +- test/core/resolvers/gitResolver.js | 6 +- test/core/resolvers/resolver.js | 21 +++--- test/core/resolvers/svnResolver.js | 6 +- test/core/resolvers/urlResolver.js | 4 +- test/helpers.js | 41 ++++++++--- test/util/removeIgnores.js | 16 +++-- 38 files changed, 215 insertions(+), 144 deletions(-) diff --git a/lib/commands/cache/clean.js b/lib/commands/cache/clean.js index 2bcd2844e..044442bcf 100644 --- a/lib/commands/cache/clean.js +++ b/lib/commands/cache/clean.js @@ -14,7 +14,7 @@ function clean(logger, endpoints, options, config) { var names; options = options || {}; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); // If endpoints is an empty array, null them if (endpoints && !endpoints.length) { diff --git a/lib/commands/cache/list.js b/lib/commands/cache/list.js index ed0441857..761085cc1 100644 --- a/lib/commands/cache/list.js +++ b/lib/commands/cache/list.js @@ -6,7 +6,7 @@ var defaultConfig = require('../../config'); function list(logger, packages, options, config) { var repository; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); repository = new PackageRepository(config, logger); // If packages is an empty array, null them diff --git a/lib/commands/home.js b/lib/commands/home.js index 93a64bd18..3bb5e48f6 100644 --- a/lib/commands/home.js +++ b/lib/commands/home.js @@ -1,4 +1,3 @@ -var mout = require('mout'); var Project = require('../core/Project'); var open = require('opn'); var endpointParser = require('bower-endpoint-parser'); @@ -11,7 +10,7 @@ function home(logger, name, config) { var promise; var decEndpoint; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); project = new Project(config, logger); // Get the package meta diff --git a/lib/commands/info.js b/lib/commands/info.js index 3e238ecce..84d9c4601 100644 --- a/lib/commands/info.js +++ b/lib/commands/info.js @@ -11,7 +11,7 @@ function info(logger, endpoint, property, config) { var decEndpoint; var tracker; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); repository = new PackageRepository(config, logger); tracker = new Tracker(config); diff --git a/lib/commands/init.js b/lib/commands/init.js index 0131ef347..639263916 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -14,7 +14,7 @@ var createError = require('../util/createError'); function init(logger, config) { var project; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); // This command requires interactive to be enabled if (!config.interactive) { diff --git a/lib/commands/install.js b/lib/commands/install.js index 20927bb04..dba8d0494 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -1,4 +1,3 @@ -var mout = require('mout'); var endpointParser = require('bower-endpoint-parser'); var Project = require('../core/Project'); var cli = require('../util/cli'); @@ -11,7 +10,7 @@ function install(logger, endpoints, options, config) { var tracker; options = options || {}; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); if (options.save === undefined) { options.save = config.defaultSave; } diff --git a/lib/commands/link.js b/lib/commands/link.js index 1f6be11d4..60a669157 100644 --- a/lib/commands/link.js +++ b/lib/commands/link.js @@ -1,6 +1,5 @@ var path = require('path'); var rimraf = require('rimraf'); -var mout = require('mout'); var Q = require('q'); var Project = require('../core/Project'); var createLink = require('../util/createLink'); @@ -18,7 +17,7 @@ function link(logger, name, localName) { function linkSelf(logger, config) { var project; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); project = new Project(config, logger); return project.getJson() @@ -44,9 +43,10 @@ function linkSelf(logger, config) { function linkTo(logger, name, localName, config) { var src; var dst; - var project = new Project(config, logger); + var project; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); + project = new Project(config, logger); localName = localName || name; src = path.join(config.storage.links, name); diff --git a/lib/commands/list.js b/lib/commands/list.js index 02c93f7e6..08244fe08 100644 --- a/lib/commands/list.js +++ b/lib/commands/list.js @@ -16,7 +16,7 @@ function list(logger, options, config) { options.relative = true; } - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); project = new Project(config, logger); return project.getTree(options) diff --git a/lib/commands/lookup.js b/lib/commands/lookup.js index f4e61d0c2..748fece52 100644 --- a/lib/commands/lookup.js +++ b/lib/commands/lookup.js @@ -1,4 +1,3 @@ -var mout = require('mout'); var Q = require('q'); var RegistryClient = require('bower-registry-client'); var cli = require('../util/cli'); @@ -7,7 +6,7 @@ var defaultConfig = require('../config'); function lookup(logger, name, config) { var registryClient; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); config.cache = config.storage.registry; registryClient = new RegistryClient(config, logger); diff --git a/lib/commands/prune.js b/lib/commands/prune.js index c3f9ddb41..dc9c03347 100644 --- a/lib/commands/prune.js +++ b/lib/commands/prune.js @@ -7,7 +7,7 @@ function prune(logger, options, config) { var project; options = options || {}; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); project = new Project(config, logger); return clean(project, options); diff --git a/lib/commands/register.js b/lib/commands/register.js index 5058f3b6a..40b04b73b 100644 --- a/lib/commands/register.js +++ b/lib/commands/register.js @@ -15,7 +15,7 @@ function register(logger, name, url, config) { var tracker; var force; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); force = config.force; tracker = new Tracker(config); diff --git a/lib/commands/search.js b/lib/commands/search.js index 04937742e..8fb6e9d67 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -1,4 +1,3 @@ -var mout = require('mout'); var Q = require('q'); var RegistryClient = require('bower-registry-client'); var cli = require('../util/cli'); @@ -9,7 +8,7 @@ function search(logger, name, config) { var registryClient; var tracker; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); config.cache = config.storage.registry; registryClient = new RegistryClient(config, logger); diff --git a/lib/commands/uninstall.js b/lib/commands/uninstall.js index 1ceb76ad0..324a6e9d6 100644 --- a/lib/commands/uninstall.js +++ b/lib/commands/uninstall.js @@ -10,7 +10,7 @@ function uninstall(logger, names, options, config) { var tracker; options = options || {}; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); project = new Project(config, logger); tracker = new Tracker(config); diff --git a/lib/commands/update.js b/lib/commands/update.js index 2087a7007..f92130310 100644 --- a/lib/commands/update.js +++ b/lib/commands/update.js @@ -1,4 +1,3 @@ -var mout = require('mout'); var Project = require('../core/Project'); var cli = require('../util/cli'); var defaultConfig = require('../config'); @@ -7,7 +6,7 @@ function update(logger, names, options, config) { var project; options = options || {}; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); project = new Project(config, logger); // If names is an empty array, null them diff --git a/lib/commands/version.js b/lib/commands/version.js index 8c262b421..8a3faa3df 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -1,4 +1,3 @@ -var mout = require('mout'); var semver = require('semver'); var which = require('which'); var fs = require('fs'); @@ -13,7 +12,7 @@ var createError = require('../util/createError'); function version(logger, versionArg, options, config) { var project; - config = mout.object.deepFillIn(config || {}, defaultConfig); + config = defaultConfig(config); project = new Project(config, logger); return bump(project, versionArg, options.message); diff --git a/lib/config.js b/lib/config.js index b97fbbba8..cd044d7f6 100644 --- a/lib/config.js +++ b/lib/config.js @@ -1,37 +1,57 @@ var tty = require('tty'); -var mout = require('mout'); -var config = require('bower-config').read(); +var object = require('mout').object; +var bowerConfig = require('bower-config'); var cli = require('./util/cli'); -// Delete the json attribute because it is no longer supported -// and conflicts with --json -delete config.json; - -// If interactive is auto (null), guess its value -if (config.interactive == null) { - config.interactive = ( - process.bin === 'bower' && - tty.isatty(1) && - !process.env.CI - ); +var cachedConfigs = {}; + +function defaultConfig(config) { + config = config || {}; + + var cachedConfig = readCachedConfig(config.cwd || process.cwd()); + + return object.merge(cachedConfig, config); } -// If `analytics` hasn't been explicitly set, we disable -// it when ran programatically. -if (config.analytics == null) { - // Don't enable analytics on CI server unless explicitly configured. - config.analytics = config.interactive; +function readCachedConfig(cwd) { + if (cachedConfigs[cwd]) { + return cachedConfigs[cwd]; + } + + var config = cachedConfigs[cwd] = bowerConfig.read(cwd); + + // Delete the json attribute because it is no longer supported + // and conflicts with --json + delete config.json; + + // If interactive is auto (null), guess its value + if (config.interactive == null) { + config.interactive = ( + process.bin === 'bower' && + tty.isatty(1) && + !process.env.CI + ); + } + + // If `analytics` hasn't been explicitly set, we disable + // it when ran programatically. + if (config.analytics == null) { + // Don't enable analytics on CI server unless explicitly configured. + config.analytics = config.interactive; + } + + // Merge common CLI options into the config + object.mixIn(config, cli.readOptions({ + force: { type: Boolean, shorthand: 'f' }, + offline: { type: Boolean, shorthand: 'o' }, + verbose: { type: Boolean, shorthand: 'V' }, + quiet: { type: Boolean, shorthand: 'q' }, + loglevel: { type: String, shorthand: 'l' }, + json: { type: Boolean, shorthand: 'j' }, + silent: { type: Boolean, shorthand: 's' } + })); + + return config; } -// Merge common CLI options into the config -mout.object.mixIn(config, cli.readOptions({ - force: { type: Boolean, shorthand: 'f' }, - offline: { type: Boolean, shorthand: 'o' }, - verbose: { type: Boolean, shorthand: 'V' }, - quiet: { type: Boolean, shorthand: 'q' }, - loglevel: { type: String, shorthand: 'l' }, - json: { type: Boolean, shorthand: 'j' }, - silent: { type: Boolean, shorthand: 's' } -})); - -module.exports = config; +module.exports = defaultConfig; diff --git a/lib/core/Project.js b/lib/core/Project.js index 2399238b6..2b6de418c 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -20,7 +20,7 @@ function Project(config, logger) { // on config and logger // The reason behind it is that users can likely use this component // directly if commands do not fulfil their needs - this._config = config || defaultConfig; + this._config = defaultConfig(config); this._logger = logger || new Logger(); this._manager = new Manager(this._config, this._logger); diff --git a/lib/core/resolvers/GitResolver.js b/lib/core/resolvers/GitResolver.js index 800e1c8d4..231c98828 100644 --- a/lib/core/resolvers/GitResolver.js +++ b/lib/core/resolvers/GitResolver.js @@ -10,7 +10,6 @@ var mout = require('mout'); var Resolver = require('./Resolver'); var semver = require('../../util/semver'); var createError = require('../../util/createError'); -var defaultConfig = require('../../config'); var hasGit; @@ -22,13 +21,13 @@ try { hasGit = false; } -// Set template dir to the empty directory so that user templates are not run -// This environment variable is not multiple config aware but it's not documented -// anyway -mkdirp.sync(defaultConfig.storage.empty); -process.env.GIT_TEMPLATE_DIR = defaultConfig.storage.empty; - function GitResolver(decEndpoint, config, logger) { + // Set template dir to the empty directory so that user templates are not run + // This environment variable is not multiple config aware but it's not documented + // anyway + mkdirp.sync(config.storage.empty); + process.env.GIT_TEMPLATE_DIR = config.storage.empty; + Resolver.call(this, decEndpoint, config, logger); if (!hasGit) { diff --git a/lib/index.js b/lib/index.js index d1cedd055..1efed6af1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -37,7 +37,7 @@ function clearRuntimeCache() { module.exports = { version: pkg.version, commands: commands, - config: require('./config'), + config: require('./config')(), abbreviations: abbreviations, reset: clearRuntimeCache }; diff --git a/test/assets/test-temp-dir/test-exception.js b/test/assets/test-temp-dir/test-exception.js index f97bfc004..fd73e18a0 100644 --- a/test/assets/test-temp-dir/test-exception.js +++ b/test/assets/test-temp-dir/test-exception.js @@ -4,7 +4,7 @@ var Logger = require('bower-logger'); var Resolver = require('../../../lib/core/resolvers/Resolver'); var defaultConfig = require('../../../lib/config'); -var resolver = new Resolver({ source: 'foo' }, defaultConfig, new Logger()); +var resolver = new Resolver({ source: 'foo' }, defaultConfig(), new Logger()); resolver._createTempDir() .then(function (dir) { // Need to write something to prevent tmp to automatically diff --git a/test/assets/test-temp-dir/test.js b/test/assets/test-temp-dir/test.js index f9d965adb..5950a717d 100644 --- a/test/assets/test-temp-dir/test.js +++ b/test/assets/test-temp-dir/test.js @@ -4,7 +4,7 @@ var Logger = require('bower-logger'); var Resolver = require('../../../lib/core/resolvers/Resolver'); var defaultConfig = require('../../../lib/config'); -var resolver = new Resolver({ source: 'foo' }, defaultConfig, new Logger()); +var resolver = new Resolver({ source: 'foo' }, defaultConfig(), new Logger()); resolver._createTempDir() .then(function (dir) { // Need to write something to prevent tmp to automatically diff --git a/test/commands/init.js b/test/commands/init.js index ffe355769..5e3ebff68 100644 --- a/test/commands/init.js +++ b/test/commands/init.js @@ -7,15 +7,17 @@ var bower = helpers.require('lib/index'); describe('bower init', function () { - var tempDir = helpers.createTmpDir(); - var bowerJsonPath = path.join(tempDir, 'bower.json'); + var tempDir = new helpers.TempDir(); + var bowerJsonPath = path.join(tempDir.path, 'bower.json'); var config = { - cwd: tempDir, + cwd: tempDir.path, interactive: true }; it('generates bower.json file', function () { + tempDir.prepare(); + var logger = bower.commands.init(config); return helpers.expectEvent(logger, 'prompt') diff --git a/test/commands/install.js b/test/commands/install.js index 206b890ad..b1fd971fc 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -3,25 +3,41 @@ var expect = require('expect.js'); var fs = require('fs'); var helpers = require('../helpers'); -var bower = helpers.require('lib/index'); +var commands = helpers.require('lib/index').commands; describe('bower install', function () { - var tempDir = helpers.createTmpDir(); - var bowerJsonPath = path.join(tempDir, 'bower_components', 'underscore', 'bower.json'); + var tempDir = new helpers.TempDir(); + function bowerJson() { + var bowerJsonPath = path.join( + tempDir.path, 'bower_components', 'underscore', 'bower.json' + ); + return JSON.parse(fs.readFileSync(bowerJsonPath)); } var config = { - cwd: tempDir, + cwd: tempDir.path, interactive: true }; + var install = function(options) { + options = options || {}; + + var logger = commands.install( + options.packages, options.options, config + ); + + return helpers.expectEvent(logger, 'end'); + }; + it.skip('installs a package', function () { + tempDir.prepare(); + this.timeout(10000); - var logger = bower.commands.install(['underscore'], undefined, config); + var logger = commands.install(['underscore'], undefined, config); return helpers.expectEvent(logger, 'end') .then(function () { @@ -30,7 +46,9 @@ describe('bower install', function () { }); it.skip('installs package with --save flag', function () { - var logger = bower.commands.install(['underscore'], {save: true}, config); + tempDir.prepare(); + + var logger = commands.install(['underscore'], {save: true}, config); return helpers.expectEvent(logger, 'end') .then(function () { @@ -38,4 +56,27 @@ describe('bower install', function () { }); }); + it('reads .bowerrc from cwd', function () { + var package = new helpers.TempDir({ + 'bower.json': { + name: 'package' + }, + foo: 'bar' + }).prepare(); + + tempDir.prepare({ + '.bowerrc': { directory: 'assets' }, + 'bower.json': { + name: 'test', + dependencies: { + package: package.path + } + } + }); + + return install().then(function() { + expect(tempDir.read('assets/package/foo')).to.be('bar'); + }); + }); + }); diff --git a/test/commands/uninstall.js b/test/commands/uninstall.js index decf3a70f..dd7038d4c 100644 --- a/test/commands/uninstall.js +++ b/test/commands/uninstall.js @@ -7,7 +7,7 @@ var bower = helpers.require('lib/index'); describe('bower uninstall', function () { - var tempDir = helpers.createTmpDir({ + var tempDir = new helpers.TempDir({ 'bower.json': { name: 'hello-world', dependencies: { @@ -16,14 +16,18 @@ describe('bower uninstall', function () { } }); - var bowerJsonPath = path.join(tempDir, 'bower.json'); + beforeEach(function() { + tempDir.prepare(); + }); + + var bowerJsonPath = path.join(tempDir.path, 'bower.json'); function bowerJson() { return JSON.parse(fs.readFileSync(bowerJsonPath)); } var config = { - cwd: tempDir, + cwd: tempDir.path, interactive: true }; diff --git a/test/core/Manager.js b/test/core/Manager.js index 06f6db34f..940d8887d 100644 --- a/test/core/Manager.js +++ b/test/core/Manager.js @@ -1,6 +1,5 @@ var expect = require('expect.js'); var path = require('path'); -var mout = require('mout'); var rimraf = require('rimraf'); var Logger = require('bower-logger'); var Manager = require('../../lib/core/Manager'); @@ -23,7 +22,7 @@ describe('Manager', function () { beforeEach(function (next) { var logger = new Logger(); - var config = mout.object.deepMixIn({}, defaultConfig, { + var config = defaultConfig({ storage: { packages: packagesCacheDir, registry: registryCacheDir diff --git a/test/core/packageRepository.js b/test/core/packageRepository.js index 36e6ef643..1b7cf1f7d 100644 --- a/test/core/packageRepository.js +++ b/test/core/packageRepository.js @@ -35,7 +35,7 @@ describe('PackageRepository', function () { var logger = new Logger(); // Config - config = mout.object.deepMixIn({}, defaultConfig, { + config = defaultConfig({ storage: { packages: packagesCacheDir, registry: registryCacheDir diff --git a/test/core/resolveCache.js b/test/core/resolveCache.js index a00fb4bb6..97ffdfbd4 100644 --- a/test/core/resolveCache.js +++ b/test/core/resolveCache.js @@ -23,7 +23,7 @@ describe('ResolveCache', function () { rimraf.sync(cacheDir); // Instantiate resolver cache - resolveCache = new ResolveCache(mout.object.deepMixIn(defaultConfig, { + resolveCache = new ResolveCache(defaultConfig({ storage: { packages: cacheDir } @@ -55,7 +55,7 @@ describe('ResolveCache', function () { }); function initialize(cacheDir) { - return new ResolveCache(mout.object.deepMixIn(defaultConfig, { + return new ResolveCache(defaultConfig({ storage: { packages: cacheDir } diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 3c2bcf14a..7a960bf8a 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -14,9 +14,9 @@ var defaultConfig = require('../../lib/config'); describe('resolverFactory', function () { var tempSource; var logger = new Logger(); - var registryClient = new RegistryClient(mout.object.fillIn({ - cache: defaultConfig._registry - }, defaultConfig)); + var registryClient = new RegistryClient(defaultConfig({ + cache: defaultConfig()._registry + })); afterEach(function (next) { logger.removeAllListeners(); @@ -34,7 +34,7 @@ describe('resolverFactory', function () { }); function callFactory(decEndpoint, config) { - return resolverFactory(decEndpoint, config || defaultConfig, logger, registryClient); + return resolverFactory(decEndpoint, defaultConfig(config), logger, registryClient); } it('should recognize git remote endpoints correctly', function (next) { @@ -584,14 +584,12 @@ describe('resolverFactory', function () { it('should use the configured shorthand resolver', function (next) { callFactory({ source: 'bower/bower' }) .then(function (resolver) { - var config; + var config = { + shorthandResolver: 'git://bower.io/{{owner}}/{{package}}/{{shorthand}}' + }; expect(resolver.getSource()).to.equal('git://github.com/bower/bower.git'); - config = mout.object.fillIn({ - shorthandResolver: 'git://bower.io/{{owner}}/{{package}}/{{shorthand}}' - }, defaultConfig); - return callFactory({ source: 'IndigoUnited/promptly' }, config); }) .then(function (resolver) { @@ -616,7 +614,7 @@ describe('resolverFactory', function () { it('should error out if there\'s no suitable resolver for a given source', function (next) { - resolverFactory({ source: 'some-package-that-will-never-exist' }, defaultConfig, logger) + resolverFactory({ source: 'some-package-that-will-never-exist' }, defaultConfig(), logger) .then(function () { throw new Error('Should have failed'); }, function (err) { diff --git a/test/core/resolvers/fsResolver.js b/test/core/resolvers/fsResolver.js index 0705e214d..a7151d5ca 100644 --- a/test/core/resolvers/fsResolver.js +++ b/test/core/resolvers/fsResolver.js @@ -35,12 +35,12 @@ describe('FsResolver', function () { } }); - function create(decEndpoint, config) { + function create(decEndpoint) { if (typeof decEndpoint === 'string') { decEndpoint = { source: decEndpoint }; } - return new FsResolver(decEndpoint, config || defaultConfig, logger); + return new FsResolver(decEndpoint, defaultConfig(), logger); } describe('.constructor', function () { diff --git a/test/core/resolvers/gitFsResolver.js b/test/core/resolvers/gitFsResolver.js index 262d86a4f..59219c352 100644 --- a/test/core/resolvers/gitFsResolver.js +++ b/test/core/resolvers/gitFsResolver.js @@ -33,12 +33,12 @@ describe('GitFsResolver', function () { GitFsResolver.clearRuntimeCache(); } - function create(decEndpoint, config) { + function create(decEndpoint) { if (typeof decEndpoint === 'string') { decEndpoint = { source: decEndpoint }; } - return new GitFsResolver(decEndpoint, config || defaultConfig, logger); + return new GitFsResolver(decEndpoint, defaultConfig(), logger); } describe('.constructor', function () { diff --git a/test/core/resolvers/gitHubResolver.js b/test/core/resolvers/gitHubResolver.js index 4b7c0d7f6..0e4b253ad 100644 --- a/test/core/resolvers/gitHubResolver.js +++ b/test/core/resolvers/gitHubResolver.js @@ -15,27 +15,19 @@ describe('GitHub', function () { logger = new Logger(); }); - beforeEach(function () { - // Turn off strict ssl because it gives problems with nock - defaultConfig.strictSsl = false; - }); - afterEach(function () { // Clean nocks nock.cleanAll(); logger.removeAllListeners(); - - // Enable strict ssl back again - defaultConfig.strictSsl = true; }); - function create(decEndpoint, config) { + function create(decEndpoint) { if (typeof decEndpoint === 'string') { decEndpoint = { source: decEndpoint }; } - return new GitHubResolver(decEndpoint, config || defaultConfig, logger); + return new GitHubResolver(decEndpoint, defaultConfig({ strictSsl: false }), logger); } describe('.constructor', function () { diff --git a/test/core/resolvers/gitRemoteResolver.js b/test/core/resolvers/gitRemoteResolver.js index f52d21b40..0d40db88d 100644 --- a/test/core/resolvers/gitRemoteResolver.js +++ b/test/core/resolvers/gitRemoteResolver.js @@ -21,12 +21,12 @@ describe('GitRemoteResolver', function () { GitRemoteResolver.clearRuntimeCache(); } - function create(decEndpoint, config) { + function create(decEndpoint) { if (typeof decEndpoint === 'string') { decEndpoint = { source: decEndpoint }; } - return new GitRemoteResolver(decEndpoint, config || defaultConfig, logger); + return new GitRemoteResolver(decEndpoint, defaultConfig(), logger); } describe('.constructor', function () { diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index 58f7d8bf1..cb74e9822 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -30,12 +30,12 @@ describe('GitResolver', function () { GitResolver.clearRuntimeCache(); } - function create(decEndpoint, config) { + function create(decEndpoint) { if (typeof decEndpoint === 'string') { decEndpoint = { source: decEndpoint }; } - return new GitResolver(decEndpoint, config || defaultConfig, logger); + return new GitResolver(decEndpoint, defaultConfig(), logger); } describe('misc', function () { @@ -334,7 +334,7 @@ describe('GitResolver', function () { }.bind(this)); }; - resolver = new DummyResolver({ source: 'foo', target: 'master' }, defaultConfig, logger); + resolver = new DummyResolver({ source: 'foo', target: 'master' }, defaultConfig(), logger); resolver.resolve() .then(function () { diff --git a/test/core/resolvers/resolver.js b/test/core/resolvers/resolver.js index b5769aa55..b6e590385 100644 --- a/test/core/resolvers/resolver.js +++ b/test/core/resolvers/resolver.js @@ -17,6 +17,7 @@ describe('Resolver', function () { var testPackage = path.resolve(__dirname, '../../assets/package-a'); var logger; var dirMode0777; + var config = defaultConfig(); before(function () { var stat; @@ -33,12 +34,12 @@ describe('Resolver', function () { logger.removeAllListeners(); }); - function create(decEndpoint, config) { + function create(decEndpoint) { if (typeof decEndpoint === 'string') { decEndpoint = { source: decEndpoint }; } - return new Resolver(decEndpoint, config || defaultConfig, logger); + return new Resolver(decEndpoint, config, logger); } describe('.getSource', function () { @@ -333,7 +334,7 @@ describe('Resolver', function () { }.bind(this)); }; - resolver = new DummyResolver({ source: 'foo'}, defaultConfig, logger); + resolver = new DummyResolver({ source: 'foo'}, config, logger); resolver.resolve() .then(function () { @@ -461,7 +462,7 @@ describe('Resolver', function () { osTempDir = path.resolve(tmp.tmpdir); expect(dir.indexOf(osTempDir)).to.be(0); - expect(dir.indexOf(defaultConfig.tmp)).to.be(0); + expect(dir.indexOf(config.tmp)).to.be(0); expect(path.basename(dirname)).to.equal('bower'); expect(path.dirname(path.dirname(dirname))).to.equal(osTempDir); @@ -487,13 +488,13 @@ describe('Resolver', function () { it('should remove the folder after execution', function (next) { this.timeout(15000); // Give some time to execute - rimraf(defaultConfig.tmp, function (err) { + rimraf(config.tmp, function (err) { if (err) return next(err); cmd('node', ['test/assets/test-temp-dir/test.js'], { cwd: path.resolve(__dirname, '../../..') }) .then(function () { - expect(fs.existsSync(defaultConfig.tmp)).to.be(true); - expect(fs.readdirSync(defaultConfig.tmp)).to.eql([]); + expect(fs.existsSync(config.tmp)).to.be(true); + expect(fs.readdirSync(config.tmp)).to.eql([]); next(); }, function (err) { next(new Error(err.details)); @@ -503,15 +504,15 @@ describe('Resolver', function () { }); it('should remove the folder on an uncaught exception', function (next) { - rimraf(defaultConfig.tmp, function (err) { + rimraf(config.tmp, function (err) { if (err) return next(err); cmd('node', ['test/assets/test-temp-dir/test-exception.js'], { cwd: path.resolve(__dirname, '../../..') }) .then(function () { next(new Error('The command should have failed')); }, function () { - expect(fs.existsSync(defaultConfig.tmp)).to.be(true); - expect(fs.readdirSync(defaultConfig.tmp)).to.eql([]); + expect(fs.existsSync(config.tmp)).to.be(true); + expect(fs.readdirSync(config.tmp)).to.eql([]); next(); }) .done(); diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index df3a46fb4..b431436f5 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -30,12 +30,12 @@ describe('SvnResolver', function () { SvnResolver.clearRuntimeCache(); } - function create(decEndpoint, config) { + function create(decEndpoint) { if (typeof decEndpoint === 'string') { decEndpoint = { source: decEndpoint }; } - return new SvnResolver(decEndpoint, config || defaultConfig, logger); + return new SvnResolver(decEndpoint, defaultConfig(), logger); } describe('misc', function () { @@ -278,7 +278,7 @@ describe('SvnResolver', function () { }.bind(this)); }; - resolver = new DummyResolver({ source: 'foo', target: '1.0.0' }, defaultConfig, logger); + resolver = new DummyResolver({ source: 'foo', target: '1.0.0' }, defaultConfig(), logger); resolver.resolve() .then(function () { diff --git a/test/core/resolvers/urlResolver.js b/test/core/resolvers/urlResolver.js index c150f9311..79c3a05b7 100644 --- a/test/core/resolvers/urlResolver.js +++ b/test/core/resolvers/urlResolver.js @@ -31,12 +31,12 @@ describe('UrlResolver', function () { nock.cleanAll(); }); - function create(decEndpoint, config) { + function create(decEndpoint) { if (typeof decEndpoint === 'string') { decEndpoint = { source: decEndpoint }; } - return new UrlResolver(decEndpoint, config || defaultConfig, logger); + return new UrlResolver(decEndpoint, defaultConfig(), logger); } describe('.constructor', function () { diff --git a/test/helpers.js b/test/helpers.js index 43c47e296..8224485ed 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -5,16 +5,31 @@ var rimraf = require('rimraf'); var uuid = require('node-uuid'); var object = require('mout/object'); var fs = require('fs'); +var object = require('mout/object'); exports.require = function (name) { return require(path.join(__dirname, '../', name)); }; -exports.createTmpDir = function (files) { - var tempDir = path.join(__dirname, 'tmp/' + uuid.v4()); - beforeEach(function () { - mkdirp.sync(tempDir); +after(function () { + rimraf.sync(path.join(__dirname, 'tmp')); +}); + +exports.TempDir = (function() { + function TempDir (defaultFiles) { + this.path = path.join(__dirname, 'tmp/' + uuid.v4()); + this.defaultFiles = defaultFiles; + } + + TempDir.prototype.prepare = function (files) { + var that = this; + + files = object.merge(files || {}, this.defaultFiles); + + rimraf.sync(that.path); + + mkdirp.sync(that.path); if (files) { object.forOwn(files, function (contents, filepath) { @@ -22,24 +37,28 @@ exports.createTmpDir = function (files) { contents = JSON.stringify(contents, null, ' '); } - var fullPath = path.join(tempDir, filepath); + var fullPath = path.join(that.path, filepath); mkdirp.sync(path.dirname(fullPath)); fs.writeFileSync(fullPath, contents); }); } - }); - afterEach(function () { - rimraf.sync(tempDir); - }); + return this; + }; - return tempDir; -}; + TempDir.prototype.read = function (name) { + return fs.readFileSync(path.join(this.path, name), 'utf8'); + }; + + return TempDir; +})(); exports.expectEvent = function (emitter, eventName) { var deferred = Q.defer(); + emitter.once(eventName, function () { deferred.resolve(arguments); }); + return deferred.promise; }; diff --git a/test/util/removeIgnores.js b/test/util/removeIgnores.js index 37914f74d..3d79aeb7a 100644 --- a/test/util/removeIgnores.js +++ b/test/util/removeIgnores.js @@ -7,13 +7,15 @@ var removeIgnores = require('../../lib/util/removeIgnores'); describe('removeIgnores', function () { - var tempDir = helpers.createTmpDir({ + var tempDir = new helpers.TempDir({ 'bower.json': {}, 'index.js': 'Not to ignore', 'node_modules/underscore/index.js': 'Should be ignored' }); var ignoreTest = function(dir, meta, leftovers) { + tempDir.prepare(); + var deferred = Q.defer(); removeIgnores(dir, meta).then(function() { @@ -27,42 +29,42 @@ describe('removeIgnores', function () { }; it('removes all files in directory', function () { - return ignoreTest(tempDir, + return ignoreTest(tempDir.path, { ignore: [ 'node_modules/**/*' ] }, [ 'bower.json', 'index.js' ] ); }); it('removes whole directory', function () { - return ignoreTest(tempDir, + return ignoreTest(tempDir.path, { ignore: [ 'node_modules/' ] }, [ 'bower.json', 'index.js' ] ); }); it('removes whole directory (no ending slash)', function () { - return ignoreTest(tempDir, + return ignoreTest(tempDir.path, { ignore: [ 'node_modules' ] }, [ 'bower.json', 'index.js' ] ); }); it('removes all but one file', function() { - return ignoreTest(tempDir, + return ignoreTest(tempDir.path, { ignore: [ '**/*', '!bower.json' ] }, [ 'bower.json' ] ); }); it('refuses to ignore bower.json', function() { - return ignoreTest(tempDir, + return ignoreTest(tempDir.path, { ignore: [ '**/*', '!index.js' ] }, [ 'bower.json', 'index.js' ] ); }); it('removes all but one file deep down the tree', function() { - return ignoreTest(tempDir, + return ignoreTest(tempDir.path, { ignore: [ '**/*', '!node_modules/underscore/index.js' ] }, [ 'bower.json', From 91aa5dc6dd8d2c6cdc671880460f6a58468e09ab Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sat, 6 Sep 2014 17:20:32 +0200 Subject: [PATCH 0446/1021] bump dependencies --- .travis.yml | 2 -- package.json | 33 +++++++++++++++++---------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 13b27d5d7..a910f7a3a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,5 @@ node_js: matrix: allow_failures: - node_js: '0.11' -before_script: - - npm install -g grunt-cli script: - grunt travis diff --git a/package.json b/package.json index 9a4108954..15ae23b42 100644 --- a/package.json +++ b/package.json @@ -26,34 +26,34 @@ "cardinal": "~0.4.0", "chalk": "~0.5.0", "chmodr": "~0.1.0", - "decompress-zip": "0.0.6", - "fstream": "~0.1.22", - "fstream-ignore": "0.0.6", + "decompress-zip": "0.0.8", + "fstream": "~1.0.2", + "fstream-ignore": "~1.0.1", "glob": "~4.0.2", "graceful-fs": "~3.0.1", - "handlebars": "~1.3.0", - "inquirer": "~0.5.1", + "handlebars": "~2.0.0", + "inquirer": "~0.7.1", "insight": "~0.4.1", - "is-root": "~0.1.0", - "junk": "~0.3.0", - "lockfile": "~0.4.2", + "is-root": "~1.0.0", + "junk": "~1.0.0", + "lockfile": "~1.0.0", "lru-cache": "~2.5.0", "mkdirp": "~0.5.0", - "mout": "~0.9.1", + "mout": "~0.10.0", "nopt": "~3.0.0", - "opn": "~0.1.1", + "opn": "~1.0.0", "osenv": "~0.1.0", "p-throttler": "0.0.1", "promptly": "~0.2.0", "q": "~1.0.1", - "request": "~2.36.0", + "request": "~2.42.0", "request-progress": "~0.3.0", "retry": "~0.6.0", "rimraf": "~2.2.0", "semver": "~2.3.0", "shell-quote": "~1.4.1", - "stringify-object": "~0.2.0", - "tar": "~0.1.17", + "stringify-object": "~1.0.0", + "tar": "~1.0.1", "tmp": "0.0.23", "update-notifier": "~0.2.0", "which": "~1.0.5" @@ -62,14 +62,15 @@ "coveralls": "~2.11.0", "expect.js": "~0.3.1", "grunt": "~0.4.4", + "grunt-cli": "^0.1.13", "grunt-contrib-jshint": "~0.10.0", "grunt-contrib-watch": "~0.6.1", "grunt-exec": "~0.4.2", "grunt-simple-mocha": "~0.4.0", - "istanbul": "~0.2.4", + "istanbul": "~0.3.2", "load-grunt-tasks": "~0.6.0", - "mocha": "~1.20.1", - "nock": "~0.41.0", + "mocha": "~1.21.4", + "nock": "~0.46.0", "node-uuid": "~1.4.1", "proxyquire": "~1.0.1" }, From bf93a6a1ab34dfb22bf36893cfc17192d536a086 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sat, 6 Sep 2014 17:58:47 +0200 Subject: [PATCH 0447/1021] make `bower list --paths` a bit prettier --- lib/renderers/StandardRenderer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index 279676963..4d5af6d1d 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -169,7 +169,7 @@ StandardRenderer.prototype._list = function (tree) { tree.root = true; cliTree = archy(this._tree2archy(tree)); } else { - cliTree = stringifyObject(tree, { indent: ' ' }) + '\n'; + cliTree = stringifyObject(tree, { indent: ' ' }).replace(/[{}]/g, '') + '\n'; } this._write(process.stdout, cliTree); From 32356f23d39ed19d4cdbdd2eb1016f0cf2a09ffb Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 6 Sep 2014 03:15:04 +0200 Subject: [PATCH 0448/1021] Run posthook after saving bower.json, fixes #1471 --- lib/config.js | 5 ++ lib/core/Manager.js | 40 ++++++++++-- lib/core/Project.js | 21 ++++-- test/commands/install.js | 136 ++++++++++++++++++++++++++++----------- test/helpers.js | 11 +++- 5 files changed, 163 insertions(+), 50 deletions(-) diff --git a/lib/config.js b/lib/config.js index cd044d7f6..20985f31f 100644 --- a/lib/config.js +++ b/lib/config.js @@ -54,4 +54,9 @@ function readCachedConfig(cwd) { return config; } +function resetCache () { + cachedConfigs = {}; +} + module.exports = defaultConfig; +module.exports.reset = resetCache; diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 42725d9f6..fc460b6ab 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -109,6 +109,40 @@ Manager.prototype.resolve = function () { }.bind(this)); }; +Manager.prototype.preinstall = function (json) { + var that = this; + var componentsDir = path.join(this._config.cwd, this._config.directory); + + // If nothing to install, skip the code bellow + if (mout.lang.isEmpty(that._dissected)) { + return Q.resolve({}); + } + + return Q.nfcall(mkdirp, componentsDir) + .then(function () { + return scripts.preinstall( + that._config, that._logger, that._dissected, that._installed, json + ); + }); +}; + +Manager.prototype.postinstall = function (json) { + var that = this; + var componentsDir = path.join(this._config.cwd, this._config.directory); + + // If nothing to install, skip the code bellow + if (mout.lang.isEmpty(that._dissected)) { + return Q.resolve({}); + } + + return Q.nfcall(mkdirp, componentsDir) + .then(function () { + return scripts.postinstall( + that._config, that._logger, that._dissected, that._installed, json + ); + }); +}; + Manager.prototype.install = function (json) { var componentsDir; var that = this; @@ -125,9 +159,6 @@ Manager.prototype.install = function (json) { componentsDir = path.join(this._config.cwd, this._config.directory); return Q.nfcall(mkdirp, componentsDir) - .then(function () { - return scripts.preinstall(that._config, that._logger, that._dissected, that._installed, json); - }) .then(function () { var promises = []; @@ -169,9 +200,6 @@ Manager.prototype.install = function (json) { return Q.all(promises); }) - .then(function () { - return scripts.postinstall(that._config, that._logger, that._dissected, that._installed, json); - }) .then(function () { // Sync up dissected dependencies and dependants // See: https://github.com/bower/bower/issues/879 diff --git a/lib/core/Project.js b/lib/core/Project.js index 2b6de418c..b38b17e51 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -78,6 +78,12 @@ Project.prototype.install = function (decEndpoints, options, config) { // Bootstrap the process return that._bootstrap(targets, resolved, incompatibles); }) + .then(function () { + return that._manager.preinstall(that._json); + }) + .then(function () { + return that._manager.install(that._json); + }) .then(function (installed) { // Handle save and saveDev options if (that._options.save || that._options.saveDev) { @@ -100,7 +106,9 @@ Project.prototype.install = function (decEndpoints, options, config) { // Save JSON, might contain changes to dependencies and resolutions return that.saveJson() .then(function () { - return installed; + return that._manager.postinstall(that._json).then(function () { + return installed; + }); }); }) .fin(function () { @@ -181,11 +189,16 @@ Project.prototype.update = function (names, options) { // Bootstrap the process return that._bootstrap(targets, resolved, incompatibles) + .then(function () { + return that._manager.preinstall(that._json); + }) .then(function (installed) { // Save JSON, might contain changes to resolutions return that.saveJson() .then(function () { - return installed; + return that._manager.postinstall(that._json).then(function () { + return installed; + }); }); }); }) @@ -529,9 +542,7 @@ Project.prototype._bootstrap = function (targets, resolved, incompatibles) { if (!mout.object.size(this._json.resolutions)) { delete this._json.resolutions; } - }.bind(this)) - // Install resolved ones - .then(this._manager.install.bind(this._manager, this._json)); + }.bind(this)); }; Project.prototype._readJson = function () { diff --git a/test/commands/install.js b/test/commands/install.js index b1fd971fc..60539f958 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -1,6 +1,5 @@ -var path = require('path'); var expect = require('expect.js'); -var fs = require('fs'); +var object = require('mout').object; var helpers = require('../helpers'); var commands = helpers.require('lib/index').commands; @@ -9,74 +8,135 @@ describe('bower install', function () { var tempDir = new helpers.TempDir(); + var package = new helpers.TempDir({ + 'bower.json': { + name: 'package' + } + }).prepare(); - function bowerJson() { - var bowerJsonPath = path.join( - tempDir.path, 'bower_components', 'underscore', 'bower.json' - ); - - return JSON.parse(fs.readFileSync(bowerJsonPath)); - } - - var config = { - cwd: tempDir.path, - interactive: true - }; - - var install = function(options) { - options = options || {}; + var install = function(packages, options, config) { + config = object.merge(config || {}, { + cwd: tempDir.path + }); var logger = commands.install( - options.packages, options.options, config + packages, options, config ); return helpers.expectEvent(logger, 'end'); }; - it.skip('installs a package', function () { - tempDir.prepare(); + it('writes to bower.json if --save flag is used', function () { + package.prepare(); - this.timeout(10000); - var logger = commands.install(['underscore'], undefined, config); + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); - return helpers.expectEvent(logger, 'end') - .then(function () { - expect(bowerJson()).to.have.key('name'); + return install([package.path], { save: true }).then(function() { + expect(tempDir.read('bower.json')).to.contain('dependencies'); }); }); - it.skip('installs package with --save flag', function () { - tempDir.prepare(); + it('reads .bowerrc from cwd', function () { + package.prepare({ foo: 'bar' }); - var logger = commands.install(['underscore'], {save: true}, config); + tempDir.prepare({ + '.bowerrc': { directory: 'assets' }, + 'bower.json': { + name: 'test', + dependencies: { + package: package.path + } + } + }); - return helpers.expectEvent(logger, 'end') - .then(function () { - expect(bowerJson()).to.have.key('name'); + return install().then(function() { + expect(tempDir.read('assets/package/foo')).to.be('bar'); }); }); - it('reads .bowerrc from cwd', function () { - var package = new helpers.TempDir({ + it('runs preinstall hook', function () { + package.prepare(); + + tempDir.prepare({ 'bower.json': { - name: 'package' + name: 'test', + dependencies: { + package: package.path + } }, - foo: 'bar' - }).prepare(); + '.bowerrc': { + scripts: { + preinstall: 'bash -c "echo -n % > preinstall.txt"' + } + } + }); + + return install().then(function() { + expect(tempDir.read('preinstall.txt')).to.be('package'); + }); + }); + + it('runs preinstall hook', function () { + package.prepare(); tempDir.prepare({ - '.bowerrc': { directory: 'assets' }, 'bower.json': { name: 'test', dependencies: { package: package.path } + }, + '.bowerrc': { + scripts: { + postinstall: 'bash -c "echo -n % > postinstall.txt"' + } } }); return install().then(function() { - expect(tempDir.read('assets/package/foo')).to.be('bar'); + expect(tempDir.read('postinstall.txt')).to.be('package'); }); }); + // To be discussed, but that's the implementation now + it('does not run hooks if nothing is installed', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test' + }, + '.bowerrc': { + scripts: { + postinstall: 'bash -c "echo -n % > hooks.txt"', + preinstall: 'bash -c "echo -n % > hooks.txt"' + } + } + }); + + return install().then(function() { + expect(tempDir.exists('hooks.txt')).to.be(false); + }); + }); + + it('runs postinstall after bower.json is written', function () { + package.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test' + }, + '.bowerrc': { + scripts: { + postinstall: 'bash -c "cat bower.json > hook.txt"', + } + } + }); + + return install([package.path], { save: true }).then(function() { + expect(tempDir.read('hook.txt')).to.contain('dependencies'); + }); + }); }); diff --git a/test/helpers.js b/test/helpers.js index 8224485ed..21e1ab925 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -6,11 +6,16 @@ var uuid = require('node-uuid'); var object = require('mout/object'); var fs = require('fs'); var object = require('mout/object'); +var config = require('../lib/config'); exports.require = function (name) { return require(path.join(__dirname, '../', name)); }; +// We need to reset cache because tests are reusing temp directories +beforeEach(function () { + config.reset(); +}); after(function () { rimraf.sync(path.join(__dirname, 'tmp')); @@ -34,7 +39,7 @@ exports.TempDir = (function() { if (files) { object.forOwn(files, function (contents, filepath) { if (typeof contents === 'object') { - contents = JSON.stringify(contents, null, ' '); + contents = JSON.stringify(contents, null, ' ') + '\n'; } var fullPath = path.join(that.path, filepath); @@ -50,6 +55,10 @@ exports.TempDir = (function() { return fs.readFileSync(path.join(this.path, name), 'utf8'); }; + TempDir.prototype.exists = function (name) { + return fs.existsSync(path.join(this.path, name)); + }; + return TempDir; })(); From 623f6e9542e4bd6681f6b9bede4f749adfadfb39 Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Wed, 3 Sep 2014 13:07:47 +0300 Subject: [PATCH 0449/1021] Use `tar-fs` instead of `tar` for faster TAR extraction --- lib/util/extract.js | 22 +++++++++++----------- package.json | 2 +- test/core/resolvers/urlResolver.js | 1 - 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/util/extract.js b/lib/util/extract.js index a7a47eedf..580c5662c 100644 --- a/lib/util/extract.js +++ b/lib/util/extract.js @@ -2,7 +2,7 @@ var path = require('path'); var fs = require('graceful-fs'); var zlib = require('zlib'); var DecompressZip = require('decompress-zip'); -var tar = require('tar'); +var tar = require('tar-fs'); var Q = require('q'); var mout = require('mout'); var junk = require('junk'); @@ -51,13 +51,11 @@ function extractTar(archive, dst) { fs.createReadStream(archive) .on('error', deferred.reject) - .pipe(tar.Extract({ - path: dst, - follow: false, // Do not follow symlinks (#699) - filter: filterSymlinks // Filter symlink files + .pipe(tar.extract(dst, { + ignore: isSymlink // Filter symlink files })) .on('error', deferred.reject) - .on('close', deferred.resolve.bind(deferred, dst)); + .on('finish', deferred.resolve.bind(deferred, dst)); return deferred.promise; } @@ -69,13 +67,11 @@ function extractTarGz(archive, dst) { .on('error', deferred.reject) .pipe(zlib.createGunzip()) .on('error', deferred.reject) - .pipe(tar.Extract({ - path: dst, - follow: false, // Do not follow symlinks (#699) - filter: filterSymlinks // Filter symlink files + .pipe(tar.extract(dst, { + ignore: isSymlink // Filter symlink files })) .on('error', deferred.reject) - .on('close', deferred.resolve.bind(deferred, dst)); + .on('finish', deferred.resolve.bind(deferred, dst)); return deferred.promise; } @@ -94,6 +90,10 @@ function extractGz(archive, dst) { return deferred.promise; } +function isSymlink(entry) { + return entry.type === 'SymbolicLink'; +} + function filterSymlinks(entry) { return entry.type !== 'SymbolicLink'; } diff --git a/package.json b/package.json index 15ae23b42..3b798140d 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "semver": "~2.3.0", "shell-quote": "~1.4.1", "stringify-object": "~1.0.0", - "tar": "~1.0.1", + "tar-fs": "~0.5.0", "tmp": "0.0.23", "update-notifier": "~0.2.0", "which": "~1.0.5" diff --git a/test/core/resolvers/urlResolver.js b/test/core/resolvers/urlResolver.js index 79c3a05b7..e4c441d2c 100644 --- a/test/core/resolvers/urlResolver.js +++ b/test/core/resolvers/urlResolver.js @@ -1,7 +1,6 @@ var expect = require('expect.js'); var path = require('path'); var fs = require('graceful-fs'); -var path = require('path'); var nock = require('nock'); var Q = require('q'); var rimraf = require('rimraf'); From 59d26c6825364f6b1631429274b43a10157e101e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 7 Sep 2014 23:43:39 +0200 Subject: [PATCH 0450/1021] Prevent error when piping bower output to head, fixes #1396 --- lib/renderers/StandardRenderer.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index 4d5af6d1d..6c804c634 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -30,6 +30,16 @@ function StandardRenderer(command, config) { } else { this._compact = process.stdout.columns < 120; } + + var exitOnPipeError = function (err) { + if (err.code === 'EPIPE') { + process.exit(0); + } + }; + + // It happens when piping command to "head" util + process.stdout.on('error', exitOnPipeError); + process.stderr.on('error', exitOnPipeError); } StandardRenderer.prototype.end = function (data) { From d743352bc0a94b5a9db01c98680203f7e004bf78 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 9 Jun 2014 02:24:29 +0200 Subject: [PATCH 0451/1021] Disable removing unnecessary resolutions, #1061 --- lib/core/Manager.js | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index fc460b6ab..0b059ec39 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -565,21 +565,6 @@ Manager.prototype._dissect = function () { // After a suitable version has been elected for every package promise .then(function () { - // Look for extraneous resolutions - mout.object.forOwn(this._resolutions, function (resolution, name) { - if (this._conflicted[name]) { - return; - } - - this._logger.info('resolution', 'Removed unnecessary ' + name + '#' + resolution + ' resolution', { - name: name, - resolution: resolution, - action: 'delete' - }); - - delete this._resolutions[name]; - }, this); - // Filter only packages that need to be installed componentsDir = path.resolve(that._config.cwd, that._config.directory); this._dissected = mout.object.filter(suitables, function (decEndpoint, name) { From 7565c71eb2f3f38c95d2b057eb84573cff6b4d54 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 8 Sep 2014 01:13:55 +0200 Subject: [PATCH 0452/1021] Warn about unnecessary resolution, #1061 --- lib/core/Manager.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 0b059ec39..d519b4f4b 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -565,6 +565,19 @@ Manager.prototype._dissect = function () { // After a suitable version has been elected for every package promise .then(function () { + // Look for extraneous resolutions + mout.object.forOwn(this._resolutions, function (resolution, name) { + if (this._conflicted[name]) { + return; + } + + this._logger.warn('extra-resolution', 'Unnecessary resolution: ' + name + '#' + resolution, { + name: name, + resolution: resolution, + action: 'delete' + }); + }, this); + // Filter only packages that need to be installed componentsDir = path.resolve(that._config.cwd, that._config.directory); this._dissected = mout.object.filter(suitables, function (decEndpoint, name) { From 3e1a50ab9ade35b3bfd53acd3f1cb9df57294447 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 8 Sep 2014 03:02:57 +0200 Subject: [PATCH 0453/1021] [test] Add tests for git repository install --- test/commands/install.js | 32 ++++++++++++++++++ test/helpers.js | 73 ++++++++++++++++++++++++++++++++++------ 2 files changed, 94 insertions(+), 11 deletions(-) diff --git a/test/commands/install.js b/test/commands/install.js index 60539f958..b875991b4 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -14,6 +14,8 @@ describe('bower install', function () { } }).prepare(); + var gitPackage = new helpers.TempDir(); + var install = function(packages, options, config) { config = object.merge(config || {}, { cwd: tempDir.path @@ -139,4 +141,34 @@ describe('bower install', function () { expect(tempDir.read('hook.txt')).to.contain('dependencies'); }); }); + + it('works for git repositories', function () { + return gitPackage.prepareGit({ + '1.0.0': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '1.0.0' + }, + '1.0.1': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '1.0.1' + } + }).then(function() { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.0' + } + } + }); + + return install().then(function() { + expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); + }); + }); + }); }); diff --git a/test/helpers.js b/test/helpers.js index 21e1ab925..59288d3f9 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -5,9 +5,13 @@ var rimraf = require('rimraf'); var uuid = require('node-uuid'); var object = require('mout/object'); var fs = require('fs'); -var object = require('mout/object'); +var glob = require('glob'); +var os = require('os'); +var cmd = require('../lib/util/cmd'); var config = require('../lib/config'); +var tmpLocation = path.join(os.tmpdir ? os.tmpdir() : os.tmpDir(), 'bower-tests'); + exports.require = function (name) { return require(path.join(__dirname, '../', name)); }; @@ -18,23 +22,19 @@ beforeEach(function () { }); after(function () { - rimraf.sync(path.join(__dirname, 'tmp')); + rimraf.sync(path.join(tmpLocation, 'tmp')); }); exports.TempDir = (function() { - function TempDir (defaultFiles) { - this.path = path.join(__dirname, 'tmp/' + uuid.v4()); - this.defaultFiles = defaultFiles; + function TempDir (defaults) { + this.path = path.join(tmpLocation, 'tmp/' + uuid.v4()); + this.defaults = defaults; } - TempDir.prototype.prepare = function (files) { + TempDir.prototype.create = function (files) { var that = this; - files = object.merge(files || {}, this.defaultFiles); - - rimraf.sync(that.path); - - mkdirp.sync(that.path); + files = object.merge(files || {}, this.defaults); if (files) { object.forOwn(files, function (contents, filepath) { @@ -51,6 +51,57 @@ exports.TempDir = (function() { return this; }; + TempDir.prototype.prepare = function (files) { + rimraf.sync(this.path); + mkdirp.sync(this.path); + this.create(files); + + return this; + }; + + // TODO: Rewrite to synchronous form + TempDir.prototype.prepareGit = function (revisions) { + var that = this; + + + revisions = object.merge(revisions || {}, this.defaults); + + rimraf.sync(that.path); + + mkdirp.sync(that.path); + + var promise = new Q(); + + object.forOwn(revisions, function (files, tag) { + promise = promise.then(function () { + return cmd('git', ['init'], { cwd: that.path }); + }).then(function () { + that.glob('./!(.git)').map(function (removePath) { + var fullPath = path.join(that.path, removePath); + + rimraf.sync(fullPath); + }); + + that.create(files); + }).then(function () { + return cmd('git', ['add', '-A'], { cwd: that.path }); + }).then(function () { + return cmd('git', ['commit', '-m"commit"'], { cwd: that.path }); + }).then(function () { + return cmd('git', ['tag', tag], { cwd: that.path }); + }); + }); + + return promise; + }; + + TempDir.prototype.glob = function (pattern) { + return glob.sync(pattern, { + cwd: this.path, + dot: true + }); + }; + TempDir.prototype.read = function (name) { return fs.readFileSync(path.join(this.path, name), 'utf8'); }; From c3b69d12013fdb325e03f6ab6c3b186be4185a8d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 8 Sep 2014 03:10:02 +0200 Subject: [PATCH 0454/1021] [test] Provide git credentials for tests on CI --- test/helpers.js | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 59288d3f9..06815c94f 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -10,6 +10,18 @@ var os = require('os'); var cmd = require('../lib/util/cmd'); var config = require('../lib/config'); +var env = { + 'GIT_AUTHOR_DATE': 'Sun Apr 7 22:13:13 2013 +0000', + 'GIT_AUTHOR_NAME': 'André Cruz', + 'GIT_AUTHOR_EMAIL': 'amdfcruz@gmail.com', + 'GIT_COMMITTER_DATE': 'Sun Apr 7 22:13:13 2013 +0000', + 'GIT_COMMITTER_NAME': 'André Cruz', + 'GIT_COMMITTER_EMAIL': 'amdfcruz@gmail.com' +}; + +// Preserve the original environment +object.mixIn(env, process.env); + var tmpLocation = path.join(os.tmpdir ? os.tmpdir() : os.tmpDir(), 'bower-tests'); exports.require = function (name) { @@ -63,7 +75,6 @@ exports.TempDir = (function() { TempDir.prototype.prepareGit = function (revisions) { var that = this; - revisions = object.merge(revisions || {}, this.defaults); rimraf.sync(that.path); @@ -74,7 +85,7 @@ exports.TempDir = (function() { object.forOwn(revisions, function (files, tag) { promise = promise.then(function () { - return cmd('git', ['init'], { cwd: that.path }); + return that.git('init'); }).then(function () { that.glob('./!(.git)').map(function (removePath) { var fullPath = path.join(that.path, removePath); @@ -84,11 +95,11 @@ exports.TempDir = (function() { that.create(files); }).then(function () { - return cmd('git', ['add', '-A'], { cwd: that.path }); + return that.git('add', '-A'); }).then(function () { - return cmd('git', ['commit', '-m"commit"'], { cwd: that.path }); + return that.git('commit', '-m"commit"'); }).then(function () { - return cmd('git', ['tag', tag], { cwd: that.path }); + return that.git('tag', tag); }); }); @@ -106,6 +117,12 @@ exports.TempDir = (function() { return fs.readFileSync(path.join(this.path, name), 'utf8'); }; + TempDir.prototype.git = function () { + var args = Array.prototype.slice.call(arguments); + + return cmd('git', args, { cwd: this.path, env: env }); + }; + TempDir.prototype.exists = function (name) { return fs.existsSync(path.join(this.path, name)); }; From dc183125fc5695deeb9ec7f7ada546d8034947cb Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 8 Sep 2014 03:12:36 +0200 Subject: [PATCH 0455/1021] [test] Show coverage status for master branch --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c47c46d95..bdd234d70 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bower -[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Coverage Status](https://coveralls.io/repos/bower/bower/badge.png?branch=feature%2Fintegration)](https://coveralls.io/r/bower/bower?branch=feature%2Fintegration) +[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Coverage Status](https://coveralls.io/repos/bower/bower/badge.png?branch=master)](https://coveralls.io/r/bower/bower?branch=master) From 615eba3b40e17d0c7daadab012a32512ce580cee Mon Sep 17 00:00:00 2001 From: Laurent Goderre Date: Thu, 11 Sep 2014 13:13:32 -0400 Subject: [PATCH 0456/1021] Update p-throttle to allow displaying the output of hooks Fixes #1484 --- package.json | 2 +- test/commands/install.js | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 3b798140d..853ce71c8 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "nopt": "~3.0.0", "opn": "~1.0.0", "osenv": "~0.1.0", - "p-throttler": "0.0.1", + "p-throttler": "0.1.0", "promptly": "~0.2.0", "q": "~1.0.1", "request": "~2.42.0", diff --git a/test/commands/install.js b/test/commands/install.js index b875991b4..53e622b4a 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -16,14 +16,16 @@ describe('bower install', function () { var gitPackage = new helpers.TempDir(); - var install = function(packages, options, config) { + var installLogger = function(packages, options, config) { config = object.merge(config || {}, { cwd: tempDir.path }); - var logger = commands.install( - packages, options, config - ); + return commands.install(packages, options, config); + }; + + var install = function(packages, options, config) { + var logger = installLogger(packages, options, config); return helpers.expectEvent(logger, 'end'); }; @@ -142,6 +144,34 @@ describe('bower install', function () { }); }); + it('display the output of hook scripts', function () { + package.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: package.path + } + }, + '.bowerrc': { + scripts: { + postinstall: 'bash -c "echo foobar"' + } + } + }); + + var lastAction = null; + + installLogger().intercept(function (log) { + if (log.level === 'action') { + lastAction = log; + } + }).on('end', function () { + expect(lastAction.message).to.be('foobar'); + }); + }); + it('works for git repositories', function () { return gitPackage.prepareGit({ '1.0.0': { From 6637762aecf3c0d07046d2d578ffd778efa8bf38 Mon Sep 17 00:00:00 2001 From: John Schulz Date: Wed, 13 Aug 2014 19:58:23 -0700 Subject: [PATCH 0457/1021] "analytics" value in \`.bowerrc\` removes need to prompt user --- lib/config.js | 7 ------- lib/util/analytics.js | 29 ++++++++++++++++++++++------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/lib/config.js b/lib/config.js index 20985f31f..3dfa6c5fe 100644 --- a/lib/config.js +++ b/lib/config.js @@ -33,13 +33,6 @@ function readCachedConfig(cwd) { ); } - // If `analytics` hasn't been explicitly set, we disable - // it when ran programatically. - if (config.analytics == null) { - // Don't enable analytics on CI server unless explicitly configured. - config.analytics = config.interactive; - } - // Merge common CLI options into the config object.mixIn(config, cli.readOptions({ force: { type: Boolean, shorthand: 'f' }, diff --git a/lib/util/analytics.js b/lib/util/analytics.js index 6638e410d..8b29e9d21 100644 --- a/lib/util/analytics.js +++ b/lib/util/analytics.js @@ -9,24 +9,39 @@ var insight; analytics.setup = function setup(config) { var deferred = Q.defer(); - // Display the ask prompt only if it hasn't been answered before - // and the current session is looking to configure the analytics. - if (config.analytics) { + // if `analytics` hasn't been explicitly set + if (config.analytics == null) { var Insight = require('insight'); var pkg = require('../../package.json'); - insight = new Insight({ trackingCode: 'UA-43531210-1', packageName: pkg.name, packageVersion: pkg.version }); - if (insight.optOut === undefined) { - insight.askPermission(null, deferred.resolve); - } else { + // if there is a stored value + if (insight.optOut !== undefined) { + // set analytics to the stored value + config.analytics = !insight.optOut; deferred.resolve(); + } else { + if (config.interactive) { + // prompt the user if this is an interactive session + insight.askPermission(null, function(err, optOut) { + // value is the *opposite* of user response + // https://github.com/yeoman/insight/issues/31 + config.analytics = !optOut; + deferred.resolve(); + }); + } else { + // no specified value, no stored value, and can't prompt for one + // so set analytics to true + config.analytics = true; + deferred.resolve(); + } } } else { + // use the specified value deferred.resolve(); } From dfd2c7a3d227bdbb404cf94cc32fbe5f79b47019 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 7 Sep 2014 23:09:04 +0200 Subject: [PATCH 0458/1021] Add tests to analytics and fix them --- lib/util/analytics.js | 37 +++++++++------ package.json | 2 +- test/util/analytics.js | 105 +++++++++++++++++++++++++++++++++++++++++ test/util/index.js | 1 + 4 files changed, 129 insertions(+), 16 deletions(-) create mode 100644 test/util/analytics.js diff --git a/lib/util/analytics.js b/lib/util/analytics.js index 8b29e9d21..1262ccc10 100644 --- a/lib/util/analytics.js +++ b/lib/util/analytics.js @@ -2,15 +2,13 @@ var Q = require('q'); var mout = require('mout'); var analytics = module.exports; -var insight; -// Initializes the application-wide insight singleton and asks for the -// permission on the CLI during the first run. -analytics.setup = function setup(config) { - var deferred = Q.defer(); +var insight; - // if `analytics` hasn't been explicitly set - if (config.analytics == null) { +// Insight takes long to load, and often causes problems +// in non-interactive environment, so we load it lazily +function ensureInsight () { + if (!insight) { var Insight = require('insight'); var pkg = require('../../package.json'); insight = new Insight({ @@ -18,6 +16,17 @@ analytics.setup = function setup(config) { packageName: pkg.name, packageVersion: pkg.version }); + } +} + +// Initializes the application-wide insight singleton and asks for the +// permission on the CLI during the first run. +analytics.setup = function setup (config) { + var deferred = Q.defer(); + + // if `analytics` hasn't been explicitly set + if (config.analytics == null) { + ensureInsight(); // if there is a stored value if (insight.optOut !== undefined) { @@ -26,11 +35,10 @@ analytics.setup = function setup(config) { deferred.resolve(); } else { if (config.interactive) { - // prompt the user if this is an interactive session - insight.askPermission(null, function(err, optOut) { - // value is the *opposite* of user response - // https://github.com/yeoman/insight/issues/31 - config.analytics = !optOut; + insight.askPermission(null, function(err, optIn) { + // optIn callback param was exactly opposite before 0.4.3 + // so we force at least insight@0.4.3 in package.json + config.analytics = optIn; deferred.resolve(); }); } else { @@ -55,9 +63,8 @@ var Tracker = analytics.Tracker = function Tracker(config) { }; Tracker.prototype.track = function track() { - if (!insight) { - throw new Error('You must call analytics.setup() prior to tracking.'); - } + ensureInsight(); + insight.track.apply(insight, arguments); }; diff --git a/package.json b/package.json index 853ce71c8..ff3f1fe28 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "graceful-fs": "~3.0.1", "handlebars": "~2.0.0", "inquirer": "~0.7.1", - "insight": "~0.4.1", + "insight": "~0.4.3", "is-root": "~1.0.0", "junk": "~1.0.0", "lockfile": "~1.0.0", diff --git a/test/util/analytics.js b/test/util/analytics.js new file mode 100644 index 000000000..19725a8eb --- /dev/null +++ b/test/util/analytics.js @@ -0,0 +1,105 @@ +var expect = require('expect.js'); +var proxyquire = require('proxyquire'); +var object = require('mout').object; + +describe('analytics', function () { + + var mockAnalytics = function(stubs, promptResponse) { + return proxyquire('../../lib/util/analytics', { + insight: function () { + return object.merge(stubs || {}, { + askPermission: function (message, callback) { + callback(undefined, promptResponse); + } + }); + }, + }); + }; + + describe('#setup', function () { + it('leaves analytics enabled if provided', function () { + var config = { analytics: true }; + + return mockAnalytics().setup(config).then(function () { + expect(config.analytics).to.be(true); + }); + }); + + it('leaves analytics disabled if provided', function () { + var config = { analytics: false }; + + return mockAnalytics().setup(config).then(function () { + expect(config.analytics).to.be(false); + }); + }); + + it('defaults to false if insight.optOut is true', function () { + var config = { }; + + return mockAnalytics({ optOut: true }).setup(config).then(function () { + expect(config.analytics).to.be(false); + }); + }); + + it('defaults to true if insight.optOut is false', function () { + var config = { }; + + return mockAnalytics({ optOut: false }).setup(config).then(function () { + expect(config.analytics).to.be(true); + }); + }); + + it('defaults to true if insight.optOut is undefined and noninteractive', function () { + var config = { }; + + return mockAnalytics({ optOut: undefined }).setup(config).then(function () { + expect(config.analytics).to.be(true); + }); + }); + + it('defautls to true if interactive insights return true from prompt', function () { + var config = { interactive: true }; + + return mockAnalytics({ optOut: undefined }, true).setup(config).then(function () { + expect(config.analytics).to.be(true); + }); + }); + + it('defautls to false if interactive insights return false from prompt', function () { + var config = { interactive: true }; + + return mockAnalytics({ optOut: undefined }, false).setup(config).then(function () { + expect(config.analytics).to.be(false); + }); + }); + }); + + describe('Tracker', function (next) { + it('tracks if analytics = true', function(next) { + var analytics = mockAnalytics({ + track: function (arg) { + expect(arg).to.be('foo'); + next(); + } + }); + + new analytics.Tracker({ + analytics: true + }).track('foo'); + }); + + it('does not track if analytics = false', function () { + var analytics = mockAnalytics({ + track: function (arg) { + throw new Error(); + } + }); + + expect(function () { + new analytics.Tracker({ + analytics: false + }).track('foo'); + }).to.not.throwError(); + }); + }); +}); diff --git a/test/util/index.js b/test/util/index.js index 8cd973a8d..0a53444a4 100644 --- a/test/util/index.js +++ b/test/util/index.js @@ -1,3 +1,4 @@ describe('util', function () { require('./removeIgnores'); + require('./analytics'); }); From 4ab36cb3bc839908c9f824501ca40ecb37694866 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 13 Sep 2014 16:04:02 +0200 Subject: [PATCH 0459/1021] [test] Use new temp location per process --- test/helpers.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index 06815c94f..28829f8fe 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -22,7 +22,11 @@ var env = { // Preserve the original environment object.mixIn(env, process.env); -var tmpLocation = path.join(os.tmpdir ? os.tmpdir() : os.tmpDir(), 'bower-tests'); +var tmpLocation = path.join( + os.tmpdir ? os.tmpdir() : os.tmpDir(), + 'bower-tests', + uuid.v4().slice(0, 8) +); exports.require = function (name) { return require(path.join(__dirname, '../', name)); @@ -34,12 +38,12 @@ beforeEach(function () { }); after(function () { - rimraf.sync(path.join(tmpLocation, 'tmp')); + rimraf.sync(tmpLocation); }); exports.TempDir = (function() { function TempDir (defaults) { - this.path = path.join(tmpLocation, 'tmp/' + uuid.v4()); + this.path = path.join(tmpLocation, uuid.v4()); this.defaults = defaults; } From 8e458c21e958b4ff834d37d0f1245c32968ce308 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 13 Sep 2014 16:12:06 +0200 Subject: [PATCH 0460/1021] [test] Make sure install ends before running next test --- test/commands/install.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/commands/install.js b/test/commands/install.js index 53e622b4a..49386cc4b 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -144,7 +144,7 @@ describe('bower install', function () { }); }); - it('display the output of hook scripts', function () { + it('display the output of hook scripts', function (next) { package.prepare(); tempDir.prepare({ @@ -169,6 +169,7 @@ describe('bower install', function () { } }).on('end', function () { expect(lastAction.message).to.be('foobar'); + next(); }); }); From fd4d68038bb8f96df4d16d70f38d6075ddbc0195 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 13 Sep 2014 16:39:35 +0200 Subject: [PATCH 0461/1021] Bump and update changelog --- CHANGELOG.md | 13 +++++++++++++ package.json | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f956d138..39b4b3148 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 1.3.10 - 2014-09-13 + +- [fix] Back down concurrency from 50 to 5 ([#1483](https://github.com/bower/bower/pull/1483)) +- [fix] Read .bowerrc from specified cwd ([#1301](https://github.com/bower/bower/pull/1301)) +- [fix] Disable shallow clones except those from GitHub ([#1393](https://github.com/bower/bower/pull/1393)) +- [fix] Expose bower version ([#1478](https://github.com/bower/bower/pull/1478)) +- [fix] Bump dependencies, including "request" ([#1467](https://github.com/bower/bower/pull/1467)) +- [fix] Prevent an error when piping bower output to head ([#1508](https://github.com/bower/bower/pull/1508)) +- [fix] Disable removing unnecessary resolutions ([#1061](https://github.com/bower/bower/pull/1061)) +- [fix] Display the output of hooks again ([#1484](https://github.com/bower/bower/issues/1484)) +- [fix] analytics: true in .bowerrc prevents user prompt ([#1470](https://github.com/bower/bower/pull/1470)) +- [perf] Use `tar-fs` instead of `tar` for faster TAR extraction ([#1490](https://github.com/bower/bower/pull/1490)) + ## 1.3.9 - 2014-08-06 - [fix] Handle `tmp` sometimes returning an array ([#1434](https://github.com/bower/bower/pull/1434)) diff --git a/package.json b/package.json index ff3f1fe28..8d1453b4a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.3.9", + "version": "1.3.10", "description": "The browser package manager", "author": "Twitter", "licenses": [ From ef237fc521316ec89144a3bcdc040d0698aed21b Mon Sep 17 00:00:00 2001 From: Laurent Goderre Date: Tue, 16 Sep 2014 10:24:20 -0400 Subject: [PATCH 0462/1021] Added the missing install command to the update task Fixes #1518 --- lib/core/Project.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/core/Project.js b/lib/core/Project.js index b38b17e51..32586080f 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -192,6 +192,9 @@ Project.prototype.update = function (names, options) { .then(function () { return that._manager.preinstall(that._json); }) + .then(function () { + return that._manager.install(that._json); + }) .then(function (installed) { // Save JSON, might contain changes to resolutions return that.saveJson() From e83ab86f1f4f39ab7571da79cdfbb16cf6e8ea73 Mon Sep 17 00:00:00 2001 From: Laurent Goderre Date: Tue, 16 Sep 2014 10:24:20 -0400 Subject: [PATCH 0463/1021] Added update test cases --- test/commands/index.js | 1 + test/commands/update.js | 239 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 test/commands/update.js diff --git a/test/commands/index.js b/test/commands/index.js index afef2f8d8..c02a4d894 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -2,4 +2,5 @@ describe('integration tests', function () { require('./init'); require('./install'); require('./uninstall'); + require('./update'); }); diff --git a/test/commands/update.js b/test/commands/update.js new file mode 100644 index 000000000..c72e05bfe --- /dev/null +++ b/test/commands/update.js @@ -0,0 +1,239 @@ +var expect = require('expect.js'); +var object = require('mout').object; + +var helpers = require('../helpers'); +var commands = helpers.require('lib/index').commands; + +describe('bower update', function () { + + var tempDir = new helpers.TempDir(); + + var gitPackage = new helpers.TempDir(); + gitPackage.prepareGit({ + '1.0.0': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '1.0.0' + }, + '1.0.1': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '1.0.1' + } + }); + + var package = new helpers.TempDir({ + 'bower.json': { + name: 'package' + } + }).prepare(); + + var updateLogger = function(packages, options, config) { + config = object.merge(config || {}, { + cwd: tempDir.path + }); + + return commands.update(packages, options, config); + }; + + var update = function(packages, options, config) { + var logger = updateLogger(packages, options, config); + + return helpers.expectEvent(logger, 'end'); + }; + + var install = function(packages, options, config) { + config = object.merge(config || {}, { + cwd: tempDir.path + }); + + var logger = commands.install( + packages, options, config + ); + + return helpers.expectEvent(logger, 'end'); + }; + + it('install missing packages', function () { + package.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: package.path + } + } + }); + + return update().then(function() { + expect(tempDir.exists('bower_components/package/bower.json')).to.equal(true); + expect(tempDir.read('bower_components/package/bower.json')).to.contain('"name": "package"'); + }); + }); + + it('runs preinstall hook when installing missing package', function () { + package.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: package.path + } + }, + '.bowerrc': { + scripts: { + preinstall: 'bash -c "echo -n % > preinstall.txt"' + } + } + }); + + return update().then(function() { + expect(tempDir.read('preinstall.txt')).to.be('package'); + }); + }); + + it('runs postinstall hook when installing missing package', function () { + package.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: package.path + } + }, + '.bowerrc': { + scripts: { + postinstall: 'bash -c "echo -n % > postinstall.txt"' + } + } + }); + + return update().then(function() { + expect(tempDir.read('postinstall.txt')).to.be('package'); + }); + }); + + it('doesn\'t runs postinstall when no package is update', function () { + package.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: package.path + } + }, + '.bowerrc': { + scripts: { + postinstall: 'bash -c "echo -n % > postinstall.txt"' + } + } + }); + + return install().then(function() { + tempDir.prepare(); + + return update().then(function() { + expect(tempDir.exists('postinstall.txt')).to.be(false); + }); + }); + }); + + it('updates a package', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.0' + } + } + }); + + return install().then(function() { + + expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.1' + } + } + }); + + return update().then(function() { + expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.1'); + }); + }); + }); + + it('runs preinstall hook when updating a package', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.0' + } + }, + '.bowerrc': { + scripts: { + preinstall: 'bash -c "echo -n % > preinstall.txt"' + } + } + }); + + return install().then(function() { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.1' + } + } + }); + + expect(tempDir.exists('preinstall.txt')).to.be(false); + return update().then(function() { + expect(tempDir.read('preinstall.txt')).to.be('package'); + }); + }); + }); + + it('runs postinstall hook when updating a package', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.0' + } + }, + '.bowerrc': { + scripts: { + postinstall: 'bash -c "echo -n % > postinstall.txt"' + } + } + }); + + return install().then(function() { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.1' + } + } + }); + + expect(tempDir.exists('postinstall.txt')).to.be(false); + return update().then(function() { + expect(tempDir.read('postinstall.txt')).to.be('package'); + }); + }); + }); +}); From fe2f71c9b89f650bba107bc221cf730c6bb5ab26 Mon Sep 17 00:00:00 2001 From: Laurent Goderre Date: Wed, 17 Sep 2014 11:12:17 -0400 Subject: [PATCH 0464/1021] Bump and update changelog --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39b4b3148..aadb37419 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.3.11 - 2014-09-17 + +- [fix] Restore install missing dependencies on update ([1519](https://github.com/bower/bower/pull/1519)) + ## 1.3.10 - 2014-09-13 - [fix] Back down concurrency from 50 to 5 ([#1483](https://github.com/bower/bower/pull/1483)) diff --git a/package.json b/package.json index 8d1453b4a..71f050148 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.3.10", + "version": "1.3.11", "description": "The browser package manager", "author": "Twitter", "licenses": [ From e590b44c77ead15ba60f71a03c5688fbabe53a2c Mon Sep 17 00:00:00 2001 From: Rodolphe Gohard Date: Fri, 19 Sep 2014 12:03:20 +0200 Subject: [PATCH 0465/1021] Fix 0.x dependencies to prevent breaking API updates Semver states > Major version zero (0.y.z) is for initial development. > Anything may change at any time. The public API should > not be considered stable. We already had a case where a tmp package update (0.0.24) broke bower install. This can happen again with 0.x dependencies that can introduce breaking API changes anytime. --- package.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 71f050148..e13102fe4 100644 --- a/package.json +++ b/package.json @@ -23,39 +23,39 @@ "bower-json": "~0.4.0", "bower-logger": "~0.2.2", "bower-registry-client": "~0.2.0", - "cardinal": "~0.4.0", - "chalk": "~0.5.0", - "chmodr": "~0.1.0", + "cardinal": "0.4.0", + "chalk": "0.5.0", + "chmodr": "0.1.0", "decompress-zip": "0.0.8", "fstream": "~1.0.2", "fstream-ignore": "~1.0.1", "glob": "~4.0.2", "graceful-fs": "~3.0.1", "handlebars": "~2.0.0", - "inquirer": "~0.7.1", - "insight": "~0.4.3", + "inquirer": "0.7.1", + "insight": "0.4.3", "is-root": "~1.0.0", "junk": "~1.0.0", "lockfile": "~1.0.0", "lru-cache": "~2.5.0", - "mkdirp": "~0.5.0", - "mout": "~0.10.0", + "mkdirp": "0.5.0", + "mout": "0.10.0", "nopt": "~3.0.0", "opn": "~1.0.0", - "osenv": "~0.1.0", + "osenv": "0.1.0", "p-throttler": "0.1.0", - "promptly": "~0.2.0", + "promptly": "0.2.0", "q": "~1.0.1", "request": "~2.42.0", - "request-progress": "~0.3.0", - "retry": "~0.6.0", + "request-progress": "0.3.0", + "retry": "0.6.0", "rimraf": "~2.2.0", "semver": "~2.3.0", "shell-quote": "~1.4.1", "stringify-object": "~1.0.0", - "tar-fs": "~0.5.0", + "tar-fs": "0.5.0", "tmp": "0.0.23", - "update-notifier": "~0.2.0", + "update-notifier": "0.2.0", "which": "~1.0.5" }, "devDependencies": { From eec9a3cb8fc27a567cc6aab79f6773c7d00a4dcc Mon Sep 17 00:00:00 2001 From: zhiyelee Date: Mon, 22 Sep 2014 11:23:31 +0800 Subject: [PATCH 0466/1021] add linebreak --- templates/std/lookup.std | 1 + templates/std/search-results.std | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/templates/std/lookup.std b/templates/std/lookup.std index 3bab82492..4545c0adb 100644 --- a/templates/std/lookup.std +++ b/templates/std/lookup.std @@ -5,3 +5,4 @@ Package not found. {{/if}} {{/condense}} + diff --git a/templates/std/search-results.std b/templates/std/search-results.std index c73d3e729..bb25acdca 100644 --- a/templates/std/search-results.std +++ b/templates/std/search-results.std @@ -5,5 +5,6 @@ {{#cyan}}{{{name}}}{{/cyan}} {{{url}}} {{/.}} {{/condense}} + {{else}}No results. -{{/if}} \ No newline at end of file +{{/if}} From c620004168fe7cb6bdab8d696a73cd9ac9c908d3 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 23 Sep 2014 16:24:56 +0200 Subject: [PATCH 0467/1021] Update tar-fs version, fixes #1537 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e13102fe4..9034621b9 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "semver": "~2.3.0", "shell-quote": "~1.4.1", "stringify-object": "~1.0.0", - "tar-fs": "0.5.0", + "tar-fs": "0.5.2", "tmp": "0.0.23", "update-notifier": "0.2.0", "which": "~1.0.5" From 179b8a28b41bda716ae3f2d5323d9b21b49043ed Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 23 Sep 2014 16:43:22 +0200 Subject: [PATCH 0468/1021] Use local appdata for cache, fixes bower/bower#1536 --- packages/bower-config/lib/util/paths.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/paths.js b/packages/bower-config/lib/util/paths.js index 566ba7261..d1eddf080 100644 --- a/packages/bower-config/lib/util/paths.js +++ b/packages/bower-config/lib/util/paths.js @@ -24,7 +24,7 @@ var base; // Fallbacks for windows if (process.platform === 'win32') { - base = path.resolve(process.env.APPDATA || home || tmp); + base = path.resolve(process.env.LOCALAPPDATA || home || tmp); base = path.join(base, 'bower'); paths.config = paths.config || path.join(base, 'config'); From 3df6144b77e1ae7cbf74699082d1fbc2e0fc28fc Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 23 Sep 2014 20:12:19 +0200 Subject: [PATCH 0469/1021] Downgrade mout to 0.9.0, closes #1525 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9034621b9..fca2e8ae1 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "lockfile": "~1.0.0", "lru-cache": "~2.5.0", "mkdirp": "0.5.0", - "mout": "0.10.0", + "mout": "~0.9.0", "nopt": "~3.0.0", "opn": "~1.0.0", "osenv": "0.1.0", From 46560219027ba482b665083260425fd5b6d6727a Mon Sep 17 00:00:00 2001 From: Ray Shan Date: Thu, 18 Sep 2014 00:58:55 -0700 Subject: [PATCH 0470/1021] fix broken analytics tracking introduced in #1507 --- lib/util/analytics.js | 71 ++++++++++++++++++-------- test/util/analytics.js | 111 ++++++++++++++++++++++++----------------- 2 files changed, 114 insertions(+), 68 deletions(-) diff --git a/lib/util/analytics.js b/lib/util/analytics.js index 1262ccc10..d25f103e1 100644 --- a/lib/util/analytics.js +++ b/lib/util/analytics.js @@ -5,8 +5,20 @@ var analytics = module.exports; var insight; +var enableAnalytics = false; + // Insight takes long to load, and often causes problems // in non-interactive environment, so we load it lazily +// +// Insight is used in two cases: +// +// 1. Read insight configuration (whether track user actions) +// 2. Track user actions (Tracker.track method) +// +// We don't want to instantiate Insight in non-interactive mode +// because it takes time to read config and configstore has concurrency issues: +// +// https://github.com/yeoman/configstore/issues/20 function ensureInsight () { if (!insight) { var Insight = require('insight'); @@ -21,50 +33,65 @@ function ensureInsight () { // Initializes the application-wide insight singleton and asks for the // permission on the CLI during the first run. +// +// This method is called only from bin/bower. Programmatic API skips it. analytics.setup = function setup (config) { var deferred = Q.defer(); - // if `analytics` hasn't been explicitly set - if (config.analytics == null) { + // No need for asking if analytics is set in bower config + if (config.analytics === undefined) { ensureInsight(); - // if there is a stored value - if (insight.optOut !== undefined) { - // set analytics to the stored value - config.analytics = !insight.optOut; - deferred.resolve(); - } else { - if (config.interactive) { + // For non-interactive call from bin/bower we disable analytics + if (config.interactive) { + if (insight.optOut !== undefined) { + deferred.resolve(!insight.optOut); + } else { insight.askPermission(null, function(err, optIn) { // optIn callback param was exactly opposite before 0.4.3 // so we force at least insight@0.4.3 in package.json - config.analytics = optIn; - deferred.resolve(); + deferred.resolve(optIn); }); - } else { - // no specified value, no stored value, and can't prompt for one - // so set analytics to true - config.analytics = true; - deferred.resolve(); } + } else { + // no specified value, no stored value, and can't prompt for one + // most likely CI environment; defaults to false to reduce data noise + deferred.resolve(false); } } else { // use the specified value - deferred.resolve(); + deferred.resolve(config.analytics); } - return deferred.promise; + return deferred.promise.then(function (enabled) { + enableAnalytics = enabled; + + return enabled; + }); }; var Tracker = analytics.Tracker = function Tracker(config) { - if (!config.analytics) { - this.track = function noop() {}; + function analyticsEnabled () { + // Allow for overriding analytics default + if (config && config.analytics !== undefined) { + return config.analytics; + } + + // TODO: let bower pass this variable from bin/bower instead closure + return enableAnalytics; + } + + if (analyticsEnabled()) { + ensureInsight(); + } else { + this.track = function noop () {}; + this.trackDecomposedEndpoints = function noop () {}; + this.trackPackages = function noop () {}; + this.trackNames = function noop () {}; } }; Tracker.prototype.track = function track() { - ensureInsight(); - insight.track.apply(insight, arguments); }; diff --git a/test/util/analytics.js b/test/util/analytics.js index 19725a8eb..d95cd170e 100644 --- a/test/util/analytics.js +++ b/test/util/analytics.js @@ -12,65 +12,73 @@ describe('analytics', function () { callback(undefined, promptResponse); } }); - }, + } }); }; describe('#setup', function () { it('leaves analytics enabled if provided', function () { - var config = { analytics: true }; - - return mockAnalytics().setup(config).then(function () { - expect(config.analytics).to.be(true); - }); + return mockAnalytics() + .setup({ analytics: true }) + .then(function (enabled) { + expect(enabled).to.be(true); + }); }); it('leaves analytics disabled if provided', function () { - var config = { analytics: false }; - - return mockAnalytics().setup(config).then(function () { - expect(config.analytics).to.be(false); - }); + return mockAnalytics() + .setup({ analytics: false }) + .then(function (enabled) { + expect(enabled).to.be(false); + }); }); - it('defaults to false if insight.optOut is true', function () { - var config = { }; - - return mockAnalytics({ optOut: true }).setup(config).then(function () { - expect(config.analytics).to.be(false); - }); + it('disables analytics for non-interactive mode', function () { + return mockAnalytics() + .setup({ interactive: false }) + .then(function (enabled) { + expect(enabled).to.be(false); + }); }); - it('defaults to true if insight.optOut is false', function () { - var config = { }; - - return mockAnalytics({ optOut: false }).setup(config).then(function () { - expect(config.analytics).to.be(true); - }); + it('disables if insight.optOut is true and interactive', function () { + return mockAnalytics({ optOut: true }) + .setup({ interactive: true }) + .then(function (enabled) { + expect(enabled).to.be(false); + }); }); - it('defaults to true if insight.optOut is undefined and noninteractive', function () { - var config = { }; - - return mockAnalytics({ optOut: undefined }).setup(config).then(function () { - expect(config.analytics).to.be(true); - }); + it('enables if insight.optOut is false and interactive', function () { + return mockAnalytics({ optOut: false }) + .setup({ interactive: true }) + .then(function (enabled) { + expect(enabled).to.be(true); + }); }); - it('defautls to true if interactive insights return true from prompt', function () { - var config = { interactive: true }; - - return mockAnalytics({ optOut: undefined }, true).setup(config).then(function () { - expect(config.analytics).to.be(true); - }); + it('disables if insight.optOut is false and non-interactive', function () { + return mockAnalytics({ optOut: false }) + .setup({ interactive: false }) + .then(function (enabled) { + expect(enabled).to.be(false); + }); }); - it('defautls to false if interactive insights return false from prompt', function () { - var config = { interactive: true }; + it('enables if interactive insights return true from prompt', function () { + return mockAnalytics({ optOut: undefined }, true) + .setup({ interactive: true }) + .then(function (enabled) { + expect(enabled).to.be(true); + }); + }); - return mockAnalytics({ optOut: undefined }, false).setup(config).then(function () { - expect(config.analytics).to.be(false); - }); + it('disables if interactive insights return false from prompt', function () { + return mockAnalytics({ optOut: undefined }, false) + .setup({ interactive: true }) + .then(function (enabled) { + expect(enabled).to.be(false); + }); }); }); @@ -83,9 +91,7 @@ describe('analytics', function () { } }); - new analytics.Tracker({ - analytics: true - }).track('foo'); + new analytics.Tracker({ analytics: true }).track('foo'); }); it('does not track if analytics = false', function () { @@ -96,10 +102,23 @@ describe('analytics', function () { }); expect(function () { - new analytics.Tracker({ - analytics: false - }).track('foo'); + new analytics.Tracker({ analytics: false }).track('foo'); }).to.not.throwError(); }); + + it('tracks if analytics = undefined and setup returns true', function(next) { + var analytics = mockAnalytics({ + track: function (arg) { + expect(arg).to.be('foo'); + next(); + } + }); + + analytics + .setup({ analytics: true }) + .then(function () { + new analytics.Tracker({}).track('foo'); + }); + }); }); }); From c99482f59d90e73caf471571b6b609a745322333 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 28 Sep 2014 15:58:59 +0200 Subject: [PATCH 0471/1021] [doc] Explain why env in test/helpers.js is needed --- test/helpers.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/helpers.js b/test/helpers.js index 28829f8fe..9136560ac 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -10,6 +10,7 @@ var os = require('os'); var cmd = require('../lib/util/cmd'); var config = require('../lib/config'); +// Those are needed for Travis or not configured git environment var env = { 'GIT_AUTHOR_DATE': 'Sun Apr 7 22:13:13 2013 +0000', 'GIT_AUTHOR_NAME': 'André Cruz', From b26c072f0db054a1902ec4d2e3726dbf8a1c799a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 28 Sep 2014 17:37:40 +0200 Subject: [PATCH 0472/1021] Bump version to 1.3.12 and update changelog --- CHANGELOG.md | 9 +++++++++ package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aadb37419..4ee1e359b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 1.3.12 - 2014-09-28 + +- [stability] Fix versions for unstable dependencies ([#1532](https://github.com/bower/bower/pull/1532)) +- [fix] Update tar-fs to support old tar format ([#1537](https://github.com/bower/bower/issues/1537)) +- [fix] Make analytics work again ([#1529](https://github.com/bower/bower/pull/1529)) +- [fix] Always disable analytics for non-interactive mode ([#1529](https://github.com/bower/bower/pull/1529)) +- [fix] Bower init can create private packages again ([#1522](https://github.com/bower/bower/issues/1522)) +- [fix] Show again missing newline for bower search output ([#1538](https://github.com/bower/bower/issues/1538)) + ## 1.3.11 - 2014-09-17 - [fix] Restore install missing dependencies on update ([1519](https://github.com/bower/bower/pull/1519)) diff --git a/package.json b/package.json index fca2e8ae1..af56ac9b5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.3.11", + "version": "1.3.12", "description": "The browser package manager", "author": "Twitter", "licenses": [ From c00cadb37ada437cfa0c428fe2283bc0374a81df Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 28 Sep 2014 18:21:24 +0200 Subject: [PATCH 0473/1021] [fix] Ensure extracted files are readable, update tar-fs --- lib/util/extract.js | 8 ++++++-- package.json | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/util/extract.js b/lib/util/extract.js index 580c5662c..e8a4011b0 100644 --- a/lib/util/extract.js +++ b/lib/util/extract.js @@ -52,7 +52,9 @@ function extractTar(archive, dst) { fs.createReadStream(archive) .on('error', deferred.reject) .pipe(tar.extract(dst, { - ignore: isSymlink // Filter symlink files + ignore: isSymlink, // Filter symlink files + dmode: 0555, // Ensure dirs are readable + fmode: 0444 // Ensure files are readable })) .on('error', deferred.reject) .on('finish', deferred.resolve.bind(deferred, dst)); @@ -68,7 +70,9 @@ function extractTarGz(archive, dst) { .pipe(zlib.createGunzip()) .on('error', deferred.reject) .pipe(tar.extract(dst, { - ignore: isSymlink // Filter symlink files + ignore: isSymlink, // Filter symlink files + dmode: 0555, // Ensure dirs are readable + fmode: 0444 // Ensure files are readable })) .on('error', deferred.reject) .on('finish', deferred.resolve.bind(deferred, dst)); diff --git a/package.json b/package.json index af56ac9b5..03f6042a8 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "semver": "~2.3.0", "shell-quote": "~1.4.1", "stringify-object": "~1.0.0", - "tar-fs": "0.5.2", + "tar-fs": "~1.0.0", "tmp": "0.0.23", "update-notifier": "0.2.0", "which": "~1.0.5" From 836bcd09ec33b9b15af301afc6139b21f129395e Mon Sep 17 00:00:00 2001 From: ISNIT0 Date: Mon, 6 Oct 2014 12:58:04 +0100 Subject: [PATCH 0474/1021] Added return character https://github.com/bower/bower/issues/1554 --- templates/std/conflict.std | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/std/conflict.std b/templates/std/conflict.std index 2a16dd3f7..0f041e23a 100644 --- a/templates/std/conflict.std +++ b/templates/std/conflict.std @@ -5,5 +5,6 @@ {{/each}} {{/condense}} {{#unless saveResolutions}} + Prefix the choice with ! to persist it to bower.json {{/unless}} From de6f341f41fea3d4202843e357aa99a83c0fd8ee Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 16 Oct 2014 11:52:46 +0200 Subject: [PATCH 0475/1021] bump to latest `chalk` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 03f6042a8..7a3fa5f2e 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "bower-logger": "~0.2.2", "bower-registry-client": "~0.2.0", "cardinal": "0.4.0", - "chalk": "0.5.0", + "chalk": "0.5.1", "chmodr": "0.1.0", "decompress-zip": "0.0.8", "fstream": "~1.0.2", From 8b0d55a72950b42e748b4152231d7c028894a19c Mon Sep 17 00:00:00 2001 From: Daniel Darabos Date: Mon, 27 Oct 2014 14:00:13 +0100 Subject: [PATCH 0476/1021] Add extra newline at the end of help-cache.std Without this newline, the template is rendered without a newline at the end. So when you run `grunt help cache`, the output does not have a newline at the end and the shell prompt will be printed at the end of the last line. --- templates/std/help-cache.std | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/std/help-cache.std b/templates/std/help-cache.std index 369968f6c..18e2803e9 100644 --- a/templates/std/help-cache.std +++ b/templates/std/help-cache.std @@ -14,3 +14,4 @@ Commands: {{#rpad length="23"}}{{@key}}{{/rpad}} {{.}} {{/each}} {{/condense}} + From f242e60c1ab4e8afb5cb469f2234ea5d95e8313c Mon Sep 17 00:00:00 2001 From: Tej Chajed Date: Sat, 1 Nov 2014 09:08:58 -0400 Subject: [PATCH 0477/1021] Change duplicate package status code to 403 Registry no longer sends 406 so clients would previously just see "Unknown error: 403 if they tried to register a duplicate package. --- packages/bower-registry-client/lib/register.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/lib/register.js b/packages/bower-registry-client/lib/register.js index fb431894b..d2b1baf83 100644 --- a/packages/bower-registry-client/lib/register.js +++ b/packages/bower-registry-client/lib/register.js @@ -35,7 +35,7 @@ function register(name, url, callback) { } // Duplicate - if (response.statusCode === 406) { + if (response.statusCode === 403) { return callback(createError('Duplicate package', 'EDUPLICATE')); } From 962a565d30b47a5b1beb500749b571412f1ca1dd Mon Sep 17 00:00:00 2001 From: Veres Lajos Date: Sun, 2 Nov 2014 22:40:58 +0000 Subject: [PATCH 0478/1021] typo fixes --- lib/commands/help.js | 2 +- lib/core/Manager.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/commands/help.js b/lib/commands/help.js index 8edd38400..5fac8a986 100644 --- a/lib/commands/help.js +++ b/lib/commands/help.js @@ -18,7 +18,7 @@ function help(logger, name) { }) .then(function (exists) { if (!exists) { - throw createError('Unknown command: ' + name, 'EUNKOWNCMD', { + throw createError('Unknown command: ' + name, 'EUNKNOWNCMD', { command: name }); } diff --git a/lib/core/Manager.js b/lib/core/Manager.js index d519b4f4b..3de930a30 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -827,7 +827,7 @@ Manager.prototype._storeResolution = function (pick) { * * It is used in two situations: * * checks if resolved component matches dependency constraint - * * checks if not resolved component matches alredy fetched component + * * checks if not resolved component matches already fetched component * * If candidate matches already resolved component, it won't be downloaded. * From a464f5a88e14b2c4c1fd97e79396882b2a192e0b Mon Sep 17 00:00:00 2001 From: joneshf Date: Sat, 29 Nov 2014 12:22:58 -0800 Subject: [PATCH 0479/1021] Remove erroneous colon. --- lib/core/Manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index d519b4f4b..d8c72a959 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -775,7 +775,7 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { choices = picks.map(function (pick, index) { return index + 1; }); return Q.nfcall(this._logger.prompt.bind(this._logger), { type: 'input', - message: 'Answer:', + message: 'Answer', validate: function (choice) { choice = Number(mout.string.trim(choice.trim(), '!')); From 92ff0fe6247c6671d955c4c784b8b27447e4333d Mon Sep 17 00:00:00 2001 From: "Merrifield, Jay" Date: Thu, 4 Dec 2014 23:24:45 -0500 Subject: [PATCH 0480/1021] Added unit tests of bower.commands.list() --- test/commands/index.js | 1 + test/commands/list.js | 246 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+) create mode 100644 test/commands/list.js diff --git a/test/commands/index.js b/test/commands/index.js index c02a4d894..7815de70d 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -3,4 +3,5 @@ describe('integration tests', function () { require('./install'); require('./uninstall'); require('./update'); + require('./list'); }); diff --git a/test/commands/list.js b/test/commands/list.js new file mode 100644 index 000000000..a9f89a6f9 --- /dev/null +++ b/test/commands/list.js @@ -0,0 +1,246 @@ +var expect = require('expect.js'); +var object = require('mout').object; + +var helpers = require('../helpers'); +var commands = helpers.require('lib/index').commands; + +describe('bower list', function () { + + var tempDir = new helpers.TempDir(); + + var gitPackage = new helpers.TempDir(); + + var installLogger = function(packages, options, config) { + config = object.merge(config || {}, { + cwd: tempDir.path + }); + + return commands.install(packages, options, config); + }; + + var install = function(options, config) { + var installer = installLogger(options, config); + + return helpers.expectEvent(installer, 'end'); + }; + + var listLogger = function(options, config) { + config = object.merge(config || {}, { + cwd: tempDir.path + }); + + return commands.list(options, config); + }; + + var list = function(options, config) { + var logger = listLogger(options, config); + + return helpers.expectEvent(logger, 'end'); + }; + + it('lists no packages when nothing installed', function () { + tempDir.prepare(); + + return list().then(function(args) { + var results = args[0]; + expect(args.length).to.equal(1); + expect(results).to.be.an(Object); + expect(results.canonicalDir).to.equal(tempDir.path); + expect(results.pkgMeta.dependencies).to.eql({}); + expect(results.pkgMeta.devDependencies).to.eql({}); + expect(results.dependencies).to.eql({}); + expect(results.nrDependants).to.eql(0); + expect(results.versions).to.eql([]); + }); + }); + + it('lists 1 dependency when 1 local package installed', function () { + + var package = new helpers.TempDir({ + 'bower.json': { + name: 'package', + main: 'test.txt' + } + }).prepare(); + package.prepare(); + + return install([package.path]).then(function() { + return list().then(function(args) { + var results = args[0]; + expect(args.length).to.equal(1); + expect(results).to.be.an(Object); + expect(results.canonicalDir).to.equal(tempDir.path); + expect(results.pkgMeta.dependencies).to.eql({ + package: package.path + '#*' + }); + expect(results.pkgMeta.devDependencies).to.eql({}); + expect(results.dependencies.package).to.be.an(Object); + expect(results.dependencies.package.pkgMeta).to.be.an(Object); + expect(results.dependencies.package.pkgMeta.main).to.equal('test.txt'); + expect(results.dependencies.package.canonicalDir).to.equal(tempDir.path + '/bower_components/package'); + expect(results.dependencies.package.dependencies).to.eql({}); + expect(results.dependencies.package.nrDependants).to.equal(1); + expect(results.dependencies.package.versions).to.eql([]); + expect(results.nrDependants).to.equal(0); + expect(results.versions).to.eql([]); + }); + }); + }); + + it('lists 1 dependency with relative paths when 1 local package installed', function () { + + var package = new helpers.TempDir({ + 'bower.json': { + name: 'package', + main: 'test.txt' + } + }).prepare(); + package.prepare(); + + return install([package.path]).then(function() { + return list({relative: true}).then(function(args) { + var results = args[0]; + expect(args.length).to.equal(1); + expect(results).to.be.an(Object); + expect(results.canonicalDir).to.equal(tempDir.path); + expect(results.dependencies).to.be.an(Object); + expect(results.dependencies.package).to.be.an(Object); + expect(results.dependencies.package.pkgMeta).to.be.an(Object); + expect(results.dependencies.package.pkgMeta.main).to.equal('test.txt'); + expect(results.pkgMeta.dependencies).to.eql({ + package: package.path + '#*' + }); + expect(results.dependencies.package.canonicalDir).to.equal('bower_components/package'); + }); + }); + }); + + it('lists 1 dependency with 1 source relative source mapping when 1 local package installed', function () { + + var package = new helpers.TempDir({ + 'bower.json': { + name: 'package', + main: 'test.txt' + } + }).prepare(); + package.prepare(); + + return install([package.path]).then(function() { + return list({paths: true}).then(function(args) { + var results = args[0]; + expect(args.length).to.equal(1); + expect(results).to.be.an(Object); + expect(results.package).to.equal('bower_components/package/test.txt'); + }); + }); + }); + + it('lists 1 dependency with 2 source relative source mapping when 1 local package installed', function () { + + var package = new helpers.TempDir({ + 'bower.json': { + name: 'package', + main: ['test.txt', 'test2.txt'] + } + }).prepare(); + package.prepare(); + + return install([package.path]).then(function() { + return list({paths: true}).then(function(args) { + var results = args[0]; + expect(args.length).to.equal(1); + expect(results).to.be.an(Object); + expect(results.package).to.be.an(Object); + expect(results.package).to.eql(['bower_components/package/test.txt', 'bower_components/package/test2.txt']); + }); + }); + }); + + it('lists 1 dependency when 1 git package installed', function () { + return gitPackage.prepareGit({ + '1.0.0': { + 'bower.json': { + name: 'package', + main: 'test.txt' + }, + 'version.txt': '1.0.0' + }, + '1.0.1': { + 'bower.json': { + name: 'package', + main: 'test2.txt' + }, + 'version.txt': '1.0.1' + } + }).then(function() { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.0' + } + } + }); + return install().then(function() { + return list().then(function(args) { + var results = args[0]; + expect(args.length).to.equal(1); + expect(results).to.be.an(Object); + expect(results.canonicalDir).to.equal(tempDir.path); + expect(results.pkgMeta.dependencies).to.eql({ + package: gitPackage.path + '#1.0.0' + }); + expect(results.pkgMeta.devDependencies).to.eql({}); + expect(results.dependencies.package).to.be.an(Object); + expect(results.dependencies.package.pkgMeta).to.be.an(Object); + expect(results.dependencies.package.pkgMeta.main).to.equal('test.txt'); + expect(results.dependencies.package.canonicalDir).to.equal(tempDir.path + '/bower_components/package'); + expect(results.dependencies.package.dependencies).to.eql({}); + expect(results.dependencies.package.nrDependants).to.equal(1); + expect(results.dependencies.package.versions).to.eql(['1.0.1', '1.0.0']); + expect(results.nrDependants).to.equal(0); + expect(results.versions).to.eql([]); + }); + }); + }); + }); + + it('lists 1 dependency with relative paths when 1 git package installed', function () { + return gitPackage.prepareGit({ + '1.0.0': { + 'bower.json': { + name: 'package', + main: 'test.txt' + }, + 'version.txt': '1.0.0' + }, + '1.0.1': { + 'bower.json': { + name: 'package', + main: 'test2.txt' + }, + 'version.txt': '1.0.1' + } + }).then(function() { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.0' + } + } + }); + return install().then(function() { + return list({relative: true}).then(function(args) { + var results = args[0]; + expect(args.length).to.equal(1); + expect(results.canonicalDir).to.equal(tempDir.path); + expect(results.pkgMeta.dependencies).to.eql({ + package: gitPackage.path + '#1.0.0' + }); + expect(results.dependencies.package.canonicalDir).to.equal('bower_components/package'); + }); + }); + }); + }); +}); From a7baa58c22ad871bb4ca5b6aa1007e089ee289e4 Mon Sep 17 00:00:00 2001 From: Ricardo Polo Date: Wed, 10 Dec 2014 21:09:27 +0700 Subject: [PATCH 0481/1021] Close #1620 PR: Showing --no-color in help. Fixes #78 --- templates/json/help.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/templates/json/help.json b/templates/json/help.json index 52e1265b5..5d97bf2de 100644 --- a/templates/json/help.json +++ b/templates/json/help.json @@ -62,6 +62,10 @@ { "flag": "--version", "description": "Output Bower version" + }, + { + "flag": "--no-color", + "description": "Disable colors" } ] } From 514eb8f0e38fefeaee6a795a28c277db67adc642 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 22 Dec 2014 22:56:27 +0700 Subject: [PATCH 0482/1021] better homedir detection --- bin/bower | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/bower b/bin/bower index 6a98d94db..53e082dda 100755 --- a/bin/bower +++ b/bin/bower @@ -6,7 +6,7 @@ process.bin = process.title = 'bower'; var Q = require('q'); var mout = require('mout'); var Logger = require('bower-logger'); -var osenv = require('osenv'); +var userHome = require('user-home'); var bower = require('../lib'); var pkg = require('../package.json'); var cli = require('../lib/util/cli'); @@ -125,8 +125,8 @@ analytics.setup(bower.config).then(function () { }); // Warn if HOME is not SET - if (!osenv.home()) { - logger.warn('no-home', 'HOME not set, user configuration will not be loaded'); + if (!userHome) { + logger.warn('no-home', 'HOME environment variable not set. User config will not be loaded.'); } if (bower.config.interactive) { diff --git a/package.json b/package.json index 7a3fa5f2e..69b1e3793 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,6 @@ "mout": "~0.9.0", "nopt": "~3.0.0", "opn": "~1.0.0", - "osenv": "0.1.0", "p-throttler": "0.1.0", "promptly": "0.2.0", "q": "~1.0.1", @@ -56,6 +55,7 @@ "tar-fs": "~1.0.0", "tmp": "0.0.23", "update-notifier": "0.2.0", + "user-home": "^1.1.0", "which": "~1.0.5" }, "devDependencies": { From 45bab9fe7106925fb45a147504b0e2e9a24f090a Mon Sep 17 00:00:00 2001 From: Daphne Maddox Date: Sat, 3 Jan 2015 11:08:33 -0800 Subject: [PATCH 0483/1021] update package.json dependencies Update dependencies in package.json to (mostly) latest available versions. Updating these dependencies removes warnings when bower is installed as a devDependency in other packages and keep the code fresh. Methodology: - `npm install` - `npm test` (all tests pass) - `npm-check-updates -u` - `npm test` (find errors, suspect semver, back off to `~2.3.0` in package.json) - `rm -rf node_modules` (and .gitignored files) - `npm install` - `npm test` (all pass, deem updated version compatible) - revert to package.json from `master` - `npm install` (install the old dependencies) - switch back to updated package.json - `npm install` (upgrade dependencies in place) - `npm test` (all tests still pass, deem upgrades safe) As to the `semver` dependency, it seems that updating to 4.x requires handling breaking changes, which is TODO. Closes #1622 --- package.json | 64 ++++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 69b1e3793..e591a0d76 100644 --- a/package.json +++ b/package.json @@ -16,63 +16,63 @@ "node": ">=0.10.0" }, "dependencies": { - "abbrev": "~1.0.4", - "archy": "0.0.2", + "abbrev": "~1.0.5", + "archy": "1.0.0", "bower-config": "~0.5.2", "bower-endpoint-parser": "~0.2.2", "bower-json": "~0.4.0", "bower-logger": "~0.2.2", - "bower-registry-client": "~0.2.0", - "cardinal": "0.4.0", + "bower-registry-client": "~0.2.1", + "cardinal": "0.4.4", "chalk": "0.5.1", "chmodr": "0.1.0", "decompress-zip": "0.0.8", - "fstream": "~1.0.2", - "fstream-ignore": "~1.0.1", - "glob": "~4.0.2", - "graceful-fs": "~3.0.1", + "fstream": "~1.0.3", + "fstream-ignore": "~1.0.2", + "glob": "~4.3.2", + "graceful-fs": "~3.0.5", "handlebars": "~2.0.0", - "inquirer": "0.7.1", + "inquirer": "0.8.0", "insight": "0.4.3", "is-root": "~1.0.0", "junk": "~1.0.0", "lockfile": "~1.0.0", "lru-cache": "~2.5.0", "mkdirp": "0.5.0", - "mout": "~0.9.0", - "nopt": "~3.0.0", - "opn": "~1.0.0", - "p-throttler": "0.1.0", + "mout": "~0.11.0", + "nopt": "~3.0.1", + "opn": "~1.0.1", + "p-throttler": "0.1.1", "promptly": "0.2.0", - "q": "~1.0.1", - "request": "~2.42.0", - "request-progress": "0.3.0", - "retry": "0.6.0", - "rimraf": "~2.2.0", + "q": "~1.1.2", + "request": "~2.51.0", + "request-progress": "0.3.1", + "retry": "0.6.1", + "rimraf": "~2.2.8", "semver": "~2.3.0", - "shell-quote": "~1.4.1", + "shell-quote": "~1.4.2", "stringify-object": "~1.0.0", - "tar-fs": "~1.0.0", - "tmp": "0.0.23", - "update-notifier": "0.2.0", + "tar-fs": "~1.4.1", + "tmp": "0.0.24", + "update-notifier": "0.2.2", "user-home": "^1.1.0", - "which": "~1.0.5" + "which": "~1.0.8" }, "devDependencies": { - "coveralls": "~2.11.0", + "coveralls": "~2.11.2", "expect.js": "~0.3.1", - "grunt": "~0.4.4", + "grunt": "~0.4.5", "grunt-cli": "^0.1.13", "grunt-contrib-jshint": "~0.10.0", "grunt-contrib-watch": "~0.6.1", - "grunt-exec": "~0.4.2", + "grunt-exec": "~0.4.6", "grunt-simple-mocha": "~0.4.0", - "istanbul": "~0.3.2", - "load-grunt-tasks": "~0.6.0", - "mocha": "~1.21.4", - "nock": "~0.46.0", - "node-uuid": "~1.4.1", - "proxyquire": "~1.0.1" + "istanbul": "~0.3.5", + "load-grunt-tasks": "~2.0.0", + "mocha": "~2.1.0", + "nock": "~0.53.0", + "node-uuid": "~1.4.2", + "proxyquire": "~1.3.0" }, "scripts": { "test": "grunt test" From b5e557ffb090cb411c88375350331fa723c7412a Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 5 Jan 2015 00:00:05 +0700 Subject: [PATCH 0484/1021] bump `decompress-zip` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e591a0d76..23043fab8 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "cardinal": "0.4.4", "chalk": "0.5.1", "chmodr": "0.1.0", - "decompress-zip": "0.0.8", + "decompress-zip": "^0.1.0", "fstream": "~1.0.3", "fstream-ignore": "~1.0.2", "glob": "~4.3.2", From 06f4d0c117835c8af9c05d644598b4528a4e14dc Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 5 Jan 2015 00:01:29 +0700 Subject: [PATCH 0485/1021] package.json - use caret version specifier --- package.json | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 23043fab8..599d2d0f0 100644 --- a/package.json +++ b/package.json @@ -16,47 +16,47 @@ "node": ">=0.10.0" }, "dependencies": { - "abbrev": "~1.0.5", + "abbrev": "^1.0.5", "archy": "1.0.0", - "bower-config": "~0.5.2", - "bower-endpoint-parser": "~0.2.2", - "bower-json": "~0.4.0", - "bower-logger": "~0.2.2", - "bower-registry-client": "~0.2.1", + "bower-config": "^0.5.2", + "bower-endpoint-parser": "^0.2.2", + "bower-json": "^0.4.0", + "bower-logger": "^0.2.2", + "bower-registry-client": "^0.2.1", "cardinal": "0.4.4", "chalk": "0.5.1", "chmodr": "0.1.0", "decompress-zip": "^0.1.0", - "fstream": "~1.0.3", - "fstream-ignore": "~1.0.2", - "glob": "~4.3.2", - "graceful-fs": "~3.0.5", - "handlebars": "~2.0.0", + "fstream": "^1.0.3", + "fstream-ignore": "^1.0.2", + "glob": "^4.3.2", + "graceful-fs": "^3.0.5", + "handlebars": "^2.0.0", "inquirer": "0.8.0", "insight": "0.4.3", - "is-root": "~1.0.0", - "junk": "~1.0.0", - "lockfile": "~1.0.0", - "lru-cache": "~2.5.0", + "is-root": "^1.0.0", + "junk": "^1.0.0", + "lockfile": "^1.0.0", + "lru-cache": "^2.5.0", "mkdirp": "0.5.0", - "mout": "~0.11.0", - "nopt": "~3.0.1", - "opn": "~1.0.1", + "mout": "^0.11.0", + "nopt": "^3.0.1", + "opn": "^1.0.1", "p-throttler": "0.1.1", "promptly": "0.2.0", - "q": "~1.1.2", - "request": "~2.51.0", + "q": "^1.1.2", + "request": "^2.51.0", "request-progress": "0.3.1", "retry": "0.6.1", - "rimraf": "~2.2.8", - "semver": "~2.3.0", - "shell-quote": "~1.4.2", - "stringify-object": "~1.0.0", - "tar-fs": "~1.4.1", + "rimraf": "^2.2.8", + "semver": "^2.3.0", + "shell-quote": "^1.4.2", + "stringify-object": "^1.0.0", + "tar-fs": "^1.4.1", "tmp": "0.0.24", "update-notifier": "0.2.2", "user-home": "^1.1.0", - "which": "~1.0.8" + "which": "^1.0.8" }, "devDependencies": { "coveralls": "~2.11.2", From 6a629e963c53d52e058fc1510efe4cc245c05099 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 5 Jan 2015 01:47:00 +0100 Subject: [PATCH 0486/1021] fix: Duplicate package has now 403 error code According to change in bower/registry#74ae4d34b68df239b8db876a4f871b100ef3c540 --- packages/bower-registry-client/lib/register.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/lib/register.js b/packages/bower-registry-client/lib/register.js index fb431894b..d2b1baf83 100644 --- a/packages/bower-registry-client/lib/register.js +++ b/packages/bower-registry-client/lib/register.js @@ -35,7 +35,7 @@ function register(name, url, callback) { } // Duplicate - if (response.statusCode === 406) { + if (response.statusCode === 403) { return callback(createError('Duplicate package', 'EDUPLICATE')); } From 703eae72eb219e9d6765d05835e4969f4fda8736 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 5 Jan 2015 01:50:06 +0100 Subject: [PATCH 0487/1021] Bump to 0.2.2 --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 94724221e..2b5cc0a17 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.2.1", + "version": "0.2.2", "description": "Provides easy interaction with the Bower registry.", "author": "Twitter", "licenses": [ From 2f2c4d67400cf3c29060879a27443fd0061da624 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 5 Jan 2015 03:31:28 +0100 Subject: [PATCH 0488/1021] Add tests for help command and fix it --- templates/json/help-cache/clean.json | 2 +- templates/json/help-cache/list.json | 2 +- test/commands/help.js | 34 ++++++++++++++++++++++++++++ test/helpers.js | 14 +++++++++++- 4 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 test/commands/help.js diff --git a/templates/json/help-cache/clean.json b/templates/json/help-cache/clean.json index daf5ee627..27407497d 100644 --- a/templates/json/help-cache/clean.json +++ b/templates/json/help-cache/clean.json @@ -1,5 +1,5 @@ { - "command": "cache list", + "command": "cache clean", "description": "Cleans cached packages.", "usage": [ "cache clean []", diff --git a/templates/json/help-cache/list.json b/templates/json/help-cache/list.json index 2abf375cf..9219a2f4f 100644 --- a/templates/json/help-cache/list.json +++ b/templates/json/help-cache/list.json @@ -1,5 +1,5 @@ { - "command": "cache clean", + "command": "cache list", "description": "Lists cached packages.", "usage": [ "cache list []", diff --git a/test/commands/help.js b/test/commands/help.js new file mode 100644 index 000000000..e36d61993 --- /dev/null +++ b/test/commands/help.js @@ -0,0 +1,34 @@ +var expect = require('expect.js'); +var helpers = require('../helpers'); + +describe('bower help', function () { + + var tempDir = new helpers.TempDir(); + + it('shows general help', function () { + tempDir.prepare(); + + return helpers.run('help').then(function(result) { + expect(result.usage[0]).to.be.a('string'); + expect(result.commands).to.be.a('object'); + expect(result.options).to.be.a('object'); + }); + }); + + var commands = [ + 'home', 'info', 'init', 'install', + 'link', 'list', 'lookup', 'prune', 'register', + 'search', 'update', 'uninstall', 'version', + 'cache list', 'cache clean' + ]; + + commands.forEach(function(command) { + it('shows help for ' + command + ' command', function() { + return helpers.run('help', [command]).then(function(result) { + expect(result.command).to.be(command); + expect(result.description).to.be.a('string'); + expect(result.usage[0]).to.be.a('string'); + }); + }); + }); +}); diff --git a/test/helpers.js b/test/helpers.js index 9136560ac..112897cd5 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -9,6 +9,7 @@ var glob = require('glob'); var os = require('os'); var cmd = require('../lib/util/cmd'); var config = require('../lib/config'); +var commands = require('../lib/index').commands; // Those are needed for Travis or not configured git environment var env = { @@ -135,7 +136,7 @@ exports.TempDir = (function() { return TempDir; })(); -exports.expectEvent = function (emitter, eventName) { +exports.expectEvent = function expectEvent(emitter, eventName) { var deferred = Q.defer(); emitter.once(eventName, function () { @@ -144,3 +145,14 @@ exports.expectEvent = function (emitter, eventName) { return deferred.promise; }; + +exports.run = function run(name, args) { + if (!commands[name]) { + throw new Error('No such command: ' + name); + } + + var installer = commands[name].apply(commands[name], args || []); + return exports.expectEvent(installer, 'end').then(function(results) { + return results[0]; + }); +}; From 6be84ab93edc5b572b8932a226c1ed948a32313c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 5 Jan 2015 03:40:34 +0100 Subject: [PATCH 0489/1021] Add test case for #1584 --- test/commands/help.js | 8 ++++++++ test/helpers.js | 12 +++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/test/commands/help.js b/test/commands/help.js index e36d61993..a95991a3d 100644 --- a/test/commands/help.js +++ b/test/commands/help.js @@ -31,4 +31,12 @@ describe('bower help', function () { }); }); }); + + it('displays error for non-existing command', function() { + return helpers.run('help', ['fuu']).fail(function(e) { + expect(e.message).to.be('Unknown command: fuu'); + expect(e.command).to.be('fuu'); + expect(e.code).to.be('EUNKNOWNCMD'); + }); + }); }); diff --git a/test/helpers.js b/test/helpers.js index 112897cd5..0ecbec844 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -139,8 +139,12 @@ exports.TempDir = (function() { exports.expectEvent = function expectEvent(emitter, eventName) { var deferred = Q.defer(); - emitter.once(eventName, function () { - deferred.resolve(arguments); + emitter.once(eventName, function (payload) { + deferred.resolve(payload); + }); + + emitter.once('error', function (reason) { + deferred.reject(reason); }); return deferred.promise; @@ -152,7 +156,5 @@ exports.run = function run(name, args) { } var installer = commands[name].apply(commands[name], args || []); - return exports.expectEvent(installer, 'end').then(function(results) { - return results[0]; - }); + return exports.expectEvent(installer, 'end'); }; From 11d89c426814c5423b60975424f23cdf9b1d329e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 5 Jan 2015 03:48:43 +0100 Subject: [PATCH 0490/1021] fix: Tests helper regression --- test/commands/help.js | 4 ++-- test/commands/index.js | 1 + test/helpers.js | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/test/commands/help.js b/test/commands/help.js index a95991a3d..f94f506ec 100644 --- a/test/commands/help.js +++ b/test/commands/help.js @@ -8,7 +8,7 @@ describe('bower help', function () { it('shows general help', function () { tempDir.prepare(); - return helpers.run('help').then(function(result) { + return helpers.run('help').spread(function(result) { expect(result.usage[0]).to.be.a('string'); expect(result.commands).to.be.a('object'); expect(result.options).to.be.a('object'); @@ -24,7 +24,7 @@ describe('bower help', function () { commands.forEach(function(command) { it('shows help for ' + command + ' command', function() { - return helpers.run('help', [command]).then(function(result) { + return helpers.run('help', [command]).spread(function(result) { expect(result.command).to.be(command); expect(result.description).to.be.a('string'); expect(result.usage[0]).to.be.a('string'); diff --git a/test/commands/index.js b/test/commands/index.js index 7815de70d..04c3c98c0 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -1,4 +1,5 @@ describe('integration tests', function () { + require('./help'); require('./init'); require('./install'); require('./uninstall'); diff --git a/test/helpers.js b/test/helpers.js index 0ecbec844..7a64dac95 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -139,8 +139,8 @@ exports.TempDir = (function() { exports.expectEvent = function expectEvent(emitter, eventName) { var deferred = Q.defer(); - emitter.once(eventName, function (payload) { - deferred.resolve(payload); + emitter.once(eventName, function () { + deferred.resolve(arguments); }); emitter.once('error', function (reason) { From b245a3d61180b41622abb9e0b85081dccbd3a58e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 5 Jan 2015 04:00:17 +0100 Subject: [PATCH 0491/1021] Remove unnecessary asserts from list test --- test/commands/list.js | 49 ++++++++++--------------------------------- 1 file changed, 11 insertions(+), 38 deletions(-) diff --git a/test/commands/list.js b/test/commands/list.js index a9f89a6f9..166dfb065 100644 --- a/test/commands/list.js +++ b/test/commands/list.js @@ -2,7 +2,6 @@ var expect = require('expect.js'); var object = require('mout').object; var helpers = require('../helpers'); -var commands = helpers.require('lib/index').commands; describe('bower list', function () { @@ -10,40 +9,26 @@ describe('bower list', function () { var gitPackage = new helpers.TempDir(); - var installLogger = function(packages, options, config) { + var install = function(packages, options, config) { config = object.merge(config || {}, { cwd: tempDir.path }); - return commands.install(packages, options, config); + return helpers.run('install', [packages, options, config]); }; - var install = function(options, config) { - var installer = installLogger(options, config); - - return helpers.expectEvent(installer, 'end'); - }; - - var listLogger = function(options, config) { + var list = function(options, config) { config = object.merge(config || {}, { cwd: tempDir.path }); - return commands.list(options, config); - }; - - var list = function(options, config) { - var logger = listLogger(options, config); - - return helpers.expectEvent(logger, 'end'); + return helpers.run('list', [options, config]); }; it('lists no packages when nothing installed', function () { tempDir.prepare(); - return list().then(function(args) { - var results = args[0]; - expect(args.length).to.equal(1); + return list().spread(function(results) { expect(results).to.be.an(Object); expect(results.canonicalDir).to.equal(tempDir.path); expect(results.pkgMeta.dependencies).to.eql({}); @@ -65,9 +50,7 @@ describe('bower list', function () { package.prepare(); return install([package.path]).then(function() { - return list().then(function(args) { - var results = args[0]; - expect(args.length).to.equal(1); + return list().spread(function(results) { expect(results).to.be.an(Object); expect(results.canonicalDir).to.equal(tempDir.path); expect(results.pkgMeta.dependencies).to.eql({ @@ -98,9 +81,7 @@ describe('bower list', function () { package.prepare(); return install([package.path]).then(function() { - return list({relative: true}).then(function(args) { - var results = args[0]; - expect(args.length).to.equal(1); + return list({relative: true}).spread(function(results) { expect(results).to.be.an(Object); expect(results.canonicalDir).to.equal(tempDir.path); expect(results.dependencies).to.be.an(Object); @@ -126,9 +107,7 @@ describe('bower list', function () { package.prepare(); return install([package.path]).then(function() { - return list({paths: true}).then(function(args) { - var results = args[0]; - expect(args.length).to.equal(1); + return list({paths: true}).spread(function(results) { expect(results).to.be.an(Object); expect(results.package).to.equal('bower_components/package/test.txt'); }); @@ -146,9 +125,7 @@ describe('bower list', function () { package.prepare(); return install([package.path]).then(function() { - return list({paths: true}).then(function(args) { - var results = args[0]; - expect(args.length).to.equal(1); + return list({paths: true}).spread(function(results) { expect(results).to.be.an(Object); expect(results.package).to.be.an(Object); expect(results.package).to.eql(['bower_components/package/test.txt', 'bower_components/package/test2.txt']); @@ -182,9 +159,7 @@ describe('bower list', function () { } }); return install().then(function() { - return list().then(function(args) { - var results = args[0]; - expect(args.length).to.equal(1); + return list().spread(function(results) { expect(results).to.be.an(Object); expect(results.canonicalDir).to.equal(tempDir.path); expect(results.pkgMeta.dependencies).to.eql({ @@ -231,9 +206,7 @@ describe('bower list', function () { } }); return install().then(function() { - return list({relative: true}).then(function(args) { - var results = args[0]; - expect(args.length).to.equal(1); + return list({relative: true}).spread(function(results) { expect(results.canonicalDir).to.equal(tempDir.path); expect(results.pkgMeta.dependencies).to.eql({ package: gitPackage.path + '#1.0.0' From c029e1005f5cdcf6ac0f2c87901e0f1f6c28d3eb Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 5 Jan 2015 05:19:54 +0100 Subject: [PATCH 0492/1021] Add tests for "bower home" command --- test/commands/help.js | 11 ++++------- test/commands/home.js | 25 ++++++++++++++++++++++++ test/commands/index.js | 3 ++- test/commands/list.js | 9 +++++++-- test/helpers.js | 43 +++++++++++++++++++++++++++++++++++------- 5 files changed, 74 insertions(+), 17 deletions(-) create mode 100644 test/commands/home.js diff --git a/test/commands/help.js b/test/commands/help.js index f94f506ec..163116626 100644 --- a/test/commands/help.js +++ b/test/commands/help.js @@ -1,14 +1,11 @@ var expect = require('expect.js'); var helpers = require('../helpers'); +var help = helpers.command('help'); describe('bower help', function () { - var tempDir = new helpers.TempDir(); - it('shows general help', function () { - tempDir.prepare(); - - return helpers.run('help').spread(function(result) { + return helpers.run(help).spread(function(result) { expect(result.usage[0]).to.be.a('string'); expect(result.commands).to.be.a('object'); expect(result.options).to.be.a('object'); @@ -24,7 +21,7 @@ describe('bower help', function () { commands.forEach(function(command) { it('shows help for ' + command + ' command', function() { - return helpers.run('help', [command]).spread(function(result) { + return helpers.run(help, [command]).spread(function(result) { expect(result.command).to.be(command); expect(result.description).to.be.a('string'); expect(result.usage[0]).to.be.a('string'); @@ -33,7 +30,7 @@ describe('bower help', function () { }); it('displays error for non-existing command', function() { - return helpers.run('help', ['fuu']).fail(function(e) { + return helpers.run(help, ['fuu']).fail(function(e) { expect(e.message).to.be('Unknown command: fuu'); expect(e.command).to.be('fuu'); expect(e.code).to.be('EUNKNOWNCMD'); diff --git a/test/commands/home.js b/test/commands/home.js new file mode 100644 index 000000000..cf320afe7 --- /dev/null +++ b/test/commands/home.js @@ -0,0 +1,25 @@ +var expect = require('expect.js'); +var helpers = require('../helpers'); + +describe('bower home', function () { + + var package = new helpers.TempDir({ + 'bower.json': { + name: 'package', + homepage: 'http://bower.io' + } + }); + + it('opens repository home page in web browser', function (done) { + package.prepare(); + + var home = helpers.command('home', { + opn: helpers.ensureDone(done, function(url) { + expect(url).to.be('http://bower.io'); + }) + }); + + return helpers.run(home, [package.path]); + }); + +}); diff --git a/test/commands/index.js b/test/commands/index.js index 04c3c98c0..098fe67e8 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -1,8 +1,9 @@ describe('integration tests', function () { require('./help'); + require('./home'); require('./init'); require('./install'); + require('./list'); require('./uninstall'); require('./update'); - require('./list'); }); diff --git a/test/commands/list.js b/test/commands/list.js index 166dfb065..4ef10dd6b 100644 --- a/test/commands/list.js +++ b/test/commands/list.js @@ -3,6 +3,11 @@ var object = require('mout').object; var helpers = require('../helpers'); +var commands = { + install: helpers.command('install'), + list: helpers.command('list') +}; + describe('bower list', function () { var tempDir = new helpers.TempDir(); @@ -14,7 +19,7 @@ describe('bower list', function () { cwd: tempDir.path }); - return helpers.run('install', [packages, options, config]); + return helpers.run(commands.install, [packages, options, config]); }; var list = function(options, config) { @@ -22,7 +27,7 @@ describe('bower list', function () { cwd: tempDir.path }); - return helpers.run('list', [options, config]); + return helpers.run(commands.list, [options, config]); }; it('lists no packages when nothing installed', function () { diff --git a/test/helpers.js b/test/helpers.js index 7a64dac95..9cb26e758 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -7,9 +7,9 @@ var object = require('mout/object'); var fs = require('fs'); var glob = require('glob'); var os = require('os'); +var proxyquire = require('proxyquire').noCallThru(); var cmd = require('../lib/util/cmd'); var config = require('../lib/config'); -var commands = require('../lib/index').commands; // Those are needed for Travis or not configured git environment var env = { @@ -30,8 +30,12 @@ var tmpLocation = path.join( uuid.v4().slice(0, 8) ); -exports.require = function (name) { - return require(path.join(__dirname, '../', name)); +exports.require = function (name, stubs) { + if (stubs) { + return proxyquire(path.join(__dirname, '../', name), stubs); + } else { + return require(path.join(__dirname, '../', name)); + } }; // We need to reset cache because tests are reusing temp directories @@ -150,11 +154,36 @@ exports.expectEvent = function expectEvent(emitter, eventName) { return deferred.promise; }; -exports.run = function run(name, args) { - if (!commands[name]) { - throw new Error('No such command: ' + name); +exports.command = function (command, stubs) { + var commandStubs = {}; + + commandStubs['./' + command] = exports.require( + 'lib/commands/' + command, stubs + ); + + var instance = exports.require( + 'lib/commands/index', commandStubs + )[command]; + + if (!instance) { + throw new Error('Unknown command: ' + command); } - var installer = commands[name].apply(commands[name], args || []); + return instance; +}; + +exports.run = function (command, args) { + var installer = command.apply(command, args || []); return exports.expectEvent(installer, 'end'); }; + +exports.ensureDone = function(done, callback) { + return function() { + try { + callback.apply(null, arguments); + done(); + } catch(e) { + done(e); + } + }; +}; From 9d06fce5f919080ac817949dd7620bd8234feea3 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 5 Jan 2015 05:31:12 +0100 Subject: [PATCH 0493/1021] Add few more tests for home command --- test/commands/home.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/test/commands/home.js b/test/commands/home.js index cf320afe7..e335b73e8 100644 --- a/test/commands/home.js +++ b/test/commands/home.js @@ -10,6 +10,12 @@ describe('bower home', function () { } }); + var wrongPackage = new helpers.TempDir({ + 'bower.json': { + name: 'package' + } + }); + it('opens repository home page in web browser', function (done) { package.prepare(); @@ -22,4 +28,31 @@ describe('bower home', function () { return helpers.run(home, [package.path]); }); + it('opens home page of current repository', function (done) { + package.prepare(); + + var home = helpers.command('home', { + opn: helpers.ensureDone(done, function(url) { + expect(url).to.be('http://bower.io'); + }) + }); + + return helpers.run(home, [undefined, { cwd: package.path }]); + }); + + it('errors if no homepage is set', function (done) { + wrongPackage.prepare(); + + var home = helpers.command('home', { + opn: helpers.ensureDone(done, function(url) { + expect(url).to.be('http://bower.io'); + }) + }); + + return helpers.run(home, [wrongPackage.path]) + .fail(helpers.ensureDone(done, function(reason) { + expect(reason.message).to.be('No homepage set for package'); + expect(reason.code).to.be('ENOHOME'); + })); + }); }); From 537cd42097f63b8aad94fd3972c001c924447be2 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 5 Jan 2015 06:07:01 +0100 Subject: [PATCH 0494/1021] Add tests for info command --- lib/commands/info.js | 8 +++---- test/commands/index.js | 1 + test/commands/info.js | 47 ++++++++++++++++++++++++++++++++++++++++++ test/helpers.js | 7 ++++--- 4 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 test/commands/info.js diff --git a/lib/commands/info.js b/lib/commands/info.js index 84d9c4601..6f01d7f32 100644 --- a/lib/commands/info.js +++ b/lib/commands/info.js @@ -7,6 +7,10 @@ var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); function info(logger, endpoint, property, config) { + if (!endpoint) { + return; + } + var repository; var decEndpoint; var tracker; @@ -58,10 +62,6 @@ info.line = function (logger, argv) { var pkg = options.argv.remain[1]; var property = options.argv.remain[2]; - if (!pkg) { - return new Q(); - } - return info(logger, pkg, property); }; diff --git a/test/commands/index.js b/test/commands/index.js index 098fe67e8..ca400ae83 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -1,6 +1,7 @@ describe('integration tests', function () { require('./help'); require('./home'); + require('./info'); require('./init'); require('./install'); require('./list'); diff --git a/test/commands/info.js b/test/commands/info.js new file mode 100644 index 000000000..b113ae03d --- /dev/null +++ b/test/commands/info.js @@ -0,0 +1,47 @@ +var expect = require('expect.js'); + +var helpers = require('../helpers'); +var info = helpers.command('info'); + +describe('bower info', function () { + + var meta = { + name: 'package', + version: '0.1.2', + homepage: 'http://bower.io', + description: 'Hello world!' + }; + + var meta2 = { + name: 'package', + version: '0.1.3', + homepage: 'http://bower.io', + description: 'Hello world! Hello!' + }; + + var package = new helpers.TempDir({ + '0.1.2': { 'bower.json': meta }, + '0.1.3': { 'bower.json': meta2 } + }); + + it('just returns if not package is specified', function () { + return helpers.run(info).spread(function(results) { + expect(results).to.be(undefined); + }); + }); + + it('shows info about given package', function () { + return package.prepareGit({}).then(function() { + return helpers.run(info, [package.path]).spread(function(results) { + expect(results).to.eql({ + 'latest': meta2, + 'name': package.path, + 'versions': [ + '0.1.3', + '0.1.2' + ] + }); + }); + }); + }); +}); diff --git a/test/helpers.js b/test/helpers.js index 9cb26e758..fb37c66f5 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -53,10 +53,11 @@ exports.TempDir = (function() { this.defaults = defaults; } - TempDir.prototype.create = function (files) { + TempDir.prototype.create = function (files, defaults) { var that = this; - files = object.merge(files || {}, this.defaults); + defaults = defaults || this.defaults || {}; + files = object.merge(files || {}, defaults); if (files) { object.forOwn(files, function (contents, filepath) { @@ -103,7 +104,7 @@ exports.TempDir = (function() { rimraf.sync(fullPath); }); - that.create(files); + that.create(files, {}); }).then(function () { return that.git('add', '-A'); }).then(function () { From 85df5b998385f7cfd75a916e6a5616cf24fa3f90 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 5 Jan 2015 06:47:01 +0100 Subject: [PATCH 0495/1021] Add test for bower binary nad standard renderer --- test/commands/bower.js | 28 ++++++++++++++++++++++++++++ test/commands/index.js | 1 + 2 files changed, 29 insertions(+) create mode 100644 test/commands/bower.js diff --git a/test/commands/bower.js b/test/commands/bower.js new file mode 100644 index 000000000..c301c21d0 --- /dev/null +++ b/test/commands/bower.js @@ -0,0 +1,28 @@ +var expect = require('expect.js'); +var helpers = require('../helpers'); + +describe('bower', function () { + + var oldStdout; + var text; + + before(function() { + oldStdout = process.stdout.write; + text = ''; + + process.stdout.write = function(args) { + text += args; + }; + }); + + it('runs bower installation', function (done) { + helpers.require('bin/bower'); + done(); + }); + + after(function() { + process.stdout.write = oldStdout; + expect(text).to.contain('Usage:'); + expect(text).to.contain('Commands:'); + }); +}); diff --git a/test/commands/index.js b/test/commands/index.js index ca400ae83..e0adcb0a7 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -1,4 +1,5 @@ describe('integration tests', function () { + require('./bower'); require('./help'); require('./home'); require('./info'); From dac055e2ef2e262137118cda66a12dd5af36f61d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 5 Jan 2015 06:51:09 +0100 Subject: [PATCH 0496/1021] Add timeout in hope to catch stdout on travis --- test/commands/bower.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/commands/bower.js b/test/commands/bower.js index c301c21d0..e69785211 100644 --- a/test/commands/bower.js +++ b/test/commands/bower.js @@ -17,7 +17,10 @@ describe('bower', function () { it('runs bower installation', function (done) { helpers.require('bin/bower'); - done(); + + setTimeout(function() { + done(); + }, 250); }); after(function() { From aad253bfadab769005c594a8ce33aa54cbf48c5d Mon Sep 17 00:00:00 2001 From: Patrick Kollitsch Date: Mon, 5 Jan 2015 12:52:31 +0700 Subject: [PATCH 0497/1021] Fix for #1639, missing line break in CLI input --- templates/std/conflict.std | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/std/conflict.std b/templates/std/conflict.std index 0f041e23a..222beb128 100644 --- a/templates/std/conflict.std +++ b/templates/std/conflict.std @@ -4,6 +4,7 @@ {{#magenta}}{{sum @index 1}}){{/magenta}} {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#green}}{{pkgMeta._release}}{{/green}}{{/if}}{{#if dependants}} and is required by {{#green}}{{dependants}}{{/green}} {{/if}} {{/each}} {{/condense}} + {{#unless saveResolutions}} Prefix the choice with ! to persist it to bower.json From 7c82da8389eb22c28a682d1f044e9733c26e6334 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 6 Jan 2015 02:13:20 +0100 Subject: [PATCH 0498/1021] Add tests for register command --- lib/commands/register.js | 19 +++--- test/commands/index.js | 4 +- test/commands/register.js | 120 ++++++++++++++++++++++++++++++++++++++ test/helpers.js | 26 ++++++++- 4 files changed, 153 insertions(+), 16 deletions(-) create mode 100644 test/commands/register.js diff --git a/lib/commands/register.js b/lib/commands/register.js index 40b04b73b..5ae64741c 100644 --- a/lib/commands/register.js +++ b/lib/commands/register.js @@ -19,18 +19,17 @@ function register(logger, name, url, config) { force = config.force; tracker = new Tracker(config); + name = (name || '').trim(); + url = (url || '').trim(); + // Bypass any cache config.offline = false; config.force = true; - // Trim name - name = name.trim(); - return Q.try(function () { - // Verify name - // TODO: Verify with the new spec regexp? - if (!name) { - throw createError('Please type a name', 'EINVNAME'); + // Verify name and url + if (!name || !url) { + throw createError('Usage: bower register ', 'EINVFORMAT'); } // The public registry only allows git:// endpoints @@ -109,11 +108,7 @@ register.line = function (logger, argv) { var name = options.argv.remain[1]; var url = options.argv.remain[2]; - if (!name || !url) { - return new Q(); - } else { - return register(logger, name, url); - } + return register(logger, name, url); }; register.completion = function () { diff --git a/test/commands/index.js b/test/commands/index.js index e0adcb0a7..3a2c0eef6 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -1,11 +1,13 @@ describe('integration tests', function () { - require('./bower'); require('./help'); require('./home'); require('./info'); require('./init'); require('./install'); require('./list'); + require('./register'); require('./uninstall'); require('./update'); + // run last because it changes defaults + require('./bower'); }); diff --git a/test/commands/register.js b/test/commands/register.js new file mode 100644 index 000000000..5ec511ca1 --- /dev/null +++ b/test/commands/register.js @@ -0,0 +1,120 @@ +var Q = require('q'); +var expect = require('expect.js'); +var helpers = require('../helpers'); + +var fakeRepositoryFactory = function (canonicalDir, pkgMeta) { + function FakeRepository() { } + + FakeRepository.prototype.fetch = function() { + return Q.fcall(function () { + return [canonicalDir, pkgMeta]; + }); + }; + + FakeRepository.prototype.getRegistryClient = function() { + return { + register: function (name, url, cb) { + cb(null, { name: name, url: url }); + } + }; + }; + + return FakeRepository; +}; + +var register = helpers.command('register'); + +var registerFactory = function (canonicalDir, pkgMeta) { + return helpers.command('register', { + '../core/PackageRepository': fakeRepositoryFactory( + canonicalDir, pkgMeta + ) + }); +}; + +describe('bower register', function () { + + var package = new helpers.TempDir({ + 'bower.json': { + name: 'package' + } + }); + + it('errors if name is not provided', function (done) { + return helpers.run(register) + .fail(helpers.ensureDone(done, function(reason) { + expect(reason.message).to.be('Usage: bower register '); + expect(reason.code).to.be('EINVFORMAT'); + })); + }); + + it('errors if url is not provided', function (done) { + return helpers.run(register, ['some-name']) + .fail(helpers.ensureDone(done, function(reason) { + expect(reason.message).to.be('Usage: bower register '); + expect(reason.code).to.be('EINVFORMAT'); + })); + }); + + it('errors if url is not correct', function (done) { + return helpers.run(register, ['some-name', 'url']) + .fail(helpers.ensureDone(done, function(reason) { + expect(reason.message).to.be('The registry only accepts URLs starting with git://'); + expect(reason.code).to.be('EINVFORMAT'); + })); + }); + + it('errors if trying to register private package', function (done) { + package.prepare({ 'bower.json': { private: true } }); + + var register = registerFactory(package.path, package.meta()); + return helpers.run(register, ['some-name', 'git://fake-url.git']) + .fail(helpers.ensureDone(done, function(reason) { + expect(reason.message).to.be('The package you are trying to register is marked as private'); + expect(reason.code).to.be('EPRIV'); + })); + }); + + it('should call registry client with name and url', function (done) { + package.prepare(); + + var register = registerFactory(package.path, package.meta()); + return helpers.run(register, ['some-name', 'git://fake-url.git']) + .spread(helpers.ensureDone(done, function(result) { + expect(result).to.eql({ + // Result from register action on stub + name: 'some-name', url: 'git://fake-url.git' + }); + })); + }); + + it('should confirm in interactive mode', function (done) { + package.prepare(); + + var register = registerFactory(package.path, package.meta()); + + var promise = helpers.run(register, + ['some-name', 'git://fake-url.git', { interactive: true }] + ); + + return helpers.expectEvent(promise.logger, 'confirm') + .spread(helpers.ensureDone(done, function(e) { + expect(e.type).to.be('confirm'); + expect(e.message).to.be('Registering a package will make it installable via the registry (\u001b[4m\u001b[36mhttps://bower.herokuapp.com\u001b[39m\u001b[24m), continue?'); + expect(e.default).to.be(true); + })); + }); + + it('should skip confirming when forcing', function (done) { + package.prepare(); + + var register = registerFactory(package.path, package.meta()); + + var promise = helpers.run(register, + ['some-name', 'git://fake-url.git', { interactive: true, force: true }] + ); + + return helpers.expectEvent(promise.logger, 'end') + .spread(helpers.ensureDone(done)); + }); +}); diff --git a/test/helpers.js b/test/helpers.js index fb37c66f5..81918f2a5 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -7,7 +7,7 @@ var object = require('mout/object'); var fs = require('fs'); var glob = require('glob'); var os = require('os'); -var proxyquire = require('proxyquire').noCallThru(); +var proxyquire = require('proxyquire').noCallThru().noPreserveCache(); var cmd = require('../lib/util/cmd'); var config = require('../lib/config'); @@ -59,6 +59,14 @@ exports.TempDir = (function() { defaults = defaults || this.defaults || {}; files = object.merge(files || {}, defaults); + this.meta = function(tag) { + if (tag) { + return files[tag]['bower.json']; + } else { + return files['bower.json']; + } + }; + if (files) { object.forOwn(files, function (contents, filepath) { if (typeof contents === 'object') { @@ -174,11 +182,23 @@ exports.command = function (command, stubs) { }; exports.run = function (command, args) { - var installer = command.apply(command, args || []); - return exports.expectEvent(installer, 'end'); + var logger = command.apply(command, args || []); + + // Hack so we can intercept prompring for data + logger.prompt = function(data) { + logger.emit('confirm', data); + }; + + var promise = exports.expectEvent(logger, 'end'); + + promise.logger = logger; + + return promise; }; exports.ensureDone = function(done, callback) { + callback = callback || function() {}; + return function() { try { callback.apply(null, arguments); From 39491b78b1e32255f72edd888ecb783d76b46667 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 6 Jan 2015 02:24:39 +0100 Subject: [PATCH 0499/1021] Test register prompt as on dumb terminal (fixes travis) --- test/commands/register.js | 2 +- test/helpers.js | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/test/commands/register.js b/test/commands/register.js index 5ec511ca1..d6948c8c9 100644 --- a/test/commands/register.js +++ b/test/commands/register.js @@ -100,7 +100,7 @@ describe('bower register', function () { return helpers.expectEvent(promise.logger, 'confirm') .spread(helpers.ensureDone(done, function(e) { expect(e.type).to.be('confirm'); - expect(e.message).to.be('Registering a package will make it installable via the registry (\u001b[4m\u001b[36mhttps://bower.herokuapp.com\u001b[39m\u001b[24m), continue?'); + expect(e.message).to.be('Registering a package will make it installable via the registry (https://bower.herokuapp.com), continue?'); expect(e.default).to.be(true); })); }); diff --git a/test/helpers.js b/test/helpers.js index 81918f2a5..44ce7f58f 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -1,3 +1,6 @@ +// So CLI output is monochrome in tests +process.env.TERM = 'dumb'; + var Q = require('q'); var path = require('path'); var mkdirp = require('mkdirp'); @@ -18,7 +21,7 @@ var env = { 'GIT_AUTHOR_EMAIL': 'amdfcruz@gmail.com', 'GIT_COMMITTER_DATE': 'Sun Apr 7 22:13:13 2013 +0000', 'GIT_COMMITTER_NAME': 'André Cruz', - 'GIT_COMMITTER_EMAIL': 'amdfcruz@gmail.com' + 'GIT_COMMITTER_EMAIL': 'amdfcruz@gmail.com', }; // Preserve the original environment From 8e0b8f2fafa126e1b895675105e8b5d89f9b7649 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 6 Jan 2015 03:12:32 +0100 Subject: [PATCH 0500/1021] [test] Force monochrome color for test cases --- test/helpers.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/helpers.js b/test/helpers.js index 44ce7f58f..44bb7bc82 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -1,6 +1,13 @@ // So CLI output is monochrome in tests process.env.TERM = 'dumb'; +// We need to reload supports-color and chalk that caches its result +Object.keys(require.cache).map(function(e) { + if (e.match('supports-color') || e.match('chalk')) { + delete require.cache[e]; + } +}); + var Q = require('q'); var path = require('path'); var mkdirp = require('mkdirp'); From 4cb027eb7385be6f47b9bec060c25a9ebde8a6b3 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 6 Jan 2015 15:56:10 +0100 Subject: [PATCH 0501/1021] Add tests for StandardRenderer --- lib/renderers/StandardRenderer.js | 2 +- package.json | 2 + templates/std/conflict.std | 2 +- test/helpers.js | 28 ++ test/renderers/StandardRenderer.js | 741 +++++++++++++++++++++++++++++ test/test.js | 1 + 6 files changed, 774 insertions(+), 2 deletions(-) create mode 100644 test/renderers/StandardRenderer.js diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index 6c804c634..57c3a1287 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -23,7 +23,7 @@ function StandardRenderer(command, config) { }; this._command = command; - this._config = config; + this._config = config || {}; if (this.constructor._wideCommands.indexOf(command) === -1) { this._compact = true; diff --git a/package.json b/package.json index 599d2d0f0..db20f131d 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "which": "^1.0.8" }, "devDependencies": { + "chai": "^1.10.0", "coveralls": "~2.11.2", "expect.js": "~0.3.1", "grunt": "~0.4.5", @@ -70,6 +71,7 @@ "istanbul": "~0.3.5", "load-grunt-tasks": "~2.0.0", "mocha": "~2.1.0", + "multiline": "^1.0.1", "nock": "~0.53.0", "node-uuid": "~1.4.2", "proxyquire": "~1.3.0" diff --git a/templates/std/conflict.std b/templates/std/conflict.std index 222beb128..cf5142781 100644 --- a/templates/std/conflict.std +++ b/templates/std/conflict.std @@ -1,7 +1,7 @@ {{#yellow}}Unable to find a suitable version for {{name}}, please choose one:{{/yellow}} {{#condense}} {{#each picks}} - {{#magenta}}{{sum @index 1}}){{/magenta}} {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#green}}{{pkgMeta._release}}{{/green}}{{/if}}{{#if dependants}} and is required by {{#green}}{{dependants}}{{/green}} {{/if}} + {{#magenta}}{{sum @index 1}}){{/magenta}} {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#green}}{{pkgMeta._release}}{{/green}}{{/if}}{{#if dependants}} and is required by {{#green}}{{dependants}}{{/green}}{{/if}} {{/each}} {{/condense}} diff --git a/test/helpers.js b/test/helpers.js index 44bb7bc82..b5eb4e102 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -218,3 +218,31 @@ exports.ensureDone = function(done, callback) { } }; }; + +exports.capture = function(callback) { + var oldStdout = process.stdout.write; + var oldStderr = process.stderr.write; + + var stdout = ''; + var stderr = ''; + + process.stdout.write = function(text) { + stdout += text; + }; + + process.stderr.write = function(text) { + stderr += text; + }; + + return Q.fcall(callback).then(function() { + process.stdout.write = oldStdout; + process.stderr.write = oldStderr; + + return [stdout, stderr]; + }).fail(function(e) { + process.stdout.write = oldStdout; + process.stderr.write = oldStderr; + + throw e; + }); +}; diff --git a/test/renderers/StandardRenderer.js b/test/renderers/StandardRenderer.js new file mode 100644 index 000000000..f78206b33 --- /dev/null +++ b/test/renderers/StandardRenderer.js @@ -0,0 +1,741 @@ +var expect = require('chai').expect; +var helpers = require('../helpers'); +var multiline = require('multiline').stripIndent; + +var StandardRenderer = helpers.require('lib/renderers/StandardRenderer'); + +describe('StandardRenderer', function () { + + // Simulate wide terminal + process.stdout.columns = 130; + + it('logs generic simple message', function () { + return helpers.capture(function() { + var renderer = new StandardRenderer(); + renderer.log({ + id: 'foobar', + message: 'hello world' + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.eq(multiline(function(){/* + bower foobar hello world + */}) + '\n'); + }); + }); + + it('logs simple error', function () { + return helpers.capture(function() { + var renderer = new StandardRenderer(); + renderer.error({ + code: 'EFOOBAR', + message: 'Hello error' + }); + }).spread(function(stdout, stderr) { + expect(stderr).to.eq(multiline(function(){/* + bower EFOOBAR Hello error + */}) + '\n'); + }); + }); + + it('logs error with details', function () { + return helpers.capture(function() { + var renderer = new StandardRenderer(); + renderer.error({ + code: 'EFOOBAR', + message: 'Hello error', + details: ' Some awesome details\nMultiline! ' + }); + }).spread(function(stdout, stderr) { + expect(stderr).to.eq(multiline(function(){/* + bower EFOOBAR Hello error + + Additional error details: + Some awesome details + Multiline! + */}) + '\n'); + }); + }); + + it('logs system details in verbose mode', function () { + return helpers.capture(function() { + var renderer = new StandardRenderer(undefined, { verbose: true }); + renderer.error({ + code: 'EFOOBAR', + message: 'Hello error', + details: ' Some awesome details\nMultiline! ' + }); + }).spread(function(stdout, stderr) { + expect(stderr).to.match(new RegExp(multiline(function(){/* + System info: + Bower version: [^\n]+ + Node version: [^\n]+ + OS: [^\n]+ + */}) + '\n')); + }); + }); + + it('logs stack trace in verbose mode', function () { + return helpers.capture(function() { + var renderer = new StandardRenderer(undefined, { verbose: true }); + renderer.error({ + code: 'EFOOBAR', + message: 'Hello error', + details: ' Some awesome details\nMultiline! ', + stack: [ + './one.js:1', + './two.js:2' + ] + }); + }).spread(function(stdout, stderr) { + expect(stderr).to.string(multiline(function(){/* + Stack trace: + ./one.js:1 + ./two.js:2 + + */})); + }); + }); + + it('logs console trace in verbose mode', function () { + return helpers.capture(function() { + var renderer = new StandardRenderer(undefined, { verbose: true }); + renderer.error({ + code: 'EFOOBAR', + message: 'Hello error', + details: ' Some awesome details\nMultiline! ' + }); + }).spread(function(stdout, stderr) { + expect(stderr).to.match(new RegExp(multiline(function(){/* + Console trace: + Trace + at StandardRenderer.error ([^:]+:82:17) + */}))); + }); + }); + + it('outputs checkout command log', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer(); + renderer.log({ + id: 'checkout', + origin: 'jquery#master', + message: 'foobar' + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + bower checkout jquery#foobar + */}) + '\n'); + }); + }); + + it('outputs full progress for wide command', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('install'); + renderer.log({ + id: 'progress', + origin: 'jquery#master', + message: 'foobar' + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + bower jquery#master progress foobar + */}) + '\n'); + }); + }); + + it('outputs full progress for narrow command', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('help'); + renderer.log({ + id: 'progress', + origin: 'jquery#master', + message: 'foobar' + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + bower progress jquery#master foobar + */}) + '\n'); + }); + }); + + it('outputs extract log just as progress log', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('install'); + renderer.log({ + id: 'extract', + origin: 'jquery#master', + message: 'foobar' + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + bower jquery#master extract foobar + */}) + '\n'); + }); + }); + + it('outputs incompatible log with suitable package', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer(); + renderer.log({ + id: 'incompatible', + data: { + resolution: '~0.1.1', + suitable: { + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'foobar' + } + }, + picks: [ + { + pkgMeta: { + _release: '0.0.0' + }, + endpoint: { + name: 'fizfuz', + target: '~0.0.0' + }, + dependants: [ + { + pkgMeta: { + _release: 'release1' + }, + endpoint: { + name: 'dependant1' + } + }, + { + pkgMeta: { + _release: 'release2' + }, + endpoint: { + name: 'dependant2' + } + } + ] + }, + { + endpoint: { + name: 'fizfuz2' + }, + dependants: [ + { + pkgMeta: { + // no release + }, + endpoint: { + name: 'jquery2' + } + } + ] + } + ] + } + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + + Please note that, + dependant1#release1, dependant2#release2 depends on fizfuz#~0.0.0 which resolved to fizfuz#0.0.0 + jquery2 depends on fizfuz2# + Resort to using foobar#~0.1.1 which resolved to foobar#0.1.2 + Code incompatibilities may occur. + */}) + '\n\n'); + }); + }); + + it('outputs solver log without suitable package', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer(); + renderer.log({ + id: 'solved', + data: { + resolution: '~0.1.1', + picks: [ + { + pkgMeta: { + _release: '0.0.0' + }, + endpoint: { + name: 'fizfuz', + target: '~0.0.0' + }, + dependants: [ + { + pkgMeta: { + _release: 'release1' + }, + endpoint: { + name: 'dependant1' + } + }, + { + pkgMeta: { + _release: 'release2' + }, + endpoint: { + name: 'dependant2' + } + } + ] + }, + { + endpoint: { + name: 'fizfuz2' + }, + dependants: [ + { + pkgMeta: { + // no release + }, + endpoint: { + name: 'jquery2' + } + } + ] + } + ] + } + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + + Unable to find a suitable version for , please choose one: + 1) fizfuz#~0.0.0 which resolved to 0.0.0 and is required by dependant1#release1, dependant2#release2 + 2) fizfuz2# and is required by jquery2 + + Prefix the choice with ! to persist it to bower.json + */}) + '\n\n'); + }); + }); + + it('outputs json log', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer(); + renderer.log({ + id: 'json', + data: { + json: { + foo: 'bar', + fiz: { + fuz: 'faz' + } + } + } + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + + { + foo: 'bar', + fiz: { + fuz: 'faz' + } + } + */}) + '\n\n'); + }); + }); + + it('outputs cached entry log', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('install'); + renderer.log({ + id: 'cached-entry', + origin: 'origin', + message: 'message' + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + bower origin cached message + */}) + '\n'); + }); + }); + + it('adjusts whitespace when package id too long', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('install', {}); + renderer.log({ + id: 'generic', + origin: 'short-origin', + message: 'message' + }); + + renderer.log({ + id: 'generic', + origin: 'very-very-long-origin-string', + message: 'message' + }); + + renderer.log({ + id: 'generic', + origin: 'short-origin', + message: 'message' + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + bower short-origin generic message + bower very-very-long-origin-string generic message + bower short-origin generic message + */}) + '\n'); + }); + }); + + it('outputs install command log', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('install', { + cwd: '/tmp' + }); + + renderer.end([ + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery' + } + }, + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + version: '0.1.2' + }, + endpoint: { + name: 'jquery' + } + }, + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery' + }, + missing: true + }, + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery' + }, + different: true + }, + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery' + }, + linked: true + }, + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery', + target: '~0.1.2' + }, + incompatible: true + }, + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery', + target: '~0.1.2' + }, + extraneous: true + }, + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery', + target: '~0.1.2' + }, + update: { + target: '0.1.5', + latest: '0.2.0' + } + }, + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery' + }, + dependencies: { + angular: { + canonicalDir: '/tmp/components/angular', + pkgMeta: { + _release: '0.1.3' + }, + endpoint: { + name: 'angular' + } + }, + ember: { + canonicalDir: '/tmp/components/ember', + pkgMeta: { + _release: '0.2.3' + }, + endpoint: { + name: 'ember' + }, + dependencies: { + // Should be ingored (only one level) + react: { + canonicalDir: '/tmp/components/react', + pkgMeta: { + _release: '0.2.3' + }, + endpoint: { + name: 'react' + } + } + } + } + } + } + ]); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + + jquery#0.1.2 components/jquery + + jquery#0.1.2 components/jquery + + jquery components/jquery not installed + + jquery#0.1.2 components/jquery different + + jquery#0.1.2 components/jquery linked + + jquery#0.1.2 components/jquery incompatible with ~0.1.2 + + jquery#0.1.2 components/jquery extraneous + + jquery#0.1.2 components/jquery (0.1.5 available, latest is 0.2.0) + + jquery#0.1.2 components/jquery + ├── angular#0.1.3 + └── ember#0.2.3 + */}) + '\n'); + }); + }); + + it('outputs short info command log', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('info', {}); + renderer.end({ + version: '1.2.3' + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + + { + version: '1.2.3' + } + + */}) + '\n'); + }); + }); + + it('outputs full info command log', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('info', {}); + renderer.end({ + name: 'foo', + latest: { + version: '1.2.3' + }, + versions: [ + '1.2.0', + '1.2.1', + '1.2.2' + ] + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + + { + version: '1.2.3' + } + + Available versions: + - 1.2.0 + - 1.2.1 + - 1.2.2 + You can request info for a specific version with 'bower info foo#' + */}) + '\n'); + }); + }); + + it('outputs lookup command log', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('lookup', {}); + renderer.end({ + name: 'bower', + url: 'http://bower.io' + }); + renderer.end({ + name: 'bower' + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + bower http://bower.io + Package not found. + */}) + '\n'); + }); + }); + + it('outputs link command log', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('link', { cwd: '/tmp' }); + renderer.end({ + src: './foo', + dst: './bar', + installed: [{ + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery' + } + }] + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + bower link ./bar > ./foo + + jquery#0.1.2 components/jquery + */}) + '\n'); + }); + }); + + it('outputs search command log', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('search'); + renderer.end([ + { + name: 'jquery', + url: 'http://jquery.io' + }, + { + name: 'bower', + url: 'http://bower.io' + } + ]); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + Search results: + + jquery http://jquery.io + bower http://bower.io + */}) + '\n'); + }); + }); + + it('outputs register command log', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('register'); + renderer.end({ + name: 'jquery', + url: 'http://jquery.io' + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + + Package jquery registered successfully! + All valid semver tags on http://jquery.io will be available as versions. + To publish a new version, just release a valid semver tag. + + Run bower info jquery to list the available versions. + */}) + '\n'); + }); + }); + + it('outputs cache list command log', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('cache list'); + renderer.end([ + { + pkgMeta: { + name: 'awesome-jquery', + _target: '0.1.1', + _source: 'jquery' + } + } + ]); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + awesome-jquery=jquery#0.1.1 + */}) + '\n'); + }); + }); + + it('outputs help command log', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('help'); + renderer.end({ + 'command': 'uninstall', + 'description': 'Uninstalls a package locally from your bower_components directory', + 'usage': [ + 'uninstall [ ..] []' + ], + 'options': [ + { + 'shorthand': '-h', + 'flag': '--help', + 'description': 'Show this help message' + }, + { + 'shorthand': '-S', + 'flag': '--save', + 'description': 'Remove uninstalled packages from the project\'s bower.json dependencies' + }, + { + 'shorthand': '-D', + 'flag': '--save-dev', + 'description': 'Remove uninstalled packages from the project\'s bower.json devDependencies' + } + ] + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function(){/* + + Usage: + + bower uninstall [ ..] [] + Options: + + -h, --help Show this help message + -S, --save Remove uninstalled packages from the project's bower.json dependencies + -D, --save-dev Remove uninstalled packages from the project's bower.json devDependencies + Additionally all global options listed in 'bower help' are available + + Description: + + Uninstalls a package locally from your bower_components directory + */}) + '\n'); + }); + }); +}); diff --git a/test/test.js b/test/test.js index 04596c3ef..661fffdb5 100644 --- a/test/test.js +++ b/test/test.js @@ -18,5 +18,6 @@ require('./core/resolveCache'); require('./core/packageRepository'); require('./core/scripts'); require('./core/Manager'); +require('./renderers/StandardRenderer.js'); require('./commands/index.js'); require('./util/index.js'); From dd30be90ad7e79c5f42bfd9fa493f93ee3a9fe2f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 6 Jan 2015 16:03:58 +0100 Subject: [PATCH 0502/1021] Fix StandardRenderer tests so they work on Travis --- test/renderers/StandardRenderer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/renderers/StandardRenderer.js b/test/renderers/StandardRenderer.js index f78206b33..bc625a464 100644 --- a/test/renderers/StandardRenderer.js +++ b/test/renderers/StandardRenderer.js @@ -108,7 +108,7 @@ describe('StandardRenderer', function () { expect(stderr).to.match(new RegExp(multiline(function(){/* Console trace: Trace - at StandardRenderer.error ([^:]+:82:17) + at StandardRenderer.error ([^:]+:\d+:\d+) */}))); }); }); From 52a32f0887e578b8470e571a210638bc2534033e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 6 Jan 2015 17:59:45 +0100 Subject: [PATCH 0503/1021] Add tests for JsonRenderer --- test/helpers.js | 3 ++ test/renderers/JsonRenderer.js | 96 ++++++++++++++++++++++++++++++++++ test/test.js | 1 + 3 files changed, 100 insertions(+) create mode 100644 test/renderers/JsonRenderer.js diff --git a/test/helpers.js b/test/helpers.js index b5eb4e102..7bbab3ccc 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -21,6 +21,9 @@ var proxyquire = require('proxyquire').noCallThru().noPreserveCache(); var cmd = require('../lib/util/cmd'); var config = require('../lib/config'); +// For better promise errors +Q.longStackSupport = true; + // Those are needed for Travis or not configured git environment var env = { 'GIT_AUTHOR_DATE': 'Sun Apr 7 22:13:13 2013 +0000', diff --git a/test/renderers/JsonRenderer.js b/test/renderers/JsonRenderer.js new file mode 100644 index 000000000..0c70a2fcb --- /dev/null +++ b/test/renderers/JsonRenderer.js @@ -0,0 +1,96 @@ +var expect = require('chai').expect; +var helpers = require('../helpers'); +var multiline = require('multiline').stripIndent; + +var JsonRenderer = helpers.require('lib/renderers/JsonRenderer'); + +var jsonRendererWithPrompt = function (stubs) { + return helpers.require('lib/renderers/JsonRenderer', { + promptly: stubs + }); +}; + +describe('JsonRenderer', function () { + + it('logs simple message to stderr', function () { + return helpers.capture(function() { + var renderer = new JsonRenderer(); + renderer.log({ + id: 'foobar', + message: 'hello world' + }); + + renderer.end(); + }).spread(function(stdout, stderr) { + expect(stderr).to.eq(multiline(function(){/* + [{ + "id": "foobar", + "message": "hello world" + }] + */}) + '\n'); + }); + }); + + it('logs error message to stderr', function () { + return helpers.capture(function() { + var renderer = new JsonRenderer(); + renderer.error({ + id: 'foobar', + message: 'hello world', + data: { + foo: 'bar' + }, + stacktrace: [ + './foo:23', + './bar:23' + ] + }); + }).spread(function(stdout, stderr) { + expect(stderr).to.eq(multiline(function(){/* + [{ + "id": "error", + "data": { + "foo": "bar" + }, + "stacktrace": "N/A", + "level": "error", + "message": "hello world" + }] + */}) + '\n'); + }); + }); + + it('prompts for answer', function () { + var JsonRenderer = jsonRendererWithPrompt({ + prompt: function(name, opts, callback) { + callback(null, 'something2'); + } + }); + + var renderer = new JsonRenderer(); + + return helpers.capture(function() { + return renderer.prompt([ + { + type: 'input', + name: 'field', + message: 'Please enter something', + default: 'something' + } + ]).then(function(response) { + expect(response.field).to.eq('something2'); + renderer.end(); + }); + }).spread(function(stdout, stderr) { + expect(stderr).to.eq(multiline(function(){/* + [{ + "type": "input", + "name": "field", + "message": "Please enter something", + "default": "something", + "level": "prompt" + }] + */}) + '\n'); + }); + }); +}); diff --git a/test/test.js b/test/test.js index 661fffdb5..1000753c2 100644 --- a/test/test.js +++ b/test/test.js @@ -19,5 +19,6 @@ require('./core/packageRepository'); require('./core/scripts'); require('./core/Manager'); require('./renderers/StandardRenderer.js'); +require('./renderers/JsonRenderer.js'); require('./commands/index.js'); require('./util/index.js'); From ee62d00c96f5ffe66beeeb001847ca745e713f90 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 6 Jan 2015 20:49:17 +0100 Subject: [PATCH 0504/1021] Add tests for "version" command --- lib/commands/version.js | 24 ++++---- test/commands/index.js | 1 + test/commands/version.js | 91 ++++++++++++++++++++++++++++++ test/helpers.js | 4 ++ test/renderers/StandardRenderer.js | 6 +- 5 files changed, 112 insertions(+), 14 deletions(-) create mode 100644 test/commands/version.js diff --git a/lib/commands/version.js b/lib/commands/version.js index 8a3faa3df..419fe3cf4 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -12,6 +12,7 @@ var createError = require('../util/createError'); function version(logger, versionArg, options, config) { var project; + options = options || {}; config = defaultConfig(config); project = new Project(config, logger); @@ -19,10 +20,11 @@ function version(logger, versionArg, options, config) { } function bump(project, versionArg, message) { + var cwd = project._config.cwd || process.cwd(); var newVersion; var doGitCommit = false; - return checkGit() + return checkGit(cwd) .then(function (hasGit) { doGitCommit = hasGit; }) @@ -34,7 +36,7 @@ function bump(project, versionArg, message) { .then(project.saveJson.bind(project)) .then(function () { if (doGitCommit) { - return gitCommitAndTag(newVersion, message); + return gitCommitAndTag(cwd, newVersion, message); } }) .then(function () { @@ -56,12 +58,12 @@ function getNewVersion(currentVersion, versionArg) { return newVersion; } -function checkGit() { - var gitDir = path.join(process.cwd(), '.git'); +function checkGit(cwd) { + var gitDir = path.join(cwd, '.git'); return Q.nfcall(fs.stat, gitDir) .then(function (stat) { if (stat.isDirectory()) { - return checkGitStatus(); + return checkGitStatus(cwd); } return false; }, function () { @@ -70,14 +72,14 @@ function checkGit() { }); } -function checkGitStatus() { +function checkGitStatus(cwd) { return Q.nfcall(which, 'git') .fail(function (err) { err.code = 'ENOGIT'; throw err; }) .then(function () { - return Q.nfcall(execFile, 'git', ['status', '--porcelain'], {env: process.env}); + return Q.nfcall(execFile, 'git', ['status', '--porcelain'], {env: process.env, cwd: cwd}); }) .then(function (value) { var stdout = value[0]; @@ -98,16 +100,16 @@ function filterModifiedStatusLines(stdout) { }); } -function gitCommitAndTag(newVersion, message) { +function gitCommitAndTag(cwd, newVersion, message) { var tag = 'v' + newVersion; message = message || tag; message = message.replace(/%s/g, newVersion); - return Q.nfcall(execFile, 'git', ['add', 'bower.json'], {env: process.env}) + return Q.nfcall(execFile, 'git', ['add', 'bower.json'], {env: process.env, cwd: cwd}) .then(function () { - return Q.nfcall(execFile, 'git', ['commit', '-m', message], {env: process.env}); + return Q.nfcall(execFile, 'git', ['commit', '-m', message], {env: process.env, cwd: cwd}); }) .then(function () { - return Q.nfcall(execFile, 'git', ['tag', tag, '-am', message], {env: process.env}); + return Q.nfcall(execFile, 'git', ['tag', tag, '-am', message], {env: process.env, cwd: cwd}); }); } diff --git a/test/commands/index.js b/test/commands/index.js index 3a2c0eef6..ea85082dc 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -8,6 +8,7 @@ describe('integration tests', function () { require('./register'); require('./uninstall'); require('./update'); + require('./version'); // run last because it changes defaults require('./bower'); }); diff --git a/test/commands/version.js b/test/commands/version.js new file mode 100644 index 000000000..4855b900f --- /dev/null +++ b/test/commands/version.js @@ -0,0 +1,91 @@ +var expect = require('expect.js'); + +var helpers = require('../helpers'); +var version = helpers.require('lib/commands').version; + +describe('bower list', function () { + + var package = new helpers.TempDir({ + 'bower.json': { + name: 'foobar', + version: '0.0.0' + } + }); + + var gitPackage = new helpers.TempDir({ + 'v0.0.0': { + 'bower.json': { + name: 'foobar', + version: '0.0.0' + } + } + }); + + it('bumps patch version', function() { + package.prepare(); + + return helpers.run(version, ['patch', {}, { cwd: package.path }]).then(function() { + expect(package.readJson('bower.json').version).to.be('0.0.1'); + }); + }); + + it('bumps minor version', function() { + package.prepare(); + + return helpers.run(version, ['minor', {}, { cwd: package.path }]).then(function() { + expect(package.readJson('bower.json').version).to.be('0.1.0'); + }); + }); + + it('bumps major version', function() { + package.prepare(); + + return helpers.run(version, ['major', {}, { cwd: package.path }]).then(function() { + expect(package.readJson('bower.json').version).to.be('1.0.0'); + }); + }); + + it('changes version', function() { + package.prepare(); + + return helpers.run(version, ['1.2.3', {}, { cwd: package.path }]).then(function() { + expect(package.readJson('bower.json').version).to.be('1.2.3'); + }); + }); + + it('bumps patch version, create commit, and tag', function() { + return gitPackage.prepareGit().then(function() { + + return helpers.run(version, ['patch', {}, { cwd: gitPackage.path }]).then(function() { + expect(gitPackage.readJson('bower.json').version).to.be('0.0.1'); + + return gitPackage.git('tag').spread(function(result) { + expect(result).to.be('v0.0.0\nv0.0.1\n'); + + return gitPackage.git('log', '--pretty=format:%s', '-n1').spread(function(result) { + expect(result).to.be('v0.0.1'); + }); + }); + }); + + }); + }); + + it('bumps with custom commit message', function() { + return gitPackage.prepareGit().then(function() { + + return helpers.run(version, ['patch', { message: 'Bumping %s, because what'}, { cwd: gitPackage.path }]).then(function() { + expect(gitPackage.readJson('bower.json').version).to.be('0.0.1'); + + return gitPackage.git('tag').spread(function(result) { + expect(result).to.be('v0.0.0\nv0.0.1\n'); + + return gitPackage.git('log', '--pretty=format:%s', '-n1').spread(function(result) { + expect(result).to.be('Bumping 0.0.1, because what'); + }); + }); + }); + + }); + }); +}); diff --git a/test/helpers.js b/test/helpers.js index 7bbab3ccc..d74e32ee6 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -149,6 +149,10 @@ exports.TempDir = (function() { return fs.readFileSync(path.join(this.path, name), 'utf8'); }; + TempDir.prototype.readJson = function (name) { + return JSON.parse(this.read(name)); + }; + TempDir.prototype.git = function () { var args = Array.prototype.slice.call(arguments); diff --git a/test/renderers/StandardRenderer.js b/test/renderers/StandardRenderer.js index bc625a464..172139587 100644 --- a/test/renderers/StandardRenderer.js +++ b/test/renderers/StandardRenderer.js @@ -1,3 +1,6 @@ +// Simulate wide terminal +process.stdout.columns = 130; + var expect = require('chai').expect; var helpers = require('../helpers'); var multiline = require('multiline').stripIndent; @@ -6,9 +9,6 @@ var StandardRenderer = helpers.require('lib/renderers/StandardRenderer'); describe('StandardRenderer', function () { - // Simulate wide terminal - process.stdout.columns = 130; - it('logs generic simple message', function () { return helpers.capture(function() { var renderer = new StandardRenderer(); From 85c50eb5424a2f1b5f037fb68aa7a6b666dbd7f9 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 6 Jan 2015 20:56:27 +0100 Subject: [PATCH 0505/1021] Inject credentials to ENV for Travis --- test/helpers.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/helpers.js b/test/helpers.js index d74e32ee6..ab4474e10 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -34,8 +34,7 @@ var env = { 'GIT_COMMITTER_EMAIL': 'amdfcruz@gmail.com', }; -// Preserve the original environment -object.mixIn(env, process.env); +object.mixIn(process.env, env); var tmpLocation = path.join( os.tmpdir ? os.tmpdir() : os.tmpDir(), From 2d4fec01b1f6e68ced170e6125d01cc299c8630d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 7 Jan 2015 02:04:34 +0100 Subject: [PATCH 0506/1021] Refactor some tests to promise style --- test/commands/home.js | 43 ++++++++++++++++------------------- test/commands/register.js | 48 +++++++++++++++++++-------------------- test/helpers.js | 14 +----------- 3 files changed, 43 insertions(+), 62 deletions(-) diff --git a/test/commands/home.js b/test/commands/home.js index e335b73e8..6665fd12a 100644 --- a/test/commands/home.js +++ b/test/commands/home.js @@ -1,3 +1,4 @@ +var Q = require('q'); var expect = require('expect.js'); var helpers = require('../helpers'); @@ -16,43 +17,37 @@ describe('bower home', function () { } }); - it('opens repository home page in web browser', function (done) { + it('opens repository home page in web browser', function () { package.prepare(); - var home = helpers.command('home', { - opn: helpers.ensureDone(done, function(url) { - expect(url).to.be('http://bower.io'); - }) + return Q.Promise(function(resolve) { + var home = helpers.command('home', { opn: resolve }); + helpers.run(home, [package.path]); + }).then(function(url) { + expect(url).to.be('http://bower.io'); }); - - return helpers.run(home, [package.path]); }); - it('opens home page of current repository', function (done) { + it('opens home page of current repository', function () { package.prepare(); - var home = helpers.command('home', { - opn: helpers.ensureDone(done, function(url) { - expect(url).to.be('http://bower.io'); - }) + return Q.Promise(function(resolve) { + var home = helpers.command('home', { opn: resolve }); + helpers.run(home, [undefined, { cwd: package.path }]); + }).then(function(url) { + expect(url).to.be('http://bower.io'); }); - - return helpers.run(home, [undefined, { cwd: package.path }]); }); - it('errors if no homepage is set', function (done) { + it('errors if no homepage is set', function () { wrongPackage.prepare(); - var home = helpers.command('home', { - opn: helpers.ensureDone(done, function(url) { - expect(url).to.be('http://bower.io'); - }) - }); - - return helpers.run(home, [wrongPackage.path]) - .fail(helpers.ensureDone(done, function(reason) { + return Q.Promise(function(resolve) { + var home = helpers.command('home', { opn: resolve }); + helpers.run(home, [wrongPackage.path]).fail(resolve); + }).then(function(reason) { expect(reason.message).to.be('No homepage set for package'); expect(reason.code).to.be('ENOHOME'); - })); + }); }); }); diff --git a/test/commands/register.js b/test/commands/register.js index d6948c8c9..b0af55265 100644 --- a/test/commands/register.js +++ b/test/commands/register.js @@ -40,55 +40,54 @@ describe('bower register', function () { } }); - it('errors if name is not provided', function (done) { - return helpers.run(register) - .fail(helpers.ensureDone(done, function(reason) { + it('errors if name is not provided', function () { + return helpers.run(register).fail(function(reason) { expect(reason.message).to.be('Usage: bower register '); expect(reason.code).to.be('EINVFORMAT'); - })); + }); }); - it('errors if url is not provided', function (done) { + it('errors if url is not provided', function () { return helpers.run(register, ['some-name']) - .fail(helpers.ensureDone(done, function(reason) { + .fail(function(reason) { expect(reason.message).to.be('Usage: bower register '); expect(reason.code).to.be('EINVFORMAT'); - })); + }); }); - it('errors if url is not correct', function (done) { + it('errors if url is not correct', function () { return helpers.run(register, ['some-name', 'url']) - .fail(helpers.ensureDone(done, function(reason) { + .fail(function(reason) { expect(reason.message).to.be('The registry only accepts URLs starting with git://'); expect(reason.code).to.be('EINVFORMAT'); - })); + }); }); - it('errors if trying to register private package', function (done) { + it('errors if trying to register private package', function () { package.prepare({ 'bower.json': { private: true } }); var register = registerFactory(package.path, package.meta()); return helpers.run(register, ['some-name', 'git://fake-url.git']) - .fail(helpers.ensureDone(done, function(reason) { + .fail(function(reason) { expect(reason.message).to.be('The package you are trying to register is marked as private'); expect(reason.code).to.be('EPRIV'); - })); + }); }); - it('should call registry client with name and url', function (done) { + it('should call registry client with name and url', function () { package.prepare(); var register = registerFactory(package.path, package.meta()); return helpers.run(register, ['some-name', 'git://fake-url.git']) - .spread(helpers.ensureDone(done, function(result) { + .spread(function(result) { expect(result).to.eql({ // Result from register action on stub name: 'some-name', url: 'git://fake-url.git' }); - })); + }); }); - it('should confirm in interactive mode', function (done) { + it('should confirm in interactive mode', function () { package.prepare(); var register = registerFactory(package.path, package.meta()); @@ -98,23 +97,22 @@ describe('bower register', function () { ); return helpers.expectEvent(promise.logger, 'confirm') - .spread(helpers.ensureDone(done, function(e) { + .spread(function(e) { expect(e.type).to.be('confirm'); expect(e.message).to.be('Registering a package will make it installable via the registry (https://bower.herokuapp.com), continue?'); expect(e.default).to.be(true); - })); + }); }); - it('should skip confirming when forcing', function (done) { + it('should skip confirming when forcing', function () { package.prepare(); var register = registerFactory(package.path, package.meta()); - var promise = helpers.run(register, - ['some-name', 'git://fake-url.git', { interactive: true, force: true }] + return helpers.run(register, + ['some-name', 'git://fake-url.git', + { interactive: true, force: true } + ] ); - - return helpers.expectEvent(promise.logger, 'end') - .spread(helpers.ensureDone(done)); }); }); diff --git a/test/helpers.js b/test/helpers.js index ab4474e10..6d91e97da 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -212,19 +212,7 @@ exports.run = function (command, args) { return promise; }; -exports.ensureDone = function(done, callback) { - callback = callback || function() {}; - - return function() { - try { - callback.apply(null, arguments); - done(); - } catch(e) { - done(e); - } - }; -}; - +// Captures all stdout and stderr exports.capture = function(callback) { var oldStdout = process.stdout.write; var oldStderr = process.stderr.write; From 3be4764d54e3de1033418921126add71810cd55b Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 7 Jan 2015 03:32:55 +0100 Subject: [PATCH 0507/1021] Add tests for prune command --- test/commands/index.js | 1 + test/commands/prune.js | 55 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 test/commands/prune.js diff --git a/test/commands/index.js b/test/commands/index.js index ea85082dc..1796fac8a 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -5,6 +5,7 @@ describe('integration tests', function () { require('./init'); require('./install'); require('./list'); + require('./prune'); require('./register'); require('./uninstall'); require('./update'); diff --git a/test/commands/prune.js b/test/commands/prune.js new file mode 100644 index 000000000..e99a06270 --- /dev/null +++ b/test/commands/prune.js @@ -0,0 +1,55 @@ +var expect = require('expect.js'); +var helpers = require('../helpers'); + +var prune = helpers.command('prune'); + +describe('bower home', function () { + + var package = new helpers.TempDir({ + 'bower.json': { + name: 'package', + dependencies: { + jquery: '*' + } + }, + 'bower_components/jquery/jquery.js': 'jquery source' + }); + + it('removes extraneous packages', function () { + package.prepare({ + 'bower_components/angular/angular.js': 'angular source', + 'bower_components/angular/.bower.json': { name: 'angular' } + }); + + return helpers.run(prune, [{}, { cwd: package.path }]).then(function() { + expect(package.exists('bower_components/angular/angular.js')) + .to.be(false); + }); + }); + + it('leaves non-bower packages', function () { + package.prepare({ + 'bower_components/angular/angular.js': 'angular source' + }); + + return helpers.run(prune, [{}, { cwd: package.path }]).then(function() { + expect(package.exists('bower_components/angular/angular.js')) + .to.be(true); + }); + }); + + it('deals with custom directory', function () { + package.prepare({ + '.bowerrc': { directory: 'components' }, + 'bower_components/angular/.bower.json': { name: 'angular' }, + 'bower_components/angular/angular.js': 'angular source', + 'components/angular/.bower.json': { name: 'angular' }, + 'components/angular/angular.js': 'angular source' + }); + + return helpers.run(prune, [{}, { cwd: package.path }]).then(function() { + expect(package.exists('components/angular/angular.js')).to.be(false); + expect(package.exists('bower_components/angular/angular.js')).to.be(true); + }); + }); +}); From a04b69dc6a2405a543ebf995f464229c0a99c1a2 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 8 Jan 2015 05:09:32 +0100 Subject: [PATCH 0508/1021] Test and fix link command --- lib/commands/link.js | 8 ++-- test/commands/index.js | 1 + test/commands/link.js | 105 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 test/commands/link.js diff --git a/lib/commands/link.js b/lib/commands/link.js index 60a669157..6b7bf26cf 100644 --- a/lib/commands/link.js +++ b/lib/commands/link.js @@ -6,11 +6,11 @@ var createLink = require('../util/createLink'); var cli = require('../util/cli'); var defaultConfig = require('../config'); -function link(logger, name, localName) { +function link(logger, name, localName, config) { if (name) { - return linkTo(logger, name, localName); + return linkTo(logger, name, localName, config); } else { - return linkSelf(logger); + return linkSelf(logger, config); } } @@ -50,7 +50,7 @@ function linkTo(logger, name, localName, config) { localName = localName || name; src = path.join(config.storage.links, name); - dst = path.join(process.cwd(), config.directory, localName); + dst = path.join(config.cwd, config.directory, localName); // Delete destination folder if any return Q.nfcall(rimraf, dst) diff --git a/test/commands/index.js b/test/commands/index.js index 1796fac8a..9b59c89b6 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -5,6 +5,7 @@ describe('integration tests', function () { require('./init'); require('./install'); require('./list'); + require('./link'); require('./prune'); require('./register'); require('./uninstall'); diff --git a/test/commands/link.js b/test/commands/link.js new file mode 100644 index 000000000..22e6d243e --- /dev/null +++ b/test/commands/link.js @@ -0,0 +1,105 @@ +var expect = require('expect.js'); +var helpers = require('../helpers'); + +var link = helpers.command('link'); + +describe('bower link', function () { + + var package = new helpers.TempDir({ + 'bower.json': { + name: 'package', + }, + 'index.js': 'Hello World!' + }); + + var otherPackage = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + }, + 'index.js': 'Welcome World!' + }); + + var linksDir = new helpers.TempDir(); + + beforeEach(function() { + package.prepare(); + otherPackage.prepare(); + linksDir.prepare(); + }); + + it('creates self link', function () { + return helpers.run(link, [undefined, undefined, + { + cwd: package.path, + storage: { + links: linksDir.path + } + } + ]).then(function() { + expect(linksDir.read('package/index.js')) + .to.be('Hello World!'); + }); + }); + + it('creates inter-link', function () { + return helpers.run(link, [undefined, undefined, + { + cwd: package.path, + storage: { + links: linksDir.path + } + } + ]).then(function () { + return helpers.run(link, ['package', undefined, + { + cwd: otherPackage.path, + storage: { + links: linksDir.path + } + } + ]); + }).then(function() { + expect(otherPackage.read('bower_components/package/index.js')) + .to.be('Hello World!'); + }); + }); + + it('creates inter-link with custom local name', function () { + return helpers.run(link, [undefined, undefined, + { + cwd: package.path, + storage: { + links: linksDir.path + } + } + ]).then(function () { + return helpers.run(link, ['package', 'local', + { + cwd: otherPackage.path, + storage: { + links: linksDir.path + } + } + ]); + }).then(function() { + expect(otherPackage.read('bower_components/local/index.js')) + .to.be('Hello World!'); + }); + }); + + it('errors on unexising package', function () { + return helpers.run(link, ['package', 'local', + { + cwd: otherPackage.path, + storage: { + links: linksDir.path + } + } + ]).then(function() { + throw 'Should fail creating a link!'; + }).fail(function(reason) { + expect(reason.code).to.be('ENOENT'); + expect(reason.message).to.be('Failed to create link to package'); + }); + }); +}); From 63da3e45958e0239b1ed0f1fdc3281e928a95272 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 8 Jan 2015 09:44:06 +0100 Subject: [PATCH 0509/1021] Add tests for cache list command --- test/commands/cache/list.js | 55 +++++++++++++++++++++++++++++++++++++ test/commands/index.js | 1 + test/helpers.js | 14 ++++++++-- 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 test/commands/cache/list.js diff --git a/test/commands/cache/list.js b/test/commands/cache/list.js new file mode 100644 index 000000000..636086640 --- /dev/null +++ b/test/commands/cache/list.js @@ -0,0 +1,55 @@ +var expect = require('expect.js'); +var helpers = require('../../helpers'); + +var cacheList = helpers.command('cache/list'); + +describe('bower cache list', function () { + + var cacheDir = new helpers.TempDir({ + '87323d6d4e48be291a9616a033d4cc6c/1.3.8/.bower.json': { + name: 'angular', + version: '1.3.8' + }, + '87323d6d4e48be291a9616a033d4cc6c/1.3.9/.bower.json': { + name: 'angular', + version: '1.3.9' + }, + '9eaed103d6a7e78d91f673cfad796850/1.0.0/.bower.json': { + name: 'jquery', + version: '1.0.0' + } + }); + + it('lists packages from cache', function () { + cacheDir.prepare(); + + return helpers.run(cacheList, [undefined, {}, { + storage: { + packages: cacheDir.path + } + }]).spread(function(result) { + expect(result[0].canonicalDir) + .to.be(cacheDir.getPath('87323d6d4e48be291a9616a033d4cc6c/1.3.8')); + expect(result[0].pkgMeta.version).to.be('1.3.8'); + expect(result[1].pkgMeta.version).to.be('1.3.9'); + expect(result[2].pkgMeta.version).to.be('1.0.0'); + }); + + }); + + it('lists selected package names', function () { + cacheDir.prepare(); + + return helpers.run(cacheList, [['angular'], {}, { + storage: { + packages: cacheDir.path + } + }]).spread(function(result) { + expect(result[0].canonicalDir) + .to.be(cacheDir.getPath('87323d6d4e48be291a9616a033d4cc6c/1.3.8')); + expect(result[0].pkgMeta.version).to.be('1.3.8'); + expect(result[1].pkgMeta.version).to.be('1.3.9'); + }); + + }); +}); diff --git a/test/commands/index.js b/test/commands/index.js index 9b59c89b6..440f7d2e6 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -1,4 +1,5 @@ describe('integration tests', function () { + require('./cache/list'); require('./help'); require('./home'); require('./info'); diff --git a/test/helpers.js b/test/helpers.js index 6d91e97da..ff09a2ccf 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -144,8 +144,12 @@ exports.TempDir = (function() { }); }; + TempDir.prototype.getPath = function (name) { + return path.join(this.path, name); + }; + TempDir.prototype.read = function (name) { - return fs.readFileSync(path.join(this.path, name), 'utf8'); + return fs.readFileSync(this.getPath(name), 'utf8'); }; TempDir.prototype.readJson = function (name) { @@ -188,7 +192,13 @@ exports.command = function (command, stubs) { var instance = exports.require( 'lib/commands/index', commandStubs - )[command]; + ); + + var commandParts = command.split('/'); + + while (commandParts.length > 0) { + instance = instance[commandParts.shift()]; + } if (!instance) { throw new Error('Unknown command: ' + command); From 3f8de0efb933e079d541f6e95af936b7c36492e2 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 9 Jan 2015 01:47:45 +0100 Subject: [PATCH 0510/1021] Add tests for cache clean command --- test/commands/cache/clean.js | 84 ++++++++++++++++++++++++++++++++++++ test/commands/index.js | 1 + 2 files changed, 85 insertions(+) create mode 100644 test/commands/cache/clean.js diff --git a/test/commands/cache/clean.js b/test/commands/cache/clean.js new file mode 100644 index 000000000..df335a768 --- /dev/null +++ b/test/commands/cache/clean.js @@ -0,0 +1,84 @@ +var expect = require('expect.js'); +var helpers = require('../../helpers'); + +var cacheClean = helpers.command('cache/clean'); +var md5 = helpers.require('lib/util/md5'); +var object = require('mout/object'); + +describe('bower cache clean', function () { + + // Because directory names are required to be mp5 of _source + var cacheFilesFactory = function (spec) { + var files = {}; + + object.map(spec, function(bowerJson) { + bowerJson._source = bowerJson.name + '/' + bowerJson.version; + var path = md5(bowerJson._source) + '/' + bowerJson.version + '/.bower.json'; + files[path] = bowerJson; + }); + + return files; + }; + + + var cacheFiles = cacheFilesFactory([ + { + name: 'angular', + version: '1.3.8' + }, + { + name: 'angular', + version: '1.3.9' + }, + { + name: 'jquery', + version: '1.0.0' + } + ]); + + var cacheDir = new helpers.TempDir(cacheFiles); + + it('removes all cache', function () { + cacheDir.prepare(); + + return helpers.run(cacheClean, [undefined, {}, { + storage: { + packages: cacheDir.path + } + }]).spread(function(result) { + object.map(cacheFiles, function (_, cacheFile) { + expect(cacheDir.exists(cacheFile)).to.be(false); + }); + }); + }); + + it('removes single package', function () { + cacheDir.prepare(); + + return helpers.run(cacheClean, [['angular'], {}, { + storage: { + packages: cacheDir.path + } + }]).spread(function(result) { + var paths = Object.keys(cacheFiles); + expect(cacheDir.exists(paths[0])).to.be(false); + expect(cacheDir.exists(paths[1])).to.be(false); + expect(cacheDir.exists(paths[2])).to.be(true); + }); + }); + + it('removes single package package version', function () { + cacheDir.prepare(); + + return helpers.run(cacheClean, [['angular#1.3.8'], {}, { + storage: { + packages: cacheDir.path + } + }]).spread(function(result) { + var paths = Object.keys(cacheFiles); + expect(cacheDir.exists(paths[0])).to.be(false); + expect(cacheDir.exists(paths[1])).to.be(true); + expect(cacheDir.exists(paths[2])).to.be(true); + }); + }); +}); diff --git a/test/commands/index.js b/test/commands/index.js index 440f7d2e6..a03759f4f 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -1,5 +1,6 @@ describe('integration tests', function () { require('./cache/list'); + require('./cache/clean'); require('./help'); require('./home'); require('./info'); From 5e747b2cfd703bfb535cf520007478704cb72719 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 9 Jan 2015 02:22:05 +0100 Subject: [PATCH 0511/1021] Add tests for search and lookup commands --- test/commands/index.js | 3 +++ test/commands/lookup.js | 23 +++++++++++++++++++++++ test/commands/search.js | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 test/commands/lookup.js create mode 100644 test/commands/search.js diff --git a/test/commands/index.js b/test/commands/index.js index a03759f4f..505fcfe38 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -8,11 +8,14 @@ describe('integration tests', function () { require('./install'); require('./list'); require('./link'); + require('./lookup'); require('./prune'); require('./register'); + require('./search'); require('./uninstall'); require('./update'); require('./version'); + // run last because it changes defaults require('./bower'); }); diff --git a/test/commands/lookup.js b/test/commands/lookup.js new file mode 100644 index 000000000..132a91ea3 --- /dev/null +++ b/test/commands/lookup.js @@ -0,0 +1,23 @@ +var Q = require('q'); +var expect = require('expect.js'); +var helpers = require('../helpers'); + +describe('bower lookup', function () { + + it('lookups package by name', function () { + return Q.Promise(function(resolve) { + var lookup = helpers.command('lookup', { + 'bower-registry-client': function() { + return { + lookup: resolve + }; + } + }); + + helpers.run(lookup, ['jquery'], {}); + }).then(function (query) { + expect(query).to.be('jquery'); + }); + }); + +}); diff --git a/test/commands/search.js b/test/commands/search.js new file mode 100644 index 000000000..14a50b709 --- /dev/null +++ b/test/commands/search.js @@ -0,0 +1,37 @@ +var Q = require('q'); +var expect = require('expect.js'); +var helpers = require('../helpers'); + +describe('bower search', function () { + + it('searches for single repository', function () { + return Q.Promise(function(resolve) { + var search = helpers.command('search', { + 'bower-registry-client': function() { + return { + search: resolve + }; + } + }); + + helpers.run(search, ['jquery'], {}); + }).then(function(query) { + expect(query).to.be('jquery'); + }); + }); + + it('lists all repositories if no query given', function () { + return Q.Promise(function(resolve) { + var search = helpers.command('search', { + 'bower-registry-client': function() { + return { + list: resolve + }; + } + }); + + helpers.run(search, [], {}); + }); + }); + +}); From 33842b6f92bd4eb5dce16e27dad447fd04a171b8 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 9 Jan 2015 02:29:18 +0100 Subject: [PATCH 0512/1021] Remove dummy completion command --- lib/commands/cache/clean.js | 25 +------------------------ lib/commands/cache/list.js | 4 ---- lib/commands/completion.js | 21 --------------------- lib/commands/help.js | 4 ---- lib/commands/home.js | 4 ---- lib/commands/index.js | 1 - lib/commands/info.js | 4 ---- lib/commands/init.js | 4 ---- lib/commands/install.js | 4 ---- lib/commands/link.js | 4 ---- lib/commands/list.js | 4 ---- lib/commands/lookup.js | 4 ---- lib/commands/prune.js | 4 ---- lib/commands/register.js | 4 ---- lib/commands/search.js | 4 ---- lib/commands/uninstall.js | 4 ---- lib/commands/update.js | 4 ---- lib/commands/version.js | 4 ---- 18 files changed, 1 insertion(+), 106 deletions(-) delete mode 100644 lib/commands/completion.js diff --git a/lib/commands/cache/clean.js b/lib/commands/cache/clean.js index 044442bcf..ff190e959 100644 --- a/lib/commands/cache/clean.js +++ b/lib/commands/cache/clean.js @@ -33,8 +33,7 @@ function clean(logger, endpoints, options, config) { return Q.all([ clearPackages(decEndpoints, config, logger), - clearLinks(names, config, logger), - !names ? clearCompletion(config, logger) : null + clearLinks(names, config, logger) ]) .spread(function (entries) { return entries; @@ -172,24 +171,6 @@ function clearLinks(names, config, logger) { }); } -function clearCompletion(config, logger) { - var dir = config.storage.completion; - - return Q.nfcall(fs.stat, dir) - .then(function () { - return Q.nfcall(rimraf, dir) - .then(function () { - logger.info('deleted', 'Completion cache', { - file: dir - }); - }); - }, function (error) { - if (error.code !== 'ENOENT') { - throw error; - } - }); -} - // ------------------- clean.line = function (logger, argv) { @@ -198,8 +179,4 @@ clean.line = function (logger, argv) { return clean(logger, endpoints, options); }; -clean.completion = function () { - // TODO: -}; - module.exports = clean; diff --git a/lib/commands/cache/list.js b/lib/commands/cache/list.js index 761085cc1..523f13fec 100644 --- a/lib/commands/cache/list.js +++ b/lib/commands/cache/list.js @@ -37,8 +37,4 @@ list.line = function (logger, argv) { return list(logger, packages, options); }; -list.completion = function () { - // TODO: -}; - module.exports = list; diff --git a/lib/commands/completion.js b/lib/commands/completion.js deleted file mode 100644 index 4cc0017cd..000000000 --- a/lib/commands/completion.js +++ /dev/null @@ -1,21 +0,0 @@ -var Q = require('q'); -var cli = require('../util/cli'); - -function completion(config) { - return new Q(); -} - -// ------------------- - -completion.line = function (logger, argv) { - var options = cli.readOptions(argv); - var name = options.argv.remain[1]; - - return completion(logger, name); -}; - -completion.completion = function () { - // TODO: -}; - -module.exports = completion; diff --git a/lib/commands/help.js b/lib/commands/help.js index 5fac8a986..5aa822a15 100644 --- a/lib/commands/help.js +++ b/lib/commands/help.js @@ -35,8 +35,4 @@ help.line = function (logger, argv) { return help(logger, name); }; -help.completion = function () { - // TODO -}; - module.exports = help; diff --git a/lib/commands/home.js b/lib/commands/home.js index 3bb5e48f6..e39c61f77 100644 --- a/lib/commands/home.js +++ b/lib/commands/home.js @@ -55,8 +55,4 @@ home.line = function (logger, argv) { return home(logger, name); }; -home.completion = function () { - // TODO: -}; - module.exports = home; diff --git a/lib/commands/index.js b/lib/commands/index.js index fecf77b5f..6c9d6baf1 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -53,7 +53,6 @@ module.exports = { clean: commandFactory('./cache/clean'), list: commandFactory('./cache/list'), }, - completion: commandFactory('./completion'), help: commandFactory('./help'), home: commandFactory('./home'), info: commandFactory('./info'), diff --git a/lib/commands/info.js b/lib/commands/info.js index 6f01d7f32..1654c81b3 100644 --- a/lib/commands/info.js +++ b/lib/commands/info.js @@ -65,8 +65,4 @@ info.line = function (logger, argv) { return info(logger, pkg, property); }; -info.completion = function () { - // TODO: -}; - module.exports = info; diff --git a/lib/commands/init.js b/lib/commands/init.js index 639263916..47ddc0115 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -325,8 +325,4 @@ init.line = function (logger, argv) { return init(logger, options); }; -init.completion = function () { - // TODO: -}; - module.exports = init; diff --git a/lib/commands/install.js b/lib/commands/install.js index dba8d0494..4299cf796 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -43,8 +43,4 @@ install.options = function (argv) { }, argv); }; -install.completion = function () { - // TODO: -}; - module.exports = install; diff --git a/lib/commands/link.js b/lib/commands/link.js index 6b7bf26cf..2537b3a9e 100644 --- a/lib/commands/link.js +++ b/lib/commands/link.js @@ -80,8 +80,4 @@ link.line = function (logger, argv) { return link(logger, name, localName); }; -link.completion = function () { - // TODO: -}; - module.exports = link; diff --git a/lib/commands/list.js b/lib/commands/list.js index 08244fe08..87d5798fb 100644 --- a/lib/commands/list.js +++ b/lib/commands/list.js @@ -163,8 +163,4 @@ list.options = function (argv) { }, argv); }; -list.completion = function () { - // TODO: -}; - module.exports = list; diff --git a/lib/commands/lookup.js b/lib/commands/lookup.js index 748fece52..3301328ca 100644 --- a/lib/commands/lookup.js +++ b/lib/commands/lookup.js @@ -35,8 +35,4 @@ lookup.line = function (logger, argv) { } }; -lookup.completion = function () { - // TODO: -}; - module.exports = lookup; diff --git a/lib/commands/prune.js b/lib/commands/prune.js index dc9c03347..20c316441 100644 --- a/lib/commands/prune.js +++ b/lib/commands/prune.js @@ -52,8 +52,4 @@ prune.options = function (argv) { }, argv); }; -prune.completion = function () { - // TODO: -}; - module.exports = prune; diff --git a/lib/commands/register.js b/lib/commands/register.js index 5ae64741c..a241fe8cf 100644 --- a/lib/commands/register.js +++ b/lib/commands/register.js @@ -111,8 +111,4 @@ register.line = function (logger, argv) { return register(logger, name, url); }; -register.completion = function () { - // TODO: -}; - module.exports = register; diff --git a/lib/commands/search.js b/lib/commands/search.js index 8fb6e9d67..d6a259eda 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -32,8 +32,4 @@ search.line = function (logger, argv) { return search(logger, name, options); }; -search.completion = function () { - // TODO: -}; - module.exports = search; diff --git a/lib/commands/uninstall.js b/lib/commands/uninstall.js index 324a6e9d6..919550edb 100644 --- a/lib/commands/uninstall.js +++ b/lib/commands/uninstall.js @@ -117,8 +117,4 @@ uninstall.options = function (argv) { }, argv); }; -uninstall.completion = function () { - // TODO: -}; - module.exports = uninstall; diff --git a/lib/commands/update.js b/lib/commands/update.js index f92130310..ce9875dba 100644 --- a/lib/commands/update.js +++ b/lib/commands/update.js @@ -32,8 +32,4 @@ update.options = function (argv) { }, argv); }; -update.completion = function () { - // TODO: -}; - module.exports = update; diff --git a/lib/commands/version.js b/lib/commands/version.js index 419fe3cf4..fbc6f68f1 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -126,8 +126,4 @@ version.options = function (argv) { }, argv); }; -version.completion = function () { - // TODO: -}; - module.exports = version; From 6b53ccc8bd223fbd113a3addd291d075ecf36b06 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 9 Jan 2015 03:18:53 +0100 Subject: [PATCH 0513/1021] Add tests for init command and fix it In non-interactive mode error has been thrown in wrong way. --- lib/commands/init.js | 7 ++--- test/commands/init.js | 66 +++++++++++++++++++++++++++++++------------ 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/lib/commands/init.js b/lib/commands/init.js index 47ddc0115..3b26d8e66 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -18,12 +18,9 @@ function init(logger, config) { // This command requires interactive to be enabled if (!config.interactive) { - process.nextTick(function () { - logger.emit('error', createError('Register requires an interactive shell', 'ENOINT', { - details: 'Note that you can manually force an interactive shell with --config.interactive' - })); + throw createError('Register requires an interactive shell', 'ENOINT', { + details: 'Note that you can manually force an interactive shell with --config.interactive' }); - return logger; } project = new Project(config, logger); diff --git a/test/commands/init.js b/test/commands/init.js index 5e3ebff68..4c153db42 100644 --- a/test/commands/init.js +++ b/test/commands/init.js @@ -1,24 +1,19 @@ -var path = require('path'); var expect = require('expect.js'); -var fs = require('fs'); - var helpers = require('../helpers'); -var bower = helpers.require('lib/index'); -describe('bower init', function () { +var init = helpers.command('init'); - var tempDir = new helpers.TempDir(); - var bowerJsonPath = path.join(tempDir.path, 'bower.json'); +describe('bower init', function () { - var config = { - cwd: tempDir.path, - interactive: true - }; + var package = new helpers.TempDir(); it('generates bower.json file', function () { - tempDir.prepare(); + package.prepare(); - var logger = bower.commands.init(config); + var logger = init({ + cwd: package.path, + interactive: true + }); return helpers.expectEvent(logger, 'prompt') .spread(function (prompt, answer) { @@ -37,14 +32,49 @@ describe('bower init', function () { return helpers.expectEvent(logger, 'prompt'); }) .spread(function (prompt, answer) { - answer({ - prompt: true - }); - + answer({ prompt: true }); return helpers.expectEvent(logger, 'end'); }) .then(function () { - expect(fs.existsSync(bowerJsonPath)).to.be(true); + expect(package.readJson('bower.json')).to.eql({ + name: 'test-name', + version: 'test-version', + homepage: 'test-homepage', + authors: [ 'test-author' ], + description: 'test-description', + moduleType: 'test-moduleType', + keywords: [ 'test-keyword' ], + license: 'test-license' + }); + }); + }); + + it('errors on non-interactive mode', function () { + package.prepare(); + + return helpers.run(init, { cwd: package.path }).then( + function () { throw 'should fail'; }, + function (reason) { + expect(reason.message).to.be('Register requires an interactive shell'); + expect(reason.code).to.be('ENOINT'); + } + ); + }); + + it('warns about existing bower.json', function () { + package.prepare({ + 'bower.json': { + name: 'foobar' + } + }); + + var logger = init({ cwd: package.path, interactive: true }); + + return helpers.expectEvent(logger, 'log').spread(function(event) { + expect(event.level).to.be('warn'); + expect(event.message).to.be( + 'The existing bower.json file will be used and filled in' + ); }); }); }); From e351322ce48b93989856a5cd4fcc05b41555bfce Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 10 Jan 2015 04:47:19 +0100 Subject: [PATCH 0514/1021] More tests for lookup command and little refactor --- lib/commands/lookup.js | 10 ++++----- test/commands/lookup.js | 47 +++++++++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/lib/commands/lookup.js b/lib/commands/lookup.js index 3301328ca..997e94756 100644 --- a/lib/commands/lookup.js +++ b/lib/commands/lookup.js @@ -4,6 +4,10 @@ var cli = require('../util/cli'); var defaultConfig = require('../config'); function lookup(logger, name, config) { + if (!name) { + return new Q(null); + } + var registryClient; config = defaultConfig(config); @@ -28,11 +32,7 @@ lookup.line = function (logger, argv) { var options = cli.readOptions(argv); var name = options.argv.remain[1]; - if (!name) { - return new Q(); - } else { - return lookup(logger, name); - } + return lookup(logger, name); }; module.exports = lookup; diff --git a/test/commands/lookup.js b/test/commands/lookup.js index 132a91ea3..4f003480b 100644 --- a/test/commands/lookup.js +++ b/test/commands/lookup.js @@ -1,23 +1,48 @@ -var Q = require('q'); var expect = require('expect.js'); var helpers = require('../helpers'); describe('bower lookup', function () { + var lookupWithResult = function (response) { + return helpers.command('lookup', { + 'bower-registry-client': function() { + return { + lookup: function(query, callback) { + if (query in response) { + callback(null, response[query]); + } else { + callback(); + } + } + }; + } + }); + }; + it('lookups package by name', function () { - return Q.Promise(function(resolve) { - var lookup = helpers.command('lookup', { - 'bower-registry-client': function() { - return { - lookup: resolve - }; - } + var lookup = lookupWithResult({ jquery: { url: 'http://jquery.org' } }); + + return helpers.run(lookup, ['jquery']).spread(function(result) { + expect(result).to.eql({ + name: 'jquery', + url: 'http://jquery.org' }); + }); + }); - helpers.run(lookup, ['jquery'], {}); - }).then(function (query) { - expect(query).to.be('jquery'); + it('returns null if no package is found', function () { + var lookup = lookupWithResult({ jquery: { url: 'http://jquery.org' } }); + + return helpers.run(lookup, ['foobar']).spread(function(result) { + expect(result).to.eql(null); }); }); + it('returns null if called without argument', function () { + var lookup = lookupWithResult({ jquery: { url: 'http://jquery.org' } }); + + return helpers.run(lookup, []).spread(function(result) { + expect(result).to.eql(null); + }); + }); }); From 5bb77b1e0379be2bcf5fb9e5f0a63236fcb52446 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 10 Jan 2015 05:49:42 +0100 Subject: [PATCH 0515/1021] [refactor] Prepare command argv readers for testing --- lib/commands/cache/clean.js | 7 ++++--- lib/commands/cache/list.js | 7 ++++--- lib/commands/help.js | 7 ++++--- lib/commands/home.js | 6 +++--- lib/commands/index.js | 7 ++++++- lib/commands/info.js | 6 +++--- lib/commands/init.js | 6 ++---- lib/commands/install.js | 12 +++++------- lib/commands/link.js | 7 ++++--- lib/commands/list.js | 12 +++++------- lib/commands/lookup.js | 8 ++++---- lib/commands/prune.js | 18 +++++++++--------- lib/commands/register.js | 7 ++++--- lib/commands/search.js | 7 ++++--- lib/commands/uninstall.js | 24 +++++++++++------------- lib/commands/update.js | 15 +++++++-------- lib/commands/version.js | 12 +++++------- 17 files changed, 84 insertions(+), 84 deletions(-) diff --git a/lib/commands/cache/clean.js b/lib/commands/cache/clean.js index ff190e959..a03826621 100644 --- a/lib/commands/cache/clean.js +++ b/lib/commands/cache/clean.js @@ -6,7 +6,6 @@ var rimraf = require('rimraf'); var endpointParser = require('bower-endpoint-parser'); var PackageRepository = require('../../core/PackageRepository'); var semver = require('../../util/semver'); -var cli = require('../../util/cli'); var defaultConfig = require('../../config'); function clean(logger, endpoints, options, config) { @@ -173,10 +172,12 @@ function clearLinks(names, config, logger) { // ------------------- -clean.line = function (logger, argv) { +clean.readOptions = function (argv) { + var cli = require('../../util/cli'); var options = cli.readOptions(argv); var endpoints = options.argv.remain.slice(2); - return clean(logger, endpoints, options); + + return [endpoints, options]; }; module.exports = clean; diff --git a/lib/commands/cache/list.js b/lib/commands/cache/list.js index 523f13fec..110b668ee 100644 --- a/lib/commands/cache/list.js +++ b/lib/commands/cache/list.js @@ -1,6 +1,5 @@ var mout = require('mout'); var PackageRepository = require('../../core/PackageRepository'); -var cli = require('../../util/cli'); var defaultConfig = require('../../config'); function list(logger, packages, options, config) { @@ -31,10 +30,12 @@ function list(logger, packages, options, config) { // ------------------- -list.line = function (logger, argv) { +list.readOptions = function (argv) { + var cli = require('../../util/cli'); var options = cli.readOptions(argv); var packages = options.argv.remain.slice(2); - return list(logger, packages, options); + + return [packages, options]; }; module.exports = list; diff --git a/lib/commands/help.js b/lib/commands/help.js index 5aa822a15..21d3c9342 100644 --- a/lib/commands/help.js +++ b/lib/commands/help.js @@ -1,7 +1,6 @@ var Q = require('q'); var path = require('path'); var fs = require('graceful-fs'); -var cli = require('../util/cli'); var createError = require('../util/createError'); function help(logger, name) { @@ -29,10 +28,12 @@ function help(logger, name) { // ------------------- -help.line = function (logger, argv) { +help.readOptions = function (argv) { + var cli = require('../util/cli'); var options = cli.readOptions(argv); var name = options.argv.remain.slice(1).join(' '); - return help(logger, name); + + return [name]; }; module.exports = help; diff --git a/lib/commands/home.js b/lib/commands/home.js index e39c61f77..b9323f026 100644 --- a/lib/commands/home.js +++ b/lib/commands/home.js @@ -1,7 +1,6 @@ var Project = require('../core/Project'); var open = require('opn'); var endpointParser = require('bower-endpoint-parser'); -var cli = require('../util/cli'); var createError = require('../util/createError'); var defaultConfig = require('../config'); @@ -48,11 +47,12 @@ function home(logger, name, config) { // ------------------- -home.line = function (logger, argv) { +home.readOptions = function (argv) { + var cli = require('../util/cli'); var options = cli.readOptions(argv); var name = options.argv.remain[1]; - return home(logger, name); + return [name]; }; module.exports = home; diff --git a/lib/commands/index.js b/lib/commands/index.js index 6c9d6baf1..dbdf4b294 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -24,7 +24,12 @@ function commandFactory(id) { function runFromArgv(argv) { return withLogger(function (logger) { - return require(id).line.call(undefined, logger, argv); + var command = require(id); + + var commandArgs = command.readOptions(argv); + commandArgs.unshift(logger); + + return command.apply(undefined, commandArgs); }); } diff --git a/lib/commands/info.js b/lib/commands/info.js index 1654c81b3..8430c71f8 100644 --- a/lib/commands/info.js +++ b/lib/commands/info.js @@ -2,7 +2,6 @@ var mout = require('mout'); var Q = require('q'); var endpointParser = require('bower-endpoint-parser'); var PackageRepository = require('../core/PackageRepository'); -var cli = require('../util/cli'); var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); @@ -57,12 +56,13 @@ function getPkgMeta(repository, decEndpoint, property) { // ------------------- -info.line = function (logger, argv) { +info.readOptions = function (argv) { + var cli = require('../util/cli'); var options = cli.readOptions(argv); var pkg = options.argv.remain[1]; var property = options.argv.remain[2]; - return info(logger, pkg, property); + return [pkg, property]; }; module.exports = info; diff --git a/lib/commands/init.js b/lib/commands/init.js index 3b26d8e66..1116f2667 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -7,7 +7,6 @@ var Project = require('../core/Project'); var defaultConfig = require('../config'); var GitHubResolver = require('../core/resolvers/GitHubResolver'); var GitFsResolver = require('../core/resolvers/GitFsResolver'); -var cli = require('../util/cli'); var cmd = require('../util/cmd'); var createError = require('../util/createError'); @@ -317,9 +316,8 @@ function setDependencies(project, json, answers) { // ------------------- -init.line = function (logger, argv) { - var options = cli.readOptions(argv); - return init(logger, options); +init.readOptions = function (argv) { + return []; }; module.exports = init; diff --git a/lib/commands/install.js b/lib/commands/install.js index 4299cf796..32b4ce714 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -1,6 +1,5 @@ var endpointParser = require('bower-endpoint-parser'); var Project = require('../core/Project'); -var cli = require('../util/cli'); var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); @@ -29,18 +28,17 @@ function install(logger, endpoints, options, config) { // ------------------- -install.line = function (logger, argv) { - var options = install.options(argv); - return install(logger, options.argv.remain.slice(1), options); -}; +install.readOptions = function (argv) { + var cli = require('../util/cli'); -install.options = function (argv) { - return cli.readOptions({ + var options = cli.readOptions({ 'force-latest': { type: Boolean, shorthand: 'F'}, 'production': { type: Boolean, shorthand: 'p' }, 'save': { type: Boolean, shorthand: 'S' }, 'save-dev': { type: Boolean, shorthand: 'D' } }, argv); + + return [options.argv.remain.slice(1), options]; }; module.exports = install; diff --git a/lib/commands/link.js b/lib/commands/link.js index 2537b3a9e..4f189f5a9 100644 --- a/lib/commands/link.js +++ b/lib/commands/link.js @@ -3,7 +3,6 @@ var rimraf = require('rimraf'); var Q = require('q'); var Project = require('../core/Project'); var createLink = require('../util/createLink'); -var cli = require('../util/cli'); var defaultConfig = require('../config'); function link(logger, name, localName, config) { @@ -73,11 +72,13 @@ function linkTo(logger, name, localName, config) { // ------------------- -link.line = function (logger, argv) { +link.readOptions = function (argv) { + var cli = require('../util/cli'); var options = cli.readOptions(argv); var name = options.argv.remain[1]; var localName = options.argv.remain[2]; - return link(logger, name, localName); + + return [name, localName]; }; module.exports = link; diff --git a/lib/commands/list.js b/lib/commands/list.js index 87d5798fb..4022dc5b6 100644 --- a/lib/commands/list.js +++ b/lib/commands/list.js @@ -3,7 +3,6 @@ var mout = require('mout'); var Q = require('q'); var Project = require('../core/Project'); var semver = require('../util/semver'); -var cli = require('../util/cli'); var defaultConfig = require('../config'); function list(logger, options, config) { @@ -151,16 +150,15 @@ function normalize(src) { // ------------------- -list.line = function (logger, argv) { - var options = list.options(argv); - return list(logger, options); -}; +list.readOptions = function (argv) { + var cli = require('../util/cli'); -list.options = function (argv) { - return cli.readOptions({ + var options = cli.readOptions({ 'paths': { type: Boolean, shorthand: 'p' }, 'relative': { type: Boolean, shorthand: 'r' } }, argv); + + return [options]; }; module.exports = list; diff --git a/lib/commands/lookup.js b/lib/commands/lookup.js index 997e94756..94a9d3771 100644 --- a/lib/commands/lookup.js +++ b/lib/commands/lookup.js @@ -1,6 +1,5 @@ var Q = require('q'); var RegistryClient = require('bower-registry-client'); -var cli = require('../util/cli'); var defaultConfig = require('../config'); function lookup(logger, name, config) { @@ -28,11 +27,12 @@ function lookup(logger, name, config) { // ------------------- -lookup.line = function (logger, argv) { - var options = cli.readOptions(argv); +lookup.readOptions = function (argv) { + var cli = require('../util/cli'); + var options = cli.readOptions(argv); var name = options.argv.remain[1]; - return lookup(logger, name); + return [name]; }; module.exports = lookup; diff --git a/lib/commands/prune.js b/lib/commands/prune.js index 20c316441..4487fd902 100644 --- a/lib/commands/prune.js +++ b/lib/commands/prune.js @@ -1,6 +1,5 @@ var mout = require('mout'); var Project = require('../core/Project'); -var cli = require('../util/cli'); var defaultConfig = require('../config'); function prune(logger, options, config) { @@ -41,15 +40,16 @@ function clean(project, options, removed) { // ------------------- -prune.line = function (logger, argv) { - var options = prune.options(argv); - return prune(logger, options); -}; +prune.readOptions = function (argv) { + var cli = require('../util/cli'); + + var options = function (argv) { + return cli.readOptions({ + 'production': { type: Boolean, shorthand: 'p' }, + }, argv); + }; -prune.options = function (argv) { - return cli.readOptions({ - 'production': { type: Boolean, shorthand: 'p' }, - }, argv); + return [options]; }; module.exports = prune; diff --git a/lib/commands/register.js b/lib/commands/register.js index a241fe8cf..5ce2c5a29 100644 --- a/lib/commands/register.js +++ b/lib/commands/register.js @@ -4,7 +4,6 @@ var chalk = require('chalk'); var PackageRepository = require('../core/PackageRepository'); var Config = require('bower-config'); var Tracker = require('../util/analytics').Tracker; -var cli = require('../util/cli'); var createError = require('../util/createError'); var defaultConfig = require('../config'); var GitHubResolver = require('../core/resolvers/GitHubResolver'); @@ -103,12 +102,14 @@ function convertUrl(url, logger) { // ------------------- -register.line = function (logger, argv) { +register.readOptions = function (argv) { + var cli = require('../util/cli'); + var options = cli.readOptions(argv); var name = options.argv.remain[1]; var url = options.argv.remain[2]; - return register(logger, name, url); + return [name, url]; }; module.exports = register; diff --git a/lib/commands/search.js b/lib/commands/search.js index d6a259eda..ad09f3a79 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -1,6 +1,5 @@ var Q = require('q'); var RegistryClient = require('bower-registry-client'); -var cli = require('../util/cli'); var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); @@ -26,10 +25,12 @@ function search(logger, name, config) { // ------------------- -search.line = function (logger, argv) { +search.readOptions = function (argv) { + var cli = require('../util/cli'); var options = cli.readOptions(argv); var name = options.argv.remain.slice(1).join(' '); - return search(logger, name, options); + + return [name, options]; }; module.exports = search; diff --git a/lib/commands/uninstall.js b/lib/commands/uninstall.js index 919550edb..349e0866d 100644 --- a/lib/commands/uninstall.js +++ b/lib/commands/uninstall.js @@ -1,11 +1,14 @@ var mout = require('mout'); var Q = require('q'); var Project = require('../core/Project'); -var cli = require('../util/cli'); var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); function uninstall(logger, names, options, config) { + if (!names.length) { + return new Q(); + } + var project; var tracker; @@ -99,22 +102,17 @@ function clean(project, names, removed) { // ------------------- -uninstall.line = function (logger, argv) { - var options = uninstall.options(argv); - var names = options.argv.remain.slice(1); +uninstall.readOptions = function (argv) { + var cli = require('../util/cli'); - if (!names.length) { - return new Q(); - } else { - return uninstall(logger, names, options); - } -}; - -uninstall.options = function (argv) { - return cli.readOptions({ + var options = cli.readOptions({ 'save': { type: Boolean, shorthand: 'S' }, 'save-dev': { type: Boolean, shorthand: 'D' } }, argv); + + var names = options.argv.remain.slice(1); + + return [names, options]; }; module.exports = uninstall; diff --git a/lib/commands/update.js b/lib/commands/update.js index ce9875dba..78eaf7b71 100644 --- a/lib/commands/update.js +++ b/lib/commands/update.js @@ -1,5 +1,4 @@ var Project = require('../core/Project'); -var cli = require('../util/cli'); var defaultConfig = require('../config'); function update(logger, names, options, config) { @@ -19,17 +18,17 @@ function update(logger, names, options, config) { // ------------------- -update.line = function (logger, argv) { - var options = update.options(argv); - var names = options.argv.remain.slice(1); - return update(logger, names, options); -}; +update.readOptions = function (argv) { + var cli = require('../util/cli'); -update.options = function (argv) { - return cli.readOptions({ + var options = cli.readOptions({ 'force-latest': { type: Boolean, shorthand: 'F' }, 'production': { type: Boolean, shorthand: 'p' } }, argv); + + var names = options.argv.remain.slice(1); + + return [names, options]; }; module.exports = update; diff --git a/lib/commands/version.js b/lib/commands/version.js index fbc6f68f1..80ac3895e 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -5,7 +5,6 @@ var path = require('path'); var Q = require('q'); var execFile = require('child_process').execFile; var Project = require('../core/Project'); -var cli = require('../util/cli'); var defaultConfig = require('../config'); var createError = require('../util/createError'); @@ -115,15 +114,14 @@ function gitCommitAndTag(cwd, newVersion, message) { // ------------------- -version.line = function (logger, argv) { - var options = version.options(argv); - return version(logger, options.argv.remain[1], options); -}; +version.readOptions = function (argv) { + var cli = require('../util/cli'); -version.options = function (argv) { - return cli.readOptions({ + var options = cli.readOptions({ 'message': { type: String, shorthand: 'm'} }, argv); + + return [options.argv.remain[1], options]; }; module.exports = version; From 58a7de3136e32cebd1d7ecdc37c7eefcaaadab2d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 10 Jan 2015 05:53:21 +0100 Subject: [PATCH 0516/1021] Prevent loading cli module in headless mode --- lib/config.js | 23 +++++++++++++---------- lib/util/rootCheck.js | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/config.js b/lib/config.js index 3dfa6c5fe..4c463e108 100644 --- a/lib/config.js +++ b/lib/config.js @@ -1,7 +1,6 @@ var tty = require('tty'); var object = require('mout').object; var bowerConfig = require('bower-config'); -var cli = require('./util/cli'); var cachedConfigs = {}; @@ -34,15 +33,19 @@ function readCachedConfig(cwd) { } // Merge common CLI options into the config - object.mixIn(config, cli.readOptions({ - force: { type: Boolean, shorthand: 'f' }, - offline: { type: Boolean, shorthand: 'o' }, - verbose: { type: Boolean, shorthand: 'V' }, - quiet: { type: Boolean, shorthand: 'q' }, - loglevel: { type: String, shorthand: 'l' }, - json: { type: Boolean, shorthand: 'j' }, - silent: { type: Boolean, shorthand: 's' } - })); + if (process.bin === 'bower') { + var cli = require('./util/cli'); + + object.mixIn(config, cli.readOptions({ + force: { type: Boolean, shorthand: 'f' }, + offline: { type: Boolean, shorthand: 'o' }, + verbose: { type: Boolean, shorthand: 'V' }, + quiet: { type: Boolean, shorthand: 'q' }, + loglevel: { type: String, shorthand: 'l' }, + json: { type: Boolean, shorthand: 'j' }, + silent: { type: Boolean, shorthand: 's' } + })); + } return config; } diff --git a/lib/util/rootCheck.js b/lib/util/rootCheck.js index 9f91b5131..6d0d712a6 100644 --- a/lib/util/rootCheck.js +++ b/lib/util/rootCheck.js @@ -2,7 +2,6 @@ 'use strict'; var isRoot = require('is-root'); var createError = require('./createError'); -var cli = require('./cli'); var renderer; @@ -23,6 +22,7 @@ https://gist.github.com/isaacs/579814\n\n\ You can however run a command with sudo using --allow-root option'; if (isRoot()) { + var cli = require('./cli'); renderer = cli.getRenderer('', false, config); renderer.error(createError('Cannot be run with sudo', 'ESUDO', { details : errorMsg })); process.exit(1); From 0b9acc18cce4f6cf17d234a4b77adac66aa2c0bd Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 10 Jan 2015 12:56:15 +0100 Subject: [PATCH 0517/1021] Test reading commands arguments --- lib/commands/cache/clean.js | 2 ++ lib/commands/cache/list.js | 2 ++ lib/commands/help.js | 2 +- lib/commands/index.js | 1 + lib/commands/install.js | 6 +++- lib/commands/list.js | 2 ++ lib/commands/prune.js | 10 +++---- lib/commands/search.js | 2 +- lib/commands/uninstall.js | 2 ++ lib/commands/update.js | 2 ++ test/commands/cache/clean.js | 5 ++++ test/commands/cache/list.js | 5 ++++ test/commands/help.js | 4 +++ test/commands/home.js | 6 ++++ test/commands/info.js | 5 ++++ test/commands/init.js | 5 ++++ test/commands/install.js | 57 ++++++++++++++++++++---------------- test/commands/link.js | 5 ++++ test/commands/list.js | 16 ++++++++++ test/commands/lookup.js | 7 +++++ test/commands/prune.js | 10 +++++++ test/commands/register.js | 7 +++++ test/commands/search.js | 7 +++++ test/commands/uninstall.js | 22 ++++++++------ test/commands/update.js | 6 ++++ test/helpers.js | 23 +++++++++++++-- 26 files changed, 177 insertions(+), 44 deletions(-) diff --git a/lib/commands/cache/clean.js b/lib/commands/cache/clean.js index a03826621..111ba41e4 100644 --- a/lib/commands/cache/clean.js +++ b/lib/commands/cache/clean.js @@ -177,6 +177,8 @@ clean.readOptions = function (argv) { var options = cli.readOptions(argv); var endpoints = options.argv.remain.slice(2); + delete options.argv; + return [endpoints, options]; }; diff --git a/lib/commands/cache/list.js b/lib/commands/cache/list.js index 110b668ee..f5b2fb3f4 100644 --- a/lib/commands/cache/list.js +++ b/lib/commands/cache/list.js @@ -35,6 +35,8 @@ list.readOptions = function (argv) { var options = cli.readOptions(argv); var packages = options.argv.remain.slice(2); + delete options.argv; + return [packages, options]; }; diff --git a/lib/commands/help.js b/lib/commands/help.js index 21d3c9342..83adfd978 100644 --- a/lib/commands/help.js +++ b/lib/commands/help.js @@ -3,7 +3,7 @@ var path = require('path'); var fs = require('graceful-fs'); var createError = require('../util/createError'); -function help(logger, name) { +function help(logger, name, config) { var json; if (name) { diff --git a/lib/commands/index.js b/lib/commands/index.js index dbdf4b294..045b3abc3 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -49,6 +49,7 @@ function commandFactory(id) { } command.line = runFromArgv; + return command; } diff --git a/lib/commands/install.js b/lib/commands/install.js index 32b4ce714..879fb99be 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -38,7 +38,11 @@ install.readOptions = function (argv) { 'save-dev': { type: Boolean, shorthand: 'D' } }, argv); - return [options.argv.remain.slice(1), options]; + var packages = options.argv.remain.slice(1); + + delete options.argv; + + return [packages, options]; }; module.exports = install; diff --git a/lib/commands/list.js b/lib/commands/list.js index 4022dc5b6..ed68cbd83 100644 --- a/lib/commands/list.js +++ b/lib/commands/list.js @@ -158,6 +158,8 @@ list.readOptions = function (argv) { 'relative': { type: Boolean, shorthand: 'r' } }, argv); + delete options.argv; + return [options]; }; diff --git a/lib/commands/prune.js b/lib/commands/prune.js index 4487fd902..c57bbe484 100644 --- a/lib/commands/prune.js +++ b/lib/commands/prune.js @@ -43,11 +43,11 @@ function clean(project, options, removed) { prune.readOptions = function (argv) { var cli = require('../util/cli'); - var options = function (argv) { - return cli.readOptions({ - 'production': { type: Boolean, shorthand: 'p' }, - }, argv); - }; + var options = cli.readOptions({ + 'production': { type: Boolean, shorthand: 'p' }, + }, argv); + + delete options.argv; return [options]; }; diff --git a/lib/commands/search.js b/lib/commands/search.js index ad09f3a79..58e04c6bb 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -30,7 +30,7 @@ search.readOptions = function (argv) { var options = cli.readOptions(argv); var name = options.argv.remain.slice(1).join(' '); - return [name, options]; + return [name]; }; module.exports = search; diff --git a/lib/commands/uninstall.js b/lib/commands/uninstall.js index 349e0866d..d14854e6d 100644 --- a/lib/commands/uninstall.js +++ b/lib/commands/uninstall.js @@ -112,6 +112,8 @@ uninstall.readOptions = function (argv) { var names = options.argv.remain.slice(1); + delete options.argv; + return [names, options]; }; diff --git a/lib/commands/update.js b/lib/commands/update.js index 78eaf7b71..9d2d65e97 100644 --- a/lib/commands/update.js +++ b/lib/commands/update.js @@ -28,6 +28,8 @@ update.readOptions = function (argv) { var names = options.argv.remain.slice(1); + delete options.argv; + return [names, options]; }; diff --git a/test/commands/cache/clean.js b/test/commands/cache/clean.js index df335a768..658eb47db 100644 --- a/test/commands/cache/clean.js +++ b/test/commands/cache/clean.js @@ -38,6 +38,11 @@ describe('bower cache clean', function () { var cacheDir = new helpers.TempDir(cacheFiles); + it('correctly reads arguments', function() { + expect(cacheClean.readOptions(['jquery', 'angular'])) + .to.eql([['jquery', 'angular'], {}]); + }); + it('removes all cache', function () { cacheDir.prepare(); diff --git a/test/commands/cache/list.js b/test/commands/cache/list.js index 636086640..cea9710e1 100644 --- a/test/commands/cache/list.js +++ b/test/commands/cache/list.js @@ -20,6 +20,11 @@ describe('bower cache list', function () { } }); + it('correctly reads arguments', function() { + expect(cacheList.readOptions(['jquery', 'angular'])) + .to.eql([['jquery', 'angular'], {}]); + }); + it('lists packages from cache', function () { cacheDir.prepare(); diff --git a/test/commands/help.js b/test/commands/help.js index 163116626..dfd7e895f 100644 --- a/test/commands/help.js +++ b/test/commands/help.js @@ -4,6 +4,10 @@ var help = helpers.command('help'); describe('bower help', function () { + it('correctly reads arguments', function() { + expect(help.readOptions(['foo'])).to.eql(['foo']); + }); + it('shows general help', function () { return helpers.run(help).spread(function(result) { expect(result.usage[0]).to.be.a('string'); diff --git a/test/commands/home.js b/test/commands/home.js index 6665fd12a..71af4a3cc 100644 --- a/test/commands/home.js +++ b/test/commands/home.js @@ -2,8 +2,14 @@ var Q = require('q'); var expect = require('expect.js'); var helpers = require('../helpers'); +var home = helpers.command('home'); + describe('bower home', function () { + it('correctly reads arguments', function() { + expect(home.readOptions(['foo'])).to.eql(['foo']); + }); + var package = new helpers.TempDir({ 'bower.json': { name: 'package', diff --git a/test/commands/info.js b/test/commands/info.js index b113ae03d..d69adb4cc 100644 --- a/test/commands/info.js +++ b/test/commands/info.js @@ -5,6 +5,11 @@ var info = helpers.command('info'); describe('bower info', function () { + it('correctly reads arguments', function() { + expect(info.readOptions(['pkg', 'property'])) + .to.eql(['pkg', 'property']); + }); + var meta = { name: 'package', version: '0.1.2', diff --git a/test/commands/init.js b/test/commands/init.js index 4c153db42..fdf905738 100644 --- a/test/commands/init.js +++ b/test/commands/init.js @@ -7,6 +7,11 @@ describe('bower init', function () { var package = new helpers.TempDir(); + it('correctly reads arguments', function() { + expect(init.readOptions([])) + .to.eql([]); + }); + it('generates bower.json file', function () { package.prepare(); diff --git a/test/commands/install.js b/test/commands/install.js index 49386cc4b..a03e3c5ba 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -1,13 +1,34 @@ var expect = require('expect.js'); -var object = require('mout').object; - var helpers = require('../helpers'); -var commands = helpers.require('lib/index').commands; describe('bower install', function () { var tempDir = new helpers.TempDir(); + var install = helpers.command('install', { cwd: tempDir.path }); + + it('correctly reads arguments', function() { + expect(install.readOptions(['jquery', 'angular', '-F', '-p', '-S', '-D'])) + .to.eql([['jquery', 'angular'], { + forceLatest: true, + production: true, + save: true, + saveDev: true + }]); + }); + + it('correctly reads long arguments', function() { + expect(install.readOptions([ + 'jquery', 'angular', + '--force-latest', '--production', '--save', '--save-dev' + ])).to.eql([['jquery', 'angular'], { + forceLatest: true, + production: true, + save: true, + saveDev: true + }]); + }); + var package = new helpers.TempDir({ 'bower.json': { name: 'package' @@ -16,20 +37,6 @@ describe('bower install', function () { var gitPackage = new helpers.TempDir(); - var installLogger = function(packages, options, config) { - config = object.merge(config || {}, { - cwd: tempDir.path - }); - - return commands.install(packages, options, config); - }; - - var install = function(packages, options, config) { - var logger = installLogger(packages, options, config); - - return helpers.expectEvent(logger, 'end'); - }; - it('writes to bower.json if --save flag is used', function () { package.prepare(); @@ -39,7 +46,7 @@ describe('bower install', function () { } }); - return install([package.path], { save: true }).then(function() { + return helpers.run(install, [[package.path], { save: true }]).then(function() { expect(tempDir.read('bower.json')).to.contain('dependencies'); }); }); @@ -57,7 +64,7 @@ describe('bower install', function () { } }); - return install().then(function() { + return helpers.run(install).then(function() { expect(tempDir.read('assets/package/foo')).to.be('bar'); }); }); @@ -79,7 +86,7 @@ describe('bower install', function () { } }); - return install().then(function() { + return helpers.run(install).then(function() { expect(tempDir.read('preinstall.txt')).to.be('package'); }); }); @@ -101,7 +108,7 @@ describe('bower install', function () { } }); - return install().then(function() { + return helpers.run(install).then(function() { expect(tempDir.read('postinstall.txt')).to.be('package'); }); }); @@ -120,7 +127,7 @@ describe('bower install', function () { } }); - return install().then(function() { + return helpers.run(install).then(function() { expect(tempDir.exists('hooks.txt')).to.be(false); }); }); @@ -139,7 +146,7 @@ describe('bower install', function () { } }); - return install([package.path], { save: true }).then(function() { + return helpers.run(install, [[package.path], { save: true }]).then(function() { expect(tempDir.read('hook.txt')).to.contain('dependencies'); }); }); @@ -163,7 +170,7 @@ describe('bower install', function () { var lastAction = null; - installLogger().intercept(function (log) { + helpers.run(install).logger.intercept(function (log) { if (log.level === 'action') { lastAction = log; } @@ -197,7 +204,7 @@ describe('bower install', function () { } }); - return install().then(function() { + return helpers.run(install).then(function() { expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); }); }); diff --git a/test/commands/link.js b/test/commands/link.js index 22e6d243e..f221352eb 100644 --- a/test/commands/link.js +++ b/test/commands/link.js @@ -27,6 +27,11 @@ describe('bower link', function () { linksDir.prepare(); }); + it('correctly reads arguments', function() { + expect(link.readOptions(['jquery', 'angular'])) + .to.eql(['jquery', 'angular']); + }); + it('creates self link', function () { return helpers.run(link, [undefined, undefined, { diff --git a/test/commands/list.js b/test/commands/list.js index 4ef10dd6b..1a85094e8 100644 --- a/test/commands/list.js +++ b/test/commands/list.js @@ -30,6 +30,22 @@ describe('bower list', function () { return helpers.run(commands.list, [options, config]); }; + it('correctly reads arguments', function() { + expect(commands.list.readOptions(['-p', '-r'])) + .to.eql([{ + paths: true, + relative: true + }]); + }); + + it('correctly reads long arguments', function() { + expect(commands.list.readOptions(['--paths', '--relative'])) + .to.eql([{ + paths: true, + relative: true + }]); + }); + it('lists no packages when nothing installed', function () { tempDir.prepare(); diff --git a/test/commands/lookup.js b/test/commands/lookup.js index 4f003480b..3e385f62c 100644 --- a/test/commands/lookup.js +++ b/test/commands/lookup.js @@ -1,6 +1,8 @@ var expect = require('expect.js'); var helpers = require('../helpers'); +var lookup = helpers.command('lookup'); + describe('bower lookup', function () { var lookupWithResult = function (response) { @@ -19,6 +21,11 @@ describe('bower lookup', function () { }); }; + it('correctly reads arguments', function() { + expect(lookup.readOptions(['jquery'])) + .to.eql(['jquery']); + }); + it('lookups package by name', function () { var lookup = lookupWithResult({ jquery: { url: 'http://jquery.org' } }); diff --git a/test/commands/prune.js b/test/commands/prune.js index e99a06270..ee3068d93 100644 --- a/test/commands/prune.js +++ b/test/commands/prune.js @@ -15,6 +15,16 @@ describe('bower home', function () { 'bower_components/jquery/jquery.js': 'jquery source' }); + it('correctly reads arguments', function() { + expect(prune.readOptions(['-p'])) + .to.eql([{ production: true }]); + }); + + it('correctly reads long arguments', function() { + expect(prune.readOptions(['--production'])) + .to.eql([{ production: true }]); + }); + it('removes extraneous packages', function () { package.prepare({ 'bower_components/angular/angular.js': 'angular source', diff --git a/test/commands/register.js b/test/commands/register.js index b0af55265..58c441857 100644 --- a/test/commands/register.js +++ b/test/commands/register.js @@ -2,6 +2,8 @@ var Q = require('q'); var expect = require('expect.js'); var helpers = require('../helpers'); +var register = helpers.command('register'); + var fakeRepositoryFactory = function (canonicalDir, pkgMeta) { function FakeRepository() { } @@ -40,6 +42,11 @@ describe('bower register', function () { } }); + it('correctly reads arguments', function() { + expect(register.readOptions(['jquery', 'url'])) + .to.eql(['jquery', 'url']); + }); + it('errors if name is not provided', function () { return helpers.run(register).fail(function(reason) { expect(reason.message).to.be('Usage: bower register '); diff --git a/test/commands/search.js b/test/commands/search.js index 14a50b709..6a903b876 100644 --- a/test/commands/search.js +++ b/test/commands/search.js @@ -2,8 +2,15 @@ var Q = require('q'); var expect = require('expect.js'); var helpers = require('../helpers'); +var search = helpers.command('search'); + describe('bower search', function () { + it('correctly reads arguments', function() { + expect(search.readOptions(['jquery'])) + .to.eql(['jquery']); + }); + it('searches for single repository', function () { return Q.Promise(function(resolve) { var search = helpers.command('search', { diff --git a/test/commands/uninstall.js b/test/commands/uninstall.js index dd7038d4c..f369b5f59 100644 --- a/test/commands/uninstall.js +++ b/test/commands/uninstall.js @@ -3,7 +3,7 @@ var expect = require('expect.js'); var fs = require('fs'); var helpers = require('../helpers'); -var bower = helpers.require('lib/index'); +var uninstall = helpers.command('uninstall'); describe('bower uninstall', function () { @@ -31,20 +31,24 @@ describe('bower uninstall', function () { interactive: true }; - it('does not remove anything from dependencies by default', function () { - var logger = bower.commands.uninstall(['underscore'], undefined, config); + it('correctly reads arguments', function() { + expect(uninstall.readOptions(['jquery', '-S', '-D'])) + .to.eql([['jquery'], { save: true, saveDev: true }]); + }); + + it('correctly reads long arguments', function() { + expect(uninstall.readOptions(['jquery', '--save', '--save-dev'])) + .to.eql([['jquery'], { save: true, saveDev: true }]); + }); - return helpers.expectEvent(logger, 'end') - .then(function () { + it('does not remove anything from dependencies by default', function () { + return helpers.run(uninstall, [['underscore'], undefined, config]).then(function () { expect(bowerJson().dependencies).to.eql({ 'underscore': '*' }); }); }); it('removes dependency from bower.json if --save flag is used', function () { - var logger = bower.commands.uninstall(['underscore'], {save: true}, config); - - return helpers.expectEvent(logger, 'end') - .then(function () { + return helpers.run(uninstall, [['underscore'], {save: true}, config]).then(function () { expect(bowerJson().dependencies).to.eql({}); }); }); diff --git a/test/commands/update.js b/test/commands/update.js index c72e05bfe..12322033e 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -2,6 +2,7 @@ var expect = require('expect.js'); var object = require('mout').object; var helpers = require('../helpers'); +var updateCmd = helpers.command('update'); var commands = helpers.require('lib/index').commands; describe('bower update', function () { @@ -56,6 +57,11 @@ describe('bower update', function () { return helpers.expectEvent(logger, 'end'); }; + it('correctly reads arguments', function() { + expect(updateCmd.readOptions(['jquery', '-F', '-p'])) + .to.eql([['jquery'], { forceLatest: true, production: true }]); + }); + it('install missing packages', function () { package.prepare(); diff --git a/test/helpers.js b/test/helpers.js index ff09a2ccf..38714967c 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -184,16 +184,27 @@ exports.expectEvent = function expectEvent(emitter, eventName) { }; exports.command = function (command, stubs) { + var rawCommand; var commandStubs = {}; - commandStubs['./' + command] = exports.require( + stubs = stubs || {}; + var cwd = stubs.cwd; + delete stubs.cwd; + + rawCommand = exports.require( 'lib/commands/' + command, stubs ); + commandStubs['./' + command] = function () { + var args = [].slice.call(arguments); + args[rawCommand.length - 1] = object.merge({ cwd: cwd }, args[rawCommand.length - 1] || {}); + return rawCommand.apply(null, args); + }; + var instance = exports.require( 'lib/commands/index', commandStubs ); - + var commandParts = command.split('/'); while (commandParts.length > 0) { @@ -204,6 +215,14 @@ exports.command = function (command, stubs) { throw new Error('Unknown command: ' + command); } + // TODO: refactor tests, so they can use readOptions directly + instance.readOptions = function (argv) { + argv = ['node', 'bower'].concat(argv); + argv = command.split('/').concat(argv); + + return rawCommand.readOptions(argv); + }; + return instance; }; From df71d251f05f574217a3189bbe9e18d56a098fd3 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 10 Jan 2015 16:30:56 +0100 Subject: [PATCH 0518/1021] Disable SVN testing for unsuppoted hosts (e.g. AppVeyor) --- test/core/resolverFactory.js | 5 ++++- test/core/resolvers/svnResolver.js | 4 +++- test/helpers.js | 10 ++++++++++ test/test.js | 8 ++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 7a960bf8a..1c2a5fb08 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -10,6 +10,7 @@ var Logger = require('bower-logger'); var resolverFactory = require('../../lib/core/resolverFactory'); var resolvers = require('../../lib/core/resolvers'); var defaultConfig = require('../../lib/config'); +var helpers = require('../helpers'); describe('resolverFactory', function () { var tempSource; @@ -339,7 +340,9 @@ describe('resolverFactory', function () { .done(); }); - it('should recognize svn remote endpoints correctly', function (next) { + if (!helpers.hasSvn()) + describe.skip('should recognize svn remote endpoints correctly', function() {}); + else it('should recognize svn remote endpoints correctly', function (next) { var promise = Q.resolve(); var endpoints; diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index b431436f5..1c30a6a71 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -9,8 +9,10 @@ var mout = require('mout'); var Logger = require('bower-logger'); var SvnResolver = require('../../../lib/core/resolvers/SvnResolver'); var defaultConfig = require('../../../lib/config'); +var helpers = require('../../helpers'); -describe('SvnResolver', function () { +if (!helpers.hasSvn()) describe.skip('SvnResolver', function() {}); +else describe('SvnResolver', function () { var tempDir = path.resolve(__dirname, '../../tmp/tmp'); var testPackage = path.resolve(__dirname, '../../assets/package-svn/repo'); var testPackageAdmin = path.resolve(__dirname, '../../assets/package-svn/admin'); diff --git a/test/helpers.js b/test/helpers.js index 38714967c..57d23f6e0 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -17,6 +17,7 @@ var object = require('mout/object'); var fs = require('fs'); var glob = require('glob'); var os = require('os'); +var which = require('which'); var proxyquire = require('proxyquire').noCallThru().noPreserveCache(); var cmd = require('../lib/util/cmd'); var config = require('../lib/config'); @@ -269,3 +270,12 @@ exports.capture = function(callback) { throw e; }); }; + +exports.hasSvn = function() { + try { + which.sync('svn'); + return true; + } catch (ex) { + return false; + } +}; diff --git a/test/test.js b/test/test.js index 1000753c2..49c0612f3 100644 --- a/test/test.js +++ b/test/test.js @@ -1,3 +1,11 @@ +var helpers = require('./helpers'); + +if (!helpers.hasSvn()) { + console.warn('#######################################################'); + console.warn('It is recommended you install svn for complete testing!'); + console.warn('#######################################################'); +} + // Cleanup the uncaughtException added by the tmp module // It messes with the mocha uncaughtException event to caught errors // Please note that is the Resolver that calls tmp.setGracefulCleanup() From c7df6f50caf47f2bb0dfd87aad87c494bcc938e3 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 10 Jan 2015 15:57:31 +0100 Subject: [PATCH 0519/1021] Add AppVeyor config for Windows CI --- Gruntfile.js | 2 +- appveyor.yml | 40 ++++++++ lib/renderers/StandardRenderer.js | 2 +- package.json | 2 +- test/commands/install.js | 12 +-- test/commands/list.js | 26 ++++-- test/commands/update.js | 11 ++- test/core/packageRepository.js | 8 +- test/core/resolveCache.js | 4 +- test/core/scripts.js | 18 +++- test/helpers.js | 25 +++-- test/renderers/JsonRenderer.js | 20 ++-- test/renderers/StandardRenderer.js | 145 ++++++++++++++++++++--------- 13 files changed, 228 insertions(+), 87 deletions(-) create mode 100644 appveyor.yml diff --git a/Gruntfile.js b/Gruntfile.js index a6d5b32c1..994fd82ec 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -20,7 +20,7 @@ module.exports = function (grunt) { simplemocha: { options: { reporter: 'spec', - timeout: '5000' + timeout: '8000' }, full: { src: ['test/test.js'] diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 000000000..47259b1a5 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,40 @@ +# Thanks for Grunt for template of this file! + +# http://www.appveyor.com/docs/appveyor-yml + +# Fix line endings in Windows. (runs before repo cloning) +init: + - git config --global core.autocrlf input + +# Test against these versions of Node.js. +environment: + matrix: + - nodejs_version: "0.10" + - nodejs_version: "0.11" + +# Allow failing jobs for bleeding-edge Node.js versions. +matrix: + allow_failures: + - nodejs_version: "0.11" + +# Install scripts. (runs after repo cloning) +install: + # Get the latest stable version of Node 0.STABLE.latest + - ps: Install-Product node $env:nodejs_version + # Install subversion + - choco install svn + # Install bower + - npm install + +# Post-install test scripts. +test_script: + # Output useful info for debugging. + - node --version + - npm --version + - cmd: npm test + +# Don't actually build. +build: off + +# Set build version format here instead of in the admin panel. +version: "{build}" diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index 57c3a1287..a230ef584 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -79,7 +79,7 @@ StandardRenderer.prototype.error = function (err) { /*jshint camelcase:true*/ this._write(process.stderr, str); - console.trace(); + this._write(process.stderr, new Error().stack); // Print bower version, node version and system info. this._write(process.stderr, chalk.yellow('\nSystem info:\n')); diff --git a/package.json b/package.json index db20f131d..0967be780 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "istanbul": "~0.3.5", "load-grunt-tasks": "~2.0.0", "mocha": "~2.1.0", - "multiline": "^1.0.1", + "multiline": "^1.0.2", "nock": "~0.53.0", "node-uuid": "~1.4.2", "proxyquire": "~1.3.0" diff --git a/test/commands/install.js b/test/commands/install.js index a03e3c5ba..096b0a302 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -81,7 +81,7 @@ describe('bower install', function () { }, '.bowerrc': { scripts: { - preinstall: 'bash -c "echo -n % > preinstall.txt"' + preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' } } }); @@ -103,7 +103,7 @@ describe('bower install', function () { }, '.bowerrc': { scripts: { - postinstall: 'bash -c "echo -n % > postinstall.txt"' + postinstall: 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' } } }); @@ -121,8 +121,8 @@ describe('bower install', function () { }, '.bowerrc': { scripts: { - postinstall: 'bash -c "echo -n % > hooks.txt"', - preinstall: 'bash -c "echo -n % > hooks.txt"' + postinstall: 'node -e \'require("fs").writeFileSync("hooks.txt", "%")\'', + preinstall: 'node -e \'require("fs").writeFileSync("hooks.txt", "%")\'' } } }); @@ -141,7 +141,7 @@ describe('bower install', function () { }, '.bowerrc': { scripts: { - postinstall: 'bash -c "cat bower.json > hook.txt"', + postinstall: 'node -e \'var fs = require("fs"); fs.writeFileSync("hook.txt", fs.readFileSync("bower.json"));\'' } } }); @@ -163,7 +163,7 @@ describe('bower install', function () { }, '.bowerrc': { scripts: { - postinstall: 'bash -c "echo foobar"' + postinstall: 'node -e \'process.stdout.write("foobar")\'' } } }); diff --git a/test/commands/list.js b/test/commands/list.js index 1a85094e8..8ce33775b 100644 --- a/test/commands/list.js +++ b/test/commands/list.js @@ -1,5 +1,6 @@ var expect = require('expect.js'); var object = require('mout').object; +var path = require('path'); var helpers = require('../helpers'); @@ -81,7 +82,9 @@ describe('bower list', function () { expect(results.dependencies.package).to.be.an(Object); expect(results.dependencies.package.pkgMeta).to.be.an(Object); expect(results.dependencies.package.pkgMeta.main).to.equal('test.txt'); - expect(results.dependencies.package.canonicalDir).to.equal(tempDir.path + '/bower_components/package'); + expect(results.dependencies.package.canonicalDir).to.equal( + path.join(tempDir.path, 'bower_components/package') + ); expect(results.dependencies.package.dependencies).to.eql({}); expect(results.dependencies.package.nrDependants).to.equal(1); expect(results.dependencies.package.versions).to.eql([]); @@ -112,7 +115,9 @@ describe('bower list', function () { expect(results.pkgMeta.dependencies).to.eql({ package: package.path + '#*' }); - expect(results.dependencies.package.canonicalDir).to.equal('bower_components/package'); + expect(results.dependencies.package.canonicalDir).to.equal( + path.normalize('bower_components/package') + ); }); }); }); @@ -130,7 +135,9 @@ describe('bower list', function () { return install([package.path]).then(function() { return list({paths: true}).spread(function(results) { expect(results).to.be.an(Object); - expect(results.package).to.equal('bower_components/package/test.txt'); + expect(results.package).to.equal( + 'bower_components/package/test.txt' + ); }); }); }); @@ -149,7 +156,10 @@ describe('bower list', function () { return list({paths: true}).spread(function(results) { expect(results).to.be.an(Object); expect(results.package).to.be.an(Object); - expect(results.package).to.eql(['bower_components/package/test.txt', 'bower_components/package/test2.txt']); + expect(results.package).to.eql([ + 'bower_components/package/test.txt', + 'bower_components/package/test2.txt' + ]); }); }); }); @@ -190,7 +200,9 @@ describe('bower list', function () { expect(results.dependencies.package).to.be.an(Object); expect(results.dependencies.package.pkgMeta).to.be.an(Object); expect(results.dependencies.package.pkgMeta.main).to.equal('test.txt'); - expect(results.dependencies.package.canonicalDir).to.equal(tempDir.path + '/bower_components/package'); + expect(results.dependencies.package.canonicalDir).to.equal( + path.join(tempDir.path, 'bower_components/package') + ); expect(results.dependencies.package.dependencies).to.eql({}); expect(results.dependencies.package.nrDependants).to.equal(1); expect(results.dependencies.package.versions).to.eql(['1.0.1', '1.0.0']); @@ -232,7 +244,9 @@ describe('bower list', function () { expect(results.pkgMeta.dependencies).to.eql({ package: gitPackage.path + '#1.0.0' }); - expect(results.dependencies.package.canonicalDir).to.equal('bower_components/package'); + expect(results.dependencies.package.canonicalDir).to.equal( + path.normalize('bower_components/package') + ); }); }); }); diff --git a/test/commands/update.js b/test/commands/update.js index 12322033e..0c12c1e2f 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -92,7 +92,7 @@ describe('bower update', function () { }, '.bowerrc': { scripts: { - preinstall: 'bash -c "echo -n % > preinstall.txt"' + preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' } } }); @@ -114,7 +114,7 @@ describe('bower update', function () { }, '.bowerrc': { scripts: { - postinstall: 'bash -c "echo -n % > postinstall.txt"' + postinstall: 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' } } }); @@ -136,7 +136,7 @@ describe('bower update', function () { }, '.bowerrc': { scripts: { - postinstall: 'bash -c "echo -n % > postinstall.txt"' + postinstall: 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' } } }); @@ -189,7 +189,7 @@ describe('bower update', function () { }, '.bowerrc': { scripts: { - preinstall: 'bash -c "echo -n % > preinstall.txt"' + preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' } } }); @@ -221,7 +221,8 @@ describe('bower update', function () { }, '.bowerrc': { scripts: { - postinstall: 'bash -c "echo -n % > postinstall.txt"' + preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'', + postinstall: 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' } } }); diff --git a/test/core/packageRepository.js b/test/core/packageRepository.js index 210c87855..f0ab5ce91 100644 --- a/test/core/packageRepository.js +++ b/test/core/packageRepository.js @@ -11,6 +11,7 @@ var defaultConfig = require('../../lib/config'); var ResolveCache = require('../../lib/core/ResolveCache'); var resolvers = require('../../lib/core/resolvers'); var copy = require('../../lib/util/copy'); +var helpers = require('../helpers'); describe('PackageRepository', function () { var packageRepository; @@ -21,7 +22,8 @@ describe('PackageRepository', function () { var tempPackage = path.resolve(__dirname, '../tmp/temp-package'); var packagesCacheDir = path.join(__dirname, '../tmp/temp-resolve-cache'); var registryCacheDir = path.join(__dirname, '../tmp/temp-registry-cache'); - var mockSource = 'file://' + testPackage; + var mockSource = helpers.localSource(testPackage); + var forceCaching = true; after(function () { @@ -65,7 +67,7 @@ describe('PackageRepository', function () { return Q.resolve(resolver); } resolverFactory.getConstructor = function () { - return Q.resolve([resolvers.GitRemote, 'file://' + testPackage, false]); + return Q.resolve([resolvers.GitRemote, helpers.localSource(testPackage), false]); }; resolverFactory.clearRuntimeCache = function () { resolverFactoryClearHook(); @@ -182,7 +184,7 @@ describe('PackageRepository', function () { return originalRetrieve.apply(this, arguments); }; - packageRepository.fetch({ name: '', source: testPackage, target: '~0.1.0' }) + packageRepository.fetch({ name: '', source: helpers.localSource(testPackage), target: '~0.1.0' }) .spread(function (canonicalDir, pkgMeta) { expect(called).to.be(false); expect(fs.existsSync(canonicalDir)).to.be(true); diff --git a/test/core/resolveCache.js b/test/core/resolveCache.js index 97ffdfbd4..9ea798ede 100644 --- a/test/core/resolveCache.js +++ b/test/core/resolveCache.js @@ -908,7 +908,6 @@ describe('ResolveCache', function () { expect(entries).to.be.an('array'); expectedJson = fs.readFileSync(path.join(__dirname, '../assets/resolve-cache/list-json-1.json')); - expectedJson = expectedJson.toString().trim(); mout.object.forOwn(entries, function (entry) { // Trim absolute bower path from json @@ -917,8 +916,7 @@ describe('ResolveCache', function () { entry.canonicalDir = entry.canonicalDir.replace(/\\/g, '/'); }); - json = JSON.stringify(entries, null, ' '); - expect(json).to.equal(expectedJson); + expect(entries).to.eql(JSON.parse(expectedJson)); next(); }) diff --git a/test/core/scripts.js b/test/core/scripts.js index a82733113..dfd8306d2 100644 --- a/test/core/scripts.js +++ b/test/core/scripts.js @@ -12,12 +12,22 @@ describe('scripts', function () { var packageName = 'package-zip'; var packageDir = path.join(__dirname, '../assets/' + packageName + '.zip'); + // We cannot use pure touch, because Windows + var touch = function (file) { + return 'node -e "var fs = require(\'fs\'); fs.closeSync(fs.openSync(\'' + file + '\', \'w\'));"'; + }; + + // We cannot use pure touch, because Windows + var touchWithPid = function (file) { + return 'node -e "var fs = require(\'fs\'); fs.closeSync(fs.openSync(process.env.BOWER_PID + \'' + file + '\', \'w\'));"'; + }; + var config = { cwd: tempDir, scripts: { - preinstall: 'touch preinstall_%', - postinstall: 'touch postinstall_%', - preuninstall: 'touch preuninstall_%' + preinstall: touch('preinstall_%'), + postinstall: touch('postinstall_%'), + preuninstall: touch('preuninstall_%') } }; @@ -112,7 +122,7 @@ describe('scripts', function () { it('should process scripts with quotes and vars in the cmd properly.', function (next) { - config.scripts.preinstall = 'touch "$BOWER_PID %"'; + config.scripts.preinstall = touchWithPid(' %'); bower.commands .install([packageDir], undefined, config) diff --git a/test/helpers.js b/test/helpers.js index 57d23f6e0..0fb4627b1 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -1,12 +1,4 @@ -// So CLI output is monochrome in tests -process.env.TERM = 'dumb'; - -// We need to reload supports-color and chalk that caches its result -Object.keys(require.cache).map(function(e) { - if (e.match('supports-color') || e.match('chalk')) { - delete require.cache[e]; - } -}); +require('chalk').enabled = false; var Q = require('q'); var path = require('path'); @@ -18,6 +10,7 @@ var fs = require('fs'); var glob = require('glob'); var os = require('os'); var which = require('which'); +var path = require('path'); var proxyquire = require('proxyquire').noCallThru().noPreserveCache(); var cmd = require('../lib/util/cmd'); var config = require('../lib/config'); @@ -279,3 +272,17 @@ exports.hasSvn = function() { return false; } }; + +exports.isWin = function() { + return process.platform === 'win32'; +}; + +exports.localSource = function (localPath) { + localPath = path.normalize(localPath); + + if (!exports.isWin()) { + localPath = 'file://' + localPath; + } + + return localPath; +}; diff --git a/test/renderers/JsonRenderer.js b/test/renderers/JsonRenderer.js index 0c70a2fcb..0e43ad44d 100644 --- a/test/renderers/JsonRenderer.js +++ b/test/renderers/JsonRenderer.js @@ -10,6 +10,11 @@ var jsonRendererWithPrompt = function (stubs) { }); }; +// When cloning on Windows it's possible carrets are used +var normalize = function (string) { + return string.replace(/\r\n|\r/g, '\n'); +}; + describe('JsonRenderer', function () { it('logs simple message to stderr', function () { @@ -22,12 +27,13 @@ describe('JsonRenderer', function () { renderer.end(); }).spread(function(stdout, stderr) { - expect(stderr).to.eq(multiline(function(){/* + expect(stderr).to.eq(normalize(multiline(function(){/* [{ "id": "foobar", "message": "hello world" }] - */}) + '\n'); + + */}))); }); }); @@ -46,7 +52,7 @@ describe('JsonRenderer', function () { ] }); }).spread(function(stdout, stderr) { - expect(stderr).to.eq(multiline(function(){/* + expect(stderr).to.eq(normalize(multiline(function(){/* [{ "id": "error", "data": { @@ -56,7 +62,8 @@ describe('JsonRenderer', function () { "level": "error", "message": "hello world" }] - */}) + '\n'); + + */}))); }); }); @@ -82,7 +89,7 @@ describe('JsonRenderer', function () { renderer.end(); }); }).spread(function(stdout, stderr) { - expect(stderr).to.eq(multiline(function(){/* + expect(stderr).to.eq(normalize(multiline(function(){/* [{ "type": "input", "name": "field", @@ -90,7 +97,8 @@ describe('JsonRenderer', function () { "default": "something", "level": "prompt" }] - */}) + '\n'); + + */}))); }); }); }); diff --git a/test/renderers/StandardRenderer.js b/test/renderers/StandardRenderer.js index 172139587..058836cff 100644 --- a/test/renderers/StandardRenderer.js +++ b/test/renderers/StandardRenderer.js @@ -19,7 +19,8 @@ describe('StandardRenderer', function () { }).spread(function(stdout, stderr) { expect(stdout).to.eq(multiline(function(){/* bower foobar hello world - */}) + '\n'); + + */})); }); }); @@ -33,7 +34,8 @@ describe('StandardRenderer', function () { }).spread(function(stdout, stderr) { expect(stderr).to.eq(multiline(function(){/* bower EFOOBAR Hello error - */}) + '\n'); + + */})); }); }); @@ -52,7 +54,8 @@ describe('StandardRenderer', function () { Additional error details: Some awesome details Multiline! - */}) + '\n'); + + */})); }); }); @@ -65,12 +68,14 @@ describe('StandardRenderer', function () { details: ' Some awesome details\nMultiline! ' }); }).spread(function(stdout, stderr) { + console.log('asA'); expect(stderr).to.match(new RegExp(multiline(function(){/* System info: - Bower version: [^\n]+ - Node version: [^\n]+ - OS: [^\n]+ - */}) + '\n')); + Bower version: [^\r\n]+ + Node version: [^\r\n]+ + OS: [^\r\n]+ + + */}))); }); }); @@ -107,8 +112,9 @@ describe('StandardRenderer', function () { }).spread(function(stdout, stderr) { expect(stderr).to.match(new RegExp(multiline(function(){/* Console trace: - Trace - at StandardRenderer.error ([^:]+:\d+:\d+) + Error + at StandardRenderer.error \(.+?\) + */}))); }); }); @@ -124,7 +130,8 @@ describe('StandardRenderer', function () { }).spread(function(stdout, stderr) { expect(stdout).to.equal(multiline(function(){/* bower checkout jquery#foobar - */}) + '\n'); + + */})); }); }); @@ -139,7 +146,8 @@ describe('StandardRenderer', function () { }).spread(function(stdout, stderr) { expect(stdout).to.equal(multiline(function(){/* bower jquery#master progress foobar - */}) + '\n'); + + */})); }); }); @@ -154,7 +162,8 @@ describe('StandardRenderer', function () { }).spread(function(stdout, stderr) { expect(stdout).to.equal(multiline(function(){/* bower progress jquery#master foobar - */}) + '\n'); + + */})); }); }); @@ -169,7 +178,8 @@ describe('StandardRenderer', function () { }).spread(function(stdout, stderr) { expect(stdout).to.equal(multiline(function(){/* bower jquery#master extract foobar - */}) + '\n'); + + */})); }); }); @@ -242,7 +252,9 @@ describe('StandardRenderer', function () { jquery2 depends on fizfuz2# Resort to using foobar#~0.1.1 which resolved to foobar#0.1.2 Code incompatibilities may occur. - */}) + '\n\n'); + + + */})); }); }); @@ -307,7 +319,9 @@ describe('StandardRenderer', function () { 2) fizfuz2# and is required by jquery2 Prefix the choice with ! to persist it to bower.json - */}) + '\n\n'); + + + */})); }); }); @@ -334,7 +348,9 @@ describe('StandardRenderer', function () { fuz: 'faz' } } - */}) + '\n\n'); + + + */})); }); }); @@ -349,7 +365,8 @@ describe('StandardRenderer', function () { }).spread(function(stdout, stderr) { expect(stdout).to.equal(multiline(function(){/* bower origin cached message - */}) + '\n'); + + */})); }); }); @@ -378,7 +395,8 @@ describe('StandardRenderer', function () { bower short-origin generic message bower very-very-long-origin-string generic message bower short-origin generic message - */}) + '\n'); + + */})); }); }); @@ -516,28 +534,55 @@ describe('StandardRenderer', function () { } ]); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + if (helpers.isWin()) { + expect(stdout).to.equal(multiline(function(){/* + + jquery#0.1.2 components\jquery + + jquery#0.1.2 components\jquery + + jquery components\jquery not installed + + jquery#0.1.2 components\jquery different + + jquery#0.1.2 components\jquery linked + + jquery#0.1.2 components\jquery incompatible with ~0.1.2 + + jquery#0.1.2 components\jquery extraneous - jquery#0.1.2 components/jquery + jquery#0.1.2 components\jquery (0.1.5 available, latest is 0.2.0) - jquery#0.1.2 components/jquery + jquery#0.1.2 components\jquery + ├── angular#0.1.3 + └── ember#0.2.3 - jquery components/jquery not installed + */})); + } else { + expect(stdout).to.equal(multiline(function(){/* - jquery#0.1.2 components/jquery different + jquery#0.1.2 components/jquery - jquery#0.1.2 components/jquery linked + jquery#0.1.2 components/jquery - jquery#0.1.2 components/jquery incompatible with ~0.1.2 + jquery components/jquery not installed - jquery#0.1.2 components/jquery extraneous + jquery#0.1.2 components/jquery different - jquery#0.1.2 components/jquery (0.1.5 available, latest is 0.2.0) + jquery#0.1.2 components/jquery linked - jquery#0.1.2 components/jquery - ├── angular#0.1.3 - └── ember#0.2.3 - */}) + '\n'); + jquery#0.1.2 components/jquery incompatible with ~0.1.2 + + jquery#0.1.2 components/jquery extraneous + + jquery#0.1.2 components/jquery (0.1.5 available, latest is 0.2.0) + + jquery#0.1.2 components/jquery + ├── angular#0.1.3 + └── ember#0.2.3 + + */})); + } }); }); @@ -554,7 +599,7 @@ describe('StandardRenderer', function () { version: '1.2.3' } - */}) + '\n'); + */})); }); }); @@ -584,7 +629,8 @@ describe('StandardRenderer', function () { - 1.2.1 - 1.2.2 You can request info for a specific version with 'bower info foo#' - */}) + '\n'); + + */})); }); }); @@ -602,7 +648,8 @@ describe('StandardRenderer', function () { expect(stdout).to.equal(multiline(function(){/* bower http://bower.io Package not found. - */}) + '\n'); + + */})); }); }); @@ -623,11 +670,21 @@ describe('StandardRenderer', function () { }] }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* - bower link ./bar > ./foo + if (helpers.isWin()) { + expect(stdout).to.equal(multiline(function(){/* + bower link ./bar > ./foo + + jquery#0.1.2 components\jquery - jquery#0.1.2 components/jquery - */}) + '\n'); + */})); + } else { + expect(stdout).to.equal(multiline(function(){/* + bower link ./bar > ./foo + + jquery#0.1.2 components/jquery + + */})); + } }); }); @@ -650,7 +707,8 @@ describe('StandardRenderer', function () { jquery http://jquery.io bower http://bower.io - */}) + '\n'); + + */})); }); }); @@ -669,7 +727,8 @@ describe('StandardRenderer', function () { To publish a new version, just release a valid semver tag. Run bower info jquery to list the available versions. - */}) + '\n'); + + */})); }); }); @@ -688,7 +747,8 @@ describe('StandardRenderer', function () { }).spread(function(stdout, stderr) { expect(stdout).to.equal(multiline(function(){/* awesome-jquery=jquery#0.1.1 - */}) + '\n'); + + */})); }); }); @@ -735,7 +795,8 @@ describe('StandardRenderer', function () { Description: Uninstalls a package locally from your bower_components directory - */}) + '\n'); + + */})); }); }); }); From de023bc6ea89b8b84eb36d02bdda69d3d3ac34c6 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 11 Jan 2015 03:13:01 +0100 Subject: [PATCH 0520/1021] Update badges --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bdd234d70..199929186 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bower -[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Coverage Status](https://coveralls.io/repos/bower/bower/badge.png?branch=master)](https://coveralls.io/r/bower/bower?branch=master) +[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)] [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) From 7e5bd648855d0f91fd8514fd49565c501b84a9be Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 11 Jan 2015 03:15:33 +0100 Subject: [PATCH 0521/1021] Fix AppVeyor badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 199929186..0c20f1a24 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bower -[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)] [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) +[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) ![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true) [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) From 1e0ef941c7aa6e45b0917bf244fb6fc3d737d002 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 11 Jan 2015 03:24:18 +0100 Subject: [PATCH 0522/1021] Add link to AppVeyor badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0c20f1a24..582368963 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bower -[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) ![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true) [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) +[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)](https://ci.appveyor.com/project/sheerun/bower/history) [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) From 95ce9cbf0c27a10facdef5e5d096c7ee9c28523b Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 11 Jan 2015 03:28:12 +0100 Subject: [PATCH 0523/1021] Remove node@0.11 from Windows builds --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 47259b1a5..b793c7fcb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ init: environment: matrix: - nodejs_version: "0.10" - - nodejs_version: "0.11" + # - nodejs_version: "0.11" # Allow failing jobs for bleeding-edge Node.js versions. matrix: From 639f7939a31bc79dab55ede403732f81951b4356 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 11 Jan 2015 03:33:23 +0100 Subject: [PATCH 0524/1021] Add info about Windows git configuration for testing --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 582368963..58200be65 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,12 @@ review the [guidelines for contributing](CONTRIBUTING.md). * [Pull requests](CONTRIBUTING.md#pull-requests) +Note that on Windows for tests to pass you need to configure Git before cloning: + +``` +git config --global core.autocrlf input +``` + ## Bower Team Bower is made by lots of people across the globe, contributions large and small. Our thanks to everyone who has played a part. From 2f6d680b6c72cdcde66775856e7f29a847cfc03e Mon Sep 17 00:00:00 2001 From: Alexander Gugel Date: Sat, 10 Jan 2015 03:05:29 +0100 Subject: [PATCH 0525/1021] Add --save-exact flag --- lib/commands/install.js | 3 +- lib/core/Project.js | 4 ++ templates/json/help-install.json | 5 +++ test/commands/install.js | 72 ++++++++++++++++++++++++++++++-- 4 files changed, 79 insertions(+), 5 deletions(-) diff --git a/lib/commands/install.js b/lib/commands/install.js index 879fb99be..f934b63e5 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -35,7 +35,8 @@ install.readOptions = function (argv) { 'force-latest': { type: Boolean, shorthand: 'F'}, 'production': { type: Boolean, shorthand: 'p' }, 'save': { type: Boolean, shorthand: 'S' }, - 'save-dev': { type: Boolean, shorthand: 'D' } + 'save-dev': { type: Boolean, shorthand: 'D' }, + 'save-exact': { type: Boolean, shorthand: 'E' } }, argv); var packages = options.argv.remain.slice(1); diff --git a/lib/core/Project.js b/lib/core/Project.js index 32586080f..99ad7cfbf 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -93,6 +93,10 @@ Project.prototype.install = function (decEndpoints, options, config) { jsonEndpoint = endpointParser.decomposed2json(decEndpoint); + if (that._options.saveExact) { + jsonEndpoint[decEndpoint.name] = decEndpoint.pkgMeta.version; + } + if (that._options.save) { that._json.dependencies = mout.object.mixIn(that._json.dependencies || {}, jsonEndpoint); } diff --git a/templates/json/help-install.json b/templates/json/help-install.json index 8e118d259..d150801cd 100644 --- a/templates/json/help-install.json +++ b/templates/json/help-install.json @@ -30,6 +30,11 @@ "shorthand": "-D", "flag": "--save-dev", "description": "Save installed packages into the project's bower.json devDependencies" + }, + { + "shorthand": "-E", + "flag": "--save-exact", + "description": "Configure installed packages with an exact version rather than semver" } ] } diff --git a/test/commands/install.js b/test/commands/install.js index 096b0a302..a09f350ed 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -8,24 +8,26 @@ describe('bower install', function () { var install = helpers.command('install', { cwd: tempDir.path }); it('correctly reads arguments', function() { - expect(install.readOptions(['jquery', 'angular', '-F', '-p', '-S', '-D'])) + expect(install.readOptions(['jquery', 'angular', '-F', '-p', '-S', '-D', '-E'])) .to.eql([['jquery', 'angular'], { forceLatest: true, production: true, save: true, - saveDev: true + saveDev: true, + saveExact: true }]); }); it('correctly reads long arguments', function() { expect(install.readOptions([ 'jquery', 'angular', - '--force-latest', '--production', '--save', '--save-dev' + '--force-latest', '--production', '--save', '--save-dev', '--save-exact' ])).to.eql([['jquery', 'angular'], { forceLatest: true, production: true, save: true, - saveDev: true + saveDev: true, + saveExact: true }]); }); @@ -51,6 +53,68 @@ describe('bower install', function () { }); }); + it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function () { + package.prepare({ + 'bower.json': { + version: '1.2.3' + } + }); + + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); + + return helpers.run(install, [ + [package.path], + { saveExact: true, save: true } + ]).then(function() { + expect(tempDir.readJson('bower.json').dependencies.package).to.equal('1.2.3'); + }); + }); + + it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function () { + package.prepare({ + 'bower.json': { + version: '0.1.0' + } + }); + + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); + + return helpers.run(install, [ + [package.path], + { saveExact: true, saveDev: true } + ]).then(function() { + expect(tempDir.readJson('bower.json').devDependencies.package).to.equal('0.1.0'); + }); + }); + + + it('does not write to bower.json if only --save-exact flag is used', function() { + package.prepare({ + 'bower.json': { + version: '1.2.3' + } + }); + + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); + + return helpers.run(install, [[package.path], { saveExact: true }]).then(function() { + expect(tempDir.read('bower.json')).to.not.contain('dependencies'); + expect(tempDir.read('bower.json')).to.not.contain('devDependencies'); + }); + }); + it('reads .bowerrc from cwd', function () { package.prepare({ foo: 'bar' }); From d7b0db41f4055c8c6d6c250d9ba371d23c5e591c Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 12 Jan 2015 08:27:39 +0800 Subject: [PATCH 0526/1021] bump update-notifier --- bin/bower | 5 +---- package.json | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/bin/bower b/bin/bower index 53e082dda..2768bbd6e 100755 --- a/bin/bower +++ b/bin/bower @@ -133,10 +133,7 @@ analytics.setup(bower.config).then(function () { var updateNotifier = require('update-notifier'); // Check for newer version of Bower - var notifier = updateNotifier({ - packageName: pkg.name, - packageVersion: pkg.version - }); + var notifier = updateNotifier({pkg: pkg}); if (notifier.update && levels.info >= loglevel) { notifier.notify(); diff --git a/package.json b/package.json index 0967be780..1e2ccaabf 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", "tmp": "0.0.24", - "update-notifier": "0.2.2", + "update-notifier": "^0.3.0", "user-home": "^1.1.0", "which": "^1.0.8" }, From 6a96815c44732d65e78d160777fe5ca535b7804d Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 12 Jan 2015 10:04:25 +0800 Subject: [PATCH 0527/1021] bump `insight` --- lib/util/analytics.js | 4 +--- package.json | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/util/analytics.js b/lib/util/analytics.js index d25f103e1..8291c4b8a 100644 --- a/lib/util/analytics.js +++ b/lib/util/analytics.js @@ -22,11 +22,9 @@ var enableAnalytics = false; function ensureInsight () { if (!insight) { var Insight = require('insight'); - var pkg = require('../../package.json'); insight = new Insight({ trackingCode: 'UA-43531210-1', - packageName: pkg.name, - packageVersion: pkg.version + pkg: require('../../package.json') }); } } diff --git a/package.json b/package.json index 1e2ccaabf..e118f155e 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "graceful-fs": "^3.0.5", "handlebars": "^2.0.0", "inquirer": "0.8.0", - "insight": "0.4.3", + "insight": "^0.5.0", "is-root": "^1.0.0", "junk": "^1.0.0", "lockfile": "^1.0.0", From 0ce7053598bf8b79f059c61bdd7afab08497868b Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 12 Jan 2015 10:09:33 +0800 Subject: [PATCH 0528/1021] bump dev deps --- package.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index e118f155e..c56544960 100644 --- a/package.json +++ b/package.json @@ -60,21 +60,21 @@ }, "devDependencies": { "chai": "^1.10.0", - "coveralls": "~2.11.2", - "expect.js": "~0.3.1", - "grunt": "~0.4.5", + "coveralls": "^2.11.2", + "expect.js": "^0.3.1", + "grunt": "^0.4.5", "grunt-cli": "^0.1.13", - "grunt-contrib-jshint": "~0.10.0", - "grunt-contrib-watch": "~0.6.1", - "grunt-exec": "~0.4.6", - "grunt-simple-mocha": "~0.4.0", - "istanbul": "~0.3.5", - "load-grunt-tasks": "~2.0.0", - "mocha": "~2.1.0", + "grunt-contrib-jshint": "^0.10.0", + "grunt-contrib-watch": "^0.6.1", + "grunt-exec": "^0.4.6", + "grunt-simple-mocha": "^0.4.0", + "istanbul": "^0.3.5", + "load-grunt-tasks": "^2.0.0", + "mocha": "^2.1.0", "multiline": "^1.0.2", - "nock": "~0.53.0", - "node-uuid": "~1.4.2", - "proxyquire": "~1.3.0" + "nock": "^0.56.0", + "node-uuid": "^1.4.2", + "proxyquire": "^1.3.0" }, "scripts": { "test": "grunt test" From 8db09d2fede090634c8bfe3ce91d64bf8f9f348d Mon Sep 17 00:00:00 2001 From: Paul Irish Date: Mon, 12 Jan 2015 16:02:05 +0800 Subject: [PATCH 0529/1021] Close #1655 PR: extend mocha timeout to 30s for travis.. --- Gruntfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index 994fd82ec..610bc54ad 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -40,7 +40,7 @@ module.exports = function (grunt) { command: 'node test/packages.js --force && node test/packages-svn.js --force' }, cover: { - command: 'STRICT_REQUIRE=1 node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- -R dot test/test.js' + command: 'STRICT_REQUIRE=1 node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' }, coveralls: { command: 'node node_modules/.bin/coveralls < test/reports/lcov.info' From f458114c5b2edbc7c6ca778c7e849b1349957497 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 10 Jan 2015 15:30:27 +0100 Subject: [PATCH 0530/1021] Enable OSX Travis build --- .travis.yml | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index a910f7a3a..f3b5be67d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,23 @@ -language: node_js -node_js: - - '0.10' - - '0.11' +env: + - NODE_VERSION=0.10 + - NODE_VERSION=0.11 + +install: + - test $TRAVIS_OS_NAME = "osx" && brew install nvm && source $(brew --prefix nvm)/nvm.sh || test $TRAVIS_OS_NAME = "linux" + - nvm install $NODE_VERSION + - node --version + - npm --version + - npm install -g grunt-cli + - npm install + +os: + - osx + - linux + matrix: allow_failures: - - node_js: '0.11' + - os: osx + - env: "NODE_VERSION=0.11" + script: - grunt travis From e203b1aa9a810c692444a10991690b34aa3e9727 Mon Sep 17 00:00:00 2001 From: Jason Sigal Date: Tue, 20 Jan 2015 17:31:41 -0500 Subject: [PATCH 0531/1021] Update License Year to 2015 Happy new year! --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 4d2229da5..cc4f84880 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014 Twitter and other contributors +Copyright (c) 2015 Twitter and other contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in From 16de28994205cd68f3e7285f684dab1fe7cf4859 Mon Sep 17 00:00:00 2001 From: Tomo Masakura Date: Wed, 21 Jan 2015 13:57:28 +0900 Subject: [PATCH 0532/1021] Fix error bower command behind proxy. --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 2b5cc0a17..024f5505a 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -22,7 +22,7 @@ "bower-config": "~0.5.0", "graceful-fs": "~2.0.0", "lru-cache": "~2.3.0", - "request": "~2.27.0", + "request": "~2.51.0", "request-replay": "~0.2.0", "rimraf": "~2.2.0", "mkdirp": "~0.3.5" From 041d3f2843c355ac9850cf5d76d516d29a5f95bf Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 22 Jan 2015 17:23:36 +0800 Subject: [PATCH 0533/1021] minor tweaks --- packages/bower-registry-client/.travis.yml | 5 +---- packages/bower-registry-client/Gruntfile.js | 18 ++++++------------ packages/bower-registry-client/README.md | 14 +++++++------- packages/bower-registry-client/package.json | 12 +++++------- 4 files changed, 19 insertions(+), 30 deletions(-) diff --git a/packages/bower-registry-client/.travis.yml b/packages/bower-registry-client/.travis.yml index 7ab092601..244b7e88e 100644 --- a/packages/bower-registry-client/.travis.yml +++ b/packages/bower-registry-client/.travis.yml @@ -1,6 +1,3 @@ -before_script: - - npm install -g grunt-cli language: node_js node_js: - - "0.10" - - "0.8" + - '0.10' diff --git a/packages/bower-registry-client/Gruntfile.js b/packages/bower-registry-client/Gruntfile.js index 11042a5d4..d7e9d440c 100644 --- a/packages/bower-registry-client/Gruntfile.js +++ b/packages/bower-registry-client/Gruntfile.js @@ -1,14 +1,10 @@ +'use strict'; module.exports = function (grunt) { - - 'use strict'; - grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-simple-mocha'); - // Project configuration. grunt.initConfig({ - jshint: { files: [ 'Gruntfile.js', @@ -19,12 +15,14 @@ module.exports = function (grunt) { jshintrc: '.jshintrc' } }, - simplemocha: { options: { - reporter: 'spec' + reporter: 'spec', + timeout: 20000 + }, + full: { + src: ['test/runner.js'] }, - full: { src: ['test/runner.js'] }, short: { options: { reporter: 'dot' @@ -38,16 +36,12 @@ module.exports = function (grunt) { src: ['test/runner.js'] } }, - - watch: { files: ['<%= jshint.files %>'], tasks: ['jshint', 'simplemocha:short'] } - }); - // Default task. grunt.registerTask('test', ['simplemocha:full']); grunt.registerTask('default', ['jshint', 'test']); }; diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index c043a98a9..32661bfea 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -1,17 +1,18 @@ -# bower-registry-client [![Build Status](https://secure.travis-ci.org/bower/registry-client.png?branch=master)](http://travis-ci.org/bower/registry-client) +# bower-registry-client [![Build Status](https://travis-ci.org/bower/registry-client.png?branch=master)](https://travis-ci.org/bower/registry-client) -This module allows you to easily interact with the Bower registry server API. +> Provides easy interaction with the Bower registry -Install -```sh -npm install --save bower-registry-client +## Install + +``` +$ npm install --save bower-registry-client ``` + ## Usage ```js - var RegistryClient = require('bower-registry-client'); var registry = new RegistryClient(options, logger); ``` @@ -147,7 +148,6 @@ RegistryClient.clearRuntimeCache(); ``` - ## License Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 024f5505a..29d15cf98 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,7 +1,7 @@ { "name": "bower-registry-client", "version": "0.2.2", - "description": "Provides easy interaction with the Bower registry.", + "description": "Provides easy interaction with the Bower registry", "author": "Twitter", "licenses": [ { @@ -9,13 +9,10 @@ "url": "https://github.com/bower/registry-client/blob/master/LICENSE" } ], - "repository": { - "type": "git", - "url": "git://github.com/bower/registry-client.git" - }, + "repository": "bower/registry-client", "main": "Client", "engines": { - "node": ">=0.8.0" + "node": ">=0.10.0" }, "dependencies": { "async": "~0.2.8", @@ -30,8 +27,9 @@ "devDependencies": { "expect.js": "~0.2.0", "grunt": "~0.4.1", - "grunt-contrib-watch": "~0.5.0", + "grunt-cli": "^0.1.13", "grunt-contrib-jshint": "~0.6.0", + "grunt-contrib-watch": "~0.5.0", "grunt-simple-mocha": "~0.4.0", "mocha": "~1.12.0", "nock": "~0.22.0" From a1ec83b002c1ca31ef0f33122908d30b09c00fea Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 22 Jan 2015 17:43:09 +0800 Subject: [PATCH 0534/1021] 0.2.3 --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 29d15cf98..46457cfd2 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.2.2", + "version": "0.2.3", "description": "Provides easy interaction with the Bower registry", "author": "Twitter", "licenses": [ From fd8d603831869a067bd63670a9bc772d19d4bf68 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sun, 8 Feb 2015 20:45:29 +0700 Subject: [PATCH 0535/1021] Update .travis.yml --- packages/bower-registry-client/.travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/bower-registry-client/.travis.yml b/packages/bower-registry-client/.travis.yml index 244b7e88e..dedfc07f2 100644 --- a/packages/bower-registry-client/.travis.yml +++ b/packages/bower-registry-client/.travis.yml @@ -1,3 +1,6 @@ +sudo: false language: node_js node_js: + - 'iojs' + - '0.12' - '0.10' From 463584ea103a4368972b4f5a66ee1b6c351dc441 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sun, 8 Feb 2015 20:46:55 +0700 Subject: [PATCH 0536/1021] Update .travis.yml --- packages/bower-config/.travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/bower-config/.travis.yml b/packages/bower-config/.travis.yml index df63076b8..dedfc07f2 100644 --- a/packages/bower-config/.travis.yml +++ b/packages/bower-config/.travis.yml @@ -1,4 +1,6 @@ +sudo: false language: node_js node_js: - - "0.10" - - "0.8" + - 'iojs' + - '0.12' + - '0.10' From 6f4b77a44093c178a7d2a858a9163b61ab1e0c20 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sun, 8 Feb 2015 20:47:09 +0700 Subject: [PATCH 0537/1021] Update .travis.yml --- packages/bower-logger/.travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/bower-logger/.travis.yml b/packages/bower-logger/.travis.yml index 2ca91f289..dedfc07f2 100644 --- a/packages/bower-logger/.travis.yml +++ b/packages/bower-logger/.travis.yml @@ -1,4 +1,6 @@ +sudo: false language: node_js node_js: - - "0.10" - - "0.8" \ No newline at end of file + - 'iojs' + - '0.12' + - '0.10' From b6dd5e445ebeb307ed2752b73ef6ce294516f044 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sun, 8 Feb 2015 21:12:31 +0700 Subject: [PATCH 0538/1021] minor tweaks --- packages/bower-json/.travis.yml | 9 ++++---- packages/bower-json/package.json | 35 ++++++++++++++++---------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/bower-json/.travis.yml b/packages/bower-json/.travis.yml index 9e6247c3e..dedfc07f2 100644 --- a/packages/bower-json/.travis.yml +++ b/packages/bower-json/.travis.yml @@ -1,7 +1,6 @@ -before_install: - - npm install -g npm - - npm install -g grunt-cli +sudo: false language: node_js node_js: - - "0.10" - - "0.8" + - 'iojs' + - '0.12' + - '0.10' diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 9192cdf93..bd1ac54c9 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,7 +1,7 @@ { "name": "bower-json", "version": "0.4.0", - "description": "Read bower.json files with semantics, normalisation, defaults and validation.", + "description": "Read bower.json files with semantics, normalisation, defaults and validation", "author": "Twitter", "licenses": [ { @@ -9,29 +9,30 @@ "url": "https://github.com/bower/json/blob/master/LICENSE" } ], - "repository": { - "type": "git", - "url": "git://github.com/bower/json.git" - }, + "repository": "bower/json", "main": "lib/json", "engines": { - "node": ">=0.8.0" + "node": ">=0.10.0" }, "dependencies": { - "deep-extend": "~0.2.5", - "graceful-fs": "~3.0.0", - "intersect": "~0.1.0" + "deep-extend": "^0.3.2", + "graceful-fs": "^3.0.0", + "intersect": "^0.1.0" }, "devDependencies": { - "expect.js": "~0.3.1", - "mocha": "~1.20.0", - "grunt": "~0.4.4", - "grunt-contrib-watch": "~0.6.1", - "grunt-contrib-jshint": "~0.10.0", - "grunt-simple-mocha": "~0.4.0", - "underscore.string": "~2.3.3" + "expect.js": "^0.3.1", + "grunt": "^0.4.4", + "grunt-cli": "^0.1.13", + "grunt-contrib-jshint": "^0.10.0", + "grunt-contrib-watch": "^0.6.1", + "grunt-simple-mocha": "^0.4.0", + "mocha": "*", + "underscore.string": "^2.3.3" }, "scripts": { "test": "grunt test" - } + }, + "files": [ + "lib" + ] } From 7a26bf1a101991ca2a60eaa873f1cd5d53f7877c Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 23 Feb 2015 15:07:56 +0700 Subject: [PATCH 0539/1021] bump `chalk` https://github.com/sindresorhus/chalk/releases/tag/v1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c56544960..81688b967 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "bower-logger": "^0.2.2", "bower-registry-client": "^0.2.1", "cardinal": "0.4.4", - "chalk": "0.5.1", + "chalk": "^1.0.0", "chmodr": "0.1.0", "decompress-zip": "^0.1.0", "fstream": "^1.0.3", From b6e33d70c864f088379e7896c474ed559ac885da Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sun, 1 Mar 2015 02:58:15 +0800 Subject: [PATCH 0540/1021] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 58200be65..aca4bc624 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,6 @@ Bower is made by lots of people across the globe, contributions large and small. * [@wibblymat](https://github.com/wibblymat) * [@paulirish](https://github.com/paulirish) * [@benschwarz](https://github.com/benschwarz) -* [@sindresorhus](https://github.com/sindresorhus) * [@svnlto](https://github.com/svnlto) * [@sheerun](https://github.com/sheerun) From 61a68a9e38fd0ed1ca17f153d88dabee7d3c7fad Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 28 Feb 2015 19:37:50 -0800 Subject: [PATCH 0541/1021] test: Replace dejavu repo with pure (dejavu moved) --- test/core/resolverFactory.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 1c2a5fb08..ed3c9e946 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -31,7 +31,7 @@ describe('resolverFactory', function () { }); after(function (next) { - rimraf('dejavu', next); + rimraf('pure', next); }); function callFactory(decEndpoint, config) { @@ -527,31 +527,31 @@ describe('resolverFactory', function () { }); it('should recognize registry endpoints correctly', function (next) { - // Create a 'dejavu' file at the root to prevent regressions of #666 - fs.writeFileSync('dejavu', 'foo'); + // Create a 'pure' file at the root to prevent regressions of #666 + fs.writeFileSync('pure', 'foo'); - callFactory({ source: 'dejavu' }) + callFactory({ source: 'pure' }) .then(function (resolver) { expect(resolver).to.be.a(resolvers.GitRemote); - expect(resolver.getSource()).to.equal('git://github.com/IndigoUnited/dejavu.git'); + expect(resolver.getSource()).to.equal('git://github.com/yui/pure-release.git'); expect(resolver.getTarget()).to.equal('*'); }) .then(function () { // Test with name - return callFactory({ source: 'dejavu', name: 'foo' }) + return callFactory({ source: 'pure', name: 'foo' }) .then(function (resolver) { expect(resolver).to.be.a(resolvers.GitRemote); - expect(resolver.getSource()).to.equal('git://github.com/IndigoUnited/dejavu.git'); + expect(resolver.getSource()).to.equal('git://github.com/yui/pure-release.git'); expect(resolver.getName()).to.equal('foo'); expect(resolver.getTarget()).to.equal('*'); }); }) .then(function () { // Test with target - return callFactory({ source: 'dejavu', target: '~2.0.0' }) + return callFactory({ source: 'pure', target: '~0.4.0' }) .then(function (resolver) { expect(resolver).to.be.a(resolvers.GitRemote); - expect(resolver.getTarget()).to.equal('~2.0.0'); + expect(resolver.getTarget()).to.equal('~0.4.0'); next(); }); @@ -574,7 +574,7 @@ describe('resolverFactory', function () { }); it('should set registry to true on the decomposed endpoint if fetched from the registry', function (next) { - var decEndpoint = { source: 'dejavu' }; + var decEndpoint = { source: 'pure' }; callFactory(decEndpoint) .then(function () { From 182d92f9bd9a719cbe0aa525c1e7e1ec29874389 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 28 Feb 2015 19:57:50 -0800 Subject: [PATCH 0542/1021] test: Fix SvnResolver tests on all platforms --- .travis.yml | 2 ++ Gruntfile.js | 2 +- lib/core/resolvers/SvnResolver.js | 11 +++++---- lib/util/cmd.js | 2 +- test/core/resolvers/svnResolver.js | 8 +++---- test/helpers.js | 13 ++++++++++ test/packages-svn.js | 38 ++++++++++++++++++++++++------ test/renderers/StandardRenderer.js | 1 - 8 files changed, 58 insertions(+), 19 deletions(-) diff --git a/.travis.yml b/.travis.yml index f3b5be67d..180e0395a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,8 @@ install: - nvm install $NODE_VERSION - node --version - npm --version + - git --version + - svn --version | head -n 1 - npm install -g grunt-cli - npm install diff --git a/Gruntfile.js b/Gruntfile.js index 610bc54ad..7aa80376e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -20,7 +20,7 @@ module.exports = function (grunt) { simplemocha: { options: { reporter: 'spec', - timeout: '8000' + timeout: '10000' }, full: { src: ['test/test.js'] diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js index 866fad789..c2be641a2 100644 --- a/lib/core/resolvers/SvnResolver.js +++ b/lib/core/resolvers/SvnResolver.js @@ -3,6 +3,7 @@ var Q = require('q'); var which = require('which'); var LRU = require('lru-cache'); var mout = require('mout'); +var path = require('path'); var Resolver = require('./Resolver'); var semver = require('../../util/semver'); var createError = require('../../util/createError'); @@ -86,13 +87,13 @@ SvnResolver.prototype._export = function () { }); if (resolution.type === 'commit') { - promise = cmd('svn', ['export', '--force', this._source + '/trunk', '-r' + resolution.commit, this._tempDir]); + promise = cmd('svn', ['export', '--force', this._source + path.normalize('/trunk'), '-r' + resolution.commit, this._tempDir]); } else if (resolution.type === 'branch' && resolution.branch === 'trunk') { - promise = cmd('svn', ['export', '--force', this._source + '/trunk', this._tempDir]); + promise = cmd('svn', ['export', '--force', this._source + path.normalize('/trunk'), this._tempDir]); } else if (resolution.type === 'branch') { - promise = cmd('svn', ['export', '--force', this._source + '/branches/' + resolution.branch, this._tempDir]); + promise = cmd('svn', ['export', '--force', this._source + path.normalize('/branches/' + resolution.branch), this._tempDir]); } else { - promise = cmd('svn', ['export', '--force', this._source + '/tags/' + resolution.tag, this._tempDir]); + promise = cmd('svn', ['export', '--force', this._source + path.normalize('/tags/' + resolution.tag), this._tempDir]); } // Throttle the progress reporter to 1 time each sec @@ -324,7 +325,7 @@ SvnResolver.tags = function (source) { return Q.resolve(value); } - value = cmd('svn', ['list', source + '/tags', '--verbose']) + value = cmd('svn', ['list', source + path.normalize('/tags'), '--verbose']) .spread(function (stout) { var tags = SvnResolver.parseSubversionListOutput(stout.toString()); diff --git a/lib/util/cmd.js b/lib/util/cmd.js index aa59fad39..f2894999e 100644 --- a/lib/util/cmd.js +++ b/lib/util/cmd.js @@ -99,7 +99,7 @@ function executeCmd(command, args, options) { fullCommand += args.length ? ' ' + args.join(' ') : ''; // Build the error instance - error = createError('Failed to execute "' + fullCommand + '", exit code of #' + code, 'ECMDERR', { + error = createError('Failed to execute "' + fullCommand + '", exit code of #' + code + '\n' + stderr, 'ECMDERR', { details: stderr, exitCode: code }); diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index 1c30a6a71..47a8a5a37 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -15,7 +15,7 @@ if (!helpers.hasSvn()) describe.skip('SvnResolver', function() {}); else describe('SvnResolver', function () { var tempDir = path.resolve(__dirname, '../../tmp/tmp'); var testPackage = path.resolve(__dirname, '../../assets/package-svn/repo'); - var testPackageAdmin = path.resolve(__dirname, '../../assets/package-svn/admin'); + // var testPackageAdmin = path.resolve(__dirname, '../../assets/package-svn/admin'); var originaltags = SvnResolver.tags; var logger; @@ -1002,7 +1002,7 @@ else describe('SvnResolver', function () { it('should guess the name from the path', function () { var resolver; - resolver = create('file://' + testPackage); + resolver = create(helpers.localSource(testPackage)); expect(resolver.getName()).to.equal('repo'); resolver = create('svn+http://yii.googlecode.com/svn'); @@ -1013,7 +1013,7 @@ else describe('SvnResolver', function () { describe('.resolve', function () { it('should export correctly if resolution is a tag', function (next) { - var resolver = create({ source: 'file://' + testPackageAdmin, target: '0.0.1' }); + var resolver = create({ source: testPackage, target: '0.0.1' }); resolver.resolve() .then(function (dir) { @@ -1029,7 +1029,7 @@ else describe('SvnResolver', function () { }); it('should export correctly if resolution is a commit', function (next) { - var resolver = create({ source: 'file://' + testPackageAdmin, target: 'r1' }); + var resolver = create({ source: testPackage, target: 'r1' }); resolver.resolve() .then(function (dir) { diff --git a/test/helpers.js b/test/helpers.js index 0fb4627b1..e613933bb 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -286,3 +286,16 @@ exports.localSource = function (localPath) { return localPath; }; + +// Used for example by "svn checkout" and "svn export" +exports.localUrl = function (localPath) { + localPath = path.normalize(localPath); + + if (!exports.isWin()) { + localPath = 'file://' + localPath; + } else { + localPath = 'file:///' + localPath; + } + + return localPath; +}; diff --git a/test/packages-svn.js b/test/packages-svn.js index a862aab9c..295ed645f 100644 --- a/test/packages-svn.js +++ b/test/packages-svn.js @@ -10,6 +10,23 @@ var cmd = require('../lib/util/cmd'); var packages = require('./packages-svn.json'); var nopt = require('nopt'); +var isWin = function() { + return process.platform === 'win32'; +}; + +var pathToUrl = function (localPath) { + localPath = path.normalize(localPath); + + if (!isWin()) { + localPath = 'file://' + localPath; + } else { + localPath = 'file:///' + localPath; + } + + return localPath; +}; + + var options = nopt({ 'force': Boolean }, { @@ -22,15 +39,22 @@ var env = {}; mout.object.mixIn(env, process.env); function ensurePackage(admin, dir) { - var promise; + var promise = new Q(); // If force is specified, delete folder if (options.force) { - promise = Q.nfcall(rimraf, dir) - .then(function () { + promise = promise.then(function () { + return Q.nfcall(rimraf, admin); + }); + + promise = promise.then(function () { + return Q.nfcall(rimraf, dir); + }); + + promise = promise.then(function () { throw new Error(); }); - // Otherwise check if .svn is already created + // Otherwise check if .git is already created } else { promise = Q.nfcall(fs.stat, path.join(dir, '.svn')); } @@ -40,9 +64,9 @@ function ensurePackage(admin, dir) { // Create dir return Q.nfcall(mkdirp, dir) // Init svn repo - .then(cmd.bind(null, 'svnadmin', ['create', admin])) + .then(cmd.bind(null, 'svnadmin', ['create', admin], {})) // checkout the repo - .then(cmd.bind(null, 'svn', ['checkout', 'file://' + admin, dir])) + .then(cmd.bind(null, 'svn', ['checkout', pathToUrl(admin), dir], {})) // create directory structure .then(cmd.bind(null, 'svn', ['mkdir', 'trunk'], { cwd: dir })) .then(cmd.bind(null, 'svn', ['mkdir', 'tags'], { cwd: dir })) @@ -81,7 +105,7 @@ function checkRelease(dir, release) { function createRelease(admin, dir, release, files) { // checkout the repo - return cmd('svn', ['checkout', 'file://' + admin, dir]) + return cmd('svn', ['checkout', pathToUrl(admin), dir]) // Attempt to delete branch, ignoring the error .then(function () { return cmd('svn', ['delete', dir + '/branches/' + release], { cwd: dir }) diff --git a/test/renderers/StandardRenderer.js b/test/renderers/StandardRenderer.js index 058836cff..31bfe290f 100644 --- a/test/renderers/StandardRenderer.js +++ b/test/renderers/StandardRenderer.js @@ -68,7 +68,6 @@ describe('StandardRenderer', function () { details: ' Some awesome details\nMultiline! ' }); }).spread(function(stdout, stderr) { - console.log('asA'); expect(stderr).to.match(new RegExp(multiline(function(){/* System info: Bower version: [^\r\n]+ From 61bb4f53c0739318379a92bd70fbdd013b52e6f5 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 4 Mar 2015 22:25:24 -0800 Subject: [PATCH 0543/1021] Increase timeout for test --- packages/bower-registry-client/test/Client.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 63ce875a0..ed3b31820 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -197,6 +197,7 @@ describe('RegistryClient', function () { describe('calling the lookup instance method without argument', function () { it('should return no result', function (next) { + this.timeout(10000); this.registry.lookup('', function (err, entry) { expect(err).to.not.be.ok(); expect(entry).to.not.be.ok(); From 009e5ce0c872a72eb5548a2a933eed350eba3978 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 4 Mar 2015 22:25:35 -0800 Subject: [PATCH 0544/1021] Better error messages for unregistering --- packages/bower-registry-client/lib/unregister.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-registry-client/lib/unregister.js b/packages/bower-registry-client/lib/unregister.js index 9d4930476..0955c2b29 100644 --- a/packages/bower-registry-client/lib/unregister.js +++ b/packages/bower-registry-client/lib/unregister.js @@ -31,12 +31,12 @@ function unregister(name, callback) { // Forbidden if (response.statusCode === 403) { - return callback(createError('Not authorized', 'EFORBIDDEN')); + return callback(createError(response.body, 'EFORBIDDEN')); } // Everything other than 204 is unknown if (response.statusCode !== 204) { - return callback(createError('Unknown error: ' + response.statusCode + ', ' + response.body, 'EUNKNOWN')); + return callback(createError(response.body, 'EUNKNOWN')); } callback(null, { From c93bbbd302b92f976f331cd323daa136a8267ad3 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 4 Mar 2015 22:38:12 -0800 Subject: [PATCH 0545/1021] Bump to 0.2.4 --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 46457cfd2..fa0af173a 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.2.3", + "version": "0.2.4", "description": "Provides easy interaction with the Bower registry", "author": "Twitter", "licenses": [ From 260b4adb8c135e6f4cf8f40cd827f040250eb610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dar=C3=ADo=20Here=C3=B1=C3=BA?= Date: Fri, 6 Mar 2015 14:30:00 -0300 Subject: [PATCH 0546/1021] Update year of copyright --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aca4bc624..6434c8bc5 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,6 @@ Bower is made by lots of people across the globe, contributions large and small. ## License -Copyright (c) 2014 Twitter and other contributors +Copyright (c) 2015 Twitter and other contributors Licensed under the MIT License From 9aef3b7f1d56427245939f5fc7bf41a5a3bf696e Mon Sep 17 00:00:00 2001 From: Marcus Zanona Date: Wed, 11 Mar 2015 09:45:48 +0000 Subject: [PATCH 0547/1021] Allow NPM config variables. Resolve bower/bower#1711 --- packages/bower-config/lib/util/rc.js | 1 + packages/bower-config/test/test.js | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 8ab86c1be..76a86e516 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -29,6 +29,7 @@ function rc(name, defaults, cwd, argv) { !home ? {} : json(path.join(home, '.' + name + 'rc')), json(path.join(paths.config, name + 'rc')), json(find('.' + name + 'rc', cwd)), + env('npm_package_config_' + name + '_'), env(name + '_'), argvConfig ]); diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index e69de29bb..0c929c507 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -0,0 +1,18 @@ +var assert = require('assert'); + +describe('NPM Config on package.json', function () { + describe('Setting process.env.npm_package_config', function () { + /*jshint camelcase:false*/ + process.env.npm_package_config_bower_directory = 'npm-path'; + process.env.npm_package_config_bower_colors = false; + + var config = require('../lib/Config').create().load()._config; + + it('should return "npm-path" for "bower_directory"', function () { + assert.equal('npm-path', config.directory); + }); + it('should return "false" for "bower_colors"', function () { + assert.equal('false', config.colors); + }); + }); +}); From 7d748ae15e2b6e5f0ad810224735113a55c85456 Mon Sep 17 00:00:00 2001 From: Amine Mouafik Date: Fri, 13 Mar 2015 11:41:36 +0700 Subject: [PATCH 0548/1021] Fix broken link to npm completion doc --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6434c8bc5..e86569482 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ Bower can be configured using JSON in a `.bowerrc` file. Read over available opt _NOTE_: Completion is still not implemented for the 1.0.0 release Bower now has an experimental `completion` command that is based on, and works -similarly to the [npm completion](https://npmjs.org/doc/completion.html). It is +similarly to the [npm completion](https://npmjs.org/doc/cli/completion.html). It is not available for Windows users. This command will output a Bash / ZSH script to put into your `~/.bashrc`, From 4ad5ed64d79e6780ad90c30ba961215ffd332233 Mon Sep 17 00:00:00 2001 From: Nils Winkler Date: Fri, 12 Dec 2014 08:40:25 +0100 Subject: [PATCH 0549/1021] Automatically detecting _smart Git hosts_. Added logic to automatically detect smart Git hosts that allow shallow cloning. This is done by sending an `ls-remote` request to the server and then evaluating the returned HTTP header fields. For this, Curl verbose logging is enabled for the `ls-remote` request, since Curl verbose logging sends the returned HTTP headers to `stderr`. If the `stderr` output contains the desired header Content-Type: application/x-git-upload-pack-advertisement then the server supports shallow cloning. This approach uses Git and Curl for the heavy lifting. Instead of implementing the request to the server using a simple HTTP client, Git is used, since it takes care of authentication using stored credentials. The used approach should also work for BitBucket, which only sends the Content-Type header when a specific user agent is used. Using Git to make the request enables this behavior. The function to detect the smart Git host (`GitRemoteResolver.prototype._supportsShallowCloning`) returns a promise that is resolved when the server's request is evaluated. The promise handling required an addition to `GitHubResolver.js` - to always resolve the promise to `true`, since GitHub supports shallow cloning. Added test cases to verify the new functionality. --- lib/core/resolvers/GitHubResolver.js | 3 +- lib/core/resolvers/GitRemoteResolver.js | 107 ++++++++++---- test/core/resolvers/gitRemoteResolver.js | 172 +++++++++++++++++++++++ 3 files changed, 254 insertions(+), 28 deletions(-) diff --git a/lib/core/resolvers/GitHubResolver.js b/lib/core/resolvers/GitHubResolver.js index 8b3463931..e8f02d7cf 100644 --- a/lib/core/resolvers/GitHubResolver.js +++ b/lib/core/resolvers/GitHubResolver.js @@ -1,6 +1,7 @@ var util = require('util'); var path = require('path'); var mout = require('mout'); +var Q = require('q'); var GitRemoteResolver = require('./GitRemoteResolver'); var download = require('../../util/download'); var extract = require('../../util/extract'); @@ -37,7 +38,7 @@ function GitHubResolver(decEndpoint, config, logger) { } // Enable shallow clones for GitHub repos - this._shallowClone = true; + this._shallowClone = Q.resolve(true); } util.inherits(GitHubResolver, GitRemoteResolver); diff --git a/lib/core/resolvers/GitRemoteResolver.js b/lib/core/resolvers/GitRemoteResolver.js index 3223c89b3..fa8766736 100644 --- a/lib/core/resolvers/GitRemoteResolver.js +++ b/lib/core/resolvers/GitRemoteResolver.js @@ -26,8 +26,10 @@ function GitRemoteResolver(decEndpoint, config, logger) { this._host = url.parse(this._source).host; } - // Disable shallow clones - this._shallowClone = false; + this._remote = url.parse(this._source); + + // Verify whether the server supports shallow cloning + this._shallowClone = this._supportsShallowCloning(); } util.inherits(GitRemoteResolver, GitResolver); @@ -115,34 +117,36 @@ GitRemoteResolver.prototype._fastClone = function (resolution) { branch = resolution.tag || resolution.branch; args = ['clone', this._source, '-b', branch, '--progress', '.']; - // If the host does not support shallow clones, we don't use --depth=1 - if (this._shallowClone && !GitRemoteResolver._noShallow.get(this._host)) { - args.push('--depth', 1); - } - - return cmd('git', args, { cwd: this._tempDir }) - .spread(function (stdout, stderr) { - // Only after 1.7.10 --branch accepts tags - // Detect those cases and inform the user to update git otherwise it's - // a lot slower than newer versions - if (!/branch .+? not found/i.test(stderr)) { - return; + return this._shallowClone.then(function (shallowCloningSupported) { + // If the host does not support shallow clones, we don't use --depth=1 + if (shallowCloningSupported && !GitRemoteResolver._noShallow.get(this._host)) { + args.push('--depth', 1); } - that._logger.warn('old-git', 'It seems you are using an old version of git, it will be slower and propitious to errors!'); - return cmd('git', ['checkout', resolution.commit], { cwd: that._tempDir }); - }, function (err) { - // Some git servers do not support shallow clones - // When that happens, we mark this host and try again - if (!GitRemoteResolver._noShallow.has(that._source) && - err.details && - /(rpc failed|shallow|--depth)/i.test(err.details) - ) { - GitRemoteResolver._noShallow.set(that._host, true); - return that._fastClone(resolution); - } + return cmd('git', args, { cwd: that._tempDir }) + .spread(function (stdout, stderr) { + // Only after 1.7.10 --branch accepts tags + // Detect those cases and inform the user to update git otherwise it's + // a lot slower than newer versions + if (!/branch .+? not found/i.test(stderr)) { + return; + } - throw err; + that._logger.warn('old-git', 'It seems you are using an old version of git, it will be slower and propitious to errors!'); + return cmd('git', ['checkout', resolution.commit], { cwd: that._tempDir }); + }, function (err) { + // Some git servers do not support shallow clones + // When that happens, we mark this host and try again + if (!GitRemoteResolver._noShallow.has(that._source) && + err.details && + /(rpc failed|shallow|--depth)/i.test(err.details) + ) { + GitRemoteResolver._noShallow.set(that._host, true); + return that._fastClone(resolution); + } + + throw err; + }); }); }; @@ -160,6 +164,55 @@ GitRemoteResolver.prototype._suggestProxyWorkaround = function (err) { } }; +// Verifies whether the server supports shallow cloning. +// This is done according to the rules found in the following links: +// * https://github.com/dimitri/el-get/pull/1921/files +// * http://stackoverflow.com/questions/9270488/is-it-possible-to-detect-whether-a-http-git-remote-is-smart-or-dumb +// +// Summary of the rules: +// * Protocols like ssh or git always support shallow cloning +// * HTTP-based protocols can be verified by sending a HEAD or GET request to the URI (appended to the URL of the Git repo): +// /info/refs?service=git-upload-pack +// * If the server responds with a 'Content-Type' header of 'application/x-git-upload-pack-advertisement', +// the server supports shallow cloning ("smart server") +// * If the server responds with a different content type, the server does not support shallow cloning ("dumb server") +// * Instead of doing the HEAD or GET request using an HTTP client, we're letting Git and Curl do the heavy lifting. +// Calling Git with the GIT_CURL_VERBOSE=2 env variable will provide the Git and Curl output, which includes +// the content type. This has the advantage that Git will take care of using stored credentials and any additional +// negotiation that needs to take place. +// +// The above should cover most cases, including BitBucket. +GitRemoteResolver.prototype._supportsShallowCloning = function () { + var value = true; + + if (mout.string.startsWith(this._remote.protocol, 'http')) { + // Provide GIT_CURL_VERBOSE=2 environment variable to capture curl output. + // Calling ls-remote includes a call to the git-upload-pack service, which returns the content type in the response. + var processEnv = mout.object.merge(process.env, { 'GIT_CURL_VERBOSE': 2 }); + + value = cmd('git', ['ls-remote', '--heads', this._source], { + env: processEnv + }) + .spread(function (stdout, stderr) { + // Check stderr for content-type, ignore stdout + var isSmartServer; + + // If the content type is 'x-git', then the server supports shallow cloning + isSmartServer = mout.string.contains(stderr, + 'Content-Type: application/x-git-upload-pack-advertisement'); + + this._logger.debug('detect-smart-git', 'Smart Git host detected: ' + isSmartServer); + + return isSmartServer; + }.bind(this)); + } + else { + return Q.resolve(true); + } + + return value; +}; + // ------------------------------ // Grab refs remotely diff --git a/test/core/resolvers/gitRemoteResolver.js b/test/core/resolvers/gitRemoteResolver.js index 0d40db88d..f98317ee4 100644 --- a/test/core/resolvers/gitRemoteResolver.js +++ b/test/core/resolvers/gitRemoteResolver.js @@ -2,6 +2,10 @@ var expect = require('expect.js'); var path = require('path'); var fs = require('graceful-fs'); var Logger = require('bower-logger'); +var helpers = require('../../helpers'); +var Q = require('q'); +var mout = require('mout'); +var multiline = require('multiline').stripIndent; var GitRemoteResolver = require('../../../lib/core/resolvers/GitRemoteResolver'); var defaultConfig = require('../../../lib/config'); @@ -106,6 +110,92 @@ describe('GitRemoteResolver', function () { .done(); }); + describe('shallow cloning', function () { + var gitRemoteResolverFactory; + + beforeEach(function () { + gitRemoteResolverFactory = function (handler) { + return helpers.require('lib/core/resolvers/GitRemoteResolver', { + '../../util/cmd': handler + }); + }; + }); + + it('should add --depth=1 when shallow cloning is supported', function (next) { + var testSource = 'http://foo/bar.git'; + + var MyGitRemoteResolver = gitRemoteResolverFactory(function (cmd, args) { + // The first git call fetches the tags for the provided source + if (mout.array.equals(args, ['ls-remote', '--tags', '--heads', testSource])) { + // Return list of commits, including one tag. + // The tag will be used for the clone call. + return Q.all([multiline(function () {/* + e4655d250f2a3f64ef2d712f25dafa60652bb93e refs/heads/some-branch + 0a7daf646d4fd743b6ef701d63bdbe20eee422de refs/tags/0.0.1 + */ + })]); + } + else if (args[0] === 'clone') { + // Verify parameters of the clone call. + // In this case, the arguments need to contain "--depth 1". + expect(args).to.eql(['clone', 'http://foo/bar.git', '-b', '0.0.1', '--progress', '.', '--depth', 1]); + + // In this case, only the stderr content is evaluated. Everything's fine as long as it + // does not contain any error description. + return Q.all(['stdout', 'stderr']); + } + }); + + // Mock the call, return true for this test. + MyGitRemoteResolver.prototype._supportsShallowCloning = function () { + return Q.resolve(true); + }; + + var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + + resolver.resolve().then(function () { + next(); + }); + }); + + it('should not add --depth=1 when shallow cloning is not supported', function (next) { + var testSource = 'http://foo/bar.git'; + + var MyGitRemoteResolver = gitRemoteResolverFactory(function (cmd, args) { + // The first git call fetches the tags for the provided source + if (mout.array.equals(args, ['ls-remote', '--tags', '--heads', testSource])) { + // Return list of commits, including one tag. + // The tag will be used for the clone call. + return Q.all([multiline(function () {/* + e4655d250f2a3f64ef2d712f25dafa60652bb93e refs/heads/some-branch + 0a7daf646d4fd743b6ef701d63bdbe20eee422de refs/tags/0.0.1 + */ + })]); + } + else if (args[0] === 'clone') { + // Verify parameters of the clone call. + // In this case, the arguments should not contain "--depth 1". + expect(args).to.eql(['clone', 'http://foo/bar.git', '-b', '0.0.1', '--progress', '.']); + + // In this case, only the stderr content is evaluated. Everything's fine as long as it + // does not contain any error description. + return Q.all(['stdout', 'stderr']); + } + }); + + // Mock the call, return false for this test. + MyGitRemoteResolver.prototype._supportsShallowCloning = function () { + return Q.resolve(false); + }; + + var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + + resolver.resolve().then(function () { + next(); + }); + }); + }); + it.skip('should handle gracefully servers that do not support --depth=1'); it.skip('should report progress when it takes too long to clone'); }); @@ -162,4 +252,86 @@ describe('GitRemoteResolver', function () { .done(); }); }); + + describe('#_supportsShallowCloning', function () { + var gitRemoteResolverFactory; + + beforeEach(function () { + gitRemoteResolverFactory = function (handler) { + return helpers.require('lib/core/resolvers/GitRemoteResolver', { + '../../util/cmd': handler + }); + }; + }); + + function createCmdHandlerFn (testSource, stderr) { + return function (cmd, args, options) { + expect(cmd).to.be('git'); + expect(args).to.eql([ 'ls-remote', '--heads', testSource ]); + expect(options.env.GIT_CURL_VERBOSE).to.be(2); + + return Q.all(['stdout', stderr]); + }; + } + + it('should call ls-remote when using http protocol', function (next) { + var testSource = 'http://foo/bar.git'; + + var MyGitRemoteResolver = gitRemoteResolverFactory( + createCmdHandlerFn(testSource, multiline(function () {/* + foo: bar + Content-Type: none + 1234: 5678 + */})) + ); + + var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + + resolver._shallowClone.then(function (shallowCloningSupported) { + expect(shallowCloningSupported).to.be(false); + + next(); + }); + }); + + it('should call ls-remote when using https protocol', function (next) { + var testSource = 'https://foo/bar.git'; + + var MyGitRemoteResolver = gitRemoteResolverFactory( + createCmdHandlerFn(testSource, multiline(function () {/* + foo: bar + Content-Type: none + 1234: 5678 + */})) + ); + + var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + + resolver._shallowClone.then(function (shallowCloningSupported) { + expect(shallowCloningSupported).to.be(false); + + next(); + }); + }); + + it('should evaluate to true when the smart content type is returned', function (next) { + var testSource = 'https://foo/bar.git'; + + var MyGitRemoteResolver = gitRemoteResolverFactory( + createCmdHandlerFn(testSource, multiline(function () {/* + foo: bar + Content-Type: application/x-git-upload-pack-advertisement + 1234: 5678 + */})) + ); + + var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + + resolver._shallowClone.then(function (shallowCloningSupported) { + expect(shallowCloningSupported).to.be(true); + + next(); + }); + }); + }); }); From a352d51711372298a6b97c30345cc72a7b59a26e Mon Sep 17 00:00:00 2001 From: Nils Winkler Date: Tue, 24 Mar 2015 17:11:33 +0100 Subject: [PATCH 0550/1021] Using a function reference instead of calling directly from constructor --- lib/core/resolvers/GitHubResolver.js | 4 +++- lib/core/resolvers/GitRemoteResolver.js | 4 ++-- test/core/resolvers/gitRemoteResolver.js | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/core/resolvers/GitHubResolver.js b/lib/core/resolvers/GitHubResolver.js index e8f02d7cf..1978016b1 100644 --- a/lib/core/resolvers/GitHubResolver.js +++ b/lib/core/resolvers/GitHubResolver.js @@ -38,7 +38,9 @@ function GitHubResolver(decEndpoint, config, logger) { } // Enable shallow clones for GitHub repos - this._shallowClone = Q.resolve(true); + this._shallowClone = function() { + return Q.resolve(true); + }; } util.inherits(GitHubResolver, GitRemoteResolver); diff --git a/lib/core/resolvers/GitRemoteResolver.js b/lib/core/resolvers/GitRemoteResolver.js index fa8766736..a7b218503 100644 --- a/lib/core/resolvers/GitRemoteResolver.js +++ b/lib/core/resolvers/GitRemoteResolver.js @@ -29,7 +29,7 @@ function GitRemoteResolver(decEndpoint, config, logger) { this._remote = url.parse(this._source); // Verify whether the server supports shallow cloning - this._shallowClone = this._supportsShallowCloning(); + this._shallowClone = this._supportsShallowCloning; } util.inherits(GitRemoteResolver, GitResolver); @@ -117,7 +117,7 @@ GitRemoteResolver.prototype._fastClone = function (resolution) { branch = resolution.tag || resolution.branch; args = ['clone', this._source, '-b', branch, '--progress', '.']; - return this._shallowClone.then(function (shallowCloningSupported) { + return this._shallowClone().then(function (shallowCloningSupported) { // If the host does not support shallow clones, we don't use --depth=1 if (shallowCloningSupported && !GitRemoteResolver._noShallow.get(this._host)) { args.push('--depth', 1); diff --git a/test/core/resolvers/gitRemoteResolver.js b/test/core/resolvers/gitRemoteResolver.js index f98317ee4..8d01c1645 100644 --- a/test/core/resolvers/gitRemoteResolver.js +++ b/test/core/resolvers/gitRemoteResolver.js @@ -287,7 +287,7 @@ describe('GitRemoteResolver', function () { var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); - resolver._shallowClone.then(function (shallowCloningSupported) { + resolver._shallowClone().then(function (shallowCloningSupported) { expect(shallowCloningSupported).to.be(false); next(); @@ -307,7 +307,7 @@ describe('GitRemoteResolver', function () { var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); - resolver._shallowClone.then(function (shallowCloningSupported) { + resolver._shallowClone().then(function (shallowCloningSupported) { expect(shallowCloningSupported).to.be(false); next(); @@ -327,7 +327,7 @@ describe('GitRemoteResolver', function () { var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); - resolver._shallowClone.then(function (shallowCloningSupported) { + resolver._shallowClone().then(function (shallowCloningSupported) { expect(shallowCloningSupported).to.be(true); next(); From 912808b672bd3c81f3ddc9c6bb187a7af0f99a3e Mon Sep 17 00:00:00 2001 From: Nils Winkler Date: Tue, 24 Mar 2015 20:22:15 +0100 Subject: [PATCH 0551/1021] Added support for caching hosts that support shallow cloning. --- lib/core/resolvers/GitRemoteResolver.js | 18 ++- test/core/resolvers/gitRemoteResolver.js | 146 +++++++++++++++++++++++ 2 files changed, 163 insertions(+), 1 deletion(-) diff --git a/lib/core/resolvers/GitRemoteResolver.js b/lib/core/resolvers/GitRemoteResolver.js index a7b218503..2bfd46d5b 100644 --- a/lib/core/resolvers/GitRemoteResolver.js +++ b/lib/core/resolvers/GitRemoteResolver.js @@ -185,7 +185,12 @@ GitRemoteResolver.prototype._suggestProxyWorkaround = function (err) { GitRemoteResolver.prototype._supportsShallowCloning = function () { var value = true; - if (mout.string.startsWith(this._remote.protocol, 'http')) { + // Check for protocol - the remote check for hosts supporting shallow cloning is only required for + // HTTP or HTTPS, not for Git or SSH. + // Also check for hosts that have been checked in a previous request and have been found to support + // shallow cloning. + if (mout.string.startsWith(this._remote.protocol, 'http') + && !GitRemoteResolver._canShallow.get(this._host)) { // Provide GIT_CURL_VERBOSE=2 environment variable to capture curl output. // Calling ls-remote includes a call to the git-upload-pack service, which returns the content type in the response. var processEnv = mout.object.merge(process.env, { 'GIT_CURL_VERBOSE': 2 }); @@ -203,10 +208,18 @@ GitRemoteResolver.prototype._supportsShallowCloning = function () { this._logger.debug('detect-smart-git', 'Smart Git host detected: ' + isSmartServer); + if (isSmartServer) { + // Cache this host + GitRemoteResolver._canShallow.set(this._host, true); + } + return isSmartServer; }.bind(this)); } else { + // One of the following cases: + // * A non-HTTP/HTTPS protocol + // * A host that has been checked before and that supports shallow cloning return Q.resolve(true); } @@ -251,4 +264,7 @@ GitRemoteResolver.refs = function (source) { // Store hosts that do not support shallow clones here GitRemoteResolver._noShallow = new LRU({ max: 50, maxAge: 5 * 60 * 1000 }); +// Store hosts that support shallow clones here +GitRemoteResolver._canShallow = new LRU({ max: 50, maxAge: 5 * 60 * 1000 }); + module.exports = GitRemoteResolver; diff --git a/test/core/resolvers/gitRemoteResolver.js b/test/core/resolvers/gitRemoteResolver.js index 8d01c1645..c3b5049f0 100644 --- a/test/core/resolvers/gitRemoteResolver.js +++ b/test/core/resolvers/gitRemoteResolver.js @@ -333,5 +333,151 @@ describe('GitRemoteResolver', function () { next(); }); }); + + it('should cache hosts that support shallow cloning', function (next) { + var testSource = 'https://foo/bar.git'; + + var counter = 0; + + var MyGitRemoteResolver = gitRemoteResolverFactory( + function (cmd, args, options) { + counter++; + + if (counter === 1) { + expect(cmd).to.be('git'); + expect(args).to.eql([ 'ls-remote', '--heads', testSource ]); + expect(options.env.GIT_CURL_VERBOSE).to.be(2); + + return Q.all(['stdout', multiline(function () {/* + foo: bar + Content-Type: application/x-git-upload-pack-advertisement + 1234: 5678 + */ + })]); + } + else { + return Q.reject(new Error('More calls than expected')); + } + } + ); + + var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + + resolver._shallowClone().then(function (shallowCloningSupported) { + expect(shallowCloningSupported).to.be(true); + + var resolver2 = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + + resolver2._shallowClone().then(function (shallowCloningSupported) { + expect(shallowCloningSupported).to.be(true); + + next(); + }, function(err) { + console.log('Error', err); + next(err); + }); + }); + }); + + it('should cache hosts that support shallow cloning across multiple repos', function (next) { + var testSource1 = 'https://foo/bar.git'; + var testSource2 = 'https://foo/barbaz.git'; + + var counter = 0; + + var MyGitRemoteResolver = gitRemoteResolverFactory( + function (cmd, args, options) { + counter++; + + if (counter === 1) { + expect(cmd).to.be('git'); + expect(args).to.eql([ 'ls-remote', '--heads', testSource1 ]); + expect(options.env.GIT_CURL_VERBOSE).to.be(2); + + return Q.all(['stdout', multiline(function () {/* + foo: bar + Content-Type: application/x-git-upload-pack-advertisement + 1234: 5678 + */ + })]); + } + else { + return Q.reject(new Error('More calls than expected')); + } + } + ); + + var resolver = new MyGitRemoteResolver({ source: testSource1 }, defaultConfig(), logger); + + resolver._shallowClone().then(function (shallowCloningSupported) { + expect(shallowCloningSupported).to.be(true); + + var resolver2 = new MyGitRemoteResolver({ source: testSource2 }, defaultConfig(), logger); + + resolver2._shallowClone().then(function (shallowCloningSupported) { + expect(shallowCloningSupported).to.be(true); + + next(); + }, function(err) { + console.log('Error', err); + next(err); + }); + }); + }); + + it('should run separate checks for separate hosts ', function (next) { + var testSource1 = 'https://foo/bar.git'; + var testSource2 = 'https://foo.bar.baz/barbaz.git'; + + var counter = 0; + + var MyGitRemoteResolver = gitRemoteResolverFactory( + function (cmd, args, options) { + counter++; + + if (counter === 1) { + expect(cmd).to.be('git'); + expect(args).to.eql([ 'ls-remote', '--heads', testSource1 ]); + expect(options.env.GIT_CURL_VERBOSE).to.be(2); + + return Q.all(['stdout', multiline(function () {/* + foo: bar + Content-Type: application/x-git-upload-pack-advertisement + 1234: 5678 + */ + })]); + } + else { + expect(cmd).to.be('git'); + expect(args).to.eql([ 'ls-remote', '--heads', testSource2 ]); + expect(options.env.GIT_CURL_VERBOSE).to.be(2); + + return Q.all(['stdout', multiline(function () {/* + foo: barbaz + Content-Type: application/x-git-upload-pack-advertisement + 1234: 5678 + */ + })]); + } + } + ); + + var resolver = new MyGitRemoteResolver({ source: testSource1 }, defaultConfig(), logger); + + resolver._shallowClone().then(function (shallowCloningSupported) { + expect(shallowCloningSupported).to.be(true); + + var resolver2 = new MyGitRemoteResolver({ source: testSource2 }, defaultConfig(), logger); + + resolver2._shallowClone().then(function (shallowCloningSupported) { + expect(shallowCloningSupported).to.be(true); + + next(); + }, function(err) { + console.log('Error', err); + next(err); + }); + }); + }); }); }); From 7e0a2ea4cb15fd7a962cd15fe0eec3e974f00a3b Mon Sep 17 00:00:00 2001 From: Nils Winkler Date: Tue, 24 Mar 2015 20:36:15 +0100 Subject: [PATCH 0552/1021] Added check for empty remote or no protocol set. --- lib/core/resolvers/GitRemoteResolver.js | 6 ++++++ test/core/resolvers/gitRemoteResolver.js | 25 +++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/core/resolvers/GitRemoteResolver.js b/lib/core/resolvers/GitRemoteResolver.js index 2bfd46d5b..61cf86b01 100644 --- a/lib/core/resolvers/GitRemoteResolver.js +++ b/lib/core/resolvers/GitRemoteResolver.js @@ -185,6 +185,12 @@ GitRemoteResolver.prototype._suggestProxyWorkaround = function (err) { GitRemoteResolver.prototype._supportsShallowCloning = function () { var value = true; + // Verify that the remote could be parsed and that a protocol is set + // This case is unlikely, but let's still cover it. + if (this._remote == null || this._remote.protocol == null) { + return Q.resolve(false); + } + // Check for protocol - the remote check for hosts supporting shallow cloning is only required for // HTTP or HTTPS, not for Git or SSH. // Also check for hosts that have been checked in a previous request and have been found to support diff --git a/test/core/resolvers/gitRemoteResolver.js b/test/core/resolvers/gitRemoteResolver.js index c3b5049f0..039cac494 100644 --- a/test/core/resolvers/gitRemoteResolver.js +++ b/test/core/resolvers/gitRemoteResolver.js @@ -314,6 +314,28 @@ describe('GitRemoteResolver', function () { }); }); + it('should evaluate to false when the URL can not be parsed', function (next) { + var testSource = 'grmblfjx///:::.git'; + + var MyGitRemoteResolver = gitRemoteResolverFactory( + createCmdHandlerFn(testSource, multiline(function () {/* + foo: bar + Content-Type: none + 1234: 5678 + */})) + ); + + var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + + resolver._shallowClone().then(function (shallowCloningSupported) { + expect(shallowCloningSupported).to.be(false); + + next(); + }, function (err) { + next(err); + }); + }); + it('should evaluate to true when the smart content type is returned', function (next) { var testSource = 'https://foo/bar.git'; @@ -373,7 +395,6 @@ describe('GitRemoteResolver', function () { next(); }, function(err) { - console.log('Error', err); next(err); }); }); @@ -419,7 +440,6 @@ describe('GitRemoteResolver', function () { next(); }, function(err) { - console.log('Error', err); next(err); }); }); @@ -474,7 +494,6 @@ describe('GitRemoteResolver', function () { next(); }, function(err) { - console.log('Error', err); next(err); }); }); From c2f222760a0c43dd6f9c8d63176dc2215fa8f21a Mon Sep 17 00:00:00 2001 From: Kody Peterson Date: Wed, 25 Mar 2015 13:42:44 -0400 Subject: [PATCH 0553/1021] Fixes https://github.com/bower/bower/issues/1689 and actually adds tests and testing ability --- packages/bower-config/Gruntfile.js | 53 ++++++++++ packages/bower-config/lib/Config.js | 4 +- packages/bower-config/lib/util/rc.js | 53 +++++----- packages/bower-config/package.json | 19 +++- packages/bower-config/test/helpers.js | 126 +++++++++++++++++++++++ packages/bower-config/test/test.js | 1 + packages/bower-config/test/util/index.js | 3 + packages/bower-config/test/util/rc.js | 29 ++++++ 8 files changed, 256 insertions(+), 32 deletions(-) create mode 100644 packages/bower-config/Gruntfile.js create mode 100644 packages/bower-config/test/helpers.js create mode 100644 packages/bower-config/test/util/index.js create mode 100644 packages/bower-config/test/util/rc.js diff --git a/packages/bower-config/Gruntfile.js b/packages/bower-config/Gruntfile.js new file mode 100644 index 000000000..d2bc8f705 --- /dev/null +++ b/packages/bower-config/Gruntfile.js @@ -0,0 +1,53 @@ +'use strict'; +module.exports = function (grunt) { + require('load-grunt-tasks')(grunt); + + grunt.initConfig({ + jshint: { + options: { + jshintrc: '.jshintrc' + }, + files: [ + 'Gruntfile.js', + 'bin/*', + 'lib/**/*.js', + 'test/**/*.js', + '!test/assets/**/*', + '!test/reports/**/*', + '!test/tmp/**/*' + ] + }, + simplemocha: { + options: { + reporter: 'spec', + timeout: '10000' + }, + full: { + src: ['test/test.js'] + }, + short: { + options: { + reporter: 'dot' + }, + src: ['test/test.js'] + } + }, + exec: { + cover: { + command: 'STRICT_REQUIRE=1 node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' + }, + coveralls: { + command: 'node node_modules/.bin/coveralls < test/reports/lcov.info' + } + }, + watch: { + files: ['<%= jshint.files %>'], + tasks: ['jshint', 'simplemocha:short'] + } + }); + + grunt.registerTask('test', ['jshint', 'simplemocha:full']); + grunt.registerTask('cover', 'exec:cover'); + grunt.registerTask('travis', ['jshint', 'exec:cover', 'exec:coveralls']); + grunt.registerTask('default', 'test'); +}; \ No newline at end of file diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index 7da02e916..b87abb45c 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -14,7 +14,7 @@ Config.prototype.load = function () { this._config = rc('bower', defaults, this._cwd); return this; }; - +/* jshint ignore:start */ Config.prototype.get = function (key) { // TODO }; @@ -32,7 +32,7 @@ Config.prototype.del = function (key, value) { Config.prototype.save = function (where, callback) { // TODO }; - +/* jshint ignore:end */ Config.prototype.toObject = function () { var config = lang.deepClone(this._config); diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 8ab86c1be..6d3121a49 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -5,6 +5,7 @@ var osenv = require('osenv'); var object = require('mout/object'); var string = require('mout/string'); var paths = require('./paths'); +var glob = require('glob'); var win = process.platform === 'win32'; var home = osenv.home(); @@ -59,15 +60,25 @@ function parse(content, file) { } function json(file) { - var content; + var content = {}; + if (!Array.isArray(file)) { + try { + content = fs.readFileSync(file).toString(); + } catch (err) { + return null; + } - try { - content = fs.readFileSync(file).toString(); - } catch (err) { - return null; - } + return parse(content, file); + } else { + // This is multiple json files + file.forEach(function(filename) { + var json = fs.readFileSync(filename).toString(); + json = parse(json, filename); + content = object.merge(content, json); + }); - return parse(content, file); + return content; + } } function env(prefix) { @@ -92,25 +103,15 @@ function env(prefix) { } function find(filename, dir) { - var walk = function (filename, dir) { - var file = path.join(dir, filename); - var parent = path.dirname(dir); - - try { - fs.statSync(file); - return file; - } catch (err) { - // Check if we hit the root - if (parent === dir) { - return null; - } - - return walk(filename, parent); - } - }; - - dir = dir || process.cwd(); - return walk(filename, dir); + var files = glob.sync('**/' + filename, { + cwd: dir + }); + files.forEach(function(file, index) { + files[index] = path.join(dir, file); + }); + // Reverse the array so that merges are done hierarchically + files.reverse(); + return files; } module.exports = rc; diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 52c260efc..154d7bc51 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -19,16 +19,27 @@ "node": ">=0.8.0" }, "dependencies": { + "glob": "^4.5.3", "graceful-fs": "~2.0.0", + "mkdirp": "^0.5.0", "mout": "~0.9.0", "optimist": "~0.6.0", - "osenv": "0.0.3" + "osenv": "0.0.3", + "q": "^1.2.0", + "rimraf": "^2.3.2" }, "devDependencies": { - "expect.js": "~0.2.0", - "mocha": "~1.12.0" + "expect.js": "^0.3.1", + "grunt": "^0.4.5", + "grunt-cli": "^0.1.13", + "grunt-contrib-jshint": "^0.10.0", + "grunt-contrib-watch": "^0.6.1", + "grunt-simple-mocha": "^0.4.0", + "load-grunt-tasks": "^2.0.0", + "mocha": "~1.12.0", + "node-uuid": "^1.4.3" }, "scripts": { - "test": "mocha -R spec" + "test": "grunt test" } } diff --git a/packages/bower-config/test/helpers.js b/packages/bower-config/test/helpers.js new file mode 100644 index 000000000..8722dad41 --- /dev/null +++ b/packages/bower-config/test/helpers.js @@ -0,0 +1,126 @@ +var Q = require('q'); +var mkdirp = require('mkdirp'); +var rimraf = require('rimraf'); +var uuid = require('node-uuid'); +var object = require('mout/object'); +var fs = require('fs'); +var glob = require('glob'); +var os = require('os'); +var path = require('path'); + +// For better promise errors +Q.longStackSupport = true; + +var tmpLocation = path.join( + os.tmpdir ? os.tmpdir() : os.tmpDir(), + 'bower-config-tests', + uuid.v4().slice(0, 8) +); + +after(function () { + rimraf.sync(tmpLocation); +}); + +exports.TempDir = (function() { + function TempDir (defaults) { + this.path = path.join(tmpLocation, uuid.v4()); + this.defaults = defaults; + } + + TempDir.prototype.create = function (files, defaults) { + var that = this; + + defaults = defaults || this.defaults || {}; + files = object.merge(files || {}, defaults); + + this.meta = function(tag) { + if (tag) { + return files[tag]['bower.json']; + } else { + return files['bower.json']; + } + }; + + if (files) { + object.forOwn(files, function (contents, filepath) { + if (typeof contents === 'object') { + contents = JSON.stringify(contents, null, ' ') + '\n'; + } + + var fullPath = path.join(that.path, filepath); + mkdirp.sync(path.dirname(fullPath)); + fs.writeFileSync(fullPath, contents); + }); + } + + return this; + }; + + TempDir.prototype.prepare = function (files) { + rimraf.sync(this.path); + mkdirp.sync(this.path); + this.create(files); + + return this; + }; + + // TODO: Rewrite to synchronous form + TempDir.prototype.prepareGit = function (revisions) { + var that = this; + + revisions = object.merge(revisions || {}, this.defaults); + + rimraf.sync(that.path); + + mkdirp.sync(that.path); + + var promise = new Q(); + + object.forOwn(revisions, function (files, tag) { + promise = promise.then(function () { + return that.git('init'); + }).then(function () { + that.glob('./!(.git)').map(function (removePath) { + var fullPath = path.join(that.path, removePath); + + rimraf.sync(fullPath); + }); + + that.create(files, {}); + }).then(function () { + return that.git('add', '-A'); + }).then(function () { + return that.git('commit', '-m"commit"'); + }).then(function () { + return that.git('tag', tag); + }); + }); + + return promise; + }; + + TempDir.prototype.glob = function (pattern) { + return glob.sync(pattern, { + cwd: this.path, + dot: true + }); + }; + + TempDir.prototype.getPath = function (name) { + return path.join(this.path, name); + }; + + TempDir.prototype.read = function (name) { + return fs.readFileSync(this.getPath(name), 'utf8'); + }; + + TempDir.prototype.readJson = function (name) { + return JSON.parse(this.read(name)); + }; + + TempDir.prototype.exists = function (name) { + return fs.existsSync(path.join(this.path, name)); + }; + + return TempDir; +})(); \ No newline at end of file diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index e69de29bb..0b03ef2fd 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -0,0 +1 @@ +require('./util/index'); \ No newline at end of file diff --git a/packages/bower-config/test/util/index.js b/packages/bower-config/test/util/index.js new file mode 100644 index 000000000..2a2d25259 --- /dev/null +++ b/packages/bower-config/test/util/index.js @@ -0,0 +1,3 @@ +describe('util', function () { + require('./rc'); +}); \ No newline at end of file diff --git a/packages/bower-config/test/util/rc.js b/packages/bower-config/test/util/rc.js new file mode 100644 index 000000000..9ca123d66 --- /dev/null +++ b/packages/bower-config/test/util/rc.js @@ -0,0 +1,29 @@ +var expect = require('expect.js'); +var helpers = require('../helpers'); + +describe('rc', function() { + var tempDir = new helpers.TempDir(); + + var rc = require('../../lib/util/rc'); + var defaults = require('../../lib/util/defaults'); + defaults.cwd = tempDir.path; + + tempDir.prepare({ + '.bowerrc': { + key: 'value' + }, + 'child/.bowerrc': { + key2: 'value2' + }, + 'child2/.bowerrc': { + key: 'valueShouldBeOverwrittenByParent' + } + }); + + it('correctly reads .bowerrc files', function() { + var config = rc('bower', defaults, tempDir.path); + + expect(config.key).to.eql('value'); + expect(config.key2).to.eql('value2'); + }); +}); \ No newline at end of file From a1ecf8a413724ed0b173d92c2a46dbb7fe2bbe78 Mon Sep 17 00:00:00 2001 From: Dan Rumney Date: Thu, 26 Mar 2015 10:03:52 -0500 Subject: [PATCH 0554/1021] Fixes #1754: The version command in the programmatic API now returns the new version When users of the programmatic API update the version, they may do so without having to inspect the new contents of the bower.json file to find out the new version. This is useful in scripts where the tag needs to be pushed programatically; the user can push the new tag explicitly. --- lib/commands/version.js | 1 + test/commands/version.js | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/lib/commands/version.js b/lib/commands/version.js index 80ac3895e..6e2978899 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -40,6 +40,7 @@ function bump(project, versionArg, message) { }) .then(function () { console.log('v' + newVersion); + return newVersion; }); } diff --git a/test/commands/version.js b/test/commands/version.js index 4855b900f..7b70153ab 100644 --- a/test/commands/version.js +++ b/test/commands/version.js @@ -53,6 +53,14 @@ describe('bower list', function () { }); }); + it('returns the new version', function() { + package.prepare(); + + return helpers.run(version, ['major', {}, { cwd: package.path }]).then(function(results) { + expect(results[0]).to.be('1.0.0'); + }); + }); + it('bumps patch version, create commit, and tag', function() { return gitPackage.prepareGit().then(function() { From 379de05a61f0ac8818943296611c56f3dca1cd80 Mon Sep 17 00:00:00 2001 From: Kody Peterson Date: Thu, 26 Mar 2015 14:25:42 -0400 Subject: [PATCH 0555/1021] Correct the logic --- packages/bower-config/lib/util/rc.js | 27 ++++++++++++++++++--------- packages/bower-config/test/util/rc.js | 14 ++++++++++++++ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 6d3121a49..819ef3189 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -5,7 +5,7 @@ var osenv = require('osenv'); var object = require('mout/object'); var string = require('mout/string'); var paths = require('./paths'); -var glob = require('glob'); +//var glob = require('glob'); var win = process.platform === 'win32'; var home = osenv.home(); @@ -103,14 +103,23 @@ function env(prefix) { } function find(filename, dir) { - var files = glob.sync('**/' + filename, { - cwd: dir - }); - files.forEach(function(file, index) { - files[index] = path.join(dir, file); - }); - // Reverse the array so that merges are done hierarchically - files.reverse(); + var files = []; + + var walk = function (filename, dir) { + var file = path.join(dir, filename); + var parent = path.dirname(dir); + + if (fs.existsSync(file)) { + files.push(file); + if (parent !== dir) { + walk(filename, parent); + } + } + }; + + dir = dir || process.cwd(); + walk(filename, dir); + return files; } diff --git a/packages/bower-config/test/util/rc.js b/packages/bower-config/test/util/rc.js index 9ca123d66..2187da515 100644 --- a/packages/bower-config/test/util/rc.js +++ b/packages/bower-config/test/util/rc.js @@ -23,7 +23,21 @@ describe('rc', function() { it('correctly reads .bowerrc files', function() { var config = rc('bower', defaults, tempDir.path); + expect(config.key).to.eql('value'); + expect(config.key2).to.eql(undefined); + }); + + it('correctly reads .bowerrc files from child', function() { + var config = rc('bower', defaults, tempDir.path + '/child/'); + expect(config.key).to.eql('value'); expect(config.key2).to.eql('value2'); }); + + it('correctly reads .bowerrc files from child2', function() { + var config = rc('bower', defaults, tempDir.path + '/child2/'); + + expect(config.key).to.eql('value'); + expect(config.key2).to.eql(undefined); + }); }); \ No newline at end of file From bea46fb879b099a38c6c3f748b351831284f5671 Mon Sep 17 00:00:00 2001 From: Kody Peterson Date: Thu, 26 Mar 2015 14:32:35 -0400 Subject: [PATCH 0556/1021] Children should be source --- packages/bower-config/lib/util/rc.js | 2 +- packages/bower-config/test/util/rc.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 819ef3189..797b25863 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -119,7 +119,7 @@ function find(filename, dir) { dir = dir || process.cwd(); walk(filename, dir); - + files.reverse(); return files; } diff --git a/packages/bower-config/test/util/rc.js b/packages/bower-config/test/util/rc.js index 2187da515..93fac35ab 100644 --- a/packages/bower-config/test/util/rc.js +++ b/packages/bower-config/test/util/rc.js @@ -16,7 +16,7 @@ describe('rc', function() { key2: 'value2' }, 'child2/.bowerrc': { - key: 'valueShouldBeOverwrittenByParent' + key: 'valueShouldBeOverwriteParent' } }); @@ -37,7 +37,7 @@ describe('rc', function() { it('correctly reads .bowerrc files from child2', function() { var config = rc('bower', defaults, tempDir.path + '/child2/'); - expect(config.key).to.eql('value'); + expect(config.key).to.eql('valueShouldBeOverwriteParent'); expect(config.key2).to.eql(undefined); }); }); \ No newline at end of file From f8c179b153689976f424c4be0a350aa7f869ec5c Mon Sep 17 00:00:00 2001 From: Kody Peterson Date: Fri, 27 Mar 2015 11:05:41 -0400 Subject: [PATCH 0557/1021] Cleanup --- packages/bower-config/lib/util/rc.js | 1 - packages/bower-config/package.json | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 797b25863..5f4f07a67 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -5,7 +5,6 @@ var osenv = require('osenv'); var object = require('mout/object'); var string = require('mout/string'); var paths = require('./paths'); -//var glob = require('glob'); var win = process.platform === 'win32'; var home = osenv.home(); diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 154d7bc51..2edcb89b1 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -19,25 +19,25 @@ "node": ">=0.8.0" }, "dependencies": { - "glob": "^4.5.3", "graceful-fs": "~2.0.0", - "mkdirp": "^0.5.0", "mout": "~0.9.0", "optimist": "~0.6.0", - "osenv": "0.0.3", - "q": "^1.2.0", - "rimraf": "^2.3.2" + "osenv": "0.0.3" }, "devDependencies": { "expect.js": "^0.3.1", + "glob": "^4.5.3", "grunt": "^0.4.5", "grunt-cli": "^0.1.13", "grunt-contrib-jshint": "^0.10.0", "grunt-contrib-watch": "^0.6.1", "grunt-simple-mocha": "^0.4.0", "load-grunt-tasks": "^2.0.0", + "mkdirp": "^0.5.0", "mocha": "~1.12.0", - "node-uuid": "^1.4.3" + "node-uuid": "^1.4.3", + "q": "^1.2.0", + "rimraf": "^2.3.2" }, "scripts": { "test": "grunt test" From 39a295901ae886de6f7bc39a64e997b9b955257b Mon Sep 17 00:00:00 2001 From: Nils Winkler Date: Sun, 29 Mar 2015 16:38:07 +0200 Subject: [PATCH 0558/1021] Set request version to 2.53.0 This fixes the failing unit tests --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 81688b967..6904dccc7 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "p-throttler": "0.1.1", "promptly": "0.2.0", "q": "^1.1.2", - "request": "^2.51.0", + "request": "2.53.0", "request-progress": "0.3.1", "retry": "0.6.1", "rimraf": "^2.2.8", From 126da9ee1261fd555b8425aa47ec31abc7ace7fa Mon Sep 17 00:00:00 2001 From: Mat Scales Date: Tue, 1 Apr 2014 16:41:32 +0100 Subject: [PATCH 0559/1021] Unregister and login commands --- Gruntfile.js | 2 +- lib/commands/index.js | 2 + lib/commands/login.js | 90 +++++++++++++++++++++++++ lib/commands/unregister.js | 95 +++++++++++++++++++++++++++ lib/config.js | 4 ++ package.json | 2 + templates/json/help-login.json | 19 ++++++ templates/json/help-unregister.json | 14 ++++ templates/json/help.json | 2 + test/core/resolvers/gitHubResolver.js | 4 ++ 10 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 lib/commands/login.js create mode 100644 lib/commands/unregister.js create mode 100644 templates/json/help-login.json create mode 100644 templates/json/help-unregister.json diff --git a/Gruntfile.js b/Gruntfile.js index 7aa80376e..01abcf46c 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -20,7 +20,7 @@ module.exports = function (grunt) { simplemocha: { options: { reporter: 'spec', - timeout: '10000' + timeout: '15000' }, full: { src: ['test/test.js'] diff --git a/lib/commands/index.js b/lib/commands/index.js index 045b3abc3..5779d4b94 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -66,11 +66,13 @@ module.exports = { install: commandFactory('./install'), link: commandFactory('./link'), list: commandFactory('./list'), + login: commandFactory('./login'), lookup: commandFactory('./lookup'), prune: commandFactory('./prune'), register: commandFactory('./register'), search: commandFactory('./search'), update: commandFactory('./update'), uninstall: commandFactory('./uninstall'), + unregister: commandFactory('./unregister'), version: commandFactory('./version') }; diff --git a/lib/commands/login.js b/lib/commands/login.js new file mode 100644 index 000000000..8a61a48d7 --- /dev/null +++ b/lib/commands/login.js @@ -0,0 +1,90 @@ +var Configstore = require('configstore'); +var GitHub = require('github'); +var Q = require('q'); + +var createError = require('../util/createError'); +var defaultConfig = require('../config'); + +function login(logger, options, config) { + var configstore = new Configstore('bower-github'); + + config = defaultConfig(config); + + var promise; + + if (options.token) { + promise = Q.resolve({ token: options.token }); + } else { + // This command requires interactive to be enabled + if (!config.interactive) { + process.nextTick(function () { + logger.emit('error', createError('Login requires an interactive shell', 'ENOINT', { + details: 'Note that you can manually force an interactive shell with --config.interactive' + })); + }); + return logger; + } + + var questions = [ + { + 'name': 'username', + 'message': 'Username', + 'type': 'input', + 'default': configstore.get('username') + }, + { + 'name': 'password', + 'message': 'Password', + 'type': 'password' + } + ]; + + var github = new GitHub({ + version: '3.0.0' + }); + + promise = Q.nfcall(logger.prompt.bind(logger), questions) + .then(function (answers) { + configstore.set('username', answers.username); + + github.authenticate({ + type: 'basic', + username: answers.username, + password: answers.password + }); + + return Q.ninvoke(github.authorization, 'create', { + scopes: ['user', 'repo'], + note: 'Bower command line client (' + (new Date()).toISOString() + ')' + }); + }); + } + + promise + .fail(function (error) { + logger.error('login error', 'Could not authenticate'); + }) + .then(function (result) { + configstore.set('accessToken', result.token); + + logger.emit('end', result); + }); + + return logger; +} + +// ------------------- + +login.readOptions = function (argv) { + var cli = require('../util/cli'); + + var options = cli.readOptions({ + token: { type: String, shorthand: 't' }, + }, argv); + + delete options.argv; + + return [options]; +}; + +module.exports = login; diff --git a/lib/commands/unregister.js b/lib/commands/unregister.js new file mode 100644 index 000000000..d9862f7ac --- /dev/null +++ b/lib/commands/unregister.js @@ -0,0 +1,95 @@ +var chalk = require('chalk'); +var Q = require('q'); + +var defaultConfig = require('../config'); +var PackageRepository = require('../core/PackageRepository'); +var Tracker = require('../util/analytics').Tracker; +var createError = require('../util/createError'); + +function unregister(logger, name, config) { + + if (!name) { + return; + } + + var repository; + var registryClient; + var tracker; + var force; + + config = defaultConfig(config); + force = config.force; + tracker = new Tracker(config); + + // Bypass any cache + config.offline = false; + config.force = true; + + // Trim name + name = name.trim(); + + repository = new PackageRepository(config, logger); + + process.nextTick(function () { + tracker.track('unregister'); + + if (!config.accessToken) { + return logger.emit('error', + createError('Use "bower login" with collaborator credentials', 'EFORBIDDEN') + ); + } + + Q.resolve() + .then(function () { + // If non interactive or user forced, bypass confirmation + if (!config.interactive || force) { + return true; + } + + // Confirm if the user really wants to unregister + logger.warn('confirm unregister', 'You are about to remove component "' + chalk.cyan.underline(name) + '" from the bower registry (' + chalk.cyan.underline(config.registry.register) + '). It is generally considered bad behavior to remove versions of a library that others are depending on.'); + return Q.nfcall(logger.prompt.bind(logger), { + type: 'confirm', + message: 'Are you really sure?', + default: false + }); + }) + .then(function (result) { + // If user response was negative, abort + if (!result) { + return; + } + + // Register + registryClient = repository.getRegistryClient(); + + logger.action('unregister', name, { + name: name + }); + + return Q.nfcall(registryClient.unregister.bind(registryClient), name); + }) + .done(function (result) { + tracker.track('unregistered'); + logger.info('Package unregistered', name); + logger.emit('end', result); + }, function (error) { + logger.emit('error', error); + }); + }); + + return logger; +} + +// ------------------- + +unregister.readOptions = function (argv) { + var cli = require('../util/cli'); + + var options = cli.readOptions(argv); + var name = options.argv.remain[1]; + + return [name]; +}; + +module.exports = unregister; diff --git a/lib/config.js b/lib/config.js index 4c463e108..b8d780edb 100644 --- a/lib/config.js +++ b/lib/config.js @@ -1,6 +1,7 @@ var tty = require('tty'); var object = require('mout').object; var bowerConfig = require('bower-config'); +var Configstore = require('configstore'); var cachedConfigs = {}; @@ -18,6 +19,9 @@ function readCachedConfig(cwd) { } var config = cachedConfigs[cwd] = bowerConfig.read(cwd); + var configstore = new Configstore('bower-github').all; + + object.mixIn(config, configstore); // Delete the json attribute because it is no longer supported // and conflicts with --json diff --git a/package.json b/package.json index 6904dccc7..540ef3eb9 100644 --- a/package.json +++ b/package.json @@ -26,9 +26,11 @@ "cardinal": "0.4.4", "chalk": "^1.0.0", "chmodr": "0.1.0", + "configstore": "^0.3.2", "decompress-zip": "^0.1.0", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", + "github": "^0.2.3", "glob": "^4.3.2", "graceful-fs": "^3.0.5", "handlebars": "^2.0.0", diff --git a/templates/json/help-login.json b/templates/json/help-login.json new file mode 100644 index 000000000..a5a45d453 --- /dev/null +++ b/templates/json/help-login.json @@ -0,0 +1,19 @@ +{ + "command": "login", + "description": "Authenticate with GitHub and store credentials to be used later.", + "usage": [ + "login []" + ], + "options": [ + { + "shorthand": "-h", + "flag": "--help", + "description": "Show this help message" + }, + { + "shorthand": "-t", + "flag": "--token", + "description": "Pass an existing GitHub auth token rather than prompting for username and password." + } + ] +} diff --git a/templates/json/help-unregister.json b/templates/json/help-unregister.json new file mode 100644 index 000000000..f6c311645 --- /dev/null +++ b/templates/json/help-unregister.json @@ -0,0 +1,14 @@ +{ + "command": "unregister", + "description": "Unregisters a package.", + "usage": [ + "unregister []" + ], + "options": [ + { + "shorthand": "-h", + "flag": "--help", + "description": "Show this help message" + } + ] +} diff --git a/templates/json/help.json b/templates/json/help.json index 5d97bf2de..4a1825e80 100644 --- a/templates/json/help.json +++ b/templates/json/help.json @@ -11,12 +11,14 @@ "install": "Install a package locally", "link": "Symlink a package folder", "list": "List local packages - and possible updates", + "login": "Authenticate with GitHub and store credentials", "lookup": "Look up a package URL by name", "prune": "Removes local extraneous packages", "register": "Register a package", "search": "Search for a package by name", "update": "Update a local package", "uninstall": "Remove a local package", + "unregister": "Remove a package from the registry", "version": "Bump a package version" }, "options": [ diff --git a/test/core/resolvers/gitHubResolver.js b/test/core/resolvers/gitHubResolver.js index 0e4b253ad..84cb706c2 100644 --- a/test/core/resolvers/gitHubResolver.js +++ b/test/core/resolvers/gitHubResolver.js @@ -70,6 +70,8 @@ describe('GitHub', function () { }); it('should retry using the GitRemoteResolver mechanism if download failed', function (next) { + this.timeout(20000); + var resolver; var retried; @@ -100,6 +102,8 @@ describe('GitHub', function () { }); it('should retry using the GitRemoteResolver mechanism if extraction failed', function (next) { + this.timeout(20000); + var resolver; var retried; From 905c2775d291ef1d1d36482d42a23bb325088b38 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 6 Mar 2015 22:36:53 -0800 Subject: [PATCH 0560/1021] Add tests for unregister command --- lib/commands/login.js | 13 +++--- lib/commands/unregister.js | 78 ++++++++++++++++-------------------- test/commands/unregister.js | 79 +++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 52 deletions(-) create mode 100644 test/commands/unregister.js diff --git a/lib/commands/login.js b/lib/commands/login.js index 8a61a48d7..5b59dcabd 100644 --- a/lib/commands/login.js +++ b/lib/commands/login.js @@ -17,11 +17,10 @@ function login(logger, options, config) { } else { // This command requires interactive to be enabled if (!config.interactive) { - process.nextTick(function () { - logger.emit('error', createError('Login requires an interactive shell', 'ENOINT', { - details: 'Note that you can manually force an interactive shell with --config.interactive' - })); - }); + logger.emit('error', createError('Login requires an interactive shell', 'ENOINT', { + details: 'Note that you can manually force an interactive shell with --config.interactive' + })); + return logger; } @@ -60,7 +59,7 @@ function login(logger, options, config) { }); } - promise + return promise .fail(function (error) { logger.error('login error', 'Could not authenticate'); }) @@ -69,8 +68,6 @@ function login(logger, options, config) { logger.emit('end', result); }); - - return logger; } // ------------------- diff --git a/lib/commands/unregister.js b/lib/commands/unregister.js index d9862f7ac..3cdba091b 100644 --- a/lib/commands/unregister.js +++ b/lib/commands/unregister.js @@ -30,55 +30,45 @@ function unregister(logger, name, config) { repository = new PackageRepository(config, logger); - process.nextTick(function () { - tracker.track('unregister'); + tracker.track('unregister'); - if (!config.accessToken) { - return logger.emit('error', - createError('Use "bower login" with collaborator credentials', 'EFORBIDDEN') - ); + if (!config.accessToken) { + return logger.emit('error', + createError('Use "bower login" with collaborator credentials', 'EFORBIDDEN') + ); + } + + return Q.resolve() + .then(function () { + // If non interactive or user forced, bypass confirmation + if (!config.interactive || force) { + return true; } - Q.resolve() - .then(function () { - // If non interactive or user forced, bypass confirmation - if (!config.interactive || force) { - return true; - } - - // Confirm if the user really wants to unregister - logger.warn('confirm unregister', 'You are about to remove component "' + chalk.cyan.underline(name) + '" from the bower registry (' + chalk.cyan.underline(config.registry.register) + '). It is generally considered bad behavior to remove versions of a library that others are depending on.'); - return Q.nfcall(logger.prompt.bind(logger), { - type: 'confirm', - message: 'Are you really sure?', - default: false - }); - }) - .then(function (result) { - // If user response was negative, abort - if (!result) { - return; - } - - // Register - registryClient = repository.getRegistryClient(); - - logger.action('unregister', name, { - name: name - }); - - return Q.nfcall(registryClient.unregister.bind(registryClient), name); - }) - .done(function (result) { - tracker.track('unregistered'); - logger.info('Package unregistered', name); - logger.emit('end', result); - }, function (error) { - logger.emit('error', error); + return Q.nfcall(logger.prompt.bind(logger), { + type: 'confirm', + message: 'You are about to remove component "' + chalk.cyan.underline(name) + '" from the bower registry (' + chalk.cyan.underline(config.registry.register) + '). It is generally considered bad behavior to remove versions of a library that others are depending on. Are you really sure?', + default: false }); - }); + }) + .then(function (result) { + // If user response was negative, abort + if (!result) { + return; + } - return logger; + registryClient = repository.getRegistryClient(); + + logger.action('unregister', name, { name: name }); + + return Q.nfcall(registryClient.unregister.bind(registryClient), name); + }) + .then(function (result) { + tracker.track('unregistered'); + logger.info('Package unregistered', name); + + return result; + }); } // ------------------- diff --git a/test/commands/unregister.js b/test/commands/unregister.js new file mode 100644 index 000000000..1d2c39ce1 --- /dev/null +++ b/test/commands/unregister.js @@ -0,0 +1,79 @@ +var expect = require('expect.js'); +var helpers = require('../helpers'); + +var fakeRepositoryFactory = function () { + function FakeRepository() { } + + FakeRepository.prototype.getRegistryClient = function() { + return { + unregister: function (name, cb) { + cb(null, { name: name }); + } + }; + }; + + return FakeRepository; +}; + +var unregister = helpers.command('unregister'); + +var unregisterFactory = function (canonicalDir, pkgMeta) { + return helpers.command('unregister', { + '../core/PackageRepository': fakeRepositoryFactory() + }); +}; + +describe('bower unregister', function () { + + it('correctly reads arguments', function() { + expect(unregister.readOptions(['jquery'])) + .to.eql(['jquery']); + }); + + it('errors if name is not provided', function () { + return helpers.run(unregister).fail(function(reason) { + expect(reason.message).to.be('Usage: bower unregister '); + expect(reason.code).to.be('EINVFORMAT'); + }); + }); + + it('should call registry client with name', function () { + var unregister = unregisterFactory(); + + return helpers.run(unregister, ['some-name']) + .spread(function(result) { + expect(result).to.eql({ + // Result from register action on stub + name: 'some-name' + }); + }); + }); + + it('should confirm in interactive mode', function () { + var register = unregisterFactory(); + + var promise = helpers.run(register, + ['some-name', { + interactive: true, + registry: { register: 'http://localhost' } + }] + ); + + return helpers.expectEvent(promise.logger, 'confirm') + .spread(function(e) { + expect(e.type).to.be('confirm'); + expect(e.message).to.be('You are about to remove component "some-name" from the bower registry (http://localhost). It is generally considered bad behavior to remove versions of a library that others are depending on. Are you really sure?'); + expect(e.default).to.be(false); + }); + }); + + it('should skip confirming when forcing', function () { + var register = unregisterFactory(); + + return helpers.run(register, + ['some-name', + { interactive: true, force: true } + ] + ); + }); +}); From 1a7abfd3b7260f4ba58241c2c2edcfbe655ddae7 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 29 Mar 2015 23:31:20 -0700 Subject: [PATCH 0561/1021] Add tests for login command --- lib/commands/login.js | 14 ++-- test/commands/login.js | 160 ++++++++++++++++++++++++++++++++++++ test/commands/unregister.js | 2 +- 3 files changed, 168 insertions(+), 8 deletions(-) create mode 100644 test/commands/login.js diff --git a/lib/commands/login.js b/lib/commands/login.js index 5b59dcabd..b659a4b89 100644 --- a/lib/commands/login.js +++ b/lib/commands/login.js @@ -12,6 +12,8 @@ function login(logger, options, config) { var promise; + options = options || {}; + if (options.token) { promise = Q.resolve({ token: options.token }); } else { @@ -21,7 +23,7 @@ function login(logger, options, config) { details: 'Note that you can manually force an interactive shell with --config.interactive' })); - return logger; + return; } var questions = [ @@ -59,14 +61,12 @@ function login(logger, options, config) { }); } - return promise - .fail(function (error) { - logger.error('login error', 'Could not authenticate'); - }) - .then(function (result) { + return promise.then(function (result) { configstore.set('accessToken', result.token); - logger.emit('end', result); + return result; + }, function (error) { + logger.error('login error', 'Could not authenticate'); }); } diff --git a/test/commands/login.js b/test/commands/login.js new file mode 100644 index 000000000..17ebfebb5 --- /dev/null +++ b/test/commands/login.js @@ -0,0 +1,160 @@ +var expect = require('expect.js'); +var helpers = require('../helpers'); + +var fakeGitHub = function (authenticate) { + function FakeGitHub() { } + + var _authenticated = false; + + FakeGitHub.prototype.authenticate = function (creds) { + if (creds.password === 'validpassword') { + _authenticated = true; + } + }; + + FakeGitHub.prototype.authorization = { + create: function (options, cb) { + if (_authenticated) { + cb(null, { token: 'faketoken' }); + } else { + cb('Not authenticated'); + } + } + }; + + return FakeGitHub; +}; + +var fakeConfigstore = function (set, get) { + function FakeConfigstore() { } + + FakeConfigstore.prototype.set = set; + FakeConfigstore.prototype.get = get; + + return FakeConfigstore; +}; + +var login = helpers.command('login'); + +var loginFactory = function (options) { + return helpers.command('login', { + 'github': fakeGitHub(), + 'configstore': fakeConfigstore( + options.set || function () { return true; }, + options.get || function () { return true; } + ) + }); +}; + +describe('bower login', function () { + + it('correctly reads arguments', function() { + expect(login.readOptions(['--token', 'foobar'])) + .to.eql([{ token: 'foobar' }]); + }); + + it('fails if run in non-interactive shell without token passed', function () { + return helpers.run(login, []).fail(function(reason) { + expect(reason.message).to.be('Login requires an interactive shell'); + expect(reason.code).to.be('ENOINT'); + }); + }); + + it('succeeds if run in non-interactive shell with token passed', function () { + return helpers.run(login, [{ token: 'foobar' }]); + }); + + it('succeeds if provided password is valid', function () { + var login = loginFactory({}); + + var logger = login({}, { interactive: true }); + + logger.once('prompt', function (prompt, answer) { + answer({ + username: 'user', + password: 'validpassword' + }); + }); + + return helpers.expectEvent(logger, 'end') + .spread(function(options) { + expect(options.token).to.be('faketoken'); + }); + }); + + it('fails if provided password is invalid', function () { + var login = loginFactory({}); + + var logger = login({}, { interactive: true }); + + logger.once('prompt', function (prompt, answer) { + answer({ + username: 'user', + password: 'invalidpassword' + }); + }); + + return helpers.expectEvent(logger, 'log').spread(function (log) { + expect(log.level).to.be('error'); + expect(log.id).to.be('login error'); + expect(log.message).to.be('Could not authenticate'); + }); + }); + + it('uses username stored in config as default username', function () { + var login = loginFactory({ + get: function (key) { + if (key === 'username') { + return 'savedusername'; + } + } + }); + + var logger = login({}, { interactive: true }); + + return helpers.expectEvent(logger, 'prompt') + .spread(function (prompt, answer) { + expect(prompt[0].default).to.be('savedusername'); + }); + }); + + it('saves username in config', function (done) { + var login = loginFactory({ + set: function (key, value) { + if(key === 'username') { + expect(value).to.be('user'); + done(); + } + } + }); + + var logger = login({}, { interactive: true }); + + logger.once('prompt', function (prompt, answer) { + answer({ + username: 'user', + password: 'validpassword' + }); + }); + }); + + it('saves received token in accessToken config', function (done) { + var login = loginFactory({ + set: function (key, value) { + if(key === 'accessToken') { + expect(value).to.be('faketoken'); + done(); + } + } + }); + + var logger = login({}, { interactive: true }); + + logger.once('prompt', function (prompt, answer) { + answer({ + username: 'user', + password: 'validpassword' + }); + }); + }); +}); diff --git a/test/commands/unregister.js b/test/commands/unregister.js index 1d2c39ce1..fc5a3ad88 100644 --- a/test/commands/unregister.js +++ b/test/commands/unregister.js @@ -17,7 +17,7 @@ var fakeRepositoryFactory = function () { var unregister = helpers.command('unregister'); -var unregisterFactory = function (canonicalDir, pkgMeta) { +var unregisterFactory = function () { return helpers.command('unregister', { '../core/PackageRepository': fakeRepositoryFactory() }); From 0f68da4eb8d2f278d26d07c5811d64b01424b468 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 30 Mar 2015 00:19:05 -0700 Subject: [PATCH 0562/1021] Add support for two-factor authentication for login --- lib/commands/login.js | 38 +++++++++++++++++++++++++++++++++- test/commands/login.js | 47 +++++++++++++++++++++++++++++++++--------- 2 files changed, 74 insertions(+), 11 deletions(-) diff --git a/lib/commands/login.js b/lib/commands/login.js index b659a4b89..2087efa9e 100644 --- a/lib/commands/login.js +++ b/lib/commands/login.js @@ -66,7 +66,43 @@ function login(logger, options, config) { return result; }, function (error) { - logger.error('login error', 'Could not authenticate'); + var message; + + try { + message = JSON.parse(error.message).message; + } catch (e) { + message = 'Authorization failed'; + } + + var questions = [ + { + 'name': 'otpcode', + 'message': 'Two-Factor Auth Code', + 'type': 'input' + } + ]; + + if (message === 'Must specify two-factor authentication OTP code.') { + return Q.nfcall(logger.prompt.bind(logger), questions) + .then(function (answers) { + return Q.ninvoke(github.authorization, 'create', { + scopes: ['user', 'repo'], + note: 'Bower command line client (' + (new Date()).toISOString() + ')', + headers: { + 'X-GitHub-OTP': answers.otpcode + } + }); + }) + .then(function (result) { + configstore.set('accessToken', result.token); + + return result; + }, function () { + logger.emit('error', createError(message, 'EAUTH')); + }); + } else { + logger.emit('error', createError(message, 'EAUTH')); + } }); } diff --git a/test/commands/login.js b/test/commands/login.js index 17ebfebb5..1654751bb 100644 --- a/test/commands/login.js +++ b/test/commands/login.js @@ -4,20 +4,24 @@ var helpers = require('../helpers'); var fakeGitHub = function (authenticate) { function FakeGitHub() { } - var _authenticated = false; + var _creds; FakeGitHub.prototype.authenticate = function (creds) { - if (creds.password === 'validpassword') { - _authenticated = true; - } + _creds = creds; }; FakeGitHub.prototype.authorization = { create: function (options, cb) { - if (_authenticated) { + if (_creds.password === 'validpassword') { cb(null, { token: 'faketoken' }); + } else if (_creds.password === 'withtwofactor') { + if (options.headers && options.headers['X-GitHub-OTP'] === '123456') { + cb(null, { token: 'faketwoauthtoken' }); + } else { + cb({ code: 401, message: '{ "message": "Must specify two-factor authentication OTP code." }' }); + } } else { - cb('Not authenticated'); + cb({ code: 401, message: 'Bad credentials' }); } } }; @@ -82,6 +86,30 @@ describe('bower login', function () { }); }); + it('supports two-factor authorization', function () { + var login = loginFactory({}); + + var logger = login({}, { interactive: true }); + + logger.once('prompt', function (prompt, answer) { + logger.once('prompt', function (prompt, answer) { + answer({ + otpcode: '123456' + }); + }); + + answer({ + username: 'user', + password: 'withtwofactor' + }); + }); + + return helpers.expectEvent(logger, 'end') + .spread(function(options) { + expect(options.token).to.be('faketwoauthtoken'); + }); + }); + it('fails if provided password is invalid', function () { var login = loginFactory({}); @@ -94,10 +122,9 @@ describe('bower login', function () { }); }); - return helpers.expectEvent(logger, 'log').spread(function (log) { - expect(log.level).to.be('error'); - expect(log.id).to.be('login error'); - expect(log.message).to.be('Could not authenticate'); + return helpers.expectEvent(logger, 'error').spread(function (error) { + expect(error.code).to.be('EAUTH'); + expect(error.message).to.be('Authorization failed'); }); }); From e727566741c0fb3be0512706a1de12fe926508e6 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 30 Mar 2015 00:49:06 -0700 Subject: [PATCH 0563/1021] Revert SvnResolver changes (windows paths in URLs) --- lib/core/resolvers/SvnResolver.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js index c2be641a2..866fad789 100644 --- a/lib/core/resolvers/SvnResolver.js +++ b/lib/core/resolvers/SvnResolver.js @@ -3,7 +3,6 @@ var Q = require('q'); var which = require('which'); var LRU = require('lru-cache'); var mout = require('mout'); -var path = require('path'); var Resolver = require('./Resolver'); var semver = require('../../util/semver'); var createError = require('../../util/createError'); @@ -87,13 +86,13 @@ SvnResolver.prototype._export = function () { }); if (resolution.type === 'commit') { - promise = cmd('svn', ['export', '--force', this._source + path.normalize('/trunk'), '-r' + resolution.commit, this._tempDir]); + promise = cmd('svn', ['export', '--force', this._source + '/trunk', '-r' + resolution.commit, this._tempDir]); } else if (resolution.type === 'branch' && resolution.branch === 'trunk') { - promise = cmd('svn', ['export', '--force', this._source + path.normalize('/trunk'), this._tempDir]); + promise = cmd('svn', ['export', '--force', this._source + '/trunk', this._tempDir]); } else if (resolution.type === 'branch') { - promise = cmd('svn', ['export', '--force', this._source + path.normalize('/branches/' + resolution.branch), this._tempDir]); + promise = cmd('svn', ['export', '--force', this._source + '/branches/' + resolution.branch, this._tempDir]); } else { - promise = cmd('svn', ['export', '--force', this._source + path.normalize('/tags/' + resolution.tag), this._tempDir]); + promise = cmd('svn', ['export', '--force', this._source + '/tags/' + resolution.tag, this._tempDir]); } // Throttle the progress reporter to 1 time each sec @@ -325,7 +324,7 @@ SvnResolver.tags = function (source) { return Q.resolve(value); } - value = cmd('svn', ['list', source + path.normalize('/tags'), '--verbose']) + value = cmd('svn', ['list', source + '/tags', '--verbose']) .spread(function (stout) { var tags = SvnResolver.parseSubversionListOutput(stout.toString()); From f6178c2f75e88170307add52ae43bd919313f712 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 30 Mar 2015 01:19:35 -0700 Subject: [PATCH 0564/1021] Bump to 0.6.0 --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 2edcb89b1..06709b60f 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.5.2", + "version": "0.6.0", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 77b735543354e4d37a65cfc8da57823727b97e25 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 30 Mar 2015 01:23:20 -0700 Subject: [PATCH 0565/1021] Bump npm-config, fixes #1689, fixes #1711 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 540ef3eb9..fc03fd62d 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "dependencies": { "abbrev": "^1.0.5", "archy": "1.0.0", - "bower-config": "^0.5.2", + "bower-config": "^0.6.0", "bower-endpoint-parser": "^0.2.2", "bower-json": "^0.4.0", "bower-logger": "^0.2.2", From ea1f5d1ff088a9397d7d0556c4f7a4597ec102fa Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 30 Mar 2015 15:46:30 -0700 Subject: [PATCH 0566/1021] Bump to 1.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fc03fd62d..b52a2f83b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.3.12", + "version": "1.4.0", "description": "The browser package manager", "author": "Twitter", "licenses": [ From c4ca24a537dcc140f1177bacfadd10376cc13c4c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 31 Mar 2015 08:52:55 -0700 Subject: [PATCH 0567/1021] Add changelog for 1.4.0 --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ee1e359b..e6ed2396e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## 1.4.0 - 2015-03-30 + +- Add login and unregister commands ([#1719](https://github.com/bower/bower/issues/1719)) +- Automatically detecting smart Git hosts ([#1628](https://github.com/bower/bower/issues/1628)) +- [bower/config#23] Allow npm config variables ([#1711](https://github.com/bower/bower/issues/1711)) +- [bower/config#24] Merge .bowerrc files upwards directory tree ([#1689](https://github.com/bower/bower/issues/1689)) +- Better homedir detection (514eb8f) +- Add --save-exact flag ([#1654](https://github.com/bower/bower/issues/1654)) +- Ensure extracted files are readable (tar-fs) ([#1548](https://github.com/bower/bower/issues/1548)) +- The version command in the programmatic API now returns the new version ([#1755](https://github.com/bower/bower/issues/1755)) +- Some minor fixes: #1639, #1620, #1576, #1557, 962a565, a464f5a +- Improved Windows support (AppVeyor CI, tests actually passing on Windows) +- OSX testing enabled on TravisCI + +It also includes improved test coverage (~60% -> ~85%) and many refactors. + ## 1.3.12 - 2014-09-28 - [stability] Fix versions for unstable dependencies ([#1532](https://github.com/bower/bower/pull/1532)) From 94455192adec8dd2e6a6d9f38b99459288293b4f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 31 Mar 2015 18:42:21 -0700 Subject: [PATCH 0568/1021] Use -y flag for Chocolatey as AppVeyor suggests --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index b793c7fcb..fe69c143b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,7 +22,7 @@ install: # Get the latest stable version of Node 0.STABLE.latest - ps: Install-Product node $env:nodejs_version # Install subversion - - choco install svn + - choco install svn -y # Install bower - npm install From 7e110603b5ec408d1c74d28648c7a7be49514d65 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 31 Mar 2015 19:07:04 -0700 Subject: [PATCH 0569/1021] [test] Make git helper in tests synchronous --- package.json | 3 +- test/commands/info.js | 4 +- test/commands/install.js | 24 +++++----- test/commands/list.js | 94 ++++++++++++++++++++-------------------- test/commands/update.js | 1 + test/commands/version.js | 38 ++++++---------- test/helpers.js | 37 +++++++--------- 7 files changed, 94 insertions(+), 107 deletions(-) diff --git a/package.json b/package.json index b52a2f83b..4f2d2dee0 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,8 @@ "multiline": "^1.0.2", "nock": "^0.56.0", "node-uuid": "^1.4.2", - "proxyquire": "^1.3.0" + "proxyquire": "^1.3.0", + "sync-exec": "^0.5.0" }, "scripts": { "test": "grunt test" diff --git a/test/commands/info.js b/test/commands/info.js index d69adb4cc..0fbe1e5dc 100644 --- a/test/commands/info.js +++ b/test/commands/info.js @@ -36,7 +36,8 @@ describe('bower info', function () { }); it('shows info about given package', function () { - return package.prepareGit({}).then(function() { + package.prepareGit({}); + return helpers.run(info, [package.path]).spread(function(results) { expect(results).to.eql({ 'latest': meta2, @@ -47,6 +48,5 @@ describe('bower info', function () { ] }); }); - }); }); }); diff --git a/test/commands/install.js b/test/commands/install.js index a09f350ed..765fc0947 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -245,7 +245,7 @@ describe('bower install', function () { }); it('works for git repositories', function () { - return gitPackage.prepareGit({ + gitPackage.prepareGit({ '1.0.0': { 'bower.json': { name: 'package' @@ -258,19 +258,19 @@ describe('bower install', function () { }, 'version.txt': '1.0.1' } - }).then(function() { - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package: gitPackage.path + '#1.0.0' - } + }); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.0' } - }); + } + }); - return helpers.run(install).then(function() { - expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); - }); + return helpers.run(install).then(function() { + expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); }); }); }); diff --git a/test/commands/list.js b/test/commands/list.js index 8ce33775b..a1c00cb25 100644 --- a/test/commands/list.js +++ b/test/commands/list.js @@ -165,7 +165,7 @@ describe('bower list', function () { }); it('lists 1 dependency when 1 git package installed', function () { - return gitPackage.prepareGit({ + gitPackage.prepareGit({ '1.0.0': { 'bower.json': { name: 'package', @@ -180,41 +180,42 @@ describe('bower list', function () { }, 'version.txt': '1.0.1' } - }).then(function() { - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package: gitPackage.path + '#1.0.0' - } + }); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.0' } - }); - return install().then(function() { - return list().spread(function(results) { - expect(results).to.be.an(Object); - expect(results.canonicalDir).to.equal(tempDir.path); - expect(results.pkgMeta.dependencies).to.eql({ - package: gitPackage.path + '#1.0.0' - }); - expect(results.pkgMeta.devDependencies).to.eql({}); - expect(results.dependencies.package).to.be.an(Object); - expect(results.dependencies.package.pkgMeta).to.be.an(Object); - expect(results.dependencies.package.pkgMeta.main).to.equal('test.txt'); - expect(results.dependencies.package.canonicalDir).to.equal( - path.join(tempDir.path, 'bower_components/package') - ); - expect(results.dependencies.package.dependencies).to.eql({}); - expect(results.dependencies.package.nrDependants).to.equal(1); - expect(results.dependencies.package.versions).to.eql(['1.0.1', '1.0.0']); - expect(results.nrDependants).to.equal(0); - expect(results.versions).to.eql([]); + } + }); + + return install().then(function() { + return list().spread(function(results) { + expect(results).to.be.an(Object); + expect(results.canonicalDir).to.equal(tempDir.path); + expect(results.pkgMeta.dependencies).to.eql({ + package: gitPackage.path + '#1.0.0' }); + expect(results.pkgMeta.devDependencies).to.eql({}); + expect(results.dependencies.package).to.be.an(Object); + expect(results.dependencies.package.pkgMeta).to.be.an(Object); + expect(results.dependencies.package.pkgMeta.main).to.equal('test.txt'); + expect(results.dependencies.package.canonicalDir).to.equal( + path.join(tempDir.path, 'bower_components/package') + ); + expect(results.dependencies.package.dependencies).to.eql({}); + expect(results.dependencies.package.nrDependants).to.equal(1); + expect(results.dependencies.package.versions).to.eql(['1.0.1', '1.0.0']); + expect(results.nrDependants).to.equal(0); + expect(results.versions).to.eql([]); }); }); }); it('lists 1 dependency with relative paths when 1 git package installed', function () { - return gitPackage.prepareGit({ + gitPackage.prepareGit({ '1.0.0': { 'bower.json': { name: 'package', @@ -229,25 +230,26 @@ describe('bower list', function () { }, 'version.txt': '1.0.1' } - }).then(function() { - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package: gitPackage.path + '#1.0.0' - } + }); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.0' } - }); - return install().then(function() { - return list({relative: true}).spread(function(results) { - expect(results.canonicalDir).to.equal(tempDir.path); - expect(results.pkgMeta.dependencies).to.eql({ - package: gitPackage.path + '#1.0.0' - }); - expect(results.dependencies.package.canonicalDir).to.equal( - path.normalize('bower_components/package') - ); + } + }); + + return install().then(function() { + return list({relative: true}).spread(function(results) { + expect(results.canonicalDir).to.equal(tempDir.path); + expect(results.pkgMeta.dependencies).to.eql({ + package: gitPackage.path + '#1.0.0' }); + expect(results.dependencies.package.canonicalDir).to.equal( + path.normalize('bower_components/package') + ); }); }); }); diff --git a/test/commands/update.js b/test/commands/update.js index 0c12c1e2f..8dca277d4 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -10,6 +10,7 @@ describe('bower update', function () { var tempDir = new helpers.TempDir(); var gitPackage = new helpers.TempDir(); + gitPackage.prepareGit({ '1.0.0': { 'bower.json': { diff --git a/test/commands/version.js b/test/commands/version.js index 7b70153ab..679f3129e 100644 --- a/test/commands/version.js +++ b/test/commands/version.js @@ -62,38 +62,28 @@ describe('bower list', function () { }); it('bumps patch version, create commit, and tag', function() { - return gitPackage.prepareGit().then(function() { + gitPackage.prepareGit(); - return helpers.run(version, ['patch', {}, { cwd: gitPackage.path }]).then(function() { - expect(gitPackage.readJson('bower.json').version).to.be('0.0.1'); - - return gitPackage.git('tag').spread(function(result) { - expect(result).to.be('v0.0.0\nv0.0.1\n'); - - return gitPackage.git('log', '--pretty=format:%s', '-n1').spread(function(result) { - expect(result).to.be('v0.0.1'); - }); - }); - }); + return helpers.run(version, ['patch', {}, { cwd: gitPackage.path }]).then(function() { + expect(gitPackage.readJson('bower.json').version).to.be('0.0.1'); + var tags = gitPackage.git('tag'); + expect(tags).to.be('v0.0.0\nv0.0.1\n'); + var message = gitPackage.git('log', '--pretty=format:%s', '-n1'); + expect(message).to.be('v0.0.1'); }); }); it('bumps with custom commit message', function() { - return gitPackage.prepareGit().then(function() { - - return helpers.run(version, ['patch', { message: 'Bumping %s, because what'}, { cwd: gitPackage.path }]).then(function() { - expect(gitPackage.readJson('bower.json').version).to.be('0.0.1'); - - return gitPackage.git('tag').spread(function(result) { - expect(result).to.be('v0.0.0\nv0.0.1\n'); + gitPackage.prepareGit(); - return gitPackage.git('log', '--pretty=format:%s', '-n1').spread(function(result) { - expect(result).to.be('Bumping 0.0.1, because what'); - }); - }); - }); + return helpers.run(version, ['patch', { message: 'Bumping %s, because what'}, { cwd: gitPackage.path }]).then(function() { + expect(gitPackage.readJson('bower.json').version).to.be('0.0.1'); + var tags = gitPackage.git('tag'); + expect(tags).to.be('v0.0.0\nv0.0.1\n'); + var message = gitPackage.git('log', '--pretty=format:%s', '-n1'); + expect(message).to.be('Bumping 0.0.1, because what'); }); }); }); diff --git a/test/helpers.js b/test/helpers.js index e613933bb..b34482fe2 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -12,7 +12,7 @@ var os = require('os'); var which = require('which'); var path = require('path'); var proxyquire = require('proxyquire').noCallThru().noPreserveCache(); -var cmd = require('../lib/util/cmd'); +var exec = require('sync-exec'); var config = require('../lib/config'); // For better promise errors @@ -106,29 +106,22 @@ exports.TempDir = (function() { mkdirp.sync(that.path); - var promise = new Q(); + this.git('init'); - object.forOwn(revisions, function (files, tag) { - promise = promise.then(function () { - return that.git('init'); - }).then(function () { - that.glob('./!(.git)').map(function (removePath) { - var fullPath = path.join(that.path, removePath); - - rimraf.sync(fullPath); - }); - - that.create(files, {}); - }).then(function () { - return that.git('add', '-A'); - }).then(function () { - return that.git('commit', '-m"commit"'); - }).then(function () { - return that.git('tag', tag); - }); + this.glob('./!(.git)').map(function (removePath) { + var fullPath = path.join(that.path, removePath); + + rimraf.sync(fullPath); }); - return promise; + object.forOwn(revisions, function (files, tag) { + this.create(files, {}); + this.git('add', '-A'); + this.git('commit', '-m"commit"'); + this.git('tag', tag); + }.bind(this)); + + return this; }; TempDir.prototype.glob = function (pattern) { @@ -153,7 +146,7 @@ exports.TempDir = (function() { TempDir.prototype.git = function () { var args = Array.prototype.slice.call(arguments); - return cmd('git', args, { cwd: this.path, env: env }); + return exec('git ' + args.join(' '), { cwd: this.path, env: env }).stdout; }; TempDir.prototype.exists = function (name) { From ab4f8a0e39c80e74646bce138c5f0a35a910e1fe Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 31 Mar 2015 22:00:02 -0700 Subject: [PATCH 0570/1021] [test] Make synchronous exec work on Windows --- test/helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helpers.js b/test/helpers.js index b34482fe2..166b63c58 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -146,7 +146,7 @@ exports.TempDir = (function() { TempDir.prototype.git = function () { var args = Array.prototype.slice.call(arguments); - return exec('git ' + args.join(' '), { cwd: this.path, env: env }).stdout; + return exec('cd ' + this.path + ' && git ' + args.join(' ')).stdout; }; TempDir.prototype.exists = function (name) { From 395b208a0cef3baf57e2cd44c97baac371fb884d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 31 Mar 2015 22:26:39 -0700 Subject: [PATCH 0571/1021] Merge all .bowerrc upwards directory tree, fixes #25 --- packages/bower-config/lib/util/rc.js | 7 ++++--- packages/bower-config/test/util/rc.js | 12 +++++++++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index c41045779..246e958ef 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -111,9 +111,10 @@ function find(filename, dir) { if (fs.existsSync(file)) { files.push(file); - if (parent !== dir) { - walk(filename, parent); - } + } + + if (parent !== dir) { + walk(filename, parent); } }; diff --git a/packages/bower-config/test/util/rc.js b/packages/bower-config/test/util/rc.js index 93fac35ab..b4a8ebf92 100644 --- a/packages/bower-config/test/util/rc.js +++ b/packages/bower-config/test/util/rc.js @@ -17,6 +17,9 @@ describe('rc', function() { }, 'child2/.bowerrc': { key: 'valueShouldBeOverwriteParent' + }, + 'child3/bower.json': { + name: 'without-bowerrc' } }); @@ -40,4 +43,11 @@ describe('rc', function() { expect(config.key).to.eql('valueShouldBeOverwriteParent'); expect(config.key2).to.eql(undefined); }); -}); \ No newline at end of file + + it('correctly reads .bowerrc files from child3', function() { + var config = rc('bower', defaults, tempDir.path + '/child3/'); + + expect(config.key).to.eql('value'); + expect(config.key2).to.eql(undefined); + }); +}); From 8a47aab01de2f0feb4fb6900f5195b7ca945af23 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 31 Mar 2015 22:27:07 -0700 Subject: [PATCH 0572/1021] Bump to 0.6.1 --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 06709b60f..10ee59ad3 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.6.0", + "version": "0.6.1", "description": "The Bower config reader and writer.", "author": "Twitter", "licenses": [ From 4af22cfbc0e182bc5ac036aa2aedf510ea4bb705 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 31 Mar 2015 23:39:13 -0700 Subject: [PATCH 0573/1021] [test] Replace sync-exec with spawn-sync sync-exec has performance issue on Windows --- package.json | 2 +- test/helpers.js | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 4f2d2dee0..7d40aaa5d 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "nock": "^0.56.0", "node-uuid": "^1.4.2", "proxyquire": "^1.3.0", - "sync-exec": "^0.5.0" + "spawn-sync": "^1.0.5" }, "scripts": { "test": "grunt test" diff --git a/test/helpers.js b/test/helpers.js index 166b63c58..ae1293139 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -12,7 +12,7 @@ var os = require('os'); var which = require('which'); var path = require('path'); var proxyquire = require('proxyquire').noCallThru().noPreserveCache(); -var exec = require('sync-exec'); +var spawnSync = require('spawn-sync'); var config = require('../lib/config'); // For better promise errors @@ -145,8 +145,13 @@ exports.TempDir = (function() { TempDir.prototype.git = function () { var args = Array.prototype.slice.call(arguments); + var result = spawnSync('git', args, { cwd: this.path }); - return exec('cd ' + this.path + ' && git ' + args.join(' ')).stdout; + if (result.status !== 0) { + throw new Error(result.stderr); + } else { + return result.stdout.toString(); + } }; TempDir.prototype.exists = function (name) { From e98d8139bc759c7faa1767c805786322ad615c5e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 1 Apr 2015 00:24:22 -0700 Subject: [PATCH 0574/1021] Bump bower-config version (bower/config#25) --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index fa0af173a..fd374831c 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -16,7 +16,7 @@ }, "dependencies": { "async": "~0.2.8", - "bower-config": "~0.5.0", + "bower-config": "~0.6.1", "graceful-fs": "~2.0.0", "lru-cache": "~2.3.0", "request": "~2.51.0", From 7d74d7d8f6f2e27a652847e33c313823ff882b8e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 1 Apr 2015 00:24:38 -0700 Subject: [PATCH 0575/1021] 0.3.0 --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index fd374831c..869ad3d91 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.2.4", + "version": "0.3.0", "description": "Provides easy interaction with the Bower registry", "author": "Twitter", "licenses": [ From 335081053d5384c47331b510f66e54d12d9f804e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 1 Apr 2015 00:35:00 -0700 Subject: [PATCH 0576/1021] Bump bower-config and bower-registry-client versions, fixes #1763 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7d40aaa5d..7f6347d81 100644 --- a/package.json +++ b/package.json @@ -18,11 +18,11 @@ "dependencies": { "abbrev": "^1.0.5", "archy": "1.0.0", - "bower-config": "^0.6.0", + "bower-config": "^0.6.1", "bower-endpoint-parser": "^0.2.2", "bower-json": "^0.4.0", "bower-logger": "^0.2.2", - "bower-registry-client": "^0.2.1", + "bower-registry-client": "^0.3.0", "cardinal": "0.4.4", "chalk": "^1.0.0", "chmodr": "0.1.0", From 00dc877f0a5a4d72139bb3bdfa1db4daf3a11cac Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 1 Apr 2015 00:35:54 -0700 Subject: [PATCH 0577/1021] 1.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7f6347d81..7c33c3367 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.4.0", + "version": "1.4.1", "description": "The browser package manager", "author": "Twitter", "licenses": [ From a1287416d40f944d58cb8f2e774e2076bfffd32f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 1 Apr 2015 00:38:21 -0700 Subject: [PATCH 0578/1021] Update changelog for 1.4.1 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6ed2396e..77c9dd5a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.4.1 - 2015-04-01 + +- [fix] Reading .bowerrc upwards directory tree ([#1763](https://github.com/bower/bower/issues/1763)) +- [fix] Update bower-registry-client so it uses the same bower-config as bower + ## 1.4.0 - 2015-03-30 - Add login and unregister commands ([#1719](https://github.com/bower/bower/issues/1719)) From 9dd79a80614925e10e5cead9e74f834051feece9 Mon Sep 17 00:00:00 2001 From: insanehong Date: Wed, 2 Jul 2014 15:36:14 +0900 Subject: [PATCH 0579/1021] Auto-sort bower.json dependencies alphabetically, fixes #1373 --- lib/core/Project.js | 5 +++-- package.json | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/core/Project.js b/lib/core/Project.js index 99ad7cfbf..be290d76e 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -14,6 +14,7 @@ var createError = require('../util/createError'); var readJson = require('../util/readJson'); var validLink = require('../util/validLink'); var scripts = require('./scripts'); +var sortobject = require('deep-sort-object'); function Project(config, logger) { // This is the only architecture component that ensures defaults @@ -98,11 +99,11 @@ Project.prototype.install = function (decEndpoints, options, config) { } if (that._options.save) { - that._json.dependencies = mout.object.mixIn(that._json.dependencies || {}, jsonEndpoint); + that._json.dependencies = sortobject(mout.object.mixIn(that._json.dependencies || {}, jsonEndpoint)); } if (that._options.saveDev) { - that._json.devDependencies = mout.object.mixIn(that._json.devDependencies || {}, jsonEndpoint); + that._json.devDependencies = sortobject(mout.object.mixIn(that._json.devDependencies || {}, jsonEndpoint)); } }); } diff --git a/package.json b/package.json index 7c33c3367..973df5108 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "chmodr": "0.1.0", "configstore": "^0.3.2", "decompress-zip": "^0.1.0", + "deep-sort-object": "~0.1.1", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", "github": "^0.2.3", From 87d21e7968c50d5b9ed38a8be876c5d18c6b3358 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 28 Apr 2015 12:34:28 +0700 Subject: [PATCH 0580/1021] use package.json `files` object to reduce the package size https://docs.npmjs.com/files/package.json#files --- package.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 973df5108..ec064531f 100644 --- a/package.json +++ b/package.json @@ -86,5 +86,10 @@ "bin": { "bower": "bin/bower" }, - "preferGlobal": true + "preferGlobal": true, + "files": [ + "bin", + "lib", + "templates" + ] } From 406a96e4d1cb2b70f3e76d6e8645288b142ca1da Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 28 Apr 2015 12:40:35 +0700 Subject: [PATCH 0581/1021] use package.json `files` object to reduce the package size https://docs.npmjs.com/files/package.json#files --- packages/bower-registry-client/package.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 869ad3d91..2eab18519 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -36,5 +36,9 @@ }, "scripts": { "test": "grunt test" - } + }, + "files": [ + "lib", + "Client.js" + ] } From 7603886e04eb9520d8e104547e1c55a9c2cb14a9 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 28 Apr 2015 12:41:43 +0700 Subject: [PATCH 0582/1021] minor package.json tweak --- packages/bower-config/package.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 10ee59ad3..e431381dc 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -9,10 +9,7 @@ "url": "https://github.com/bower/config/blob/master/LICENSE" } ], - "repository": { - "type": "git", - "url": "git://github.com/bower/config.git" - }, + "repository": "bower/config", "main": "lib/Config", "homepage": "http://bower.io", "engines": { From c65cdc8699b13bec5d42dd20312efbe17adc9aef Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 28 Apr 2015 12:42:26 +0700 Subject: [PATCH 0583/1021] use package.json `files` object to reduce the package size https://docs.npmjs.com/files/package.json#files --- packages/bower-config/package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index e431381dc..8626cc381 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -38,5 +38,8 @@ }, "scripts": { "test": "grunt test" - } + }, + "files": [ + "lib" + ] } From 6039f6c69132ba93827c43549e71d47cd4795782 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 28 Apr 2015 12:50:10 +0700 Subject: [PATCH 0584/1021] minor package.json tweak --- packages/bower-logger/package.json | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/bower-logger/package.json b/packages/bower-logger/package.json index 6c2dc7fa4..dbf88fe21 100644 --- a/packages/bower-logger/package.json +++ b/packages/bower-logger/package.json @@ -2,20 +2,18 @@ "name": "bower-logger", "version": "0.2.1", "description": "The logger used in the various architecture components of Bower.", - "author": "Twitter", + "author": "Bower", "licenses": [ { "type": "MIT", "url": "https://github.com/bower/logger/blob/master/LICENSE" } ], - "repository": { - "type": "git", - "url": "git://github.com/bower/logger.git" + "repository": "bower/logger", }, "main": "lib/Logger", "engines": { - "node": ">=0.8.0" + "node": ">=0.10.0" }, "devDependencies": { "expect.js": "~0.2.0", From b3390ce2012488c5dbbd702de5dcff6c594ce437 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 28 Apr 2015 12:50:37 +0700 Subject: [PATCH 0585/1021] use package.json `files` object to reduce the package size https://docs.npmjs.com/files/package.json#files --- packages/bower-logger/package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/bower-logger/package.json b/packages/bower-logger/package.json index dbf88fe21..320cbca75 100644 --- a/packages/bower-logger/package.json +++ b/packages/bower-logger/package.json @@ -21,5 +21,8 @@ }, "scripts": { "test": "mocha -R spec" - } + }, + "files": [ + "lib" + ] } From ccadffea73b13ef90825144c748ca0076e7d4976 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 28 Apr 2015 12:54:04 +0700 Subject: [PATCH 0586/1021] Update package.json --- packages/bower-logger/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/bower-logger/package.json b/packages/bower-logger/package.json index 320cbca75..a3c781907 100644 --- a/packages/bower-logger/package.json +++ b/packages/bower-logger/package.json @@ -10,7 +10,6 @@ } ], "repository": "bower/logger", - }, "main": "lib/Logger", "engines": { "node": ">=0.10.0" From dbb302f22a44cb8e903506e61bfda6c6b0d503bf Mon Sep 17 00:00:00 2001 From: Gilad Peleg Date: Tue, 19 May 2015 13:05:23 +0300 Subject: [PATCH 0587/1021] update license attribute specifying the type and URL is deprecated: https://docs.npmjs.com/files/package.json#license http://npm1k.org/ --- package.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/package.json b/package.json index ec064531f..d6bd09c04 100644 --- a/package.json +++ b/package.json @@ -3,12 +3,7 @@ "version": "1.4.1", "description": "The browser package manager", "author": "Twitter", - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/bower/bower/blob/master/LICENSE" - } - ], + "license": "MIT", "repository": "bower/bower", "main": "lib", "homepage": "http://bower.io", From 833f97198ecf2b8e44549e8c3c8a0318dd09856f Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 19 May 2015 20:55:20 +0200 Subject: [PATCH 0588/1021] minor package.json tweak --- package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/package.json b/package.json index d6bd09c04..447c1cb76 100644 --- a/package.json +++ b/package.json @@ -78,9 +78,7 @@ "scripts": { "test": "grunt test" }, - "bin": { - "bower": "bin/bower" - }, + "bin": "bin/bower", "preferGlobal": true, "files": [ "bin", From 065a7a1f1b98e83e88ed34622de3c26fd498ad9d Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 19 May 2015 22:06:35 +0200 Subject: [PATCH 0589/1021] bump deps --- packages/bower-json/package.json | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index bd1ac54c9..5bd946cf3 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -3,31 +3,26 @@ "version": "0.4.0", "description": "Read bower.json files with semantics, normalisation, defaults and validation", "author": "Twitter", - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/bower/json/blob/master/LICENSE" - } - ], + "license": "MIT", "repository": "bower/json", "main": "lib/json", "engines": { "node": ">=0.10.0" }, "dependencies": { - "deep-extend": "^0.3.2", + "deep-extend": "^0.4.0", "graceful-fs": "^3.0.0", - "intersect": "^0.1.0" + "intersect": "^1.0.1" }, "devDependencies": { "expect.js": "^0.3.1", "grunt": "^0.4.4", "grunt-cli": "^0.1.13", - "grunt-contrib-jshint": "^0.10.0", + "grunt-contrib-jshint": "^0.11.2", "grunt-contrib-watch": "^0.6.1", "grunt-simple-mocha": "^0.4.0", "mocha": "*", - "underscore.string": "^2.3.3" + "underscore.string": "^3.0.3" }, "scripts": { "test": "grunt test" From d5fc402a895d03d6a83c6196bb06d7831c911c42 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 19 May 2015 22:07:12 +0200 Subject: [PATCH 0590/1021] 0.5.0 --- packages/bower-json/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 5bd946cf3..aef88e284 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,6 +1,6 @@ { "name": "bower-json", - "version": "0.4.0", + "version": "0.5.0", "description": "Read bower.json files with semantics, normalisation, defaults and validation", "author": "Twitter", "license": "MIT", From 938c69c8168bd622b0aafcdc0d030cbdf2513b84 Mon Sep 17 00:00:00 2001 From: Peter deHaan Date: Wed, 20 May 2015 16:57:57 -0700 Subject: [PATCH 0591/1021] Update license attribute specifying the type and URL is deprecated: https://docs.npmjs.com/files/package.json#license http://npm1k.org/ --- packages/bower-config/package.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 8626cc381..fea8a45ef 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -3,12 +3,7 @@ "version": "0.6.1", "description": "The Bower config reader and writer.", "author": "Twitter", - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/bower/config/blob/master/LICENSE" - } - ], + "license": "MIT", "repository": "bower/config", "main": "lib/Config", "homepage": "http://bower.io", From 816cdda6bb0b6211809c17d3e4a5dc98363db98e Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Mon, 29 Jun 2015 12:34:14 +0200 Subject: [PATCH 0592/1021] doc: remove section about completion The completion command appears to have been lost during the rewrite (#1066). So to avoid confusion it should not be mentioned in the README. --- README.md | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/README.md b/README.md index e86569482..d0af4d4cf 100644 --- a/README.md +++ b/README.md @@ -81,21 +81,6 @@ path if needed. Bower can be configured using JSON in a `.bowerrc` file. Read over available options at [bower.io/docs/config](http://bower.io/docs/config). -## Completion (experimental) - -_NOTE_: Completion is still not implemented for the 1.0.0 release - -Bower now has an experimental `completion` command that is based on, and works -similarly to the [npm completion](https://npmjs.org/doc/cli/completion.html). It is -not available for Windows users. - -This command will output a Bash / ZSH script to put into your `~/.bashrc`, -`~/.bash_profile`, or `~/.zshrc` file. - -```sh -$ bower completion >> ~/.bash_profile -``` - ## Support From 50b0186c06c803d7accbb46b6cacb2d94b50dc07 Mon Sep 17 00:00:00 2001 From: Web Artisan Date: Tue, 30 Jun 2015 11:40:05 +0200 Subject: [PATCH 0593/1021] Added keywords tag Added keywords tag --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index 447c1cb76..c81f1e63d 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,9 @@ "engines": { "node": ">=0.10.0" }, + "keywords": [ + "bower" + ], "dependencies": { "abbrev": "^1.0.5", "archy": "1.0.0", From 95f46930a5076aa68a6adea9bd1f5fa5c0851c11 Mon Sep 17 00:00:00 2001 From: Chris Rebert Date: Tue, 30 Jun 2015 22:45:26 -0700 Subject: [PATCH 0594/1021] Remove non-spec-compliant comma-separated string interpretation of `main` See https://github.com/bower/bower.json-spec/#main --- packages/bower-json/lib/json.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index 20fddf1d3..aa7471862 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -115,7 +115,7 @@ function validate(json) { function normalize(json) { if (typeof json.main === 'string') { - json.main = json.main.split(','); + json.main = [json.main]; } // TODO From 1c62adcdb6f09875434de2d886c23731a0bae53c Mon Sep 17 00:00:00 2001 From: Chris Rebert Date: Tue, 30 Jun 2015 23:01:10 -0700 Subject: [PATCH 0595/1021] Validate that `main` conforms to the bower.json spec --- packages/bower-json/lib/json.js | 40 ++++++++++++++++ packages/bower-json/lib/util/isAsset.js | 12 +++++ packages/bower-json/package.json | 1 + packages/bower-json/test/test.js | 63 +++++++++++++++++++++++++ 4 files changed, 116 insertions(+) create mode 100644 packages/bower-json/lib/util/isAsset.js diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index 20fddf1d3..bc0a8f262 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -1,6 +1,7 @@ var fs = require('graceful-fs'); var path = require('path'); var deepExtend = require('deep-extend'); +var isAsset = require('./util/isAsset'); var isComponent = require('./util/isComponent'); var createError = require('./util/createError'); @@ -108,6 +109,45 @@ function validate(json) { throw createError('The description is too long. 140 characters should be more than enough', 'EINVALID'); } + if (json.main !== undefined) { + var main = json.main; + if (typeof main === 'string') { + main = [main]; + } + if (!(main instanceof Array)) { + throw createError('The "main" field has to be either an Array or a String', 'EINVALID'); + } + var ext2files = {}; + main.forEach(function (filename) { + if (typeof filename !== 'string') { + throw createError('The "main" Array has to contain only Strings', 'EINVALID'); + } + if (/[*]/.test(filename)) { + throw createError('The "main" field cannot contain globs (example: "*.js")', 'EINVALID'); + } + if (/[.]min[.][^/]+$/.test(filename)) { + throw createError('The "main" field cannot contain minified files', 'EINVALID'); + } + if (isAsset(filename)) { + throw createError('The "main" field cannot contain font, image, audio, or video files', 'EINVALID'); + } + var ext = path.extname(filename); + if (ext.length >= 2) { + var files = ext2files[ext]; + if (!files) { + files = ext2files[ext] = []; + } + files.push(filename); + } + }); + Object.keys(ext2files).forEach(function (ext) { + var files = ext2files[ext]; + if (files.length > 1) { + throw createError('The "main" field has to contain only 1 file per filetype; found multiple ' + ext + ' files: ' + JSON.stringify(files), 'EINVALID'); + } + }); + } + // TODO https://github.com/bower/bower.json-spec return json; diff --git a/packages/bower-json/lib/util/isAsset.js b/packages/bower-json/lib/util/isAsset.js new file mode 100644 index 000000000..e373cb1d5 --- /dev/null +++ b/packages/bower-json/lib/util/isAsset.js @@ -0,0 +1,12 @@ +var extName = require('ext-name'); + +function isAsset(filename) { + var info = extName(filename); + + return info && info.mime && ( + /^((image)|(audio)|(video)|(font))\//.test(info.mime) || + /application\/((x[-]font[-])|(font[-]woff(\d?))|(vnd[.]ms[-]fontobject))/.test(info.mime) + ); +} + +module.exports = isAsset; diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index aef88e284..6d77fd2c6 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "deep-extend": "^0.4.0", + "ext-name": "^3.0.0", "graceful-fs": "^3.0.0", "intersect": "^1.0.1" }, diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index c70758205..becdb4218 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -243,6 +243,69 @@ describe('.validate', function () { bowerJson.validate(json); }).to.not.throwException(); }); + it('should validate the type of main', function () { + var json = { + name: 'foo', + main: {} + }; + expect(function () { + bowerJson.validate(json); + }).to.throwException(); + }); + it('should validate the type of items of an Array main', function () { + var json = { + name: 'foo', + main: [{}] + }; + expect(function () { + bowerJson.validate(json); + }).to.throwException(); + }); + it('should validate that main does not contain globs', function () { + var json = { + name: 'foo', + main: ['js/*.js'] + }; + expect(function () { + bowerJson.validate(json); + }).to.throwException(); + }); + it('should validate that main does not contain minified files', function () { + expect(function () { + bowerJson.validate(json); + }).to.throwException(); + var json = { + name: 'foo', + main: ['foo.min.css'] + }; + }); + it('should validate that main does not contain fonts', function () { + var json = { + name: 'foo', + main: ['foo.woff'] + }; + expect(function () { + bowerJson.validate(json); + }).to.throwException(); + }); + it('should validate that main does not contain images', function () { + var json = { + name: 'foo', + main: ['foo.png'] + }; + expect(function () { + bowerJson.validate(json); + }).to.throwException(); + }); + it('should validate that main does not contain multiple files of the same filetype', function () { + var json = { + name: 'foo', + main: ['foo.js', 'bar.js'] + }; + expect(function () { + bowerJson.validate(json); + }).to.throwException(); + }); }); describe('.normalize', function () { From ada6fc18d9becdc0e015d3c331022585c5742a20 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 9 Jul 2015 18:30:26 +0300 Subject: [PATCH 0596/1021] Implement initial version of pluggable resolvers --- lib/core/Manager.js | 51 ++++++- lib/core/PackageRepository.js | 2 +- lib/core/resolverFactory.js | 201 +++++++++++++++----------- lib/core/resolvers/PluginResolver.js | 204 +++++++++++++++++++++++++++ 4 files changed, 368 insertions(+), 90 deletions(-) create mode 100644 lib/core/resolvers/PluginResolver.js diff --git a/lib/core/Manager.js b/lib/core/Manager.js index a6a9125e1..6ddb97a75 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -80,6 +80,17 @@ Manager.prototype.configure = function (setup) { return this; }; +/** + * It starts recursive fetching of targets. The flow is as follows: + * + * 1. this._fetch() that calls: + * 2. this._onFetchError() or this._onFetchSuccess() that calls: + * 3. this._parseDependencies() that calls for all dependencies: + * 4. this._fetch() again. + * + * Fetching and parsing of dependencies continues until all dependencies are fetched. + * + */ Manager.prototype.resolve = function () { // If already resolving, error out if (this._working) { @@ -337,7 +348,7 @@ Manager.prototype._onFetchSuccess = function (decEndpoint, canonicalDir, pkgMeta resolved.push(decEndpoint); // Parse dependencies - this._parseDependencies(decEndpoint, pkgMeta, 'dependencies'); + this._parseDependencies(decEndpoint, pkgMeta); // Check if there are incompatibilities for this package name // If there are, we need to fetch them @@ -414,13 +425,21 @@ Manager.prototype._failFast = function () { }.bind(this), 20000); }; -Manager.prototype._parseDependencies = function (decEndpoint, pkgMeta, jsonKey) { +/** + * Parses decEndpoint dependencies and fetches missing ones. + * + * It fetches all non-yet-fetching dependencies with _fetch. + * + * + * @param {string} pkgMeta Metadata of package to resolve dependencies. + */ +Manager.prototype._parseDependencies = function (decEndpoint, pkgMeta) { var pending = []; decEndpoint.dependencies = decEndpoint.dependencies || {}; // Parse package dependencies - mout.object.forOwn(pkgMeta[jsonKey], function (value, key) { + mout.object.forOwn(pkgMeta.dependencies, function (value, key) { var resolved; var fetching; var compatible; @@ -489,11 +508,24 @@ Manager.prototype._parseDependencies = function (decEndpoint, pkgMeta, jsonKey) if (pending.length > 0) { Q.all(pending) .then(function () { - this._parseDependencies(decEndpoint, pkgMeta, jsonKey); + this._parseDependencies(decEndpoint, pkgMeta); }.bind(this)); } }; +/** + * After batch of packages has been fetched, the results are stored in _resolved hash. + * + * { + * packageName: [array, of, decEndpoints] + * } + * + * This method takes all possible decEndpoints and selects only one of them per packageName. + * + * It stores selected packages in the this._dissected array. + * + * The _dissected array is used later on by install method to move packages to config.directory. + */ Manager.prototype._dissect = function () { var err; var componentsDir; @@ -571,6 +603,11 @@ Manager.prototype._dissect = function () { return; } + // Packages that didn't have any conflicts in resolution yet have + // "resolution" entry in bower.json are deemed unnecessary + // + // Probably in future we want to use them for force given resolution, but for now... + // See: https://github.com/bower/bower/issues/1362 this._logger.warn('extra-resolution', 'Unnecessary resolution: ' + name + '#' + resolution, { name: name, resolution: resolution, @@ -590,12 +627,16 @@ Manager.prototype._dissect = function () { } // Skip if source is the same as dest + // FIXME: Shoudn't we force installation if force flag is used here? dst = path.join(componentsDir, name); if (dst === decEndpoint.canonicalDir) { return false; } - // Analyse a few props + // We skip installing decEndpoint, if: + // 1. We have installed package with the same name + // 2. Packages have matching meta fields (needs explanation) + // 3. We didn't force the installation if (installedMeta && installedMeta._target === decEndpoint.target && installedMeta._originalSource === decEndpoint.source && diff --git a/lib/core/PackageRepository.js b/lib/core/PackageRepository.js index 43f0ec53e..a39396b87 100644 --- a/lib/core/PackageRepository.js +++ b/lib/core/PackageRepository.js @@ -117,7 +117,7 @@ PackageRepository.prototype.fetch = function (decEndpoint) { PackageRepository.prototype.versions = function (source) { // Resolve the source using the factory because the // source can actually be a registry name - return resolverFactory.getConstructor(source, this._config, this._registryClient) + return resolverFactory.getConstructor(source, this._config, this._logger, this._registryClient) .spread(function (ConcreteResolver, source) { // If offline, resolve using the cached versions if (this._config.offline) { diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index 2e01b017e..fe5136ae5 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -5,8 +5,10 @@ var mout = require('mout'); var resolvers = require('./resolvers'); var createError = require('../util/createError'); +var pluginResolver = require('./resolvers/PluginResolver'); + function createInstance(decEndpoint, config, logger, registryClient) { - return getConstructor(decEndpoint.source, config, registryClient) + return getConstructor(decEndpoint.source, config, logger, registryClient) .spread(function (ConcreteResolver, source, fromRegistry) { var decEndpointCopy = mout.object.pick(decEndpoint, ['name', 'target']); @@ -25,16 +27,63 @@ function createInstance(decEndpoint, config, logger, registryClient) { }); } -function getConstructor(source, config, registryClient) { - var absolutePath, - promise; +function getConstructor(source, config, logger, registryClient) { + // Below we try a series of async tests to guess the type of resolver to use + // If a step was unable to guess the resolver, it returns undefined + // If a step was able to guess the resolver, it resolves with construcotor of resolver + + var promise = Q.resolve(); + + var addResolver = function (getConstructor) { + promise = promise.then(function (result) { + if (result === undefined) { + return getConstructor(source, config, logger); + } else { + return result; + } + }); + }; + + // Plugin resolvers. It requires each resolver defined in config.resolvers + // and calls its match function that returns instance of resolver or undefined + // + // Instance of resolver is then + addResolver(function (source, config, logger) { + var selectedResolver; + + var resolverNames = config.resolvers || []; + + var resolverOptions = { config: config, logger: logger }; + + var resolverPromises = resolverNames.map(function (resolverName) { + var resolver = resolvers[resolverName] || pluginResolver(resolverName, resolverOptions); + + return function () { + if (selectedResolver === undefined) { + return Q.when(resolver.matches(source)).then(function (result) { + if (result) { + return selectedResolver = resolver; + } + }); + } else { + return selectedResolver; + } + }; + }); + + return resolverPromises.reduce(Q.when, new Q(undefined)).then(function (resolver) { + if (resolver) { + return [resolver, source]; + } + }); + }); // Git case: git git+ssh, git+http, git+https // .git at the end (probably ssh shorthand) // git@ at the start - if (/^git(\+(ssh|https?))?:\/\//i.test(source) || /\.git\/?$/i.test(source) || /^git@/i.test(source)) { - source = source.replace(/^git\+/, ''); - return Q.fcall(function () { + addResolver(function(source, config) { + if (/^git(\+(ssh|https?))?:\/\//i.test(source) || /\.git\/?$/i.test(source) || /^git@/i.test(source)) { + source = source.replace(/^git\+/, ''); // If it's a GitHub repository, return the specialized resolver if (resolvers.GitHub.getOrgRepoPair(source)) { @@ -42,80 +91,70 @@ function getConstructor(source, config, registryClient) { } return [resolvers.GitRemote, source]; - }); - } + } + }); // SVN case: svn, svn+ssh, svn+http, svn+https, svn+file - if (/^svn(\+(ssh|https?|file))?:\/\//i.test(source)) { - return Q.fcall(function () { + addResolver(function (source, config) { + if (/^svn(\+(ssh|https?|file))?:\/\//i.test(source)) { return [resolvers.Svn, source]; - }); - } + } + }); // URL case - if (/^https?:\/\//i.exec(source)) { - return Q.fcall(function () { + addResolver(function (source, config) { + if (/^https?:\/\//i.exec(source)) { return [resolvers.Url, source]; - }); - } + } + }); - // Below we try a series of async tests to guess the type of resolver to use - // If a step was unable to guess the resolver, it throws an error - // If a step was able to guess the resolver, it resolves with a function - // That function returns a promise that will resolve with the concrete type // If source is ./ or ../ or an absolute path - absolutePath = path.resolve(config.cwd, source); - if (/^\.\.?[\/\\]/.test(source) || /^~\//.test(source) || path.normalize(source).replace(/[\/\\]+$/, '') === absolutePath) { - promise = Q.nfcall(fs.stat, path.join(absolutePath, '.git')) - .then(function (stats) { - if (stats.isDirectory()) { - return function () { - return Q.resolve([resolvers.GitFs, absolutePath]); - }; - } + addResolver(function (source, config) { + var absolutePath = path.resolve(config.cwd, source); - throw new Error('Not a Git repository'); - }) - // If not, check if source is a valid Subversion repository - .fail(function () { - return Q.nfcall(fs.stat, path.join(absolutePath, '.svn')) + if (/^\.\.?[\/\\]/.test(source) || /^~\//.test(source) || + path.normalize(source).replace(/[\/\\]+$/, '') === absolutePath + ) { + return Q.nfcall(fs.stat, path.join(absolutePath, '.git')) .then(function (stats) { if (stats.isDirectory()) { - return function () { - return Q.resolve([resolvers.Svn, absolutePath]); - }; + return Q.resolve([resolvers.GitFs, absolutePath]); } - throw new Error('Not a Subversion repository'); - }); - }) - // If not, check if source is a valid file/folder - .fail(function () { - return Q.nfcall(fs.stat, absolutePath) - .then(function () { - return function () { + throw new Error('Not a Git repository'); + }) + // If not, check if source is a valid Subversion repository + .fail(function () { + return Q.nfcall(fs.stat, path.join(absolutePath, '.svn')) + .then(function (stats) { + if (stats.isDirectory()) { + return Q.resolve([resolvers.Svn, absolutePath]); + } + + throw new Error('Not a Subversion repository'); + }); + }) + // If not, check if source is a valid file/folder + .fail(function () { + return Q.nfcall(fs.stat, absolutePath) + .then(function () { return Q.resolve([resolvers.Fs, absolutePath]); - }; + }); }); - }); - } else { - promise = Q.reject(new Error('Not an absolute or relative file')); - } + } + }); - return promise // Check if is a shorthand and expand it - .fail(function (err) { - var parts; - + addResolver(function (source, config) { // Skip ssh and/or URL with auth if (/[:@]/.test(source)) { - throw err; + return; } // Ensure exactly only one "/" - parts = source.split('/'); + var parts = source.split('/'); if (parts.length === 2) { source = mout.string.interpolate(config.shorthandResolver, { shorthand: source, @@ -123,44 +162,38 @@ function getConstructor(source, config, registryClient) { package: parts[1] }); - return function () { - return getConstructor(source, config, registryClient); - }; + return getConstructor(source, config, logger, registryClient); } + }); - throw err; - }) // As last resort, we try the registry - .fail(function (err) { + addResolver(function (source, config) { if (!registryClient) { - throw err; + return; } - return function () { - return Q.nfcall(registryClient.lookup.bind(registryClient), source) - .then(function (entry) { - if (!entry) { - throw createError('Package ' + source + ' not found', 'ENOTFOUND'); - } + return Q.nfcall(registryClient.lookup.bind(registryClient), source) + .then(function (entry) { + if (!entry) { + throw createError('Package ' + source + ' not found', 'ENOTFOUND'); + } - // TODO: Handle entry.type.. for now it's only 'alias' - // When we got published packages, this needs to be adjusted - source = entry.url; + // TODO: Handle entry.type.. for now it's only 'alias' + // When we got published packages, this needs to be adjusted + source = entry.url; - return getConstructor(source, config, registryClient) - .spread(function (ConcreteResolver, source) { - return [ConcreteResolver, source, true]; - }); + return getConstructor(source, config, logger, registryClient) + .spread(function (ConcreteResolver, source) { + return [ConcreteResolver, source, true]; }); - }; - }) - // If we got the function, simply call and return - .then(function (func) { - return func(); - // Finally throw a meaningful error - }, function () { + }); + }); + + addResolver(function () { throw createError('Could not find appropriate resolver for ' + source, 'ENORESOLVER'); }); + + return promise; } function clearRuntimeCache() { diff --git a/lib/core/resolvers/PluginResolver.js b/lib/core/resolvers/PluginResolver.js new file mode 100644 index 000000000..66c7ef833 --- /dev/null +++ b/lib/core/resolvers/PluginResolver.js @@ -0,0 +1,204 @@ +var util = require('util'); +var mout = require('mout'); +var Q = require('q'); +var Resolver = require('./Resolver'); +var LRU = require('lru-cache'); +var semver = require('../../util/semver'); +var createError = require('../../util/createError'); +var path = require('path'); + + +function Adapter(pluginName, options) { + var pluginFactory = require(pluginName); + + var plugin = pluginFactory(options); + + function PluginResolver(decEndpoint) { + this._source = decEndpoint.source; + this._target = decEndpoint.target || '*'; + this._name = decEndpoint.name; + + this._config = options.config; + this._logger = options.logger; + } + + util.inherits(PluginResolver, Resolver); + mout.object.mixIn(PluginResolver, Resolver); + + PluginResolver.getName = function() { + if (!this._name && plugin.getName) { + this._name = plugin.getName(this._source); + } + + if (!this._name) { + this._name = path.basename(this._source); + } + + if (this._name) { + return this._name; + } + }; + + // ----------------- + + function maxSatisfyingVersion(versions, target) { + var versionsArr, index; + + versionsArr = versions.map(function (obj) { return obj.version; }); + + // Find a satisfying version, enabling strict match so that pre-releases + // have lower priority over normal ones when target is * + index = semver.maxSatisfyingIndex(versionsArr, target, true); + + if (index !== -1) { + return versions[index]; + } + } + + // Plugin Resolver is always considered potentially cacheable + // The "resolve" method decides whether to use cached or fetch new version. + PluginResolver.prototype.isCacheable = function() { + return true; + }; + + // Not only it's always potentially cacheable, but also always potenially new. + // The "resolve" handles logic of re-downloading target if new one is available. + PluginResolver.prototype.hasNew = function (canonicalDir, pkgMeta) { + if (this.hasNewPromise) { + return this.hasNewPromise; + } + + this._canonicalDir = canonicalDir; + this._oldPkgMeta = pkgMeta; + this._resolution = pkgMeta._resolution; + + return this.hasNewPromise = this.resolve().then(function (result) { + return result !== undefined; + }); + }; + + PluginResolver.prototype.resolve = function () { + if (this.resolvePromise) { + return this.resolvePromise; + } + + // If already working, error out + if (this._working) { + return Q.reject(createError('Already working', 'EWORKING')); + } + + this._working = true; + + var that = this; + + var target = this._target; + + return this.resolvePromise = Q.fcall(function() { + // It means that we can accept ranges as targets + if(that.constructor.isTargetable()) { + if (semver.validRange(target)) { + return plugin.versions(that._source) + .then(function (versions) { + var maxVersion = maxSatisfyingVersion(versions, target); + + if (maxVersion) { + return maxVersion.target; + } else { + return Q.reject(new Error('The range ' + target + ' does not match any version of ' + that._source)); + } + }); + } else { + return target; + } + } else { + if (semver.validRange(target) && target !== '*') { + return Q.reject(createError('Resolver ' + pluginName + ' does not accept version ranges (' + target + ')')); + } + + return target; + } + }) + .then(function (target) { + // We pass old _resolution (if hasNew has been called before fetch). + // So plugin can decide wheter use cached version of fetch new one. + return plugin.fetch(that._source, target, that._resolution); + }) + .then(function (result) { + // Empty result means to re-use existing resolution + if (!result) { + return; + } else { + if (!result.contents) { + throw createError('Resolver did not provide path to extracted package contents.'); + } + + that._tempDir = result.contents; + + return that._readJson().then(function (meta) { + return that._applyPkgMeta(meta) + .then(that._savePkgMeta.bind(that, meta, result.resolution)) + .then(function () { + return that._tempDir; + }); + }); + } + }) + .catch(function(e) { + e.code = pluginName; + throw e; + }) + .fin(function () { + that._working = false; + }); + }; + + PluginResolver.prototype._savePkgMeta = function (meta, resolution) { + if (this.constructor.isTargetable()) { + meta._resolution = resolution; + meta._release = resolution.target; + } + + return Resolver.prototype._savePkgMeta.call(this, meta); + }; + + PluginResolver.versions = function (source) { + return plugin.versions(source).then(function (versions) { + versions = versions.filter(function (version) { + return versions.version !== undefined; + }); + + versions = versions.map(function (version) { + return semver.clean(versions.version); + }); + + versions.sort(function (a, b) { + return semver.rcompare(a.version, b.version); + }); + + return versions; + }); + }; + + PluginResolver.isTargetable = function() { + // If plugin doesn't define versions function, it's not targetable.. + return typeof plugin.versions === 'function'; + }; + + PluginResolver.clearRuntimeCache = function () { + plugin = pluginFactory(options); + PluginResolver._cache.versions.reset(); + }; + + PluginResolver._cache = { + versions: new LRU({ max: 50, maxAge: 5 * 60 * 1000 }) + }; + + PluginResolver.matches = function (source) { + return plugin.matches(source); + }; + + return PluginResolver; +} + + +module.exports = Adapter; From a1596bb63c69eae0fafceb3a3f9946b7f383fa22 Mon Sep 17 00:00:00 2001 From: Chris Rebert Date: Mon, 13 Jul 2015 19:17:20 -0700 Subject: [PATCH 0597/1021] 0.6.0 --- packages/bower-json/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 6d77fd2c6..261ff2244 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,6 +1,6 @@ { "name": "bower-json", - "version": "0.5.0", + "version": "0.6.0", "description": "Read bower.json files with semantics, normalisation, defaults and validation", "author": "Twitter", "license": "MIT", From 8744449016d292de7703ef28a7dda478441e5514 Mon Sep 17 00:00:00 2001 From: Peter Chanthamynavong Date: Sun, 12 Jul 2015 11:51:44 -0700 Subject: [PATCH 0598/1021] upgrade to newer semver, fixes #1817,#1845,#1851 Upgrading to latest version of semver to fix (#1817, #1845, #1851). Possible breaking changes in regards to the way semvers handles pre-releases. If a version has a prerelease tags (for example, 1.2.3-alpha.3) then it will only be allowed to satisfy comparator sets if at least one comparator with the same [major, minor, patch] tuple also has a prerelease tag. For example, the range >1.2.3-alpha.0 would be allowed to match the version 1.2.3-alpha.7, but it would not be satisfied by * or 1.2.3. See [semvers](https://github.com/npm/node-semver#prerelease-tags) additional details. --- package.json | 2 +- test/core/resolveCache.js | 32 +++++++++++++++++++++++++++++- test/core/resolvers/gitResolver.js | 31 ++++++++++++++++++++++++++--- test/core/resolvers/svnResolver.js | 28 ++++++++++++++++++++++++-- 4 files changed, 86 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 447c1cb76..b976921af 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "request-progress": "0.3.1", "retry": "0.6.1", "rimraf": "^2.2.8", - "semver": "^2.3.0", + "semver": "^5.0.1", "shell-quote": "^1.4.2", "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", diff --git a/test/core/resolveCache.js b/test/core/resolveCache.js index 9ea798ede..7f7830bef 100644 --- a/test/core/resolveCache.js +++ b/test/core/resolveCache.js @@ -513,7 +513,7 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir, '0.1.0-rc.2')); fs.writeFileSync(path.join(sourceDir, '0.1.0-rc.2', '.bower.json'), JSON.stringify(json, null, ' ')); - resolveCache.retrieve(source, '~0.1.0') + resolveCache.retrieve(source, '~0.1.0 || ~0.1.0-rc.0') .spread(function (canonicalDir, pkgMeta) { expect(pkgMeta).to.be.an('object'); expect(pkgMeta.version).to.equal('0.1.0-rc.2'); @@ -524,6 +524,36 @@ describe('ResolveCache', function () { .done(); }); + it('should resolve to the highest package that matches an x-range target, ignoring pre-releases versions', function (next) { + var source = String(Math.random()); + var sourceId = md5(source); + var sourceDir = path.join(cacheDir, sourceId); + var json = { name: 'foo' }; + + // Create some versions + fs.mkdirSync(sourceDir); + + // fix #1817 : >=1.2.x <=1.4.x which resolved to 1.3.16 + + json.version = '1.3.16-rc.1'; + fs.mkdirSync(path.join(sourceDir, json.version)); + fs.writeFileSync(path.join(sourceDir, json.version, '.bower.json'), JSON.stringify(json, null, ' ')); + + json.version = '1.3.16'; + fs.mkdirSync(path.join(sourceDir, json.version)); + fs.writeFileSync(path.join(sourceDir, json.version, '.bower.json'), JSON.stringify(json, null, ' ')); + + resolveCache.retrieve(source, '>=1.2.x <=1.4.x') + .spread(function (canonicalDir, pkgMeta) { + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta.version).to.equal('1.3.16'); + expect(canonicalDir).to.equal(path.join(sourceDir, '1.3.16')); + + next(); + }) + .done(); + }); + it('should resolve to exact match (including build metadata) if available', function (next) { var source = String(Math.random()); var sourceId = md5(source); diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index cb74e9822..b7d0dbeb2 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -506,7 +506,7 @@ describe('GitResolver', function () { .done(); }); - it('should resolve "*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { + it('should fail to resolve "*" if a repository has valid semver tags, ignoring pre-releases if they are the only versions', function (next) { var resolver; GitResolver.refs = function () { @@ -519,6 +519,31 @@ describe('GitResolver', function () { resolver = create('foo'); resolver._findResolution('*') + .then(function () { + next(new Error('Should have failed')); + }, function (err) { + expect(err).to.be.an(Error); + expect(err.message).to.match(/no tag found that was able to satisfy/i); + expect(err.details).to.match(/0.1.0-rc/i); + expect(err.code).to.equal('ENORESTARGET'); + next(); + }) + .done(); + }); + + it('should resolve "* || >=0.1.0-rc.0" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { + var resolver; + + GitResolver.refs = function () { + return Q.resolve([ + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.1.0-rc.1', + 'cccccccccccccccccccccccccccccccccccccccc refs/tags/0.1.0-rc.2' + ]); + }; + + resolver = create('foo'); + resolver._findResolution('* || >=0.1.0-rc.0') .then(function (resolution) { expect(resolution).to.eql({ type: 'version', @@ -542,7 +567,7 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('0.1.*') + resolver._findResolution('0.1.* || >=0.1.0-rc.1') .then(function (resolution) { expect(resolution).to.eql({ type: 'version', @@ -642,7 +667,7 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('~0.2.1') + resolver._findResolution('~0.2.1-rc.0') .then(function (resolution) { expect(resolution).to.eql({ type: 'version', diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index 47a8a5a37..259aa1e47 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -362,7 +362,7 @@ else describe('SvnResolver', function () { .done(); }); - it('should resolve "*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { + it('should fail to resolve "*" if a repository has valid semver tags, ignoring pre-releases if they are the only versions', function (next) { var resolver; SvnResolver.tags = function () { @@ -374,6 +374,30 @@ else describe('SvnResolver', function () { resolver = create('foo'); resolver._findResolution('*') + .then(function () { + next(new Error('Should have failed')); + }, function (err) { + expect(err).to.be.an(Error); + expect(err.message).to.match(/no tag found that was able to satisfy/i); + expect(err.details).to.match(/0.1.0-rc/i); + expect(err.code).to.equal('ENORESTARGET'); + next(); + }) + .done(); + }); + + it('should resolve "*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { + var resolver; + + SvnResolver.tags = function () { + return Q.resolve({ + '0.1.0-rc.1': 1, + '0.1.0-rc.2': 2 + }); + }; + + resolver = create('foo'); + resolver._findResolution('* || >=0.1.0-rc.0') .then(function (resolution) { expect(resolution).to.eql({ type: 'version', @@ -445,7 +469,7 @@ else describe('SvnResolver', function () { }; resolver = create('foo'); - resolver._findResolution('~0.2.1') + resolver._findResolution('~0.2.1 || ~0.2.1-rc.0') .then(function (resolution) { expect(resolution).to.eql({ type: 'version', From 50fd944a62ffe1cf727f15f0f8fa98422b46ecd9 Mon Sep 17 00:00:00 2001 From: jody tate Date: Tue, 28 Jul 2015 08:19:05 -0700 Subject: [PATCH 0599/1021] change to use a standard three dot ellipsis --- lib/commands/list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/commands/list.js b/lib/commands/list.js index ed68cbd83..a9afcb54c 100644 --- a/lib/commands/list.js +++ b/lib/commands/list.js @@ -81,7 +81,7 @@ function checkVersions(project, tree, logger) { }, true); if (nodes.length) { - logger.info('check-new', 'Checking for new versions of the project dependencies..'); + logger.info('check-new', 'Checking for new versions of the project dependencies...'); } // Check for new versions for each node From 2817936b877e3cd288c8c2f3fdfe45118d724c07 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 28 Jul 2015 22:22:56 +0200 Subject: [PATCH 0600/1021] No longer prefer installing bower as global Installing bower locally if perfectly good. It allows to use different version of bower locally. The next step is to create bower-cli package that can run local bower installation. --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index b976921af..50fb4e29f 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,6 @@ "test": "grunt test" }, "bin": "bin/bower", - "preferGlobal": true, "files": [ "bin", "lib", From 7acafc26d6207e44794b02402cdf6b9f66c53f01 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 28 Jul 2015 23:22:44 +0200 Subject: [PATCH 0601/1021] Make bower commands work from subdirectories --- lib/config.js | 10 +++++++++- package.json | 1 + test/commands/install.js | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/lib/config.js b/lib/config.js index b8d780edb..2e148a87d 100644 --- a/lib/config.js +++ b/lib/config.js @@ -2,13 +2,21 @@ var tty = require('tty'); var object = require('mout').object; var bowerConfig = require('bower-config'); var Configstore = require('configstore'); +var findup = require('findup-sync'); +var path = require('path'); var cachedConfigs = {}; function defaultConfig(config) { config = config || {}; - var cachedConfig = readCachedConfig(config.cwd || process.cwd()); + var cwd = path.dirname(findup('bower.json', { + cwd: config.cwd || process.cwd() + })) || config.cwd || process.cwd(); + + config.cwd = cwd; + + var cachedConfig = readCachedConfig(cwd); return object.merge(cachedConfig, config); } diff --git a/package.json b/package.json index b976921af..21438c77a 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "configstore": "^0.3.2", "decompress-zip": "^0.1.0", "deep-sort-object": "~0.1.1", + "findup-sync": "^0.2.1", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", "github": "^0.2.3", diff --git a/test/commands/install.js b/test/commands/install.js index 765fc0947..9cb8efd91 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -133,6 +133,25 @@ describe('bower install', function () { }); }); + it.only('works if bower is run in child directory', function () { + package.prepare({ foo: 'bar' }); + + tempDir.prepare({ + '.bowerrc': { directory: 'assets' }, + 'foo/bar/baz.txt': 'Hello world', + 'bower.json': { + name: 'test', + dependencies: { + package: package.path + } + } + }); + + return helpers.run(install, [undefined, undefined, { cwd: tempDir.path + '/foo/bar' }]).then(function() { + expect(tempDir.read('assets/package/foo')).to.be('bar'); + }); + }); + it('runs preinstall hook', function () { package.prepare(); From 749d46930d8c817010406627fc1f5c76c4b3581d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 29 Jul 2015 00:02:12 +0200 Subject: [PATCH 0602/1021] Mention about issue with node path on Ubuntu --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index d0af4d4cf..97f89c662 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,14 @@ password, you should add the following environment variable: `GIT_SSH - C:\Program Files\TortoiseGit\bin\TortoisePlink.exe`. Adjust the `TortoisePlink` path if needed. +### Ubuntu users + +To use Bower on Ubuntu, you might need to link `nodejs` executable to `node`: + +``` +sudo ln -s /usr/bin/nodejs /usr/bin/node +``` + ## Configuration Bower can be configured using JSON in a `.bowerrc` file. Read over available options at [bower.io/docs/config](http://bower.io/docs/config). From 4fc2b5cf76de6c9daca6373478f8b35d3343597c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 4 Aug 2015 06:21:06 +0200 Subject: [PATCH 0603/1021] Add tests and improve resolver interface --- lib/core/PackageRepository.js | 20 +- lib/core/resolverFactory.js | 106 +++---- lib/core/resolvers/GitResolver.js | 2 +- lib/core/resolvers/PluginResolver.js | 204 ------------- lib/core/resolvers/Resolver.js | 24 +- lib/core/resolvers/SvnResolver.js | 2 +- lib/core/resolvers/UrlResolver.js | 2 +- lib/core/resolvers/pluginResolverFactory.js | 309 ++++++++++++++++++++ test/core/packageRepository.js | 21 +- test/core/resolverFactory.js | 68 ++++- test/core/resolvers/fsResolver.js | 8 +- test/core/resolvers/gitResolver.js | 56 ++-- test/core/resolvers/resolver.js | 39 +-- test/core/resolvers/svnResolver.js | 40 +-- test/core/resolvers/urlResolver.js | 30 +- 15 files changed, 532 insertions(+), 399 deletions(-) delete mode 100644 lib/core/resolvers/PluginResolver.js create mode 100644 lib/core/resolvers/pluginResolverFactory.js diff --git a/lib/core/PackageRepository.js b/lib/core/PackageRepository.js index a39396b87..25084ed81 100644 --- a/lib/core/PackageRepository.js +++ b/lib/core/PackageRepository.js @@ -38,8 +38,7 @@ PackageRepository.prototype.fetch = function (decEndpoint) { that._extendLog(log, info); }); - // Get the appropriate resolver - return resolverFactory(decEndpoint, this._config, logger, this._registryClient) + return this._getResolver(decEndpoint, logger) // Decide if we retrieve from the cache or not // Also decide if we validate the cached entry or not .then(function (resolver) { @@ -91,7 +90,7 @@ PackageRepository.prototype.fetch = function (decEndpoint) { logger.action('validate', (pkgMeta._release ? pkgMeta._release + ' against ': '') + resolver.getSource() + (resolver.getTarget() ? '#' + resolver.getTarget() : '')); - return resolver.hasNew(canonicalDir, pkgMeta) + return resolver.hasNew(pkgMeta) .then(function (hasNew) { // If there are no new contents, resolve to // the cached one @@ -117,15 +116,15 @@ PackageRepository.prototype.fetch = function (decEndpoint) { PackageRepository.prototype.versions = function (source) { // Resolve the source using the factory because the // source can actually be a registry name - return resolverFactory.getConstructor(source, this._config, this._logger, this._registryClient) - .spread(function (ConcreteResolver, source) { + return this._getResolver({ source: source }) + .then(function (resolver) { // If offline, resolve using the cached versions if (this._config.offline) { - return this._resolveCache.versions(source); + return this._resolveCache.versions(resolver.getSource()); } // Otherwise, fetch remotely - return ConcreteResolver.versions(source); + return resolver.constructor.versions(resolver.getSource()); }.bind(this)); }; @@ -168,6 +167,13 @@ PackageRepository.clearRuntimeCache = function () { // --------------------- +PackageRepository.prototype._getResolver = function (decEndpoint, logger) { + logger = logger || this._logger; + + // Get the appropriate resolver + return resolverFactory(decEndpoint, { config: this._config, logger: logger }, this._registryClient); +}; + PackageRepository.prototype._resolve = function (resolver, logger) { var that = this; diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index fe5136ae5..80de7f28d 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -5,62 +5,55 @@ var mout = require('mout'); var resolvers = require('./resolvers'); var createError = require('../util/createError'); -var pluginResolver = require('./resolvers/PluginResolver'); +var pluginResolverFactory = require('./resolvers/pluginResolverFactory'); -function createInstance(decEndpoint, config, logger, registryClient) { - return getConstructor(decEndpoint.source, config, logger, registryClient) - .spread(function (ConcreteResolver, source, fromRegistry) { - var decEndpointCopy = mout.object.pick(decEndpoint, ['name', 'target']); +function createInstance(decEndpoint, options, registryClient) { + decEndpoint = mout.object.pick(decEndpoint, ['name', 'target', 'source']); - decEndpointCopy.source = source; - - // Signal if it was fetched from the registry - if (fromRegistry) { - decEndpoint.registry = true; - // If no name was specified, assume the name from the registry - if (!decEndpointCopy.name) { - decEndpointCopy.name = decEndpoint.name = decEndpoint.source; - } - } - - return new ConcreteResolver(decEndpointCopy, config, logger); + return getConstructor(decEndpoint, options, registryClient) + .spread(function (ConcreteResolver, decEndpoint) { + return new ConcreteResolver(decEndpoint, options.config, options.logger); }); } -function getConstructor(source, config, logger, registryClient) { +function getConstructor(decEndpoint, options, registryClient) { + var source = decEndpoint.source; + var config = options.config; + // Below we try a series of async tests to guess the type of resolver to use // If a step was unable to guess the resolver, it returns undefined - // If a step was able to guess the resolver, it resolves with construcotor of resolver + // If a step can guess the resolver, it returns with construcotor of resolver var promise = Q.resolve(); - var addResolver = function (getConstructor) { + var addResolver = function (resolverFactory) { promise = promise.then(function (result) { if (result === undefined) { - return getConstructor(source, config, logger); + return resolverFactory(decEndpoint, options); } else { return result; } }); }; - // Plugin resolvers. It requires each resolver defined in config.resolvers - // and calls its match function that returns instance of resolver or undefined + // Plugin resolvers. // - // Instance of resolver is then - addResolver(function (source, config, logger) { + // It requires each resolver defined in config.resolvers and calls + // its "matches" to check if given resolves supports given decEndpoint + addResolver(function () { var selectedResolver; var resolverNames = config.resolvers || []; - var resolverOptions = { config: config, logger: logger }; - var resolverPromises = resolverNames.map(function (resolverName) { - var resolver = resolvers[resolverName] || pluginResolver(resolverName, resolverOptions); + var resolver = resolvers[resolverName] + || pluginResolverFactory(require(resolverName), options); return function () { if (selectedResolver === undefined) { - return Q.when(resolver.matches(source)).then(function (result) { + var matches = resolver.matches.bind(resolver); + + return Q.fcall(matches, source).then(function (result) { if (result) { return selectedResolver = resolver; } @@ -73,7 +66,7 @@ function getConstructor(source, config, logger, registryClient) { return resolverPromises.reduce(Q.when, new Q(undefined)).then(function (resolver) { if (resolver) { - return [resolver, source]; + return [resolver, decEndpoint]; } }); }); @@ -81,37 +74,37 @@ function getConstructor(source, config, logger, registryClient) { // Git case: git git+ssh, git+http, git+https // .git at the end (probably ssh shorthand) // git@ at the start - addResolver(function(source, config) { + addResolver(function() { if (/^git(\+(ssh|https?))?:\/\//i.test(source) || /\.git\/?$/i.test(source) || /^git@/i.test(source)) { - source = source.replace(/^git\+/, ''); + decEndpoint.source = source.replace(/^git\+/, ''); // If it's a GitHub repository, return the specialized resolver if (resolvers.GitHub.getOrgRepoPair(source)) { - return [resolvers.GitHub, source]; + return [resolvers.GitHub, decEndpoint]; } - return [resolvers.GitRemote, source]; + return [resolvers.GitRemote, decEndpoint]; } }); // SVN case: svn, svn+ssh, svn+http, svn+https, svn+file - addResolver(function (source, config) { + addResolver(function () { if (/^svn(\+(ssh|https?|file))?:\/\//i.test(source)) { - return [resolvers.Svn, source]; + return [resolvers.Svn, decEndpoint]; } }); // URL case - addResolver(function (source, config) { + addResolver(function () { if (/^https?:\/\//i.exec(source)) { - return [resolvers.Url, source]; + return [resolvers.Url, decEndpoint]; } }); // If source is ./ or ../ or an absolute path - addResolver(function (source, config) { + addResolver(function () { var absolutePath = path.resolve(config.cwd, source); if (/^\.\.?[\/\\]/.test(source) || /^~\//.test(source) || @@ -119,8 +112,10 @@ function getConstructor(source, config, logger, registryClient) { ) { return Q.nfcall(fs.stat, path.join(absolutePath, '.git')) .then(function (stats) { + decEndpoint.source = absolutePath; + if (stats.isDirectory()) { - return Q.resolve([resolvers.GitFs, absolutePath]); + return Q.resolve([resolvers.GitFs, decEndpoint]); } throw new Error('Not a Git repository'); @@ -129,8 +124,10 @@ function getConstructor(source, config, logger, registryClient) { .fail(function () { return Q.nfcall(fs.stat, path.join(absolutePath, '.svn')) .then(function (stats) { + decEndpoint.source = absolutePath; + if (stats.isDirectory()) { - return Q.resolve([resolvers.Svn, absolutePath]); + return Q.resolve([resolvers.Svn, decEndpoint]); } throw new Error('Not a Subversion repository'); @@ -140,14 +137,16 @@ function getConstructor(source, config, logger, registryClient) { .fail(function () { return Q.nfcall(fs.stat, absolutePath) .then(function () { - return Q.resolve([resolvers.Fs, absolutePath]); + decEndpoint.source = absolutePath; + + return Q.resolve([resolvers.Fs, decEndpoint]); }); }); } }); // Check if is a shorthand and expand it - addResolver(function (source, config) { + addResolver(function () { // Skip ssh and/or URL with auth if (/[:@]/.test(source)) { return; @@ -156,18 +155,18 @@ function getConstructor(source, config, logger, registryClient) { // Ensure exactly only one "/" var parts = source.split('/'); if (parts.length === 2) { - source = mout.string.interpolate(config.shorthandResolver, { + decEndpoint.source = mout.string.interpolate(config.shorthandResolver, { shorthand: source, owner: parts[0], package: parts[1] }); - return getConstructor(source, config, logger, registryClient); + return getConstructor(decEndpoint, options, registryClient); } }); // As last resort, we try the registry - addResolver(function (source, config) { + addResolver(function () { if (!registryClient) { return; } @@ -178,14 +177,15 @@ function getConstructor(source, config, logger, registryClient) { throw createError('Package ' + source + ' not found', 'ENOTFOUND'); } - // TODO: Handle entry.type.. for now it's only 'alias' - // When we got published packages, this needs to be adjusted - source = entry.url; + decEndpoint.registry = true; - return getConstructor(source, config, logger, registryClient) - .spread(function (ConcreteResolver, source) { - return [ConcreteResolver, source, true]; - }); + if (!decEndpoint.name) { + decEndpoint.name = decEndpoint.source; + } + + decEndpoint.source = entry.url; + + return getConstructor(decEndpoint, options); }); }); diff --git a/lib/core/resolvers/GitResolver.js b/lib/core/resolvers/GitResolver.js index 231c98828..e4d8d2946 100644 --- a/lib/core/resolvers/GitResolver.js +++ b/lib/core/resolvers/GitResolver.js @@ -40,7 +40,7 @@ mout.object.mixIn(GitResolver, Resolver); // ----------------- -GitResolver.prototype._hasNew = function (canonicalDir, pkgMeta) { +GitResolver.prototype._hasNew = function (pkgMeta) { var oldResolution = pkgMeta._resolution || {}; return this._findResolution() diff --git a/lib/core/resolvers/PluginResolver.js b/lib/core/resolvers/PluginResolver.js deleted file mode 100644 index 66c7ef833..000000000 --- a/lib/core/resolvers/PluginResolver.js +++ /dev/null @@ -1,204 +0,0 @@ -var util = require('util'); -var mout = require('mout'); -var Q = require('q'); -var Resolver = require('./Resolver'); -var LRU = require('lru-cache'); -var semver = require('../../util/semver'); -var createError = require('../../util/createError'); -var path = require('path'); - - -function Adapter(pluginName, options) { - var pluginFactory = require(pluginName); - - var plugin = pluginFactory(options); - - function PluginResolver(decEndpoint) { - this._source = decEndpoint.source; - this._target = decEndpoint.target || '*'; - this._name = decEndpoint.name; - - this._config = options.config; - this._logger = options.logger; - } - - util.inherits(PluginResolver, Resolver); - mout.object.mixIn(PluginResolver, Resolver); - - PluginResolver.getName = function() { - if (!this._name && plugin.getName) { - this._name = plugin.getName(this._source); - } - - if (!this._name) { - this._name = path.basename(this._source); - } - - if (this._name) { - return this._name; - } - }; - - // ----------------- - - function maxSatisfyingVersion(versions, target) { - var versionsArr, index; - - versionsArr = versions.map(function (obj) { return obj.version; }); - - // Find a satisfying version, enabling strict match so that pre-releases - // have lower priority over normal ones when target is * - index = semver.maxSatisfyingIndex(versionsArr, target, true); - - if (index !== -1) { - return versions[index]; - } - } - - // Plugin Resolver is always considered potentially cacheable - // The "resolve" method decides whether to use cached or fetch new version. - PluginResolver.prototype.isCacheable = function() { - return true; - }; - - // Not only it's always potentially cacheable, but also always potenially new. - // The "resolve" handles logic of re-downloading target if new one is available. - PluginResolver.prototype.hasNew = function (canonicalDir, pkgMeta) { - if (this.hasNewPromise) { - return this.hasNewPromise; - } - - this._canonicalDir = canonicalDir; - this._oldPkgMeta = pkgMeta; - this._resolution = pkgMeta._resolution; - - return this.hasNewPromise = this.resolve().then(function (result) { - return result !== undefined; - }); - }; - - PluginResolver.prototype.resolve = function () { - if (this.resolvePromise) { - return this.resolvePromise; - } - - // If already working, error out - if (this._working) { - return Q.reject(createError('Already working', 'EWORKING')); - } - - this._working = true; - - var that = this; - - var target = this._target; - - return this.resolvePromise = Q.fcall(function() { - // It means that we can accept ranges as targets - if(that.constructor.isTargetable()) { - if (semver.validRange(target)) { - return plugin.versions(that._source) - .then(function (versions) { - var maxVersion = maxSatisfyingVersion(versions, target); - - if (maxVersion) { - return maxVersion.target; - } else { - return Q.reject(new Error('The range ' + target + ' does not match any version of ' + that._source)); - } - }); - } else { - return target; - } - } else { - if (semver.validRange(target) && target !== '*') { - return Q.reject(createError('Resolver ' + pluginName + ' does not accept version ranges (' + target + ')')); - } - - return target; - } - }) - .then(function (target) { - // We pass old _resolution (if hasNew has been called before fetch). - // So plugin can decide wheter use cached version of fetch new one. - return plugin.fetch(that._source, target, that._resolution); - }) - .then(function (result) { - // Empty result means to re-use existing resolution - if (!result) { - return; - } else { - if (!result.contents) { - throw createError('Resolver did not provide path to extracted package contents.'); - } - - that._tempDir = result.contents; - - return that._readJson().then(function (meta) { - return that._applyPkgMeta(meta) - .then(that._savePkgMeta.bind(that, meta, result.resolution)) - .then(function () { - return that._tempDir; - }); - }); - } - }) - .catch(function(e) { - e.code = pluginName; - throw e; - }) - .fin(function () { - that._working = false; - }); - }; - - PluginResolver.prototype._savePkgMeta = function (meta, resolution) { - if (this.constructor.isTargetable()) { - meta._resolution = resolution; - meta._release = resolution.target; - } - - return Resolver.prototype._savePkgMeta.call(this, meta); - }; - - PluginResolver.versions = function (source) { - return plugin.versions(source).then(function (versions) { - versions = versions.filter(function (version) { - return versions.version !== undefined; - }); - - versions = versions.map(function (version) { - return semver.clean(versions.version); - }); - - versions.sort(function (a, b) { - return semver.rcompare(a.version, b.version); - }); - - return versions; - }); - }; - - PluginResolver.isTargetable = function() { - // If plugin doesn't define versions function, it's not targetable.. - return typeof plugin.versions === 'function'; - }; - - PluginResolver.clearRuntimeCache = function () { - plugin = pluginFactory(options); - PluginResolver._cache.versions.reset(); - }; - - PluginResolver._cache = { - versions: new LRU({ max: 50, maxAge: 5 * 60 * 1000 }) - }; - - PluginResolver.matches = function (source) { - return plugin.matches(source); - }; - - return PluginResolver; -} - - -module.exports = Adapter; diff --git a/lib/core/resolvers/Resolver.js b/lib/core/resolvers/Resolver.js index 38ff87b66..4e6bdc891 100644 --- a/lib/core/resolvers/Resolver.js +++ b/lib/core/resolvers/Resolver.js @@ -43,9 +43,8 @@ Resolver.prototype.getPkgMeta = function () { return this._pkgMeta; }; -Resolver.prototype.hasNew = function (canonicalDir, pkgMeta) { +Resolver.prototype.hasNew = function (pkgMeta) { var promise; - var metaFile; var that = this; // If already working, error out @@ -56,24 +55,7 @@ Resolver.prototype.hasNew = function (canonicalDir, pkgMeta) { this._working = true; // Avoid reading the package meta if already given - if (pkgMeta) { - promise = this._hasNew(canonicalDir, pkgMeta); - // Otherwise call _hasNew with both the package meta and the canonical dir - } else { - metaFile = path.join(canonicalDir, '.bower.json'); - - promise = readJson(metaFile) - .spread(function (pkgMeta) { - return that._hasNew(canonicalDir, pkgMeta); - }, function (err) { - that._logger.debug('read-json', 'Failed to read ' + metaFile, { - filename: metaFile, - error: err - }); - - return true; // Simply resolve to true if there was an error reading the file - }); - } + promise = this._hasNew(pkgMeta); return promise.fin(function () { that._working = false; @@ -143,7 +125,7 @@ Resolver.prototype._resolve = function () { // Abstract functions that can be re-implemented by concrete resolvers // as necessary -Resolver.prototype._hasNew = function (canonicalDir, pkgMeta) { +Resolver.prototype._hasNew = function (pkgMeta) { return Q.resolve(true); }; diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js index 866fad789..601bcaba6 100644 --- a/lib/core/resolvers/SvnResolver.js +++ b/lib/core/resolvers/SvnResolver.js @@ -40,7 +40,7 @@ SvnResolver.getSource = function (source) { .replace(/\/+$/, ''); // Remove trailing slashes }; -SvnResolver.prototype._hasNew = function (canonicalDir, pkgMeta) { +SvnResolver.prototype._hasNew = function (pkgMeta) { var oldResolution = pkgMeta._resolution || {}; return this._findResolution() diff --git a/lib/core/resolvers/UrlResolver.js b/lib/core/resolvers/UrlResolver.js index 00487865c..cdd03c134 100644 --- a/lib/core/resolvers/UrlResolver.js +++ b/lib/core/resolvers/UrlResolver.js @@ -39,7 +39,7 @@ UrlResolver.isTargetable = function () { return false; }; -UrlResolver.prototype._hasNew = function (canonicalDir, pkgMeta) { +UrlResolver.prototype._hasNew = function (pkgMeta) { var oldCacheHeaders = pkgMeta._cacheHeaders || {}; var reqHeaders = {}; diff --git a/lib/core/resolvers/pluginResolverFactory.js b/lib/core/resolvers/pluginResolverFactory.js new file mode 100644 index 000000000..0265f404c --- /dev/null +++ b/lib/core/resolvers/pluginResolverFactory.js @@ -0,0 +1,309 @@ +var Q = require('q'); +var path = require('path'); +var fs = require('fs'); +var mout = require('mout'); + +var semver = require('../../util/semver'); +var createError = require('../../util/createError'); +var readJson = require('../../util/readJson'); +var removeIgnores = require('../../util/removeIgnores'); + +function pluginResolverFactory(pluginFactory, options) { + options = options || {}; + + if (typeof pluginFactory !== 'function') { + throw new Error('Resolver has "' + typeof pluginFactory + '" type instead of "function" type.'); + } + + var plugin = pluginFactory(options); + + if (!plugin) { + throw new Error('Resolver returned "' + typeof plugin + '" type instead of factory instance.'); + } + + function PluginResolver(decEndpoint) { + this._source = decEndpoint.source; + this._target = decEndpoint.target || '*'; + this._name = decEndpoint.name; + + this._config = options.config; + this._logger = options.logger; + } + + PluginResolver.prototype.getSource = function () { + return this._source; + }; + + PluginResolver.prototype.getTarget = function () { + return this._target; + }; + + PluginResolver.prototype.getName = function() { + if (!this._name && plugin.getName) { + this._name = plugin.getName(this._source); + } + + if (!this._name) { + return path.basename(this._source); + } else { + return this._name; + } + }; + + PluginResolver.prototype.getPkgMeta = function () { + return this._pkgMeta; + }; + + // ----------------- + + function maxSatisfyingVersion(versions, target) { + var versionsArr, index; + + versionsArr = versions.map(function (obj) { return obj.version; }); + + // Find a satisfying version, enabling strict match so that pre-releases + // have lower priority over normal ones when target is * + index = semver.maxSatisfyingIndex(versionsArr, target, true); + + if (index !== -1) { + return versions[index]; + } + } + + // Plugin Resolver is always considered potentially cacheable + // The "resolve" method decides whether to use cached or fetch new version. + PluginResolver.prototype.isCacheable = function() { + return true; + }; + + // Not only it's always potentially cacheable, but also always potenially new. + // The "resolve" handles logic of re-downloading target if needed. + PluginResolver.prototype.hasNew = function (pkgMeta) { + if (this.hasNewPromise) { + return this.hasNewPromise; + } + + this._pkgMeta = pkgMeta; + + return this.hasNewPromise = this.resolve().then(function (result) { + return result !== undefined; + }); + }; + + PluginResolver.prototype.resolve = function () { + if (this.resolvePromise) { + return this.resolvePromise; + } + + var that = this; + + var source = this._source; + var target = this._target; + + return this.resolvePromise = Q.fcall(function() { + // It means that we can accept ranges as targets + if(that.constructor.isTargetable()) { + that._release = target; + + if (semver.validRange(target)) { + return Q.fcall(plugin.releases.bind(plugin), source) + .then(function (result) { + if (!result.releases) { + throw createError('Resolver did not provide releases of package.'); + } + + var releases = result.releases; + + var versions = releases.filter(function (target) { + return semver.clean(target.version); + }); + + var maxRelease = maxSatisfyingVersion(versions, target); + + if (maxRelease) { + that._version = maxRelease.version; + that._release = target = maxRelease.target; + } else { + return Q.reject(new Error('The range ' + target + ' does not match any version of ' + that._source)); + } + }); + } + } else { + if (semver.validRange(target) && target !== '*') { + return Q.reject(createError('Resolver does not accept version ranges (' + target + ')')); + } + } + }) + .then(function () { + + // We pass old _resolution (if hasNew has been called before contents). + // So plugin can decide wheter use cached version of contents new one. + if (typeof plugin.contents !== 'function') { + throw createError('Resolver does not implement the "contents" method.'); + } + + if (that._releases) { + options.releases = that._releases; + } + + if (that._pkgMeta) { + options.cached = { + source: that._pkgMeta._source, + target: that._pkgMeta._target, + version: that._pkgMeta.version, + release: that._pkgMeta._release, + resolution: that._pkgMeta._resolution || {} + }; + } + + return Q.fcall(plugin.contents.bind(plugin), source, target, options); + }) + .then(function (result) { + // Empty result means to re-use existing resolution + if (!result) { + return; + } else { + if (!result.contents) { + throw createError('Resolver did not provide path to extracted contents of package.'); + } + + that._tempDir = result.contents; + + return that._readJson(that._tempDir).then(function (meta) { + return that._applyPkgMeta(meta) + .then(that._savePkgMeta.bind(that, meta, result)) + .then(function () { + return that._tempDir; + }); + }); + } + }); + }; + + PluginResolver.prototype._readJson = function (dir) { + var that = this; + + return readJson(dir, { + assume: { name: that.getName() } + }) + .spread(function (json, deprecated) { + if (deprecated) { + that._logger.warn('deprecated', 'Package ' + that.getName() + ' is using the deprecated ' + deprecated); + } + + return json; + }); + }; + + PluginResolver.prototype._applyPkgMeta = function (meta) { + // Check if name defined in the json is different + // If so and if the name was "guessed", assume the json name + if (meta.name !== this._name) { + this._name = meta.name; + } + + // Handle ignore property, deleting all files from the temporary directory + // If no ignores were specified, simply resolve + if (!meta.ignore || !meta.ignore.length) { + return Q.resolve(meta); + } + + // Otherwise remove them from the temp dir + return removeIgnores(this._tempDir, meta).then(function () { + return meta; + }); + }; + + PluginResolver.prototype._savePkgMeta = function (meta, result) { + var that = this; + var contents; + + meta._source = that._source; + meta._target = that._target; + + if (result.resolution) { + meta._resolution = result.resolution; + } + + if (that._release) { + meta._release = that._release; + } + + if (that._version) { + meta.version = that._version; + } else { + delete meta.version; + } + + ['main', 'ignore'].forEach(function (attr) { + if (meta[attr]) return; + + that._logger.log( + 'warn', 'invalid-meta', + (meta.name || 'component') + ' is missing "' + attr + '" entry in bower.json' + ); + }); + + // Stringify contents + contents = JSON.stringify(meta, null, 2); + + return Q.nfcall(fs.writeFile, path.join(this._tempDir, '.bower.json'), contents) + .then(function () { + return that._pkgMeta = meta; + }); + }; + + // It is used only by "bower info". It returns all semver versions. + PluginResolver.versions = function (source) { + return Q.fcall(plugin.releases.bind(plugin), source).then(function (result) { + if (!result.releases) { + throw createError('Resolver did not provide releases of package.'); + } + + var releases = result.releases; + + var versions = releases.map(function (version) { + return semver.clean(version.version); + }); + + versions = versions.filter(function (version) { + return version; + }); + + versions.sort(function (a, b) { + return semver.rcompare(a, b); + }); + + return versions; + }); + }; + + PluginResolver.isTargetable = function() { + // If plugin doesn't define versions function, it's not targetable.. + return typeof plugin.releases === 'function'; + }; + + PluginResolver.clearRuntimeCache = function () { + plugin = pluginFactory(options); + }; + + PluginResolver.matches = function (source) { + if (typeof plugin.matches !== 'function') { + throw new Error('Resolver is missing "matches" method.'); + } + + return Q.fcall(plugin.matches.bind(plugin), source).then(function (result) { + if (typeof result !== 'boolean') { + throw new Error('Resolver\'s "matches" method should return a boolean'); + } + + return result; + }); + }; + + return PluginResolver; +} + + +module.exports = pluginResolverFactory; + diff --git a/test/core/packageRepository.js b/test/core/packageRepository.js index f0ab5ce91..2361c9855 100644 --- a/test/core/packageRepository.js +++ b/test/core/packageRepository.js @@ -45,7 +45,10 @@ describe('PackageRepository', function () { }); // Mock the resolver factory to always return a resolver for the test package - function resolverFactory(decEndpoint, _config, _logger, _registryClient) { + function resolverFactory(decEndpoint, options, _registryClient) { + var _config = options.config; + var _logger = options.logger; + expect(_config).to.eql(config); expect(_logger).to.be.an(Logger); expect(_registryClient).to.be.an(RegistryClient); @@ -67,7 +70,9 @@ describe('PackageRepository', function () { return Q.resolve(resolver); } resolverFactory.getConstructor = function () { - return Q.resolve([resolvers.GitRemote, helpers.localSource(testPackage), false]); + return Q.resolve([resolvers.GitRemote, { + source: helpers.localSource(testPackage) + }]); }; resolverFactory.clearRuntimeCache = function () { resolverFactoryClearHook(); @@ -239,8 +244,7 @@ describe('PackageRepository', function () { resolverFactoryHook = function (resolver) { var originalHasNew = resolver.hasNew; - resolver.hasNew = function (canonicalDir, pkgMeta) { - expect(canonicalDir).to.equal(tempPackage); + resolver.hasNew = function (pkgMeta) { expect(pkgMeta).to.eql(json); called = true; return originalHasNew.apply(this, arguments); @@ -283,8 +287,7 @@ describe('PackageRepository', function () { return originalResolve.apply(this, arguments); }; - resolver.hasNew = function (canonicalDir, pkgMeta) { - expect(canonicalDir).to.equal(tempPackage); + resolver.hasNew = function (pkgMeta) { expect(pkgMeta).to.eql(json); called.push('hasNew'); return Q.resolve(true); @@ -327,8 +330,7 @@ describe('PackageRepository', function () { return originalResolve.apply(this, arguments); }; - resolver.hasNew = function (canonicalDir, pkgMeta) { - expect(canonicalDir).to.equal(tempPackage); + resolver.hasNew = function (pkgMeta) { expect(pkgMeta).to.eql(json); called.push('hasNew'); return Q.resolve(false); @@ -364,8 +366,7 @@ describe('PackageRepository', function () { resolverFactoryHook = function (resolver) { var originalResolve = resolver.resolve; - resolver.hasNew = function (canonicalDir, pkgMeta) { - expect(canonicalDir).to.equal(tempPackage); + resolver.hasNew = function (pkgMeta) { expect(pkgMeta).to.eql(json); called.push('resolve'); return originalResolve.apply(this, arguments); diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index ed3c9e946..1700ec019 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -34,8 +34,8 @@ describe('resolverFactory', function () { rimraf('pure', next); }); - function callFactory(decEndpoint, config) { - return resolverFactory(decEndpoint, defaultConfig(config), logger, registryClient); + function callFactory(decEndpoint, config, skipRegistry) { + return resolverFactory(decEndpoint, { config: defaultConfig(config), logger: logger }, skipRegistry ? undefined : registryClient); } it('should recognize git remote endpoints correctly', function (next) { @@ -526,6 +526,51 @@ describe('resolverFactory', function () { .done(); }); + it('should recognize URL endpoints correctly', function (next) { + var promise = Q.resolve(); + var endpoints; + + endpoints = [ + 'http://bower.io/foo.js', + 'https://bower.io/foo.js' + ]; + + endpoints.forEach(function (source) { + // Test without name + promise = promise.then(function () { + return callFactory({ source: source }); + }) + .then(function (resolver) { + expect(resolver).to.be.a(resolvers.Url); + expect(resolver.getSource()).to.equal(source); + }); + + // Test with name + promise = promise.then(function () { + return callFactory({ name: 'foo', source: source }); + }) + .then(function (resolver) { + expect(resolver).to.be.a(resolvers.Url); + expect(resolver.getName()).to.equal('foo'); + expect(resolver.getSource()).to.equal(source); + }); + }); + + promise + .then(next.bind(next, null)) + .done(); + }); + + it('should recognize URL endpoints correctly', function () { + var source = 'custom://hello-world'; + + return callFactory({ source: source }) + .then(function (resolver) { + + }) + .done(); + }); + it('should recognize registry endpoints correctly', function (next) { // Create a 'pure' file at the root to prevent regressions of #666 fs.writeFileSync('pure', 'foo'); @@ -573,16 +618,15 @@ describe('resolverFactory', function () { .done(); }); - it('should set registry to true on the decomposed endpoint if fetched from the registry', function (next) { - var decEndpoint = { source: 'pure' }; + // it('should set registry to true on the decomposed endpoint if fetched from the registry', function (next) { + // var decEndpoint = { source: 'pure' }; - callFactory(decEndpoint) - .then(function () { - expect(decEndpoint.registry).to.be(true); - next(); - }) - .done(); - }); + // return callFactory(decEndpoint, { resolvers: ['sample-custom-resolver'] }) + // .then(function () { + // next(); + // }) + // .done(); + // }); it('should use the configured shorthand resolver', function (next) { callFactory({ source: 'bower/bower' }) @@ -617,7 +661,7 @@ describe('resolverFactory', function () { it('should error out if there\'s no suitable resolver for a given source', function (next) { - resolverFactory({ source: 'some-package-that-will-never-exist' }, defaultConfig(), logger) + callFactory({ source: 'some-package-that-will-never-exist' }, undefined, true) .then(function () { throw new Error('Should have failed'); }, function (err) { diff --git a/test/core/resolvers/fsResolver.js b/test/core/resolvers/fsResolver.js index a7151d5ca..b01c5212d 100644 --- a/test/core/resolvers/fsResolver.js +++ b/test/core/resolvers/fsResolver.js @@ -82,13 +82,11 @@ describe('FsResolver', function () { it('should resolve always to true (for now..)', function (next) { var resolver = create(testPackage); - tempSource = path.resolve(__dirname, '../../tmp/tmp'); - mkdirp.sync(tempSource); - fs.writeFileSync(path.join(tempSource, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'test' - })); + }; - resolver.hasNew(tempSource) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(true); next(); diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index cb74e9822..0b2d4030f 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -61,7 +61,7 @@ describe('GitResolver', function () { it('should be true when the resolution type is different', function (next) { var resolver; - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '0.0.0', _resolution: { @@ -69,7 +69,8 @@ describe('GitResolver', function () { tag: '0.0.0', commit: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' } - })); + }; + GitResolver.refs = function () { return Q.resolve([ 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/master' // same commit hash on purpose @@ -77,7 +78,7 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(true); next(); @@ -88,7 +89,7 @@ describe('GitResolver', function () { it('should be true when a higher version for a range is available', function (next) { var resolver; - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '1.0.0', _resolution: { @@ -96,7 +97,8 @@ describe('GitResolver', function () { tag: '1.0.0', commit: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' } - })); + }; + GitResolver.refs = function () { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', @@ -106,7 +108,7 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(true); next(); @@ -117,7 +119,7 @@ describe('GitResolver', function () { it('should be true when a resolved to a lower version of a range', function (next) { var resolver; - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '1.0.1', _resolution: { @@ -125,7 +127,8 @@ describe('GitResolver', function () { tag: '1.0.1', commit: 'cccccccccccccccccccccccccccccccccccccccc' } - })); + }; + GitResolver.refs = function () { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', @@ -134,7 +137,7 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(true); next(); @@ -145,7 +148,7 @@ describe('GitResolver', function () { it('should be false when resolved to the same tag (with same commit hash) for a given range', function (next) { var resolver; - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '1.0.1', _resolution: { @@ -153,7 +156,8 @@ describe('GitResolver', function () { tag: '1.0.1', commit: 'cccccccccccccccccccccccccccccccccccccccc' } - })); + }; + GitResolver.refs = function () { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', @@ -163,7 +167,7 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(false); next(); @@ -174,7 +178,7 @@ describe('GitResolver', function () { it('should be true when resolved to the same tag (with different commit hash) for a given range', function (next) { var resolver; - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '1.0.1', _resolution: { @@ -182,7 +186,8 @@ describe('GitResolver', function () { tag: '1.0.1', commit: 'cccccccccccccccccccccccccccccccccccccccc' } - })); + }; + GitResolver.refs = function () { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', @@ -192,7 +197,7 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(true); next(); @@ -203,14 +208,15 @@ describe('GitResolver', function () { it('should be true when a different commit hash for a given branch is available', function (next) { var resolver; - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', _resolution: { type: 'branch', branch: 'master', commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' } - })); + }; + GitResolver.refs = function () { return Q.resolve([ 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/master' @@ -218,7 +224,7 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(true); next(); @@ -229,14 +235,15 @@ describe('GitResolver', function () { it('should be false when resolved to the the same commit hash for a given branch', function (next) { var resolver; - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', _resolution: { type: 'branch', branch: 'master', commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' } - })); + }; + GitResolver.refs = function () { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master' @@ -244,7 +251,7 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(false); next(); @@ -255,13 +262,14 @@ describe('GitResolver', function () { it('should be false when targeting commit hashes', function (next) { var resolver; - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', _resolution: { type: 'commit', commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' } - })); + }; + GitResolver.refs = function () { return Q.resolve([ 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/master' @@ -269,7 +277,7 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(true); next(); diff --git a/test/core/resolvers/resolver.js b/test/core/resolvers/resolver.js index dd1848721..e7bf13936 100644 --- a/test/core/resolvers/resolver.js +++ b/test/core/resolvers/resolver.js @@ -115,7 +115,7 @@ describe('Resolver', function () { }) .done(); - resolver.hasNew(tempDir) + resolver.hasNew({}) .then(function () { succeeded = true; }, function (err) { @@ -129,17 +129,17 @@ describe('Resolver', function () { var resolver = create('foo'); var succeeded; - resolver.hasNew(tempDir) + resolver.hasNew({}) .then(function () { // Test if hasNew can be called again when done - resolver.hasNew(tempDir) + resolver.hasNew({}) .then(function () { next(succeeded ? new Error('Should have failed') : null); }); }) .done(); - resolver.hasNew(tempDir) + resolver.hasNew({}) .then(function () { succeeded = true; }, function (err) { @@ -152,7 +152,7 @@ describe('Resolver', function () { it('should resolve to true by default', function (next) { var resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew({}) .then(function (hasNew) { expect(hasNew).to.equal(true); next(); @@ -160,32 +160,17 @@ describe('Resolver', function () { .done(); }); - it('should resolve to true if the there\'s an error reading the package meta', function (next) { + it('should call _hasNew with the package meta', function (next) { var resolver = create('foo'); - - rimraf.sync(path.join(tempDir, '.bower.json')); - resolver.hasNew(tempDir) - .then(function (hasNew) { - expect(hasNew).to.equal(true); - next(); - }) - .done(); - }); - - it('should call _hasNew with the canonical dir and the package meta', function (next) { - var resolver = create('foo'); - var canonical; var meta; - resolver._hasNew = function (canonicalDir, pkgMeta) { - canonical = canonicalDir; + resolver._hasNew = function (pkgMeta) { meta = pkgMeta; return Q.resolve(true); }; - resolver.hasNew(tempDir) + resolver.hasNew({ name: 'test' }) .then(function () { - expect(canonical).to.equal(tempDir); expect(meta).to.be.an('object'); expect(meta.name).to.equal('test'); next(); @@ -197,12 +182,12 @@ describe('Resolver', function () { var resolver = create('foo'); var meta; - resolver._hasNew = function (canonicalDir, pkgMeta) { + resolver._hasNew = function (pkgMeta) { meta = pkgMeta; return Q.resolve(true); }; - resolver.hasNew(tempDir, { + resolver.hasNew({ name: 'foo' }) .then(function () { @@ -261,10 +246,10 @@ describe('Resolver', function () { resolver._resolve = function () {}; - resolver.hasNew(tempDir) + resolver.hasNew({}) .then(function () { // Test if hasNew can be called again when done - resolver.hasNew(tempDir) + resolver.hasNew({}) .then(function () { next(succeeded ? new Error('Should have failed') : null); }); diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index 47a8a5a37..a2e3ed415 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -63,7 +63,7 @@ else describe('SvnResolver', function () { it('should be true when the resolution type is different', function (next) { var resolver; - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '0.0.0', _resolution: { @@ -71,7 +71,7 @@ else describe('SvnResolver', function () { tag: '0.0.0', commit: 123 } - })); + }; SvnResolver.tags = function () { return Q.resolve({ @@ -86,7 +86,7 @@ else describe('SvnResolver', function () { }; resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(true); next(); @@ -97,7 +97,7 @@ else describe('SvnResolver', function () { it('should be true when a higher version for a range is available', function (next) { var resolver; - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '1.0.0', _resolution: { @@ -105,7 +105,7 @@ else describe('SvnResolver', function () { tag: '1.0.0', commit: 3 } - })); + }; SvnResolver.tags = function () { return Q.resolve({ @@ -115,7 +115,7 @@ else describe('SvnResolver', function () { }; resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(true); next(); @@ -126,7 +126,7 @@ else describe('SvnResolver', function () { it('should be true when a resolved to a lower version of a range', function (next) { var resolver; - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '1.0.1', _resolution: { @@ -134,7 +134,8 @@ else describe('SvnResolver', function () { tag: '1.0.1', commit: 3 } - })); + }; + SvnResolver.tags = function () { return Q.resolve({ '1.0.0': 2 @@ -142,7 +143,7 @@ else describe('SvnResolver', function () { }; resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(true); next(); @@ -153,7 +154,7 @@ else describe('SvnResolver', function () { it('should be false when resolved to the same tag (with same commit hash) for a given range', function (next) { var resolver; - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '1.0.1', _resolution: { @@ -161,7 +162,8 @@ else describe('SvnResolver', function () { tag: '1.0.1', commit: 2 } - })); + }; + SvnResolver.tags = function () { return Q.resolve({ '1.0.0': 1, @@ -170,7 +172,7 @@ else describe('SvnResolver', function () { }; resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(false); next(); @@ -181,7 +183,7 @@ else describe('SvnResolver', function () { it('should be true when resolved to the same tag (with different commit hash) for a given range', function (next) { var resolver; - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '1.0.1', _resolution: { @@ -189,7 +191,8 @@ else describe('SvnResolver', function () { tag: '1.0.1', commit: 3 } - })); + }; + SvnResolver.tags = function () { return Q.resolve({ '1.0.0': 2, @@ -198,7 +201,7 @@ else describe('SvnResolver', function () { }; resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(true); next(); @@ -210,13 +213,14 @@ else describe('SvnResolver', function () { it('should be false when targeting commit hashes', function (next) { var resolver; - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', _resolution: { type: 'commit', commit: 1 } - })); + }; + SvnResolver.tags = function () { return Q.resolve({ '1.0.0': 2 @@ -224,7 +228,7 @@ else describe('SvnResolver', function () { }; resolver = create('foo'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(true); next(); diff --git a/test/core/resolvers/urlResolver.js b/test/core/resolvers/urlResolver.js index e4c441d2c..98ee0fd57 100644 --- a/test/core/resolvers/urlResolver.js +++ b/test/core/resolvers/urlResolver.js @@ -93,12 +93,12 @@ describe('UrlResolver', function () { .head('/foo.js') .reply(500); - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '0.0.0' - })); + }; - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(true); next(); @@ -116,16 +116,16 @@ describe('UrlResolver', function () { 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' }); - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '0.0.0', _cacheHeaders: { 'ETag': 'fk3454fdmmlw20i9nf', 'Last-Modified': 'Tue, 16 Nov 2012 13:35:29 GMT' } - })); + }; - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(true); next(); @@ -143,16 +143,16 @@ describe('UrlResolver', function () { 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' }); - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '0.0.0', _cacheHeaders: { 'ETag': '686897696a7c876b7e', 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' } - })); + }; - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(false); next(); @@ -171,16 +171,16 @@ describe('UrlResolver', function () { 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' }); - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '0.0.0', _cacheHeaders: { 'ETag': '686897696a7c876b7e', 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' } - })); + }; - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(false); next(); @@ -205,18 +205,18 @@ describe('UrlResolver', function () { }); - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ + var pkgMeta = { name: 'foo', version: '0.0.0', _cacheHeaders: { 'ETag': '686897696a7c876b7e', 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' } - })); + }; resolver = create(redirectingUrl + '/foo.js'); - resolver.hasNew(tempDir) + resolver.hasNew(pkgMeta) .then(function (hasNew) { expect(hasNew).to.be(false); next(); From ed27e8754076c6e25bc2d1143719faeae3ec3c07 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 4 Aug 2015 06:40:03 +0200 Subject: [PATCH 0604/1021] Fix the tests --- lib/core/resolvers/pluginResolverFactory.js | 1 - test/core/resolverFactory.js | 10 ---------- 2 files changed, 11 deletions(-) diff --git a/lib/core/resolvers/pluginResolverFactory.js b/lib/core/resolvers/pluginResolverFactory.js index 0265f404c..7218215c7 100644 --- a/lib/core/resolvers/pluginResolverFactory.js +++ b/lib/core/resolvers/pluginResolverFactory.js @@ -1,7 +1,6 @@ var Q = require('q'); var path = require('path'); var fs = require('fs'); -var mout = require('mout'); var semver = require('../../util/semver'); var createError = require('../../util/createError'); diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 1700ec019..72754c26a 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -561,16 +561,6 @@ describe('resolverFactory', function () { .done(); }); - it('should recognize URL endpoints correctly', function () { - var source = 'custom://hello-world'; - - return callFactory({ source: source }) - .then(function (resolver) { - - }) - .done(); - }); - it('should recognize registry endpoints correctly', function (next) { // Create a 'pure' file at the root to prevent regressions of #666 fs.writeFileSync('pure', 'foo'); From 725fc26880f5bbf47e4f3cdef440578ae5c09305 Mon Sep 17 00:00:00 2001 From: insanehong Date: Tue, 4 Aug 2015 13:58:23 +0900 Subject: [PATCH 0605/1021] Add shorthand for version of options in help.json "-v" shorthand aleady supported of cli opeion for output version --- templates/json/help.json | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/json/help.json b/templates/json/help.json index 4a1825e80..21a5d7a27 100644 --- a/templates/json/help.json +++ b/templates/json/help.json @@ -62,6 +62,7 @@ "description": "Allows running commands as root" }, { + "shorthand": "-v", "flag": "--version", "description": "Output Bower version" }, From 800119fc926bea03221980e1aadf1aaa4028c54c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 13 Aug 2015 23:11:44 +0200 Subject: [PATCH 0606/1021] Remove core team section from README Instead, use link to contributors page on GitHub --- README.md | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 97f89c662..697d3fbd2 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ Bower can be configured using JSON in a `.bowerrc` file. Read over available opt ## Contributing -We welcome contributions of all kinds from anyone. Please take a moment to +We welcome [contributions](https://github.com/bower/bower/graphs/contributors) of all kinds from anyone. Please take a moment to review the [guidelines for contributing](CONTRIBUTING.md). * [Bug reports](CONTRIBUTING.md#bugs) @@ -113,27 +113,8 @@ Note that on Windows for tests to pass you need to configure Git before cloning: git config --global core.autocrlf input ``` -## Bower Team - -Bower is made by lots of people across the globe, contributions large and small. Our thanks to everyone who has played a part. - -### Core team - -* [@satazor](https://github.com/satazor) -* [@wibblymat](https://github.com/wibblymat) -* [@paulirish](https://github.com/paulirish) -* [@benschwarz](https://github.com/benschwarz) -* [@svnlto](https://github.com/svnlto) -* [@sheerun](https://github.com/sheerun) - -### Bower Alumni - -* [@fat](https://github.com/fat) -* [@maccman](https://github.com/maccman) - - ## License -Copyright (c) 2015 Twitter and other contributors +Copyright (c) 2015 Twitter and [other contributors](https://github.com/bower/bower/graphs/contributors) Licensed under the MIT License From 69be742619fc2624bc440cb239203d9e861c5dc9 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 23 Aug 2015 13:44:00 +0200 Subject: [PATCH 0607/1021] Improve API for pluggable resolvers --- lib/core/resolverFactory.js | 16 +- lib/core/resolvers/pluginResolverFactory.js | 180 +++++++++++--------- 2 files changed, 109 insertions(+), 87 deletions(-) diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index 80de7f28d..9ac4cb380 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -39,7 +39,7 @@ function getConstructor(decEndpoint, options, registryClient) { // Plugin resolvers. // // It requires each resolver defined in config.resolvers and calls - // its "matches" to check if given resolves supports given decEndpoint + // its "match" to check if given resolves supports given decEndpoint addResolver(function () { var selectedResolver; @@ -51,9 +51,9 @@ function getConstructor(decEndpoint, options, registryClient) { return function () { if (selectedResolver === undefined) { - var matches = resolver.matches.bind(resolver); + var match = resolver.match.bind(resolver); - return Q.fcall(matches, source).then(function (result) { + return Q.fcall(match, source).then(function (result) { if (result) { return selectedResolver = resolver; } @@ -66,7 +66,15 @@ function getConstructor(decEndpoint, options, registryClient) { return resolverPromises.reduce(Q.when, new Q(undefined)).then(function (resolver) { if (resolver) { - return [resolver, decEndpoint]; + return Q.fcall(resolver.locate.bind(resolver), decEndpoint.source).then(function (result) { + if (result && result !== decEndpoint.source) { + decEndpoint.source = result; + decEndpoint.registry = true; + return getConstructor(decEndpoint, options, registryClient); + } else { + return [resolver, decEndpoint]; + } + }); } }); }); diff --git a/lib/core/resolvers/pluginResolverFactory.js b/lib/core/resolvers/pluginResolverFactory.js index 7218215c7..7a05d067b 100644 --- a/lib/core/resolvers/pluginResolverFactory.js +++ b/lib/core/resolvers/pluginResolverFactory.js @@ -1,51 +1,64 @@ var Q = require('q'); var path = require('path'); var fs = require('fs'); +var object = require('mout/object'); var semver = require('../../util/semver'); var createError = require('../../util/createError'); var readJson = require('../../util/readJson'); var removeIgnores = require('../../util/removeIgnores'); -function pluginResolverFactory(pluginFactory, options) { +function pluginResolverFactory(resolverFactory, options) { options = options || {}; - if (typeof pluginFactory !== 'function') { - throw new Error('Resolver has "' + typeof pluginFactory + '" type instead of "function" type.'); + if (typeof resolverFactory !== 'function') { + throw createError('Resolver has "' + typeof resolverFactory + '" type instead of "function" type.', 'ERESOLERAPI'); } - var plugin = pluginFactory(options); + var resolver = resolverFactory(options); - if (!plugin) { - throw new Error('Resolver returned "' + typeof plugin + '" type instead of factory instance.'); + function maxSatisfyingVersion(versions, target) { + var versionsArr, index; + + versionsArr = versions.map(function (obj) { return obj.version; }); + + // Find a satisfying version, enabling strict match so that pre-releases + // have lower priority over normal ones when target is * + index = semver.maxSatisfyingIndex(versionsArr, target, true); + + if (index !== -1) { + return versions[index]; + } } function PluginResolver(decEndpoint) { - this._source = decEndpoint.source; - this._target = decEndpoint.target || '*'; - this._name = decEndpoint.name; - - this._config = options.config; - this._logger = options.logger; + this._decEndpoint = decEndpoint; } + // @private + PluginResolver.prototype.getEndpoint = function () { + return object.merge(this._decEndpoint, { + name: this.getName(), + source: this.getSource(), + target: this.getTarget() + }); + }; + PluginResolver.prototype.getSource = function () { - return this._source; + return this._decEndpoint.source; }; PluginResolver.prototype.getTarget = function () { - return this._target; + return this._decEndpoint.target || '*'; }; PluginResolver.prototype.getName = function() { - if (!this._name && plugin.getName) { - this._name = plugin.getName(this._source); - } - - if (!this._name) { - return path.basename(this._source); + if (!this._decEndpoint.name && typeof resolver.getName === 'function') { + return resolver.getName.call(resolver, this.getSource()); + } else if (!this._decEndpoint.name) { + return path.basename(this.getSource()); } else { - return this._name; + return this._decEndpoint.name; } }; @@ -55,20 +68,6 @@ function pluginResolverFactory(pluginFactory, options) { // ----------------- - function maxSatisfyingVersion(versions, target) { - var versionsArr, index; - - versionsArr = versions.map(function (obj) { return obj.version; }); - - // Find a satisfying version, enabling strict match so that pre-releases - // have lower priority over normal ones when target is * - index = semver.maxSatisfyingIndex(versionsArr, target, true); - - if (index !== -1) { - return versions[index]; - } - } - // Plugin Resolver is always considered potentially cacheable // The "resolve" method decides whether to use cached or fetch new version. PluginResolver.prototype.isCacheable = function() { @@ -96,22 +95,21 @@ function pluginResolverFactory(pluginFactory, options) { var that = this; - var source = this._source; - var target = this._target; - return this.resolvePromise = Q.fcall(function() { + var target = this.getTarget(); + // It means that we can accept ranges as targets if(that.constructor.isTargetable()) { that._release = target; if (semver.validRange(target)) { - return Q.fcall(plugin.releases.bind(plugin), source) + return Q.fcall(resolver.releases.bind(resolver), that.getSource()) .then(function (result) { - if (!result.releases) { + if (!result) { throw createError('Resolver did not provide releases of package.'); } - var releases = result.releases; + var releases = this._releases = result; var versions = releases.filter(function (target) { return semver.clean(target.version); @@ -121,9 +119,13 @@ function pluginResolverFactory(pluginFactory, options) { if (maxRelease) { that._version = maxRelease.version; - that._release = target = maxRelease.target; + that._release = that._decEndpoint.target = maxRelease.target; } else { - return Q.reject(new Error('The range ' + target + ' does not match any version of ' + that._source)); + throw createError('No version found that was able to satisfy ' + target, 'ENORESTARGET', { + details: !versions.length ? + 'No versions found in ' + that.getSource() : + 'Available versions: ' + versions.map(function (version) { return version.version; }).join(', ') + }); } }); } @@ -136,40 +138,46 @@ function pluginResolverFactory(pluginFactory, options) { .then(function () { // We pass old _resolution (if hasNew has been called before contents). - // So plugin can decide wheter use cached version of contents new one. - if (typeof plugin.contents !== 'function') { - throw createError('Resolver does not implement the "contents" method.'); + // So resolver can decide wheter use cached version of contents new one. + if (typeof resolver.fetch !== 'function') { + throw createError('Resolver does not implement the "fetch" method.'); } + var cached = {}; + if (that._releases) { - options.releases = that._releases; + cached.releases = that._releases; } if (that._pkgMeta) { - options.cached = { + cached.endpoint = { + name: that._pkgMeta.name, source: that._pkgMeta._source, - target: that._pkgMeta._target, - version: that._pkgMeta.version, - release: that._pkgMeta._release, - resolution: that._pkgMeta._resolution || {} + target: that._pkgMeta._target }; + + cached.release = that._pkgMeta._release; + + cached.version = that._pkgMeta.version; + + cached.resolution = that._pkgMeta._resolution || {}; } - return Q.fcall(plugin.contents.bind(plugin), source, target, options); + return Q.fcall(resolver.fetch.bind(resolver), that.getEndpoint(), cached); }) .then(function (result) { // Empty result means to re-use existing resolution if (!result) { return; } else { - if (!result.contents) { + if (!result.tempPath) { throw createError('Resolver did not provide path to extracted contents of package.'); } - that._tempDir = result.contents; + that._tempDir = result.tempPath; return that._readJson(that._tempDir).then(function (meta) { - return that._applyPkgMeta(meta) + return that._applyPkgMeta(meta, result) .then(that._savePkgMeta.bind(that, meta, result)) .then(function () { return that._tempDir; @@ -187,14 +195,14 @@ function pluginResolverFactory(pluginFactory, options) { }) .spread(function (json, deprecated) { if (deprecated) { - that._logger.warn('deprecated', 'Package ' + that.getName() + ' is using the deprecated ' + deprecated); + options.logger.warn('deprecated', 'Package ' + that.getName() + ' is using the deprecated ' + deprecated); } return json; }); }; - PluginResolver.prototype._applyPkgMeta = function (meta) { + PluginResolver.prototype._applyPkgMeta = function (meta, result) { // Check if name defined in the json is different // If so and if the name was "guessed", assume the json name if (meta.name !== this._name) { @@ -203,7 +211,7 @@ function pluginResolverFactory(pluginFactory, options) { // Handle ignore property, deleting all files from the temporary directory // If no ignores were specified, simply resolve - if (!meta.ignore || !meta.ignore.length) { + if (result.removeIgnores === false || !meta.ignore || !meta.ignore.length) { return Q.resolve(meta); } @@ -215,10 +223,9 @@ function pluginResolverFactory(pluginFactory, options) { PluginResolver.prototype._savePkgMeta = function (meta, result) { var that = this; - var contents; - meta._source = that._source; - meta._target = that._target; + meta._source = that.getSource(); + meta._target = that.getTarget(); if (result.resolution) { meta._resolution = result.resolution; @@ -234,17 +241,8 @@ function pluginResolverFactory(pluginFactory, options) { delete meta.version; } - ['main', 'ignore'].forEach(function (attr) { - if (meta[attr]) return; - - that._logger.log( - 'warn', 'invalid-meta', - (meta.name || 'component') + ' is missing "' + attr + '" entry in bower.json' - ); - }); - // Stringify contents - contents = JSON.stringify(meta, null, 2); + var contents = JSON.stringify(meta, null, 2); return Q.nfcall(fs.writeFile, path.join(this._tempDir, '.bower.json'), contents) .then(function () { @@ -254,12 +252,12 @@ function pluginResolverFactory(pluginFactory, options) { // It is used only by "bower info". It returns all semver versions. PluginResolver.versions = function (source) { - return Q.fcall(plugin.releases.bind(plugin), source).then(function (result) { - if (!result.releases) { + return Q.fcall(resolver.releases.bind(resolver), source).then(function (result) { + if (!result) { throw createError('Resolver did not provide releases of package.'); } - var releases = result.releases; + var releases = this._releases = result; var versions = releases.map(function (version) { return semver.clean(version.version); @@ -278,22 +276,38 @@ function pluginResolverFactory(pluginFactory, options) { }; PluginResolver.isTargetable = function() { - // If plugin doesn't define versions function, it's not targetable.. - return typeof plugin.releases === 'function'; + // If resolver doesn't define versions function, it's not targetable.. + return typeof resolver.releases === 'function'; }; PluginResolver.clearRuntimeCache = function () { - plugin = pluginFactory(options); + resolver = resolverFactory(options); }; - PluginResolver.matches = function (source) { - if (typeof plugin.matches !== 'function') { - throw new Error('Resolver is missing "matches" method.'); + PluginResolver.match = function (source) { + if (typeof resolver.match !== 'function') { + throw createError('Resolver is missing "match" method.', 'ERESOLVERAPI'); } - return Q.fcall(plugin.matches.bind(plugin), source).then(function (result) { + var match = resolver.match.bind(resolver); + + return Q.fcall(match, source).then(function (result) { if (typeof result !== 'boolean') { - throw new Error('Resolver\'s "matches" method should return a boolean'); + throw createError('Resolver\'s "match" method should return a boolean', 'ERESOLVERAPI'); + } + + return result; + }); + }; + + PluginResolver.locate = function (source) { + if (typeof resolver.locate !== 'function') { + return source; + } + + return Q.fcall(resolver.locate.bind(resolver), source).then(function (result) { + if (typeof result !== 'string') { + throw createError('Resolver\'s "locate" method should return a string', 'ERESOLVERAPI'); } return result; From 821979bab13aaf885478e39718f39b8dc43b6ffc Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 23 Aug 2015 14:16:23 +0200 Subject: [PATCH 0608/1021] Rename options to bower and add "version" to resolvers options --- lib/core/resolverFactory.js | 4 +++- lib/core/resolvers/pluginResolverFactory.js | 12 ++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index 9ac4cb380..936438b47 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -10,6 +10,8 @@ var pluginResolverFactory = require('./resolvers/pluginResolverFactory'); function createInstance(decEndpoint, options, registryClient) { decEndpoint = mout.object.pick(decEndpoint, ['name', 'target', 'source']); + options.version = require('../../package.json')["version"]; + return getConstructor(decEndpoint, options, registryClient) .spread(function (ConcreteResolver, decEndpoint) { return new ConcreteResolver(decEndpoint, options.config, options.logger); @@ -70,7 +72,7 @@ function getConstructor(decEndpoint, options, registryClient) { if (result && result !== decEndpoint.source) { decEndpoint.source = result; decEndpoint.registry = true; - return getConstructor(decEndpoint, options, registryClient); + return getConstructor(decEndpoint, options, re); } else { return [resolver, decEndpoint]; } diff --git a/lib/core/resolvers/pluginResolverFactory.js b/lib/core/resolvers/pluginResolverFactory.js index 7a05d067b..2752165cc 100644 --- a/lib/core/resolvers/pluginResolverFactory.js +++ b/lib/core/resolvers/pluginResolverFactory.js @@ -8,14 +8,14 @@ var createError = require('../../util/createError'); var readJson = require('../../util/readJson'); var removeIgnores = require('../../util/removeIgnores'); -function pluginResolverFactory(resolverFactory, options) { - options = options || {}; +function pluginResolverFactory(resolverFactory, bower) { + bower = bower || {}; if (typeof resolverFactory !== 'function') { throw createError('Resolver has "' + typeof resolverFactory + '" type instead of "function" type.', 'ERESOLERAPI'); } - var resolver = resolverFactory(options); + var resolver = resolverFactory(bower); function maxSatisfyingVersion(versions, target) { var versionsArr, index; @@ -96,7 +96,7 @@ function pluginResolverFactory(resolverFactory, options) { var that = this; return this.resolvePromise = Q.fcall(function() { - var target = this.getTarget(); + var target = that.getTarget(); // It means that we can accept ranges as targets if(that.constructor.isTargetable()) { @@ -195,7 +195,7 @@ function pluginResolverFactory(resolverFactory, options) { }) .spread(function (json, deprecated) { if (deprecated) { - options.logger.warn('deprecated', 'Package ' + that.getName() + ' is using the deprecated ' + deprecated); + bower.logger.warn('deprecated', 'Package ' + that.getName() + ' is using the deprecated ' + deprecated); } return json; @@ -281,7 +281,7 @@ function pluginResolverFactory(resolverFactory, options) { }; PluginResolver.clearRuntimeCache = function () { - resolver = resolverFactory(options); + resolver = resolverFactory(bower); }; PluginResolver.match = function (source) { From a4a05a5413cfff8e56ac54ba35cb4eb4c27b8b57 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 23 Aug 2015 14:20:09 +0200 Subject: [PATCH 0609/1021] Make custom resolvers implementation pass through linter --- lib/core/resolverFactory.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index 936438b47..b192e795d 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -10,7 +10,7 @@ var pluginResolverFactory = require('./resolvers/pluginResolverFactory'); function createInstance(decEndpoint, options, registryClient) { decEndpoint = mout.object.pick(decEndpoint, ['name', 'target', 'source']); - options.version = require('../../package.json')["version"]; + options.version = require('../../package.json').version; return getConstructor(decEndpoint, options, registryClient) .spread(function (ConcreteResolver, decEndpoint) { @@ -72,7 +72,7 @@ function getConstructor(decEndpoint, options, registryClient) { if (result && result !== decEndpoint.source) { decEndpoint.source = result; decEndpoint.registry = true; - return getConstructor(decEndpoint, options, re); + return getConstructor(decEndpoint, options, registryClient); } else { return [resolver, decEndpoint]; } From 45fe5c37ccf1ec3fdfc7ac810ba7703ceb0bda08 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 23 Aug 2015 14:34:30 +0200 Subject: [PATCH 0610/1021] Bump version to 1.5.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e670ecdd1..7c703e3b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.4.1", + "version": "1.5.0", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 0993621bb8b071be969642c09751815e52af7346 Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Sun, 23 Aug 2015 09:26:48 -0400 Subject: [PATCH 0611/1021] Remove `it.only`. --- test/commands/install.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/commands/install.js b/test/commands/install.js index 9cb8efd91..69d19ac77 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -133,7 +133,7 @@ describe('bower install', function () { }); }); - it.only('works if bower is run in child directory', function () { + it('works if bower is run in child directory', function () { package.prepare({ foo: 'bar' }); tempDir.prepare({ From dd67cc7de0630fb6dd367b67cf2532bb88458d4b Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 23 Aug 2015 16:24:36 +0200 Subject: [PATCH 0612/1021] If cwd provided explicitly, force using it, fixes #1866 --- lib/commands/init.js | 6 ++++++ lib/config.js | 6 +++--- lib/core/scripts.js | 2 +- test/commands/install.js | 5 ++++- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/commands/init.js b/lib/commands/init.js index 1116f2667..80531b0f0 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -13,6 +13,12 @@ var createError = require('../util/createError'); function init(logger, config) { var project; + config = config || {}; + + if (!config.cwd) { + config.cwd = process.cwd(); + } + config = defaultConfig(config); // This command requires interactive to be enabled diff --git a/lib/config.js b/lib/config.js index 2e148a87d..2b0f2cc24 100644 --- a/lib/config.js +++ b/lib/config.js @@ -10,9 +10,9 @@ var cachedConfigs = {}; function defaultConfig(config) { config = config || {}; - var cwd = path.dirname(findup('bower.json', { - cwd: config.cwd || process.cwd() - })) || config.cwd || process.cwd(); + var cwd = config.cwd || path.dirname(findup('bower.json', { + cwd: process.cwd() + })) || process.cwd(); config.cwd = cwd; diff --git a/lib/core/scripts.js b/lib/core/scripts.js index 0d5eeaba9..94be8ff6a 100644 --- a/lib/core/scripts.js +++ b/lib/core/scripts.js @@ -93,4 +93,4 @@ module.exports = { postinstall: mout.function.partial(hook, 'postinstall', true), //only exposed for test _orderByDependencies: orderByDependencies -}; \ No newline at end of file +}; diff --git a/test/commands/install.js b/test/commands/install.js index 69d19ac77..dac5d1ed2 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -1,3 +1,4 @@ +var path = require('path'); var expect = require('expect.js'); var helpers = require('../helpers'); @@ -147,7 +148,9 @@ describe('bower install', function () { } }); - return helpers.run(install, [undefined, undefined, { cwd: tempDir.path + '/foo/bar' }]).then(function() { + process.chdir(path.join(tempDir.path, '/foo/bar')); + + return helpers.run(install).then(function() { expect(tempDir.read('assets/package/foo')).to.be('bar'); }); }); From fac08cf835ef8ad1b654302a0885981fc0f878c9 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 23 Aug 2015 16:32:45 +0200 Subject: [PATCH 0613/1021] [test] Recover process.cwd() after running one test --- test/commands/install.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/commands/install.js b/test/commands/install.js index dac5d1ed2..ac89c8408 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -148,10 +148,13 @@ describe('bower install', function () { } }); + var oldDir = process.cwd(); process.chdir(path.join(tempDir.path, '/foo/bar')); return helpers.run(install).then(function() { expect(tempDir.read('assets/package/foo')).to.be('bar'); + }).fin(function () { + process.chdir(oldDir); }); }); From 23afb3a12964e3b6e0716a9e4eccdba6cbf60f27 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 23 Aug 2015 16:37:07 +0200 Subject: [PATCH 0614/1021] Bump version to 1.5.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7c703e3b1..30954a682 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.5.0", + "version": "1.5.1", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 5ef5403d6988dff83f8efe42483328b42e9ea6a9 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 25 Aug 2015 11:20:57 +0200 Subject: [PATCH 0615/1021] Update changelog --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77c9dd5a1..627bd85c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 1.5.1 - 2015-08-25 + +- If cwd provided explicitly, force using it, fixes #1866 + +## 1.5.0 - 2015-08-25 + +- Pluggable Resolvers! http://bower.io/docs/pluggable-resolvers/ +- Update semver version from 2.x to 5.x ([#1852](https://github.com/bower/bower/issues/1852)) +- Auto-sort dependencies alphabetically ([#1381](https://github.com/bower/bower/issues/1381)) +- Make bower commands work from subdirectories ([#1866](https://github.com/bower/bower/issues/1866)) +- No longer prefer installing bower as global module ([#1865](https://github.com/bower/bower/issues/1865)) + ## 1.4.1 - 2015-04-01 - [fix] Reading .bowerrc upwards directory tree ([#1763](https://github.com/bower/bower/issues/1763)) From 79679f9b08dad419c9072227b2a97af70ba6385a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 25 Aug 2015 17:11:48 +0200 Subject: [PATCH 0616/1021] Revert "Make bower commands work from subdirectories" This reverts commit 7acafc26d6207e44794b02402cdf6b9f66c53f01. --- lib/config.js | 10 +--------- package.json | 1 - test/commands/install.js | 25 ------------------------- 3 files changed, 1 insertion(+), 35 deletions(-) diff --git a/lib/config.js b/lib/config.js index 2b0f2cc24..b8d780edb 100644 --- a/lib/config.js +++ b/lib/config.js @@ -2,21 +2,13 @@ var tty = require('tty'); var object = require('mout').object; var bowerConfig = require('bower-config'); var Configstore = require('configstore'); -var findup = require('findup-sync'); -var path = require('path'); var cachedConfigs = {}; function defaultConfig(config) { config = config || {}; - var cwd = config.cwd || path.dirname(findup('bower.json', { - cwd: process.cwd() - })) || process.cwd(); - - config.cwd = cwd; - - var cachedConfig = readCachedConfig(cwd); + var cachedConfig = readCachedConfig(config.cwd || process.cwd()); return object.merge(cachedConfig, config); } diff --git a/package.json b/package.json index 30954a682..48ccbeafa 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "configstore": "^0.3.2", "decompress-zip": "^0.1.0", "deep-sort-object": "~0.1.1", - "findup-sync": "^0.2.1", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", "github": "^0.2.3", diff --git a/test/commands/install.js b/test/commands/install.js index ac89c8408..765fc0947 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -1,4 +1,3 @@ -var path = require('path'); var expect = require('expect.js'); var helpers = require('../helpers'); @@ -134,30 +133,6 @@ describe('bower install', function () { }); }); - it('works if bower is run in child directory', function () { - package.prepare({ foo: 'bar' }); - - tempDir.prepare({ - '.bowerrc': { directory: 'assets' }, - 'foo/bar/baz.txt': 'Hello world', - 'bower.json': { - name: 'test', - dependencies: { - package: package.path - } - } - }); - - var oldDir = process.cwd(); - process.chdir(path.join(tempDir.path, '/foo/bar')); - - return helpers.run(install).then(function() { - expect(tempDir.read('assets/package/foo')).to.be('bar'); - }).fin(function () { - process.chdir(oldDir); - }); - }); - it('runs preinstall hook', function () { package.prepare(); From fe9a1bb5fcb75be96747a3f563567a308bad0753 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 25 Aug 2015 17:12:51 +0200 Subject: [PATCH 0617/1021] Revert "upgrade to newer semver, fixes #1817,#1845,#1851" This reverts commit 8744449016d292de7703ef28a7dda478441e5514. --- package.json | 2 +- test/core/resolveCache.js | 32 +----------------------------- test/core/resolvers/gitResolver.js | 31 +++-------------------------- test/core/resolvers/svnResolver.js | 28 ++------------------------ 4 files changed, 7 insertions(+), 86 deletions(-) diff --git a/package.json b/package.json index 48ccbeafa..e1914e6ba 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "request-progress": "0.3.1", "retry": "0.6.1", "rimraf": "^2.2.8", - "semver": "^5.0.1", + "semver": "^2.3.0", "shell-quote": "^1.4.2", "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", diff --git a/test/core/resolveCache.js b/test/core/resolveCache.js index 7f7830bef..9ea798ede 100644 --- a/test/core/resolveCache.js +++ b/test/core/resolveCache.js @@ -513,7 +513,7 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir, '0.1.0-rc.2')); fs.writeFileSync(path.join(sourceDir, '0.1.0-rc.2', '.bower.json'), JSON.stringify(json, null, ' ')); - resolveCache.retrieve(source, '~0.1.0 || ~0.1.0-rc.0') + resolveCache.retrieve(source, '~0.1.0') .spread(function (canonicalDir, pkgMeta) { expect(pkgMeta).to.be.an('object'); expect(pkgMeta.version).to.equal('0.1.0-rc.2'); @@ -524,36 +524,6 @@ describe('ResolveCache', function () { .done(); }); - it('should resolve to the highest package that matches an x-range target, ignoring pre-releases versions', function (next) { - var source = String(Math.random()); - var sourceId = md5(source); - var sourceDir = path.join(cacheDir, sourceId); - var json = { name: 'foo' }; - - // Create some versions - fs.mkdirSync(sourceDir); - - // fix #1817 : >=1.2.x <=1.4.x which resolved to 1.3.16 - - json.version = '1.3.16-rc.1'; - fs.mkdirSync(path.join(sourceDir, json.version)); - fs.writeFileSync(path.join(sourceDir, json.version, '.bower.json'), JSON.stringify(json, null, ' ')); - - json.version = '1.3.16'; - fs.mkdirSync(path.join(sourceDir, json.version)); - fs.writeFileSync(path.join(sourceDir, json.version, '.bower.json'), JSON.stringify(json, null, ' ')); - - resolveCache.retrieve(source, '>=1.2.x <=1.4.x') - .spread(function (canonicalDir, pkgMeta) { - expect(pkgMeta).to.be.an('object'); - expect(pkgMeta.version).to.equal('1.3.16'); - expect(canonicalDir).to.equal(path.join(sourceDir, '1.3.16')); - - next(); - }) - .done(); - }); - it('should resolve to exact match (including build metadata) if available', function (next) { var source = String(Math.random()); var sourceId = md5(source); diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index fc5f3a185..0b2d4030f 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -514,7 +514,7 @@ describe('GitResolver', function () { .done(); }); - it('should fail to resolve "*" if a repository has valid semver tags, ignoring pre-releases if they are the only versions', function (next) { + it('should resolve "*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { var resolver; GitResolver.refs = function () { @@ -527,31 +527,6 @@ describe('GitResolver', function () { resolver = create('foo'); resolver._findResolution('*') - .then(function () { - next(new Error('Should have failed')); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.message).to.match(/no tag found that was able to satisfy/i); - expect(err.details).to.match(/0.1.0-rc/i); - expect(err.code).to.equal('ENORESTARGET'); - next(); - }) - .done(); - }); - - it('should resolve "* || >=0.1.0-rc.0" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { - var resolver; - - GitResolver.refs = function () { - return Q.resolve([ - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', - 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.1.0-rc.1', - 'cccccccccccccccccccccccccccccccccccccccc refs/tags/0.1.0-rc.2' - ]); - }; - - resolver = create('foo'); - resolver._findResolution('* || >=0.1.0-rc.0') .then(function (resolution) { expect(resolution).to.eql({ type: 'version', @@ -575,7 +550,7 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('0.1.* || >=0.1.0-rc.1') + resolver._findResolution('0.1.*') .then(function (resolution) { expect(resolution).to.eql({ type: 'version', @@ -675,7 +650,7 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('~0.2.1-rc.0') + resolver._findResolution('~0.2.1') .then(function (resolution) { expect(resolution).to.eql({ type: 'version', diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index 9dd023f8f..a2e3ed415 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -366,30 +366,6 @@ else describe('SvnResolver', function () { .done(); }); - it('should fail to resolve "*" if a repository has valid semver tags, ignoring pre-releases if they are the only versions', function (next) { - var resolver; - - SvnResolver.tags = function () { - return Q.resolve({ - '0.1.0-rc.1': 1, - '0.1.0-rc.2': 2 - }); - }; - - resolver = create('foo'); - resolver._findResolution('*') - .then(function () { - next(new Error('Should have failed')); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.message).to.match(/no tag found that was able to satisfy/i); - expect(err.details).to.match(/0.1.0-rc/i); - expect(err.code).to.equal('ENORESTARGET'); - next(); - }) - .done(); - }); - it('should resolve "*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { var resolver; @@ -401,7 +377,7 @@ else describe('SvnResolver', function () { }; resolver = create('foo'); - resolver._findResolution('* || >=0.1.0-rc.0') + resolver._findResolution('*') .then(function (resolution) { expect(resolution).to.eql({ type: 'version', @@ -473,7 +449,7 @@ else describe('SvnResolver', function () { }; resolver = create('foo'); - resolver._findResolution('~0.2.1 || ~0.2.1-rc.0') + resolver._findResolution('~0.2.1') .then(function (resolution) { expect(resolution).to.eql({ type: 'version', From 26f80d25bef495d66c080e9bd4327f5de96436df Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 25 Aug 2015 22:09:38 +0200 Subject: [PATCH 0618/1021] Put smart host detection behind a configuration, fixes #1764 --- lib/core/resolvers/GitRemoteResolver.js | 5 +++++ test/core/resolvers/gitRemoteResolver.js | 18 +++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/core/resolvers/GitRemoteResolver.js b/lib/core/resolvers/GitRemoteResolver.js index 61cf86b01..e5d576247 100644 --- a/lib/core/resolvers/GitRemoteResolver.js +++ b/lib/core/resolvers/GitRemoteResolver.js @@ -191,6 +191,11 @@ GitRemoteResolver.prototype._supportsShallowCloning = function () { return Q.resolve(false); } + + if (!this._host || !this._config.shallowCloneHosts || this._config.shallowCloneHosts.indexOf(this._host) === -1) { + return Q.resolve(false); + } + // Check for protocol - the remote check for hosts supporting shallow cloning is only required for // HTTP or HTTPS, not for Git or SSH. // Also check for hosts that have been checked in a previous request and have been found to support diff --git a/test/core/resolvers/gitRemoteResolver.js b/test/core/resolvers/gitRemoteResolver.js index 039cac494..f90b03c81 100644 --- a/test/core/resolvers/gitRemoteResolver.js +++ b/test/core/resolvers/gitRemoteResolver.js @@ -285,7 +285,7 @@ describe('GitRemoteResolver', function () { */})) ); - var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); resolver._shallowClone().then(function (shallowCloningSupported) { expect(shallowCloningSupported).to.be(false); @@ -305,7 +305,7 @@ describe('GitRemoteResolver', function () { */})) ); - var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); resolver._shallowClone().then(function (shallowCloningSupported) { expect(shallowCloningSupported).to.be(false); @@ -347,7 +347,7 @@ describe('GitRemoteResolver', function () { */})) ); - var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); resolver._shallowClone().then(function (shallowCloningSupported) { expect(shallowCloningSupported).to.be(true); @@ -383,12 +383,12 @@ describe('GitRemoteResolver', function () { } ); - var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); resolver._shallowClone().then(function (shallowCloningSupported) { expect(shallowCloningSupported).to.be(true); - var resolver2 = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + var resolver2 = new MyGitRemoteResolver({ source: testSource }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); resolver2._shallowClone().then(function (shallowCloningSupported) { expect(shallowCloningSupported).to.be(true); @@ -428,12 +428,12 @@ describe('GitRemoteResolver', function () { } ); - var resolver = new MyGitRemoteResolver({ source: testSource1 }, defaultConfig(), logger); + var resolver = new MyGitRemoteResolver({ source: testSource1 }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); resolver._shallowClone().then(function (shallowCloningSupported) { expect(shallowCloningSupported).to.be(true); - var resolver2 = new MyGitRemoteResolver({ source: testSource2 }, defaultConfig(), logger); + var resolver2 = new MyGitRemoteResolver({ source: testSource2 }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); resolver2._shallowClone().then(function (shallowCloningSupported) { expect(shallowCloningSupported).to.be(true); @@ -482,12 +482,12 @@ describe('GitRemoteResolver', function () { } ); - var resolver = new MyGitRemoteResolver({ source: testSource1 }, defaultConfig(), logger); + var resolver = new MyGitRemoteResolver({ source: testSource1 }, defaultConfig({ shallowCloneHosts: ['foo', 'foo.bar.baz'] }), logger); resolver._shallowClone().then(function (shallowCloningSupported) { expect(shallowCloningSupported).to.be(true); - var resolver2 = new MyGitRemoteResolver({ source: testSource2 }, defaultConfig(), logger); + var resolver2 = new MyGitRemoteResolver({ source: testSource2 }, defaultConfig({ shallowCloneHosts: ['foo', 'foo.bar.baz'] }), logger); resolver2._shallowClone().then(function (shallowCloningSupported) { expect(shallowCloningSupported).to.be(true); From cb019c405b18dcee20aeb4370b6d3d10b9377e4c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 25 Aug 2015 22:31:13 +0200 Subject: [PATCH 0619/1021] Bump version to 1.5.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e1914e6ba..c5fbc3a5e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.5.1", + "version": "1.5.2", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 64d990ba102c8491c474dd99605b9a9725e62cbb Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 25 Aug 2015 22:37:23 +0200 Subject: [PATCH 0620/1021] Add changelog for 1.5.2 --- CHANGELOG.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 627bd85c3..10cbb45b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,16 @@ # Changelog -## 1.5.1 - 2015-08-25 +## 1.5.2 - 2015-08-25 + +- Revert update semver version from 2.x to 5.x, fixes ([#1896](https://github.com/bower/bower/issues/1896)) +- Make bower commands work from subdirectories, fixes ([#1893](https://github.com/bower/bower/issues/1893)) +- Put auto shallow cloning for git behind a flag, fixes ([#1764](https://github.com/bower/bower/issues/1764)) + +## 1.5.1 - 2015-08-24 - If cwd provided explicitly, force using it, fixes #1866 -## 1.5.0 - 2015-08-25 +## 1.5.0 - 2015-08-24 - Pluggable Resolvers! http://bower.io/docs/pluggable-resolvers/ - Update semver version from 2.x to 5.x ([#1852](https://github.com/bower/bower/issues/1852)) From 490f63a8381ab56eb7c27bd63a67d05ebf6f3524 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 3 Sep 2015 11:00:38 +0700 Subject: [PATCH 0621/1021] modularize the MD5 util function --- lib/core/Project.js | 2 +- lib/core/ResolveCache.js | 2 +- lib/util/md5.js | 7 ------- package.json | 1 + test/commands/cache/clean.js | 6 +++--- test/core/resolveCache.js | 2 +- 6 files changed, 7 insertions(+), 13 deletions(-) delete mode 100644 lib/util/md5.js diff --git a/lib/core/Project.js b/lib/core/Project.js index be290d76e..0987e499c 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -6,10 +6,10 @@ var mout = require('mout'); var rimraf = require('rimraf'); var endpointParser = require('bower-endpoint-parser'); var Logger = require('bower-logger'); +var md5 = require('md5-hex'); var Manager = require('./Manager'); var defaultConfig = require('../config'); var semver = require('../util/semver'); -var md5 = require('../util/md5'); var createError = require('../util/createError'); var readJson = require('../util/readJson'); var validLink = require('../util/validLink'); diff --git a/lib/core/ResolveCache.js b/lib/core/ResolveCache.js index 1103a9014..b60171be1 100644 --- a/lib/core/ResolveCache.js +++ b/lib/core/ResolveCache.js @@ -6,10 +6,10 @@ var mkdirp = require('mkdirp'); var rimraf = require('rimraf'); var LRU = require('lru-cache'); var lockFile = require('lockfile'); +var md5 = require('md5-hex'); var semver = require('../util/semver'); var readJson = require('../util/readJson'); var copy = require('../util/copy'); -var md5 = require('../util/md5'); function ResolveCache(config) { // TODO: Make some config entries, such as: diff --git a/lib/util/md5.js b/lib/util/md5.js deleted file mode 100644 index dbc920b04..000000000 --- a/lib/util/md5.js +++ /dev/null @@ -1,7 +0,0 @@ -var crypto = require('crypto'); - -function md5(contents) { - return crypto.createHash('md5').update(contents).digest('hex'); -} - -module.exports = md5; diff --git a/package.json b/package.json index c5fbc3a5e..42596d5da 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "junk": "^1.0.0", "lockfile": "^1.0.0", "lru-cache": "^2.5.0", + "md5-hex": "^1.0.2", "mkdirp": "0.5.0", "mout": "^0.11.0", "nopt": "^3.0.1", diff --git a/test/commands/cache/clean.js b/test/commands/cache/clean.js index 658eb47db..f0e8634c6 100644 --- a/test/commands/cache/clean.js +++ b/test/commands/cache/clean.js @@ -1,13 +1,13 @@ var expect = require('expect.js'); +var md5 = require('md5-hex'); var helpers = require('../../helpers'); var cacheClean = helpers.command('cache/clean'); -var md5 = helpers.require('lib/util/md5'); var object = require('mout/object'); describe('bower cache clean', function () { - // Because directory names are required to be mp5 of _source + // Because directory names are required to be md5 of _source var cacheFilesFactory = function (spec) { var files = {}; @@ -20,7 +20,7 @@ describe('bower cache clean', function () { return files; }; - + var cacheFiles = cacheFilesFactory([ { name: 'angular', diff --git a/test/core/resolveCache.js b/test/core/resolveCache.js index 9ea798ede..8276275af 100644 --- a/test/core/resolveCache.js +++ b/test/core/resolveCache.js @@ -5,11 +5,11 @@ var fs = require('graceful-fs'); var Q = require('q'); var expect = require('expect.js'); var mkdirp = require('mkdirp'); +var md5 = require('md5-hex'); var ResolveCache = require('../../lib/core/ResolveCache'); var defaultConfig = require('../../lib/config'); var cmd = require('../../lib/util/cmd'); var copy = require('../../lib/util/copy'); -var md5 = require('../../lib/util/md5'); describe('ResolveCache', function () { var resolveCache; From 304b6393d424b8f886a599a40e8cc0c28fa2d1a8 Mon Sep 17 00:00:00 2001 From: Ben Cullen-Kerney Date: Thu, 11 Jun 2015 14:48:48 -0500 Subject: [PATCH 0622/1021] Allow whitelisted values in bower.json file created by `bower init` A change in the behavior of `mout.lang.isEmpty()` in Mout v0.10.0 introduced a bug in `bower init`, preventing it from including Boolean values in "bower.json". This commit explicitly whitelists the types that are used in the bower.json spec - Object, Array, String, Boolean - as well as Number for future compatibility. --- lib/commands/init.js | 14 +++++++++++++- test/commands/init.js | 3 ++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/commands/init.js b/lib/commands/init.js index 80531b0f0..ee09b29d3 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -58,7 +58,7 @@ function readJson(project, logger) { function saveJson(project, logger, json) { // Cleanup empty props (null values, empty strings, objects and arrays) mout.object.forOwn(json, function (value, key) { - if (value == null || mout.lang.isEmpty(value)) { + if (!validConfigValue(value)) { delete json[key]; } }); @@ -81,6 +81,18 @@ function saveJson(project, logger, json) { }); } +// Test if value is of a type supported by bower.json[0] - Object, Array, String, Boolean - or a Number +// [0]: https://github.com/bower/bower.json-spec +function validConfigValue(val) { + return ( + mout.lang.isObject(val) || + mout.lang.isArray(val) || + mout.lang.isString(val) || + mout.lang.isBoolean(val) || + mout.lang.isNumber(val) + ); +} + function setDefaults(config, json) { var name; var promise = Q.resolve(); diff --git a/test/commands/init.js b/test/commands/init.js index fdf905738..7f5e1049b 100644 --- a/test/commands/init.js +++ b/test/commands/init.js @@ -49,7 +49,8 @@ describe('bower init', function () { description: 'test-description', moduleType: 'test-moduleType', keywords: [ 'test-keyword' ], - license: 'test-license' + license: 'test-license', + private: true }); }); }); From 5d13ffda095dcac34bc69c02b3edba4b698706de Mon Sep 17 00:00:00 2001 From: Luke Melia Date: Sat, 12 Sep 2015 21:10:01 -0400 Subject: [PATCH 0623/1021] Include package name in error info when a version is not found. Prior to this commit, when specifying a package version that cannot be resolved, but other versions are available, the error message did not state which what package failed, allowing for confusion. For example, you might see: ``` bower ENORESTARGET No tag found that was able to satisfy 1.0.2 Additional error details: Available versions: 1.0.1, 1.0.0 ``` After this change, in the above situation the svn and git resolvers will produce the following: ``` bower ENORESTARGET No tag found that was able to satisfy 1.0.2 Additional error details: Available versions in somelib: 1.0.1, 1.0.0 ``` --- lib/core/resolvers/GitResolver.js | 2 +- lib/core/resolvers/SvnResolver.js | 2 +- test/core/resolvers/gitResolver.js | 2 +- test/core/resolvers/svnResolver.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/core/resolvers/GitResolver.js b/lib/core/resolvers/GitResolver.js index e4d8d2946..e20409fcf 100644 --- a/lib/core/resolvers/GitResolver.js +++ b/lib/core/resolvers/GitResolver.js @@ -144,7 +144,7 @@ GitResolver.prototype._findResolution = function (target) { throw createError('No tag found that was able to satisfy ' + target, 'ENORESTARGET', { details: !versions.length ? 'No versions found in ' + that._source : - 'Available versions: ' + versions.map(function (version) { return version.version; }).join(', ') + 'Available versions in ' + that._source + ': ' + versions.map(function (version) { return version.version; }).join(', ') }); }); }); diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js index 601bcaba6..7f414bf08 100644 --- a/lib/core/resolvers/SvnResolver.js +++ b/lib/core/resolvers/SvnResolver.js @@ -188,7 +188,7 @@ SvnResolver.prototype._findResolution = function (target) { throw createError('No tag found that was able to satisfy ' + target, 'ENORESTARGET', { details: !versions.length ? 'No versions found in ' + that._source : - 'Available versions: ' + versions.map(function (version) { return version.version; }).join(', ') + 'Available versions in ' + that._source + ': ' + versions.map(function (version) { return version.version; }).join(', ') }); }); }); diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index 0b2d4030f..98c13cec4 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -706,7 +706,7 @@ describe('GitResolver', function () { }, function (err) { expect(err).to.be.an(Error); expect(err.message).to.match(/was able to satisfy ~0.2.0/i); - expect(err.details).to.match(/available versions: 0\.1\.1, 0\.1\.0/i); + expect(err.details).to.match(/available versions in foo: 0\.1\.1, 0\.1\.0/i); expect(err.code).to.equal('ENORESTARGET'); next(); }) diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index a2e3ed415..e2d5f06dc 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -503,7 +503,7 @@ else describe('SvnResolver', function () { }, function (err) { expect(err).to.be.an(Error); expect(err.message).to.match(/was able to satisfy ~0.2.0/i); - expect(err.details).to.match(/available versions: 0\.1\.1, 0\.1\.0/i); + expect(err.details).to.match(/available versions in foo: 0\.1\.1, 0\.1\.0/i); expect(err.code).to.equal('ENORESTARGET'); next(); }) From 889b54f309fe25a9abddc955e15f4cbaf6027b76 Mon Sep 17 00:00:00 2001 From: Peng Wang Date: Thu, 17 Sep 2015 16:25:05 -0500 Subject: [PATCH 0624/1021] allow --config.resolvers={required package} --- lib/core/resolverFactory.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index b192e795d..a397a539e 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -44,8 +44,15 @@ function getConstructor(decEndpoint, options, registryClient) { // its "match" to check if given resolves supports given decEndpoint addResolver(function () { var selectedResolver; - - var resolverNames = config.resolvers || []; + var resolverNames; + + if (Array.isArray(config.resolvers)) { + resolverNames = config.resolvers; + } else if (!!config.resolvers) { + resolverNames = config.resolvers.split(','); + } else { + resolverNames = []; + } var resolverPromises = resolverNames.map(function (resolverName) { var resolver = resolvers[resolverName] From aac254d275eda504c817a84fe8af54b1eab08ea4 Mon Sep 17 00:00:00 2001 From: Michael Storgaard Date: Fri, 18 Sep 2015 11:18:08 +0200 Subject: [PATCH 0625/1021] Bumped Insight to reduce prompt friction - Insight now checks for `process.env.CI` before prompting - Insight now times out after 30 seconds of no response to prompt --- package.json | 2 +- test/util/analytics.js | 43 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 42596d5da..c5bec0d71 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "graceful-fs": "^3.0.5", "handlebars": "^2.0.0", "inquirer": "0.8.0", - "insight": "^0.5.0", + "insight": "^0.7.0", "is-root": "^1.0.0", "junk": "^1.0.0", "lockfile": "^1.0.0", diff --git a/test/util/analytics.js b/test/util/analytics.js index d95cd170e..8b0fdb23e 100644 --- a/test/util/analytics.js +++ b/test/util/analytics.js @@ -17,6 +17,15 @@ describe('analytics', function () { }; describe('#setup', function () { + // Reset process.env.CI after tests are done + var oldCI; + beforeEach(function () { + oldCI = process.env.CI; + }); + afterEach(function () { + process.env.CI = oldCI; + }); + it('leaves analytics enabled if provided', function () { return mockAnalytics() .setup({ analytics: true }) @@ -80,6 +89,40 @@ describe('analytics', function () { expect(enabled).to.be(false); }); }); + + it('disables if process.env.CI is true', function () { + process.env.CI = true; + + // Clear cache set by proxyquire + delete require.cache[require.resolve('../../lib/util/analytics')]; + + var analytics = require('../../lib/util/analytics'); + return analytics.setup({ interactive: true }) + .then(function (enabled) { + expect(enabled).to.be(false); + }); + }); + + it('disables if prompt times out', function () { + // Create mock insight with very low permission timeout + var Insight = require('insight'); + var mockInsight = new Insight({ + trackingCode: 'mock', + pkg: require('../../package.json') + }); + mockInsight._permissionTimeout = 0.1; + var mockAnalyticsWithInsight = proxyquire('../../lib/util/analytics', { + insight: function () { + return mockInsight; + } + }); + + return mockAnalyticsWithInsight + .setup({ interactive: true }) + .then(function (enabled) { + expect(enabled).to.be(false); + }); + }); }); describe('Tracker', function (next) { From 9c52ec2751d689a2cddb34adb004df41ce7c8a92 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 24 Sep 2015 11:06:55 +0200 Subject: [PATCH 0626/1021] Revert "Auto-sort bower.json dependencies alphabetically, fixes #1373" This reverts commit 9dd79a80614925e10e5cead9e74f834051feece9. --- lib/core/Project.js | 5 ++--- package.json | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/core/Project.js b/lib/core/Project.js index 0987e499c..3779819a1 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -14,7 +14,6 @@ var createError = require('../util/createError'); var readJson = require('../util/readJson'); var validLink = require('../util/validLink'); var scripts = require('./scripts'); -var sortobject = require('deep-sort-object'); function Project(config, logger) { // This is the only architecture component that ensures defaults @@ -99,11 +98,11 @@ Project.prototype.install = function (decEndpoints, options, config) { } if (that._options.save) { - that._json.dependencies = sortobject(mout.object.mixIn(that._json.dependencies || {}, jsonEndpoint)); + that._json.dependencies = mout.object.mixIn(that._json.dependencies || {}, jsonEndpoint); } if (that._options.saveDev) { - that._json.devDependencies = sortobject(mout.object.mixIn(that._json.devDependencies || {}, jsonEndpoint)); + that._json.devDependencies = mout.object.mixIn(that._json.devDependencies || {}, jsonEndpoint); } }); } diff --git a/package.json b/package.json index c5bec0d71..560144831 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,6 @@ "chmodr": "0.1.0", "configstore": "^0.3.2", "decompress-zip": "^0.1.0", - "deep-sort-object": "~0.1.1", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", "github": "^0.2.3", From 87a041a212a03142e92c56ff832bcf5cbf49a72b Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 24 Sep 2015 13:34:49 +0200 Subject: [PATCH 0627/1021] Fix --save-exact feature for github endpoints, fixes #1925 --- lib/core/Project.js | 14 ++++++++------ test/commands/install.js | 26 ++++---------------------- 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/lib/core/Project.js b/lib/core/Project.js index 3779819a1..895d9a452 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -86,7 +86,7 @@ Project.prototype.install = function (decEndpoints, options, config) { }) .then(function (installed) { // Handle save and saveDev options - if (that._options.save || that._options.saveDev) { + if (that._options.save || that._options.saveDev || that._options.saveExact) { // Cycle through the specified endpoints decEndpoints.forEach(function (decEndpoint) { var jsonEndpoint; @@ -94,15 +94,17 @@ Project.prototype.install = function (decEndpoints, options, config) { jsonEndpoint = endpointParser.decomposed2json(decEndpoint); if (that._options.saveExact) { - jsonEndpoint[decEndpoint.name] = decEndpoint.pkgMeta.version; - } - - if (that._options.save) { - that._json.dependencies = mout.object.mixIn(that._json.dependencies || {}, jsonEndpoint); + if (decEndpoint.name !== decEndpoint.source) { + jsonEndpoint[decEndpoint.name] = decEndpoint.source + '#' + decEndpoint.pkgMeta.version; + } else { + jsonEndpoint[decEndpoint.name] = decEndpoint.pkgMeta.version; + } } if (that._options.saveDev) { that._json.devDependencies = mout.object.mixIn(that._json.devDependencies || {}, jsonEndpoint); + } else { + that._json.dependencies = mout.object.mixIn(that._json.dependencies || {}, jsonEndpoint); } }); } diff --git a/test/commands/install.js b/test/commands/install.js index 765fc0947..7559a7d84 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -56,6 +56,7 @@ describe('bower install', function () { it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function () { package.prepare({ 'bower.json': { + name: 'package', version: '1.2.3' } }); @@ -70,13 +71,14 @@ describe('bower install', function () { [package.path], { saveExact: true, save: true } ]).then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal('1.2.3'); + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(package.path + '#1.2.3'); }); }); it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function () { package.prepare({ 'bower.json': { + name: 'package', version: '0.1.0' } }); @@ -91,27 +93,7 @@ describe('bower install', function () { [package.path], { saveExact: true, saveDev: true } ]).then(function() { - expect(tempDir.readJson('bower.json').devDependencies.package).to.equal('0.1.0'); - }); - }); - - - it('does not write to bower.json if only --save-exact flag is used', function() { - package.prepare({ - 'bower.json': { - version: '1.2.3' - } - }); - - tempDir.prepare({ - 'bower.json': { - name: 'test' - } - }); - - return helpers.run(install, [[package.path], { saveExact: true }]).then(function() { - expect(tempDir.read('bower.json')).to.not.contain('dependencies'); - expect(tempDir.read('bower.json')).to.not.contain('devDependencies'); + expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(package.path + '#0.1.0'); }); }); From 66310523d16a1f342f3da2aa49ea90d927fe7d46 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 24 Sep 2015 13:58:05 +0200 Subject: [PATCH 0628/1021] Bump to 1.5.3 --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10cbb45b1..0c9808043 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 1.5.3 - 2015-09-24 + +- Revert auto sorting of bower dependencies, fixes ([#1897](https://github.com/bower/bower/issues/1897)) +- Fix --save-exact feature for github endpoints, fixes ([#1925](https://github.com/bower/bower/issues/1925)) +- Fix `bower init` to support private flag again ([#1819](https://github.com/bower/bower/pull/1819)) +- Bump insight dependency to support prompt timeout ([#1102](https://github.com/bower/bower/issues/1102)) + ## 1.5.2 - 2015-08-25 - Revert update semver version from 2.x to 5.x, fixes ([#1896](https://github.com/bower/bower/issues/1896)) diff --git a/package.json b/package.json index 560144831..7227df002 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.5.2", + "version": "1.5.3", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From d72d01823d60bb1523b0c802010a8498209732d9 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 24 Sep 2015 14:54:16 +0200 Subject: [PATCH 0629/1021] Bump inquirer to 0.10, closes #1883 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7227df002..4f0c7b0e7 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "glob": "^4.3.2", "graceful-fs": "^3.0.5", "handlebars": "^2.0.0", - "inquirer": "0.8.0", + "inquirer": "0.10.0", "insight": "^0.7.0", "is-root": "^1.0.0", "junk": "^1.0.0", From 44a52600508953e92590b2e43f42851a70622883 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 12:22:30 +0200 Subject: [PATCH 0630/1021] test: Clear analytics config for test environment --- lib/util/analytics.js | 22 ++++++++++++++++++---- test/helpers.js | 1 + test/util/analytics.js | 3 +++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/util/analytics.js b/lib/util/analytics.js index 8291c4b8a..6cd50adf2 100644 --- a/lib/util/analytics.js +++ b/lib/util/analytics.js @@ -19,13 +19,27 @@ var enableAnalytics = false; // because it takes time to read config and configstore has concurrency issues: // // https://github.com/yeoman/configstore/issues/20 + function ensureInsight () { if (!insight) { var Insight = require('insight'); - insight = new Insight({ - trackingCode: 'UA-43531210-1', - pkg: require('../../package.json') - }); + + if (process.env.NODE_ENV === 'test') { + insight = new Insight({ + trackingCode: 'UA-00000000-0', + pkg: { + name: 'bower-test', + version: '1.0.0' + } + }); + + insight.config.clear(); + } else { + insight = new Insight({ + trackingCode: 'UA-43531210-1', + pkg: require('../../package.json') + }); + } } } diff --git a/test/helpers.js b/test/helpers.js index ae1293139..fda14ecba 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -26,6 +26,7 @@ var env = { 'GIT_COMMITTER_DATE': 'Sun Apr 7 22:13:13 2013 +0000', 'GIT_COMMITTER_NAME': 'André Cruz', 'GIT_COMMITTER_EMAIL': 'amdfcruz@gmail.com', + 'NODE_ENV': 'test' }; object.mixIn(process.env, env); diff --git a/test/util/analytics.js b/test/util/analytics.js index 8b0fdb23e..bd8857f1a 100644 --- a/test/util/analytics.js +++ b/test/util/analytics.js @@ -10,6 +10,9 @@ describe('analytics', function () { return object.merge(stubs || {}, { askPermission: function (message, callback) { callback(undefined, promptResponse); + }, + config: { + clear: function () {} } }); } From 4805c3615b056b72bf4ca7ac080594bdb6136e85 Mon Sep 17 00:00:00 2001 From: SignalDancer Date: Tue, 8 Jul 2014 16:54:54 -0400 Subject: [PATCH 0631/1021] Allow Ignore For Child Dependencies Fix for bug #927. Ignore package if name matches specified in bower.json. Permit fetch if package is explicitly declared in dependencies or devDependencies. Designed for users who need tighter control of versions due to corporate liscence restrictions or other reasons. Code Review Comments --- lib/core/Manager.js | 11 ++++++++++- lib/core/Project.js | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 6ddb97a75..b10d3c760 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -68,6 +68,9 @@ Manager.prototype.configure = function (setup) { } }, this); + // Dependencies to resolve ONLY if explicitly declared at top level. + this._ignoredDependencies = setup.ignoredDependencies; + // Resolutions this._resolutions = setup.resolutions || {}; @@ -445,6 +448,12 @@ Manager.prototype._parseDependencies = function (decEndpoint, pkgMeta) { var compatible; var childDecEndpoint = endpointParser.json2decomposed(key, value); + // Check if this depdendency should be skipped. + if (mout.array.contains(this._ignoredDependencies, childDecEndpoint.name)) { + this._logger.action('skipped', childDecEndpoint.name, this.toData(decEndpoint)); + return; + } + // Check if a compatible one is already resolved // If there's one, we don't need to resolve it twice resolved = this._resolved[key]; @@ -1048,5 +1057,5 @@ Manager.prototype._uniquify = function (decEndpoints) { return true; }); }; - + module.exports = Manager; diff --git a/lib/core/Project.js b/lib/core/Project.js index 895d9a452..79868a15f 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -543,7 +543,8 @@ Project.prototype._bootstrap = function (targets, resolved, incompatibles) { incompatibles: incompatibles, resolutions: this._json.resolutions, installed: installed, - forceLatest: this._options.forceLatest + forceLatest: this._options.forceLatest, + ignoredDependencies: this._json.ignoredDependencies || [] }) .resolve() .then(function () { From e7d22ffb11b970147eb11c57bea1ac6511d9e648 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Mon, 22 Jun 2015 15:05:02 -0700 Subject: [PATCH 0632/1021] install and update tests for ignoredDependencies --- test/commands/install.js | 35 +++++++++++++++++++ test/commands/update.js | 74 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 106 insertions(+), 3 deletions(-) diff --git a/test/commands/install.js b/test/commands/install.js index 7559a7d84..bf4767d0f 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -255,4 +255,39 @@ describe('bower install', function () { expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); }); }); + + it('does not install ignored dependencies', function() { + package.prepare(); + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + } + }).prepare(); + + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3', + dependencies: { + package2: package2.path, + package: package.path, + } + } + }).prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test_tw', + dependencies: { + package3: package3.path + }, + ignoredDependencies: ['package'] + }, + }); + + return helpers.run(install).then(function() { + expect(tempDir.exists('bower_components/package')).to.be(false); + expect(tempDir.exists('bower_components/package2')).to.be(true); + }); + + }); }); diff --git a/test/commands/update.js b/test/commands/update.js index 8dca277d4..c32552400 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -9,6 +9,12 @@ describe('bower update', function () { var tempDir = new helpers.TempDir(); + var subPackage = new helpers.TempDir({ + 'bower.json': { + name: 'subPackage' + } + }).prepare(); + var gitPackage = new helpers.TempDir(); gitPackage.prepareGit({ @@ -20,7 +26,10 @@ describe('bower update', function () { }, '1.0.1': { 'bower.json': { - name: 'package' + name: 'package', + dependencies: { + subPackage: subPackage.path + } }, 'version.txt': '1.0.1' } @@ -81,6 +90,33 @@ describe('bower update', function () { }); }); + it('does not install ignored dependencies', function() { + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + dependencies: { + package: package.path + } + } + }).prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package2: package2.path + }, + ignoredDependencies: ['package'] + } + }); + + return update().then(function() { + expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); + expect(tempDir.exists('bower_components/package')).to.equal(false); + }); + + }); + it('runs preinstall hook when installing missing package', function () { package.prepare(); @@ -180,6 +216,38 @@ describe('bower update', function () { }); }); + it('does not install ignored dependencies when updating a package', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.0' + } + } + }); + + return install().then(function() { + + expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); + expect(tempDir.exists('bower_components/subPackage')).to.equal(false); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.1' + }, + ignoredDependencies: ['subPackage'] + } + }); + + return update().then(function() { + expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.1'); + expect(tempDir.exists('bower_components/subPackage')).to.equal(false); + }); + }); + }); + it('runs preinstall hook when updating a package', function () { tempDir.prepare({ 'bower.json': { @@ -207,7 +275,7 @@ describe('bower update', function () { expect(tempDir.exists('preinstall.txt')).to.be(false); return update().then(function() { - expect(tempDir.read('preinstall.txt')).to.be('package'); + expect(tempDir.read('preinstall.txt')).to.be('subPackage package'); }); }); }); @@ -240,7 +308,7 @@ describe('bower update', function () { expect(tempDir.exists('postinstall.txt')).to.be(false); return update().then(function() { - expect(tempDir.read('postinstall.txt')).to.be('package'); + expect(tempDir.read('postinstall.txt')).to.be('subPackage package'); }); }); }); From 2ccc05cb984c926ea96eb82c415beb4b133954ec Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Tue, 22 Sep 2015 10:06:38 -0700 Subject: [PATCH 0633/1021] get ignoredDependencies from .bowerrc instead of bower.json --- lib/core/Manager.js | 8 ++------ lib/core/Project.js | 3 +-- test/commands/install.js | 6 ++++-- test/commands/update.js | 10 +++++++--- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index b10d3c760..65e114930 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -23,7 +23,6 @@ function Manager(config, logger) { Manager.prototype.configure = function (setup) { var targetsHash = {}; - this._conflicted = {}; // Targets @@ -68,9 +67,6 @@ Manager.prototype.configure = function (setup) { } }, this); - // Dependencies to resolve ONLY if explicitly declared at top level. - this._ignoredDependencies = setup.ignoredDependencies; - // Resolutions this._resolutions = setup.resolutions || {}; @@ -449,7 +445,7 @@ Manager.prototype._parseDependencies = function (decEndpoint, pkgMeta) { var childDecEndpoint = endpointParser.json2decomposed(key, value); // Check if this depdendency should be skipped. - if (mout.array.contains(this._ignoredDependencies, childDecEndpoint.name)) { + if (mout.array.contains(this._config.ignoredDependencies, childDecEndpoint.name)) { this._logger.action('skipped', childDecEndpoint.name, this.toData(decEndpoint)); return; } @@ -1057,5 +1053,5 @@ Manager.prototype._uniquify = function (decEndpoints) { return true; }); }; - + module.exports = Manager; diff --git a/lib/core/Project.js b/lib/core/Project.js index 79868a15f..895d9a452 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -543,8 +543,7 @@ Project.prototype._bootstrap = function (targets, resolved, incompatibles) { incompatibles: incompatibles, resolutions: this._json.resolutions, installed: installed, - forceLatest: this._options.forceLatest, - ignoredDependencies: this._json.ignoredDependencies || [] + forceLatest: this._options.forceLatest }) .resolve() .then(function () { diff --git a/test/commands/install.js b/test/commands/install.js index bf4767d0f..34a7ab671 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -279,9 +279,11 @@ describe('bower install', function () { name: 'test_tw', dependencies: { package3: package3.path - }, - ignoredDependencies: ['package'] + } }, + '.bowerrc': { + ignoredDependencies: ['package'] + } }); return helpers.run(install).then(function() { diff --git a/test/commands/update.js b/test/commands/update.js index c32552400..847387e8b 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -105,7 +105,9 @@ describe('bower update', function () { name: 'test', dependencies: { package2: package2.path - }, + } + }, + '.bowerrc': { ignoredDependencies: ['package'] } }); @@ -223,6 +225,9 @@ describe('bower update', function () { dependencies: { package: gitPackage.path + '#1.0.0' } + }, + '.bowerrc': { + ignoredDependencies: ['subPackage'] } }); @@ -236,8 +241,7 @@ describe('bower update', function () { name: 'test', dependencies: { package: gitPackage.path + '#1.0.1' - }, - ignoredDependencies: ['subPackage'] + } } }); From 201b8a3bc69e4e5d259d0206e1f3dfc51266b094 Mon Sep 17 00:00:00 2001 From: Adriaan Thomas Date: Fri, 31 Jul 2015 12:22:58 +0200 Subject: [PATCH 0634/1021] Load CA file contents instead of keeping the path, so the request library can use it. --- packages/bower-config/lib/Config.js | 33 +++++++++++++++ .../test/assets/custom-ca/.bowerrc | 3 ++ .../test/assets/custom-ca/ca-bundle.crt | 40 +++++++++++++++++++ packages/bower-config/test/test.js | 30 ++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 packages/bower-config/test/assets/custom-ca/.bowerrc create mode 100644 packages/bower-config/test/assets/custom-ca/ca-bundle.crt diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index b87abb45c..3e64a31cc 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -4,6 +4,7 @@ var rc = require('./util/rc'); var defaults = require('./util/defaults'); var expand = require('./util/expand'); var path = require('path'); +var fs = require('fs'); function Config(cwd) { this._cwd = cwd || process.cwd(); @@ -33,10 +34,42 @@ Config.prototype.save = function (where, callback) { // TODO }; /* jshint ignore:end */ + +function readCertFile(path) { + var sep = '-----END CERTIFICATE-----'; + + return fs.readFileSync(path, { encoding: 'utf8' }) + .split(sep) + .filter(function(s) { return !s.match(/^\s*$/); }) + .map(function(s) { return s + sep; }); +} + +function loadCAs(caConfig) { + // If a ca file path has been specified, expand that here to the file's + // contents. As a user can specify these individually, we must load them + // one by one. + if (caConfig.search) { + caConfig.search = caConfig.search.map(function(s) { + return readCertFile(s); + }); + } + ['register', 'publish'].forEach(function(p) { + if (caConfig[p]) { + caConfig[p] = readCertFile(caConfig[p]); + } + }); +} + Config.prototype.toObject = function () { var config = lang.deepClone(this._config); config = Config.normalise(config); + + // Load CA files and replace their paths with their contents. + // Do that here so that we have a normalised config object, + // and so that it is done only once. + loadCAs(config.ca); + return config; }; diff --git a/packages/bower-config/test/assets/custom-ca/.bowerrc b/packages/bower-config/test/assets/custom-ca/.bowerrc new file mode 100644 index 000000000..bf9669c26 --- /dev/null +++ b/packages/bower-config/test/assets/custom-ca/.bowerrc @@ -0,0 +1,3 @@ +{ + "ca": "test/assets/custom-ca/ca-bundle.crt" +} diff --git a/packages/bower-config/test/assets/custom-ca/ca-bundle.crt b/packages/bower-config/test/assets/custom-ca/ca-bundle.crt new file mode 100644 index 000000000..5c60cfbf8 --- /dev/null +++ b/packages/bower-config/test/assets/custom-ca/ca-bundle.crt @@ -0,0 +1,40 @@ +Equifax Secure CA +================= +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE +ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT +B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB +nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR +fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW +8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG +A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE +CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG +A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS +spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB +Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961 +zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB +BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95 +70+sB3c4 +-----END CERTIFICATE----- + +GlobalSign Root CA +================== +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx +GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds +b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV +BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD +VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa +DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc +THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb +Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP +c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX +gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF +AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj +Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG +j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH +hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC +X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index b0e6183f5..5351ba31f 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -1,4 +1,5 @@ var assert = require('assert'); +var path = require('path'); describe('NPM Config on package.json', function () { describe('Setting process.env.npm_package_config', function () { @@ -15,6 +16,35 @@ describe('NPM Config on package.json', function () { assert.equal('false', config.colors); }); }); + + describe('Specifying custom CA', function() { + var config = require('../lib/Config') + .read(path.resolve('test/assets/custom-ca')); + + it('should read the CA file', function() { + function assertCAContents(caData, name) { + var r = /-----BEGIN CERTIFICATE-----[a-zA-Z0-9+\/=\n\r]+-----END CERTIFICATE-----/; + + assert(caData, name + ' should be set'); + assert(Array.isArray(caData), name + ' should be an array'); + assert.equal(2, caData.length); + caData.forEach(function(c, i) { + assert(c.match(r), + name + '[' + i + '] should contain a certificate'); + }); + } + + ['register', 'publish'].forEach(function (p) { + assertCAContents(config.ca[p], 'config.ca.' + p); + }); + + assert(Array.isArray(config.ca.search), + 'ca property search should be an array'); + config.ca.search.forEach(function(c, i) { + assertCAContents(c, 'config.ca.search[' + i + ']'); + }); + }); + }); }); require('./util/index'); From af9b386d8a637cc26ac4c7adf3a1d8884f8e9afd Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 13:33:28 +0200 Subject: [PATCH 0635/1021] Suport backward-compatible ca certificate embedding --- packages/bower-config/lib/Config.js | 12 +++++- packages/bower-config/lib/util/expand.js | 18 +++++++- .../test/assets/custom-ca-embed/.bowerrc | 3 ++ packages/bower-config/test/test.js | 42 +++++++++++++------ 4 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 packages/bower-config/test/assets/custom-ca-embed/.bowerrc diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index 3e64a31cc..4ef370d8e 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -36,9 +36,19 @@ Config.prototype.save = function (where, callback) { /* jshint ignore:end */ function readCertFile(path) { + path = path || ''; + var sep = '-----END CERTIFICATE-----'; - return fs.readFileSync(path, { encoding: 'utf8' }) + var certificates; + + if (path.indexOf(sep) === -1) { + certificates = fs.readFileSync(path, { encoding: 'utf8' }); + } else { + certificates = path; + } + + return certificates .split(sep) .filter(function(s) { return !s.match(/^\s*$/); }) .map(function(s) { return s + sep; }); diff --git a/packages/bower-config/lib/util/expand.js b/packages/bower-config/lib/util/expand.js index 6243f74bb..e59bf7b78 100644 --- a/packages/bower-config/lib/util/expand.js +++ b/packages/bower-config/lib/util/expand.js @@ -26,27 +26,41 @@ function expand(config) { // Registry if (typeof config.registry === 'string') { config.registry = { + default: config.registry, search: [config.registry], register: config.registry, publish: config.registry }; - } else if (config.registry) { + } else if (typeof config.registry === 'object') { if (config.registry.search && !Array.isArray(config.registry.search)) { config.registry.search = [config.registry.search]; } + + if (config.registry.default) { + config.registry.search = config.registry.search || config.registry.default; + config.registry.register = config.registry.register || config.registry.default; + config.registry.publish = config.registry.publish || config.registry.default; + } } // CA if (typeof config.ca === 'string') { config.ca = { + default: config.ca, search: [config.ca], register: config.ca, publish: config.ca }; - } else if (config.ca) { + } else if (typeof config.ca === 'object') { if (config.ca.search && !Array.isArray(config.ca.search)) { config.ca.search = [config.ca.search]; } + + if (config.ca.default) { + config.ca.search = config.ca.search || config.ca.default; + config.ca.register = config.ca.register || config.ca.default; + config.ca.publish = config.ca.publish || config.ca.default; + } } return config; diff --git a/packages/bower-config/test/assets/custom-ca-embed/.bowerrc b/packages/bower-config/test/assets/custom-ca-embed/.bowerrc new file mode 100644 index 000000000..519774b8a --- /dev/null +++ b/packages/bower-config/test/assets/custom-ca-embed/.bowerrc @@ -0,0 +1,3 @@ +{ + "ca": "Equifax Secure CA\n=================\n-----BEGIN CERTIFICATE-----\nMIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE\nChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5\nMB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT\nB0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB\nnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR\nfM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW\n8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG\nA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE\nCxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG\nA1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS\nspXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB\nAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961\nzgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB\nBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95\n70+sB3c4\n-----END CERTIFICATE-----\n\nGlobalSign Root CA\n==================\n-----BEGIN CERTIFICATE-----\nMIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx\nGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds\nb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV\nBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD\nVQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa\nDuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc\nTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb\nKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP\nc1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX\ngzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\nHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF\nAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj\nY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG\nj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH\nhm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC\nX4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\n-----END CERTIFICATE-----" +} diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index 5351ba31f..08a3066ee 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -2,6 +2,18 @@ var assert = require('assert'); var path = require('path'); describe('NPM Config on package.json', function () { + function assertCAContents(caData, name) { + var r = /-----BEGIN CERTIFICATE-----[a-zA-Z0-9+\/=\n\r]+-----END CERTIFICATE-----/; + + assert(caData, name + ' should be set'); + assert(Array.isArray(caData), name + ' should be an array'); + assert.equal(2, caData.length); + caData.forEach(function(c, i) { + assert(c.match(r), + name + '[' + i + '] should contain a certificate. Given: ' + JSON.stringify(c)); + }); + } + describe('Setting process.env.npm_package_config', function () { /*jshint camelcase:false*/ process.env.npm_package_config_bower_directory = 'npm-path'; @@ -18,21 +30,25 @@ describe('NPM Config on package.json', function () { }); describe('Specifying custom CA', function() { - var config = require('../lib/Config') - .read(path.resolve('test/assets/custom-ca')); it('should read the CA file', function() { - function assertCAContents(caData, name) { - var r = /-----BEGIN CERTIFICATE-----[a-zA-Z0-9+\/=\n\r]+-----END CERTIFICATE-----/; - - assert(caData, name + ' should be set'); - assert(Array.isArray(caData), name + ' should be an array'); - assert.equal(2, caData.length); - caData.forEach(function(c, i) { - assert(c.match(r), - name + '[' + i + '] should contain a certificate'); - }); - } + var config = require('../lib/Config') + .read(path.resolve('test/assets/custom-ca')); + + ['register', 'publish'].forEach(function (p) { + assertCAContents(config.ca[p], 'config.ca.' + p); + }); + + assert(Array.isArray(config.ca.search), + 'ca property search should be an array'); + config.ca.search.forEach(function(c, i) { + assertCAContents(c, 'config.ca.search[' + i + ']'); + }); + }); + + it('should backward-support certificate inside .bowerrc', function() { + var config = require('../lib/Config') + .read(path.resolve('test/assets/custom-ca-embed')); ['register', 'publish'].forEach(function (p) { assertCAContents(config.ca[p], 'config.ca.' + p); From 4e3e45a88bb5bc4b9ac4ba7f34233bf29dcc4f35 Mon Sep 17 00:00:00 2001 From: John Andersen Date: Fri, 11 Sep 2015 08:07:28 -0700 Subject: [PATCH 0636/1021] Support for setting and restoring proxy related env variables --- packages/bower-config/.jshintrc | 1 - packages/bower-config/lib/Config.js | 8 +++ packages/bower-config/lib/util/defaults.js | 6 ++- packages/bower-config/lib/util/proxy.js | 52 +++++++++++++++++++ .../test/assets/env-variables/.bowerrc | 5 ++ packages/bower-config/test/test.js | 46 +++++++++++++++- 6 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 packages/bower-config/lib/util/proxy.js create mode 100644 packages/bower-config/test/assets/env-variables/.bowerrc diff --git a/packages/bower-config/.jshintrc b/packages/bower-config/.jshintrc index eae6f9cf4..52c609091 100644 --- a/packages/bower-config/.jshintrc +++ b/packages/bower-config/.jshintrc @@ -30,7 +30,6 @@ "quotmark": "single", "strict": false, "trailing": true, - "camelcase": true, "asi": false, "boss": true, diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index 4ef370d8e..00db28d24 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -3,18 +3,26 @@ var object = require('mout/object'); var rc = require('./util/rc'); var defaults = require('./util/defaults'); var expand = require('./util/expand'); +var EnvProxy = require('./util/proxy'); var path = require('path'); var fs = require('fs'); function Config(cwd) { this._cwd = cwd || process.cwd(); + this._proxy = new EnvProxy(); this._config = {}; } Config.prototype.load = function () { this._config = rc('bower', defaults, this._cwd); + this._proxy.set(this._config); return this; }; + +Config.prototype.restore = function () { + this._proxy.restore(); +}; + /* jshint ignore:start */ Config.prototype.get = function (key) { // TODO diff --git a/packages/bower-config/lib/util/defaults.js b/packages/bower-config/lib/util/defaults.js index c742cbd09..e982d163c 100644 --- a/packages/bower-config/lib/util/defaults.js +++ b/packages/bower-config/lib/util/defaults.js @@ -2,7 +2,6 @@ var path = require('path'); var paths = require('./paths'); // Guess proxy defined in the env -/*jshint camelcase: false*/ var proxy = process.env.HTTP_PROXY || process.env.http_proxy || null; @@ -10,7 +9,9 @@ var proxy = process.env.HTTP_PROXY var httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy || proxy; -/*jshint camelcase: true*/ + +var noProxy = process.env.NO_PROXY + || process.env.no_proxy; // Use a well known user agent (in this case, curl) when using a proxy, // to avoid potential filtering on many corporate proxies with blank or unknown agents @@ -26,6 +27,7 @@ var defaults = { 'tmp': paths.tmp, 'proxy': proxy, 'https-proxy': httpsProxy, + 'no-proxy': noProxy, 'timeout': 30000, 'ca': { search: [] }, 'strict-ssl': true, diff --git a/packages/bower-config/lib/util/proxy.js b/packages/bower-config/lib/util/proxy.js new file mode 100644 index 000000000..fc461c085 --- /dev/null +++ b/packages/bower-config/lib/util/proxy.js @@ -0,0 +1,52 @@ +// EnvProxy uses the proxy vaiables passed to it in set and sets the +// process.env uppercase proxy variables to them with the ability +// to restore the original values later +var EnvProxy = function() { + this.restoreFrom = {}; +}; + +EnvProxy.prototype.set = function (config) { + this.config = config; + + // Override environment defaults if proxy config options are set + // This will make requests.js follow the proxies in config + if (Object.prototype.hasOwnProperty.call(config, 'no-proxy')) { + this.restoreFrom.NO_PROXY = process.env.NO_PROXY; + this.restoreFrom.no_proxy = process.env.no_proxy; + process.env.NO_PROXY = config['no-proxy']; + delete process.env.no_proxy; + } + + if (Object.prototype.hasOwnProperty.call(config, 'proxy')) { + this.restoreFrom.HTTP_PROXY = process.env.HTTP_PROXY; + this.restoreFrom.http_proxy = process.env.http_proxy; + process.env.HTTP_PROXY = config.proxy; + delete process.env.http_proxy; + } + + if (Object.prototype.hasOwnProperty.call(config, 'https-proxy')) { + this.restoreFrom.HTTPS_PROXY = process.env.HTTPS_PROXY; + this.restoreFrom.https_proxy = process.env.https_proxy; + process.env.HTTPS_PROXY = config['https-proxy']; + delete process.env.https_proxy; + } +}; + +EnvProxy.prototype.restore = function () { + if (Object.prototype.hasOwnProperty.call(this.config, 'no-proxy')) { + process.env.NO_PROXY = this.restoreFrom.NO_PROXY; + process.env.no_proxy = this.restoreFrom.no_proxy; + } + + if (Object.prototype.hasOwnProperty.call(this.config, 'proxy')) { + process.env.HTTP_PROXY = this.restoreFrom.HTTP_PROXY; + process.env.http_proxy = this.restoreFrom.http_proxy; + } + + if (Object.prototype.hasOwnProperty.call(this.config, 'https-proxy')) { + process.env.HTTPS_PROXY = this.restoreFrom.HTTPS_PROXY; + process.env.https_proxy = this.restoreFrom.https_proxy; + } +}; + +module.exports = EnvProxy; diff --git a/packages/bower-config/test/assets/env-variables/.bowerrc b/packages/bower-config/test/assets/env-variables/.bowerrc new file mode 100644 index 000000000..44148200e --- /dev/null +++ b/packages/bower-config/test/assets/env-variables/.bowerrc @@ -0,0 +1,5 @@ +{ + "proxy": "http://HTTP_PROXY", + "https-proxy": "http://HTTPS_PROXY", + "no-proxy": "google.com" +} diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index 08a3066ee..3e504549e 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -15,11 +15,10 @@ describe('NPM Config on package.json', function () { } describe('Setting process.env.npm_package_config', function () { - /*jshint camelcase:false*/ process.env.npm_package_config_bower_directory = 'npm-path'; process.env.npm_package_config_bower_colors = false; - var config = require('../lib/Config').create().load()._config; + var config = require('../lib/Config').read(); it('should return "npm-path" for "bower_directory"', function () { assert.equal('npm-path', config.directory); @@ -61,6 +60,49 @@ describe('NPM Config on package.json', function () { }); }); }); + + describe('setting ENV variables', function () { + beforeEach(function () { + delete process.env.no_proxy; + delete process.env.http_proxy; + delete process.env.https_proxy; + delete process.env.NO_PROXY; + delete process.env.HTTP_PROXY; + delete process.env.HTTPS_PROXY; + }); + + it('sets env variables', function () { + require('../lib/Config').read('test/assets/env-variables'); + + assert.equal(process.env.HTTP_PROXY, 'http://HTTP_PROXY'); + assert.equal(process.env.HTTPS_PROXY, 'http://HTTPS_PROXY'); + assert.equal(process.env.NO_PROXY, 'google.com'); + + assert.equal(process.env.http_proxy, undefined); + assert.equal(process.env.https_proxy, undefined); + assert.equal(process.env.no_proxy, undefined); + }); + + it('restores env variables', function () { + process.env.HTTP_PROXY = 'a'; + process.env.HTTPS_PROXY = 'b'; + process.env.NO_PROXY = 'c'; + process.env.http_proxy = 'd'; + process.env.https_proxy = 'e'; + process.env.no_proxy = 'f'; + + var config = require('../lib/Config').create('test/assets/env-variables').load(); + config.restore(); + + assert.equal(process.env.HTTP_PROXY, 'a'); + assert.equal(process.env.HTTPS_PROXY, 'b'); + assert.equal(process.env.NO_PROXY, 'c'); + + assert.equal(process.env.http_proxy, 'd'); + assert.equal(process.env.https_proxy, 'e'); + assert.equal(process.env.no_proxy, 'f'); + }); + }); }); require('./util/index'); From b2d4412e59edadb5b7f5a0daea12844f97fe77ec Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 14:14:35 +0200 Subject: [PATCH 0637/1021] Remove unused methods and better document .restore method --- packages/bower-config/README.md | 38 +++++++++-------------------- packages/bower-config/lib/Config.js | 20 --------------- 2 files changed, 11 insertions(+), 47 deletions(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index f3bb1f3e0..dd9045c52 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -18,38 +18,24 @@ $ npm install --save bower-config Loads the bower configuration from the configuration files. +This method overwrites following environment variables: -#### .get(key) - NOT YET IMPLEMENTED +- `HTTP_PROXY` with `proxy` configuration variable +- `HTTPS_PROXY` with `https-proxy` configuration variable +- `NO_PROXY` with `no-proxy` configuration variable -Returns a configuration value by `key`. -Keys with dots are supported to access deep values. +It also clears `http_proxy`, `https_proxy`, and `no_proxy` environment variables. +To restore those variables you can use `restore` method. -#### .set(key, value) - NOT YET IMPLEMENTED - -Sets a configuration value for `key`. -Keys with dots are supported to set deep values. - - -#### .del(key) - NOT YET IMPLEMENTED - -Removes configuration named `key`. -Keys with dots are supported to delete deep keys. - - -#### .save(where, callback) - NOT YET IMPLEMENTED - -Saves changes to `where`. -The `where` argument can be a path to a configuration file or: - -- `local` to save it in the configured current working directory (defaulting to `process.cwd`) -- `user` to save it in the configuration file located in the home directory +### restore(cwd) +Restores environment variables overwritten by `.load` method. #### .toObject() -Returns a deep copy of the underlying configuration object. -The returned configuration is normalised. +Returns a deep copy of the underlying configuration object. +The returned configuration is normalised. The object keys will be camelCase. @@ -63,7 +49,6 @@ var config = require('bower-config').create(); var config2 = require('bower-config').create('./some/path'); ``` - #### #read(cwd) Alias for: @@ -75,8 +60,7 @@ var configObject = (new Config(cwd)).load().toJson(); #### #normalise(config) -Returns a new normalised config object based on `config`. -Object keys will be converted to camelCase. +Returns a new normalised config object based on `config`. Object keys will be converted to camelCase. ## License diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index 00db28d24..a183d57ad 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -23,26 +23,6 @@ Config.prototype.restore = function () { this._proxy.restore(); }; -/* jshint ignore:start */ -Config.prototype.get = function (key) { - // TODO -}; - -Config.prototype.set = function (key, value) { - // TODO - return this; -}; - -Config.prototype.del = function (key, value) { - // TODO - return this; -}; - -Config.prototype.save = function (where, callback) { - // TODO -}; -/* jshint ignore:end */ - function readCertFile(path) { path = path || ''; From 8c0155e8bd4ccfa62ce7e73f5afc079a60d293af Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 14:33:22 +0200 Subject: [PATCH 0638/1021] Normalize config right away in load method --- packages/bower-config/lib/Config.js | 17 +++++++---------- packages/bower-config/lib/util/proxy.js | 12 ++++++------ 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index a183d57ad..77e9481d8 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -15,7 +15,13 @@ function Config(cwd) { Config.prototype.load = function () { this._config = rc('bower', defaults, this._cwd); + + this._config = Config.normalise(this._config); + + loadCAs(this._config.ca); + this._proxy.set(this._config); + return this; }; @@ -59,16 +65,7 @@ function loadCAs(caConfig) { } Config.prototype.toObject = function () { - var config = lang.deepClone(this._config); - - config = Config.normalise(config); - - // Load CA files and replace their paths with their contents. - // Do that here so that we have a normalised config object, - // and so that it is done only once. - loadCAs(config.ca); - - return config; + return lang.deepClone(this._config); }; Config.create = function (cwd) { diff --git a/packages/bower-config/lib/util/proxy.js b/packages/bower-config/lib/util/proxy.js index fc461c085..8cdbbbd67 100644 --- a/packages/bower-config/lib/util/proxy.js +++ b/packages/bower-config/lib/util/proxy.js @@ -10,10 +10,10 @@ EnvProxy.prototype.set = function (config) { // Override environment defaults if proxy config options are set // This will make requests.js follow the proxies in config - if (Object.prototype.hasOwnProperty.call(config, 'no-proxy')) { + if (Object.prototype.hasOwnProperty.call(config, 'noProxy')) { this.restoreFrom.NO_PROXY = process.env.NO_PROXY; this.restoreFrom.no_proxy = process.env.no_proxy; - process.env.NO_PROXY = config['no-proxy']; + process.env.NO_PROXY = config.noProxy; delete process.env.no_proxy; } @@ -24,16 +24,16 @@ EnvProxy.prototype.set = function (config) { delete process.env.http_proxy; } - if (Object.prototype.hasOwnProperty.call(config, 'https-proxy')) { + if (Object.prototype.hasOwnProperty.call(config, 'httpsProxy')) { this.restoreFrom.HTTPS_PROXY = process.env.HTTPS_PROXY; this.restoreFrom.https_proxy = process.env.https_proxy; - process.env.HTTPS_PROXY = config['https-proxy']; + process.env.HTTPS_PROXY = config.httpsProxy; delete process.env.https_proxy; } }; EnvProxy.prototype.restore = function () { - if (Object.prototype.hasOwnProperty.call(this.config, 'no-proxy')) { + if (Object.prototype.hasOwnProperty.call(this.config, 'noProxy')) { process.env.NO_PROXY = this.restoreFrom.NO_PROXY; process.env.no_proxy = this.restoreFrom.no_proxy; } @@ -43,7 +43,7 @@ EnvProxy.prototype.restore = function () { process.env.http_proxy = this.restoreFrom.http_proxy; } - if (Object.prototype.hasOwnProperty.call(this.config, 'https-proxy')) { + if (Object.prototype.hasOwnProperty.call(this.config, 'httpsProxy')) { process.env.HTTPS_PROXY = this.restoreFrom.HTTPS_PROXY; process.env.https_proxy = this.restoreFrom.https_proxy; } From eed8735238d22b0a5cff283175f01ec4abebc668 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 14:41:17 +0200 Subject: [PATCH 0639/1021] Fix formatting in the readme --- packages/bower-config/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index dd9045c52..5b162762d 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -28,7 +28,7 @@ It also clears `http_proxy`, `https_proxy`, and `no_proxy` environment variables To restore those variables you can use `restore` method. -### restore(cwd) +#### restore(cwd) Restores environment variables overwritten by `.load` method. From c4fc6cd0e282ef657868863ede40f7ad4295b484 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 14:41:54 +0200 Subject: [PATCH 0640/1021] Typo in readme --- packages/bower-config/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index 5b162762d..2f7f87564 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -28,7 +28,7 @@ It also clears `http_proxy`, `https_proxy`, and `no_proxy` environment variables To restore those variables you can use `restore` method. -#### restore(cwd) +#### restore() Restores environment variables overwritten by `.load` method. From 6018fc13b247677b8c77a11a0cdcbd3dd12934fa Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 14:42:47 +0200 Subject: [PATCH 0641/1021] Bump version to 1.0.0 --- packages/bower-config/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index fea8a45ef..264b64a90 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "0.6.1", + "version": "1.0.0", "description": "The Bower config reader and writer.", "author": "Twitter", "license": "MIT", @@ -35,6 +35,6 @@ "test": "grunt test" }, "files": [ - "lib" + "lib" ] } From c630f01baa896b3ddb021839918ded548967e021 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 15:02:48 +0200 Subject: [PATCH 0642/1021] Update dependencies --- packages/bower-config/package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 264b64a90..b0c675f56 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -11,10 +11,10 @@ "node": ">=0.8.0" }, "dependencies": { - "graceful-fs": "~2.0.0", - "mout": "~0.9.0", - "optimist": "~0.6.0", - "osenv": "0.0.3" + "graceful-fs": "^4.0.0", + "mout": ">=0.9.0 <1.0.0", + "optimist": "^0.6.1", + "osenv": "^0.1.3" }, "devDependencies": { "expect.js": "^0.3.1", From 4c129d470fbc1b871085a1e9b986c1c883b5fd3d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 15:03:33 +0200 Subject: [PATCH 0643/1021] Bump to 1.0.1 --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index b0c675f56..132ecf637 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "1.0.0", + "version": "1.0.1", "description": "The Bower config reader and writer.", "author": "Twitter", "license": "MIT", From 674e09dc568aabd2f8114eed4168259e3da01283 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 16:34:51 +0200 Subject: [PATCH 0644/1021] Allow for overwriting options --- packages/bower-config/README.md | 8 +++++--- packages/bower-config/lib/Config.js | 8 +++++--- packages/bower-config/test/test.js | 12 +++++++++++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index 2f7f87564..d0e4d0baf 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -14,10 +14,12 @@ $ npm install --save bower-config ## Usage -#### .load() +#### .load(overwrites) Loads the bower configuration from the configuration files. +Configuration is overwritten (before normalisation) with `overwrites` argument. + This method overwrites following environment variables: - `HTTP_PROXY` with `proxy` configuration variable @@ -49,12 +51,12 @@ var config = require('bower-config').create(); var config2 = require('bower-config').create('./some/path'); ``` -#### #read(cwd) +#### #read(cwd, overrides) Alias for: ```js -var configObject = (new Config(cwd)).load().toJson(); +var configObject = (new Config(cwd)).load(overrides).toJson(); ``` diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index 77e9481d8..acee066f8 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -13,9 +13,11 @@ function Config(cwd) { this._config = {}; } -Config.prototype.load = function () { +Config.prototype.load = function (overwrites) { this._config = rc('bower', defaults, this._cwd); + this._config = object.merge(this._config, overwrites || {}); + this._config = Config.normalise(this._config); loadCAs(this._config.ca); @@ -72,9 +74,9 @@ Config.create = function (cwd) { return new Config(cwd); }; -Config.read = function (cwd) { +Config.read = function (cwd, overrides) { var config = new Config(cwd); - return config.load().toObject(); + return config.load(overrides).toObject(); }; Config.normalise = function (rawConfig) { diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index 3e504549e..6cfeb8760 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -72,7 +72,7 @@ describe('NPM Config on package.json', function () { }); it('sets env variables', function () { - require('../lib/Config').read('test/assets/env-variables'); + require('../lib/config').read('test/assets/env-variables'); assert.equal(process.env.HTTP_PROXY, 'http://HTTP_PROXY'); assert.equal(process.env.HTTPS_PROXY, 'http://HTTPS_PROXY'); @@ -102,7 +102,17 @@ describe('NPM Config on package.json', function () { assert.equal(process.env.https_proxy, 'e'); assert.equal(process.env.no_proxy, 'f'); }); + + it('allows for overriding options', function () { + require('../lib/config').read('test/assets/env-variables', { + proxy: 'http://other-proxy.local' + }); + + assert.equal(process.env.HTTP_PROXY, 'http://other-proxy.local'); + assert.equal(process.env.HTTPS_PROXY, 'http://HTTPS_PROXY'); + }); }); + }); require('./util/index'); From 1647994471458a4f687d2a628419f7079db1b14d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 16:35:01 +0200 Subject: [PATCH 0645/1021] Bump to 1.1.0 --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 132ecf637..c35879e53 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "1.0.1", + "version": "1.1.0", "description": "The Bower config reader and writer.", "author": "Twitter", "license": "MIT", From 3ba696937cf8d1c799721ffe96090c7c0c66c649 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 16:41:32 +0200 Subject: [PATCH 0646/1021] Merge extra config after normalisation --- packages/bower-config/README.md | 2 +- packages/bower-config/lib/Config.js | 4 ++-- packages/bower-config/test/test.js | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index d0e4d0baf..371e3d1c5 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -18,7 +18,7 @@ $ npm install --save bower-config Loads the bower configuration from the configuration files. -Configuration is overwritten (before normalisation) with `overwrites` argument. +Configuration is overwritten (after camelcase normalisation) with `overwrites` argument. This method overwrites following environment variables: diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index acee066f8..2fc77dd5a 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -16,10 +16,10 @@ function Config(cwd) { Config.prototype.load = function (overwrites) { this._config = rc('bower', defaults, this._cwd); - this._config = object.merge(this._config, overwrites || {}); - this._config = Config.normalise(this._config); + this._config = object.merge(this._config, overwrites || {}); + loadCAs(this._config.ca); this._proxy.set(this._config); diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index 6cfeb8760..29f79abc8 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -105,11 +105,11 @@ describe('NPM Config on package.json', function () { it('allows for overriding options', function () { require('../lib/config').read('test/assets/env-variables', { - proxy: 'http://other-proxy.local' + httpsProxy: 'http://other-proxy.local' }); - assert.equal(process.env.HTTP_PROXY, 'http://other-proxy.local'); - assert.equal(process.env.HTTPS_PROXY, 'http://HTTPS_PROXY'); + assert.equal(process.env.HTTP_PROXY, 'http://HTTP_PROXY'); + assert.equal(process.env.HTTPS_PROXY, 'http://other-proxy.local'); }); }); From 4c7f37e0f8288cf9b39f96ebb55edc6f49fc7d66 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 16:41:44 +0200 Subject: [PATCH 0647/1021] Bump to 1.1.1 --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index c35879e53..b20c01fc8 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "1.1.0", + "version": "1.1.1", "description": "The Bower config reader and writer.", "author": "Twitter", "license": "MIT", From acbe60cdf1c6e15b4e2dc20eb26002d232020a2f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 17:08:42 +0200 Subject: [PATCH 0648/1021] Perform only camelcase normalization before merging configs --- packages/bower-config/lib/Config.js | 27 ++++++++++++++------------- packages/bower-config/test/test.js | 1 + 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index 2fc77dd5a..71b226ca2 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -16,11 +16,13 @@ function Config(cwd) { Config.prototype.load = function (overwrites) { this._config = rc('bower', defaults, this._cwd); - this._config = Config.normalise(this._config); - - this._config = object.merge(this._config, overwrites || {}); + this._config = object.merge( + expand(defaults || {}), + expand(this._config || {}), + expand(overwrites || {}) + ); - loadCAs(this._config.ca); + this._config = Config.normalise(this._config); this._proxy.set(this._config); @@ -44,10 +46,10 @@ function readCertFile(path) { certificates = path; } - return certificates - .split(sep) - .filter(function(s) { return !s.match(/^\s*$/); }) - .map(function(s) { return s + sep; }); + return certificates. + split(sep). + filter(function(s) { return !s.match(/^\s*$/); }). + map(function(s) { return s + sep; }); } function loadCAs(caConfig) { @@ -79,11 +81,8 @@ Config.read = function (cwd, overrides) { return config.load(overrides).toObject(); }; -Config.normalise = function (rawConfig) { - var config = {}; - - // Mix in defaults and raw config - object.deepMixIn(config, expand(defaults), expand(rawConfig)); +Config.normalise = function (config) { + config = expand(config); // Some backwards compatible things.. config.shorthandResolver = config.shorthandResolver @@ -98,6 +97,8 @@ Config.normalise = function (rawConfig) { config.registry.publish = config.registry.publish.replace(/\/+$/, ''); config.tmp = path.resolve(config.tmp); + loadCAs(config.ca); + return config; }; diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index 29f79abc8..e81a8537d 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -40,6 +40,7 @@ describe('NPM Config on package.json', function () { assert(Array.isArray(config.ca.search), 'ca property search should be an array'); + config.ca.search.forEach(function(c, i) { assertCAContents(c, 'config.ca.search[' + i + ']'); }); From f53100d8d3e6a654da60d8481b637606a757277d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 17:08:55 +0200 Subject: [PATCH 0649/1021] Bump version to 1.1.2 --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index b20c01fc8..9aeeff68d 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "1.1.1", + "version": "1.1.2", "description": "The Bower config reader and writer.", "author": "Twitter", "license": "MIT", From bf23d81c9ee005c950f602237886e0730e2a844c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 18:10:59 +0200 Subject: [PATCH 0650/1021] Update bower-config and fix tests for ignoreDependenies --- lib/commands/index.js | 3 + lib/config.js | 25 +- lib/core/Project.js | 7 +- lib/index.js | 2 +- package.json | 4 +- test/commands/install.js | 540 +++++++++++++++++++++------------------ test/commands/update.js | 82 ++++-- 7 files changed, 367 insertions(+), 296 deletions(-) diff --git a/lib/commands/index.js b/lib/commands/index.js index 5779d4b94..9511c9203 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -1,5 +1,6 @@ var Q = require('q'); var Logger = require('bower-logger'); +var config = require('../config'); /** * Require commands only when called. @@ -38,10 +39,12 @@ function commandFactory(id) { Q.try(func, logger) .done(function () { + config.restore(); var args = [].slice.call(arguments); args.unshift('end'); logger.emit.apply(logger, args); }, function (error) { + config.restore(); logger.emit('error', error); }); diff --git a/lib/config.js b/lib/config.js index b8d780edb..af0a27849 100644 --- a/lib/config.js +++ b/lib/config.js @@ -3,22 +3,19 @@ var object = require('mout').object; var bowerConfig = require('bower-config'); var Configstore = require('configstore'); -var cachedConfigs = {}; +var current; function defaultConfig(config) { config = config || {}; - var cachedConfig = readCachedConfig(config.cwd || process.cwd()); - - return object.merge(cachedConfig, config); + return readCachedConfig(config.cwd || process.cwd(), config); } -function readCachedConfig(cwd) { - if (cachedConfigs[cwd]) { - return cachedConfigs[cwd]; - } +function readCachedConfig(cwd, overwrites) { + current = bowerConfig.create(cwd).load(overwrites); + + var config = current.toObject(); - var config = cachedConfigs[cwd] = bowerConfig.read(cwd); var configstore = new Configstore('bower-github').all; object.mixIn(config, configstore); @@ -54,9 +51,17 @@ function readCachedConfig(cwd) { return config; } +function restoreConfig () { + if (current) { + current.restore(); + } +} + function resetCache () { - cachedConfigs = {}; + restoreConfig(); + current = undefined; } module.exports = defaultConfig; +module.exports.restore = restoreConfig; module.exports.reset = resetCache; diff --git a/lib/core/Project.js b/lib/core/Project.js index 895d9a452..ff5c17267 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -8,7 +8,6 @@ var endpointParser = require('bower-endpoint-parser'); var Logger = require('bower-logger'); var md5 = require('md5-hex'); var Manager = require('./Manager'); -var defaultConfig = require('../config'); var semver = require('../util/semver'); var createError = require('../util/createError'); var readJson = require('../util/readJson'); @@ -16,11 +15,7 @@ var validLink = require('../util/validLink'); var scripts = require('./scripts'); function Project(config, logger) { - // This is the only architecture component that ensures defaults - // on config and logger - // The reason behind it is that users can likely use this component - // directly if commands do not fulfil their needs - this._config = defaultConfig(config); + this._config = config; this._logger = logger || new Logger(); this._manager = new Manager(this._config, this._logger); diff --git a/lib/index.js b/lib/index.js index 1efed6af1..f9ad14905 100644 --- a/lib/index.js +++ b/lib/index.js @@ -37,7 +37,7 @@ function clearRuntimeCache() { module.exports = { version: pkg.version, commands: commands, - config: require('./config')(), + config: require('bower-config'), abbreviations: abbreviations, reset: clearRuntimeCache }; diff --git a/package.json b/package.json index 4f0c7b0e7..606b56e54 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "dependencies": { "abbrev": "^1.0.5", "archy": "1.0.0", - "bower-config": "^0.6.1", + "bower-config": "^1.1.2", "bower-endpoint-parser": "^0.2.2", "bower-json": "^0.4.0", "bower-logger": "^0.2.2", @@ -70,7 +70,7 @@ "load-grunt-tasks": "^2.0.0", "mocha": "^2.1.0", "multiline": "^1.0.2", - "nock": "^0.56.0", + "nock": "^2.13.0", "node-uuid": "^1.4.2", "proxyquire": "^1.3.0", "spawn-sync": "^1.0.5" diff --git a/test/commands/install.js b/test/commands/install.js index 34a7ab671..4966a6a6d 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -1,295 +1,327 @@ var expect = require('expect.js'); var helpers = require('../helpers'); +var nock = require('nock'); describe('bower install', function () { - var tempDir = new helpers.TempDir(); + var tempDir = new helpers.TempDir(); + + var install = helpers.command('install', { cwd: tempDir.path }); + + it('correctly reads arguments', function() { + expect(install.readOptions(['jquery', 'angular', '-F', '-p', '-S', '-D', '-E'])) + .to.eql([['jquery', 'angular'], { + forceLatest: true, + production: true, + save: true, + saveDev: true, + saveExact: true + }]); + }); + + it('correctly reads long arguments', function() { + expect(install.readOptions([ + 'jquery', 'angular', + '--force-latest', '--production', '--save', '--save-dev', '--save-exact' + ])).to.eql([['jquery', 'angular'], { + forceLatest: true, + production: true, + save: true, + saveDev: true, + saveExact: true + }]); + }); + + var package = new helpers.TempDir({ + 'bower.json': { + name: 'package' + } + }).prepare(); + + var gitPackage = new helpers.TempDir(); + + it('writes to bower.json if --save flag is used', function () { + package.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); - var install = helpers.command('install', { cwd: tempDir.path }); + return helpers.run(install, [[package.path], { save: true }]).then(function() { + expect(tempDir.read('bower.json')).to.contain('dependencies'); + }); + }); + + it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function () { + package.prepare({ + 'bower.json': { + name: 'package', + version: '1.2.3' + } + }); - it('correctly reads arguments', function() { - expect(install.readOptions(['jquery', 'angular', '-F', '-p', '-S', '-D', '-E'])) - .to.eql([['jquery', 'angular'], { - forceLatest: true, - production: true, - save: true, - saveDev: true, - saveExact: true - }]); + tempDir.prepare({ + 'bower.json': { + name: 'test' + } }); - it('correctly reads long arguments', function() { - expect(install.readOptions([ - 'jquery', 'angular', - '--force-latest', '--production', '--save', '--save-dev', '--save-exact' - ])).to.eql([['jquery', 'angular'], { - forceLatest: true, - production: true, - save: true, - saveDev: true, - saveExact: true - }]); + return helpers.run(install, [ + [package.path], + { saveExact: true, save: true } + ]).then(function() { + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(package.path + '#1.2.3'); + }); + }); + + it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function () { + package.prepare({ + 'bower.json': { + name: 'package', + version: '0.1.0' + } }); - var package = new helpers.TempDir({ - 'bower.json': { - name: 'package' + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); + + return helpers.run(install, [ + [package.path], + { saveExact: true, saveDev: true } + ]).then(function() { + expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(package.path + '#0.1.0'); + }); + }); + + it('reads .bowerrc from cwd', function () { + package.prepare({ foo: 'bar' }); + + tempDir.prepare({ + '.bowerrc': { directory: 'assets' }, + 'bower.json': { + name: 'test', + dependencies: { + package: package.path } - }).prepare(); + } + }); + + return helpers.run(install).then(function() { + expect(tempDir.read('assets/package/foo')).to.be('bar'); + }); + }); - var gitPackage = new helpers.TempDir(); + it('runs preinstall hook', function () { + package.prepare(); - it('writes to bower.json if --save flag is used', function () { - package.prepare(); + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: package.path + } + }, + '.bowerrc': { + scripts: { + preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' + } + } + }); - tempDir.prepare({ - 'bower.json': { - name: 'test' - } - }); + return helpers.run(install).then(function() { + expect(tempDir.read('preinstall.txt')).to.be('package'); + }); + }); + + it('runs preinstall hook', function () { + package.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: package.path + } + }, + '.bowerrc': { + scripts: { + postinstall: 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' + } + } + }); - return helpers.run(install, [[package.path], { save: true }]).then(function() { - expect(tempDir.read('bower.json')).to.contain('dependencies'); - }); + return helpers.run(install).then(function() { + expect(tempDir.read('postinstall.txt')).to.be('package'); + }); + }); + + // To be discussed, but that's the implementation now + it('does not run hooks if nothing is installed', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test' + }, + '.bowerrc': { + scripts: { + postinstall: 'node -e \'require("fs").writeFileSync("hooks.txt", "%")\'', + preinstall: 'node -e \'require("fs").writeFileSync("hooks.txt", "%")\'' + } + } }); - it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function () { - package.prepare({ - 'bower.json': { - name: 'package', - version: '1.2.3' - } - }); - - tempDir.prepare({ - 'bower.json': { - name: 'test' - } - }); - - return helpers.run(install, [ - [package.path], - { saveExact: true, save: true } - ]).then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(package.path + '#1.2.3'); - }); + return helpers.run(install).then(function() { + expect(tempDir.exists('hooks.txt')).to.be(false); + }); + }); + + it('runs postinstall after bower.json is written', function () { + package.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test' + }, + '.bowerrc': { + scripts: { + postinstall: 'node -e \'var fs = require("fs"); fs.writeFileSync("hook.txt", fs.readFileSync("bower.json"));\'' + } + } }); - it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function () { - package.prepare({ - 'bower.json': { - name: 'package', - version: '0.1.0' - } - }); - - tempDir.prepare({ - 'bower.json': { - name: 'test' - } - }); - - return helpers.run(install, [ - [package.path], - { saveExact: true, saveDev: true } - ]).then(function() { - expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(package.path + '#0.1.0'); - }); + return helpers.run(install, [[package.path], { save: true }]).then(function() { + expect(tempDir.read('hook.txt')).to.contain('dependencies'); }); + }); + + it('display the output of hook scripts', function (next) { + package.prepare(); - it('reads .bowerrc from cwd', function () { - package.prepare({ foo: 'bar' }); - - tempDir.prepare({ - '.bowerrc': { directory: 'assets' }, - 'bower.json': { - name: 'test', - dependencies: { - package: package.path - } - } - }); - - return helpers.run(install).then(function() { - expect(tempDir.read('assets/package/foo')).to.be('bar'); - }); + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: package.path + } + }, + '.bowerrc': { + scripts: { + postinstall: 'node -e \'process.stdout.write("foobar")\'' + } + } }); - it('runs preinstall hook', function () { - package.prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package: package.path - } - }, - '.bowerrc': { - scripts: { - preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' - } - } - }); - - return helpers.run(install).then(function() { - expect(tempDir.read('preinstall.txt')).to.be('package'); - }); + var lastAction = null; + + helpers.run(install).logger.intercept(function (log) { + if (log.level === 'action') { + lastAction = log; + } + }).on('end', function () { + expect(lastAction.message).to.be('foobar'); + next(); }); + }); - it('runs preinstall hook', function () { - package.prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package: package.path - } - }, - '.bowerrc': { - scripts: { - postinstall: 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' - } - } - }); - - return helpers.run(install).then(function() { - expect(tempDir.read('postinstall.txt')).to.be('package'); - }); + it('works for git repositories', function () { + gitPackage.prepareGit({ + '1.0.0': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '1.0.0' + }, + '1.0.1': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '1.0.1' + } }); - // To be discussed, but that's the implementation now - it('does not run hooks if nothing is installed', function () { - tempDir.prepare({ - 'bower.json': { - name: 'test' - }, - '.bowerrc': { - scripts: { - postinstall: 'node -e \'require("fs").writeFileSync("hooks.txt", "%")\'', - preinstall: 'node -e \'require("fs").writeFileSync("hooks.txt", "%")\'' - } - } - }); - - return helpers.run(install).then(function() { - expect(tempDir.exists('hooks.txt')).to.be(false); - }); + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.0' + } + } }); - it('runs postinstall after bower.json is written', function () { - package.prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test' - }, - '.bowerrc': { - scripts: { - postinstall: 'node -e \'var fs = require("fs"); fs.writeFileSync("hook.txt", fs.readFileSync("bower.json"));\'' - } - } - }); - - return helpers.run(install, [[package.path], { save: true }]).then(function() { - expect(tempDir.read('hook.txt')).to.contain('dependencies'); - }); + return helpers.run(install).then(function() { + expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); }); + }); + + it('does not install ignored dependencies', function() { + package.prepare(); + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + } + }).prepare(); + + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3', + dependencies: { + package2: package2.path, + package: package.path, + } + } + }).prepare(); - it('display the output of hook scripts', function (next) { - package.prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package: package.path - } - }, - '.bowerrc': { - scripts: { - postinstall: 'node -e \'process.stdout.write("foobar")\'' - } - } - }); - - var lastAction = null; - - helpers.run(install).logger.intercept(function (log) { - if (log.level === 'action') { - lastAction = log; - } - }).on('end', function () { - expect(lastAction.message).to.be('foobar'); - next(); - }); + tempDir.prepare({ + 'bower.json': { + name: 'test_tw', + dependencies: { + package3: package3.path + } + }, + '.bowerrc': { + ignoredDependencies: ['package'] + } }); - it('works for git repositories', function () { - gitPackage.prepareGit({ - '1.0.0': { - 'bower.json': { - name: 'package' - }, - 'version.txt': '1.0.0' - }, - '1.0.1': { - 'bower.json': { - name: 'package' - }, - 'version.txt': '1.0.1' - } - }); - - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package: gitPackage.path + '#1.0.0' - } - } - }); - - return helpers.run(install).then(function() { - expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); - }); + return helpers.run(install).then(function() { + expect(tempDir.exists('bower_components/package')).to.be(false); + expect(tempDir.exists('bower_components/package2')).to.be(true); }); - it('does not install ignored dependencies', function() { - package.prepare(); - var package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - } - }).prepare(); + }); - var package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3', - dependencies: { - package2: package2.path, - package: package.path, - } + it('recognizes proxy option in config', function () { + this.timeout(10000); + + tempDir.prepare({ + 'bower.json': { + name: 'test_tw', + dependencies: { + pure: 'http://github.com/yahoo/pure/archive/v0.6.0.tar.gz' } - }).prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test_tw', - dependencies: { - package3: package3.path - } - }, - '.bowerrc': { - ignoredDependencies: ['package'] - } - }); - - return helpers.run(install).then(function() { - expect(tempDir.exists('bower_components/package')).to.be(false); - expect(tempDir.exists('bower_components/package2')).to.be(true); - }); + } + }); + + var install = helpers.command('install', { + cwd: tempDir.path + }); + nock.disableNetConnect(); + nock('http://dummy.local') + .get('http://github.com/yahoo/pure/archive/v0.6.0.tar.gz') + .reply(500); + + return helpers.run(install, [ + undefined, + undefined, + { proxy: 'http://dummy.local/' } + ]).fail(function(error) { + expect(error.message).to.equal('Status code of 500'); + nock.enableNetConnect(); }); + }); }); diff --git a/test/commands/update.js b/test/commands/update.js index 847387e8b..8e3b4a296 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -91,11 +91,17 @@ describe('bower update', function () { }); it('does not install ignored dependencies', function() { + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3' + } + }).prepare(); + var package2 = new helpers.TempDir({ 'bower.json': { name: 'package2', dependencies: { - package: package.path + package3: package3.path } } }).prepare(); @@ -108,13 +114,13 @@ describe('bower update', function () { } }, '.bowerrc': { - ignoredDependencies: ['package'] + ignoredDependencies: ['package3'] } }); return update().then(function() { expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); - expect(tempDir.exists('bower_components/package')).to.equal(false); + expect(tempDir.exists('bower_components/package3')).to.equal(false); }); }); @@ -219,35 +225,65 @@ describe('bower update', function () { }); it('does not install ignored dependencies when updating a package', function () { + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3' + } + }).prepare(); + + var package2 = new helpers.TempDir().prepareGit({ + '1.0.0': { + 'bower.json': { + name: 'package2', + version: '1.0.0', + dependencies: { + package3: package3.path + } + } + }, + '1.0.1': { + 'bower.json': { + name: 'package2', + version: '1.0.1', + dependencies: { + package3: package3.path + } + } + } + }); + tempDir.prepare({ 'bower.json': { name: 'test', dependencies: { - package: gitPackage.path + '#1.0.0' + package2: package2.path + '#1.0.0' } }, '.bowerrc': { - ignoredDependencies: ['subPackage'] + ignoredDependencies: ['package3'] } }); return install().then(function() { - expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); - expect(tempDir.exists('bower_components/subPackage')).to.equal(false); + expect(tempDir.readJson('bower_components/package2/bower.json').version).to.equal('1.0.0'); + expect(tempDir.exists('bower_components/package3')).to.equal(false); - tempDir.prepare({ + tempDir.prepare({ 'bower.json': { name: 'test', dependencies: { - package: gitPackage.path + '#1.0.1' + package2: package2.path + '#1.0.1' } + }, + '.bowerrc': { + ignoredDependencies: ['package3'] } }); return update().then(function() { - expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.1'); - expect(tempDir.exists('bower_components/subPackage')).to.equal(false); + expect(tempDir.readJson('bower_components/package2/bower.json').version).to.equal('1.0.1'); + expect(tempDir.exists('bower_components/package3')).to.equal(false); }); }); }); @@ -259,21 +295,21 @@ describe('bower update', function () { dependencies: { package: gitPackage.path + '#1.0.0' } - }, - '.bowerrc': { - scripts: { - preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' - } } }); return install().then(function() { - tempDir.prepare({ + tempDir.prepare({ 'bower.json': { name: 'test', dependencies: { package: gitPackage.path + '#1.0.1' } + }, + '.bowerrc': { + scripts: { + preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' + } } }); @@ -291,12 +327,6 @@ describe('bower update', function () { dependencies: { package: gitPackage.path + '#1.0.0' } - }, - '.bowerrc': { - scripts: { - preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'', - postinstall: 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' - } } }); @@ -307,6 +337,12 @@ describe('bower update', function () { dependencies: { package: gitPackage.path + '#1.0.1' } + }, + '.bowerrc': { + scripts: { + preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'', + postinstall: 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' + } } }); From 9cc3dd4c9218656be6585206702f0e94d184c555 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 18:17:40 +0200 Subject: [PATCH 0651/1021] Pass certificate for GitHubResolver and UrlResolver, closes #1869 --- lib/core/resolvers/GitHubResolver.js | 1 + lib/core/resolvers/UrlResolver.js | 2 ++ 2 files changed, 3 insertions(+) diff --git a/lib/core/resolvers/GitHubResolver.js b/lib/core/resolvers/GitHubResolver.js index 1978016b1..e7fac32d0 100644 --- a/lib/core/resolvers/GitHubResolver.js +++ b/lib/core/resolvers/GitHubResolver.js @@ -73,6 +73,7 @@ GitHubResolver.prototype._checkout = function () { // Download tarball return download(tarballUrl, file, { proxy: this._config.httpsProxy, + ca: this._config.ca.default, strictSSL: this._config.strictSsl, timeout: this._config.timeout, headers: reqHeaders diff --git a/lib/core/resolvers/UrlResolver.js b/lib/core/resolvers/UrlResolver.js index cdd03c134..48630ebca 100644 --- a/lib/core/resolvers/UrlResolver.js +++ b/lib/core/resolvers/UrlResolver.js @@ -56,6 +56,7 @@ UrlResolver.prototype._hasNew = function (pkgMeta) { // Make an HEAD request to the source return Q.nfcall(request.head, this._source, { proxy: this._remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, + ca: this._config.ca.default, strictSSL: this._config.strictSsl, timeout: this._config.timeout, headers: reqHeaders @@ -122,6 +123,7 @@ UrlResolver.prototype._download = function () { // Download the file return download(this._source, file, { proxy: this._remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, + ca: this._config.ca.default, strictSSL: this._config.strictSsl, timeout: this._config.timeout, headers: reqHeaders From 498fe84b99e955308d37006c7710d68ca607f058 Mon Sep 17 00:00:00 2001 From: JD Isaacks Date: Fri, 29 May 2015 22:26:46 -0400 Subject: [PATCH 0652/1021] Use values from package.json as defaults if exists --- lib/core/Project.js | 27 +++++++++++++++-- test/commands/init.js | 68 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 3 deletions(-) diff --git a/lib/core/Project.js b/lib/core/Project.js index ff5c17267..05f811e73 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -556,9 +556,30 @@ Project.prototype._readJson = function () { return Q.resolve(this._json); } - // Read local json - return this._json = readJson(this._config.cwd, { - assume: { name: path.basename(this._config.cwd) || 'root' } + return Q.fcall(function(){ + // This will throw if package.json does not exist + return fs.readFileSync(path.join(that._config.cwd, 'package.json')); + }) + .then(function(buffer){ + // If package.json exists, use it's values as defaults + var defaults = {}, npm = JSON.parse(buffer.toString()); + + defaults.name = npm.name || path.basename(that._config.cwd) || 'root'; + defaults.version = npm.version; + defaults.main = npm.main; + defaults.authors = npm.contributors || npm.author; + defaults.license = npm.license; + defaults.keywords = npm.keywords; + defaults.description = npm.description; + + return defaults; + }) + .catch(function(err){ + // Most likely no package.json so just set default name + return { name: path.basename(that._config.cwd) || 'root' }; + }) + .then(function(defaults){ + return that._json = readJson(that._config.cwd, { assume: defaults }); }) .spread(function (json, deprecated, assumed) { var jsonStr; diff --git a/test/commands/init.js b/test/commands/init.js index 7f5e1049b..67d5a8bc5 100644 --- a/test/commands/init.js +++ b/test/commands/init.js @@ -83,4 +83,72 @@ describe('bower init', function () { ); }); }); + + it('gets defaults from package.json', function () { + package.prepare({ + 'package.json': { + 'name': 'name from npm', + 'version': '0.2.0', + 'description': 'description from npm', + 'main': 'index.js', + 'keywords': [ + 'foo', + 'bar' + ], + 'author': 'JD Isaacks', + 'license': 'ISC' + } + }); + + var logger = init({ + cwd: package.path, + interactive: true + }); + + return helpers.expectEvent(logger, 'prompt') + .spread(function (prompt, answer) { + + // Get defaults from prompt + var defaults = prompt.reduce(function(memo, obj){ + memo[obj.name] = obj['default']; + return memo; + }, {}); + + // Answer with defaults + answer({ + name: defaults.name, + version: defaults.version, + description: defaults.description, + main: defaults.main, + moduleType: defaults.moduleType, + keywords: defaults.keywords, + authors: defaults.authors, + license: defaults.license, + homepage: 'test-homepage', + private: true + }); + + return helpers.expectEvent(logger, 'prompt'); + }) + .spread(function (prompt, answer) { + answer({ prompt: true }); + return helpers.expectEvent(logger, 'end'); + }) + .then(function () { + expect(package.readJson('bower.json')).to.eql({ + 'name': 'name from npm', + 'version': '0.2.0', + 'description': 'description from npm', + 'main': 'index.js', + 'keywords': [ + 'foo', + 'bar' + ], + 'authors': ['JD Isaacks'], + 'license': 'ISC', + 'private': true, + 'homepage': 'test-homepage' + }); + }); + }); }); From 2c243ea5b714c2618d1931c105c1ed92cda0e107 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 19:42:16 +0200 Subject: [PATCH 0653/1021] tests: Fix camel casing --- packages/bower-config/test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index e81a8537d..5e3b25b58 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -105,7 +105,7 @@ describe('NPM Config on package.json', function () { }); it('allows for overriding options', function () { - require('../lib/config').read('test/assets/env-variables', { + require('../lib/Config').read('test/assets/env-variables', { httpsProxy: 'http://other-proxy.local' }); From bebb4fb33b0e95085f4d2c9f85e3fdf18f5dba04 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 27 Sep 2015 19:46:22 +0200 Subject: [PATCH 0654/1021] Fix one more upper case spelling --- packages/bower-config/test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index 5e3b25b58..3768670a5 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -73,7 +73,7 @@ describe('NPM Config on package.json', function () { }); it('sets env variables', function () { - require('../lib/config').read('test/assets/env-variables'); + require('../lib/Config').read('test/assets/env-variables'); assert.equal(process.env.HTTP_PROXY, 'http://HTTP_PROXY'); assert.equal(process.env.HTTPS_PROXY, 'http://HTTPS_PROXY'); From ffde6bd22866bddffba9bc4cdd9b28d500241aa1 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 28 Sep 2015 17:07:29 +0200 Subject: [PATCH 0655/1021] Remove version generation from "bower init" command, closes #1343 --- lib/commands/init.js | 21 --------------------- lib/core/Project.js | 3 +-- test/commands/init.js | 5 ----- 3 files changed, 1 insertion(+), 28 deletions(-) diff --git a/lib/commands/init.js b/lib/commands/init.js index ee09b29d3..0373ba873 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -6,7 +6,6 @@ var endpointParser = require('bower-endpoint-parser'); var Project = require('../core/Project'); var defaultConfig = require('../config'); var GitHubResolver = require('../core/resolvers/GitHubResolver'); -var GitFsResolver = require('../core/resolvers/GitFsResolver'); var cmd = require('../util/cmd'); var createError = require('../util/createError'); @@ -102,19 +101,6 @@ function setDefaults(config, json) { json.name = path.basename(config.cwd); } - // Version - if (!json.version) { - // Assume latest semver tag if it's a git repo - promise = promise.then(function () { - return GitFsResolver.versions(config.cwd) - .then(function (versions) { - json.version = versions[0] || '0.0.0'; - }, function () { - json.version = '0.0.0'; - }); - }); - } - // Main if (!json.main) { // Remove '.js' from the end of the package name if it is there @@ -188,12 +174,6 @@ function promptUser(logger, json) { 'default': json.name, 'type': 'input' }, - { - 'name': 'version', - 'message': 'version', - 'default': json.version, - 'type': 'input' - }, { 'name': 'description', 'message': 'description', @@ -259,7 +239,6 @@ function promptUser(logger, json) { return Q.nfcall(logger.prompt.bind(logger), questions) .then(function (answers) { json.name = answers.name; - json.version = answers.version; json.description = answers.description; json.main = answers.main; json.moduleType = answers.moduleType; diff --git a/lib/core/Project.js b/lib/core/Project.js index 05f811e73..516e7b2d7 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -565,12 +565,11 @@ Project.prototype._readJson = function () { var defaults = {}, npm = JSON.parse(buffer.toString()); defaults.name = npm.name || path.basename(that._config.cwd) || 'root'; - defaults.version = npm.version; + defaults.description = npm.description; defaults.main = npm.main; defaults.authors = npm.contributors || npm.author; defaults.license = npm.license; defaults.keywords = npm.keywords; - defaults.description = npm.description; return defaults; }) diff --git a/test/commands/init.js b/test/commands/init.js index 67d5a8bc5..d31ae68fc 100644 --- a/test/commands/init.js +++ b/test/commands/init.js @@ -24,7 +24,6 @@ describe('bower init', function () { .spread(function (prompt, answer) { answer({ name: 'test-name', - version: 'test-version', description: 'test-description', moduleType: 'test-moduleType', keywords: 'test-keyword', @@ -43,7 +42,6 @@ describe('bower init', function () { .then(function () { expect(package.readJson('bower.json')).to.eql({ name: 'test-name', - version: 'test-version', homepage: 'test-homepage', authors: [ 'test-author' ], description: 'test-description', @@ -88,7 +86,6 @@ describe('bower init', function () { package.prepare({ 'package.json': { 'name': 'name from npm', - 'version': '0.2.0', 'description': 'description from npm', 'main': 'index.js', 'keywords': [ @@ -117,7 +114,6 @@ describe('bower init', function () { // Answer with defaults answer({ name: defaults.name, - version: defaults.version, description: defaults.description, main: defaults.main, moduleType: defaults.moduleType, @@ -137,7 +133,6 @@ describe('bower init', function () { .then(function () { expect(package.readJson('bower.json')).to.eql({ 'name': 'name from npm', - 'version': '0.2.0', 'description': 'description from npm', 'main': 'index.js', 'keywords': [ From 8ff0e0e2d1f9eb5dd4027ea43a9a99eb083e0d21 Mon Sep 17 00:00:00 2001 From: "de Winter, Anton" Date: Tue, 23 Jun 2015 15:31:34 -0400 Subject: [PATCH 0656/1021] Components that are not installed by bower should be left alone Rework of commit by @wibblymat for PR #1363 Make compatible with existing tests Uses fs.readdirSync() (once!) instead of async method. Added new test --- lib/core/Manager.js | 10 ++++++++++ test/commands/install.js | 24 +++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 65e114930..db94c9063 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -155,6 +155,7 @@ Manager.prototype.postinstall = function (json) { Manager.prototype.install = function (json) { var componentsDir; + var componentsDirContents; var that = this; // If already resolving, error out @@ -171,16 +172,25 @@ Manager.prototype.install = function (json) { return Q.nfcall(mkdirp, componentsDir) .then(function () { var promises = []; + componentsDirContents = fs.readdirSync(componentsDir); mout.object.forOwn(that._dissected, function (decEndpoint, name) { var promise; var dst; var release = decEndpoint.pkgMeta._release; + var exists = mout.array.contains(componentsDirContents, name); that._logger.action('install', name + (release ? '#' + release : ''), that.toData(decEndpoint)); dst = path.join(componentsDir, name); + if (exists && !that._installed[name] && !that._config.force) { + // There is a folder in the components directory that has + // this name, but it was not installed by bower. + that._logger.warn('skipped', name + ' was not installed because there is already a non-bower directory with that name in the components directory (' + path.relative(that._config.cwd, dst) + '). You can force installation with --force.'); + return; + } + // Remove existent and copy canonical dir promise = Q.nfcall(rimraf, dst) .then(copy.copyDir.bind(copy, decEndpoint.canonicalDir, dst)) diff --git a/test/commands/install.js b/test/commands/install.js index 4966a6a6d..6e78095a7 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -1,6 +1,7 @@ var expect = require('expect.js'); var helpers = require('../helpers'); var nock = require('nock'); +var fs = require('fs'); describe('bower install', function () { @@ -214,7 +215,6 @@ describe('bower install', function () { } } }); - var lastAction = null; helpers.run(install).logger.intercept(function (log) { @@ -227,6 +227,28 @@ describe('bower install', function () { }); }); + it('skips components not installed by bower', function () { + package.prepare({ + '.git': {} //Make a dummy file instead of using slower gitPrepare() + }); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: package.path + } + } + }); + + return helpers.run(install).then(function() { + var packageFiles = fs.readdirSync(package.path); + //presence of .git file implies folder was not overwritten + expect(packageFiles).to.contain('.git'); + }); + + }); + it('works for git repositories', function () { gitPackage.prepareGit({ '1.0.0': { From da961a9c4254fb9b01b631a3e8d0488ac869af48 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 28 Sep 2015 17:34:06 +0200 Subject: [PATCH 0657/1021] Pass proxy configuration to request.js via env variables --- lib/core/resolvers/GitHubResolver.js | 1 - lib/core/resolvers/UrlResolver.js | 2 -- 2 files changed, 3 deletions(-) diff --git a/lib/core/resolvers/GitHubResolver.js b/lib/core/resolvers/GitHubResolver.js index e7fac32d0..1335de19b 100644 --- a/lib/core/resolvers/GitHubResolver.js +++ b/lib/core/resolvers/GitHubResolver.js @@ -72,7 +72,6 @@ GitHubResolver.prototype._checkout = function () { // Download tarball return download(tarballUrl, file, { - proxy: this._config.httpsProxy, ca: this._config.ca.default, strictSSL: this._config.strictSsl, timeout: this._config.timeout, diff --git a/lib/core/resolvers/UrlResolver.js b/lib/core/resolvers/UrlResolver.js index 48630ebca..346bc81cc 100644 --- a/lib/core/resolvers/UrlResolver.js +++ b/lib/core/resolvers/UrlResolver.js @@ -55,7 +55,6 @@ UrlResolver.prototype._hasNew = function (pkgMeta) { // Make an HEAD request to the source return Q.nfcall(request.head, this._source, { - proxy: this._remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, ca: this._config.ca.default, strictSSL: this._config.strictSsl, timeout: this._config.timeout, @@ -122,7 +121,6 @@ UrlResolver.prototype._download = function () { // Download the file return download(this._source, file, { - proxy: this._remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, ca: this._config.ca.default, strictSSL: this._config.strictSsl, timeout: this._config.timeout, From 5365c7b428f4d463405c2e873b6f463ef54753b4 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 28 Sep 2015 17:46:58 +0200 Subject: [PATCH 0658/1021] Disable client-side check for registering git:// endpoints --- lib/commands/register.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/lib/commands/register.js b/lib/commands/register.js index 5ce2c5a29..61f83d4c9 100644 --- a/lib/commands/register.js +++ b/lib/commands/register.js @@ -2,7 +2,6 @@ var mout = require('mout'); var Q = require('q'); var chalk = require('chalk'); var PackageRepository = require('../core/PackageRepository'); -var Config = require('bower-config'); var Tracker = require('../util/analytics').Tracker; var createError = require('../util/createError'); var defaultConfig = require('../config'); @@ -31,16 +30,6 @@ function register(logger, name, url, config) { throw createError('Usage: bower register ', 'EINVFORMAT'); } - // The public registry only allows git:// endpoints - // As such, we attempt to convert URLs as necessary - if (config.registry.register === Config.DEFAULT_REGISTRY) { - url = convertUrl(url, logger); - - if (!mout.string.startsWith(url, 'git://')) { - throw createError('The registry only accepts URLs starting with git://', 'EINVFORMAT'); - } - } - tracker.track('register'); // Attempt to resolve the package referenced by the URL to ensure From 123779bbd1ae76eaea96d7c59391d622c463111a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 28 Sep 2015 18:01:46 +0200 Subject: [PATCH 0659/1021] Remove client-side check for register command, closes bower/registry#23 --- lib/commands/register.js | 18 ------------------ test/commands/register.js | 8 -------- 2 files changed, 26 deletions(-) diff --git a/lib/commands/register.js b/lib/commands/register.js index 61f83d4c9..fe2451ac8 100644 --- a/lib/commands/register.js +++ b/lib/commands/register.js @@ -1,11 +1,9 @@ -var mout = require('mout'); var Q = require('q'); var chalk = require('chalk'); var PackageRepository = require('../core/PackageRepository'); var Tracker = require('../util/analytics').Tracker; var createError = require('../util/createError'); var defaultConfig = require('../config'); -var GitHubResolver = require('../core/resolvers/GitHubResolver'); function register(logger, name, url, config) { var repository; @@ -73,22 +71,6 @@ function register(logger, name, url, config) { }); } -function convertUrl(url, logger) { - var pair; - var newUrl; - - if (!mout.string.startsWith(url, 'git://')) { - // Convert GitHub ssh & https to git:// - pair = GitHubResolver.getOrgRepoPair(url); - if (pair) { - newUrl = 'git://github.com/' + pair.org + '/' + pair.repo + '.git'; - logger.warn('convert', 'Converted ' + url + ' to ' + newUrl); - } - } - - return newUrl || url; -} - // ------------------- register.readOptions = function (argv) { diff --git a/test/commands/register.js b/test/commands/register.js index 58c441857..1c7ccac17 100644 --- a/test/commands/register.js +++ b/test/commands/register.js @@ -62,14 +62,6 @@ describe('bower register', function () { }); }); - it('errors if url is not correct', function () { - return helpers.run(register, ['some-name', 'url']) - .fail(function(reason) { - expect(reason.message).to.be('The registry only accepts URLs starting with git://'); - expect(reason.code).to.be('EINVFORMAT'); - }); - }); - it('errors if trying to register private package', function () { package.prepare({ 'bower.json': { private: true } }); From a499cc5103bdb4cbc0f182ac2700918050dc07f6 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 28 Sep 2015 17:23:22 +0200 Subject: [PATCH 0660/1021] Update bower.json dependency --- packages/bower-registry-client/package.json | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 2eab18519..ed70f3b21 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -3,12 +3,7 @@ "version": "0.3.0", "description": "Provides easy interaction with the Bower registry", "author": "Twitter", - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/bower/registry-client/blob/master/LICENSE" - } - ], + "license": "MIT", "repository": "bower/registry-client", "main": "Client", "engines": { @@ -16,7 +11,7 @@ }, "dependencies": { "async": "~0.2.8", - "bower-config": "~0.6.1", + "bower-config": "^1.1.2", "graceful-fs": "~2.0.0", "lru-cache": "~2.3.0", "request": "~2.51.0", From cf5cd619950a62f900aa7dd9a4b7ecb9e340e3b8 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 28 Sep 2015 17:35:38 +0200 Subject: [PATCH 0661/1021] Pass proxy configuration via env variables instead of directly, closes #22 --- packages/bower-registry-client/lib/list.js | 1 - packages/bower-registry-client/lib/lookup.js | 1 - packages/bower-registry-client/lib/register.js | 1 - packages/bower-registry-client/lib/search.js | 1 - packages/bower-registry-client/lib/unregister.js | 1 - 5 files changed, 5 deletions(-) diff --git a/packages/bower-registry-client/lib/list.js b/packages/bower-registry-client/lib/list.js index 18fbc0753..4ad13566f 100644 --- a/packages/bower-registry-client/lib/list.js +++ b/packages/bower-registry-client/lib/list.js @@ -94,7 +94,6 @@ function doRequest(index, callback) { } req = replay(request.get(requestUrl, { - proxy: remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, ca: this._config.ca.search[index], headers: headers, strictSSL: this._config.strictSsl, diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index c6cd6cf02..7164bce5c 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -86,7 +86,6 @@ function doRequest(name, index, callback) { } req = replay(request.get(requestUrl, { - proxy: remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, headers: headers, ca: this._config.ca.search[index], strictSSL: this._config.strictSsl, diff --git a/packages/bower-registry-client/lib/register.js b/packages/bower-registry-client/lib/register.js index dcbdf6f72..b6929ff0c 100644 --- a/packages/bower-registry-client/lib/register.js +++ b/packages/bower-registry-client/lib/register.js @@ -18,7 +18,6 @@ function register(name, url, callback) { request.post({ url: requestUrl, - proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, headers: headers, ca: config.ca.register, strictSSL: config.strictSsl, diff --git a/packages/bower-registry-client/lib/search.js b/packages/bower-registry-client/lib/search.js index 3bbd8e7ae..c994c68f7 100644 --- a/packages/bower-registry-client/lib/search.js +++ b/packages/bower-registry-client/lib/search.js @@ -102,7 +102,6 @@ function doRequest(name, index, callback) { } req = replay(request.get(requestUrl, { - proxy: remote.protocol === 'https:' ? this._config.httpsProxy : this._config.proxy, headers: headers, ca: this._config.ca.search[index], strictSSL: this._config.strictSsl, diff --git a/packages/bower-registry-client/lib/unregister.js b/packages/bower-registry-client/lib/unregister.js index 0955c2b29..d4378c687 100644 --- a/packages/bower-registry-client/lib/unregister.js +++ b/packages/bower-registry-client/lib/unregister.js @@ -18,7 +18,6 @@ function unregister(name, callback) { request.del({ url: requestUrl, - proxy: remote.protocol === 'https:' ? config.httpsProxy : config.proxy, headers: headers, ca: config.ca.register, strictSSL: config.strictSsl, From 059a5f83b70efdbe4d55a7150e8706bd0999c190 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 28 Sep 2015 18:41:29 +0200 Subject: [PATCH 0662/1021] Require using explicitly bower-config --- packages/bower-registry-client/Client.js | 7 +++-- packages/bower-registry-client/README.md | 4 ++- packages/bower-registry-client/package.json | 2 +- packages/bower-registry-client/test/Client.js | 31 ++++++++++--------- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js index 0b1ce9360..2714c3a5f 100644 --- a/packages/bower-registry-client/Client.js +++ b/packages/bower-registry-client/Client.js @@ -1,11 +1,14 @@ var async = require('async'); -var Config = require('bower-config'); var methods = require('./lib'); var Cache = require('./lib/util/Cache'); function RegistryClient(config, logger) { this._logger = logger; - this._config = Config.normalise(config); + this._config = config; + + if (!this._config.registry) { + throw new Error("You need to pass config as read by bower-config module. Registry field is missing."); + } // Cache defaults to storage registry if (!Object.prototype.hasOwnProperty.call(this._config, 'cache')) { diff --git a/packages/bower-registry-client/README.md b/packages/bower-registry-client/README.md index 32661bfea..389d91dc8 100644 --- a/packages/bower-registry-client/README.md +++ b/packages/bower-registry-client/README.md @@ -14,7 +14,9 @@ $ npm install --save bower-registry-client ```js var RegistryClient = require('bower-registry-client'); -var registry = new RegistryClient(options, logger); +var Config = require('bower-config'); +var config = Config.read(process.cwd(), options); +var registry = new RegistryClient(config, logger); ``` The `logger` is optional and is expected to be an instance of the bower [logger](https://github.com/bower/logger). diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index ed70f3b21..545c85ca7 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -11,7 +11,6 @@ }, "dependencies": { "async": "~0.2.8", - "bower-config": "^1.1.2", "graceful-fs": "~2.0.0", "lru-cache": "~2.3.0", "request": "~2.51.0", @@ -20,6 +19,7 @@ "mkdirp": "~0.3.5" }, "devDependencies": { + "bower-config": "^1.1.2", "expect.js": "~0.2.0", "grunt": "~0.4.1", "grunt-cli": "^0.1.13", diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index ed3b31820..91cbdb34b 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -4,16 +4,19 @@ var expect = require('expect.js'); var md5 = require('../lib/util/md5'); var nock = require('nock'); var http = require('http'); +var Config = require('bower-config'); describe('RegistryClient', function () { beforeEach(function () { this.uri = 'https://bower.herokuapp.com'; this.timeoutVal = 5000; - this.registry = new RegistryClient({ + this.registry = new RegistryClient(Config.read(process.cwd(), { strictSsl: false, timeout: this.timeoutVal - }); + })); + this.conf = { + default: this.uri, search: [this.uri], register: this.uri, publish: this.uri @@ -105,10 +108,10 @@ describe('RegistryClient', function () { .get('/packages/search/jquery') .replyWithFile(200, __dirname + '/fixtures/search.json'); - this.client = new RegistryClient({ + this.client = new RegistryClient(Config.read(process.cwd(), { cache: __dirname + '/cache', strictSsl: false - }); + })); this.cacheDir = this.client._config.cache; this.host = 'bower.herokuapp.com'; @@ -224,7 +227,7 @@ describe('RegistryClient', function () { url: 'git://github.com/foo/baz' }); - this.registry = new RegistryClient({ + this.registry = new RegistryClient(Config.read(process.cwd(), { strictSsl: false, force: true, registry: { @@ -233,7 +236,7 @@ describe('RegistryClient', function () { 'http://custom-registry2.com' ] } - }); + })); }); it('should return entry type', function (next) { @@ -275,7 +278,7 @@ describe('RegistryClient', function () { url: 'git://github.com/foo/baz' }); - this.registry = new RegistryClient({ + this.registry = new RegistryClient(Config.read(process.cwd(), { strictSsl: false, force: true, registry: { @@ -285,7 +288,7 @@ describe('RegistryClient', function () { 'http://custom-registry2.com' ] } - }); + })); }); it('should return entry type', function (next) { @@ -518,7 +521,7 @@ describe('RegistryClient', function () { this.pkg = 'jquery'; this.pkgUrl = 'git://github.com/bar/foo.git'; - this.registry = new RegistryClient({ + this.registry = new RegistryClient(Config.read(process.cwd(), { strictSsl: false, force: true, registry: { @@ -527,7 +530,7 @@ describe('RegistryClient', function () { 'http://custom-registry.com' ] } - }); + })); }); it('should return entry name', function (next) { @@ -620,7 +623,7 @@ describe('RegistryClient', function () { } ]); - this.registry = new RegistryClient({ + this.registry = new RegistryClient(Config.read(process.cwd(), { strictSsl: false, force: true, registry: { @@ -629,7 +632,7 @@ describe('RegistryClient', function () { 'http://custom-registry.com' ] } - }); + })); }); it('should return entry name', function (next) { @@ -721,10 +724,10 @@ describe('RegistryClient', function () { self.server.close(); }); this.server.listen('7777', '127.0.0.1'); - this.registry = new RegistryClient({ + this.registry = new RegistryClient(Config.read(process.cwd(), { userAgent: 'test agent', registry: 'http://127.0.0.1:7777' - }); + })); this.registry.search('jquery', function (err, result) { expect(self.ua).to.be('test agent'); next(); From 9b45c76744092a6fd8d15c91dcc2f5986334cbea Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 28 Sep 2015 19:14:30 +0200 Subject: [PATCH 0663/1021] Change ~ ranges to ^ --- packages/bower-registry-client/package.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 545c85ca7..742f50e6d 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -10,13 +10,13 @@ "node": ">=0.10.0" }, "dependencies": { - "async": "~0.2.8", - "graceful-fs": "~2.0.0", - "lru-cache": "~2.3.0", - "request": "~2.51.0", - "request-replay": "~0.2.0", - "rimraf": "~2.2.0", - "mkdirp": "~0.3.5" + "async": "^0.2.8", + "graceful-fs": "^4.0.0", + "lru-cache": "^2.3.0", + "request": "^2.51.0", + "request-replay": "^0.2.0", + "rimraf": "^2.2.0", + "mkdirp": "^0.3.5" }, "devDependencies": { "bower-config": "^1.1.2", From ac88ece259ae33ccfabb20ac5468fcaec27dbd5f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 28 Sep 2015 19:15:26 +0200 Subject: [PATCH 0664/1021] Bump to 1.0.0 --- packages/bower-registry-client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 742f50e6d..e7eb56586 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "0.3.0", + "version": "1.0.0", "description": "Provides easy interaction with the Bower registry", "author": "Twitter", "license": "MIT", From 30a489535edc7186b44452009919161e341fec40 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 28 Sep 2015 19:37:44 +0200 Subject: [PATCH 0665/1021] Prevent defaulting cwd to process.cwd() --- packages/bower-config/README.md | 6 --- packages/bower-config/lib/Config.js | 24 ++++++------ packages/bower-config/lib/util/defaults.js | 1 - packages/bower-config/lib/util/rc.js | 43 ++++++++++++++-------- packages/bower-config/test/test.js | 36 ++++++++++++++++++ packages/bower-config/test/util/rc.js | 10 ++--- 6 files changed, 79 insertions(+), 41 deletions(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index 371e3d1c5..b30c222c0 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -59,12 +59,6 @@ Alias for: var configObject = (new Config(cwd)).load(overrides).toJson(); ``` - -#### #normalise(config) - -Returns a new normalised config object based on `config`. Object keys will be converted to camelCase. - - ## License Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php). diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index 71b226ca2..19a7852df 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -1,28 +1,26 @@ var lang = require('mout/lang'); var object = require('mout/object'); var rc = require('./util/rc'); -var defaults = require('./util/defaults'); var expand = require('./util/expand'); var EnvProxy = require('./util/proxy'); var path = require('path'); var fs = require('fs'); function Config(cwd) { - this._cwd = cwd || process.cwd(); + this._cwd = cwd; this._proxy = new EnvProxy(); this._config = {}; } Config.prototype.load = function (overwrites) { - this._config = rc('bower', defaults, this._cwd); + this._config = rc('bower', this._cwd); this._config = object.merge( - expand(defaults || {}), expand(this._config || {}), expand(overwrites || {}) ); - this._config = Config.normalise(this._config); + this._config = normalise(this._config); this._proxy.set(this._config); @@ -77,17 +75,19 @@ Config.create = function (cwd) { }; Config.read = function (cwd, overrides) { - var config = new Config(cwd); + var config = Config.create(cwd); return config.load(overrides).toObject(); }; -Config.normalise = function (config) { +function normalise(config) { config = expand(config); // Some backwards compatible things.. - config.shorthandResolver = config.shorthandResolver - .replace(/\{\{\{/g, '{{') - .replace(/\}\}\}/g, '}}'); + if (config.shorthandResolver) { + config.shorthandResolver = config.shorthandResolver + .replace(/\{\{\{/g, '{{') + .replace(/\}\}\}/g, '}}'); + } // Ensure that every registry endpoint does not end with / config.registry.search = config.registry.search.map(function (url) { @@ -100,8 +100,8 @@ Config.normalise = function (config) { loadCAs(config.ca); return config; -}; +} -Config.DEFAULT_REGISTRY = defaults.registry; +Config.DEFAULT_REGISTRY = require('./util/defaults').registry; module.exports = Config; diff --git a/packages/bower-config/lib/util/defaults.js b/packages/bower-config/lib/util/defaults.js index e982d163c..01819dbc3 100644 --- a/packages/bower-config/lib/util/defaults.js +++ b/packages/bower-config/lib/util/defaults.js @@ -20,7 +20,6 @@ var userAgent = !proxy && !httpsProxy : 'curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5'; var defaults = { - 'cwd': process.cwd(), 'directory': 'bower_components', 'registry': 'https://bower.herokuapp.com', 'shorthand-resolver': 'git://github.com/{{owner}}/{{package}}.git', diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 246e958ef..4711f8b9c 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -5,15 +5,14 @@ var osenv = require('osenv'); var object = require('mout/object'); var string = require('mout/string'); var paths = require('./paths'); +var defaults = require('./defaults'); var win = process.platform === 'win32'; var home = osenv.home(); -function rc(name, defaults, cwd, argv) { +function rc(name, cwd, argv) { var argvConfig; - defaults = defaults || {}; - cwd = cwd || process.cwd(); argv = argv || optimist.argv; // Parse --config.foo=false @@ -21,18 +20,31 @@ function rc(name, defaults, cwd, argv) { return value === 'false' ? false : value; }); - return object.deepMixIn.apply(null, [ - {}, - defaults, - { cwd: cwd }, - win ? {} : json(path.join('/etc', name + 'rc')), - !home ? {} : json(path.join(home, '.' + name + 'rc')), - json(path.join(paths.config, name + 'rc')), - json(find('.' + name + 'rc', cwd)), - env('npm_package_config_' + name + '_'), - env(name + '_'), - argvConfig - ]); + if (cwd) { + return object.deepMixIn.apply(null, [ + {}, + defaults, + { cwd: cwd }, + win ? {} : json(path.join('/etc', name + 'rc')), + !home ? {} : json(path.join(home, '.' + name + 'rc')), + json(path.join(paths.config, name + 'rc')), + json(find('.' + name + 'rc', cwd)), + env('npm_package_config_' + name + '_'), + env(name + '_'), + argvConfig + ]); + } else { + return object.deepMixIn.apply(null, [ + {}, + defaults, + win ? {} : json(path.join('/etc', name + 'rc')), + !home ? {} : json(path.join(home, '.' + name + 'rc')), + json(path.join(paths.config, name + 'rc')), + env('npm_package_config_' + name + '_'), + env(name + '_'), + argvConfig + ]); + } } function parse(content, file) { @@ -118,7 +130,6 @@ function find(filename, dir) { } }; - dir = dir || process.cwd(); walk(filename, dir); files.reverse(); return files; diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index 3768670a5..68d18b5d2 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -2,6 +2,42 @@ var assert = require('assert'); var path = require('path'); describe('NPM Config on package.json', function () { + beforeEach(function () { + delete process.env.npm_package_config_bower_directory; + delete process.env.npm_package_config_bower_colors; + }); + + it('allows for not providing cwd', function () { + var config = require('../lib/Config').read(); + + console.log(JSON.stringify(config, undefined, ' ')); + + config.tmp = '/foo/bar'; + config.userAgent = 'firefox'; + delete config.storage; + + assert.deepEqual(config, { + 'directory': 'bower_components', + 'registry': { + 'default': 'https://bower.herokuapp.com', + 'search': [ + 'https://bower.herokuapp.com' + ], + 'register': 'https://bower.herokuapp.com', + 'publish': 'https://bower.herokuapp.com' + }, + 'shorthandResolver': 'git://github.com/{{owner}}/{{package}}.git', + 'tmp': '/foo/bar', + 'timeout': 30000, + 'ca': { + 'search': [] + }, + 'strictSsl': true, + 'userAgent': 'firefox', + 'color': true + }); + }); + function assertCAContents(caData, name) { var r = /-----BEGIN CERTIFICATE-----[a-zA-Z0-9+\/=\n\r]+-----END CERTIFICATE-----/; diff --git a/packages/bower-config/test/util/rc.js b/packages/bower-config/test/util/rc.js index b4a8ebf92..a069182ce 100644 --- a/packages/bower-config/test/util/rc.js +++ b/packages/bower-config/test/util/rc.js @@ -5,8 +5,6 @@ describe('rc', function() { var tempDir = new helpers.TempDir(); var rc = require('../../lib/util/rc'); - var defaults = require('../../lib/util/defaults'); - defaults.cwd = tempDir.path; tempDir.prepare({ '.bowerrc': { @@ -24,28 +22,28 @@ describe('rc', function() { }); it('correctly reads .bowerrc files', function() { - var config = rc('bower', defaults, tempDir.path); + var config = rc('bower', tempDir.path); expect(config.key).to.eql('value'); expect(config.key2).to.eql(undefined); }); it('correctly reads .bowerrc files from child', function() { - var config = rc('bower', defaults, tempDir.path + '/child/'); + var config = rc('bower', tempDir.path + '/child/'); expect(config.key).to.eql('value'); expect(config.key2).to.eql('value2'); }); it('correctly reads .bowerrc files from child2', function() { - var config = rc('bower', defaults, tempDir.path + '/child2/'); + var config = rc('bower', tempDir.path + '/child2/'); expect(config.key).to.eql('valueShouldBeOverwriteParent'); expect(config.key2).to.eql(undefined); }); it('correctly reads .bowerrc files from child3', function() { - var config = rc('bower', defaults, tempDir.path + '/child3/'); + var config = rc('bower', tempDir.path + '/child3/'); expect(config.key).to.eql('value'); expect(config.key2).to.eql(undefined); From 0441e16bdbfda6b85855be033f9c59e5adcf0352 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 28 Sep 2015 19:37:58 +0200 Subject: [PATCH 0666/1021] Bump to 1.2.0 --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 9aeeff68d..c1d2708f6 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "1.1.2", + "version": "1.2.0", "description": "The Bower config reader and writer.", "author": "Twitter", "license": "MIT", From aafe02f3e9682e958d912f74f501f90470e2f984 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 28 Sep 2015 19:42:35 +0200 Subject: [PATCH 0667/1021] Update bower-registry-client and bower-config --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a5deb7a01..0106cedc5 100644 --- a/package.json +++ b/package.json @@ -16,11 +16,11 @@ "dependencies": { "abbrev": "^1.0.5", "archy": "1.0.0", - "bower-config": "^1.1.2", + "bower-config": "^1.2.0", "bower-endpoint-parser": "^0.2.2", "bower-json": "^0.4.0", "bower-logger": "^0.2.2", - "bower-registry-client": "^0.3.0", + "bower-registry-client": "^1.0.0", "cardinal": "0.4.4", "chalk": "^1.0.0", "chmodr": "0.1.0", From d614b057c9ea4f5fad4228e12644e1982910be10 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 13 Oct 2015 17:27:27 +0200 Subject: [PATCH 0668/1021] fix: Set environment variable as string, not number --- lib/core/resolvers/GitRemoteResolver.js | 2 +- test/commands/install.js | 2 +- test/core/resolvers/gitRemoteResolver.js | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/core/resolvers/GitRemoteResolver.js b/lib/core/resolvers/GitRemoteResolver.js index e5d576247..05fa0bedc 100644 --- a/lib/core/resolvers/GitRemoteResolver.js +++ b/lib/core/resolvers/GitRemoteResolver.js @@ -204,7 +204,7 @@ GitRemoteResolver.prototype._supportsShallowCloning = function () { && !GitRemoteResolver._canShallow.get(this._host)) { // Provide GIT_CURL_VERBOSE=2 environment variable to capture curl output. // Calling ls-remote includes a call to the git-upload-pack service, which returns the content type in the response. - var processEnv = mout.object.merge(process.env, { 'GIT_CURL_VERBOSE': 2 }); + var processEnv = mout.object.merge(process.env, { 'GIT_CURL_VERBOSE': '2' }); value = cmd('git', ['ls-remote', '--heads', this._source], { env: processEnv diff --git a/test/commands/install.js b/test/commands/install.js index 6e78095a7..0df60909f 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -244,7 +244,7 @@ describe('bower install', function () { return helpers.run(install).then(function() { var packageFiles = fs.readdirSync(package.path); //presence of .git file implies folder was not overwritten - expect(packageFiles).to.contain('.git'); + expect(packageFiles).to.contain('.git'); }); }); diff --git a/test/core/resolvers/gitRemoteResolver.js b/test/core/resolvers/gitRemoteResolver.js index f90b03c81..d2a00c559 100644 --- a/test/core/resolvers/gitRemoteResolver.js +++ b/test/core/resolvers/gitRemoteResolver.js @@ -268,7 +268,7 @@ describe('GitRemoteResolver', function () { return function (cmd, args, options) { expect(cmd).to.be('git'); expect(args).to.eql([ 'ls-remote', '--heads', testSource ]); - expect(options.env.GIT_CURL_VERBOSE).to.be(2); + expect(options.env.GIT_CURL_VERBOSE).to.be('2'); return Q.all(['stdout', stderr]); }; @@ -368,7 +368,7 @@ describe('GitRemoteResolver', function () { if (counter === 1) { expect(cmd).to.be('git'); expect(args).to.eql([ 'ls-remote', '--heads', testSource ]); - expect(options.env.GIT_CURL_VERBOSE).to.be(2); + expect(options.env.GIT_CURL_VERBOSE).to.be('2'); return Q.all(['stdout', multiline(function () {/* foo: bar @@ -413,7 +413,7 @@ describe('GitRemoteResolver', function () { if (counter === 1) { expect(cmd).to.be('git'); expect(args).to.eql([ 'ls-remote', '--heads', testSource1 ]); - expect(options.env.GIT_CURL_VERBOSE).to.be(2); + expect(options.env.GIT_CURL_VERBOSE).to.be('2'); return Q.all(['stdout', multiline(function () {/* foo: bar @@ -458,7 +458,7 @@ describe('GitRemoteResolver', function () { if (counter === 1) { expect(cmd).to.be('git'); expect(args).to.eql([ 'ls-remote', '--heads', testSource1 ]); - expect(options.env.GIT_CURL_VERBOSE).to.be(2); + expect(options.env.GIT_CURL_VERBOSE).to.be('2'); return Q.all(['stdout', multiline(function () {/* foo: bar @@ -470,7 +470,7 @@ describe('GitRemoteResolver', function () { else { expect(cmd).to.be('git'); expect(args).to.eql([ 'ls-remote', '--heads', testSource2 ]); - expect(options.env.GIT_CURL_VERBOSE).to.be(2); + expect(options.env.GIT_CURL_VERBOSE).to.be('2'); return Q.all(['stdout', multiline(function () {/* foo: barbaz From 96f1e988598bc5fa13a0a9d16713d297700a7aa7 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 13 Oct 2015 17:56:42 +0200 Subject: [PATCH 0669/1021] test: Fix url for js-event-emitter --- test/core/resolvers/gitHubResolver.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/core/resolvers/gitHubResolver.js b/test/core/resolvers/gitHubResolver.js index 84cb706c2..8bf46068a 100644 --- a/test/core/resolvers/gitHubResolver.js +++ b/test/core/resolvers/gitHubResolver.js @@ -52,10 +52,10 @@ describe('GitHub', function () { var resolver; nock('https://github.com') - .get('/IndigoUnited/events-emitter/archive/0.1.0.tar.gz') + .get('/IndigoUnited/js-events-emitter/archive/0.1.0.tar.gz') .replyWithFile(200, path.resolve(__dirname, '../../assets/package-tar.tar.gz')); - resolver = create({ source: 'git://github.com/IndigoUnited/events-emitter.git', target: '0.1.0' }); + resolver = create({ source: 'git://github.com/IndigoUnited/js-events-emitter.git', target: '0.1.0' }); resolver.resolve() .then(function (dir) { @@ -76,7 +76,7 @@ describe('GitHub', function () { var retried; nock('https://github.com') - .get('/IndigoUnited/events-emitter/archive/0.1.0.tar.gz') + .get('/IndigoUnited/js-events-emitter/archive/0.1.0.tar.gz') .reply(200, 'this is not a valid tar'); logger.on('log', function (entry) { @@ -85,7 +85,7 @@ describe('GitHub', function () { } }); - resolver = create({ source: 'git://github.com/IndigoUnited/events-emitter.git', target: '0.1.0' }); + resolver = create({ source: 'git://github.com/IndigoUnited/js-events-emitter.git', target: '0.1.0' }); // Monkey patch source to file:// resolver._source = 'file://' + testPackage; @@ -108,7 +108,7 @@ describe('GitHub', function () { var retried; nock('https://github.com') - .get('/IndigoUnited/events-emitter/archive/0.1.0.tar.gz') + .get('/IndigoUnited/js-events-emitter/archive/0.1.0.tar.gz') .reply(500); logger.on('log', function (entry) { @@ -117,7 +117,7 @@ describe('GitHub', function () { } }); - resolver = create({ source: 'git://github.com/IndigoUnited/events-emitter.git', target: '0.1.0' }); + resolver = create({ source: 'git://github.com/IndigoUnited/js-events-emitter.git', target: '0.1.0' }); // Monkey patch source to file:// resolver._source = 'file://' + testPackage; From 99105fbb578b55f44f76f80f9ca4e1276b55808c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 14 Oct 2015 12:50:41 +0200 Subject: [PATCH 0670/1021] Try chmod 777 + rimraf as fallback on rimraf in all places --- lib/commands/cache/clean.js | 2 +- lib/commands/link.js | 2 +- lib/core/Manager.js | 2 +- lib/core/Project.js | 2 +- lib/core/ResolveCache.js | 2 +- lib/core/resolvers/GitResolver.js | 21 ++------------ lib/core/resolvers/Resolver.js | 2 +- lib/util/removeIgnores.js | 2 +- lib/util/rimraf.js | 42 ++++++++++++++++++++++++++++ test/core/Manager.js | 2 +- test/core/packageRepository.js | 2 +- test/core/resolveCache.js | 2 +- test/core/resolverFactory.js | 2 +- test/core/resolvers/fsResolver.js | 2 +- test/core/resolvers/gitFsResolver.js | 2 +- test/core/resolvers/gitResolver.js | 2 +- test/core/resolvers/resolver.js | 2 +- test/core/resolvers/svnResolver.js | 2 +- test/core/resolvers/urlResolver.js | 2 +- test/core/scripts.js | 2 +- test/helpers.js | 2 +- test/packages-svn.js | 2 +- test/packages.js | 2 +- 23 files changed, 65 insertions(+), 40 deletions(-) create mode 100644 lib/util/rimraf.js diff --git a/lib/commands/cache/clean.js b/lib/commands/cache/clean.js index 111ba41e4..e60ab1a2e 100644 --- a/lib/commands/cache/clean.js +++ b/lib/commands/cache/clean.js @@ -2,7 +2,7 @@ var fs = require('graceful-fs'); var path = require('path'); var mout = require('mout'); var Q = require('q'); -var rimraf = require('rimraf'); +var rimraf = require('../../util/rimraf'); var endpointParser = require('bower-endpoint-parser'); var PackageRepository = require('../../core/PackageRepository'); var semver = require('../../util/semver'); diff --git a/lib/commands/link.js b/lib/commands/link.js index 4f189f5a9..6747db10a 100644 --- a/lib/commands/link.js +++ b/lib/commands/link.js @@ -1,5 +1,5 @@ var path = require('path'); -var rimraf = require('rimraf'); +var rimraf = require('../util/rimraf'); var Q = require('q'); var Project = require('../core/Project'); var createLink = require('../util/createLink'); diff --git a/lib/core/Manager.js b/lib/core/Manager.js index db94c9063..1b0a4d0a3 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -2,7 +2,7 @@ var Q = require('q'); var mout = require('mout'); var path = require('path'); var mkdirp = require('mkdirp'); -var rimraf = require('rimraf'); +var rimraf = require('../util/rimraf'); var fs = require('graceful-fs'); var endpointParser = require('bower-endpoint-parser'); var PackageRepository = require('./PackageRepository'); diff --git a/lib/core/Project.js b/lib/core/Project.js index 516e7b2d7..bd4b3a6ed 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -3,7 +3,7 @@ var path = require('path'); var fs = require('graceful-fs'); var Q = require('q'); var mout = require('mout'); -var rimraf = require('rimraf'); +var rimraf = require('../util/rimraf'); var endpointParser = require('bower-endpoint-parser'); var Logger = require('bower-logger'); var md5 = require('md5-hex'); diff --git a/lib/core/ResolveCache.js b/lib/core/ResolveCache.js index b60171be1..f4f71b312 100644 --- a/lib/core/ResolveCache.js +++ b/lib/core/ResolveCache.js @@ -3,7 +3,7 @@ var path = require('path'); var mout = require('mout'); var Q = require('q'); var mkdirp = require('mkdirp'); -var rimraf = require('rimraf'); +var rimraf = require('../util/rimraf'); var LRU = require('lru-cache'); var lockFile = require('lockfile'); var md5 = require('md5-hex'); diff --git a/lib/core/resolvers/GitResolver.js b/lib/core/resolvers/GitResolver.js index e20409fcf..cf66d3c4b 100644 --- a/lib/core/resolvers/GitResolver.js +++ b/lib/core/resolvers/GitResolver.js @@ -1,8 +1,7 @@ var util = require('util'); var path = require('path'); var Q = require('q'); -var chmodr = require('chmodr'); -var rimraf = require('rimraf'); +var rimraf = require('../../util/rimraf'); var mkdirp = require('mkdirp'); var which = require('which'); var LRU = require('lru-cache'); @@ -195,23 +194,7 @@ GitResolver.prototype._findResolution = function (target) { GitResolver.prototype._cleanup = function () { var gitFolder = path.join(this._tempDir, '.git'); - // Remove the .git folder - // Note that on windows, we need to chmod to 0777 before due to a bug in git - // See: https://github.com/isaacs/rimraf/issues/19 - if (process.platform === 'win32') { - return Q.nfcall(chmodr, gitFolder, 0777) - .then(function () { - return Q.nfcall(rimraf, gitFolder); - }, function (err) { - // If .git does not exist, chmodr returns ENOENT - // so, we ignore that error code - if (err.code !== 'ENOENT') { - throw err; - } - }); - } else { - return Q.nfcall(rimraf, gitFolder); - } + return Q.nfcall(rimraf, gitFolder); }; GitResolver.prototype._savePkgMeta = function (meta) { diff --git a/lib/core/resolvers/Resolver.js b/lib/core/resolvers/Resolver.js index 4e6bdc891..8577c36aa 100644 --- a/lib/core/resolvers/Resolver.js +++ b/lib/core/resolvers/Resolver.js @@ -3,7 +3,7 @@ var path = require('path'); var Q = require('q'); var tmp = require('tmp'); var mkdirp = require('mkdirp'); -var rimraf = require('rimraf'); +var rimraf = require('../../util/rimraf'); var readJson = require('../../util/readJson'); var createError = require('../../util/createError'); var removeIgnores = require('../../util/removeIgnores'); diff --git a/lib/util/removeIgnores.js b/lib/util/removeIgnores.js index 1405bdb4b..eaa5b80f0 100644 --- a/lib/util/removeIgnores.js +++ b/lib/util/removeIgnores.js @@ -1,5 +1,5 @@ var path = require('path'); -var rimraf = require('rimraf'); +var rimraf = require('../util/rimraf'); var fstreamIgnore = require('fstream-ignore'); var mout = require('mout'); var Q = require('q'); diff --git a/lib/util/rimraf.js b/lib/util/rimraf.js new file mode 100644 index 000000000..3426b1946 --- /dev/null +++ b/lib/util/rimraf.js @@ -0,0 +1,42 @@ +var rimraf = require('rimraf'); +var chmodr = require('chmodr'); +var fs = require('fs'); + +module.exports = function (dir, callback) { + var checkAndRetry = function (err) { + fs.stat(dir, function (err, stats) { + if (err) { + if (err.code === 'ENOENT') return callback(); + return callback(err); + } + + chmodr(dir, 0777, function (err) { + if (err) return callback(err); + rimraf(dir, callback); + }); + }); + }; + + rimraf(dir, checkAndRetry); +}; + +module.exports.sync = function (dir) { + var checkAndRetry = function () { + try { + fs.statSync(dir); + chmodr.sync(dir, 0777); + return rimraf.sync(dir); + } catch (e) { + if (e.code === 'ENOENT') return; + throw e; + } + }; + + try { + return rimraf.sync(dir); + } catch (e) { + return checkAndRetry(); + } finally { + return checkAndRetry(); + } +}; diff --git a/test/core/Manager.js b/test/core/Manager.js index 940d8887d..93c983bec 100644 --- a/test/core/Manager.js +++ b/test/core/Manager.js @@ -1,6 +1,6 @@ var expect = require('expect.js'); var path = require('path'); -var rimraf = require('rimraf'); +var rimraf = require('../../lib/util/rimraf'); var Logger = require('bower-logger'); var Manager = require('../../lib/core/Manager'); var defaultConfig = require('../../lib/config'); diff --git a/test/core/packageRepository.js b/test/core/packageRepository.js index 2361c9855..a2af11a91 100644 --- a/test/core/packageRepository.js +++ b/test/core/packageRepository.js @@ -3,7 +3,7 @@ var Q = require('q'); var path = require('path'); var mout = require('mout'); var fs = require('graceful-fs'); -var rimraf = require('rimraf'); +var rimraf = require('../../lib/util/rimraf'); var RegistryClient = require('bower-registry-client'); var Logger = require('bower-logger'); var proxyquire = require('proxyquire'); diff --git a/test/core/resolveCache.js b/test/core/resolveCache.js index 8276275af..649fba7f3 100644 --- a/test/core/resolveCache.js +++ b/test/core/resolveCache.js @@ -1,6 +1,6 @@ var path = require('path'); var mout = require('mout'); -var rimraf = require('rimraf'); +var rimraf = require('../../lib/util/rimraf'); var fs = require('graceful-fs'); var Q = require('q'); var expect = require('expect.js'); diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 72754c26a..7caf29b55 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -4,7 +4,7 @@ var path = require('path'); var mkdirp = require('mkdirp'); var mout = require('mout'); var Q = require('q'); -var rimraf = require('rimraf'); +var rimraf = require('../../lib/util/rimraf'); var RegistryClient = require('bower-registry-client'); var Logger = require('bower-logger'); var resolverFactory = require('../../lib/core/resolverFactory'); diff --git a/test/core/resolvers/fsResolver.js b/test/core/resolvers/fsResolver.js index b01c5212d..e9a08b3ac 100644 --- a/test/core/resolvers/fsResolver.js +++ b/test/core/resolvers/fsResolver.js @@ -2,7 +2,7 @@ var expect = require('expect.js'); var path = require('path'); var fs = require('graceful-fs'); var path = require('path'); -var rimraf = require('rimraf'); +var rimraf = require('../../../lib/util/rimraf'); var mkdirp = require('mkdirp'); var Q = require('q'); var Logger = require('bower-logger'); diff --git a/test/core/resolvers/gitFsResolver.js b/test/core/resolvers/gitFsResolver.js index 59219c352..042cbd2c1 100644 --- a/test/core/resolvers/gitFsResolver.js +++ b/test/core/resolvers/gitFsResolver.js @@ -2,7 +2,7 @@ var expect = require('expect.js'); var path = require('path'); var fs = require('graceful-fs'); var path = require('path'); -var rimraf = require('rimraf'); +var rimraf = require('../../../lib/util/rimraf'); var Logger = require('bower-logger'); var cmd = require('../../../lib/util/cmd'); var copy = require('../../../lib/util/copy'); diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index 98c13cec4..629cc7976 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -3,7 +3,7 @@ var util = require('util'); var path = require('path'); var fs = require('graceful-fs'); var chmodr = require('chmodr'); -var rimraf = require('rimraf'); +var rimraf = require('../../../lib/util/rimraf'); var mkdirp = require('mkdirp'); var Q = require('q'); var mout = require('mout'); diff --git a/test/core/resolvers/resolver.js b/test/core/resolvers/resolver.js index e7bf13936..624697fa9 100644 --- a/test/core/resolvers/resolver.js +++ b/test/core/resolvers/resolver.js @@ -2,7 +2,7 @@ var expect = require('expect.js'); var fs = require('graceful-fs'); var path = require('path'); var util = require('util'); -var rimraf = require('rimraf'); +var rimraf = require('../../../lib/util/rimraf'); var mkdirp = require('mkdirp'); var tmp = require('tmp'); var Q = require('q'); diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index e2d5f06dc..c8c6c2782 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -2,7 +2,7 @@ var expect = require('expect.js'); var util = require('util'); var path = require('path'); var fs = require('graceful-fs'); -var rimraf = require('rimraf'); +var rimraf = require('../../../lib/util/rimraf'); var mkdirp = require('mkdirp'); var Q = require('q'); var mout = require('mout'); diff --git a/test/core/resolvers/urlResolver.js b/test/core/resolvers/urlResolver.js index 98ee0fd57..16b680b2c 100644 --- a/test/core/resolvers/urlResolver.js +++ b/test/core/resolvers/urlResolver.js @@ -3,7 +3,7 @@ var path = require('path'); var fs = require('graceful-fs'); var nock = require('nock'); var Q = require('q'); -var rimraf = require('rimraf'); +var rimraf = require('../../../lib/util/rimraf'); var mkdirp = require('mkdirp'); var Logger = require('bower-logger'); var cmd = require('../../../lib/util/cmd'); diff --git a/test/core/scripts.js b/test/core/scripts.js index dfd8306d2..f78c2231d 100644 --- a/test/core/scripts.js +++ b/test/core/scripts.js @@ -1,7 +1,7 @@ var path = require('path'); var bower = require('../../lib/index.js'); var mkdirp = require('mkdirp'); -var rimraf = require('rimraf'); +var rimraf = require('../../lib/util/rimraf'); var fs = require('fs'); var expect = require('expect.js'); var scripts = require('../../lib/core/scripts.js'); diff --git a/test/helpers.js b/test/helpers.js index fda14ecba..57bcaf5ad 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -3,7 +3,7 @@ require('chalk').enabled = false; var Q = require('q'); var path = require('path'); var mkdirp = require('mkdirp'); -var rimraf = require('rimraf'); +var rimraf = require('../lib/util/rimraf'); var uuid = require('node-uuid'); var object = require('mout/object'); var fs = require('fs'); diff --git a/test/packages-svn.js b/test/packages-svn.js index 295ed645f..faabd3e47 100644 --- a/test/packages-svn.js +++ b/test/packages-svn.js @@ -3,7 +3,7 @@ var path = require('path'); var Q = require('q'); var semver = require('semver'); var mout = require('mout'); -var rimraf = require('rimraf'); +var rimraf = require('../lib/util/rimraf'); var mkdirp = require('mkdirp'); var chalk = require('chalk'); var cmd = require('../lib/util/cmd'); diff --git a/test/packages.js b/test/packages.js index 8c33419ff..7783ab4d5 100644 --- a/test/packages.js +++ b/test/packages.js @@ -3,7 +3,7 @@ var path = require('path'); var Q = require('q'); var semver = require('semver'); var mout = require('mout'); -var rimraf = require('rimraf'); +var rimraf = require('../lib/util/rimraf'); var mkdirp = require('mkdirp'); var chalk = require('chalk'); var cmd = require('../lib/util/cmd'); From 3ce2dd39899e24c394cfd91528155c84406a3be0 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 14 Oct 2015 14:31:13 +0200 Subject: [PATCH 0671/1021] Replace all fs with graceful-fs --- lib/commands/version.js | 2 +- lib/core/resolvers/pluginResolverFactory.js | 2 +- lib/util/rimraf.js | 2 +- test/commands/install.js | 2 +- test/commands/uninstall.js | 2 +- test/core/scripts.js | 2 +- test/helpers.js | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/commands/version.js b/lib/commands/version.js index 6e2978899..2891b9386 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -1,6 +1,6 @@ var semver = require('semver'); var which = require('which'); -var fs = require('fs'); +var fs = require('graceful-fs'); var path = require('path'); var Q = require('q'); var execFile = require('child_process').execFile; diff --git a/lib/core/resolvers/pluginResolverFactory.js b/lib/core/resolvers/pluginResolverFactory.js index 2752165cc..0304bd3f1 100644 --- a/lib/core/resolvers/pluginResolverFactory.js +++ b/lib/core/resolvers/pluginResolverFactory.js @@ -1,6 +1,6 @@ var Q = require('q'); var path = require('path'); -var fs = require('fs'); +var fs = require('graceful-fs'); var object = require('mout/object'); var semver = require('../../util/semver'); diff --git a/lib/util/rimraf.js b/lib/util/rimraf.js index 3426b1946..596b8252e 100644 --- a/lib/util/rimraf.js +++ b/lib/util/rimraf.js @@ -1,6 +1,6 @@ var rimraf = require('rimraf'); var chmodr = require('chmodr'); -var fs = require('fs'); +var fs = require('graceful-fs'); module.exports = function (dir, callback) { var checkAndRetry = function (err) { diff --git a/test/commands/install.js b/test/commands/install.js index 0df60909f..71884980d 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -1,7 +1,7 @@ var expect = require('expect.js'); var helpers = require('../helpers'); var nock = require('nock'); -var fs = require('fs'); +var fs = require('graceful-fs'); describe('bower install', function () { diff --git a/test/commands/uninstall.js b/test/commands/uninstall.js index f369b5f59..bc14a7239 100644 --- a/test/commands/uninstall.js +++ b/test/commands/uninstall.js @@ -1,6 +1,6 @@ var path = require('path'); var expect = require('expect.js'); -var fs = require('fs'); +var fs = require('graceful-fs'); var helpers = require('../helpers'); var uninstall = helpers.command('uninstall'); diff --git a/test/core/scripts.js b/test/core/scripts.js index f78c2231d..bf11fa1f3 100644 --- a/test/core/scripts.js +++ b/test/core/scripts.js @@ -2,7 +2,7 @@ var path = require('path'); var bower = require('../../lib/index.js'); var mkdirp = require('mkdirp'); var rimraf = require('../../lib/util/rimraf'); -var fs = require('fs'); +var fs = require('graceful-fs'); var expect = require('expect.js'); var scripts = require('../../lib/core/scripts.js'); diff --git a/test/helpers.js b/test/helpers.js index 57bcaf5ad..a8c694700 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -6,7 +6,7 @@ var mkdirp = require('mkdirp'); var rimraf = require('../lib/util/rimraf'); var uuid = require('node-uuid'); var object = require('mout/object'); -var fs = require('fs'); +var fs = require('graceful-fs'); var glob = require('glob'); var os = require('os'); var which = require('which'); From df8e5a16beca270d36bc6a5fe6fdcc25f8977f4c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 14 Oct 2015 16:09:38 +0200 Subject: [PATCH 0672/1021] Fix readdir call on Windows Sometimes it return ENOENT instead of ENODIR for normal files. This broke code paths in few places. Also, see: https://github.com/isaacs/chmodr/pull/8 --- lib/commands/cache/clean.js | 2 +- lib/commands/help.js | 2 +- lib/commands/init.js | 2 +- lib/commands/version.js | 2 +- lib/core/Manager.js | 2 +- lib/core/Project.js | 2 +- lib/core/ResolveCache.js | 2 +- lib/core/resolverFactory.js | 2 +- lib/core/resolvers/FsResolver.js | 2 +- lib/core/resolvers/Resolver.js | 2 +- lib/core/resolvers/UrlResolver.js | 2 +- lib/core/resolvers/pluginResolverFactory.js | 2 +- lib/util/copy.js | 2 +- lib/util/createLink.js | 2 +- lib/util/download.js | 2 +- lib/util/extract.js | 2 +- lib/util/fs.js | 34 +++++++++++++++++++++ lib/util/rimraf.js | 2 +- lib/util/template.js | 2 +- lib/util/validLink.js | 2 +- test/assets/test-temp-dir/test-exception.js | 2 +- test/assets/test-temp-dir/test.js | 2 +- test/commands/install.js | 2 +- test/commands/uninstall.js | 2 +- test/core/packageRepository.js | 2 +- test/core/resolveCache.js | 2 +- test/core/resolverFactory.js | 2 +- test/core/resolvers/fsResolver.js | 2 +- test/core/resolvers/gitFsResolver.js | 2 +- test/core/resolvers/gitHubResolver.js | 2 +- test/core/resolvers/gitRemoteResolver.js | 2 +- test/core/resolvers/gitResolver.js | 2 +- test/core/resolvers/resolver.js | 2 +- test/core/resolvers/svnResolver.js | 2 +- test/core/resolvers/urlResolver.js | 2 +- test/core/scripts.js | 2 +- test/helpers.js | 2 +- test/packages-svn.js | 2 +- test/packages.js | 2 +- 39 files changed, 72 insertions(+), 38 deletions(-) create mode 100644 lib/util/fs.js diff --git a/lib/commands/cache/clean.js b/lib/commands/cache/clean.js index e60ab1a2e..5a6e3ef31 100644 --- a/lib/commands/cache/clean.js +++ b/lib/commands/cache/clean.js @@ -1,4 +1,4 @@ -var fs = require('graceful-fs'); +var fs = require('../../util/fs'); var path = require('path'); var mout = require('mout'); var Q = require('q'); diff --git a/lib/commands/help.js b/lib/commands/help.js index 83adfd978..e8d5a8a58 100644 --- a/lib/commands/help.js +++ b/lib/commands/help.js @@ -1,6 +1,6 @@ var Q = require('q'); var path = require('path'); -var fs = require('graceful-fs'); +var fs = require('../util/fs'); var createError = require('../util/createError'); function help(logger, name, config) { diff --git a/lib/commands/init.js b/lib/commands/init.js index 0373ba873..34a5e33bc 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -1,5 +1,5 @@ var mout = require('mout'); -var fs = require('graceful-fs'); +var fs = require('../util/fs'); var path = require('path'); var Q = require('q'); var endpointParser = require('bower-endpoint-parser'); diff --git a/lib/commands/version.js b/lib/commands/version.js index 2891b9386..778d907b6 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -1,6 +1,6 @@ var semver = require('semver'); var which = require('which'); -var fs = require('graceful-fs'); +var fs = require('../util/fs'); var path = require('path'); var Q = require('q'); var execFile = require('child_process').execFile; diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 1b0a4d0a3..cc769f06b 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -3,7 +3,7 @@ var mout = require('mout'); var path = require('path'); var mkdirp = require('mkdirp'); var rimraf = require('../util/rimraf'); -var fs = require('graceful-fs'); +var fs = require('../util/fs'); var endpointParser = require('bower-endpoint-parser'); var PackageRepository = require('./PackageRepository'); var semver = require('../util/semver'); diff --git a/lib/core/Project.js b/lib/core/Project.js index bd4b3a6ed..0b3c4dc60 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -1,6 +1,6 @@ var glob = require('glob'); var path = require('path'); -var fs = require('graceful-fs'); +var fs = require('../util/fs'); var Q = require('q'); var mout = require('mout'); var rimraf = require('../util/rimraf'); diff --git a/lib/core/ResolveCache.js b/lib/core/ResolveCache.js index f4f71b312..d1242d7c9 100644 --- a/lib/core/ResolveCache.js +++ b/lib/core/ResolveCache.js @@ -1,4 +1,4 @@ -var fs = require('graceful-fs'); +var fs = require('../util/fs'); var path = require('path'); var mout = require('mout'); var Q = require('q'); diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index a397a539e..7b62d3c7e 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -1,5 +1,5 @@ var Q = require('q'); -var fs = require('graceful-fs'); +var fs = require('../util/fs'); var path = require('path'); var mout = require('mout'); var resolvers = require('./resolvers'); diff --git a/lib/core/resolvers/FsResolver.js b/lib/core/resolvers/FsResolver.js index 92c916a99..e133a4428 100644 --- a/lib/core/resolvers/FsResolver.js +++ b/lib/core/resolvers/FsResolver.js @@ -1,5 +1,5 @@ var util = require('util'); -var fs = require('graceful-fs'); +var fs = require('../../util/fs'); var path = require('path'); var mout = require('mout'); var Q = require('q'); diff --git a/lib/core/resolvers/Resolver.js b/lib/core/resolvers/Resolver.js index 8577c36aa..e3b7b7715 100644 --- a/lib/core/resolvers/Resolver.js +++ b/lib/core/resolvers/Resolver.js @@ -1,4 +1,4 @@ -var fs = require('graceful-fs'); +var fs = require('../../util/fs'); var path = require('path'); var Q = require('q'); var tmp = require('tmp'); diff --git a/lib/core/resolvers/UrlResolver.js b/lib/core/resolvers/UrlResolver.js index 346bc81cc..5d1f575ed 100644 --- a/lib/core/resolvers/UrlResolver.js +++ b/lib/core/resolvers/UrlResolver.js @@ -1,6 +1,6 @@ var util = require('util'); var path = require('path'); -var fs = require('graceful-fs'); +var fs = require('../../util/fs'); var url = require('url'); var request = require('request'); var Q = require('q'); diff --git a/lib/core/resolvers/pluginResolverFactory.js b/lib/core/resolvers/pluginResolverFactory.js index 0304bd3f1..cfe245696 100644 --- a/lib/core/resolvers/pluginResolverFactory.js +++ b/lib/core/resolvers/pluginResolverFactory.js @@ -1,6 +1,6 @@ var Q = require('q'); var path = require('path'); -var fs = require('graceful-fs'); +var fs = require('../../util/fs'); var object = require('mout/object'); var semver = require('../../util/semver'); diff --git a/lib/util/copy.js b/lib/util/copy.js index a0fb10dc8..26a3f3ff5 100644 --- a/lib/util/copy.js +++ b/lib/util/copy.js @@ -1,6 +1,6 @@ var fstream = require('fstream'); var fstreamIgnore = require('fstream-ignore'); -var fs = require('graceful-fs'); +var fs = require('./fs'); var Q = require('q'); function copy(reader, writer) { diff --git a/lib/util/createLink.js b/lib/util/createLink.js index f2c26d736..838927928 100644 --- a/lib/util/createLink.js +++ b/lib/util/createLink.js @@ -1,4 +1,4 @@ -var fs = require('graceful-fs'); +var fs = require('./fs'); var path = require('path'); var Q = require('q'); var mkdirp = require('mkdirp'); diff --git a/lib/util/download.js b/lib/util/download.js index c7c71d7e5..32df6ddd0 100644 --- a/lib/util/download.js +++ b/lib/util/download.js @@ -3,7 +3,7 @@ var request = require('request'); var Q = require('q'); var mout = require('mout'); var retry = require('retry'); -var fs = require('graceful-fs'); +var fs = require('./fs'); var createError = require('./createError'); var errorCodes = [ diff --git a/lib/util/extract.js b/lib/util/extract.js index e8a4011b0..d78c1df52 100644 --- a/lib/util/extract.js +++ b/lib/util/extract.js @@ -1,5 +1,5 @@ var path = require('path'); -var fs = require('graceful-fs'); +var fs = require('./fs'); var zlib = require('zlib'); var DecompressZip = require('decompress-zip'); var tar = require('tar-fs'); diff --git a/lib/util/fs.js b/lib/util/fs.js new file mode 100644 index 000000000..70160f469 --- /dev/null +++ b/lib/util/fs.js @@ -0,0 +1,34 @@ +var fs = require('graceful-fs'); + +var readdir = fs.readdir.bind(fs); +var readdirSync = fs.readdirSync.bind(fs); + +module.exports = fs; + +module.exports.readdir = function (dir, callback) { + fs.lstat(dir, function (err, stats) { + if (err) return callback(err); + + if (stats.isDirectory()) { + return readdir(dir, callback); + } else { + var error = new Error('ENOTDIR, not a directory \'' + dir + '\''); + error.code = 'ENOTDIR'; + error.path = dir; + error.errono = -20; + return callback(error); + } + }); +}; + +module.exports.readdirSync = function (dir) { + var stats = fs.lstatSync(dir); + + if (stats.isDirectory()) { + return readdirSync(dir); + } else { + var error = new Error(); + error.code = 'ENOTDIR'; + throw error; + } +}; diff --git a/lib/util/rimraf.js b/lib/util/rimraf.js index 596b8252e..ef26f1d2a 100644 --- a/lib/util/rimraf.js +++ b/lib/util/rimraf.js @@ -1,6 +1,6 @@ var rimraf = require('rimraf'); var chmodr = require('chmodr'); -var fs = require('graceful-fs'); +var fs = require('./fs'); module.exports = function (dir, callback) { var checkAndRetry = function (err) { diff --git a/lib/util/template.js b/lib/util/template.js index 4fd012cd9..660f7e109 100644 --- a/lib/util/template.js +++ b/lib/util/template.js @@ -1,5 +1,5 @@ var path = require('path'); -var fs = require('graceful-fs'); +var fs = require('./fs'); var Handlebars = require('handlebars'); var mout = require('mout'); var helpers = require('../../templates/helpers'); diff --git a/lib/util/validLink.js b/lib/util/validLink.js index 5191556ae..b367a3c05 100644 --- a/lib/util/validLink.js +++ b/lib/util/validLink.js @@ -1,5 +1,5 @@ var Q = require('q'); -var fs = require('graceful-fs'); +var fs = require('./fs'); function validLink(file) { // Ensures that a file is a symlink that points diff --git a/test/assets/test-temp-dir/test-exception.js b/test/assets/test-temp-dir/test-exception.js index fd73e18a0..4f3a640d9 100644 --- a/test/assets/test-temp-dir/test-exception.js +++ b/test/assets/test-temp-dir/test-exception.js @@ -1,4 +1,4 @@ -var fs = require('graceful-fs'); +var fs = require('../../../lib/util/fs'); var path = require('path'); var Logger = require('bower-logger'); var Resolver = require('../../../lib/core/resolvers/Resolver'); diff --git a/test/assets/test-temp-dir/test.js b/test/assets/test-temp-dir/test.js index 5950a717d..3afa609a3 100644 --- a/test/assets/test-temp-dir/test.js +++ b/test/assets/test-temp-dir/test.js @@ -1,4 +1,4 @@ -var fs = require('graceful-fs'); +var fs = require('../../../lib/util/fs'); var path = require('path'); var Logger = require('bower-logger'); var Resolver = require('../../../lib/core/resolvers/Resolver'); diff --git a/test/commands/install.js b/test/commands/install.js index 71884980d..dbb244781 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -1,7 +1,7 @@ var expect = require('expect.js'); var helpers = require('../helpers'); var nock = require('nock'); -var fs = require('graceful-fs'); +var fs = require('../../lib/util/fs'); describe('bower install', function () { diff --git a/test/commands/uninstall.js b/test/commands/uninstall.js index bc14a7239..729e16586 100644 --- a/test/commands/uninstall.js +++ b/test/commands/uninstall.js @@ -1,6 +1,6 @@ var path = require('path'); var expect = require('expect.js'); -var fs = require('graceful-fs'); +var fs = require('../../lib/util/fs'); var helpers = require('../helpers'); var uninstall = helpers.command('uninstall'); diff --git a/test/core/packageRepository.js b/test/core/packageRepository.js index a2af11a91..9bb453069 100644 --- a/test/core/packageRepository.js +++ b/test/core/packageRepository.js @@ -2,7 +2,7 @@ var expect = require('expect.js'); var Q = require('q'); var path = require('path'); var mout = require('mout'); -var fs = require('graceful-fs'); +var fs = require('../../lib/util/fs'); var rimraf = require('../../lib/util/rimraf'); var RegistryClient = require('bower-registry-client'); var Logger = require('bower-logger'); diff --git a/test/core/resolveCache.js b/test/core/resolveCache.js index 649fba7f3..80da557c7 100644 --- a/test/core/resolveCache.js +++ b/test/core/resolveCache.js @@ -1,7 +1,7 @@ var path = require('path'); var mout = require('mout'); var rimraf = require('../../lib/util/rimraf'); -var fs = require('graceful-fs'); +var fs = require('../../lib/util/fs'); var Q = require('q'); var expect = require('expect.js'); var mkdirp = require('mkdirp'); diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 7caf29b55..2b0eace16 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -1,5 +1,5 @@ var expect = require('expect.js'); -var fs = require('graceful-fs'); +var fs = require('../../lib/util/fs'); var path = require('path'); var mkdirp = require('mkdirp'); var mout = require('mout'); diff --git a/test/core/resolvers/fsResolver.js b/test/core/resolvers/fsResolver.js index e9a08b3ac..40ae32f4e 100644 --- a/test/core/resolvers/fsResolver.js +++ b/test/core/resolvers/fsResolver.js @@ -1,6 +1,6 @@ var expect = require('expect.js'); var path = require('path'); -var fs = require('graceful-fs'); +var fs = require('../../../lib/util/fs'); var path = require('path'); var rimraf = require('../../../lib/util/rimraf'); var mkdirp = require('mkdirp'); diff --git a/test/core/resolvers/gitFsResolver.js b/test/core/resolvers/gitFsResolver.js index 042cbd2c1..d116aecaf 100644 --- a/test/core/resolvers/gitFsResolver.js +++ b/test/core/resolvers/gitFsResolver.js @@ -1,6 +1,6 @@ var expect = require('expect.js'); var path = require('path'); -var fs = require('graceful-fs'); +var fs = require('../../../lib/util/fs'); var path = require('path'); var rimraf = require('../../../lib/util/rimraf'); var Logger = require('bower-logger'); diff --git a/test/core/resolvers/gitHubResolver.js b/test/core/resolvers/gitHubResolver.js index 8bf46068a..9c74325eb 100644 --- a/test/core/resolvers/gitHubResolver.js +++ b/test/core/resolvers/gitHubResolver.js @@ -1,6 +1,6 @@ var path = require('path'); var nock = require('nock'); -var fs = require('graceful-fs'); +var fs = require('../../../lib/util/fs'); var expect = require('expect.js'); var Logger = require('bower-logger'); var GitRemoteResolver = require('../../../lib/core/resolvers/GitRemoteResolver'); diff --git a/test/core/resolvers/gitRemoteResolver.js b/test/core/resolvers/gitRemoteResolver.js index d2a00c559..4bfb72073 100644 --- a/test/core/resolvers/gitRemoteResolver.js +++ b/test/core/resolvers/gitRemoteResolver.js @@ -1,6 +1,6 @@ var expect = require('expect.js'); var path = require('path'); -var fs = require('graceful-fs'); +var fs = require('../../../lib/util/fs'); var Logger = require('bower-logger'); var helpers = require('../../helpers'); var Q = require('q'); diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index 629cc7976..0db338899 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -1,7 +1,7 @@ var expect = require('expect.js'); var util = require('util'); var path = require('path'); -var fs = require('graceful-fs'); +var fs = require('../../../lib/util/fs'); var chmodr = require('chmodr'); var rimraf = require('../../../lib/util/rimraf'); var mkdirp = require('mkdirp'); diff --git a/test/core/resolvers/resolver.js b/test/core/resolvers/resolver.js index 624697fa9..aa455e6aa 100644 --- a/test/core/resolvers/resolver.js +++ b/test/core/resolvers/resolver.js @@ -1,5 +1,5 @@ var expect = require('expect.js'); -var fs = require('graceful-fs'); +var fs = require('../../../lib/util/fs'); var path = require('path'); var util = require('util'); var rimraf = require('../../../lib/util/rimraf'); diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index c8c6c2782..108c30603 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -1,7 +1,7 @@ var expect = require('expect.js'); var util = require('util'); var path = require('path'); -var fs = require('graceful-fs'); +var fs = require('../../../lib/util/fs'); var rimraf = require('../../../lib/util/rimraf'); var mkdirp = require('mkdirp'); var Q = require('q'); diff --git a/test/core/resolvers/urlResolver.js b/test/core/resolvers/urlResolver.js index 16b680b2c..275f15a8b 100644 --- a/test/core/resolvers/urlResolver.js +++ b/test/core/resolvers/urlResolver.js @@ -1,6 +1,6 @@ var expect = require('expect.js'); var path = require('path'); -var fs = require('graceful-fs'); +var fs = require('../../../lib/util/fs'); var nock = require('nock'); var Q = require('q'); var rimraf = require('../../../lib/util/rimraf'); diff --git a/test/core/scripts.js b/test/core/scripts.js index bf11fa1f3..b31b84870 100644 --- a/test/core/scripts.js +++ b/test/core/scripts.js @@ -2,7 +2,7 @@ var path = require('path'); var bower = require('../../lib/index.js'); var mkdirp = require('mkdirp'); var rimraf = require('../../lib/util/rimraf'); -var fs = require('graceful-fs'); +var fs = require('../../lib/util/fs'); var expect = require('expect.js'); var scripts = require('../../lib/core/scripts.js'); diff --git a/test/helpers.js b/test/helpers.js index a8c694700..24b119682 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -6,7 +6,7 @@ var mkdirp = require('mkdirp'); var rimraf = require('../lib/util/rimraf'); var uuid = require('node-uuid'); var object = require('mout/object'); -var fs = require('graceful-fs'); +var fs = require('../lib/util/fs'); var glob = require('glob'); var os = require('os'); var which = require('which'); diff --git a/test/packages-svn.js b/test/packages-svn.js index faabd3e47..028db18ce 100644 --- a/test/packages-svn.js +++ b/test/packages-svn.js @@ -1,4 +1,4 @@ -var fs = require('graceful-fs'); +var fs = require('../lib/util/fs'); var path = require('path'); var Q = require('q'); var semver = require('semver'); diff --git a/test/packages.js b/test/packages.js index 7783ab4d5..954047dda 100644 --- a/test/packages.js +++ b/test/packages.js @@ -1,4 +1,4 @@ -var fs = require('graceful-fs'); +var fs = require('../lib/util/fs'); var path = require('path'); var Q = require('q'); var semver = require('semver'); From 64eb7d598a30afdffd271ff17c0ddd9f97ffbb0c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 14 Oct 2015 17:24:54 +0200 Subject: [PATCH 0673/1021] Use lstat instead of stat for rimraf util --- lib/util/rimraf.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/util/rimraf.js b/lib/util/rimraf.js index ef26f1d2a..771177168 100644 --- a/lib/util/rimraf.js +++ b/lib/util/rimraf.js @@ -4,7 +4,7 @@ var fs = require('./fs'); module.exports = function (dir, callback) { var checkAndRetry = function (err) { - fs.stat(dir, function (err, stats) { + fs.lstat(dir, function (err, stats) { if (err) { if (err.code === 'ENOENT') return callback(); return callback(err); @@ -23,7 +23,7 @@ module.exports = function (dir, callback) { module.exports.sync = function (dir) { var checkAndRetry = function () { try { - fs.statSync(dir); + fs.lstatSync(dir); chmodr.sync(dir, 0777); return rimraf.sync(dir); } catch (e) { From 0bb1536c9972e13f3be06bea9a8619632966c664 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 14 Oct 2015 19:31:53 +0200 Subject: [PATCH 0674/1021] Better manage file handles, properly close streams --- lib/util/download.js | 135 ++++++++++++++++++++++++------------------- lib/util/extract.js | 58 ++++++++++++++----- lib/util/rimraf.js | 12 ++-- package.json | 2 + 4 files changed, 128 insertions(+), 79 deletions(-) diff --git a/lib/util/download.js b/lib/util/download.js index 32df6ddd0..eebbbb4d5 100644 --- a/lib/util/download.js +++ b/lib/util/download.js @@ -3,8 +3,8 @@ var request = require('request'); var Q = require('q'); var mout = require('mout'); var retry = require('retry'); -var fs = require('./fs'); var createError = require('./createError'); +var createWriteStream = require('fs-write-stream-atomic'); var errorCodes = [ 'EADDRINFO', @@ -15,7 +15,6 @@ var errorCodes = [ function download(url, file, options) { var operation; - var response; var deferred = Q.defer(); var progressDelay = 8000; @@ -29,41 +28,14 @@ function download(url, file, options) { // Retry on network errors operation = retry.operation(options); - operation.attempt(function () { - var req; - var writeStream; - var contentLength; - var bytesDownloaded = 0; - - req = progress(request(url, options), { - delay: progressDelay - }) - .on('response', function (res) { - var status = res.statusCode; - - if (status < 200 || status >= 300) { - return deferred.reject(createError('Status code of ' + status, 'EHTTP')); - } - response = res; - contentLength = Number(res.headers['content-length']); - }) - .on('data', function (data) { - bytesDownloaded += data.length; - }) - .on('progress', function (state) { - deferred.notify(state); - }) - .on('end', function () { - // Check if the whole file was downloaded - // In some unstable connections the ACK/FIN packet might be sent in the - // middle of the download - // See: https://github.com/joyent/node/issues/6143 - if (contentLength && bytesDownloaded < contentLength) { - req.emit('error', createError('Transfer closed with ' + (contentLength - bytesDownloaded) + ' bytes remaining to read', 'EINCOMPLETE')); - } - }) - .on('error', function (error) { + operation.attempt(function () { + Q.fcall(fetch, url, file, { + progressDelay: progressDelay + }).then(function(response) { + deferred.resolve(response); + }).fail(function (error) { + // Save timeout before retrying to report var timeout = operation._timeouts[0]; // Reject if error is not a network error @@ -74,35 +46,78 @@ function download(url, file, options) { // Next attempt will start reporting download progress immediately progressDelay = 0; - // Check if there are more retries - if (operation.retry(error)) { - // Ensure that there are no more events from this request - req.removeAllListeners(); - req.on('error', function () {}); - // Ensure that there are no more events from the write stream - writeStream.removeAllListeners(); - writeStream.on('error', function () {}); - - return deferred.notify({ - retry: true, - delay: timeout, - error: error - }); - } + deferred.notify({ + retry: true, + delay: timeout, + error: error + }); - // No more retries, reject! - deferred.reject(error); + operation.retry(error); }); + }); - // Pipe read stream to write stream - writeStream = req - .pipe(fs.createWriteStream(file)) - .on('error', deferred.reject) - .on('close', function () { - deferred.resolve(response); - }); + return deferred.promise; +} + +function fetch(url, file, options) { + var response; + var deferred = Q.defer(); + + // Retry on network errors + var req; + var writeStream; + var contentLength; + var bytesDownloaded = 0; + + req = progress(request(url, options), { + delay: options.progressDelay + }) + .on('response', function (res) { + var status = res.statusCode; + + if (status < 200 || status >= 300) { + return deferred.reject(createError('Status code of ' + status, 'EHTTP')); + } + + response = res; + contentLength = Number(res.headers['content-length']); + }) + .on('data', function (data) { + bytesDownloaded += data.length; + }) + .on('progress', function (state) { + deferred.notify(state); + }) + .on('error', function (error) { + deferred.reject(error); + }) + .on('end', function () { + // Check if the whole file was downloaded + // In some unstable connections the ACK/FIN packet might be sent in the + // middle of the download + // See: https://github.com/joyent/node/issues/6143 + if (contentLength && bytesDownloaded < contentLength) { + req.emit('error', createError( + 'Transfer closed with ' + (contentLength - bytesDownloaded) + ' bytes remaining to read', + 'EINCOMPLETE' + )); + } }); + writeStream = createWriteStream(file); + + // Pipe read stream to write stream + writeStream.on('error', function (error) { + writeStream.destroy(); + deferred.reject(error); + }); + + writeStream.on('finish', function () { + deferred.resolve(response); + }); + + req.pipe(writeStream); + return deferred.promise; } diff --git a/lib/util/extract.js b/lib/util/extract.js index d78c1df52..bc7a80bf1 100644 --- a/lib/util/extract.js +++ b/lib/util/extract.js @@ -7,6 +7,8 @@ var Q = require('q'); var mout = require('mout'); var junk = require('junk'); var createError = require('./createError'); +var createWriteStream = require('fs-write-stream-atomic'); +var destroy = require('destroy'); // This forces the default chunk size to something small in an attempt // to avoid issue #314 @@ -49,15 +51,24 @@ function extractZip(archive, dst) { function extractTar(archive, dst) { var deferred = Q.defer(); - fs.createReadStream(archive) - .on('error', deferred.reject) + var stream = fs.createReadStream(archive); + + var reject = function (error) { + destroy(stream); + deferred.reject(error); + }; + + stream.on('error', reject) .pipe(tar.extract(dst, { ignore: isSymlink, // Filter symlink files dmode: 0555, // Ensure dirs are readable fmode: 0444 // Ensure files are readable })) - .on('error', deferred.reject) - .on('finish', deferred.resolve.bind(deferred, dst)); + .on('error', reject) + .on('finish', function (result) { + destroy(stream); + deferred.resolve(dst); + }); return deferred.promise; } @@ -65,17 +76,26 @@ function extractTar(archive, dst) { function extractTarGz(archive, dst) { var deferred = Q.defer(); - fs.createReadStream(archive) - .on('error', deferred.reject) + var stream = fs.createReadStream(archive); + + var reject = function (error) { + destroy(stream); + deferred.reject(error); + }; + + stream.on('error', reject) .pipe(zlib.createGunzip()) - .on('error', deferred.reject) + .on('error', reject) .pipe(tar.extract(dst, { ignore: isSymlink, // Filter symlink files dmode: 0555, // Ensure dirs are readable fmode: 0444 // Ensure files are readable })) - .on('error', deferred.reject) - .on('finish', deferred.resolve.bind(deferred, dst)); + .on('error', reject) + .on('finish', function (result) { + destroy(stream); + deferred.resolve(dst); + }); return deferred.promise; } @@ -83,13 +103,21 @@ function extractTarGz(archive, dst) { function extractGz(archive, dst) { var deferred = Q.defer(); - fs.createReadStream(archive) - .on('error', deferred.reject) + var stream = fs.createReadStream(archive); + + var reject = function (error) { + destroy(stream); + deferred.reject(error); + }; + stream.on('error', reject) .pipe(zlib.createGunzip()) - .on('error', deferred.reject) - .pipe(fs.createWriteStream(dst)) - .on('error', deferred.reject) - .on('close', deferred.resolve.bind(deferred, dst)); + .on('error', reject) + .pipe(createWriteStream(dst)) + .on('error', reject) + .on('finish', function (result) { + destroy(stream); + deferred.resolve(dst); + }); return deferred.promise; } diff --git a/lib/util/rimraf.js b/lib/util/rimraf.js index 771177168..6fa8e8687 100644 --- a/lib/util/rimraf.js +++ b/lib/util/rimraf.js @@ -3,21 +3,25 @@ var chmodr = require('chmodr'); var fs = require('./fs'); module.exports = function (dir, callback) { - var checkAndRetry = function (err) { + var checkAndRetry = function (e) { fs.lstat(dir, function (err, stats) { if (err) { if (err.code === 'ENOENT') return callback(); - return callback(err); + return callback(e); } chmodr(dir, 0777, function (err) { - if (err) return callback(err); + if (err) return callback(e); rimraf(dir, callback); }); }); }; - rimraf(dir, checkAndRetry); + if (process.platform === 'win32') { + checkAndRetry(); + } else { + rimraf(dir, checkAndRetry); + } }; module.exports.sync = function (dir) { diff --git a/package.json b/package.json index 0106cedc5..e3e882d4a 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "chmodr": "0.1.0", "configstore": "^0.3.2", "decompress-zip": "^0.1.0", + "destroy": "^1.0.3", + "fs-write-stream-atomic": "^1.0.4", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", "github": "^0.2.3", From db265d471fc1848e1d8a32a2c6eda9d577d43b01 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 14 Oct 2015 21:30:03 +0200 Subject: [PATCH 0675/1021] fix: Setting HTTP_PROXY on Windows (case insensitivity) --- packages/bower-config/lib/util/proxy.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bower-config/lib/util/proxy.js b/packages/bower-config/lib/util/proxy.js index 8cdbbbd67..d5524dbc8 100644 --- a/packages/bower-config/lib/util/proxy.js +++ b/packages/bower-config/lib/util/proxy.js @@ -13,22 +13,22 @@ EnvProxy.prototype.set = function (config) { if (Object.prototype.hasOwnProperty.call(config, 'noProxy')) { this.restoreFrom.NO_PROXY = process.env.NO_PROXY; this.restoreFrom.no_proxy = process.env.no_proxy; - process.env.NO_PROXY = config.noProxy; delete process.env.no_proxy; + process.env.NO_PROXY = config.noProxy; } if (Object.prototype.hasOwnProperty.call(config, 'proxy')) { this.restoreFrom.HTTP_PROXY = process.env.HTTP_PROXY; this.restoreFrom.http_proxy = process.env.http_proxy; - process.env.HTTP_PROXY = config.proxy; delete process.env.http_proxy; + process.env.HTTP_PROXY = config.proxy; } if (Object.prototype.hasOwnProperty.call(config, 'httpsProxy')) { this.restoreFrom.HTTPS_PROXY = process.env.HTTPS_PROXY; this.restoreFrom.https_proxy = process.env.https_proxy; - process.env.HTTPS_PROXY = config.httpsProxy; delete process.env.https_proxy; + process.env.HTTPS_PROXY = config.httpsProxy; } }; From 8df5970300fe3368a703516fa7066faaca134851 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 14 Oct 2015 21:30:26 +0200 Subject: [PATCH 0676/1021] Bump to 1.2.1 --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index c1d2708f6..075c9e492 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "1.2.0", + "version": "1.2.1", "description": "The Bower config reader and writer.", "author": "Twitter", "license": "MIT", From eba2c69308f55e79e9bb817301feffc31a879adf Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 15 Oct 2015 11:14:35 +0200 Subject: [PATCH 0677/1021] Update bower-config to fix proxy behavior on windows --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e3e882d4a..9439fd494 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dependencies": { "abbrev": "^1.0.5", "archy": "1.0.0", - "bower-config": "^1.2.0", + "bower-config": "^1.2.1", "bower-endpoint-parser": "^0.2.2", "bower-json": "^0.4.0", "bower-logger": "^0.2.2", From a019f887e9b5b84e029d980a8ec48613602e3503 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 15 Oct 2015 11:14:49 +0200 Subject: [PATCH 0678/1021] Update chmodr to fix chmod behavior on windows --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9439fd494..71ebdb3c9 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "bower-registry-client": "^1.0.0", "cardinal": "0.4.4", "chalk": "^1.0.0", - "chmodr": "0.1.0", + "chmodr": "^1.0.2", "configstore": "^0.3.2", "decompress-zip": "^0.1.0", "destroy": "^1.0.3", From 8ac68ede5d5126dc3d3f5bde9dbf3f0fbae3a85a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 15 Oct 2015 12:45:38 +0200 Subject: [PATCH 0679/1021] Shrinkwrap all dependencies and add them to bundledDependencies --- npm-shrinkwrap.json | 1575 +++++++++++++++++++++++++++++++++++++++++++ package.json | 48 ++ 2 files changed, 1623 insertions(+) create mode 100644 npm-shrinkwrap.json diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json new file mode 100644 index 000000000..f1b3d7e18 --- /dev/null +++ b/npm-shrinkwrap.json @@ -0,0 +1,1575 @@ +{ + "name": "bower", + "version": "1.5.3", + "dependencies": { + "abbrev": { + "version": "1.0.7", + "from": "abbrev@>=1.0.5 <2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz" + }, + "archy": { + "version": "1.0.0", + "from": "archy@1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz" + }, + "bower-config": { + "version": "1.2.1", + "from": "bower-config@>=1.2.1 <2.0.0", + "dependencies": { + "graceful-fs": { + "version": "4.1.2", + "from": "graceful-fs@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" + }, + "optimist": { + "version": "0.6.1", + "from": "optimist@>=0.6.1 <0.7.0", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "from": "wordwrap@>=0.0.2 <0.1.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz" + }, + "minimist": { + "version": "0.0.10", + "from": "minimist@>=0.0.1 <0.1.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz" + } + } + }, + "osenv": { + "version": "0.1.3", + "from": "osenv@>=0.1.3 <0.2.0", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", + "dependencies": { + "os-homedir": { + "version": "1.0.1", + "from": "os-homedir@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" + }, + "os-tmpdir": { + "version": "1.0.1", + "from": "os-tmpdir@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz" + } + } + } + } + }, + "bower-endpoint-parser": { + "version": "0.2.2", + "from": "bower-endpoint-parser@>=0.2.2 <0.3.0", + "resolved": "https://registry.npmjs.org/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz" + }, + "bower-json": { + "version": "0.4.0", + "from": "bower-json@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/bower-json/-/bower-json-0.4.0.tgz", + "dependencies": { + "deep-extend": { + "version": "0.2.11", + "from": "deep-extend@>=0.2.5 <0.3.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.2.11.tgz" + }, + "graceful-fs": { + "version": "2.0.3", + "from": "graceful-fs@>=2.0.0 <2.1.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz" + }, + "intersect": { + "version": "0.0.3", + "from": "intersect@>=0.0.3 <0.1.0", + "resolved": "https://registry.npmjs.org/intersect/-/intersect-0.0.3.tgz" + } + } + }, + "bower-logger": { + "version": "0.2.2", + "from": "bower-logger@>=0.2.2 <0.3.0", + "resolved": "https://registry.npmjs.org/bower-logger/-/bower-logger-0.2.2.tgz" + }, + "bower-registry-client": { + "version": "1.0.0", + "from": "bower-registry-client@>=1.0.0 <2.0.0", + "dependencies": { + "async": { + "version": "0.2.10", + "from": "async@>=0.2.8 <0.3.0", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz" + }, + "graceful-fs": { + "version": "4.1.2", + "from": "graceful-fs@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" + }, + "request-replay": { + "version": "0.2.0", + "from": "request-replay@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/request-replay/-/request-replay-0.2.0.tgz" + }, + "mkdirp": { + "version": "0.3.5", + "from": "mkdirp@>=0.3.5 <0.4.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" + } + } + }, + "cardinal": { + "version": "0.4.4", + "from": "cardinal@0.4.4", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-0.4.4.tgz", + "dependencies": { + "redeyed": { + "version": "0.4.4", + "from": "redeyed@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-0.4.4.tgz", + "dependencies": { + "esprima": { + "version": "1.0.4", + "from": "esprima@>=1.0.4 <1.1.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz" + } + } + }, + "ansicolors": { + "version": "0.2.1", + "from": "ansicolors@>=0.2.1 <0.3.0", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz" + } + } + }, + "chalk": { + "version": "1.1.1", + "from": "chalk@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.1.tgz", + "dependencies": { + "ansi-styles": { + "version": "2.1.0", + "from": "ansi-styles@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.1.0.tgz" + }, + "escape-string-regexp": { + "version": "1.0.3", + "from": "escape-string-regexp@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz" + }, + "has-ansi": { + "version": "2.0.0", + "from": "has-ansi@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "dependencies": { + "ansi-regex": { + "version": "2.0.0", + "from": "ansi-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" + } + } + }, + "strip-ansi": { + "version": "3.0.0", + "from": "strip-ansi@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", + "dependencies": { + "ansi-regex": { + "version": "2.0.0", + "from": "ansi-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" + } + } + }, + "supports-color": { + "version": "2.0.0", + "from": "supports-color@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" + } + } + }, + "chmodr": { + "version": "1.0.2", + "from": "chmodr@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/chmodr/-/chmodr-1.0.2.tgz" + }, + "configstore": { + "version": "0.3.2", + "from": "configstore@>=0.3.2 <0.4.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-0.3.2.tgz", + "dependencies": { + "js-yaml": { + "version": "3.4.2", + "from": "js-yaml@>=3.1.0 <4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.2.tgz", + "dependencies": { + "argparse": { + "version": "1.0.2", + "from": "argparse@>=1.0.2 <1.1.0", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.2.tgz", + "dependencies": { + "lodash": { + "version": "3.10.1", + "from": "lodash@>=3.2.0 <4.0.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" + }, + "sprintf-js": { + "version": "1.0.3", + "from": "sprintf-js@>=1.0.2 <1.1.0", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + } + } + }, + "esprima": { + "version": "2.2.0", + "from": "esprima@>=2.2.0 <2.3.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.2.0.tgz" + } + } + }, + "object-assign": { + "version": "2.1.1", + "from": "object-assign@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz" + }, + "osenv": { + "version": "0.1.3", + "from": "osenv@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", + "dependencies": { + "os-homedir": { + "version": "1.0.1", + "from": "os-homedir@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" + }, + "os-tmpdir": { + "version": "1.0.1", + "from": "os-tmpdir@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz" + } + } + }, + "uuid": { + "version": "2.0.1", + "from": "uuid@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz" + }, + "xdg-basedir": { + "version": "1.0.1", + "from": "xdg-basedir@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-1.0.1.tgz" + } + } + }, + "decompress-zip": { + "version": "0.1.0", + "from": "decompress-zip@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.1.0.tgz", + "dependencies": { + "binary": { + "version": "0.3.0", + "from": "binary@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "dependencies": { + "chainsaw": { + "version": "0.1.0", + "from": "chainsaw@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "dependencies": { + "traverse": { + "version": "0.3.9", + "from": "traverse@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz" + } + } + }, + "buffers": { + "version": "0.1.1", + "from": "buffers@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz" + } + } + }, + "mkpath": { + "version": "0.1.0", + "from": "mkpath@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz" + }, + "readable-stream": { + "version": "1.1.13", + "from": "readable-stream@>=1.1.8 <2.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz", + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" + }, + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + } + } + }, + "touch": { + "version": "0.0.3", + "from": "touch@0.0.3", + "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz", + "dependencies": { + "nopt": { + "version": "1.0.10", + "from": "nopt@>=1.0.10 <1.1.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz" + } + } + } + } + }, + "destroy": { + "version": "1.0.3", + "from": "destroy@*", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz" + }, + "fs-write-stream-atomic": { + "version": "1.0.4", + "from": "fs-write-stream-atomic@*", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.4.tgz", + "dependencies": { + "graceful-fs": { + "version": "4.1.2", + "from": "graceful-fs@>=4.1.2 <5.0.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" + } + } + }, + "fstream": { + "version": "1.0.8", + "from": "fstream@>=1.0.3 <2.0.0", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.8.tgz", + "dependencies": { + "graceful-fs": { + "version": "4.1.2", + "from": "graceful-fs@>=4.1.2 <5.0.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + } + } + }, + "fstream-ignore": { + "version": "1.0.2", + "from": "fstream-ignore@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.2.tgz", + "dependencies": { + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "minimatch": { + "version": "2.0.10", + "from": "minimatch@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "dependencies": { + "brace-expansion": { + "version": "1.1.1", + "from": "brace-expansion@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", + "dependencies": { + "balanced-match": { + "version": "0.2.0", + "from": "balanced-match@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + } + } + } + } + } + } + }, + "github": { + "version": "0.2.4", + "from": "github@>=0.2.3 <0.3.0", + "resolved": "https://registry.npmjs.org/github/-/github-0.2.4.tgz", + "dependencies": { + "mime": { + "version": "1.3.4", + "from": "mime@>=1.2.11 <2.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz" + } + } + }, + "glob": { + "version": "4.5.3", + "from": "glob@>=4.3.2 <5.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", + "dependencies": { + "inflight": { + "version": "1.0.4", + "from": "inflight@>=1.0.4 <2.0.0", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "minimatch": { + "version": "2.0.10", + "from": "minimatch@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "dependencies": { + "brace-expansion": { + "version": "1.1.1", + "from": "brace-expansion@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", + "dependencies": { + "balanced-match": { + "version": "0.2.0", + "from": "balanced-match@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + } + } + } + } + }, + "once": { + "version": "1.3.2", + "from": "once@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + } + } + }, + "graceful-fs": { + "version": "3.0.8", + "from": "graceful-fs@>=3.0.5 <4.0.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.8.tgz" + }, + "handlebars": { + "version": "2.0.0", + "from": "handlebars@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-2.0.0.tgz", + "dependencies": { + "optimist": { + "version": "0.3.7", + "from": "optimist@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "from": "wordwrap@>=0.0.2 <0.1.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz" + } + } + }, + "uglify-js": { + "version": "2.3.6", + "from": "uglify-js@>=2.3.0 <2.4.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.6.tgz", + "dependencies": { + "async": { + "version": "0.2.10", + "from": "async@>=0.2.6 <0.3.0", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz" + }, + "source-map": { + "version": "0.1.43", + "from": "source-map@>=0.1.7 <0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "dependencies": { + "amdefine": { + "version": "1.0.0", + "from": "amdefine@>=0.0.4", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz" + } + } + } + } + } + } + }, + "inquirer": { + "version": "0.10.0", + "from": "inquirer@0.10.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.10.0.tgz", + "dependencies": { + "ansi-escapes": { + "version": "1.1.0", + "from": "ansi-escapes@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.1.0.tgz" + }, + "ansi-regex": { + "version": "2.0.0", + "from": "ansi-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" + }, + "cli-cursor": { + "version": "1.0.2", + "from": "cli-cursor@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "dependencies": { + "restore-cursor": { + "version": "1.0.1", + "from": "restore-cursor@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "dependencies": { + "exit-hook": { + "version": "1.1.1", + "from": "exit-hook@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz" + }, + "onetime": { + "version": "1.0.0", + "from": "onetime@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.0.0.tgz" + } + } + } + } + }, + "cli-width": { + "version": "1.0.1", + "from": "cli-width@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.0.1.tgz" + }, + "figures": { + "version": "1.4.0", + "from": "figures@>=1.3.5 <2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.4.0.tgz" + }, + "lodash": { + "version": "3.10.1", + "from": "lodash@>=3.3.1 <4.0.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" + }, + "readline2": { + "version": "1.0.1", + "from": "readline2@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", + "dependencies": { + "code-point-at": { + "version": "1.0.0", + "from": "code-point-at@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.0.0.tgz", + "dependencies": { + "number-is-nan": { + "version": "1.0.0", + "from": "number-is-nan@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz" + } + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "from": "is-fullwidth-code-point@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "dependencies": { + "number-is-nan": { + "version": "1.0.0", + "from": "number-is-nan@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz" + } + } + }, + "mute-stream": { + "version": "0.0.5", + "from": "mute-stream@0.0.5", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz" + } + } + }, + "run-async": { + "version": "0.1.0", + "from": "run-async@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", + "dependencies": { + "once": { + "version": "1.3.2", + "from": "once@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + } + } + }, + "rx-lite": { + "version": "3.1.2", + "from": "rx-lite@>=3.1.2 <4.0.0", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz" + }, + "strip-ansi": { + "version": "3.0.0", + "from": "strip-ansi@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz" + }, + "through": { + "version": "2.3.8", + "from": "through@>=2.3.6 <3.0.0", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + } + } + }, + "insight": { + "version": "0.7.0", + "from": "insight@>=0.7.0 <0.8.0", + "resolved": "https://registry.npmjs.org/insight/-/insight-0.7.0.tgz", + "dependencies": { + "async": { + "version": "1.4.2", + "from": "async@>=1.4.2 <2.0.0", + "resolved": "https://registry.npmjs.org/async/-/async-1.4.2.tgz" + }, + "configstore": { + "version": "1.2.1", + "from": "configstore@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-1.2.1.tgz", + "dependencies": { + "graceful-fs": { + "version": "4.1.2", + "from": "graceful-fs@>=4.1.2 <5.0.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" + }, + "object-assign": { + "version": "3.0.0", + "from": "object-assign@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz" + }, + "os-tmpdir": { + "version": "1.0.1", + "from": "os-tmpdir@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz" + }, + "osenv": { + "version": "0.1.3", + "from": "osenv@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", + "dependencies": { + "os-homedir": { + "version": "1.0.1", + "from": "os-homedir@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" + } + } + }, + "uuid": { + "version": "2.0.1", + "from": "uuid@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz" + }, + "write-file-atomic": { + "version": "1.1.3", + "from": "write-file-atomic@>=1.1.2 <2.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.1.3.tgz", + "dependencies": { + "slide": { + "version": "1.1.6", + "from": "slide@>=1.1.5 <2.0.0", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz" + } + } + }, + "xdg-basedir": { + "version": "2.0.0", + "from": "xdg-basedir@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", + "dependencies": { + "os-homedir": { + "version": "1.0.1", + "from": "os-homedir@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" + } + } + } + } + }, + "lodash.debounce": { + "version": "3.1.1", + "from": "lodash.debounce@>=3.0.1 <4.0.0", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-3.1.1.tgz", + "dependencies": { + "lodash._getnative": { + "version": "3.9.1", + "from": "lodash._getnative@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz" + } + } + }, + "object-assign": { + "version": "4.0.1", + "from": "object-assign@>=4.0.1 <5.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.0.1.tgz" + }, + "os-name": { + "version": "1.0.3", + "from": "os-name@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/os-name/-/os-name-1.0.3.tgz", + "dependencies": { + "osx-release": { + "version": "1.1.0", + "from": "osx-release@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/osx-release/-/osx-release-1.1.0.tgz", + "dependencies": { + "minimist": { + "version": "1.2.0", + "from": "minimist@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" + } + } + }, + "win-release": { + "version": "1.1.1", + "from": "win-release@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz", + "dependencies": { + "semver": { + "version": "5.0.3", + "from": "semver@>=5.0.1 <6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz" + } + } + } + } + }, + "tough-cookie": { + "version": "2.0.0", + "from": "tough-cookie@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz" + } + } + }, + "is-root": { + "version": "1.0.0", + "from": "is-root@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-1.0.0.tgz" + }, + "junk": { + "version": "1.0.2", + "from": "junk@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/junk/-/junk-1.0.2.tgz" + }, + "lockfile": { + "version": "1.0.1", + "from": "lockfile@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.1.tgz" + }, + "lru-cache": { + "version": "2.7.0", + "from": "lru-cache@>=2.5.0 <3.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.0.tgz" + }, + "md5-hex": { + "version": "1.1.0", + "from": "md5-hex@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.1.0.tgz", + "dependencies": { + "md5-o-matic": { + "version": "0.1.1", + "from": "md5-o-matic@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz" + } + } + }, + "mkdirp": { + "version": "0.5.0", + "from": "mkdirp@0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "dependencies": { + "minimist": { + "version": "0.0.8", + "from": "minimist@0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" + } + } + }, + "mout": { + "version": "0.11.0", + "from": "mout@>=0.11.0 <0.12.0", + "resolved": "https://registry.npmjs.org/mout/-/mout-0.11.0.tgz" + }, + "nopt": { + "version": "3.0.4", + "from": "nopt@>=3.0.1 <4.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.4.tgz" + }, + "opn": { + "version": "1.0.2", + "from": "opn@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-1.0.2.tgz" + }, + "p-throttler": { + "version": "0.1.1", + "from": "p-throttler@0.1.1", + "resolved": "https://registry.npmjs.org/p-throttler/-/p-throttler-0.1.1.tgz", + "dependencies": { + "q": { + "version": "0.9.7", + "from": "q@>=0.9.2 <0.10.0", + "resolved": "https://registry.npmjs.org/q/-/q-0.9.7.tgz" + } + } + }, + "promptly": { + "version": "0.2.0", + "from": "promptly@0.2.0", + "resolved": "https://registry.npmjs.org/promptly/-/promptly-0.2.0.tgz", + "dependencies": { + "read": { + "version": "1.0.7", + "from": "read@>=1.0.4 <1.1.0", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "dependencies": { + "mute-stream": { + "version": "0.0.5", + "from": "mute-stream@>=0.0.4 <0.1.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz" + } + } + } + } + }, + "q": { + "version": "1.4.1", + "from": "q@>=1.1.2 <2.0.0", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz" + }, + "request": { + "version": "2.53.0", + "from": "request@2.53.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.53.0.tgz", + "dependencies": { + "bl": { + "version": "0.9.4", + "from": "bl@>=0.9.0 <0.10.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.4.tgz", + "dependencies": { + "readable-stream": { + "version": "1.0.33", + "from": "readable-stream@>=1.0.26 <1.1.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" + }, + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + } + } + } + } + }, + "caseless": { + "version": "0.9.0", + "from": "caseless@>=0.9.0 <0.10.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.9.0.tgz" + }, + "forever-agent": { + "version": "0.5.2", + "from": "forever-agent@>=0.5.0 <0.6.0", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz" + }, + "form-data": { + "version": "0.2.0", + "from": "form-data@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz", + "dependencies": { + "async": { + "version": "0.9.2", + "from": "async@>=0.9.0 <0.10.0", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz" + } + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "from": "json-stringify-safe@>=5.0.0 <5.1.0", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + }, + "mime-types": { + "version": "2.0.14", + "from": "mime-types@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", + "dependencies": { + "mime-db": { + "version": "1.12.0", + "from": "mime-db@>=1.12.0 <1.13.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz" + } + } + }, + "qs": { + "version": "2.3.3", + "from": "qs@>=2.3.1 <2.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz" + }, + "tunnel-agent": { + "version": "0.4.1", + "from": "tunnel-agent@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.1.tgz" + }, + "tough-cookie": { + "version": "2.0.0", + "from": "tough-cookie@>=0.12.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz" + }, + "http-signature": { + "version": "0.10.1", + "from": "http-signature@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", + "dependencies": { + "assert-plus": { + "version": "0.1.5", + "from": "assert-plus@>=0.1.5 <0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz" + }, + "asn1": { + "version": "0.1.11", + "from": "asn1@0.1.11", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz" + }, + "ctype": { + "version": "0.5.3", + "from": "ctype@0.5.3", + "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz" + } + } + }, + "oauth-sign": { + "version": "0.6.0", + "from": "oauth-sign@>=0.6.0 <0.7.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz" + }, + "hawk": { + "version": "2.3.1", + "from": "hawk@>=2.3.0 <2.4.0", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz", + "dependencies": { + "hoek": { + "version": "2.16.3", + "from": "hoek@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz" + }, + "boom": { + "version": "2.9.0", + "from": "boom@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.9.0.tgz" + }, + "cryptiles": { + "version": "2.0.5", + "from": "cryptiles@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz" + }, + "sntp": { + "version": "1.0.9", + "from": "sntp@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz" + } + } + }, + "aws-sign2": { + "version": "0.5.0", + "from": "aws-sign2@>=0.5.0 <0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz" + }, + "stringstream": { + "version": "0.0.4", + "from": "stringstream@>=0.0.4 <0.1.0", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.4.tgz" + }, + "combined-stream": { + "version": "0.0.7", + "from": "combined-stream@>=0.0.5 <0.1.0", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", + "dependencies": { + "delayed-stream": { + "version": "0.0.5", + "from": "delayed-stream@0.0.5", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz" + } + } + }, + "isstream": { + "version": "0.1.2", + "from": "isstream@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" + } + } + }, + "request-progress": { + "version": "0.3.1", + "from": "request-progress@0.3.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", + "dependencies": { + "throttleit": { + "version": "0.0.2", + "from": "throttleit@>=0.0.2 <0.1.0", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz" + } + } + }, + "retry": { + "version": "0.6.1", + "from": "retry@0.6.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.6.1.tgz" + }, + "rimraf": { + "version": "2.4.3", + "from": "rimraf@>=2.2.8 <3.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.3.tgz", + "dependencies": { + "glob": { + "version": "5.0.15", + "from": "glob@>=5.0.14 <6.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "dependencies": { + "inflight": { + "version": "1.0.4", + "from": "inflight@>=1.0.4 <2.0.0", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "minimatch": { + "version": "3.0.0", + "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.0.tgz", + "dependencies": { + "brace-expansion": { + "version": "1.1.1", + "from": "brace-expansion@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", + "dependencies": { + "balanced-match": { + "version": "0.2.0", + "from": "balanced-match@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + } + } + } + } + }, + "once": { + "version": "1.3.2", + "from": "once@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + }, + "path-is-absolute": { + "version": "1.0.0", + "from": "path-is-absolute@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz" + } + } + } + } + }, + "semver": { + "version": "2.3.2", + "from": "semver@>=2.3.0 <3.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-2.3.2.tgz" + }, + "shell-quote": { + "version": "1.4.3", + "from": "shell-quote@>=1.4.2 <2.0.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.4.3.tgz", + "dependencies": { + "jsonify": { + "version": "0.0.0", + "from": "jsonify@>=0.0.0 <0.1.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz" + }, + "array-filter": { + "version": "0.0.1", + "from": "array-filter@>=0.0.0 <0.1.0", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz" + }, + "array-reduce": { + "version": "0.0.0", + "from": "array-reduce@>=0.0.0 <0.1.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz" + }, + "array-map": { + "version": "0.0.0", + "from": "array-map@>=0.0.0 <0.1.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz" + } + } + }, + "stringify-object": { + "version": "1.0.1", + "from": "stringify-object@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-1.0.1.tgz" + }, + "tar-fs": { + "version": "1.8.1", + "from": "tar-fs@>=1.4.1 <2.0.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.8.1.tgz", + "dependencies": { + "pump": { + "version": "1.0.0", + "from": "pump@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.0.tgz", + "dependencies": { + "end-of-stream": { + "version": "1.1.0", + "from": "end-of-stream@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz" + }, + "once": { + "version": "1.3.2", + "from": "once@>=1.3.1 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + } + } + }, + "tar-stream": { + "version": "1.2.1", + "from": "tar-stream@>=1.1.2 <2.0.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.2.1.tgz", + "dependencies": { + "bl": { + "version": "1.0.0", + "from": "bl@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.0.0.tgz" + }, + "end-of-stream": { + "version": "1.1.0", + "from": "end-of-stream@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz", + "dependencies": { + "once": { + "version": "1.3.2", + "from": "once@>=1.3.0 <1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + } + } + }, + "readable-stream": { + "version": "2.0.2", + "from": "readable-stream@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "process-nextick-args": { + "version": "1.0.3", + "from": "process-nextick-args@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "util-deprecate": { + "version": "1.0.1", + "from": "util-deprecate@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz" + } + } + }, + "xtend": { + "version": "4.0.0", + "from": "xtend@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz" + } + } + } + } + }, + "tmp": { + "version": "0.0.24", + "from": "tmp@0.0.24", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz" + }, + "update-notifier": { + "version": "0.3.2", + "from": "update-notifier@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-0.3.2.tgz", + "dependencies": { + "is-npm": { + "version": "1.0.0", + "from": "is-npm@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz" + }, + "latest-version": { + "version": "1.0.1", + "from": "latest-version@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-1.0.1.tgz", + "dependencies": { + "package-json": { + "version": "1.2.0", + "from": "package-json@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-1.2.0.tgz", + "dependencies": { + "got": { + "version": "3.3.1", + "from": "got@>=3.2.0 <4.0.0", + "resolved": "https://registry.npmjs.org/got/-/got-3.3.1.tgz", + "dependencies": { + "duplexify": { + "version": "3.4.2", + "from": "duplexify@>=3.2.0 <4.0.0", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.4.2.tgz", + "dependencies": { + "end-of-stream": { + "version": "1.0.0", + "from": "end-of-stream@1.0.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz", + "dependencies": { + "once": { + "version": "1.3.2", + "from": "once@>=1.3.0 <1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + } + } + }, + "readable-stream": { + "version": "2.0.2", + "from": "readable-stream@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "process-nextick-args": { + "version": "1.0.3", + "from": "process-nextick-args@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "util-deprecate": { + "version": "1.0.1", + "from": "util-deprecate@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz" + } + } + } + } + }, + "infinity-agent": { + "version": "2.0.3", + "from": "infinity-agent@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/infinity-agent/-/infinity-agent-2.0.3.tgz" + }, + "is-redirect": { + "version": "1.0.0", + "from": "is-redirect@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz" + }, + "is-stream": { + "version": "1.0.1", + "from": "is-stream@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.0.1.tgz" + }, + "lowercase-keys": { + "version": "1.0.0", + "from": "lowercase-keys@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz" + }, + "nested-error-stacks": { + "version": "1.0.1", + "from": "nested-error-stacks@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-1.0.1.tgz", + "dependencies": { + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + } + } + }, + "object-assign": { + "version": "3.0.0", + "from": "object-assign@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz" + }, + "prepend-http": { + "version": "1.0.3", + "from": "prepend-http@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.3.tgz" + }, + "read-all-stream": { + "version": "3.0.1", + "from": "read-all-stream@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.0.1.tgz", + "dependencies": { + "pinkie-promise": { + "version": "1.0.0", + "from": "pinkie-promise@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz", + "dependencies": { + "pinkie": { + "version": "1.0.0", + "from": "pinkie@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz" + } + } + }, + "readable-stream": { + "version": "2.0.2", + "from": "readable-stream@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "process-nextick-args": { + "version": "1.0.3", + "from": "process-nextick-args@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "util-deprecate": { + "version": "1.0.1", + "from": "util-deprecate@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz" + } + } + } + } + }, + "timed-out": { + "version": "2.0.0", + "from": "timed-out@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz" + } + } + }, + "registry-url": { + "version": "3.0.3", + "from": "registry-url@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.0.3.tgz", + "dependencies": { + "rc": { + "version": "1.1.1", + "from": "rc@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.1.1.tgz", + "dependencies": { + "minimist": { + "version": "1.2.0", + "from": "minimist@>=1.1.2 <2.0.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" + }, + "deep-extend": { + "version": "0.2.11", + "from": "deep-extend@>=0.2.5 <0.3.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.2.11.tgz" + }, + "strip-json-comments": { + "version": "0.1.3", + "from": "strip-json-comments@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-0.1.3.tgz" + }, + "ini": { + "version": "1.3.4", + "from": "ini@>=1.3.0 <1.4.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz" + } + } + } + } + } + } + } + } + }, + "semver-diff": { + "version": "2.0.0", + "from": "semver-diff@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.0.0.tgz", + "dependencies": { + "semver": { + "version": "4.3.6", + "from": "semver@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz" + } + } + }, + "string-length": { + "version": "1.0.1", + "from": "string-length@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", + "dependencies": { + "strip-ansi": { + "version": "3.0.0", + "from": "strip-ansi@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", + "dependencies": { + "ansi-regex": { + "version": "2.0.0", + "from": "ansi-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" + } + } + } + } + } + } + }, + "user-home": { + "version": "1.1.1", + "from": "user-home@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz" + }, + "which": { + "version": "1.1.2", + "from": "which@>=1.0.8 <2.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.1.2.tgz", + "dependencies": { + "is-absolute": { + "version": "0.1.7", + "from": "is-absolute@>=0.1.7 <0.2.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz", + "dependencies": { + "is-relative": { + "version": "0.1.3", + "from": "is-relative@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz" + } + } + } + } + } + } +} diff --git a/package.json b/package.json index 71ebdb3c9..547553065 100644 --- a/package.json +++ b/package.json @@ -80,6 +80,54 @@ "proxyquire": "^1.3.0", "spawn-sync": "^1.0.5" }, + "bundledDependencies": [ + "abbrev", + "archy", + "bower-config", + "bower-endpoint-parser", + "bower-json", + "bower-logger", + "bower-registry-client", + "cardinal", + "chalk", + "chmodr", + "configstore", + "decompress-zip", + "destroy", + "fs-write-stream-atomic", + "fstream", + "fstream-ignore", + "github", + "glob", + "graceful-fs", + "handlebars", + "inquirer", + "insight", + "is-root", + "junk", + "lockfile", + "lru-cache", + "md5-hex", + "mkdirp", + "mout", + "nopt", + "opn", + "p-throttler", + "promptly", + "q", + "request", + "request-progress", + "retry", + "rimraf", + "semver", + "shell-quote", + "stringify-object", + "tar-fs", + "tmp", + "update-notifier", + "user-home", + "which" + ], "scripts": { "test": "grunt test" }, From bfa42956063b27356c645d56333077294429e9d6 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 15 Oct 2015 12:53:18 +0200 Subject: [PATCH 0680/1021] Try to use container-based infrastructure on Travis --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 180e0395a..bee5fc3fc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ +sudo: false + env: - NODE_VERSION=0.10 - NODE_VERSION=0.11 From 140c6d963faf155577dc767af0f62cf1184325e7 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 15 Oct 2015 13:02:52 +0200 Subject: [PATCH 0681/1021] Update changelog and bump --- CHANGELOG.md | 15 ++++++++++++++- package.json | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c9808043..b2ed40521 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,24 @@ # Changelog +## 1.6.0 - 2015-10-15 + +- Shrinkwrap all dependencies and add them to bundledDependencies ([#1948](https://github.com/bower/bower/pull/1948)) +- Allow for ignoring of child dependencies ([#1394](https://github.com/bower/bower/pull/1394)) +- Allow passing `--config.resolvers` through CLI ([#1922](https://github.com/bower/bower/pull/1922)) +- Use defaults values from package.json if it exists (bower init) ([#1731](https://github.com/bower/bower/issues/1731)) +- Properly use cerificates set in .bowerrc ([#1869](https://github.com/bower/bower/pull/1869)) +- Include package name when version conflict occurs ([#1917](https://github.com/bower/bower/pull/1917)) +- Add timeout for permission check ([yeoman/insight#35](https://github.com/yeoman/insight/pull/35)) +- Close file-handles when possible. Prevents all sorts of permission issues on Windows ([0bb1536](https://github.com/bower/bower/commit/0bb1536c9972e13f3be06bea9a8619632966c664)) +- Prevent ENOENT error on Windows when in VM environment ([isaacs/chmodr#8](https://github.com/isaacs/chmodr/pull/8)) + + ## 1.5.3 - 2015-09-24 - Revert auto sorting of bower dependencies, fixes ([#1897](https://github.com/bower/bower/issues/1897)) - Fix --save-exact feature for github endpoints, fixes ([#1925](https://github.com/bower/bower/issues/1925)) - Fix `bower init` to support private flag again ([#1819](https://github.com/bower/bower/pull/1819)) -- Bump insight dependency to support prompt timeout ([#1102](https://github.com/bower/bower/issues/1102)) +- Bump insight dependency to support prompt timeout ([#1102](https://github.com/bower/bower/issues/1102)) ## 1.5.2 - 2015-08-25 diff --git a/package.json b/package.json index 547553065..cc9df1fcc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.5.3", + "version": "1.6.0", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From b261bf8a7687e0be305e332e950674107ee2fb99 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 15 Oct 2015 13:13:21 +0200 Subject: [PATCH 0682/1021] Update npm-shrinkwrap.json for bower 1.6.0 --- npm-shrinkwrap.json | 551 ++++++++++++++++++++++---------------------- 1 file changed, 276 insertions(+), 275 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index f1b3d7e18..10ccd149d 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,56 +1,56 @@ { "name": "bower", - "version": "1.5.3", + "version": "1.6.0", "dependencies": { "abbrev": { "version": "1.0.7", - "from": "abbrev@>=1.0.5 <2.0.0", + "from": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz" }, "archy": { "version": "1.0.0", - "from": "archy@1.0.0", + "from": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz" }, "bower-config": { "version": "1.2.1", - "from": "bower-config@>=1.2.1 <2.0.0", + "from": "bower-config@1.2.1", "dependencies": { "graceful-fs": { "version": "4.1.2", - "from": "graceful-fs@>=4.0.0 <5.0.0", + "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" }, "optimist": { "version": "0.6.1", - "from": "optimist@>=0.6.1 <0.7.0", + "from": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", "dependencies": { "wordwrap": { "version": "0.0.3", - "from": "wordwrap@>=0.0.2 <0.1.0", + "from": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz" }, "minimist": { "version": "0.0.10", - "from": "minimist@>=0.0.1 <0.1.0", + "from": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz" } } }, "osenv": { "version": "0.1.3", - "from": "osenv@>=0.1.3 <0.2.0", + "from": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", "dependencies": { "os-homedir": { "version": "1.0.1", - "from": "os-homedir@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" }, "os-tmpdir": { "version": "1.0.1", - "from": "os-tmpdir@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz" } } @@ -59,274 +59,275 @@ }, "bower-endpoint-parser": { "version": "0.2.2", - "from": "bower-endpoint-parser@>=0.2.2 <0.3.0", + "from": "https://registry.npmjs.org/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz", "resolved": "https://registry.npmjs.org/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz" }, "bower-json": { "version": "0.4.0", - "from": "bower-json@>=0.4.0 <0.5.0", + "from": "https://registry.npmjs.org/bower-json/-/bower-json-0.4.0.tgz", "resolved": "https://registry.npmjs.org/bower-json/-/bower-json-0.4.0.tgz", "dependencies": { "deep-extend": { "version": "0.2.11", - "from": "deep-extend@>=0.2.5 <0.3.0", + "from": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.2.11.tgz", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.2.11.tgz" }, "graceful-fs": { "version": "2.0.3", - "from": "graceful-fs@>=2.0.0 <2.1.0", + "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz" }, "intersect": { "version": "0.0.3", - "from": "intersect@>=0.0.3 <0.1.0", + "from": "https://registry.npmjs.org/intersect/-/intersect-0.0.3.tgz", "resolved": "https://registry.npmjs.org/intersect/-/intersect-0.0.3.tgz" } } }, "bower-logger": { "version": "0.2.2", - "from": "bower-logger@>=0.2.2 <0.3.0", + "from": "https://registry.npmjs.org/bower-logger/-/bower-logger-0.2.2.tgz", "resolved": "https://registry.npmjs.org/bower-logger/-/bower-logger-0.2.2.tgz" }, "bower-registry-client": { "version": "1.0.0", - "from": "bower-registry-client@>=1.0.0 <2.0.0", + "from": "bower-registry-client@1.0.0", + "resolved": "https://registry.npmjs.org/bower-registry-client/-/bower-registry-client-1.0.0.tgz", "dependencies": { "async": { "version": "0.2.10", - "from": "async@>=0.2.8 <0.3.0", + "from": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz" }, "graceful-fs": { "version": "4.1.2", - "from": "graceful-fs@>=4.0.0 <5.0.0", + "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" }, "request-replay": { "version": "0.2.0", - "from": "request-replay@>=0.2.0 <0.3.0", + "from": "https://registry.npmjs.org/request-replay/-/request-replay-0.2.0.tgz", "resolved": "https://registry.npmjs.org/request-replay/-/request-replay-0.2.0.tgz" }, "mkdirp": { "version": "0.3.5", - "from": "mkdirp@>=0.3.5 <0.4.0", + "from": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" } } }, "cardinal": { "version": "0.4.4", - "from": "cardinal@0.4.4", + "from": "https://registry.npmjs.org/cardinal/-/cardinal-0.4.4.tgz", "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-0.4.4.tgz", "dependencies": { "redeyed": { "version": "0.4.4", - "from": "redeyed@>=0.4.0 <0.5.0", + "from": "https://registry.npmjs.org/redeyed/-/redeyed-0.4.4.tgz", "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-0.4.4.tgz", "dependencies": { "esprima": { "version": "1.0.4", - "from": "esprima@>=1.0.4 <1.1.0", + "from": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz" } } }, "ansicolors": { "version": "0.2.1", - "from": "ansicolors@>=0.2.1 <0.3.0", + "from": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz", "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz" } } }, "chalk": { "version": "1.1.1", - "from": "chalk@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/chalk/-/chalk-1.1.1.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.1.tgz", "dependencies": { "ansi-styles": { "version": "2.1.0", - "from": "ansi-styles@>=2.1.0 <3.0.0", + "from": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.1.0.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.1.0.tgz" }, "escape-string-regexp": { "version": "1.0.3", - "from": "escape-string-regexp@>=1.0.2 <2.0.0", + "from": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz" }, "has-ansi": { "version": "2.0.0", - "from": "has-ansi@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "dependencies": { "ansi-regex": { "version": "2.0.0", - "from": "ansi-regex@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" } } }, "strip-ansi": { "version": "3.0.0", - "from": "strip-ansi@>=3.0.0 <4.0.0", + "from": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", "dependencies": { "ansi-regex": { "version": "2.0.0", - "from": "ansi-regex@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" } } }, "supports-color": { "version": "2.0.0", - "from": "supports-color@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" } } }, "chmodr": { "version": "1.0.2", - "from": "chmodr@>=1.0.2 <2.0.0", + "from": "https://registry.npmjs.org/chmodr/-/chmodr-1.0.2.tgz", "resolved": "https://registry.npmjs.org/chmodr/-/chmodr-1.0.2.tgz" }, "configstore": { "version": "0.3.2", - "from": "configstore@>=0.3.2 <0.4.0", + "from": "https://registry.npmjs.org/configstore/-/configstore-0.3.2.tgz", "resolved": "https://registry.npmjs.org/configstore/-/configstore-0.3.2.tgz", "dependencies": { "js-yaml": { "version": "3.4.2", - "from": "js-yaml@>=3.1.0 <4.0.0", + "from": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.2.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.2.tgz", "dependencies": { "argparse": { "version": "1.0.2", - "from": "argparse@>=1.0.2 <1.1.0", + "from": "https://registry.npmjs.org/argparse/-/argparse-1.0.2.tgz", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.2.tgz", "dependencies": { "lodash": { "version": "3.10.1", - "from": "lodash@>=3.2.0 <4.0.0", + "from": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" }, "sprintf-js": { "version": "1.0.3", - "from": "sprintf-js@>=1.0.2 <1.1.0", + "from": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" } } }, "esprima": { "version": "2.2.0", - "from": "esprima@>=2.2.0 <2.3.0", + "from": "https://registry.npmjs.org/esprima/-/esprima-2.2.0.tgz", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.2.0.tgz" } } }, "object-assign": { "version": "2.1.1", - "from": "object-assign@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz" }, "osenv": { "version": "0.1.3", - "from": "osenv@>=0.1.0 <0.2.0", + "from": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", "dependencies": { "os-homedir": { "version": "1.0.1", - "from": "os-homedir@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" }, "os-tmpdir": { "version": "1.0.1", - "from": "os-tmpdir@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz" } } }, "uuid": { "version": "2.0.1", - "from": "uuid@>=2.0.1 <3.0.0", + "from": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz" }, "xdg-basedir": { "version": "1.0.1", - "from": "xdg-basedir@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-1.0.1.tgz" } } }, "decompress-zip": { "version": "0.1.0", - "from": "decompress-zip@>=0.1.0 <0.2.0", + "from": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.1.0.tgz", "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.1.0.tgz", "dependencies": { "binary": { "version": "0.3.0", - "from": "binary@>=0.3.0 <0.4.0", + "from": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", "dependencies": { "chainsaw": { "version": "0.1.0", - "from": "chainsaw@>=0.1.0 <0.2.0", + "from": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", "dependencies": { "traverse": { "version": "0.3.9", - "from": "traverse@>=0.3.0 <0.4.0", + "from": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz" } } }, "buffers": { "version": "0.1.1", - "from": "buffers@>=0.1.1 <0.2.0", + "from": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz" } } }, "mkpath": { "version": "0.1.0", - "from": "mkpath@>=0.1.0 <0.2.0", + "from": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz", "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz" }, "readable-stream": { "version": "1.1.13", - "from": "readable-stream@>=1.1.8 <2.0.0", + "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz", "dependencies": { "core-util-is": { "version": "1.0.1", - "from": "core-util-is@>=1.0.0 <1.1.0", + "from": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" }, "isarray": { "version": "0.0.1", - "from": "isarray@0.0.1", + "from": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" }, "string_decoder": { "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0", + "from": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" }, "inherits": { "version": "2.0.1", - "from": "inherits@>=2.0.1 <2.1.0", + "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" } } }, "touch": { "version": "0.0.3", - "from": "touch@0.0.3", + "from": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz", "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz", "dependencies": { "nopt": { "version": "1.0.10", - "from": "nopt@>=1.0.10 <1.1.0", + "from": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz" } } @@ -335,66 +336,66 @@ }, "destroy": { "version": "1.0.3", - "from": "destroy@*", + "from": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz" }, "fs-write-stream-atomic": { "version": "1.0.4", - "from": "fs-write-stream-atomic@*", + "from": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.4.tgz", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.4.tgz", "dependencies": { "graceful-fs": { "version": "4.1.2", - "from": "graceful-fs@>=4.1.2 <5.0.0", + "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" } } }, "fstream": { "version": "1.0.8", - "from": "fstream@>=1.0.3 <2.0.0", + "from": "https://registry.npmjs.org/fstream/-/fstream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.8.tgz", "dependencies": { "graceful-fs": { "version": "4.1.2", - "from": "graceful-fs@>=4.1.2 <5.0.0", + "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" }, "inherits": { "version": "2.0.1", - "from": "inherits@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" } } }, "fstream-ignore": { "version": "1.0.2", - "from": "fstream-ignore@>=1.0.2 <2.0.0", + "from": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.2.tgz", "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.2.tgz", "dependencies": { "inherits": { "version": "2.0.1", - "from": "inherits@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, "minimatch": { "version": "2.0.10", - "from": "minimatch@>=2.0.1 <3.0.0", + "from": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", "dependencies": { "brace-expansion": { "version": "1.1.1", - "from": "brace-expansion@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", "dependencies": { "balanced-match": { "version": "0.2.0", - "from": "balanced-match@>=0.2.0 <0.3.0", + "from": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" }, "concat-map": { "version": "0.0.1", - "from": "concat-map@0.0.1", + "from": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" } } @@ -405,56 +406,56 @@ }, "github": { "version": "0.2.4", - "from": "github@>=0.2.3 <0.3.0", + "from": "https://registry.npmjs.org/github/-/github-0.2.4.tgz", "resolved": "https://registry.npmjs.org/github/-/github-0.2.4.tgz", "dependencies": { "mime": { "version": "1.3.4", - "from": "mime@>=1.2.11 <2.0.0", + "from": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz" } } }, "glob": { "version": "4.5.3", - "from": "glob@>=4.3.2 <5.0.0", + "from": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", "dependencies": { "inflight": { "version": "1.0.4", - "from": "inflight@>=1.0.4 <2.0.0", + "from": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "wrappy@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } }, "inherits": { "version": "2.0.1", - "from": "inherits@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, "minimatch": { "version": "2.0.10", - "from": "minimatch@>=2.0.1 <3.0.0", + "from": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", "dependencies": { "brace-expansion": { "version": "1.1.1", - "from": "brace-expansion@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", "dependencies": { "balanced-match": { "version": "0.2.0", - "from": "balanced-match@>=0.2.0 <0.3.0", + "from": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" }, "concat-map": { "version": "0.0.1", - "from": "concat-map@0.0.1", + "from": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" } } @@ -463,12 +464,12 @@ }, "once": { "version": "1.3.2", - "from": "once@>=1.3.0 <2.0.0", + "from": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "wrappy@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } @@ -477,44 +478,44 @@ }, "graceful-fs": { "version": "3.0.8", - "from": "graceful-fs@>=3.0.5 <4.0.0", + "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.8.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.8.tgz" }, "handlebars": { "version": "2.0.0", - "from": "handlebars@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/handlebars/-/handlebars-2.0.0.tgz", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-2.0.0.tgz", "dependencies": { "optimist": { "version": "0.3.7", - "from": "optimist@>=0.3.0 <0.4.0", + "from": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", "dependencies": { "wordwrap": { "version": "0.0.3", - "from": "wordwrap@>=0.0.2 <0.1.0", + "from": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz" } } }, "uglify-js": { "version": "2.3.6", - "from": "uglify-js@>=2.3.0 <2.4.0", + "from": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.6.tgz", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.6.tgz", "dependencies": { "async": { "version": "0.2.10", - "from": "async@>=0.2.6 <0.3.0", + "from": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz" }, "source-map": { "version": "0.1.43", - "from": "source-map@>=0.1.7 <0.2.0", + "from": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", "dependencies": { "amdefine": { "version": "1.0.0", - "from": "amdefine@>=0.0.4", + "from": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz" } } @@ -525,37 +526,37 @@ }, "inquirer": { "version": "0.10.0", - "from": "inquirer@0.10.0", + "from": "https://registry.npmjs.org/inquirer/-/inquirer-0.10.0.tgz", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.10.0.tgz", "dependencies": { "ansi-escapes": { "version": "1.1.0", - "from": "ansi-escapes@>=1.1.0 <2.0.0", + "from": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.1.0.tgz", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.1.0.tgz" }, "ansi-regex": { "version": "2.0.0", - "from": "ansi-regex@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" }, "cli-cursor": { "version": "1.0.2", - "from": "cli-cursor@>=1.0.1 <2.0.0", + "from": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", "dependencies": { "restore-cursor": { "version": "1.0.1", - "from": "restore-cursor@>=1.0.1 <2.0.0", + "from": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", "dependencies": { "exit-hook": { "version": "1.1.1", - "from": "exit-hook@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz" }, "onetime": { "version": "1.0.0", - "from": "onetime@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/onetime/-/onetime-1.0.0.tgz", "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.0.0.tgz" } } @@ -564,68 +565,68 @@ }, "cli-width": { "version": "1.0.1", - "from": "cli-width@>=1.0.1 <2.0.0", + "from": "https://registry.npmjs.org/cli-width/-/cli-width-1.0.1.tgz", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.0.1.tgz" }, "figures": { "version": "1.4.0", - "from": "figures@>=1.3.5 <2.0.0", + "from": "https://registry.npmjs.org/figures/-/figures-1.4.0.tgz", "resolved": "https://registry.npmjs.org/figures/-/figures-1.4.0.tgz" }, "lodash": { "version": "3.10.1", - "from": "lodash@>=3.3.1 <4.0.0", + "from": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" }, "readline2": { "version": "1.0.1", - "from": "readline2@>=1.0.1 <2.0.0", + "from": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", "dependencies": { "code-point-at": { "version": "1.0.0", - "from": "code-point-at@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.0.0.tgz", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.0.0.tgz", "dependencies": { "number-is-nan": { "version": "1.0.0", - "from": "number-is-nan@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz" } } }, "is-fullwidth-code-point": { "version": "1.0.0", - "from": "is-fullwidth-code-point@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "dependencies": { "number-is-nan": { "version": "1.0.0", - "from": "number-is-nan@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz" } } }, "mute-stream": { "version": "0.0.5", - "from": "mute-stream@0.0.5", + "from": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz" } } }, "run-async": { "version": "0.1.0", - "from": "run-async@>=0.1.0 <0.2.0", + "from": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", "dependencies": { "once": { "version": "1.3.2", - "from": "once@>=1.3.0 <2.0.0", + "from": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "wrappy@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } @@ -634,88 +635,88 @@ }, "rx-lite": { "version": "3.1.2", - "from": "rx-lite@>=3.1.2 <4.0.0", + "from": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz" }, "strip-ansi": { "version": "3.0.0", - "from": "strip-ansi@>=3.0.0 <4.0.0", + "from": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz" }, "through": { "version": "2.3.8", - "from": "through@>=2.3.6 <3.0.0", + "from": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz" } } }, "insight": { "version": "0.7.0", - "from": "insight@>=0.7.0 <0.8.0", + "from": "https://registry.npmjs.org/insight/-/insight-0.7.0.tgz", "resolved": "https://registry.npmjs.org/insight/-/insight-0.7.0.tgz", "dependencies": { "async": { "version": "1.4.2", - "from": "async@>=1.4.2 <2.0.0", + "from": "https://registry.npmjs.org/async/-/async-1.4.2.tgz", "resolved": "https://registry.npmjs.org/async/-/async-1.4.2.tgz" }, "configstore": { "version": "1.2.1", - "from": "configstore@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/configstore/-/configstore-1.2.1.tgz", "resolved": "https://registry.npmjs.org/configstore/-/configstore-1.2.1.tgz", "dependencies": { "graceful-fs": { "version": "4.1.2", - "from": "graceful-fs@>=4.1.2 <5.0.0", + "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" }, "object-assign": { "version": "3.0.0", - "from": "object-assign@>=3.0.0 <4.0.0", + "from": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz" }, "os-tmpdir": { "version": "1.0.1", - "from": "os-tmpdir@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz" }, "osenv": { "version": "0.1.3", - "from": "osenv@>=0.1.0 <0.2.0", + "from": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", "dependencies": { "os-homedir": { "version": "1.0.1", - "from": "os-homedir@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" } } }, "uuid": { "version": "2.0.1", - "from": "uuid@>=2.0.1 <3.0.0", + "from": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz" }, "write-file-atomic": { "version": "1.1.3", - "from": "write-file-atomic@>=1.1.2 <2.0.0", + "from": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.1.3.tgz", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.1.3.tgz", "dependencies": { "slide": { "version": "1.1.6", - "from": "slide@>=1.1.5 <2.0.0", + "from": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz" } } }, "xdg-basedir": { "version": "2.0.0", - "from": "xdg-basedir@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", "dependencies": { "os-homedir": { "version": "1.0.1", - "from": "os-homedir@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" } } @@ -724,46 +725,46 @@ }, "lodash.debounce": { "version": "3.1.1", - "from": "lodash.debounce@>=3.0.1 <4.0.0", + "from": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-3.1.1.tgz", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-3.1.1.tgz", "dependencies": { "lodash._getnative": { "version": "3.9.1", - "from": "lodash._getnative@>=3.0.0 <4.0.0", + "from": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz" } } }, "object-assign": { "version": "4.0.1", - "from": "object-assign@>=4.0.1 <5.0.0", + "from": "https://registry.npmjs.org/object-assign/-/object-assign-4.0.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.0.1.tgz" }, "os-name": { "version": "1.0.3", - "from": "os-name@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/os-name/-/os-name-1.0.3.tgz", "resolved": "https://registry.npmjs.org/os-name/-/os-name-1.0.3.tgz", "dependencies": { "osx-release": { "version": "1.1.0", - "from": "osx-release@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/osx-release/-/osx-release-1.1.0.tgz", "resolved": "https://registry.npmjs.org/osx-release/-/osx-release-1.1.0.tgz", "dependencies": { "minimist": { "version": "1.2.0", - "from": "minimist@>=1.1.0 <2.0.0", + "from": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" } } }, "win-release": { "version": "1.1.1", - "from": "win-release@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz", "resolved": "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz", "dependencies": { "semver": { "version": "5.0.3", - "from": "semver@>=5.0.1 <6.0.0", + "from": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz" } } @@ -772,95 +773,95 @@ }, "tough-cookie": { "version": "2.0.0", - "from": "tough-cookie@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz" } } }, "is-root": { "version": "1.0.0", - "from": "is-root@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/is-root/-/is-root-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-root/-/is-root-1.0.0.tgz" }, "junk": { "version": "1.0.2", - "from": "junk@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/junk/-/junk-1.0.2.tgz", "resolved": "https://registry.npmjs.org/junk/-/junk-1.0.2.tgz" }, "lockfile": { "version": "1.0.1", - "from": "lockfile@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.1.tgz", "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.1.tgz" }, "lru-cache": { "version": "2.7.0", - "from": "lru-cache@>=2.5.0 <3.0.0", + "from": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.0.tgz", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.0.tgz" }, "md5-hex": { "version": "1.1.0", - "from": "md5-hex@>=1.0.2 <2.0.0", + "from": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.1.0.tgz", "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.1.0.tgz", "dependencies": { "md5-o-matic": { "version": "0.1.1", - "from": "md5-o-matic@>=0.1.1 <0.2.0", + "from": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz", "resolved": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz" } } }, "mkdirp": { "version": "0.5.0", - "from": "mkdirp@0.5.0", + "from": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", "dependencies": { "minimist": { "version": "0.0.8", - "from": "minimist@0.0.8", + "from": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" } } }, "mout": { "version": "0.11.0", - "from": "mout@>=0.11.0 <0.12.0", + "from": "https://registry.npmjs.org/mout/-/mout-0.11.0.tgz", "resolved": "https://registry.npmjs.org/mout/-/mout-0.11.0.tgz" }, "nopt": { "version": "3.0.4", - "from": "nopt@>=3.0.1 <4.0.0", + "from": "https://registry.npmjs.org/nopt/-/nopt-3.0.4.tgz", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.4.tgz" }, "opn": { "version": "1.0.2", - "from": "opn@>=1.0.1 <2.0.0", + "from": "https://registry.npmjs.org/opn/-/opn-1.0.2.tgz", "resolved": "https://registry.npmjs.org/opn/-/opn-1.0.2.tgz" }, "p-throttler": { "version": "0.1.1", - "from": "p-throttler@0.1.1", + "from": "https://registry.npmjs.org/p-throttler/-/p-throttler-0.1.1.tgz", "resolved": "https://registry.npmjs.org/p-throttler/-/p-throttler-0.1.1.tgz", "dependencies": { "q": { "version": "0.9.7", - "from": "q@>=0.9.2 <0.10.0", + "from": "https://registry.npmjs.org/q/-/q-0.9.7.tgz", "resolved": "https://registry.npmjs.org/q/-/q-0.9.7.tgz" } } }, "promptly": { "version": "0.2.0", - "from": "promptly@0.2.0", + "from": "https://registry.npmjs.org/promptly/-/promptly-0.2.0.tgz", "resolved": "https://registry.npmjs.org/promptly/-/promptly-0.2.0.tgz", "dependencies": { "read": { "version": "1.0.7", - "from": "read@>=1.0.4 <1.1.0", + "from": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", "dependencies": { "mute-stream": { "version": "0.0.5", - "from": "mute-stream@>=0.0.4 <0.1.0", + "from": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz" } } @@ -869,42 +870,42 @@ }, "q": { "version": "1.4.1", - "from": "q@>=1.1.2 <2.0.0", + "from": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz" }, "request": { "version": "2.53.0", - "from": "request@2.53.0", + "from": "https://registry.npmjs.org/request/-/request-2.53.0.tgz", "resolved": "https://registry.npmjs.org/request/-/request-2.53.0.tgz", "dependencies": { "bl": { "version": "0.9.4", - "from": "bl@>=0.9.0 <0.10.0", + "from": "https://registry.npmjs.org/bl/-/bl-0.9.4.tgz", "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.4.tgz", "dependencies": { "readable-stream": { "version": "1.0.33", - "from": "readable-stream@>=1.0.26 <1.1.0", + "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", "dependencies": { "core-util-is": { "version": "1.0.1", - "from": "core-util-is@>=1.0.0 <1.1.0", + "from": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" }, "isarray": { "version": "0.0.1", - "from": "isarray@0.0.1", + "from": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" }, "string_decoder": { "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0", + "from": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" }, "inherits": { "version": "2.0.1", - "from": "inherits@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" } } @@ -913,66 +914,66 @@ }, "caseless": { "version": "0.9.0", - "from": "caseless@>=0.9.0 <0.10.0", + "from": "https://registry.npmjs.org/caseless/-/caseless-0.9.0.tgz", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.9.0.tgz" }, "forever-agent": { "version": "0.5.2", - "from": "forever-agent@>=0.5.0 <0.6.0", + "from": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz" }, "form-data": { "version": "0.2.0", - "from": "form-data@>=0.2.0 <0.3.0", + "from": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz", "dependencies": { "async": { "version": "0.9.2", - "from": "async@>=0.9.0 <0.10.0", + "from": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz" } } }, "json-stringify-safe": { "version": "5.0.1", - "from": "json-stringify-safe@>=5.0.0 <5.1.0", + "from": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" }, "mime-types": { "version": "2.0.14", - "from": "mime-types@>=2.0.1 <2.1.0", + "from": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", "dependencies": { "mime-db": { "version": "1.12.0", - "from": "mime-db@>=1.12.0 <1.13.0", + "from": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz" } } }, "qs": { "version": "2.3.3", - "from": "qs@>=2.3.1 <2.4.0", + "from": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz" }, "tunnel-agent": { "version": "0.4.1", - "from": "tunnel-agent@>=0.4.0 <0.5.0", + "from": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.1.tgz", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.1.tgz" }, "tough-cookie": { "version": "2.0.0", - "from": "tough-cookie@>=0.12.0", + "from": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz" }, "http-signature": { "version": "0.10.1", - "from": "http-signature@>=0.10.0 <0.11.0", + "from": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", "dependencies": { "assert-plus": { "version": "0.1.5", - "from": "assert-plus@>=0.1.5 <0.2.0", + "from": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz" }, "asn1": { @@ -982,134 +983,134 @@ }, "ctype": { "version": "0.5.3", - "from": "ctype@0.5.3", + "from": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz" } } }, "oauth-sign": { "version": "0.6.0", - "from": "oauth-sign@>=0.6.0 <0.7.0", + "from": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz" }, "hawk": { "version": "2.3.1", - "from": "hawk@>=2.3.0 <2.4.0", + "from": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz", "resolved": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz", "dependencies": { "hoek": { "version": "2.16.3", - "from": "hoek@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz" }, "boom": { "version": "2.9.0", - "from": "boom@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/boom/-/boom-2.9.0.tgz", "resolved": "https://registry.npmjs.org/boom/-/boom-2.9.0.tgz" }, "cryptiles": { "version": "2.0.5", - "from": "cryptiles@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz" }, "sntp": { "version": "1.0.9", - "from": "sntp@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz" } } }, "aws-sign2": { "version": "0.5.0", - "from": "aws-sign2@>=0.5.0 <0.6.0", + "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" }, "stringstream": { "version": "0.0.4", - "from": "stringstream@>=0.0.4 <0.1.0", + "from": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.4.tgz", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.4.tgz" }, "combined-stream": { "version": "0.0.7", - "from": "combined-stream@>=0.0.5 <0.1.0", + "from": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", "dependencies": { "delayed-stream": { "version": "0.0.5", - "from": "delayed-stream@0.0.5", + "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" } } }, "isstream": { "version": "0.1.2", - "from": "isstream@>=0.1.1 <0.2.0", + "from": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" } } }, "request-progress": { "version": "0.3.1", - "from": "request-progress@0.3.1", + "from": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", "dependencies": { "throttleit": { "version": "0.0.2", - "from": "throttleit@>=0.0.2 <0.1.0", + "from": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz" } } }, "retry": { "version": "0.6.1", - "from": "retry@0.6.1", + "from": "https://registry.npmjs.org/retry/-/retry-0.6.1.tgz", "resolved": "https://registry.npmjs.org/retry/-/retry-0.6.1.tgz" }, "rimraf": { "version": "2.4.3", - "from": "rimraf@>=2.2.8 <3.0.0", + "from": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.3.tgz", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.3.tgz", "dependencies": { "glob": { "version": "5.0.15", - "from": "glob@>=5.0.14 <6.0.0", + "from": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "dependencies": { "inflight": { "version": "1.0.4", - "from": "inflight@>=1.0.4 <2.0.0", + "from": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "wrappy@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } }, "inherits": { "version": "2.0.1", - "from": "inherits@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, "minimatch": { "version": "3.0.0", - "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0", + "from": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.0.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.0.tgz", "dependencies": { "brace-expansion": { "version": "1.1.1", - "from": "brace-expansion@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", "dependencies": { "balanced-match": { "version": "0.2.0", - "from": "balanced-match@>=0.2.0 <0.3.0", + "from": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" }, "concat-map": { "version": "0.0.1", - "from": "concat-map@0.0.1", + "from": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" } } @@ -1118,19 +1119,19 @@ }, "once": { "version": "1.3.2", - "from": "once@>=1.3.0 <2.0.0", + "from": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "wrappy@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } }, "path-is-absolute": { "version": "1.0.0", - "from": "path-is-absolute@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz" } } @@ -1139,64 +1140,64 @@ }, "semver": { "version": "2.3.2", - "from": "semver@>=2.3.0 <3.0.0", + "from": "https://registry.npmjs.org/semver/-/semver-2.3.2.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-2.3.2.tgz" }, "shell-quote": { "version": "1.4.3", - "from": "shell-quote@>=1.4.2 <2.0.0", + "from": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.4.3.tgz", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.4.3.tgz", "dependencies": { "jsonify": { "version": "0.0.0", - "from": "jsonify@>=0.0.0 <0.1.0", + "from": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz" }, "array-filter": { "version": "0.0.1", - "from": "array-filter@>=0.0.0 <0.1.0", + "from": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz" }, "array-reduce": { "version": "0.0.0", - "from": "array-reduce@>=0.0.0 <0.1.0", + "from": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz" }, "array-map": { "version": "0.0.0", - "from": "array-map@>=0.0.0 <0.1.0", + "from": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz" } } }, "stringify-object": { "version": "1.0.1", - "from": "stringify-object@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/stringify-object/-/stringify-object-1.0.1.tgz", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-1.0.1.tgz" }, "tar-fs": { "version": "1.8.1", - "from": "tar-fs@>=1.4.1 <2.0.0", + "from": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.8.1.tgz", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.8.1.tgz", "dependencies": { "pump": { "version": "1.0.0", - "from": "pump@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/pump/-/pump-1.0.0.tgz", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.0.tgz", "dependencies": { "end-of-stream": { "version": "1.1.0", - "from": "end-of-stream@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz" }, "once": { "version": "1.3.2", - "from": "once@>=1.3.1 <2.0.0", + "from": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "wrappy@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } @@ -1205,27 +1206,27 @@ }, "tar-stream": { "version": "1.2.1", - "from": "tar-stream@>=1.1.2 <2.0.0", + "from": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.2.1.tgz", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.2.1.tgz", "dependencies": { "bl": { "version": "1.0.0", - "from": "bl@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/bl/-/bl-1.0.0.tgz", "resolved": "https://registry.npmjs.org/bl/-/bl-1.0.0.tgz" }, "end-of-stream": { "version": "1.1.0", - "from": "end-of-stream@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz", "dependencies": { "once": { "version": "1.3.2", - "from": "once@>=1.3.0 <1.4.0", + "from": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "wrappy@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } @@ -1234,44 +1235,44 @@ }, "readable-stream": { "version": "2.0.2", - "from": "readable-stream@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", "dependencies": { "core-util-is": { "version": "1.0.1", - "from": "core-util-is@>=1.0.0 <1.1.0", + "from": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" }, "inherits": { "version": "2.0.1", - "from": "inherits@>=2.0.1 <2.1.0", + "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, "isarray": { "version": "0.0.1", - "from": "isarray@0.0.1", + "from": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" }, "process-nextick-args": { "version": "1.0.3", - "from": "process-nextick-args@>=1.0.0 <1.1.0", + "from": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz" }, "string_decoder": { "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0", + "from": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" }, "util-deprecate": { "version": "1.0.1", - "from": "util-deprecate@>=1.0.1 <1.1.0", + "from": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz" } } }, "xtend": { "version": "4.0.0", - "from": "xtend@>=4.0.0 <5.0.0", + "from": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz" } } @@ -1280,52 +1281,52 @@ }, "tmp": { "version": "0.0.24", - "from": "tmp@0.0.24", + "from": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz" }, "update-notifier": { "version": "0.3.2", - "from": "update-notifier@>=0.3.0 <0.4.0", + "from": "https://registry.npmjs.org/update-notifier/-/update-notifier-0.3.2.tgz", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-0.3.2.tgz", "dependencies": { "is-npm": { "version": "1.0.0", - "from": "is-npm@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz" }, "latest-version": { "version": "1.0.1", - "from": "latest-version@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/latest-version/-/latest-version-1.0.1.tgz", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-1.0.1.tgz", "dependencies": { "package-json": { "version": "1.2.0", - "from": "package-json@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/package-json/-/package-json-1.2.0.tgz", "resolved": "https://registry.npmjs.org/package-json/-/package-json-1.2.0.tgz", "dependencies": { "got": { "version": "3.3.1", - "from": "got@>=3.2.0 <4.0.0", + "from": "https://registry.npmjs.org/got/-/got-3.3.1.tgz", "resolved": "https://registry.npmjs.org/got/-/got-3.3.1.tgz", "dependencies": { "duplexify": { "version": "3.4.2", - "from": "duplexify@>=3.2.0 <4.0.0", + "from": "https://registry.npmjs.org/duplexify/-/duplexify-3.4.2.tgz", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.4.2.tgz", "dependencies": { "end-of-stream": { "version": "1.0.0", - "from": "end-of-stream@1.0.0", + "from": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz", "dependencies": { "once": { "version": "1.3.2", - "from": "once@>=1.3.0 <1.4.0", + "from": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "wrappy@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } @@ -1334,37 +1335,37 @@ }, "readable-stream": { "version": "2.0.2", - "from": "readable-stream@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", "dependencies": { "core-util-is": { "version": "1.0.1", - "from": "core-util-is@>=1.0.0 <1.1.0", + "from": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" }, "inherits": { "version": "2.0.1", - "from": "inherits@>=2.0.1 <2.1.0", + "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, "isarray": { "version": "0.0.1", - "from": "isarray@0.0.1", + "from": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" }, "process-nextick-args": { "version": "1.0.3", - "from": "process-nextick-args@>=1.0.0 <1.1.0", + "from": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz" }, "string_decoder": { "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0", + "from": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" }, "util-deprecate": { "version": "1.0.1", - "from": "util-deprecate@>=1.0.1 <1.1.0", + "from": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz" } } @@ -1373,96 +1374,96 @@ }, "infinity-agent": { "version": "2.0.3", - "from": "infinity-agent@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/infinity-agent/-/infinity-agent-2.0.3.tgz", "resolved": "https://registry.npmjs.org/infinity-agent/-/infinity-agent-2.0.3.tgz" }, "is-redirect": { "version": "1.0.0", - "from": "is-redirect@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz" }, "is-stream": { "version": "1.0.1", - "from": "is-stream@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/is-stream/-/is-stream-1.0.1.tgz", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.0.1.tgz" }, "lowercase-keys": { "version": "1.0.0", - "from": "lowercase-keys@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz" }, "nested-error-stacks": { "version": "1.0.1", - "from": "nested-error-stacks@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-1.0.1.tgz", "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-1.0.1.tgz", "dependencies": { "inherits": { "version": "2.0.1", - "from": "inherits@>=2.0.1 <2.1.0", + "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" } } }, "object-assign": { "version": "3.0.0", - "from": "object-assign@>=3.0.0 <4.0.0", + "from": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz" }, "prepend-http": { "version": "1.0.3", - "from": "prepend-http@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.3.tgz", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.3.tgz" }, "read-all-stream": { "version": "3.0.1", - "from": "read-all-stream@>=3.0.0 <4.0.0", + "from": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.0.1.tgz", "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.0.1.tgz", "dependencies": { "pinkie-promise": { "version": "1.0.0", - "from": "pinkie-promise@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz", "dependencies": { "pinkie": { "version": "1.0.0", - "from": "pinkie@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz" } } }, "readable-stream": { "version": "2.0.2", - "from": "readable-stream@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", "dependencies": { "core-util-is": { "version": "1.0.1", - "from": "core-util-is@>=1.0.0 <1.1.0", + "from": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" }, "inherits": { "version": "2.0.1", - "from": "inherits@>=2.0.1 <2.1.0", + "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, "isarray": { "version": "0.0.1", - "from": "isarray@0.0.1", + "from": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" }, "process-nextick-args": { "version": "1.0.3", - "from": "process-nextick-args@>=1.0.0 <1.1.0", + "from": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz" }, "string_decoder": { "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0", + "from": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" }, "util-deprecate": { "version": "1.0.1", - "from": "util-deprecate@>=1.0.1 <1.1.0", + "from": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz" } } @@ -1471,39 +1472,39 @@ }, "timed-out": { "version": "2.0.0", - "from": "timed-out@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz" } } }, "registry-url": { "version": "3.0.3", - "from": "registry-url@>=3.0.0 <4.0.0", + "from": "https://registry.npmjs.org/registry-url/-/registry-url-3.0.3.tgz", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.0.3.tgz", "dependencies": { "rc": { "version": "1.1.1", - "from": "rc@>=1.0.1 <2.0.0", + "from": "https://registry.npmjs.org/rc/-/rc-1.1.1.tgz", "resolved": "https://registry.npmjs.org/rc/-/rc-1.1.1.tgz", "dependencies": { "minimist": { "version": "1.2.0", - "from": "minimist@>=1.1.2 <2.0.0", + "from": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" }, "deep-extend": { "version": "0.2.11", - "from": "deep-extend@>=0.2.5 <0.3.0", + "from": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.2.11.tgz", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.2.11.tgz" }, "strip-json-comments": { "version": "0.1.3", - "from": "strip-json-comments@>=0.1.0 <0.2.0", + "from": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-0.1.3.tgz", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-0.1.3.tgz" }, "ini": { "version": "1.3.4", - "from": "ini@>=1.3.0 <1.4.0", + "from": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz" } } @@ -1516,29 +1517,29 @@ }, "semver-diff": { "version": "2.0.0", - "from": "semver-diff@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.0.0.tgz", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.0.0.tgz", "dependencies": { "semver": { "version": "4.3.6", - "from": "semver@>=4.0.0 <5.0.0", + "from": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz" } } }, "string-length": { "version": "1.0.1", - "from": "string-length@>=1.0.0 <2.0.0", + "from": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", "dependencies": { "strip-ansi": { "version": "3.0.0", - "from": "strip-ansi@>=3.0.0 <4.0.0", + "from": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", "dependencies": { "ansi-regex": { "version": "2.0.0", - "from": "ansi-regex@>=2.0.0 <3.0.0", + "from": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" } } @@ -1549,22 +1550,22 @@ }, "user-home": { "version": "1.1.1", - "from": "user-home@>=1.1.0 <2.0.0", + "from": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz" }, "which": { "version": "1.1.2", - "from": "which@>=1.0.8 <2.0.0", + "from": "https://registry.npmjs.org/which/-/which-1.1.2.tgz", "resolved": "https://registry.npmjs.org/which/-/which-1.1.2.tgz", "dependencies": { "is-absolute": { "version": "0.1.7", - "from": "is-absolute@>=0.1.7 <0.2.0", + "from": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz", "dependencies": { "is-relative": { "version": "0.1.3", - "from": "is-relative@>=0.1.0 <0.2.0", + "from": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz" } } From 2311d7dc44723c41924bc1c003ce3f885899a548 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 15 Oct 2015 13:29:56 +0200 Subject: [PATCH 0683/1021] Update npm-shrinkwrap.json with npm-shrinkwrap tool --- npm-shrinkwrap.json | 477 ++++++++++---------------------------------- package.json | 1 + 2 files changed, 103 insertions(+), 375 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 10ccd149d..bfc9bcd2b 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,56 +1,48 @@ { "name": "bower", "version": "1.6.0", + "npm-shrinkwrap-version": "5.4.1", "dependencies": { "abbrev": { "version": "1.0.7", - "from": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz" }, "archy": { "version": "1.0.0", - "from": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz" }, "bower-config": { "version": "1.2.1", - "from": "bower-config@1.2.1", + "resolved": "https://registry.npmjs.org/bower-config/-/bower-config-1.2.1.tgz", "dependencies": { "graceful-fs": { "version": "4.1.2", - "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" }, "optimist": { "version": "0.6.1", - "from": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", "dependencies": { - "wordwrap": { - "version": "0.0.3", - "from": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz" - }, "minimist": { "version": "0.0.10", - "from": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz" + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz" } } }, "osenv": { "version": "0.1.3", - "from": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", "dependencies": { "os-homedir": { "version": "1.0.1", - "from": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" }, "os-tmpdir": { "version": "1.0.1", - "from": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz" } } @@ -59,275 +51,226 @@ }, "bower-endpoint-parser": { "version": "0.2.2", - "from": "https://registry.npmjs.org/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz", "resolved": "https://registry.npmjs.org/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz" }, "bower-json": { "version": "0.4.0", - "from": "https://registry.npmjs.org/bower-json/-/bower-json-0.4.0.tgz", "resolved": "https://registry.npmjs.org/bower-json/-/bower-json-0.4.0.tgz", "dependencies": { "deep-extend": { "version": "0.2.11", - "from": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.2.11.tgz", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.2.11.tgz" }, "graceful-fs": { "version": "2.0.3", - "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz" }, "intersect": { "version": "0.0.3", - "from": "https://registry.npmjs.org/intersect/-/intersect-0.0.3.tgz", "resolved": "https://registry.npmjs.org/intersect/-/intersect-0.0.3.tgz" } } }, "bower-logger": { "version": "0.2.2", - "from": "https://registry.npmjs.org/bower-logger/-/bower-logger-0.2.2.tgz", "resolved": "https://registry.npmjs.org/bower-logger/-/bower-logger-0.2.2.tgz" }, "bower-registry-client": { "version": "1.0.0", - "from": "bower-registry-client@1.0.0", "resolved": "https://registry.npmjs.org/bower-registry-client/-/bower-registry-client-1.0.0.tgz", "dependencies": { "async": { "version": "0.2.10", - "from": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz" }, "graceful-fs": { "version": "4.1.2", - "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" }, - "request-replay": { - "version": "0.2.0", - "from": "https://registry.npmjs.org/request-replay/-/request-replay-0.2.0.tgz", - "resolved": "https://registry.npmjs.org/request-replay/-/request-replay-0.2.0.tgz" - }, "mkdirp": { "version": "0.3.5", - "from": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" + }, + "request-replay": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/request-replay/-/request-replay-0.2.0.tgz" } } }, "cardinal": { "version": "0.4.4", - "from": "https://registry.npmjs.org/cardinal/-/cardinal-0.4.4.tgz", "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-0.4.4.tgz", "dependencies": { + "ansicolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz" + }, "redeyed": { "version": "0.4.4", - "from": "https://registry.npmjs.org/redeyed/-/redeyed-0.4.4.tgz", "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-0.4.4.tgz", "dependencies": { "esprima": { "version": "1.0.4", - "from": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz" } } - }, - "ansicolors": { - "version": "0.2.1", - "from": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz" } } }, "chalk": { "version": "1.1.1", - "from": "https://registry.npmjs.org/chalk/-/chalk-1.1.1.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.1.tgz", "dependencies": { "ansi-styles": { "version": "2.1.0", - "from": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.1.0.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.1.0.tgz" }, "escape-string-regexp": { "version": "1.0.3", - "from": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz" }, "has-ansi": { "version": "2.0.0", - "from": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "dependencies": { "ansi-regex": { "version": "2.0.0", - "from": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" } } }, "strip-ansi": { "version": "3.0.0", - "from": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", "dependencies": { "ansi-regex": { "version": "2.0.0", - "from": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" } } }, "supports-color": { "version": "2.0.0", - "from": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" } } }, "chmodr": { "version": "1.0.2", - "from": "https://registry.npmjs.org/chmodr/-/chmodr-1.0.2.tgz", "resolved": "https://registry.npmjs.org/chmodr/-/chmodr-1.0.2.tgz" }, "configstore": { "version": "0.3.2", - "from": "https://registry.npmjs.org/configstore/-/configstore-0.3.2.tgz", "resolved": "https://registry.npmjs.org/configstore/-/configstore-0.3.2.tgz", "dependencies": { "js-yaml": { "version": "3.4.2", - "from": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.2.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.2.tgz", "dependencies": { "argparse": { "version": "1.0.2", - "from": "https://registry.npmjs.org/argparse/-/argparse-1.0.2.tgz", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.2.tgz", "dependencies": { "lodash": { "version": "3.10.1", - "from": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" }, "sprintf-js": { "version": "1.0.3", - "from": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" } } }, "esprima": { "version": "2.2.0", - "from": "https://registry.npmjs.org/esprima/-/esprima-2.2.0.tgz", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.2.0.tgz" } } }, "object-assign": { "version": "2.1.1", - "from": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz" }, "osenv": { "version": "0.1.3", - "from": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", "dependencies": { "os-homedir": { "version": "1.0.1", - "from": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" }, "os-tmpdir": { "version": "1.0.1", - "from": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz" } } }, "uuid": { "version": "2.0.1", - "from": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz" }, "xdg-basedir": { "version": "1.0.1", - "from": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-1.0.1.tgz" } } }, "decompress-zip": { "version": "0.1.0", - "from": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.1.0.tgz", "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.1.0.tgz", "dependencies": { "binary": { "version": "0.3.0", - "from": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", "dependencies": { + "buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz" + }, "chainsaw": { "version": "0.1.0", - "from": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", "dependencies": { "traverse": { "version": "0.3.9", - "from": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz" } } - }, - "buffers": { - "version": "0.1.1", - "from": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", - "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz" } } }, "mkpath": { "version": "0.1.0", - "from": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz", "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz" }, "readable-stream": { "version": "1.1.13", - "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz", "dependencies": { "core-util-is": { "version": "1.0.1", - "from": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" }, + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, "isarray": { "version": "0.0.1", - "from": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" }, "string_decoder": { "version": "0.10.31", - "from": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - }, - "inherits": { - "version": "2.0.1", - "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" } } }, "touch": { "version": "0.0.3", - "from": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz", "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz", "dependencies": { "nopt": { "version": "1.0.10", - "from": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz" } } @@ -336,66 +279,54 @@ }, "destroy": { "version": "1.0.3", - "from": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz" }, "fs-write-stream-atomic": { "version": "1.0.4", - "from": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.4.tgz", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.4.tgz", "dependencies": { "graceful-fs": { "version": "4.1.2", - "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" } } }, "fstream": { "version": "1.0.8", - "from": "https://registry.npmjs.org/fstream/-/fstream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.8.tgz", "dependencies": { "graceful-fs": { "version": "4.1.2", - "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" }, "inherits": { "version": "2.0.1", - "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" } } }, "fstream-ignore": { "version": "1.0.2", - "from": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.2.tgz", "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.2.tgz", "dependencies": { "inherits": { "version": "2.0.1", - "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, "minimatch": { "version": "2.0.10", - "from": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", "dependencies": { "brace-expansion": { "version": "1.1.1", - "from": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", "dependencies": { "balanced-match": { "version": "0.2.0", - "from": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" }, "concat-map": { "version": "0.0.1", - "from": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" } } @@ -406,56 +337,46 @@ }, "github": { "version": "0.2.4", - "from": "https://registry.npmjs.org/github/-/github-0.2.4.tgz", "resolved": "https://registry.npmjs.org/github/-/github-0.2.4.tgz", "dependencies": { "mime": { "version": "1.3.4", - "from": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz" } } }, "glob": { "version": "4.5.3", - "from": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", "dependencies": { "inflight": { "version": "1.0.4", - "from": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } }, "inherits": { "version": "2.0.1", - "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, "minimatch": { "version": "2.0.10", - "from": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", "dependencies": { "brace-expansion": { "version": "1.1.1", - "from": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", "dependencies": { "balanced-match": { "version": "0.2.0", - "from": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" }, "concat-map": { "version": "0.0.1", - "from": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" } } @@ -464,12 +385,10 @@ }, "once": { "version": "1.3.2", - "from": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } @@ -478,44 +397,36 @@ }, "graceful-fs": { "version": "3.0.8", - "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.8.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.8.tgz" }, "handlebars": { "version": "2.0.0", - "from": "https://registry.npmjs.org/handlebars/-/handlebars-2.0.0.tgz", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-2.0.0.tgz", "dependencies": { "optimist": { "version": "0.3.7", - "from": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", "dependencies": { "wordwrap": { "version": "0.0.3", - "from": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz" } } }, "uglify-js": { "version": "2.3.6", - "from": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.6.tgz", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.6.tgz", "dependencies": { "async": { "version": "0.2.10", - "from": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz" }, "source-map": { "version": "0.1.43", - "from": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", "dependencies": { "amdefine": { "version": "1.0.0", - "from": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz" } } @@ -526,37 +437,30 @@ }, "inquirer": { "version": "0.10.0", - "from": "https://registry.npmjs.org/inquirer/-/inquirer-0.10.0.tgz", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.10.0.tgz", "dependencies": { "ansi-escapes": { "version": "1.1.0", - "from": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.1.0.tgz", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.1.0.tgz" }, "ansi-regex": { "version": "2.0.0", - "from": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" }, "cli-cursor": { "version": "1.0.2", - "from": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", "dependencies": { "restore-cursor": { "version": "1.0.1", - "from": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", "dependencies": { "exit-hook": { "version": "1.1.1", - "from": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz" }, "onetime": { "version": "1.0.0", - "from": "https://registry.npmjs.org/onetime/-/onetime-1.0.0.tgz", "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.0.0.tgz" } } @@ -565,68 +469,56 @@ }, "cli-width": { "version": "1.0.1", - "from": "https://registry.npmjs.org/cli-width/-/cli-width-1.0.1.tgz", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.0.1.tgz" }, "figures": { "version": "1.4.0", - "from": "https://registry.npmjs.org/figures/-/figures-1.4.0.tgz", "resolved": "https://registry.npmjs.org/figures/-/figures-1.4.0.tgz" }, "lodash": { "version": "3.10.1", - "from": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" }, "readline2": { "version": "1.0.1", - "from": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", "dependencies": { "code-point-at": { "version": "1.0.0", - "from": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.0.0.tgz", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.0.0.tgz", "dependencies": { "number-is-nan": { "version": "1.0.0", - "from": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz" } } }, "is-fullwidth-code-point": { "version": "1.0.0", - "from": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "dependencies": { "number-is-nan": { "version": "1.0.0", - "from": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz" } } }, "mute-stream": { "version": "0.0.5", - "from": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz" } } }, "run-async": { "version": "0.1.0", - "from": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", "dependencies": { "once": { "version": "1.3.2", - "from": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } @@ -635,88 +527,72 @@ }, "rx-lite": { "version": "3.1.2", - "from": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz" }, "strip-ansi": { "version": "3.0.0", - "from": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz" }, "through": { "version": "2.3.8", - "from": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz" } } }, "insight": { "version": "0.7.0", - "from": "https://registry.npmjs.org/insight/-/insight-0.7.0.tgz", "resolved": "https://registry.npmjs.org/insight/-/insight-0.7.0.tgz", "dependencies": { "async": { "version": "1.4.2", - "from": "https://registry.npmjs.org/async/-/async-1.4.2.tgz", "resolved": "https://registry.npmjs.org/async/-/async-1.4.2.tgz" }, "configstore": { "version": "1.2.1", - "from": "https://registry.npmjs.org/configstore/-/configstore-1.2.1.tgz", "resolved": "https://registry.npmjs.org/configstore/-/configstore-1.2.1.tgz", "dependencies": { "graceful-fs": { "version": "4.1.2", - "from": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" }, "object-assign": { "version": "3.0.0", - "from": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz" }, "os-tmpdir": { "version": "1.0.1", - "from": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz" }, "osenv": { "version": "0.1.3", - "from": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", "dependencies": { "os-homedir": { "version": "1.0.1", - "from": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" } } }, "uuid": { "version": "2.0.1", - "from": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz" }, "write-file-atomic": { "version": "1.1.3", - "from": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.1.3.tgz", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.1.3.tgz", "dependencies": { "slide": { "version": "1.1.6", - "from": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz" } } }, "xdg-basedir": { "version": "2.0.0", - "from": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", "dependencies": { "os-homedir": { "version": "1.0.1", - "from": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" } } @@ -725,46 +601,38 @@ }, "lodash.debounce": { "version": "3.1.1", - "from": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-3.1.1.tgz", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-3.1.1.tgz", "dependencies": { "lodash._getnative": { "version": "3.9.1", - "from": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz" } } }, "object-assign": { "version": "4.0.1", - "from": "https://registry.npmjs.org/object-assign/-/object-assign-4.0.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.0.1.tgz" }, "os-name": { "version": "1.0.3", - "from": "https://registry.npmjs.org/os-name/-/os-name-1.0.3.tgz", "resolved": "https://registry.npmjs.org/os-name/-/os-name-1.0.3.tgz", "dependencies": { "osx-release": { "version": "1.1.0", - "from": "https://registry.npmjs.org/osx-release/-/osx-release-1.1.0.tgz", "resolved": "https://registry.npmjs.org/osx-release/-/osx-release-1.1.0.tgz", "dependencies": { "minimist": { "version": "1.2.0", - "from": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" } } }, "win-release": { "version": "1.1.1", - "from": "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz", "resolved": "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz", "dependencies": { "semver": { "version": "5.0.3", - "from": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz" } } @@ -773,95 +641,78 @@ }, "tough-cookie": { "version": "2.0.0", - "from": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz" } } }, "is-root": { "version": "1.0.0", - "from": "https://registry.npmjs.org/is-root/-/is-root-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-root/-/is-root-1.0.0.tgz" }, "junk": { "version": "1.0.2", - "from": "https://registry.npmjs.org/junk/-/junk-1.0.2.tgz", "resolved": "https://registry.npmjs.org/junk/-/junk-1.0.2.tgz" }, "lockfile": { "version": "1.0.1", - "from": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.1.tgz", "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.1.tgz" }, "lru-cache": { "version": "2.7.0", - "from": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.0.tgz", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.0.tgz" }, "md5-hex": { "version": "1.1.0", - "from": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.1.0.tgz", "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.1.0.tgz", "dependencies": { "md5-o-matic": { "version": "0.1.1", - "from": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz", "resolved": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz" } } }, "mkdirp": { "version": "0.5.0", - "from": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", "dependencies": { "minimist": { "version": "0.0.8", - "from": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" } } }, "mout": { "version": "0.11.0", - "from": "https://registry.npmjs.org/mout/-/mout-0.11.0.tgz", "resolved": "https://registry.npmjs.org/mout/-/mout-0.11.0.tgz" }, "nopt": { "version": "3.0.4", - "from": "https://registry.npmjs.org/nopt/-/nopt-3.0.4.tgz", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.4.tgz" }, "opn": { "version": "1.0.2", - "from": "https://registry.npmjs.org/opn/-/opn-1.0.2.tgz", "resolved": "https://registry.npmjs.org/opn/-/opn-1.0.2.tgz" }, "p-throttler": { "version": "0.1.1", - "from": "https://registry.npmjs.org/p-throttler/-/p-throttler-0.1.1.tgz", "resolved": "https://registry.npmjs.org/p-throttler/-/p-throttler-0.1.1.tgz", "dependencies": { "q": { "version": "0.9.7", - "from": "https://registry.npmjs.org/q/-/q-0.9.7.tgz", "resolved": "https://registry.npmjs.org/q/-/q-0.9.7.tgz" } } }, "promptly": { "version": "0.2.0", - "from": "https://registry.npmjs.org/promptly/-/promptly-0.2.0.tgz", "resolved": "https://registry.npmjs.org/promptly/-/promptly-0.2.0.tgz", "dependencies": { "read": { "version": "1.0.7", - "from": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", "dependencies": { "mute-stream": { "version": "0.0.5", - "from": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz" } } @@ -870,43 +721,39 @@ }, "q": { "version": "1.4.1", - "from": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz" }, "request": { "version": "2.53.0", - "from": "https://registry.npmjs.org/request/-/request-2.53.0.tgz", "resolved": "https://registry.npmjs.org/request/-/request-2.53.0.tgz", "dependencies": { + "aws-sign2": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz" + }, "bl": { "version": "0.9.4", - "from": "https://registry.npmjs.org/bl/-/bl-0.9.4.tgz", "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.4.tgz", "dependencies": { "readable-stream": { "version": "1.0.33", - "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", "dependencies": { "core-util-is": { "version": "1.0.1", - "from": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" }, + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, "isarray": { "version": "0.0.1", - "from": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" }, "string_decoder": { "version": "0.10.31", - "from": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - }, - "inherits": { - "version": "2.0.1", - "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" } } } @@ -914,203 +761,162 @@ }, "caseless": { "version": "0.9.0", - "from": "https://registry.npmjs.org/caseless/-/caseless-0.9.0.tgz", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.9.0.tgz" }, + "combined-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", + "dependencies": { + "delayed-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz" + } + } + }, "forever-agent": { "version": "0.5.2", - "from": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz" }, "form-data": { "version": "0.2.0", - "from": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz", "dependencies": { "async": { "version": "0.9.2", - "from": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz" } } }, - "json-stringify-safe": { - "version": "5.0.1", - "from": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" - }, - "mime-types": { - "version": "2.0.14", - "from": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", + "hawk": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz", "dependencies": { - "mime-db": { - "version": "1.12.0", - "from": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz" + "boom": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.9.0.tgz" + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz" + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz" + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz" } } }, - "qs": { - "version": "2.3.3", - "from": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", - "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz" - }, - "tunnel-agent": { - "version": "0.4.1", - "from": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.1.tgz", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.1.tgz" - }, - "tough-cookie": { - "version": "2.0.0", - "from": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz" - }, "http-signature": { "version": "0.10.1", - "from": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", "dependencies": { - "assert-plus": { - "version": "0.1.5", - "from": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz" - }, "asn1": { "version": "0.1.11", - "from": "asn1@0.1.11", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz" }, + "assert-plus": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz" + }, "ctype": { "version": "0.5.3", - "from": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz" } } }, - "oauth-sign": { - "version": "0.6.0", - "from": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz" + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" }, - "hawk": { - "version": "2.3.1", - "from": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz", + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + }, + "mime-types": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", "dependencies": { - "hoek": { - "version": "2.16.3", - "from": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz" - }, - "boom": { - "version": "2.9.0", - "from": "https://registry.npmjs.org/boom/-/boom-2.9.0.tgz", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.9.0.tgz" - }, - "cryptiles": { - "version": "2.0.5", - "from": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz" - }, - "sntp": { - "version": "1.0.9", - "from": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz" + "mime-db": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz" } } }, - "aws-sign2": { - "version": "0.5.0", - "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" + "oauth-sign": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz" + }, + "qs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz" }, "stringstream": { "version": "0.0.4", - "from": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.4.tgz", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.4.tgz" }, - "combined-stream": { - "version": "0.0.7", - "from": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", - "dependencies": { - "delayed-stream": { - "version": "0.0.5", - "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" - } - } + "tough-cookie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz" }, - "isstream": { - "version": "0.1.2", - "from": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" + "tunnel-agent": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.1.tgz" } } }, "request-progress": { "version": "0.3.1", - "from": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", "dependencies": { "throttleit": { "version": "0.0.2", - "from": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz" } } }, "retry": { "version": "0.6.1", - "from": "https://registry.npmjs.org/retry/-/retry-0.6.1.tgz", "resolved": "https://registry.npmjs.org/retry/-/retry-0.6.1.tgz" }, "rimraf": { "version": "2.4.3", - "from": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.3.tgz", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.3.tgz", "dependencies": { "glob": { "version": "5.0.15", - "from": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "dependencies": { "inflight": { "version": "1.0.4", - "from": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } }, "inherits": { "version": "2.0.1", - "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, "minimatch": { "version": "3.0.0", - "from": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.0.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.0.tgz", "dependencies": { "brace-expansion": { "version": "1.1.1", - "from": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", "dependencies": { "balanced-match": { "version": "0.2.0", - "from": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" }, "concat-map": { "version": "0.0.1", - "from": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" } } @@ -1119,19 +925,16 @@ }, "once": { "version": "1.3.2", - "from": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } }, "path-is-absolute": { "version": "1.0.0", - "from": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz" } } @@ -1140,64 +943,52 @@ }, "semver": { "version": "2.3.2", - "from": "https://registry.npmjs.org/semver/-/semver-2.3.2.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-2.3.2.tgz" }, "shell-quote": { "version": "1.4.3", - "from": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.4.3.tgz", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.4.3.tgz", "dependencies": { - "jsonify": { - "version": "0.0.0", - "from": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz" - }, "array-filter": { "version": "0.0.1", - "from": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz" }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz" + }, "array-reduce": { "version": "0.0.0", - "from": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz" }, - "array-map": { + "jsonify": { "version": "0.0.0", - "from": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", - "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz" + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz" } } }, "stringify-object": { "version": "1.0.1", - "from": "https://registry.npmjs.org/stringify-object/-/stringify-object-1.0.1.tgz", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-1.0.1.tgz" }, "tar-fs": { "version": "1.8.1", - "from": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.8.1.tgz", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.8.1.tgz", "dependencies": { "pump": { "version": "1.0.0", - "from": "https://registry.npmjs.org/pump/-/pump-1.0.0.tgz", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.0.tgz", "dependencies": { "end-of-stream": { "version": "1.1.0", - "from": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz" }, "once": { "version": "1.3.2", - "from": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } @@ -1206,27 +997,22 @@ }, "tar-stream": { "version": "1.2.1", - "from": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.2.1.tgz", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.2.1.tgz", "dependencies": { "bl": { "version": "1.0.0", - "from": "https://registry.npmjs.org/bl/-/bl-1.0.0.tgz", "resolved": "https://registry.npmjs.org/bl/-/bl-1.0.0.tgz" }, "end-of-stream": { "version": "1.1.0", - "from": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz", "dependencies": { "once": { "version": "1.3.2", - "from": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } @@ -1235,44 +1021,36 @@ }, "readable-stream": { "version": "2.0.2", - "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", "dependencies": { "core-util-is": { "version": "1.0.1", - "from": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" }, "inherits": { "version": "2.0.1", - "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, "isarray": { "version": "0.0.1", - "from": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" }, "process-nextick-args": { "version": "1.0.3", - "from": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz" }, "string_decoder": { "version": "0.10.31", - "from": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" }, "util-deprecate": { "version": "1.0.1", - "from": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz" } } }, "xtend": { "version": "4.0.0", - "from": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz" } } @@ -1281,52 +1059,42 @@ }, "tmp": { "version": "0.0.24", - "from": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz" }, "update-notifier": { "version": "0.3.2", - "from": "https://registry.npmjs.org/update-notifier/-/update-notifier-0.3.2.tgz", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-0.3.2.tgz", "dependencies": { "is-npm": { "version": "1.0.0", - "from": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz" }, "latest-version": { "version": "1.0.1", - "from": "https://registry.npmjs.org/latest-version/-/latest-version-1.0.1.tgz", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-1.0.1.tgz", "dependencies": { "package-json": { "version": "1.2.0", - "from": "https://registry.npmjs.org/package-json/-/package-json-1.2.0.tgz", "resolved": "https://registry.npmjs.org/package-json/-/package-json-1.2.0.tgz", "dependencies": { "got": { "version": "3.3.1", - "from": "https://registry.npmjs.org/got/-/got-3.3.1.tgz", "resolved": "https://registry.npmjs.org/got/-/got-3.3.1.tgz", "dependencies": { "duplexify": { "version": "3.4.2", - "from": "https://registry.npmjs.org/duplexify/-/duplexify-3.4.2.tgz", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.4.2.tgz", "dependencies": { "end-of-stream": { "version": "1.0.0", - "from": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz", "dependencies": { "once": { "version": "1.3.2", - "from": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", "dependencies": { "wrappy": { "version": "1.0.1", - "from": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" } } @@ -1335,37 +1103,30 @@ }, "readable-stream": { "version": "2.0.2", - "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", "dependencies": { "core-util-is": { "version": "1.0.1", - "from": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" }, "inherits": { "version": "2.0.1", - "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, "isarray": { "version": "0.0.1", - "from": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" }, "process-nextick-args": { "version": "1.0.3", - "from": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz" }, "string_decoder": { "version": "0.10.31", - "from": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" }, "util-deprecate": { "version": "1.0.1", - "from": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz" } } @@ -1374,96 +1135,78 @@ }, "infinity-agent": { "version": "2.0.3", - "from": "https://registry.npmjs.org/infinity-agent/-/infinity-agent-2.0.3.tgz", "resolved": "https://registry.npmjs.org/infinity-agent/-/infinity-agent-2.0.3.tgz" }, "is-redirect": { "version": "1.0.0", - "from": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz" }, "is-stream": { "version": "1.0.1", - "from": "https://registry.npmjs.org/is-stream/-/is-stream-1.0.1.tgz", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.0.1.tgz" }, "lowercase-keys": { "version": "1.0.0", - "from": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz" }, "nested-error-stacks": { "version": "1.0.1", - "from": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-1.0.1.tgz", "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-1.0.1.tgz", "dependencies": { "inherits": { "version": "2.0.1", - "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" } } }, "object-assign": { "version": "3.0.0", - "from": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz" }, "prepend-http": { "version": "1.0.3", - "from": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.3.tgz", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.3.tgz" }, "read-all-stream": { "version": "3.0.1", - "from": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.0.1.tgz", "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.0.1.tgz", "dependencies": { "pinkie-promise": { "version": "1.0.0", - "from": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz", "dependencies": { "pinkie": { "version": "1.0.0", - "from": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz" } } }, "readable-stream": { "version": "2.0.2", - "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", "dependencies": { "core-util-is": { "version": "1.0.1", - "from": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" }, "inherits": { "version": "2.0.1", - "from": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" }, "isarray": { "version": "0.0.1", - "from": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" }, "process-nextick-args": { "version": "1.0.3", - "from": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz" }, "string_decoder": { "version": "0.10.31", - "from": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" }, "util-deprecate": { "version": "1.0.1", - "from": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz" } } @@ -1472,40 +1215,33 @@ }, "timed-out": { "version": "2.0.0", - "from": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz" } } }, "registry-url": { "version": "3.0.3", - "from": "https://registry.npmjs.org/registry-url/-/registry-url-3.0.3.tgz", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.0.3.tgz", "dependencies": { "rc": { "version": "1.1.1", - "from": "https://registry.npmjs.org/rc/-/rc-1.1.1.tgz", "resolved": "https://registry.npmjs.org/rc/-/rc-1.1.1.tgz", "dependencies": { - "minimist": { - "version": "1.2.0", - "from": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" - }, "deep-extend": { "version": "0.2.11", - "from": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.2.11.tgz", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.2.11.tgz" }, - "strip-json-comments": { - "version": "0.1.3", - "from": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-0.1.3.tgz", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-0.1.3.tgz" - }, "ini": { "version": "1.3.4", - "from": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz" + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" + }, + "strip-json-comments": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-0.1.3.tgz" } } } @@ -1517,29 +1253,24 @@ }, "semver-diff": { "version": "2.0.0", - "from": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.0.0.tgz", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.0.0.tgz", "dependencies": { "semver": { "version": "4.3.6", - "from": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz" } } }, "string-length": { "version": "1.0.1", - "from": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", "dependencies": { "strip-ansi": { "version": "3.0.0", - "from": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", "dependencies": { "ansi-regex": { "version": "2.0.0", - "from": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" } } @@ -1550,22 +1281,18 @@ }, "user-home": { "version": "1.1.1", - "from": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz" }, "which": { "version": "1.1.2", - "from": "https://registry.npmjs.org/which/-/which-1.1.2.tgz", "resolved": "https://registry.npmjs.org/which/-/which-1.1.2.tgz", "dependencies": { "is-absolute": { "version": "0.1.7", - "from": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz", "dependencies": { "is-relative": { "version": "0.1.3", - "from": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz" } } diff --git a/package.json b/package.json index cc9df1fcc..1a830b148 100644 --- a/package.json +++ b/package.json @@ -77,6 +77,7 @@ "multiline": "^1.0.2", "nock": "^2.13.0", "node-uuid": "^1.4.2", + "npm-shrinkwrap": "^5.4.1", "proxyquire": "^1.3.0", "spawn-sync": "^1.0.5" }, From af09872fba08fbac8666f9cb46ac9d89fc3c3afb Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 15 Oct 2015 13:50:36 +0200 Subject: [PATCH 0684/1021] Set default bower.config again --- lib/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index f9ad14905..1efed6af1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -37,7 +37,7 @@ function clearRuntimeCache() { module.exports = { version: pkg.version, commands: commands, - config: require('bower-config'), + config: require('./config')(), abbreviations: abbreviations, reset: clearRuntimeCache }; From 402a9f3017335e362a2c236daf86e984b075ffa4 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 15 Oct 2015 14:10:25 +0200 Subject: [PATCH 0685/1021] Add node-uuid back to npm-shrinkwrap --- npm-shrinkwrap.json | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index bfc9bcd2b..dbea02ada 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -164,8 +164,8 @@ "resolved": "https://registry.npmjs.org/configstore/-/configstore-0.3.2.tgz", "dependencies": { "js-yaml": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.2.tgz", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.3.tgz", "dependencies": { "argparse": { "version": "1.0.2", @@ -182,8 +182,8 @@ } }, "esprima": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.2.0.tgz" + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.6.0.tgz" } } }, @@ -640,8 +640,8 @@ } }, "tough-cookie": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.0.tgz" } } }, @@ -845,6 +845,10 @@ } } }, + "node-uuid": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.3.tgz" + }, "oauth-sign": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz" @@ -858,8 +862,8 @@ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.4.tgz" }, "tough-cookie": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.0.tgz" }, "tunnel-agent": { "version": "0.4.1", @@ -1044,8 +1048,8 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" }, "util-deprecate": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" } } }, @@ -1126,8 +1130,8 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" }, "util-deprecate": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" } } } @@ -1206,8 +1210,8 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" }, "util-deprecate": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" } } } @@ -1224,8 +1228,8 @@ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.0.3.tgz", "dependencies": { "rc": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.1.1.tgz", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.1.2.tgz", "dependencies": { "deep-extend": { "version": "0.2.11", @@ -1284,8 +1288,8 @@ "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz" }, "which": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/which/-/which-1.1.2.tgz", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.0.tgz", "dependencies": { "is-absolute": { "version": "0.1.7", From 20a6190ed88794793f091c7598f94eb38ad601af Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 15 Oct 2015 15:56:23 +0200 Subject: [PATCH 0686/1021] Bump to 1.6.1 and update npm-shrinkwrap.json --- npm-shrinkwrap.json | 6 +----- package.json | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index dbea02ada..ab5844938 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.0", + "version": "1.6.1", "npm-shrinkwrap-version": "5.4.1", "dependencies": { "abbrev": { @@ -845,10 +845,6 @@ } } }, - "node-uuid": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.3.tgz" - }, "oauth-sign": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz" diff --git a/package.json b/package.json index 1a830b148..a62ac0369 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.0", + "version": "1.6.1", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 8cf09f544421a767ebe5cfc55f9db7ed91dfbc38 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 15 Oct 2015 16:12:42 +0200 Subject: [PATCH 0687/1021] Revert "Bump to 1.6.1 and update npm-shrinkwrap.json" This reverts commit 20a6190ed88794793f091c7598f94eb38ad601af. --- npm-shrinkwrap.json | 6 +++++- package.json | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index ab5844938..dbea02ada 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.1", + "version": "1.6.0", "npm-shrinkwrap-version": "5.4.1", "dependencies": { "abbrev": { @@ -845,6 +845,10 @@ } } }, + "node-uuid": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.3.tgz" + }, "oauth-sign": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz" diff --git a/package.json b/package.json index a62ac0369..1a830b148 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.1", + "version": "1.6.0", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 52463dea099f73c5fcfa4858f9a89ff91f3ef147 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 15 Oct 2015 16:15:51 +0200 Subject: [PATCH 0688/1021] Bump and update npm-shrinkwrap.json for bower 1.6.2 --- npm-shrinkwrap.json | 3 +-- package.json | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index dbea02ada..b4ca1f991 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,7 +1,6 @@ { "name": "bower", - "version": "1.6.0", - "npm-shrinkwrap-version": "5.4.1", + "version": "1.6.2", "dependencies": { "abbrev": { "version": "1.0.7", diff --git a/package.json b/package.json index 1a830b148..49f82f54e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.0", + "version": "1.6.2", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 8fa1fd55e9c85981bf62c5e3935974eccdf757b7 Mon Sep 17 00:00:00 2001 From: Scott Addie Date: Thu, 15 Oct 2015 22:18:30 -0500 Subject: [PATCH 0689/1021] Replace README file msysgit references with Git for Windows --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 697d3fbd2..2f613f106 100644 --- a/README.md +++ b/README.md @@ -67,10 +67,12 @@ However, if you still want to run commands with sudo, use `--allow-root` option. ### Windows users To use Bower on Windows, you must install -[msysgit](http://msysgit.github.io/) correctly. Be sure to check the -option shown below: +[Git for Windows](http://git-for-windows.github.io/) correctly. Be sure to check the +options shown below: -![msysgit](http://f.cl.ly/items/2V2O3i1p3R2F1r2v0a12/mysgit.png) +Git for Windows + +Git for Windows Note that if you use TortoiseGit and if Bower keeps asking for your SSH password, you should add the following environment variable: `GIT_SSH - From ff0f2a8f832658e69869d44a6495a443b65ffd1e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 16 Oct 2015 11:17:03 +0200 Subject: [PATCH 0690/1021] Use stat instead of lstat for checking if something is directory, fixes #1951 --- lib/util/fs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/util/fs.js b/lib/util/fs.js index 70160f469..5fd35177a 100644 --- a/lib/util/fs.js +++ b/lib/util/fs.js @@ -6,7 +6,7 @@ var readdirSync = fs.readdirSync.bind(fs); module.exports = fs; module.exports.readdir = function (dir, callback) { - fs.lstat(dir, function (err, stats) { + fs.stat(dir, function (err, stats) { if (err) return callback(err); if (stats.isDirectory()) { @@ -22,7 +22,7 @@ module.exports.readdir = function (dir, callback) { }; module.exports.readdirSync = function (dir) { - var stats = fs.lstatSync(dir); + var stats = fs.statSync(dir); if (stats.isDirectory()) { return readdirSync(dir); From b85cf2683c20a231c251219d5a93541bf0b2475b Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 16 Oct 2015 11:37:41 +0200 Subject: [PATCH 0691/1021] Fix registry configuration expanding, closes bower/bower#1950 --- packages/bower-config/lib/util/expand.js | 17 ++++---- packages/bower-config/test/test.js | 54 +++++++++++++++++++++++- 2 files changed, 61 insertions(+), 10 deletions(-) diff --git a/packages/bower-config/lib/util/expand.js b/packages/bower-config/lib/util/expand.js index e59bf7b78..d1b356c29 100644 --- a/packages/bower-config/lib/util/expand.js +++ b/packages/bower-config/lib/util/expand.js @@ -22,8 +22,6 @@ function camelCase(config) { function expand(config) { config = camelCase(config); - // Expand some properties - // Registry if (typeof config.registry === 'string') { config.registry = { default: config.registry, @@ -32,15 +30,18 @@ function expand(config) { publish: config.registry }; } else if (typeof config.registry === 'object') { + config.registry.default = config.registry.default || 'https://bower.herokuapp.com'; + + config.registry = { + default: config.registry.default, + search: config.registry.search || config.registry.default, + register: config.registry.register || config.registry.default, + publish: config.registry.publish || config.registry.default + }; + if (config.registry.search && !Array.isArray(config.registry.search)) { config.registry.search = [config.registry.search]; } - - if (config.registry.default) { - config.registry.search = config.registry.search || config.registry.default; - config.registry.register = config.registry.register || config.registry.default; - config.registry.publish = config.registry.publish || config.registry.default; - } } // CA diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index 68d18b5d2..9546645fd 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -7,11 +7,61 @@ describe('NPM Config on package.json', function () { delete process.env.npm_package_config_bower_colors; }); + it('defaults registry entries to default registry', function () { + var config = require('../lib/Config').read(null, {}); + + assert.deepEqual(config.registry, { + 'default': 'https://bower.herokuapp.com', + 'search': [ + 'https://bower.herokuapp.com' + ], + 'register': 'https://bower.herokuapp.com', + 'publish': 'https://bower.herokuapp.com' + }); + }); + + it('can change default registry', function () { + var config = require('../lib/Config').read(null, { registry: 'https://foobar' }); + + assert.deepEqual(config.registry, { + 'default': 'https://foobar', + 'search': [ + 'https://foobar', + ], + 'register': 'https://foobar', + 'publish': 'https://foobar' + }); + }); + + it('can override single entries in registry configuration', function () { + var config = require('../lib/Config').read(null, { registry: { search: 'https://foobar' } }); + + assert.deepEqual(config.registry, { + 'default': 'https://bower.herokuapp.com', + 'search': [ + 'https://foobar', + ], + 'register': 'https://bower.herokuapp.com', + 'publish': 'https://bower.herokuapp.com' + }); + }); + + it('can override single entries in registry configuration and defaults', function () { + var config = require('../lib/Config').read(null, { registry: { default: 'https://fizfuz', search: 'https://foobar' } }); + + assert.deepEqual(config.registry, { + 'default': 'https://fizfuz', + 'search': [ + 'https://foobar', + ], + 'register': 'https://fizfuz', + 'publish': 'https://fizfuz' + }); + }); + it('allows for not providing cwd', function () { var config = require('../lib/Config').read(); - console.log(JSON.stringify(config, undefined, ' ')); - config.tmp = '/foo/bar'; config.userAgent = 'firefox'; delete config.storage; From b7c19695e7eb497f2fc3d67bc27f1324307b291a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 16 Oct 2015 11:38:06 +0200 Subject: [PATCH 0692/1021] Bump to 1.2.2 --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 075c9e492..84ac88a10 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "1.2.1", + "version": "1.2.2", "description": "The Bower config reader and writer.", "author": "Twitter", "license": "MIT", From 1316be57dc3d2ed30871667b5aae4b5030407636 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 16 Oct 2015 11:46:51 +0200 Subject: [PATCH 0693/1021] Update bower-config to 1.2.2 --- npm-shrinkwrap.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index b4ca1f991..de36a6b5c 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -11,8 +11,8 @@ "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz" }, "bower-config": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bower-config/-/bower-config-1.2.1.tgz", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bower-config/-/bower-config-1.2.2.tgz", "dependencies": { "graceful-fs": { "version": "4.1.2", diff --git a/package.json b/package.json index 49f82f54e..0f84f67f8 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dependencies": { "abbrev": "^1.0.5", "archy": "1.0.0", - "bower-config": "^1.2.1", + "bower-config": "^1.2.2", "bower-endpoint-parser": "^0.2.2", "bower-json": "^0.4.0", "bower-logger": "^0.2.2", From 2330d59ffa8f4f543a9f6ee4b0301e396236bf45 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 16 Oct 2015 11:49:04 +0200 Subject: [PATCH 0694/1021] Bump to 1.6.3 --- npm-shrinkwrap.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index de36a6b5c..df214e18b 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.2", + "version": "1.6.3", "dependencies": { "abbrev": { "version": "1.0.7", diff --git a/package.json b/package.json index 0f84f67f8..f8e2c0f4c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.2", + "version": "1.6.3", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 30898c13d3a10b4a03c4e7e1ffdfe624118a2947 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 16 Oct 2015 12:01:25 +0200 Subject: [PATCH 0695/1021] Update changelog --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2ed40521..862f24042 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## 1.6.3 - 2015-10-16 + +Fixes regression issues introduced with 1.6.2, specifically: + +- Allow for bower_components to be a symlink +- Allow setting custom registry in .bowerrc + +## 1.6.2 - 2015-10-15 + +Fix dependency issues of 1.6.1. First published release of 1.6.x. + +## 1.6.1 - 2015-10-15 + +Fix dependency issues of 1.6.0. Reverted release. + ## 1.6.0 - 2015-10-15 - Shrinkwrap all dependencies and add them to bundledDependencies ([#1948](https://github.com/bower/bower/pull/1948)) @@ -12,6 +27,7 @@ - Close file-handles when possible. Prevents all sorts of permission issues on Windows ([0bb1536](https://github.com/bower/bower/commit/0bb1536c9972e13f3be06bea9a8619632966c664)) - Prevent ENOENT error on Windows when in VM environment ([isaacs/chmodr#8](https://github.com/isaacs/chmodr/pull/8)) +Reverted release. ## 1.5.3 - 2015-09-24 From f66c0cfe5c0e30e31cac5693ab70edca9632eed5 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 16 Oct 2015 12:05:36 +0200 Subject: [PATCH 0696/1021] Update npm to 2.0.0 on travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index bee5fc3fc..3e442796a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ env: install: - test $TRAVIS_OS_NAME = "osx" && brew install nvm && source $(brew --prefix nvm)/nvm.sh || test $TRAVIS_OS_NAME = "linux" - nvm install $NODE_VERSION + - npm install -g npm@^2.0.0 - node --version - npm --version - git --version From 452217e9fa3d49d0b00f42d80755047a738b290c Mon Sep 17 00:00:00 2001 From: Patrick Kettner Date: Sat, 17 Oct 2015 21:48:10 -0500 Subject: [PATCH 0697/1021] strip trailing slash in urlResolver --- lib/core/resolvers/UrlResolver.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/core/resolvers/UrlResolver.js b/lib/core/resolvers/UrlResolver.js index 5d1f575ed..84c3f8582 100644 --- a/lib/core/resolvers/UrlResolver.js +++ b/lib/core/resolvers/UrlResolver.js @@ -104,8 +104,18 @@ UrlResolver.prototype._resolve = function () { // ----------------- +UrlResolver.prototype._parseSourceURL = function (_url) { + return url.parse(path.basename(_url)).pathname; +}; + UrlResolver.prototype._download = function () { - var fileName = url.parse(path.basename(this._source)).pathname; + var fileName = this._parseSourceURL(this._source); + + if (!fileName) { + this._source = this._source.replace(/\/(?=\?|#)/, ''); + fileName = this._parseSourceURL(this._source); + } + var file = path.join(this._tempDir, fileName); var reqHeaders = {}; var that = this; From 0f790f4293df70bf5c85629b3f5208f45759ac78 Mon Sep 17 00:00:00 2001 From: Patrick Kettner Date: Tue, 20 Oct 2015 13:51:41 -0700 Subject: [PATCH 0698/1021] add User-Agent to downloadd --- lib/util/download.js | 6 +++++- lib/util/userAgent.js | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 lib/util/userAgent.js diff --git a/lib/util/download.js b/lib/util/download.js index eebbbb4d5..788a6d948 100644 --- a/lib/util/download.js +++ b/lib/util/download.js @@ -5,6 +5,7 @@ var mout = require('mout'); var retry = require('retry'); var createError = require('./createError'); var createWriteStream = require('fs-write-stream-atomic'); +var userAgent = require('./userAgent'); var errorCodes = [ 'EADDRINFO', @@ -31,7 +32,10 @@ function download(url, file, options) { operation.attempt(function () { Q.fcall(fetch, url, file, { - progressDelay: progressDelay + progressDelay: progressDelay, + headers: { + 'User-Agent': userAgent + } }).then(function(response) { deferred.resolve(response); }).fail(function (error) { diff --git a/lib/util/userAgent.js b/lib/util/userAgent.js new file mode 100644 index 000000000..b5200144e --- /dev/null +++ b/lib/util/userAgent.js @@ -0,0 +1,3 @@ +var pkg = require('../../package.json'); + +module.exports = 'node/' + process.version + ' ' + process.platform + ' ' + process.arch + ' ' + ';Bower ' + pkg.version; From 75d80e014aaf6d63ae14c1a27d3825297077c06f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 22 Oct 2015 12:15:50 +0200 Subject: [PATCH 0699/1021] Mention about Support Declaration and BountySource --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f613f106..6212fdf9e 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,13 @@ # Bower -[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)](https://ci.appveyor.com/project/sheerun/bower/history) [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) +Bower needs resources for its maintenance. Please fill [Support Declaration](http://goo.gl/forms/P1ndzCNoiG) or donate on [BountySource](https://salt.bountysource.com/teams/bower). + +[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)](https://ci.appveyor.com/project/sheerun/bower/history) [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) +--- + > A package manager for the web Bower offers a generic, unopinionated solution to the problem of **front-end package management**, while exposing the package dependency model via an API that can be consumed by a more opinionated build stack. There are no system wide dependencies, no dependencies are shared between different apps, and the dependency tree is flat. From 302c4ade51770be0708ccac832171abd0a12f466 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 22 Oct 2015 12:19:42 +0200 Subject: [PATCH 0700/1021] Leave link only to Support Declaration --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6212fdf9e..049285af3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bower -Bower needs resources for its maintenance. Please fill [Support Declaration](http://goo.gl/forms/P1ndzCNoiG) or donate on [BountySource](https://salt.bountysource.com/teams/bower). +Bower needs resources for its maintenance. Please fill [Support Declaration](http://goo.gl/forms/P1ndzCNoiG) if you think you can help. [![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)](https://ci.appveyor.com/project/sheerun/bower/history) [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) From 4836a0cae99d8c73f235c80a08ce133a53a243ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20J=C3=B6nsson?= Date: Fri, 23 Oct 2015 09:52:19 +0200 Subject: [PATCH 0701/1021] use --non-interactive when running svn client If there is a problem in connecting to the Subversion server, e.g. credential or certificate related, the CLI client will pause to ask the user for input on the console. This is not handled by bower Subversion Resolver, causing the install process to hang forever with no message printed to the bower user. Running the Subversion CLI client with the option --non-interactive will instead cause the client to exit upon such an error.This is detected by the bower resolver and the message printed to the user, making it much easier to investigate and solve the underlying problem. --- lib/core/resolvers/SvnResolver.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js index 7f414bf08..17da23744 100644 --- a/lib/core/resolvers/SvnResolver.js +++ b/lib/core/resolvers/SvnResolver.js @@ -86,13 +86,13 @@ SvnResolver.prototype._export = function () { }); if (resolution.type === 'commit') { - promise = cmd('svn', ['export', '--force', this._source + '/trunk', '-r' + resolution.commit, this._tempDir]); + promise = cmd('svn', ['export', '--force', '--non-interactive', this._source + '/trunk', '-r' + resolution.commit, this._tempDir]); } else if (resolution.type === 'branch' && resolution.branch === 'trunk') { - promise = cmd('svn', ['export', '--force', this._source + '/trunk', this._tempDir]); + promise = cmd('svn', ['export', '--force', '--non-interactive', this._source + '/trunk', this._tempDir]); } else if (resolution.type === 'branch') { - promise = cmd('svn', ['export', '--force', this._source + '/branches/' + resolution.branch, this._tempDir]); + promise = cmd('svn', ['export', '--force', '--non-interactive', this._source + '/branches/' + resolution.branch, this._tempDir]); } else { - promise = cmd('svn', ['export', '--force', this._source + '/tags/' + resolution.tag, this._tempDir]); + promise = cmd('svn', ['export', '--force', '--non-interactive', this._source + '/tags/' + resolution.tag, this._tempDir]); } // Throttle the progress reporter to 1 time each sec @@ -324,7 +324,7 @@ SvnResolver.tags = function (source) { return Q.resolve(value); } - value = cmd('svn', ['list', source + '/tags', '--verbose']) + value = cmd('svn', ['list', source + '/tags', '--verbose', '--non-interactive']) .spread(function (stout) { var tags = SvnResolver.parseSubversionListOutput(stout.toString()); @@ -349,7 +349,7 @@ SvnResolver.branches = function (source) { return Q.resolve(value); } - value = cmd('svn', ['list', source + '/branches', '--verbose']) + value = cmd('svn', ['list', source + '/branches', '--verbose', '--non-interactive']) .spread(function (stout) { var branches = SvnResolver.parseSubversionListOutput(stout.toString()); From 43d00deb88193088f0693b3691ee05fee6aa8a0d Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Fri, 23 Oct 2015 11:52:40 -0700 Subject: [PATCH 0702/1021] fix issue #1962 - ignoredDependenices multiple install run --- lib/core/Manager.js | 7 +++++-- test/commands/install.js | 38 ++++++++++++++++++++++++++++++++++++++ test/commands/update.js | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index cc769f06b..42107a652 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -25,8 +25,11 @@ Manager.prototype.configure = function (setup) { var targetsHash = {}; this._conflicted = {}; - // Targets - this._targets = setup.targets || []; + // Targets - ignore those specified in ignoredDependencies + this._targets = mout.array.reject(setup.targets || [], function(target) { + return mout.array.contains(this._config.ignoredDependencies, target.name ); + }, this); + this._targets.forEach(function (decEndpoint) { decEndpoint.initialName = decEndpoint.name; decEndpoint.dependants = mout.object.values(decEndpoint.dependants); diff --git a/test/commands/install.js b/test/commands/install.js index dbb244781..bc53acc22 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -316,6 +316,44 @@ describe('bower install', function () { }); + it('does not install ignored dependencies if run multiple times', function() { + package.prepare(); + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + } + }).prepare(); + + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3', + dependencies: { + package2: package2.path, + package: package.path, + } + } + }).prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test_tw', + dependencies: { + package3: package3.path + } + }, + '.bowerrc': { + ignoredDependencies: ['package'] + } + }); + return helpers.run(install).then(function() { + return helpers.run(install).then(function() { + expect(tempDir.exists('bower_components/package')).to.be(false); + expect(tempDir.exists('bower_components/package2')).to.be(true); + }); + }); + + }); + it('recognizes proxy option in config', function () { this.timeout(10000); diff --git a/test/commands/update.js b/test/commands/update.js index 8e3b4a296..7e50db9c3 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -125,6 +125,43 @@ describe('bower update', function () { }); + it('does not install ignored dependencies if run multiple times', function() { + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3' + } + }).prepare(); + + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + dependencies: { + package3: package3.path + } + } + }).prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package2: package2.path + } + }, + '.bowerrc': { + ignoredDependencies: ['package3'] + } + }); + + return update().then(function() { + return update().then(function() { + expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); + expect(tempDir.exists('bower_components/package3')).to.equal(false); + }); + }); + + }); + it('runs preinstall hook when installing missing package', function () { package.prepare(); From bf2375154919a7913261d1ab3cbfcd7d9f1b1155 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 24 Oct 2015 11:37:01 +0200 Subject: [PATCH 0703/1021] Bump to 1.6.4 --- CHANGELOG.md | 7 +++++++ npm-shrinkwrap.json | 2 +- package.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 862f24042..9755f0e73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 1.6.4 - 2015-10-24 + +- Fix ignoring dependencies on multiple install run ([#1970](https://github.com/bower/bower/pull/1970)) +- Use --non-interactive when running svn client ([#1969](https://github.com/bower/bower/pull/1969)) +- Fix downloading of URLs ending with slash ([#1956](https://github.com/bower/bower/pull/1956)) +- Add user-agent field for downloads by Bower ([#1960](https://github.com/bower/bower/pull/1960)) + ## 1.6.3 - 2015-10-16 Fixes regression issues introduced with 1.6.2, specifically: diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index df214e18b..e1cd6ea7f 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.3", + "version": "1.6.4", "dependencies": { "abbrev": { "version": "1.0.7", diff --git a/package.json b/package.json index f8e2c0f4c..9214abba8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.3", + "version": "1.6.4", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From bfd1e933250d51794372d3a2eba169d94686eda7 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 24 Oct 2015 12:01:59 +0200 Subject: [PATCH 0704/1021] Install stable version on npm on appveyor --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index fe69c143b..1984cdc66 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -21,6 +21,8 @@ matrix: install: # Get the latest stable version of Node 0.STABLE.latest - ps: Install-Product node $env:nodejs_version + # Install stable version of npm + - npm install -g npm@^2.0.0 # Install subversion - choco install svn -y # Install bower From 931b0a89057cf43bdd95ff25d134fd9fb26eb0a1 Mon Sep 17 00:00:00 2001 From: Piotr Wielgolaski Date: Sat, 24 Oct 2015 16:52:22 +0200 Subject: [PATCH 0705/1021] fix passing options to request options from download need to be pass to request library that make HTTP request Also when there is http error stream need to be closed otherwise there is issue reported that unlink operation is not permitted on Windows --- lib/util/download.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/util/download.js b/lib/util/download.js index 788a6d948..443fc1572 100644 --- a/lib/util/download.js +++ b/lib/util/download.js @@ -5,7 +5,6 @@ var mout = require('mout'); var retry = require('retry'); var createError = require('./createError'); var createWriteStream = require('fs-write-stream-atomic'); -var userAgent = require('./userAgent'); var errorCodes = [ 'EADDRINFO', @@ -24,19 +23,16 @@ function download(url, file, options) { factor: 2, minTimeout: 1000, maxTimeout: 35000, - randomize: true + randomize: true, + progressDelay: progressDelay }, options || {}); // Retry on network errors operation = retry.operation(options); operation.attempt(function () { - Q.fcall(fetch, url, file, { - progressDelay: progressDelay, - headers: { - 'User-Agent': userAgent - } - }).then(function(response) { + Q.fcall(fetch, url, file, options) + .then(function(response) { deferred.resolve(response); }).fail(function (error) { // Save timeout before retrying to report @@ -93,6 +89,7 @@ function fetch(url, file, options) { deferred.notify(state); }) .on('error', function (error) { + writeStream.destroy(); deferred.reject(error); }) .on('end', function () { From 484c8985eddf4c136b7948f19edbb5e5f64460bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Gr=C3=B6nke?= Date: Mon, 26 Oct 2015 01:14:09 +0100 Subject: [PATCH 0706/1021] remove hint to use --allow-root flag from readme --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 049285af3..9862d06e8 100644 --- a/README.md +++ b/README.md @@ -63,10 +63,9 @@ $ bower uninstall On `prezto` or `oh-my-zsh`, do not forget to `alias bower='noglob bower'` or `bower install jquery\#1.9.1` -### Running commands with sudo +### Never run Bower with sudo Bower is a user command, there is no need to execute it with superuser permissions. -However, if you still want to run commands with sudo, use `--allow-root` option. ### Windows users From d57d81ca856045af96ad35095a9243a435db34e0 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 5 Nov 2015 10:38:15 +1300 Subject: [PATCH 0707/1021] Run travis tests in all versions of node --- .travis.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3e442796a..04cb7172b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,16 @@ sudo: false -env: - - NODE_VERSION=0.10 - - NODE_VERSION=0.11 +node_js: + - "5.0" + - "4.2" + - "4.1" + - "4.0" + - "0.12" + - "0.11" + - "0.10" + - "0.8" + - "0.6" + - "iojs" install: - test $TRAVIS_OS_NAME = "osx" && brew install nvm && source $(brew --prefix nvm)/nvm.sh || test $TRAVIS_OS_NAME = "linux" From 5eca9274eeb53211d99cad934be0e20d580c678d Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 5 Nov 2015 10:40:44 +1300 Subject: [PATCH 0708/1021] Added language to travis.yml --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 04cb7172b..4ba6ce674 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ sudo: false +language: node_js + node_js: - "5.0" - "4.2" From 2a91dc5fb19e23d5398eea1ace847744c150b6f8 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 5 Nov 2015 10:43:02 +1300 Subject: [PATCH 0709/1021] Updated travis tests to run in supported node versions --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4ba6ce674..f121f5a74 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,8 +10,6 @@ node_js: - "0.12" - "0.11" - "0.10" - - "0.8" - - "0.6" - "iojs" install: From 284598416985face6f6f11b9d4e40b621933f78b Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 5 Nov 2015 10:47:24 +1300 Subject: [PATCH 0710/1021] Use environment vars for node versions because OS X --- .travis.yml | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index f121f5a74..662e85cc9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,14 @@ sudo: false -language: node_js - -node_js: - - "5.0" - - "4.2" - - "4.1" - - "4.0" - - "0.12" - - "0.11" - - "0.10" - - "iojs" +env: + - NODE_VERSION=0.10 + - NODE_VERSION=0.11 + - NODE_VERSION=0.12 + - NODE_VERSION=4.0 + - NODE_VERSION=4.1 + - NODE_VERSION=4.2 + - NODE_VERSION=5 + - NODE_VERSION=iojs install: - test $TRAVIS_OS_NAME = "osx" && brew install nvm && source $(brew --prefix nvm)/nvm.sh || test $TRAVIS_OS_NAME = "linux" From 0aefe8fc0e2191c6dc9bee359034b15b72394fd7 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 5 Nov 2015 10:47:39 +1300 Subject: [PATCH 0711/1021] Be more specific with node version 5 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 662e85cc9..b374f206a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ env: - NODE_VERSION=4.0 - NODE_VERSION=4.1 - NODE_VERSION=4.2 - - NODE_VERSION=5 + - NODE_VERSION=5.0 - NODE_VERSION=iojs install: From 51a986d0d4916d0096c47de65944ea0054524db9 Mon Sep 17 00:00:00 2001 From: Piotr Wielgolaski Date: Sat, 7 Nov 2015 18:26:48 +0100 Subject: [PATCH 0712/1021] add test for download.js and fix download behavior to not leave temporary files in case of error --- lib/util/download.js | 5 +-- test/util/download.js | 95 +++++++++++++++++++++++++++++++++++++++++++ test/util/index.js | 1 + 3 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 test/util/download.js diff --git a/lib/util/download.js b/lib/util/download.js index 443fc1572..91f60f01f 100644 --- a/lib/util/download.js +++ b/lib/util/download.js @@ -76,7 +76,7 @@ function fetch(url, file, options) { var status = res.statusCode; if (status < 200 || status >= 300) { - return deferred.reject(createError('Status code of ' + status, 'EHTTP')); + return writeStream.emit('error', (createError('Status code of ' + status, 'EHTTP'))); } response = res; @@ -89,8 +89,7 @@ function fetch(url, file, options) { deferred.notify(state); }) .on('error', function (error) { - writeStream.destroy(); - deferred.reject(error); + writeStream.emit('error', error); }) .on('end', function () { // Check if the whole file was downloaded diff --git a/test/util/download.js b/test/util/download.js new file mode 100644 index 000000000..14582cf33 --- /dev/null +++ b/test/util/download.js @@ -0,0 +1,95 @@ +var expect = require('expect.js'); +var helpers = require('../helpers'); +var nock = require('nock'); +var path = require('path'); +var Q = require('q'); + +var fs = require('../../lib/util/fs'); +var download = require('../../lib/util/download'); + +describe('download', function () { + + var tempDir = new helpers.TempDir(), + source = path.resolve(__dirname, '../assets/package-tar.tar.gz'), + destination = tempDir.getPath('package.tar.gz'); + + function downloadTest(opts) { + var deferred = Q.defer(); + + tempDir.prepare(); + + opts.response( + nock('https://bower.io', opts.nockOpts) + .get('/package.tar.gz')); + + download('https://bower.io/package.tar.gz', destination, opts.downloadOpts) + .then(function () { + opts.expect(); + deferred.resolve(); + }, function () { + opts.expectError(); + deferred.resolve(); + }) + .done(); + + return deferred.promise; + } + + it('download file to directory', function () { + return downloadTest({ + response: function (nock) { + nock.replyWithFile(200, source); + }, + expect: function () { + expect(fs.existsSync(destination)).to.be(true); + expect(fs.readdirSync(tempDir.path)).to.have.length(1); + } + }); + }); + + it('pass custom user-agent to server', function () { + var userAgent = 'Custom User-Agent'; + return downloadTest({ + nockOpts: { + reqheaders: { + 'user-agent': userAgent + } + }, + downloadOpts: { + headers: { + 'User-Agent': userAgent + } + }, + response: function (nock) { + nock.replyWithFile(200, source); + }, + expect: function () { + expect(fs.existsSync(destination)).to.be(true); + expect(fs.readdirSync(tempDir.path)).to.have.length(1); + } + }); + }); + + it('handle server response 404', function () { + return downloadTest({ + response: function (nock) { + nock.reply(404); + }, + expectError: function () { + expect(fs.readdirSync(tempDir.path)).to.be.empty(); + } + }); + }); + + it('handle network error', function () { + return downloadTest({ + response: function (nock) { + nock.replyWithError('network error'); + }, + expectError: function () { + expect(fs.readdirSync(tempDir.path)).to.be.empty(); + } + }); + }); + +}); diff --git a/test/util/index.js b/test/util/index.js index 0a53444a4..ca9d3d464 100644 --- a/test/util/index.js +++ b/test/util/index.js @@ -1,4 +1,5 @@ describe('util', function () { require('./removeIgnores'); require('./analytics'); + require('./download'); }); From 83da088024cf0ed281543b632bb30218904197b4 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 14 Nov 2015 15:39:41 +0100 Subject: [PATCH 0713/1021] Update CONTRIBUTING.md --- CONTRIBUTING.md | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9600ec166..6f3995791 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,35 +1,23 @@ # Contributing to Bower -Bower is a large community project with many different developers contributing at all levels to the project. We're **actively** looking for more contributors right now. (Jan 2014) +Bower is a large community project with many different developers contributing at all levels to the project. We're **actively** looking for more contributors right now. If you're interested in becoming Bower maintainer or supporting in in any way, please full the following form: http://goo.gl/forms/P1ndzCNoiG ## Casual Involvement + * Improve the bower.io site ([tickets](https://github.com/bower/bower.github.io/issues)) -* Move forward [bower.io redesign](https://github.com/bower/bower.github.io/issues/7) -* Attend team meetings * Comment on issues and drive to resolution ## High-impact Involvement * Maintaining the bower client. - * [Authoring client tests](https://github.com/bower/bower/issues/801) * Read [Architecture doc](https://github.com/bower/bower/wiki/Rewrite-architecture) * Triage, close, fix and resolve [issues](https://github.com/bower/bower/issues) -* Developing the [new registry server](https://github.com/bower/registry/tree/node_rewrite) - * Hooking in to Elastic Search rather than the in-memory search - * Getting bower/registry-client to talk to the new server without breaking backwards compatibility - * DevOps for the server ## Team Meetings -We meet on Monday at 1:00pm PST, 9:00pm UTC in #bower on Freenode. [The meeting notes](http://goo.gl/NJZ1o2). - -
- -Following these guidelines helps to communicate that you respect the time of -the developers managing and developing this open source project. In return, -they should reciprocate that respect in addressing your issue, assessing -changes, and helping you finalize your pull requests. +We communicate through a channel on slack: https://gitter.im/bower +If you'd like to attend the meetings, please fill the [support form](http://goo.gl/forms/P1ndzCNoiG), and you'll get an invite. ## Using the issue tracker @@ -38,7 +26,8 @@ The issue tracker is the preferred channel for [bug reports](#bugs), requests](#pull-requests), but please respect the following restrictions: * Please **do not** use the issue tracker for personal support requests. Use - [Stack Overflow](http://stackoverflow.com/questions/tagged/bower), our + [Stack Overflow](http://stackoverflow.com/questions/tagged/bower) + [Gitter Channel](https://gitter.im/bower/bower) [Mailing List](http://groups.google.com/group/twitter-bower) (twitter-bower@googlegroups.com), or [#bower](http://webchat.freenode.net/?channels=bower) on Freenode. @@ -46,7 +35,6 @@ requests](#pull-requests), but please respect the following restrictions: * Please **do not** derail or troll issues. Keep the discussion on topic and respect the opinions of others. - ## Bug reports From 6614a436586b76fede99804a8fe02b89303df89d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 24 Oct 2015 12:17:23 +0200 Subject: [PATCH 0714/1021] Bump to 1.6.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9214abba8..ffc82cf81 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.4", + "version": "1.6.5", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 8a435dff27930bd25923ba1eae650bc25afedba4 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 15 Nov 2015 11:51:45 +0100 Subject: [PATCH 0715/1021] Update to newest npm in appveyor builds --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 1984cdc66..7f770b283 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,7 +22,7 @@ install: # Get the latest stable version of Node 0.STABLE.latest - ps: Install-Product node $env:nodejs_version # Install stable version of npm - - npm install -g npm@^2.0.0 + - npm install -g npm@^3.0.0 # Install subversion - choco install svn -y # Install bower From c6d89b79b4b9e502bb504fb54213c31223236867 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 15 Nov 2015 12:02:39 +0100 Subject: [PATCH 0716/1021] Remove npm-shrinkwrap from devDependencies (issues with npm@3.x) --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index ffc82cf81..5f3f6813b 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,6 @@ "multiline": "^1.0.2", "nock": "^2.13.0", "node-uuid": "^1.4.2", - "npm-shrinkwrap": "^5.4.1", "proxyquire": "^1.3.0", "spawn-sync": "^1.0.5" }, From 0a0dc8cef9a27be9540524078caee39d6af3c45b Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 15 Nov 2015 12:51:41 +0100 Subject: [PATCH 0717/1021] Update spawn-sync to fix appveyor tests --- npm-shrinkwrap.json | 54 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 1 + 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index e1cd6ea7f..1d22dd5bb 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,6 +1,8 @@ { "name": "bower", - "version": "1.6.4", + "version": "1.6.5", + "npm-shrinkwrap-version": "5.4.1", + "node-version": "v4.1.1", "dependencies": { "abbrev": { "version": "1.0.7", @@ -970,6 +972,56 @@ } } }, + "spawn-sync": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.14.tgz", + "dependencies": { + "concat-stream": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.1.tgz", + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "readable-stream": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.4.tgz", + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "process-nextick-args": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + } + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" + } + } + }, + "os-shim": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz" + } + } + }, "stringify-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-1.0.1.tgz" diff --git a/package.json b/package.json index 5f3f6813b..7d5b2efd2 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "rimraf": "^2.2.8", "semver": "^2.3.0", "shell-quote": "^1.4.2", + "spawn-sync": "^1.0.14", "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", "tmp": "0.0.24", From 37aab9c72e74a794b64d842fa65d9f75222f57b9 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 15 Nov 2015 13:01:24 +0100 Subject: [PATCH 0718/1021] Downgrade spawn-sync for appveyor --- npm-shrinkwrap.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 1d22dd5bb..7f7a23596 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -973,8 +973,8 @@ } }, "spawn-sync": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.14.tgz", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.13.tgz", "dependencies": { "concat-stream": { "version": "1.5.1", diff --git a/package.json b/package.json index 7d5b2efd2..0d6154298 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "rimraf": "^2.2.8", "semver": "^2.3.0", "shell-quote": "^1.4.2", - "spawn-sync": "^1.0.14", + "spawn-sync": "^1.0.13", "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", "tmp": "0.0.24", From 619482164323cfea9e664811420483206b3480db Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 15 Nov 2015 13:06:16 +0100 Subject: [PATCH 0719/1021] Skip installing npm and svn for appveyor --- appveyor.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 7f770b283..fc5dca047 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -21,10 +21,6 @@ matrix: install: # Get the latest stable version of Node 0.STABLE.latest - ps: Install-Product node $env:nodejs_version - # Install stable version of npm - - npm install -g npm@^3.0.0 - # Install subversion - - choco install svn -y # Install bower - npm install @@ -33,6 +29,8 @@ test_script: # Output useful info for debugging. - node --version - npm --version + - git --version + - svn --version - cmd: npm test # Don't actually build. From 5a72dae2c8802cc9126f83bd2dc70fbb7f7c3a45 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 15 Nov 2015 13:10:10 +0100 Subject: [PATCH 0720/1021] Build on both node 0.10 and 0.12 on appveyor --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index fc5dca047..6d4ccc8c0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,12 +10,12 @@ init: environment: matrix: - nodejs_version: "0.10" - # - nodejs_version: "0.11" + - nodejs_version: "0.12" # Allow failing jobs for bleeding-edge Node.js versions. matrix: allow_failures: - - nodejs_version: "0.11" + - nodejs_version: "0.10" # Install scripts. (runs after repo cloning) install: From 74eba8d2e80f6e0b119f04620a8e534f62d225d2 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 15 Nov 2015 13:14:28 +0100 Subject: [PATCH 0721/1021] Move spawn-sync back to devDependencies... --- npm-shrinkwrap.json | 50 --------------------------------------------- package.json | 3 +-- 2 files changed, 1 insertion(+), 52 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 7f7a23596..ead0c9af4 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -972,56 +972,6 @@ } } }, - "spawn-sync": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.13.tgz", - "dependencies": { - "concat-stream": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.1.tgz", - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - }, - "readable-stream": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.4.tgz", - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - }, - "process-nextick-args": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz" - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - } - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" - } - } - }, - "os-shim": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz" - } - } - }, "stringify-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-1.0.1.tgz" diff --git a/package.json b/package.json index 0d6154298..388d4625d 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,6 @@ "rimraf": "^2.2.8", "semver": "^2.3.0", "shell-quote": "^1.4.2", - "spawn-sync": "^1.0.13", "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", "tmp": "0.0.24", @@ -79,7 +78,7 @@ "nock": "^2.13.0", "node-uuid": "^1.4.2", "proxyquire": "^1.3.0", - "spawn-sync": "^1.0.5" + "spawn-sync": "^1.0.13" }, "bundledDependencies": [ "abbrev", From c6ed215260239af8c997e0d68aad7d7ecc38cee1 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 15 Nov 2015 13:15:05 +0100 Subject: [PATCH 0722/1021] Re-order scripts for appveyor build --- appveyor.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 6d4ccc8c0..147eea4d9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -21,16 +21,16 @@ matrix: install: # Get the latest stable version of Node 0.STABLE.latest - ps: Install-Product node $env:nodejs_version - # Install bower - - npm install - -# Post-install test scripts. -test_script: # Output useful info for debugging. - node --version - npm --version - git --version - svn --version + # Install all dependencies + - npm install + +# Post-install test scripts. +test_script: - cmd: npm test # Don't actually build. From 38fa1b68587aefcdae702f852d3b17edd9fe5c1d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 15 Nov 2015 13:18:33 +0100 Subject: [PATCH 0723/1021] Downgrade spawn-sync to 1.0.13 (windows build) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 388d4625d..b4651da97 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "nock": "^2.13.0", "node-uuid": "^1.4.2", "proxyquire": "^1.3.0", - "spawn-sync": "^1.0.13" + "spawn-sync": "1.0.13" }, "bundledDependencies": [ "abbrev", From 3ab71f27fff4e5554ca6d9295a85fae47705fc40 Mon Sep 17 00:00:00 2001 From: Rob Simpson Date: Mon, 16 Nov 2015 16:06:11 -0500 Subject: [PATCH 0724/1021] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9862d06e8..71b1b523d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bower -Bower needs resources for its maintenance. Please fill [Support Declaration](http://goo.gl/forms/P1ndzCNoiG) if you think you can help. +> Bower needs resources for its maintenance. Please fill [Support Declaration](http://goo.gl/forms/P1ndzCNoiG) if you think you can help. [![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)](https://ci.appveyor.com/project/sheerun/bower/history) [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) From 93be2fef6d4cdabb63d3590152e8a19333feda3e Mon Sep 17 00:00:00 2001 From: Rob Simpson Date: Mon, 16 Nov 2015 16:08:04 -0500 Subject: [PATCH 0725/1021] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 71b1b523d..8876b3ff7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Bower +# Bower - A package manager for the web > Bower needs resources for its maintenance. Please fill [Support Declaration](http://goo.gl/forms/P1ndzCNoiG) if you think you can help. @@ -8,8 +8,6 @@ --- -> A package manager for the web - Bower offers a generic, unopinionated solution to the problem of **front-end package management**, while exposing the package dependency model via an API that can be consumed by a more opinionated build stack. There are no system wide dependencies, no dependencies are shared between different apps, and the dependency tree is flat. Bower runs over Git, and is package-agnostic. A packaged component can be made up of any type of asset, and use any type of transport (e.g., AMD, CommonJS, etc.). From 814180d12981bba7f6384d9106004e18629effcb Mon Sep 17 00:00:00 2001 From: Rob Simpson Date: Mon, 16 Nov 2015 21:25:48 -0500 Subject: [PATCH 0726/1021] update bug report link to point to wiki --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8876b3ff7..017828eed 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ Bower can be configured using JSON in a `.bowerrc` file. Read over available opt We welcome [contributions](https://github.com/bower/bower/graphs/contributors) of all kinds from anyone. Please take a moment to review the [guidelines for contributing](CONTRIBUTING.md). -* [Bug reports](CONTRIBUTING.md#bugs) +* [Bug reports](wiki/Report-a-Bug) * [Feature requests](CONTRIBUTING.md#features) * [Pull requests](CONTRIBUTING.md#pull-requests) From 468657bfe2b50040f8d7b29a5ff0de7e9423a1c7 Mon Sep 17 00:00:00 2001 From: Rob Simpson Date: Mon, 16 Nov 2015 21:27:54 -0500 Subject: [PATCH 0727/1021] bug report link fix on readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 017828eed..41050c017 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ Bower can be configured using JSON in a `.bowerrc` file. Read over available opt We welcome [contributions](https://github.com/bower/bower/graphs/contributors) of all kinds from anyone. Please take a moment to review the [guidelines for contributing](CONTRIBUTING.md). -* [Bug reports](wiki/Report-a-Bug) +* [Bug reports](https://github.com/bower/bower/wiki/Report-a-Bug) * [Feature requests](CONTRIBUTING.md#features) * [Pull requests](CONTRIBUTING.md#pull-requests) From ce15df27ca728349799b3c6a2db1a5f1e9b4e9e8 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 15 Nov 2015 14:25:27 +0100 Subject: [PATCH 0728/1021] Properly destroy read stream for downloads --- lib/util/download.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/util/download.js b/lib/util/download.js index 91f60f01f..c9287d07b 100644 --- a/lib/util/download.js +++ b/lib/util/download.js @@ -5,6 +5,7 @@ var mout = require('mout'); var retry = require('retry'); var createError = require('./createError'); var createWriteStream = require('fs-write-stream-atomic'); +var destroy = require('destroy'); var errorCodes = [ 'EADDRINFO', @@ -108,11 +109,12 @@ function fetch(url, file, options) { // Pipe read stream to write stream writeStream.on('error', function (error) { - writeStream.destroy(); + destroy(req); deferred.reject(error); }); writeStream.on('finish', function () { + destroy(req); deferred.resolve(response); }); From 9fdd96c92bbda4553afedba26d198f2c21523b98 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 16 Nov 2015 00:58:40 +0100 Subject: [PATCH 0729/1021] Update fs-write-stream-atomic to fork with timing fix It turned out that removing files synchronously on windows can cause issues. This commit makes Appveyor build for Windows little better. --- npm-shrinkwrap.json | 5 +++-- package.json | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index ead0c9af4..f8314f23d 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -2,7 +2,7 @@ "name": "bower", "version": "1.6.5", "npm-shrinkwrap-version": "5.4.1", - "node-version": "v4.1.1", + "node-version": "v0.10.40", "dependencies": { "abbrev": { "version": "1.0.7", @@ -284,7 +284,8 @@ }, "fs-write-stream-atomic": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.4.tgz", + "from": "fs-write-stream-atomic@git://github.com/sheerun/fs-write-stream-atomic#81caa0fad60125bf9a208b77ae3217119a29f474", + "resolved": "git://github.com/sheerun/fs-write-stream-atomic#81caa0fad60125bf9a208b77ae3217119a29f474", "dependencies": { "graceful-fs": { "version": "4.1.2", diff --git a/package.json b/package.json index b4651da97..cd8844428 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "configstore": "^0.3.2", "decompress-zip": "^0.1.0", "destroy": "^1.0.3", - "fs-write-stream-atomic": "^1.0.4", + "fs-write-stream-atomic": "git://github.com/sheerun/fs-write-stream-atomic", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", "github": "^0.2.3", From 15f8a30cd4fcc39de7e97cb2b4b1bdc69c08799e Mon Sep 17 00:00:00 2001 From: Adriaan Thomas Date: Tue, 17 Nov 2015 13:31:40 +0100 Subject: [PATCH 0730/1021] Also load custom CA file for "default" --- packages/bower-config/lib/Config.js | 20 +++++++++++--------- packages/bower-config/test/test.js | 4 ++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index 19a7852df..470ddfd4b 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -54,16 +54,18 @@ function loadCAs(caConfig) { // If a ca file path has been specified, expand that here to the file's // contents. As a user can specify these individually, we must load them // one by one. - if (caConfig.search) { - caConfig.search = caConfig.search.map(function(s) { - return readCertFile(s); - }); - } - ['register', 'publish'].forEach(function(p) { - if (caConfig[p]) { - caConfig[p] = readCertFile(caConfig[p]); + for (var p in caConfig) { + if (caConfig.hasOwnProperty(p)) { + var prop = caConfig[p]; + if (Array.isArray(prop)) { + caConfig[p] = prop.map(function(s) { + return readCertFile(s); + }); + } else if (prop) { + caConfig[p] = readCertFile(prop); + } } - }); + } } Config.prototype.toObject = function () { diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index 9546645fd..469053a06 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -120,7 +120,7 @@ describe('NPM Config on package.json', function () { var config = require('../lib/Config') .read(path.resolve('test/assets/custom-ca')); - ['register', 'publish'].forEach(function (p) { + ['register', 'publish', 'default'].forEach(function (p) { assertCAContents(config.ca[p], 'config.ca.' + p); }); @@ -136,7 +136,7 @@ describe('NPM Config on package.json', function () { var config = require('../lib/Config') .read(path.resolve('test/assets/custom-ca-embed')); - ['register', 'publish'].forEach(function (p) { + ['register', 'publish', 'default'].forEach(function (p) { assertCAContents(config.ca[p], 'config.ca.' + p); }); From c8042b4781253f55c7a04d7421a60b577d980138 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 18 Nov 2015 14:50:00 +0100 Subject: [PATCH 0731/1021] Fix tests on node 0.10 by updating nock --- npm-shrinkwrap.json | 6 +++--- package.json | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index f8314f23d..d7ed491b4 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -283,9 +283,9 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz" }, "fs-write-stream-atomic": { - "version": "1.0.4", - "from": "fs-write-stream-atomic@git://github.com/sheerun/fs-write-stream-atomic#81caa0fad60125bf9a208b77ae3217119a29f474", - "resolved": "git://github.com/sheerun/fs-write-stream-atomic#81caa0fad60125bf9a208b77ae3217119a29f474", + "version": "1.0.4-fixed", + "from": "fs-write-stream-atomic@git://github.com/sheerun/fs-write-stream-atomic#d7450afc0cfd71162952b7527e6882a9702fba10", + "resolved": "git://github.com/sheerun/fs-write-stream-atomic#d7450afc0cfd71162952b7527e6882a9702fba10", "dependencies": { "graceful-fs": { "version": "4.1.2", diff --git a/package.json b/package.json index cd8844428..f97870c10 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "configstore": "^0.3.2", "decompress-zip": "^0.1.0", "destroy": "^1.0.3", - "fs-write-stream-atomic": "git://github.com/sheerun/fs-write-stream-atomic", + "fs-write-stream-atomic": "git://github.com/sheerun/fs-write-stream-atomic#v1.0.4-fixed", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", "github": "^0.2.3", @@ -75,7 +75,7 @@ "load-grunt-tasks": "^2.0.0", "mocha": "^2.1.0", "multiline": "^1.0.2", - "nock": "^2.13.0", + "nock": "^3.1.0", "node-uuid": "^1.4.2", "proxyquire": "^1.3.0", "spawn-sync": "1.0.13" From 89286e628b124136d90d69f039ac52beaf7a89eb Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 18 Nov 2015 15:03:44 +0100 Subject: [PATCH 0732/1021] Update to fixed version of fs-write-stream-atomic --- npm-shrinkwrap.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index d7ed491b4..794aa3e86 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -283,9 +283,9 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz" }, "fs-write-stream-atomic": { - "version": "1.0.4-fixed", - "from": "fs-write-stream-atomic@git://github.com/sheerun/fs-write-stream-atomic#d7450afc0cfd71162952b7527e6882a9702fba10", - "resolved": "git://github.com/sheerun/fs-write-stream-atomic#d7450afc0cfd71162952b7527e6882a9702fba10", + "version": "1.0.4-fix", + "from": "fs-write-stream-atomic@git://github.com/sheerun/fs-write-stream-atomic#ac0f001d165564b3763da3252d5bff327c26aea9", + "resolved": "git://github.com/sheerun/fs-write-stream-atomic#ac0f001d165564b3763da3252d5bff327c26aea9", "dependencies": { "graceful-fs": { "version": "4.1.2", diff --git a/package.json b/package.json index f97870c10..aeecd2e7c 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "configstore": "^0.3.2", "decompress-zip": "^0.1.0", "destroy": "^1.0.3", - "fs-write-stream-atomic": "git://github.com/sheerun/fs-write-stream-atomic#v1.0.4-fixed", + "fs-write-stream-atomic": "git://github.com/sheerun/fs-write-stream-atomic#v1.0.4-fix", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", "github": "^0.2.3", From e51bf20e72f1fc1e198390f45499d0f33ad768b5 Mon Sep 17 00:00:00 2001 From: kevcenteno Date: Thu, 19 Nov 2015 10:33:32 -0500 Subject: [PATCH 0733/1021] Show error if .bowerrc is a directory --- packages/bower-config/lib/util/rc.js | 6 ++++++ packages/bower-config/test/util/rc.js | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 4711f8b9c..39871a5ad 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -84,6 +84,12 @@ function json(file) { } else { // This is multiple json files file.forEach(function(filename) { + if (fs.statSync(filename).isDirectory()) { + var error; + error = new Error(filename + ' should not be a directory'); + error.code = 'EFILEISDIR'; + throw error; + } var json = fs.readFileSync(filename).toString(); json = parse(json, filename); content = object.merge(content, json); diff --git a/packages/bower-config/test/util/rc.js b/packages/bower-config/test/util/rc.js index a069182ce..192fd63eb 100644 --- a/packages/bower-config/test/util/rc.js +++ b/packages/bower-config/test/util/rc.js @@ -3,6 +3,7 @@ var helpers = require('../helpers'); describe('rc', function() { var tempDir = new helpers.TempDir(); + var tempDirBowerrc = new helpers.TempDir(); var rc = require('../../lib/util/rc'); @@ -18,7 +19,14 @@ describe('rc', function() { }, 'child3/bower.json': { name: 'without-bowerrc' + }, + }); + + tempDirBowerrc.prepare({ + '.bowerrc/foo': { + key: 'bar' } + }); it('correctly reads .bowerrc files', function() { @@ -48,4 +56,13 @@ describe('rc', function() { expect(config.key).to.eql('value'); expect(config.key2).to.eql(undefined); }); + + it('throws an easy to understand error if .bowerrc is a dir', function() { + // Gotta wrap this to catch the error + var config = function () { + rc('bower', tempDirBowerrc.path); + }; + + expect(config).to.throwError(/should not be a directory/); + }); }); From 718db0309f34bd153e1c75d6d300cf664034faad Mon Sep 17 00:00:00 2001 From: Daijiro Wachi Date: Thu, 19 Nov 2015 21:36:28 +0100 Subject: [PATCH 0734/1021] Supports ~/ paths to cwd field in .bowerrc + Add untildify module + Update config.js to convert tilde path to home path Fixes #1784 --- lib/config.js | 4 ++++ package.json | 1 + 2 files changed, 5 insertions(+) diff --git a/lib/config.js b/lib/config.js index af0a27849..16fa0b190 100644 --- a/lib/config.js +++ b/lib/config.js @@ -2,6 +2,7 @@ var tty = require('tty'); var object = require('mout').object; var bowerConfig = require('bower-config'); var Configstore = require('configstore'); +var untildify = require('untildify'); var current; @@ -48,6 +49,9 @@ function readCachedConfig(cwd, overwrites) { })); } + // Convert tilde path to home path + config.cwd = untildify(config.cwd); + return config; } diff --git a/package.json b/package.json index aeecd2e7c..d5a1645af 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", "tmp": "0.0.24", + "untildify": "^2.1.0", "update-notifier": "^0.3.0", "user-home": "^1.1.0", "which": "^1.0.8" From 49de3cca622b1d784674163465fbd0d18567be14 Mon Sep 17 00:00:00 2001 From: Daijiro Wachi Date: Thu, 19 Nov 2015 23:31:22 +0100 Subject: [PATCH 0735/1021] Add a test case to support ~/ paths to cwd field --- test/commands/install.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/commands/install.js b/test/commands/install.js index bc53acc22..f3e672b7f 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -2,6 +2,8 @@ var expect = require('expect.js'); var helpers = require('../helpers'); var nock = require('nock'); var fs = require('../../lib/util/fs'); +var untildify = require('untildify'); +var path = require('path'); describe('bower install', function () { @@ -384,4 +386,31 @@ describe('bower install', function () { nock.enableNetConnect(); }); }); + + it('Use tilde as home directly in cwd', function () { + package.prepare(); + + // Build a same path with the tempDir including a tilde + var cwd = '~'; + for (var i = 1; untildify('~').split(path.sep).length > i; i++) { + cwd += path.sep + '..'; + } + cwd += tempDir.getPath('.'); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: package.path + } + }, + '.bowerrc': { + cwd: cwd + } + }); + + return helpers.run(install).then(function() { + expect(tempDir.exists('bower_components/package')).to.be(true); + }); + }); }); From 42cd2e584f90e3c5ae439d1e93eac5972228449f Mon Sep 17 00:00:00 2001 From: Daijiro Wachi Date: Thu, 19 Nov 2015 23:46:22 +0100 Subject: [PATCH 0736/1021] Update npm-shrinkwrap.json to add untildify --- npm-shrinkwrap.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 794aa3e86..20b1365f5 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1067,6 +1067,16 @@ "version": "0.0.24", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz" }, + "untildify": { + "version": "2.1.0", + "resolved": "http://registry.npmjs.org/untildify/-/untildify-2.1.0.tgz", + "dependencies": { + "os-homedir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" + } + } + }, "update-notifier": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-0.3.2.tgz", From 50bfd14968fa8dd1ca51d402f12b7bdcb88be48d Mon Sep 17 00:00:00 2001 From: Ryan Temple Date: Mon, 23 Nov 2015 22:45:45 +0000 Subject: [PATCH 0737/1021] updated to respect the bowerrc in the cwd passed in as command line argument --- packages/bower-config/lib/util/rc.js | 4 ++++ packages/bower-config/test/util/rc.js | 18 +++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 39871a5ad..d3c3d2d5b 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -31,6 +31,8 @@ function rc(name, cwd, argv) { json(find('.' + name + 'rc', cwd)), env('npm_package_config_' + name + '_'), env(name + '_'), + // If we have specified a cwd then the bowerrc from there takes precedence + !argvConfig.cwd ? {} : json(path.join(argvConfig.cwd, '.' + name + 'rc')), argvConfig ]); } else { @@ -42,6 +44,8 @@ function rc(name, cwd, argv) { json(path.join(paths.config, name + 'rc')), env('npm_package_config_' + name + '_'), env(name + '_'), + // If we have specified a cwd then the bowerrc from there takes precedence + !argvConfig.cwd ? {} : json(path.join(argvConfig.cwd, '.' + name + 'rc')), argvConfig ]); } diff --git a/packages/bower-config/test/util/rc.js b/packages/bower-config/test/util/rc.js index 192fd63eb..bc4f2fad9 100644 --- a/packages/bower-config/test/util/rc.js +++ b/packages/bower-config/test/util/rc.js @@ -20,13 +20,16 @@ describe('rc', function() { 'child3/bower.json': { name: 'without-bowerrc' }, + 'other_dir/.bowerrc': { + key: 'othervalue' + } }); tempDirBowerrc.prepare({ '.bowerrc/foo': { key: 'bar' } - + }); it('correctly reads .bowerrc files', function() { @@ -57,6 +60,19 @@ describe('rc', function() { expect(config.key2).to.eql(undefined); }); + it('loads the .bowerrc file from the cwd specified on the command line', function(){ + var argv = { + 'config': { + 'cwd': tempDir.path + '/other_dir/' + } + }; + + var config = rc('bower', tempDir.path, argv); + + expect(config.key).to.eql('othervalue'); + + }); + it('throws an easy to understand error if .bowerrc is a dir', function() { // Gotta wrap this to catch the error var config = function () { From 2f72cd4b7d889a6249ab0f6172c90fbe9ab86260 Mon Sep 17 00:00:00 2001 From: Rob Simpson Date: Tue, 24 Nov 2015 00:10:47 -0500 Subject: [PATCH 0738/1021] Adding contributing link to CONTRIBUTING.md We now have a section in the wiki for contributors so I added a link to this until all of it can be merged together. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6f3995791..a1b830539 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to Bower -Bower is a large community project with many different developers contributing at all levels to the project. We're **actively** looking for more contributors right now. If you're interested in becoming Bower maintainer or supporting in in any way, please full the following form: http://goo.gl/forms/P1ndzCNoiG +Bower is a large community project with many different developers contributing at all levels to the project. We're **actively** looking for more contributors right now. If you're interested in becoming Bower maintainer or supporting in in any way, please full the following form: http://goo.gl/forms/P1ndzCNoiG. There is more information about [contributing](https://github.com/bower/bower/wiki/Contributor-Guidelines) in the Wiki. ## Casual Involvement From fbd02852a3a804162c9d9369d3cbf1bdc1a472cc Mon Sep 17 00:00:00 2001 From: Riyadh Al Nur Date: Tue, 24 Nov 2015 13:11:54 +0600 Subject: [PATCH 0739/1021] Added newer Node versions to Travis ADDED/UPDATED: - Updated Travis file to not test against `iojs` anymore - Added versions 4 and 5 of Node to test against on Travis --- packages/bower-config/.travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/bower-config/.travis.yml b/packages/bower-config/.travis.yml index dedfc07f2..a78e23d5e 100644 --- a/packages/bower-config/.travis.yml +++ b/packages/bower-config/.travis.yml @@ -1,6 +1,7 @@ sudo: false language: node_js node_js: - - 'iojs' + - '5' + - '4' - '0.12' - '0.10' From 5a9c0991885b3980812b31a78a8c827f9364e8ce Mon Sep 17 00:00:00 2001 From: Riyadh Al Nur Date: Tue, 24 Nov 2015 21:25:11 +0600 Subject: [PATCH 0740/1021] Revert "updated to respect the bowerrc in the cwd passed in as command line argument" --- packages/bower-config/lib/util/rc.js | 4 ---- packages/bower-config/test/util/rc.js | 18 +----------------- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index d3c3d2d5b..39871a5ad 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -31,8 +31,6 @@ function rc(name, cwd, argv) { json(find('.' + name + 'rc', cwd)), env('npm_package_config_' + name + '_'), env(name + '_'), - // If we have specified a cwd then the bowerrc from there takes precedence - !argvConfig.cwd ? {} : json(path.join(argvConfig.cwd, '.' + name + 'rc')), argvConfig ]); } else { @@ -44,8 +42,6 @@ function rc(name, cwd, argv) { json(path.join(paths.config, name + 'rc')), env('npm_package_config_' + name + '_'), env(name + '_'), - // If we have specified a cwd then the bowerrc from there takes precedence - !argvConfig.cwd ? {} : json(path.join(argvConfig.cwd, '.' + name + 'rc')), argvConfig ]); } diff --git a/packages/bower-config/test/util/rc.js b/packages/bower-config/test/util/rc.js index bc4f2fad9..192fd63eb 100644 --- a/packages/bower-config/test/util/rc.js +++ b/packages/bower-config/test/util/rc.js @@ -20,16 +20,13 @@ describe('rc', function() { 'child3/bower.json': { name: 'without-bowerrc' }, - 'other_dir/.bowerrc': { - key: 'othervalue' - } }); tempDirBowerrc.prepare({ '.bowerrc/foo': { key: 'bar' } - + }); it('correctly reads .bowerrc files', function() { @@ -60,19 +57,6 @@ describe('rc', function() { expect(config.key2).to.eql(undefined); }); - it('loads the .bowerrc file from the cwd specified on the command line', function(){ - var argv = { - 'config': { - 'cwd': tempDir.path + '/other_dir/' - } - }; - - var config = rc('bower', tempDir.path, argv); - - expect(config.key).to.eql('othervalue'); - - }); - it('throws an easy to understand error if .bowerrc is a dir', function() { // Gotta wrap this to catch the error var config = function () { From 3d4f9cd9192fbafecaa9e6222a5865113cbebbfa Mon Sep 17 00:00:00 2001 From: Vlad Filippov Date: Tue, 24 Nov 2015 14:21:27 -0500 Subject: [PATCH 0741/1021] Fix shallow clone host --- lib/core/resolvers/GitRemoteResolver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/resolvers/GitRemoteResolver.js b/lib/core/resolvers/GitRemoteResolver.js index 05fa0bedc..1a8e9be90 100644 --- a/lib/core/resolvers/GitRemoteResolver.js +++ b/lib/core/resolvers/GitRemoteResolver.js @@ -119,7 +119,7 @@ GitRemoteResolver.prototype._fastClone = function (resolution) { return this._shallowClone().then(function (shallowCloningSupported) { // If the host does not support shallow clones, we don't use --depth=1 - if (shallowCloningSupported && !GitRemoteResolver._noShallow.get(this._host)) { + if (shallowCloningSupported && !GitRemoteResolver._noShallow.get(that._host)) { args.push('--depth', 1); } From 51de67cc739f606a293dbd41464cd5919f3b7faf Mon Sep 17 00:00:00 2001 From: Paulo Pires Date: Wed, 25 Nov 2015 09:33:03 -0200 Subject: [PATCH 0742/1021] added major versions 5 and 4 to appveyor --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index 147eea4d9..a4cb95397 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,6 +11,8 @@ environment: matrix: - nodejs_version: "0.10" - nodejs_version: "0.12" + - nodejs_version: "5" + - nodejs_version: "4" # Allow failing jobs for bleeding-edge Node.js versions. matrix: From 67bd5d026f58ba2f443ac9aa5f63d1b221c83fa2 Mon Sep 17 00:00:00 2001 From: Vlad Filippov Date: Wed, 25 Nov 2015 10:45:42 -0500 Subject: [PATCH 0743/1021] Bump to 1.6.6 --- CHANGELOG.md | 9 +++++++++ package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9755f0e73..143edb556 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 1.6.6 - 2015-11-25 + +- Fixes regression with the published npm version + +## 1.6.5 - 2015-10-24 + +- Updates to tests and documentation +- Fixes passing options when requesting downloads + ## 1.6.4 - 2015-10-24 - Fix ignoring dependencies on multiple install run ([#1970](https://github.com/bower/bower/pull/1970)) diff --git a/package.json b/package.json index ffc82cf81..32850072c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.5", + "version": "1.6.6", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From e7868f0fb14ea61e6116f0bc8be3c50902a74c52 Mon Sep 17 00:00:00 2001 From: Vlad Filippov Date: Wed, 25 Nov 2015 10:54:11 -0500 Subject: [PATCH 0744/1021] Changelog updates [skip ci] --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9755f0e73..ca2d73115 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 1.6.6 - 2015-11-25 + +- Fixes regression with the published npm version + +## 1.6.5 - 2015-10-24 + +- Updates to tests and documentation +- Fixes passing options when requesting downloads + ## 1.6.4 - 2015-10-24 - Fix ignoring dependencies on multiple install run ([#1970](https://github.com/bower/bower/pull/1970)) @@ -36,6 +45,10 @@ Fix dependency issues of 1.6.0. Reverted release. Reverted release. +## 1.5.4 - 2015-11-24 + +- [fix] Lock lru-cache dependency to 2.7.0 + ## 1.5.3 - 2015-09-24 - Revert auto sorting of bower dependencies, fixes ([#1897](https://github.com/bower/bower/issues/1897)) @@ -61,6 +74,10 @@ Reverted release. - Make bower commands work from subdirectories ([#1866](https://github.com/bower/bower/issues/1866)) - No longer prefer installing bower as global module ([#1865](https://github.com/bower/bower/issues/1865)) +## 1.4.2 - 2015-11-24 + +- [fix] Lock lru-cache dependency to 2.7.0 + ## 1.4.1 - 2015-04-01 - [fix] Reading .bowerrc upwards directory tree ([#1763](https://github.com/bower/bower/issues/1763)) From da8ec1e4ab76993cb434a6e50a671d77d35ac5a6 Mon Sep 17 00:00:00 2001 From: Hector Leon Zarco Garcia Date: Wed, 25 Nov 2015 23:58:30 +0100 Subject: [PATCH 0745/1021] Move abbreviations to a different file --- lib/abbreviations.js | 30 ++++++++++++++++++++++++++++++ lib/index.js | 26 +------------------------- test/commands/bower.js | 35 ++++++++++++++--------------------- test/commands/index.js | 2 -- test/helpers.js | 11 ++++++++++- 5 files changed, 55 insertions(+), 49 deletions(-) create mode 100644 lib/abbreviations.js diff --git a/lib/abbreviations.js b/lib/abbreviations.js new file mode 100644 index 000000000..e27c32675 --- /dev/null +++ b/lib/abbreviations.js @@ -0,0 +1,30 @@ +var abbrev = require('abbrev'); +var mout = require('mout'); + +function expandNames(obj, prefix, stack) { + prefix = prefix || ''; + stack = stack || []; + + mout.object.forOwn(obj, function (value, name) { + name = prefix + name; + + stack.push(name); + + if (typeof value === 'object' && !value.line) { + expandNames(value, name + ' ', stack); + } + }); + + return stack; +} + +module.exports = function(commands) { + var abbreviations = abbrev(expandNames(commands)); + + abbreviations.i = 'install'; + abbreviations.rm = 'uninstall'; + abbreviations.unlink = 'uninstall'; + abbreviations.ls = 'list'; + + return abbreviations; +}; diff --git a/lib/index.js b/lib/index.js index 1efed6af1..28710aa89 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,30 +1,6 @@ -var abbrev = require('abbrev'); -var mout = require('mout'); var commands = require('./commands'); var pkg = require('../package.json'); - -var abbreviations = abbrev(expandNames(commands)); -abbreviations.i = 'install'; -abbreviations.rm = 'uninstall'; -abbreviations.unlink = 'uninstall'; -abbreviations.ls = 'list'; - -function expandNames(obj, prefix, stack) { - prefix = prefix || ''; - stack = stack || []; - - mout.object.forOwn(obj, function (value, name) { - name = prefix + name; - - stack.push(name); - - if (typeof value === 'object' && !value.line) { - expandNames(value, name + ' ', stack); - } - }); - - return stack; -} +var abbreviations = require('./abbreviations')(commands); function clearRuntimeCache() { // Note that in edge cases, some architecture components instance's diff --git a/test/commands/bower.js b/test/commands/bower.js index e69785211..31c801f42 100644 --- a/test/commands/bower.js +++ b/test/commands/bower.js @@ -1,31 +1,24 @@ var expect = require('expect.js'); -var helpers = require('../helpers'); +var runBin = require('../helpers').runBin; describe('bower', function () { + process.env.CI = '1'; - var oldStdout; - var text; + it('runs bower installation', function () { + var result = runBin(); + var text = result.stdout.toString(); - before(function() { - oldStdout = process.stdout.write; - text = ''; - - process.stdout.write = function(args) { - text += args; - }; + expect(text).to.contain('Usage:'); + expect(text).to.contain('Commands:'); }); +}); - it('runs bower installation', function (done) { - helpers.require('bin/bower'); - - setTimeout(function() { - done(); - }, 250); - }); +describe('abbreviations', function () { + it('Returns same value than the full command', function() { + var abbr = runBin(['ls']); + var full = runBin(['list']); - after(function() { - process.stdout.write = oldStdout; - expect(text).to.contain('Usage:'); - expect(text).to.contain('Commands:'); + expect(abbr.status).to.be(0); + expect(abbr.stdout.toString()).to.be.equal(full.stdout.toString()); }); }); diff --git a/test/commands/index.js b/test/commands/index.js index 505fcfe38..916bbc292 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -15,7 +15,5 @@ describe('integration tests', function () { require('./uninstall'); require('./update'); require('./version'); - - // run last because it changes defaults require('./bower'); }); diff --git a/test/helpers.js b/test/helpers.js index 24b119682..024afbffa 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -10,7 +10,6 @@ var fs = require('../lib/util/fs'); var glob = require('glob'); var os = require('os'); var which = require('which'); -var path = require('path'); var proxyquire = require('proxyquire').noCallThru().noPreserveCache(); var spawnSync = require('spawn-sync'); var config = require('../lib/config'); @@ -298,3 +297,13 @@ exports.localUrl = function (localPath) { return localPath; }; + +// Returns the result of executing the bower binary + args +// example: runBin('install') --> $ bower install +exports.runBin = function (args) { + args = args || []; + + var name = path.resolve(__dirname, '../bin/bower'); + + return spawnSync(name, args); +}; From e11b60d8128429afeee1ab1161898ced16ee9389 Mon Sep 17 00:00:00 2001 From: Kun Yan Date: Thu, 26 Nov 2015 10:38:35 +0800 Subject: [PATCH 0746/1021] Add badge links to readme #2048 #2049 Signed-off-by: Kun Yan --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 41050c017..763aca770 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,12 @@ > Bower needs resources for its maintenance. Please fill [Support Declaration](http://goo.gl/forms/P1ndzCNoiG) if you think you can help. -[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)](https://ci.appveyor.com/project/sheerun/bower/history) [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) +[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) +[![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)](https://ci.appveyor.com/project/sheerun/bower/history) +[![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) +[![Join the chat at https://gitter.im/bower/bower](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/bower/bower?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Issue Stats](http://issuestats.com/github/bower/bower/badge/pr?style=flat)](http://issuestats.com/github/bower/bower) +[![Issue Stats](http://issuestats.com/github/bower/bower/badge/issue?style=flat)](http://issuestats.com/github/bower/bower) From 1a990f4563c6d2733b38792cc0c140d38ea57d12 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 26 Nov 2015 12:31:53 +0100 Subject: [PATCH 0747/1021] Release 1.6.7 --- CHANGELOG.md | 6 +++++- package.json | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 143edb556..a9e1da45c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.6.7 - 2015-11-26 + +- Bundless all the dependencies again + ## 1.6.6 - 2015-11-25 - Fixes regression with the published npm version @@ -14,7 +18,7 @@ - Fix ignoring dependencies on multiple install run ([#1970](https://github.com/bower/bower/pull/1970)) - Use --non-interactive when running svn client ([#1969](https://github.com/bower/bower/pull/1969)) - Fix downloading of URLs ending with slash ([#1956](https://github.com/bower/bower/pull/1956)) -- Add user-agent field for downloads by Bower ([#1960](https://github.com/bower/bower/pull/1960)) +- Add user-agent field for downloads by Bower ([#1960](https://github.com/bower/bower/pull/1960)) ## 1.6.3 - 2015-10-16 diff --git a/package.json b/package.json index 32850072c..4b428dee4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.6", + "version": "1.6.7", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From c4539aa603250ae3570449ffe690a58a5d627e36 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 26 Nov 2015 14:01:10 +0100 Subject: [PATCH 0748/1021] Update npm-shrinkwrap.json --- npm-shrinkwrap.json | 7 +++---- package.json | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 20b1365f5..197fc91dc 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,8 +1,8 @@ { "name": "bower", - "version": "1.6.5", + "version": "1.6.7", "npm-shrinkwrap-version": "5.4.1", - "node-version": "v0.10.40", + "node-version": "v4.1.1", "dependencies": { "abbrev": { "version": "1.0.7", @@ -284,8 +284,7 @@ }, "fs-write-stream-atomic": { "version": "1.0.4-fix", - "from": "fs-write-stream-atomic@git://github.com/sheerun/fs-write-stream-atomic#ac0f001d165564b3763da3252d5bff327c26aea9", - "resolved": "git://github.com/sheerun/fs-write-stream-atomic#ac0f001d165564b3763da3252d5bff327c26aea9", + "resolved": "git://github.com/sheerun/fs-write-stream-atomic.git#ac0f001d165564b3763da3252d5bff327c26aea9", "dependencies": { "graceful-fs": { "version": "4.1.2", diff --git a/package.json b/package.json index b0763da5d..2bb045e71 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "configstore": "^0.3.2", "decompress-zip": "^0.1.0", "destroy": "^1.0.3", - "fs-write-stream-atomic": "git://github.com/sheerun/fs-write-stream-atomic#v1.0.4-fix", + "fs-write-stream-atomic": "sheerun/fs-write-stream-atomic#v1.0.4-fix", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", "github": "^0.2.3", @@ -57,7 +57,7 @@ "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", "tmp": "0.0.24", - "untildify": "^2.1.0", + "untildify": "http://registry.npmjs.org/untildify/-/untildify-2.1.0.tgz", "update-notifier": "^0.3.0", "user-home": "^1.1.0", "which": "^1.0.8" From aaecbfab17d6b85de9289dd9987d292451478c1f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 26 Nov 2015 14:23:19 +0100 Subject: [PATCH 0749/1021] evert "Merge pull request #2027 from watilde/patch/supports-tilde" This reverts commit 2ff53fc4486273327482fb35df51c4f9bac7ad8b, reversing changes made to 89286e628b124136d90d69f039ac52beaf7a89eb. --- lib/config.js | 4 ---- npm-shrinkwrap.json | 10 ---------- package.json | 1 - test/commands/install.js | 29 ----------------------------- 4 files changed, 44 deletions(-) diff --git a/lib/config.js b/lib/config.js index 16fa0b190..af0a27849 100644 --- a/lib/config.js +++ b/lib/config.js @@ -2,7 +2,6 @@ var tty = require('tty'); var object = require('mout').object; var bowerConfig = require('bower-config'); var Configstore = require('configstore'); -var untildify = require('untildify'); var current; @@ -49,9 +48,6 @@ function readCachedConfig(cwd, overwrites) { })); } - // Convert tilde path to home path - config.cwd = untildify(config.cwd); - return config; } diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 197fc91dc..8461e02c7 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1066,16 +1066,6 @@ "version": "0.0.24", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz" }, - "untildify": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/untildify/-/untildify-2.1.0.tgz", - "dependencies": { - "os-homedir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" - } - } - }, "update-notifier": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-0.3.2.tgz", diff --git a/package.json b/package.json index 2bb045e71..18aa79901 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,6 @@ "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", "tmp": "0.0.24", - "untildify": "http://registry.npmjs.org/untildify/-/untildify-2.1.0.tgz", "update-notifier": "^0.3.0", "user-home": "^1.1.0", "which": "^1.0.8" diff --git a/test/commands/install.js b/test/commands/install.js index f3e672b7f..bc53acc22 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -2,8 +2,6 @@ var expect = require('expect.js'); var helpers = require('../helpers'); var nock = require('nock'); var fs = require('../../lib/util/fs'); -var untildify = require('untildify'); -var path = require('path'); describe('bower install', function () { @@ -386,31 +384,4 @@ describe('bower install', function () { nock.enableNetConnect(); }); }); - - it('Use tilde as home directly in cwd', function () { - package.prepare(); - - // Build a same path with the tempDir including a tilde - var cwd = '~'; - for (var i = 1; untildify('~').split(path.sep).length > i; i++) { - cwd += path.sep + '..'; - } - cwd += tempDir.getPath('.'); - - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package: package.path - } - }, - '.bowerrc': { - cwd: cwd - } - }); - - return helpers.run(install).then(function() { - expect(tempDir.exists('bower_components/package')).to.be(true); - }); - }); }); From b9c3f750eb55ad9e5ca1b560f0edf4150d308e99 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 26 Nov 2015 14:25:14 +0100 Subject: [PATCH 0750/1021] Remove npm-shrinkwrap.json (bundledDependencies are enough..) --- npm-shrinkwrap.json | 1308 ------------------------------------------- 1 file changed, 1308 deletions(-) delete mode 100644 npm-shrinkwrap.json diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json deleted file mode 100644 index 8461e02c7..000000000 --- a/npm-shrinkwrap.json +++ /dev/null @@ -1,1308 +0,0 @@ -{ - "name": "bower", - "version": "1.6.7", - "npm-shrinkwrap-version": "5.4.1", - "node-version": "v4.1.1", - "dependencies": { - "abbrev": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz" - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz" - }, - "bower-config": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bower-config/-/bower-config-1.2.2.tgz", - "dependencies": { - "graceful-fs": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz" - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz" - } - } - }, - "osenv": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", - "dependencies": { - "os-homedir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" - }, - "os-tmpdir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz" - } - } - } - } - }, - "bower-endpoint-parser": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz" - }, - "bower-json": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/bower-json/-/bower-json-0.4.0.tgz", - "dependencies": { - "deep-extend": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.2.11.tgz" - }, - "graceful-fs": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz" - }, - "intersect": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/intersect/-/intersect-0.0.3.tgz" - } - } - }, - "bower-logger": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/bower-logger/-/bower-logger-0.2.2.tgz" - }, - "bower-registry-client": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/bower-registry-client/-/bower-registry-client-1.0.0.tgz", - "dependencies": { - "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz" - }, - "graceful-fs": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" - }, - "mkdirp": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" - }, - "request-replay": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/request-replay/-/request-replay-0.2.0.tgz" - } - } - }, - "cardinal": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-0.4.4.tgz", - "dependencies": { - "ansicolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz" - }, - "redeyed": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-0.4.4.tgz", - "dependencies": { - "esprima": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz" - } - } - } - } - }, - "chalk": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.1.tgz", - "dependencies": { - "ansi-styles": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.1.0.tgz" - }, - "escape-string-regexp": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz" - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "dependencies": { - "ansi-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" - } - } - }, - "strip-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", - "dependencies": { - "ansi-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" - } - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" - } - } - }, - "chmodr": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chmodr/-/chmodr-1.0.2.tgz" - }, - "configstore": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-0.3.2.tgz", - "dependencies": { - "js-yaml": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.4.3.tgz", - "dependencies": { - "argparse": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.2.tgz", - "dependencies": { - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" - } - } - }, - "esprima": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.6.0.tgz" - } - } - }, - "object-assign": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz" - }, - "osenv": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", - "dependencies": { - "os-homedir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" - }, - "os-tmpdir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz" - } - } - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz" - }, - "xdg-basedir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-1.0.1.tgz" - } - } - }, - "decompress-zip": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.1.0.tgz", - "dependencies": { - "binary": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "dependencies": { - "buffers": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz" - }, - "chainsaw": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", - "dependencies": { - "traverse": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz" - } - } - } - } - }, - "mkpath": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz" - }, - "readable-stream": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz", - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - } - } - }, - "touch": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz", - "dependencies": { - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz" - } - } - } - } - }, - "destroy": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.3.tgz" - }, - "fs-write-stream-atomic": { - "version": "1.0.4-fix", - "resolved": "git://github.com/sheerun/fs-write-stream-atomic.git#ac0f001d165564b3763da3252d5bff327c26aea9", - "dependencies": { - "graceful-fs": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" - } - } - }, - "fstream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.8.tgz", - "dependencies": { - "graceful-fs": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - } - } - }, - "fstream-ignore": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.2.tgz", - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "dependencies": { - "brace-expansion": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", - "dependencies": { - "balanced-match": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - } - } - } - } - } - } - }, - "github": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/github/-/github-0.2.4.tgz", - "dependencies": { - "mime": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz" - } - } - }, - "glob": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", - "dependencies": { - "inflight": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", - "dependencies": { - "wrappy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" - } - } - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "dependencies": { - "brace-expansion": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", - "dependencies": { - "balanced-match": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - } - } - } - } - }, - "once": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", - "dependencies": { - "wrappy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" - } - } - } - } - }, - "graceful-fs": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.8.tgz" - }, - "handlebars": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-2.0.0.tgz", - "dependencies": { - "optimist": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz", - "dependencies": { - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz" - } - } - }, - "uglify-js": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.3.6.tgz", - "dependencies": { - "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz" - }, - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "dependencies": { - "amdefine": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz" - } - } - } - } - } - } - }, - "inquirer": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.10.0.tgz", - "dependencies": { - "ansi-escapes": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.1.0.tgz" - }, - "ansi-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "dependencies": { - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "dependencies": { - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz" - }, - "onetime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.0.0.tgz" - } - } - } - } - }, - "cli-width": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.0.1.tgz" - }, - "figures": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.4.0.tgz" - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz" - }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "dependencies": { - "code-point-at": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.0.0.tgz", - "dependencies": { - "number-is-nan": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz" - } - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "dependencies": { - "number-is-nan": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz" - } - } - }, - "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz" - } - } - }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "dependencies": { - "once": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", - "dependencies": { - "wrappy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" - } - } - } - } - }, - "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz" - }, - "strip-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz" - } - } - }, - "insight": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/insight/-/insight-0.7.0.tgz", - "dependencies": { - "async": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.4.2.tgz" - }, - "configstore": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-1.2.1.tgz", - "dependencies": { - "graceful-fs": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.2.tgz" - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz" - }, - "os-tmpdir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz" - }, - "osenv": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz", - "dependencies": { - "os-homedir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" - } - } - }, - "uuid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz" - }, - "write-file-atomic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.1.3.tgz", - "dependencies": { - "slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz" - } - } - }, - "xdg-basedir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", - "dependencies": { - "os-homedir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" - } - } - } - } - }, - "lodash.debounce": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-3.1.1.tgz", - "dependencies": { - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz" - } - } - }, - "object-assign": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.0.1.tgz" - }, - "os-name": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-1.0.3.tgz", - "dependencies": { - "osx-release": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/osx-release/-/osx-release-1.1.0.tgz", - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" - } - } - }, - "win-release": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz", - "dependencies": { - "semver": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz" - } - } - } - } - }, - "tough-cookie": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.0.tgz" - } - } - }, - "is-root": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-1.0.0.tgz" - }, - "junk": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/junk/-/junk-1.0.2.tgz" - }, - "lockfile": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.1.tgz" - }, - "lru-cache": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.0.tgz" - }, - "md5-hex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.1.0.tgz", - "dependencies": { - "md5-o-matic": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz" - } - } - }, - "mkdirp": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" - } - } - }, - "mout": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/mout/-/mout-0.11.0.tgz" - }, - "nopt": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.4.tgz" - }, - "opn": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/opn/-/opn-1.0.2.tgz" - }, - "p-throttler": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/p-throttler/-/p-throttler-0.1.1.tgz", - "dependencies": { - "q": { - "version": "0.9.7", - "resolved": "https://registry.npmjs.org/q/-/q-0.9.7.tgz" - } - } - }, - "promptly": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/promptly/-/promptly-0.2.0.tgz", - "dependencies": { - "read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "dependencies": { - "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz" - } - } - } - } - }, - "q": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz" - }, - "request": { - "version": "2.53.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.53.0.tgz", - "dependencies": { - "aws-sign2": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz" - }, - "bl": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.4.tgz", - "dependencies": { - "readable-stream": { - "version": "1.0.33", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - } - } - } - } - }, - "caseless": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.9.0.tgz" - }, - "combined-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", - "dependencies": { - "delayed-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz" - } - } - }, - "forever-agent": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz" - }, - "form-data": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz", - "dependencies": { - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz" - } - } - }, - "hawk": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz", - "dependencies": { - "boom": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.9.0.tgz" - }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz" - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz" - }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz" - } - } - }, - "http-signature": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", - "dependencies": { - "asn1": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz" - }, - "assert-plus": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz" - }, - "ctype": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz" - } - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" - }, - "mime-types": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", - "dependencies": { - "mime-db": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz" - } - } - }, - "node-uuid": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.3.tgz" - }, - "oauth-sign": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz" - }, - "qs": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz" - }, - "stringstream": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.4.tgz" - }, - "tough-cookie": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.2.0.tgz" - }, - "tunnel-agent": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.1.tgz" - } - } - }, - "request-progress": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", - "dependencies": { - "throttleit": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz" - } - } - }, - "retry": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.6.1.tgz" - }, - "rimraf": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.3.tgz", - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "dependencies": { - "inflight": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", - "dependencies": { - "wrappy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" - } - } - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - }, - "minimatch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.0.tgz", - "dependencies": { - "brace-expansion": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.1.tgz", - "dependencies": { - "balanced-match": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - } - } - } - } - }, - "once": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", - "dependencies": { - "wrappy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" - } - } - }, - "path-is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz" - } - } - } - } - }, - "semver": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-2.3.2.tgz" - }, - "shell-quote": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.4.3.tgz", - "dependencies": { - "array-filter": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz" - }, - "array-map": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz" - }, - "array-reduce": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz" - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz" - } - } - }, - "stringify-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-1.0.1.tgz" - }, - "tar-fs": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.8.1.tgz", - "dependencies": { - "pump": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.0.tgz", - "dependencies": { - "end-of-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz" - }, - "once": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", - "dependencies": { - "wrappy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" - } - } - } - } - }, - "tar-stream": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.2.1.tgz", - "dependencies": { - "bl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.0.0.tgz" - }, - "end-of-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.1.0.tgz", - "dependencies": { - "once": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", - "dependencies": { - "wrappy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" - } - } - } - } - }, - "readable-stream": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - }, - "process-nextick-args": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz" - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - } - } - }, - "xtend": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz" - } - } - } - } - }, - "tmp": { - "version": "0.0.24", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz" - }, - "update-notifier": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-0.3.2.tgz", - "dependencies": { - "is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz" - }, - "latest-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-1.0.1.tgz", - "dependencies": { - "package-json": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-1.2.0.tgz", - "dependencies": { - "got": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/got/-/got-3.3.1.tgz", - "dependencies": { - "duplexify": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.4.2.tgz", - "dependencies": { - "end-of-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.0.0.tgz", - "dependencies": { - "once": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", - "dependencies": { - "wrappy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" - } - } - } - } - }, - "readable-stream": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - }, - "process-nextick-args": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz" - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - } - } - } - } - }, - "infinity-agent": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/infinity-agent/-/infinity-agent-2.0.3.tgz" - }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz" - }, - "is-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.0.1.tgz" - }, - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz" - }, - "nested-error-stacks": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-1.0.1.tgz", - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - } - } - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz" - }, - "prepend-http": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.3.tgz" - }, - "read-all-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.0.1.tgz", - "dependencies": { - "pinkie-promise": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz", - "dependencies": { - "pinkie": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz" - } - } - }, - "readable-stream": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", - "dependencies": { - "core-util-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" - }, - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" - }, - "process-nextick-args": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz" - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - } - } - } - } - }, - "timed-out": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz" - } - } - }, - "registry-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.0.3.tgz", - "dependencies": { - "rc": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.1.2.tgz", - "dependencies": { - "deep-extend": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.2.11.tgz" - }, - "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz" - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz" - }, - "strip-json-comments": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-0.1.3.tgz" - } - } - } - } - } - } - } - } - }, - "semver-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.0.0.tgz", - "dependencies": { - "semver": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz" - } - } - }, - "string-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", - "dependencies": { - "strip-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", - "dependencies": { - "ansi-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" - } - } - } - } - } - } - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz" - }, - "which": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.0.tgz", - "dependencies": { - "is-absolute": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.1.7.tgz", - "dependencies": { - "is-relative": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz" - } - } - } - } - } - } -} From b77517ef6404229ea8c0fa6d97aee7461835f7e9 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 26 Nov 2015 14:35:52 +0100 Subject: [PATCH 0751/1021] Remove iojs from versions tested on travis (node 4.0 should be enough) --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b374f206a..9ea38779d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,6 @@ env: - NODE_VERSION=4.1 - NODE_VERSION=4.2 - NODE_VERSION=5.0 - - NODE_VERSION=iojs install: - test $TRAVIS_OS_NAME = "osx" && brew install nvm && source $(brew --prefix nvm)/nvm.sh || test $TRAVIS_OS_NAME = "linux" From 4f42aeabd7ccb29a71d4fc0f46c07555dc0c3792 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 26 Nov 2015 16:20:59 +0100 Subject: [PATCH 0752/1021] Fix tests for abbreviations on Windows --- test/commands/bower.js | 5 ++--- test/helpers.js | 6 ++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/test/commands/bower.js b/test/commands/bower.js index 31c801f42..9368fc8ec 100644 --- a/test/commands/bower.js +++ b/test/commands/bower.js @@ -15,10 +15,9 @@ describe('bower', function () { describe('abbreviations', function () { it('Returns same value than the full command', function() { - var abbr = runBin(['ls']); - var full = runBin(['list']); + var abbr = runBin(['install']); + var full = runBin(['i']); - expect(abbr.status).to.be(0); expect(abbr.stdout.toString()).to.be.equal(full.stdout.toString()); }); }); diff --git a/test/helpers.js b/test/helpers.js index 024afbffa..7eeb077b6 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -302,8 +302,6 @@ exports.localUrl = function (localPath) { // example: runBin('install') --> $ bower install exports.runBin = function (args) { args = args || []; - - var name = path.resolve(__dirname, '../bin/bower'); - - return spawnSync(name, args); + args.unshift(path.resolve(__dirname, '../bin/bower')); + return spawnSync('node', args); }; From bb7c02b07ba413fe32ac699d16710f735af56020 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 26 Nov 2015 18:06:26 +0100 Subject: [PATCH 0753/1021] Fix tests on Windows (cleanup of downloaded files) --- lib/util/download.js | 64 ++++++++++++++++++++++--------------------- test/util/download.js | 20 ++++++++++---- 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/lib/util/download.js b/lib/util/download.js index c9287d07b..8097de4cb 100644 --- a/lib/util/download.js +++ b/lib/util/download.js @@ -32,9 +32,26 @@ function download(url, file, options) { operation = retry.operation(options); operation.attempt(function () { - Q.fcall(fetch, url, file, options) + Q.fcall(fetch, url, options) .then(function(response) { - deferred.resolve(response); + response.on('progress', function (state) { + deferred.notify(state); + }); + + var writeStream = createWriteStream(file); + + // Pipe read stream to write stream + writeStream.on('error', function (error) { + destroy(writeStream); + deferred.reject(error); + }); + + writeStream.on('finish', function () { + destroy(writeStream); + deferred.resolve(response); + }); + + response.pipe(writeStream); }).fail(function (error) { // Save timeout before retrying to report var timeout = operation._timeouts[0]; @@ -53,44 +70,44 @@ function download(url, file, options) { error: error }); - operation.retry(error); + if (operation.retry(error)) { + return; + } else { + deferred.reject(error); + } }); }); return deferred.promise; } -function fetch(url, file, options) { - var response; +function fetch(url, options) { var deferred = Q.defer(); // Retry on network errors var req; - var writeStream; var contentLength; var bytesDownloaded = 0; req = progress(request(url, options), { delay: options.progressDelay }) - .on('response', function (res) { - var status = res.statusCode; + .on('response', function (response) { + contentLength = Number(response.headers['content-length']); + var status = response.statusCode; if (status < 200 || status >= 300) { - return writeStream.emit('error', (createError('Status code of ' + status, 'EHTTP'))); + deferred.reject(createError('Status code of ' + status, 'EHTTP')); + } else { + deferred.resolve(response); } - - response = res; - contentLength = Number(res.headers['content-length']); }) .on('data', function (data) { bytesDownloaded += data.length; }) - .on('progress', function (state) { - deferred.notify(state); - }) .on('error', function (error) { - writeStream.emit('error', error); + destroy(req); + deferred.reject(error); }) .on('end', function () { // Check if the whole file was downloaded @@ -105,21 +122,6 @@ function fetch(url, file, options) { } }); - writeStream = createWriteStream(file); - - // Pipe read stream to write stream - writeStream.on('error', function (error) { - destroy(req); - deferred.reject(error); - }); - - writeStream.on('finish', function () { - destroy(req); - deferred.resolve(response); - }); - - req.pipe(writeStream); - return deferred.promise; } diff --git a/test/util/download.js b/test/util/download.js index 14582cf33..69946c723 100644 --- a/test/util/download.js +++ b/test/util/download.js @@ -23,12 +23,20 @@ describe('download', function () { .get('/package.tar.gz')); download('https://bower.io/package.tar.gz', destination, opts.downloadOpts) - .then(function () { - opts.expect(); - deferred.resolve(); - }, function () { - opts.expectError(); - deferred.resolve(); + .then(function (result) { + if (opts.expect) { + opts.expect(result); + deferred.resolve(); + } else { + deferred.reject(result); + } + }, function (error) { + if (opts.expectError) { + opts.expectError(); + deferred.resolve(); + } else { + deferred.reject(error); + } }) .done(); From 4c6fdc905f8a31178ee4191241a8ca25ad9dca2b Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 27 Nov 2015 00:33:15 +0100 Subject: [PATCH 0754/1021] Revert "Fix tests on Windows (cleanup of downloaded files)" This reverts commit bb7c02b07ba413fe32ac699d16710f735af56020. --- lib/util/download.js | 64 +++++++++++++++++++++---------------------- test/util/download.js | 20 ++++---------- 2 files changed, 37 insertions(+), 47 deletions(-) diff --git a/lib/util/download.js b/lib/util/download.js index 8097de4cb..c9287d07b 100644 --- a/lib/util/download.js +++ b/lib/util/download.js @@ -32,26 +32,9 @@ function download(url, file, options) { operation = retry.operation(options); operation.attempt(function () { - Q.fcall(fetch, url, options) + Q.fcall(fetch, url, file, options) .then(function(response) { - response.on('progress', function (state) { - deferred.notify(state); - }); - - var writeStream = createWriteStream(file); - - // Pipe read stream to write stream - writeStream.on('error', function (error) { - destroy(writeStream); - deferred.reject(error); - }); - - writeStream.on('finish', function () { - destroy(writeStream); - deferred.resolve(response); - }); - - response.pipe(writeStream); + deferred.resolve(response); }).fail(function (error) { // Save timeout before retrying to report var timeout = operation._timeouts[0]; @@ -70,44 +53,44 @@ function download(url, file, options) { error: error }); - if (operation.retry(error)) { - return; - } else { - deferred.reject(error); - } + operation.retry(error); }); }); return deferred.promise; } -function fetch(url, options) { +function fetch(url, file, options) { + var response; var deferred = Q.defer(); // Retry on network errors var req; + var writeStream; var contentLength; var bytesDownloaded = 0; req = progress(request(url, options), { delay: options.progressDelay }) - .on('response', function (response) { - contentLength = Number(response.headers['content-length']); - var status = response.statusCode; + .on('response', function (res) { + var status = res.statusCode; if (status < 200 || status >= 300) { - deferred.reject(createError('Status code of ' + status, 'EHTTP')); - } else { - deferred.resolve(response); + return writeStream.emit('error', (createError('Status code of ' + status, 'EHTTP'))); } + + response = res; + contentLength = Number(res.headers['content-length']); }) .on('data', function (data) { bytesDownloaded += data.length; }) + .on('progress', function (state) { + deferred.notify(state); + }) .on('error', function (error) { - destroy(req); - deferred.reject(error); + writeStream.emit('error', error); }) .on('end', function () { // Check if the whole file was downloaded @@ -122,6 +105,21 @@ function fetch(url, options) { } }); + writeStream = createWriteStream(file); + + // Pipe read stream to write stream + writeStream.on('error', function (error) { + destroy(req); + deferred.reject(error); + }); + + writeStream.on('finish', function () { + destroy(req); + deferred.resolve(response); + }); + + req.pipe(writeStream); + return deferred.promise; } diff --git a/test/util/download.js b/test/util/download.js index 69946c723..14582cf33 100644 --- a/test/util/download.js +++ b/test/util/download.js @@ -23,20 +23,12 @@ describe('download', function () { .get('/package.tar.gz')); download('https://bower.io/package.tar.gz', destination, opts.downloadOpts) - .then(function (result) { - if (opts.expect) { - opts.expect(result); - deferred.resolve(); - } else { - deferred.reject(result); - } - }, function (error) { - if (opts.expectError) { - opts.expectError(); - deferred.resolve(); - } else { - deferred.reject(error); - } + .then(function () { + opts.expect(); + deferred.resolve(); + }, function () { + opts.expectError(); + deferred.resolve(); }) .done(); From ca0a36abcf7e17b41a0dc62fadde7921f5ced63c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 27 Nov 2015 13:45:19 +0100 Subject: [PATCH 0755/1021] Make downloader work on all platforms, fixes #2050 --- lib/util/download.js | 90 ++++++++++++--------- test/commands/install.js | 8 +- test/core/resolvers/gitHubResolver.js | 3 - test/core/resolvers/urlResolver.js | 3 - test/helpers.js | 6 ++ test/util/download.js | 110 ++++++++++++++++++++++---- 6 files changed, 159 insertions(+), 61 deletions(-) diff --git a/lib/util/download.js b/lib/util/download.js index c9287d07b..3ee428f7c 100644 --- a/lib/util/download.js +++ b/lib/util/download.js @@ -11,7 +11,8 @@ var errorCodes = [ 'EADDRINFO', 'ETIMEDOUT', 'ECONNRESET', - 'ESOCKETTIMEDOUT' + 'ESOCKETTIMEDOUT', + 'ENOTFOUND' ]; function download(url, file, options) { @@ -35,7 +36,11 @@ function download(url, file, options) { Q.fcall(fetch, url, file, options) .then(function(response) { deferred.resolve(response); - }).fail(function (error) { + }) + .progress(function (status) { + deferred.notify(status); + }) + .fail(function (error) { // Save timeout before retrying to report var timeout = operation._timeouts[0]; @@ -47,13 +52,16 @@ function download(url, file, options) { // Next attempt will start reporting download progress immediately progressDelay = 0; - deferred.notify({ - retry: true, - delay: timeout, - error: error - }); - - operation.retry(error); + // This will schedule next retry or return false + if (operation.retry(error)) { + deferred.notify({ + retry: true, + delay: timeout, + error: error + }); + } else { + deferred.reject(error); + } }); }); @@ -61,27 +69,52 @@ function download(url, file, options) { } function fetch(url, file, options) { - var response; var deferred = Q.defer(); - // Retry on network errors - var req; - var writeStream; var contentLength; var bytesDownloaded = 0; - req = progress(request(url, options), { + var reject = function (error) { + deferred.reject(error); + }; + + var req = progress(request(url, options), { delay: options.progressDelay }) - .on('response', function (res) { - var status = res.statusCode; + .on('response', function (response) { + contentLength = Number(response.headers['content-length']); + + var status = response.statusCode; if (status < 200 || status >= 300) { - return writeStream.emit('error', (createError('Status code of ' + status, 'EHTTP'))); + return deferred.reject(createError('Status code of ' + status, 'EHTTP')); } - response = res; - contentLength = Number(res.headers['content-length']); + var writeStream = createWriteStream(file); + var errored = false; + + // Change error listener so it cleans up writeStream before exiting + req.removeListener('error', reject); + req.on('error', function (error) { + errored = true; + destroy(req); + destroy(writeStream); + + // Wait for writeStream to cleanup after itself... + // TODO: Maybe there's a better way? + setTimeout(function () { + deferred.reject(error); + }, 50); + }); + + writeStream.on('finish', function () { + if (!errored) { + destroy(req); + deferred.resolve(response); + } + }); + + req.pipe(writeStream); }) .on('data', function (data) { bytesDownloaded += data.length; @@ -89,9 +122,7 @@ function fetch(url, file, options) { .on('progress', function (state) { deferred.notify(state); }) - .on('error', function (error) { - writeStream.emit('error', error); - }) + .on('error', reject) .on('end', function () { // Check if the whole file was downloaded // In some unstable connections the ACK/FIN packet might be sent in the @@ -105,21 +136,6 @@ function fetch(url, file, options) { } }); - writeStream = createWriteStream(file); - - // Pipe read stream to write stream - writeStream.on('error', function (error) { - destroy(req); - deferred.reject(error); - }); - - writeStream.on('finish', function () { - destroy(req); - deferred.resolve(response); - }); - - req.pipe(writeStream); - return deferred.promise; } diff --git a/test/commands/install.js b/test/commands/install.js index bc53acc22..70994d33d 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -354,7 +354,7 @@ describe('bower install', function () { }); - it('recognizes proxy option in config', function () { + it('recognizes proxy option in config', function (done) { this.timeout(10000); tempDir.prepare({ @@ -370,7 +370,6 @@ describe('bower install', function () { cwd: tempDir.path }); - nock.disableNetConnect(); nock('http://dummy.local') .get('http://github.com/yahoo/pure/archive/v0.6.0.tar.gz') .reply(500); @@ -379,9 +378,10 @@ describe('bower install', function () { undefined, undefined, { proxy: 'http://dummy.local/' } - ]).fail(function(error) { + ]) + .fail(function(error) { expect(error.message).to.equal('Status code of 500'); - nock.enableNetConnect(); + done(); }); }); }); diff --git a/test/core/resolvers/gitHubResolver.js b/test/core/resolvers/gitHubResolver.js index 9c74325eb..5485befee 100644 --- a/test/core/resolvers/gitHubResolver.js +++ b/test/core/resolvers/gitHubResolver.js @@ -16,9 +16,6 @@ describe('GitHub', function () { }); afterEach(function () { - // Clean nocks - nock.cleanAll(); - logger.removeAllListeners(); }); diff --git a/test/core/resolvers/urlResolver.js b/test/core/resolvers/urlResolver.js index 275f15a8b..ee03b7cb1 100644 --- a/test/core/resolvers/urlResolver.js +++ b/test/core/resolvers/urlResolver.js @@ -25,9 +25,6 @@ describe('UrlResolver', function () { afterEach(function () { logger.removeAllListeners(); - - // Clean nocks - nock.cleanAll(); }); function create(decEndpoint) { diff --git a/test/helpers.js b/test/helpers.js index 7eeb077b6..42f0f6df1 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -13,6 +13,7 @@ var which = require('which'); var proxyquire = require('proxyquire').noCallThru().noPreserveCache(); var spawnSync = require('spawn-sync'); var config = require('../lib/config'); +var nock = require('nock'); // For better promise errors Q.longStackSupport = true; @@ -305,3 +306,8 @@ exports.runBin = function (args) { args.unshift(path.resolve(__dirname, '../bin/bower')); return spawnSync('node', args); }; + + +afterEach(function () { + nock.cleanAll(); +}); \ No newline at end of file diff --git a/test/util/download.js b/test/util/download.js index 14582cf33..86479bf34 100644 --- a/test/util/download.js +++ b/test/util/download.js @@ -19,16 +19,24 @@ describe('download', function () { tempDir.prepare(); opts.response( - nock('https://bower.io', opts.nockOpts) - .get('/package.tar.gz')); - - download('https://bower.io/package.tar.gz', destination, opts.downloadOpts) - .then(function () { - opts.expect(); - deferred.resolve(); - }, function () { - opts.expectError(); - deferred.resolve(); + nock('http://bower.io', opts.nockOpts) + ); + + download('http://bower.io/package.tar.gz', destination, opts.downloadOpts) + .then(function (result) { + if (opts.expect) { + opts.expect(result); + deferred.resolve(); + } else { + deferred.reject(new Error('Error expected. Got successful response.')); + } + }, function (error) { + if (opts.expectError) { + opts.expectError(error); + deferred.resolve(); + } else { + deferred.reject(error); + } }) .done(); @@ -38,7 +46,7 @@ describe('download', function () { it('download file to directory', function () { return downloadTest({ response: function (nock) { - nock.replyWithFile(200, source); + nock.get('/package.tar.gz').replyWithFile(200, source); }, expect: function () { expect(fs.existsSync(destination)).to.be(true); @@ -61,7 +69,7 @@ describe('download', function () { } }, response: function (nock) { - nock.replyWithFile(200, source); + nock.get('/package.tar.gz').replyWithFile(200, source); }, expect: function () { expect(fs.existsSync(destination)).to.be(true); @@ -73,7 +81,7 @@ describe('download', function () { it('handle server response 404', function () { return downloadTest({ response: function (nock) { - nock.reply(404); + nock.get('/package.tar.gz').reply(404); }, expectError: function () { expect(fs.readdirSync(tempDir.path)).to.be.empty(); @@ -84,7 +92,7 @@ describe('download', function () { it('handle network error', function () { return downloadTest({ response: function (nock) { - nock.replyWithError('network error'); + nock.get('/package.tar.gz').replyWithError('network error'); }, expectError: function () { expect(fs.readdirSync(tempDir.path)).to.be.empty(); @@ -92,4 +100,78 @@ describe('download', function () { }); }); + + it('handles connection timeout', function () { + return downloadTest({ + response: function (nock) { + // First connection + 5 retries + nock.get('/package.tar.gz').times(6).delayConnection(1000).replyWithFile(200, source); + }, + expectError: function (e) { + expect(e.code).to.be('ETIMEDOUT'); + expect(fs.readdirSync(tempDir.path)).to.be.empty(); + }, + downloadOpts: { + timeout: 10, + maxTimeout: 0, + minTimeout: 0 + } + }); + }); + + it('handles socket timeout', function () { + return downloadTest({ + response: function (nock) { + // First connection + 5 retries + nock.get('/package.tar.gz').times(6).socketDelay(1000).replyWithFile(200, source); + }, + expectError: function (e) { + expect(e.code).to.be('ESOCKETTIMEDOUT'); + expect(fs.readdirSync(tempDir.path)).to.be.empty(); + }, + downloadOpts: { + timeout: 10, + maxTimeout: 0, + minTimeout: 0 + } + }); + }); + + it('handles retries correctly', function () { + return downloadTest({ + response: function (nock) { + // First connection + 5 retries + nock.get('/package.tar.gz').times(5).delayConnection(1000).replyWithFile(200, source); + // Success last time + nock.get('/package.tar.gz').replyWithFile(200, source); + }, + expect: function () { + expect(fs.existsSync(destination)).to.be(true); + expect(fs.readdirSync(tempDir.path)).to.have.length(1); + }, + downloadOpts: { + timeout: 10, + maxTimeout: 0, + minTimeout: 0 + } + }); + }); + + it('fails on incorrect Content-Length match', function () { + return downloadTest({ + response: function (nock) { + // First connection + 5 retries + nock.get('/package.tar.gz').replyWithFile(200, source, { 'Content-Length': 5000 }); + }, + expectError: function (e) { + expect(e.code).to.be('EINCOMPLETE'); + expect(e.message).to.be('Transfer closed with 4636 bytes remaining to read'); + }, + downloadOpts: { + timeout: 10, + maxTimeout: 0, + minTimeout: 0 + } + }); + }); }); From 6d12ef291b6dd9a272a07b756ad1c9120a4b6d39 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 27 Nov 2015 13:53:36 +0100 Subject: [PATCH 0756/1021] Properly restore env variables if they are undefined --- packages/bower-config/lib/util/proxy.js | 39 +++++++++++++++++++++---- packages/bower-config/test/test.js | 13 +++++++++ 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/packages/bower-config/lib/util/proxy.js b/packages/bower-config/lib/util/proxy.js index d5524dbc8..1dcdc4e2a 100644 --- a/packages/bower-config/lib/util/proxy.js +++ b/packages/bower-config/lib/util/proxy.js @@ -34,18 +34,45 @@ EnvProxy.prototype.set = function (config) { EnvProxy.prototype.restore = function () { if (Object.prototype.hasOwnProperty.call(this.config, 'noProxy')) { - process.env.NO_PROXY = this.restoreFrom.NO_PROXY; - process.env.no_proxy = this.restoreFrom.no_proxy; + if (this.restoreFrom.NO_PROXY !== undefined) { + process.env.NO_PROXY = this.restoreFrom.NO_PROXY; + } else { + delete process.env.NO_PROXY; + } + + if (this.restoreFrom.no_proxy !== undefined) { + process.env.no_proxy = this.restoreFrom.no_proxy; + } else { + delete process.env.no_proxy; + } } if (Object.prototype.hasOwnProperty.call(this.config, 'proxy')) { - process.env.HTTP_PROXY = this.restoreFrom.HTTP_PROXY; - process.env.http_proxy = this.restoreFrom.http_proxy; + if (this.restoreFrom.HTTP_PROXY !== undefined) { + process.env.HTTP_PROXY = this.restoreFrom.HTTP_PROXY; + } else { + delete process.env.HTTP_PROXY; + } + + if (this.restoreFrom.http_proxy !== undefined) { + process.env.http_proxy = this.restoreFrom.http_proxy; + } else { + delete process.env.http_proxy; + } } if (Object.prototype.hasOwnProperty.call(this.config, 'httpsProxy')) { - process.env.HTTPS_PROXY = this.restoreFrom.HTTPS_PROXY; - process.env.https_proxy = this.restoreFrom.https_proxy; + if (this.restoreFrom.HTTPS_PROXY !== undefined) { + process.env.HTTPS_PROXY = this.restoreFrom.HTTPS_PROXY; + } else { + delete process.env.HTTPS_PROXY; + } + + if (this.restoreFrom.https_proxy !== undefined) { + process.env.https_proxy = this.restoreFrom.https_proxy; + } else { + delete process.env.https_proxy; + } } }; diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index 469053a06..357c31924 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -190,6 +190,19 @@ describe('NPM Config on package.json', function () { assert.equal(process.env.no_proxy, 'f'); }); + it('restores env variables if they are undefined', function () { + var config = require('../lib/Config').create('test/assets/env-variables').load(); + config.restore(); + + assert.equal(process.env.HTTP_PROXY, undefined); + assert.equal(process.env.HTTPS_PROXY, undefined); + assert.equal(process.env.NO_PROXY, undefined); + + assert.equal(process.env.http_proxy, undefined); + assert.equal(process.env.https_proxy, undefined); + assert.equal(process.env.no_proxy, undefined); + }); + it('allows for overriding options', function () { require('../lib/Config').read('test/assets/env-variables', { httpsProxy: 'http://other-proxy.local' From 8669ed2aacd6224c5ab14cb86282ac3644f9a1f3 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 27 Nov 2015 14:04:09 +0100 Subject: [PATCH 0757/1021] Bump bower-config to 1.2.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 18aa79901..3ccb3a49e 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dependencies": { "abbrev": "^1.0.5", "archy": "1.0.0", - "bower-config": "^1.2.2", + "bower-config": "^1.2.3", "bower-endpoint-parser": "^0.2.2", "bower-json": "^0.4.0", "bower-logger": "^0.2.2", From 0e1153f6101a58ca3909e65b12096f76a4d65d15 Mon Sep 17 00:00:00 2001 From: Accommodavid Date: Fri, 27 Nov 2015 13:34:30 +0100 Subject: [PATCH 0758/1021] Add ENOTDIR test for install command --- test/commands/install.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/commands/install.js b/test/commands/install.js index 70994d33d..1ec32793a 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -384,4 +384,17 @@ describe('bower install', function () { done(); }); }); + + + it('errors if the components directory is not a directory', function () { + tempDir.prepare({ + '.bowerrc': { + directory: '.bowerrc' + } + }); + + return helpers.run(install).fail(function(error) { + expect(error.code).to.equal('ENOTDIR'); + }); + }); }); From 700b46162cd32d1a7cf1841d742ea73a8f05ad16 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 27 Nov 2015 14:47:11 +0100 Subject: [PATCH 0759/1021] Remove minor bumps of node from Travis --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9ea38779d..575173225 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,6 @@ env: - NODE_VERSION=0.11 - NODE_VERSION=0.12 - NODE_VERSION=4.0 - - NODE_VERSION=4.1 - - NODE_VERSION=4.2 - NODE_VERSION=5.0 install: From 50ed13e4eed2cbd684e534087fd5f67030ae738d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 27 Nov 2015 15:53:31 +0100 Subject: [PATCH 0760/1021] Release 1.6.8 --- CHANGELOG.md | 10 ++++++++++ package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ef789066..6676b9f8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 1.6.8 - 2015-11-27 + +- Use fs-write-stream-atomic for downloads +- Improved downloader that properly cleans after itself +- Fix shallow host detection ([#2040](https://github.com/bower/bower/pull/2040)) +- Upgrade to ([bower-config#1.2.3](https://github.com/bower/config/releases/tag/1.2.3)) + - Properly restore env variables if they are undefined at the beginning + - Properly handle `default` setting for config.ca + - Display proper error if .bowerrc is a directory instead of file + ## 1.6.7 - 2015-11-26 - Bundless all the dependencies again diff --git a/package.json b/package.json index 3ccb3a49e..bd2497b6a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.7", + "version": "1.6.8", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From e8a2d92785d66ab43b727af2c4b434b654555fb3 Mon Sep 17 00:00:00 2001 From: Utsav Shah Date: Fri, 27 Nov 2015 11:36:14 -0600 Subject: [PATCH 0761/1021] Remove @ in temporary directories --- lib/core/resolvers/Resolver.js | 2 +- test/core/resolvers/resolver.js | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/core/resolvers/Resolver.js b/lib/core/resolvers/Resolver.js index e3b7b7715..f53feffe6 100644 --- a/lib/core/resolvers/Resolver.js +++ b/lib/core/resolvers/Resolver.js @@ -145,7 +145,7 @@ Resolver.prototype._createTempDir = function () { return Q.nfcall(mkdirp, this._config.tmp) .then(function () { return Q.nfcall(tmp.dir, { - template: path.join(this._config.tmp, this._name + '-' + process.pid + '-XXXXXX'), + template: path.join(this._config.tmp, this._name + '-' + process.pid + '-XXXXXX').replace(/@/g, ''), mode: 0777 & ~process.umask(), unsafeCleanup: true }); diff --git a/test/core/resolvers/resolver.js b/test/core/resolvers/resolver.js index aa455e6aa..50b9f8b5b 100644 --- a/test/core/resolvers/resolver.js +++ b/test/core/resolvers/resolver.js @@ -515,6 +515,18 @@ describe('Resolver', function () { }) .done(); }); + + it('should remove @ from directory names', function (next) { + var resolver = create('foo@bar'); + + resolver._createTempDir() + .then(function (dir) { + expect(resolver._tempDir).to.be.ok(); + expect(resolver._tempDir.indexOf('@')).to.equal(-1); + next(); + }) + .done(); + }); }); describe('._cleanTempDir', function () { From 852a586d5c93864aecec23b7116257682c22bedf Mon Sep 17 00:00:00 2001 From: Utsav Shah Date: Fri, 27 Nov 2015 13:17:36 -0600 Subject: [PATCH 0762/1021] Replace temp directory name with md5 hash Fixes issues with characters like @ interfering with directory name lookups --- lib/core/resolvers/Resolver.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/core/resolvers/Resolver.js b/lib/core/resolvers/Resolver.js index f53feffe6..972516058 100644 --- a/lib/core/resolvers/Resolver.js +++ b/lib/core/resolvers/Resolver.js @@ -7,6 +7,7 @@ var rimraf = require('../../util/rimraf'); var readJson = require('../../util/readJson'); var createError = require('../../util/createError'); var removeIgnores = require('../../util/removeIgnores'); +var md5 = require('md5-hex'); tmp.setGracefulCleanup(); @@ -145,7 +146,7 @@ Resolver.prototype._createTempDir = function () { return Q.nfcall(mkdirp, this._config.tmp) .then(function () { return Q.nfcall(tmp.dir, { - template: path.join(this._config.tmp, this._name + '-' + process.pid + '-XXXXXX').replace(/@/g, ''), + template: path.join(this._config.tmp, md5(this._name) + '-' + process.pid + '-XXXXXX'), mode: 0777 & ~process.umask(), unsafeCleanup: true }); From 4da1b6254227b383e00a5e82a6a48489a97a4e34 Mon Sep 17 00:00:00 2001 From: Ryan Temple Date: Tue, 24 Nov 2015 19:32:37 +0000 Subject: [PATCH 0763/1021] Updated so cwd is set from command line and correct directory tree used --- packages/bower-config/lib/util/rc.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 39871a5ad..f2cc3d8df 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -20,6 +20,9 @@ function rc(name, cwd, argv) { return value === 'false' ? false : value; }); + // If we have specified a cwd then use this as the base for getting config. + cwd = argvConfig.cwd ? argvConfig.cwd : cwd; + if (cwd) { return object.deepMixIn.apply(null, [ {}, From e6f1805df014596daeb3d4d8cb446db71425a73d Mon Sep 17 00:00:00 2001 From: Ryan Temple Date: Fri, 27 Nov 2015 19:31:24 +0000 Subject: [PATCH 0764/1021] Added tests --- packages/bower-config/test/util/rc.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/bower-config/test/util/rc.js b/packages/bower-config/test/util/rc.js index 192fd63eb..bc4f2fad9 100644 --- a/packages/bower-config/test/util/rc.js +++ b/packages/bower-config/test/util/rc.js @@ -20,13 +20,16 @@ describe('rc', function() { 'child3/bower.json': { name: 'without-bowerrc' }, + 'other_dir/.bowerrc': { + key: 'othervalue' + } }); tempDirBowerrc.prepare({ '.bowerrc/foo': { key: 'bar' } - + }); it('correctly reads .bowerrc files', function() { @@ -57,6 +60,19 @@ describe('rc', function() { expect(config.key2).to.eql(undefined); }); + it('loads the .bowerrc file from the cwd specified on the command line', function(){ + var argv = { + 'config': { + 'cwd': tempDir.path + '/other_dir/' + } + }; + + var config = rc('bower', tempDir.path, argv); + + expect(config.key).to.eql('othervalue'); + + }); + it('throws an easy to understand error if .bowerrc is a dir', function() { // Gotta wrap this to catch the error var config = function () { From d2ba80e6e97b13483bf113514ec1e6d1b8f8a03f Mon Sep 17 00:00:00 2001 From: Chris Contolini Date: Fri, 27 Nov 2015 20:31:46 -0500 Subject: [PATCH 0765/1021] Add `bower update --save` functionality --- lib/commands/update.js | 4 +- lib/core/Project.js | 21 ++++ test/commands/update.js | 229 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 244 insertions(+), 10 deletions(-) diff --git a/lib/commands/update.js b/lib/commands/update.js index 9d2d65e97..ed7972c12 100644 --- a/lib/commands/update.js +++ b/lib/commands/update.js @@ -23,7 +23,9 @@ update.readOptions = function (argv) { var options = cli.readOptions({ 'force-latest': { type: Boolean, shorthand: 'F' }, - 'production': { type: Boolean, shorthand: 'p' } + 'production': { type: Boolean, shorthand: 'p' }, + 'save': { type: Boolean, shorthand: 'S' }, + 'save-dev': { type: Boolean, shorthand: 'D' } }, argv); var names = options.argv.remain.slice(1); diff --git a/lib/core/Project.js b/lib/core/Project.js index 0b3c4dc60..67bbee34b 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -197,6 +197,27 @@ Project.prototype.update = function (names, options) { return that._manager.install(that._json); }) .then(function (installed) { + if (that._options.save || that._options.saveDev) { + // Cycle through the specified endpoints + targets.forEach(function (target) { + // Abort if current and new version are identical + if (target.target === target.pkgMeta.version) { + return false; + } + + var jsonEndpoint = endpointParser.decomposed2json(target); + // Bower uses the ~ range specifier for new installs + jsonEndpoint[target.name] = '~' + target.pkgMeta.version; + + if (that._options.saveDev && mout.object.has(that._json, 'devDependencies.' + target.name)) { + that._json.devDependencies = mout.object.mixIn(that._json.devDependencies || {}, jsonEndpoint); + } + + if (that._options.save && mout.object.has(that._json, 'dependencies.' + target.name)) { + that._json.dependencies = mout.object.mixIn(that._json.dependencies || {}, jsonEndpoint); + } + }); + } // Save JSON, might contain changes to resolutions return that.saveJson() .then(function () { diff --git a/test/commands/update.js b/test/commands/update.js index 7e50db9c3..ed4eaa77f 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -1,12 +1,13 @@ var expect = require('expect.js'); var object = require('mout').object; +var semver = require('semver'); var helpers = require('../helpers'); var updateCmd = helpers.command('update'); var commands = helpers.require('lib/index').commands; describe('bower update', function () { - + this.timeout(10000); var tempDir = new helpers.TempDir(); var subPackage = new helpers.TempDir({ @@ -41,16 +42,14 @@ describe('bower update', function () { } }).prepare(); - var updateLogger = function(packages, options, config) { + var update = function(packages, options, config) { config = object.merge(config || {}, { cwd: tempDir.path }); - return commands.update(packages, options, config); - }; - - var update = function(packages, options, config) { - var logger = updateLogger(packages, options, config); + var logger = commands.update( + packages, options, config + ); return helpers.expectEvent(logger, 'end'); }; @@ -68,8 +67,13 @@ describe('bower update', function () { }; it('correctly reads arguments', function() { - expect(updateCmd.readOptions(['jquery', '-F', '-p'])) - .to.eql([['jquery'], { forceLatest: true, production: true }]); + expect(updateCmd.readOptions(['jquery', '-F', '-p', '-S', '-D'])) + .to.eql([['jquery'], { + forceLatest: true, + production: true, + save: true, + saveDev: true + }]); }); it('install missing packages', function () { @@ -261,6 +265,213 @@ describe('bower update', function () { }); }); + it('doesn\'t update extraneous packages', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); + + return install(['underscore#1.5.0']).then(function() { + + expect(tempDir.readJson('bower_components/underscore/package.json').version).to.equal('1.5.0'); + + return update(null, {save: true}).then(function() { + expect(tempDir.readJson('bower_components/underscore/package.json').version).to.equal('1.5.0'); + expect(tempDir.readJson('bower.json')).to.not.have.property('dependencies'); + }); + }); + }); + + it('updates bower.json dep after updating with --save flag', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + underscore: '~1.5.0' + } + } + }); + + return install().then(function() { + + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.0'); + + return update(null, {save: true}).then(function() { + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.2'); + }); + + }); + }); + + it('updates bower.json dev dep after updating with --save-dev flag', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test', + devDependencies: { + underscore: '~1.5.0' + } + } + }); + + return install().then(function() { + + expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.0'); + + return update(null, {saveDev: true}).then(function() { + expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.2'); + }); + + }); + }); + + it('replaces "any" range with latest version', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + underscore: '*' + } + } + }); + + return install().then(function() { + + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('*'); + + return update(null, {save: true}).then(function() { + var version = semver.gte(tempDir.readJson('bower.json').dependencies.underscore.replace('~', ''), '1.8.3'); + expect(version).to.be.ok(); + }); + + }); + }); + + it('updates multiple components in bower.json after updating with --save flag', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + underscore: '~1.5.0', + lodash: '~1.0.0' + }, + devDependencies: { + neat: '~1.5.0' + }, + } + }); + + return install().then(function() { + + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.0'); + expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.0.0'); + expect(tempDir.readJson('bower.json').devDependencies.neat).to.equal('~1.5.0'); + + return update(null, {save: true}).then(function() { + // Normal deps should have changed + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.2'); + expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.0.2'); + // Dev deps should not have changed + expect(tempDir.readJson('bower.json').devDependencies.neat).to.equal('~1.5.0'); + }); + + }); + }); + + it('updates multiple components in bower.json after updating with --save-dev flag', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + neat: '~1.5.0' + }, + devDependencies: { + underscore: '~1.5.0', + lodash: '~1.0.0' + } + } + }); + + return install().then(function() { + + expect(tempDir.readJson('bower.json').dependencies.neat).to.equal('~1.5.0'); + expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.0'); + expect(tempDir.readJson('bower.json').devDependencies.lodash).to.equal('~1.0.0'); + + return update(null, {saveDev: true}).then(function() { + // Normal deps should not have changed + expect(tempDir.readJson('bower.json').dependencies.neat).to.equal('~1.5.0'); + // Dev deps should have changed + expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.2'); + expect(tempDir.readJson('bower.json').devDependencies.lodash).to.equal('~1.0.2'); + }); + + }); + }); + + it('correctly interprets semver range specifier pre-1.0', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + underscore: '^0.1.0' + } + } + }); + + return install().then(function() { + + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('^0.1.0'); + + return update(null, {save: true}).then(function() { + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~0.1.1'); + }); + + }); + }); + + it('correctly interprets semver range specifier post-1.0', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + lodash: '^1.0.0' + } + } + }); + + return install().then(function() { + + expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('^1.0.0'); + + return update(null, {save: true}).then(function() { + expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.3.1'); + }); + + }); + }); + + it('doesn\'t update bower.json if versions are identical', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + underscore: '1.5.0' + } + } + }); + + return install().then(function() { + + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('1.5.0'); + + return update(null, {save: true}).then(function() { + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('1.5.0'); + }); + + }); + }); + it('does not install ignored dependencies when updating a package', function () { var package3 = new helpers.TempDir({ 'bower.json': { From 19fc84007df7d00a1a808f2509259c6ec0a8225a Mon Sep 17 00:00:00 2001 From: AnthonyBobsin Date: Sun, 29 Nov 2015 16:22:58 -0500 Subject: [PATCH 0766/1021] Implements jscs to enforce a newly created style guide for the repo. Uses jscs to fix some minor style guide warnings. --- .jscsrc | 15 + .jshintrc | 12 - Gruntfile.js | 17 +- lib/abbreviations.js | 16 +- lib/core/Manager.js | 2 +- lib/core/resolverFactory.js | 1 + lib/core/resolvers/GitRemoteResolver.js | 1 + lib/core/resolvers/Resolver.js | 3 +- lib/core/resolvers/UrlResolver.js | 4 +- lib/renderers/JsonRenderer.js | 4 +- lib/renderers/StandardRenderer.js | 4 +- lib/util/analytics.js | 4 +- lib/util/rootCheck.js | 1 + package.json | 1 + test/commands/home.js | 10 +- test/commands/info.js | 8 +- test/commands/init.js | 22 +- test/commands/install.js | 690 ++++++++++++------------ test/commands/link.js | 10 +- test/commands/list.js | 32 +- test/commands/prune.js | 22 +- test/commands/register.js | 18 +- test/commands/update.js | 62 +-- test/commands/version.js | 30 +- test/core/scripts.js | 4 +- test/util/download.js | 4 +- 26 files changed, 509 insertions(+), 488 deletions(-) create mode 100644 .jscsrc diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 000000000..51545d4ce --- /dev/null +++ b/.jscsrc @@ -0,0 +1,15 @@ +{ + 'validateIndentation': 4, + 'requireCamelCaseOrUpperCaseIdentifiers': true, + 'requireParenthesesAroundIIFE': true, + 'requireCapitalizedConstructors': true, + 'disallowEmptyBlocks': false, + 'validateQuoteMarks': "'", + 'requireOperatorBeforeLineBreak': false, + 'requireCommaBeforeLineBreak': true, + 'disallowMultipleLineStrings': true, + 'requireDotNotation': true, + 'disallowTabs': true, + 'disallowNewlineBeforeBlockStatements': true, + 'disallowTrailingWhitespace': true +} diff --git a/.jshintrc b/.jshintrc index 2d3e74888..99614890b 100644 --- a/.jshintrc +++ b/.jshintrc @@ -9,7 +9,6 @@ "beforeEach" ], - "indent": 4, "node": true, "devel": true, @@ -17,26 +16,19 @@ "curly": false, "eqeqeq": true, "forin": false, - "immed": true, "latedef": false, - "newcap": true, "noarg": true, - "noempty": false, "nonew": true, "plusplus": false, "regexp": false, "undef": true, "unused": "vars", - "quotmark": "single", "strict": false, - "trailing": true, - "camelcase": true, "asi": false, "boss": true, "debug": false, "eqnull": true, - "es5": false, "esnext": false, "evil": false, "expr": false, @@ -44,16 +36,12 @@ "globalstrict": false, "iterator": false, "lastsemic": false, - "laxbreak": true, - "laxcomma": false, "loopfunc": true, - "multistr": false, "onecase": true, "regexdash": false, "scripturl": false, "smarttabs": false, "shadow": false, - "sub": false, "supernew": true, "validthis": false, diff --git a/Gruntfile.js b/Gruntfile.js index 01abcf46c..b63cea675 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -17,6 +17,21 @@ module.exports = function (grunt) { '!test/tmp/**/*' ] }, + jscs: { + options: { + config: '.jscsrc', + fix: true + }, + files: [ + 'Gruntfile.js', + 'bin/*', + 'lib/**/*.js', + 'test/**/*.js', + '!test/assets/**/*', + '!test/reports/**/*', + '!test/tmp/**/*' + ] + }, simplemocha: { options: { reporter: 'spec', @@ -53,7 +68,7 @@ module.exports = function (grunt) { }); grunt.registerTask('assets', ['exec:assets-force']); - grunt.registerTask('test', ['jshint', 'exec:assets', 'simplemocha:full']); + grunt.registerTask('test', ['jshint', 'jscs', 'exec:assets', 'simplemocha:full']); grunt.registerTask('cover', 'exec:cover'); grunt.registerTask('travis', ['jshint', 'exec:assets', 'exec:cover', 'exec:coveralls']); grunt.registerTask('default', 'test'); diff --git a/lib/abbreviations.js b/lib/abbreviations.js index e27c32675..52660f70b 100644 --- a/lib/abbreviations.js +++ b/lib/abbreviations.js @@ -19,12 +19,12 @@ function expandNames(obj, prefix, stack) { } module.exports = function(commands) { - var abbreviations = abbrev(expandNames(commands)); - - abbreviations.i = 'install'; - abbreviations.rm = 'uninstall'; - abbreviations.unlink = 'uninstall'; - abbreviations.ls = 'list'; - - return abbreviations; + var abbreviations = abbrev(expandNames(commands)); + + abbreviations.i = 'install'; + abbreviations.rm = 'uninstall'; + abbreviations.unlink = 'uninstall'; + abbreviations.ls = 'list'; + + return abbreviations; }; diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 42107a652..cb5a6ae58 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -27,7 +27,7 @@ Manager.prototype.configure = function (setup) { // Targets - ignore those specified in ignoredDependencies this._targets = mout.array.reject(setup.targets || [], function(target) { - return mout.array.contains(this._config.ignoredDependencies, target.name ); + return mout.array.contains(this._config.ignoredDependencies, target.name ); }, this); this._targets.forEach(function (decEndpoint) { diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index 7b62d3c7e..79463b5f1 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -1,3 +1,4 @@ +/*jshint laxbreak:true*/ var Q = require('q'); var fs = require('../util/fs'); var path = require('path'); diff --git a/lib/core/resolvers/GitRemoteResolver.js b/lib/core/resolvers/GitRemoteResolver.js index 1a8e9be90..46f19debe 100644 --- a/lib/core/resolvers/GitRemoteResolver.js +++ b/lib/core/resolvers/GitRemoteResolver.js @@ -1,3 +1,4 @@ +/*jshint laxbreak:true*/ var util = require('util'); var url = require('url'); var Q = require('q'); diff --git a/lib/core/resolvers/Resolver.js b/lib/core/resolvers/Resolver.js index 972516058..3f9221a7f 100644 --- a/lib/core/resolvers/Resolver.js +++ b/lib/core/resolvers/Resolver.js @@ -108,8 +108,7 @@ Resolver.prototype.isCacheable = function () { // We don't want to cache moving targets like branches if (this._pkgMeta && this._pkgMeta._resolution && - this._pkgMeta._resolution.type === 'branch') - { + this._pkgMeta._resolution.type === 'branch') { return false; } diff --git a/lib/core/resolvers/UrlResolver.js b/lib/core/resolvers/UrlResolver.js index 84c3f8582..48be0ba01 100644 --- a/lib/core/resolvers/UrlResolver.js +++ b/lib/core/resolvers/UrlResolver.js @@ -112,8 +112,8 @@ UrlResolver.prototype._download = function () { var fileName = this._parseSourceURL(this._source); if (!fileName) { - this._source = this._source.replace(/\/(?=\?|#)/, ''); - fileName = this._parseSourceURL(this._source); + this._source = this._source.replace(/\/(?=\?|#)/, ''); + fileName = this._parseSourceURL(this._source); } var file = path.join(this._tempDir, fileName); diff --git a/lib/renderers/JsonRenderer.js b/lib/renderers/JsonRenderer.js index 04a1ce00e..4505e2776 100644 --- a/lib/renderers/JsonRenderer.js +++ b/lib/renderers/JsonRenderer.js @@ -31,10 +31,10 @@ JsonRenderer.prototype.error = function (err) { err.message = message; // Stack - /*jshint camelcase:false*/ + // jscs:disable requireCamelCaseOrUpperCaseIdentifiers stack = err.fstream_stack || err.stack || 'N/A'; err.stacktrace = (Array.isArray(stack) ? stack.join('\n') : stack); - /*jshint camelcase:true*/ + // jscs:enable requireCamelCaseOrUpperCaseIdentifiers this.log(err); this.end(); diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index a230ef584..f8b580308 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -71,12 +71,12 @@ StandardRenderer.prototype.error = function (err) { // Print trace if verbose, the error has no code // or if the error is a node error if (this._config.verbose || !err.code || err.errno) { - /*jshint camelcase:false*/ + // jscs:disable requireCamelCaseOrUpperCaseIdentifiers stack = err.fstream_stack || err.stack || 'N/A'; str = chalk.yellow('\nStack trace:\n'); str += (Array.isArray(stack) ? stack.join('\n') : stack) + '\n'; str += chalk.yellow('\nConsole trace:\n'); - /*jshint camelcase:true*/ + // jscs:enable requireCamelCaseOrUpperCaseIdentifiers this._write(process.stderr, str); this._write(process.stderr, new Error().stack); diff --git a/lib/util/analytics.js b/lib/util/analytics.js index 6cd50adf2..a48c25fc8 100644 --- a/lib/util/analytics.js +++ b/lib/util/analytics.js @@ -114,8 +114,8 @@ Tracker.prototype.trackDecomposedEndpoints = function trackDecomposedEndpoints(c }; Tracker.prototype.trackPackages = function trackPackages(command, packages) { - mout.object.forOwn(packages, function (package) { - var meta = package.pkgMeta; + mout.object.forOwn(packages, function (_package) { + var meta = _package.pkgMeta; this.track(command, meta.name, meta.version); }.bind(this)); }; diff --git a/lib/util/rootCheck.js b/lib/util/rootCheck.js index 6d0d712a6..3fbb8190e 100644 --- a/lib/util/rootCheck.js +++ b/lib/util/rootCheck.js @@ -1,4 +1,5 @@ /*jshint multistr:true*/ +// jscs:disable disallowMultipleLineStrings 'use strict'; var isRoot = require('is-root'); var createError = require('./createError'); diff --git a/package.json b/package.json index bd2497b6a..ad13fa7a9 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "grunt-contrib-jshint": "^0.10.0", "grunt-contrib-watch": "^0.6.1", "grunt-exec": "^0.4.6", + "grunt-jscs": "^2.3.0", "grunt-simple-mocha": "^0.4.0", "istanbul": "^0.3.5", "load-grunt-tasks": "^2.0.0", diff --git a/test/commands/home.js b/test/commands/home.js index 71af4a3cc..4383259fc 100644 --- a/test/commands/home.js +++ b/test/commands/home.js @@ -10,7 +10,7 @@ describe('bower home', function () { expect(home.readOptions(['foo'])).to.eql(['foo']); }); - var package = new helpers.TempDir({ + var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package', homepage: 'http://bower.io' @@ -24,22 +24,22 @@ describe('bower home', function () { }); it('opens repository home page in web browser', function () { - package.prepare(); + mainPackage.prepare(); return Q.Promise(function(resolve) { var home = helpers.command('home', { opn: resolve }); - helpers.run(home, [package.path]); + helpers.run(home, [mainPackage.path]); }).then(function(url) { expect(url).to.be('http://bower.io'); }); }); it('opens home page of current repository', function () { - package.prepare(); + mainPackage.prepare(); return Q.Promise(function(resolve) { var home = helpers.command('home', { opn: resolve }); - helpers.run(home, [undefined, { cwd: package.path }]); + helpers.run(home, [undefined, { cwd: mainPackage.path }]); }).then(function(url) { expect(url).to.be('http://bower.io'); }); diff --git a/test/commands/info.js b/test/commands/info.js index 0fbe1e5dc..436bd5db3 100644 --- a/test/commands/info.js +++ b/test/commands/info.js @@ -24,7 +24,7 @@ describe('bower info', function () { description: 'Hello world! Hello!' }; - var package = new helpers.TempDir({ + var mainPackage = new helpers.TempDir({ '0.1.2': { 'bower.json': meta }, '0.1.3': { 'bower.json': meta2 } }); @@ -36,12 +36,12 @@ describe('bower info', function () { }); it('shows info about given package', function () { - package.prepareGit({}); + mainPackage.prepareGit({}); - return helpers.run(info, [package.path]).spread(function(results) { + return helpers.run(info, [mainPackage.path]).spread(function(results) { expect(results).to.eql({ 'latest': meta2, - 'name': package.path, + 'name': mainPackage.path, 'versions': [ '0.1.3', '0.1.2' diff --git a/test/commands/init.js b/test/commands/init.js index d31ae68fc..ffc80f807 100644 --- a/test/commands/init.js +++ b/test/commands/init.js @@ -5,7 +5,7 @@ var init = helpers.command('init'); describe('bower init', function () { - var package = new helpers.TempDir(); + var mainPackage = new helpers.TempDir(); it('correctly reads arguments', function() { expect(init.readOptions([])) @@ -13,10 +13,10 @@ describe('bower init', function () { }); it('generates bower.json file', function () { - package.prepare(); + mainPackage.prepare(); var logger = init({ - cwd: package.path, + cwd: mainPackage.path, interactive: true }); @@ -40,7 +40,7 @@ describe('bower init', function () { return helpers.expectEvent(logger, 'end'); }) .then(function () { - expect(package.readJson('bower.json')).to.eql({ + expect(mainPackage.readJson('bower.json')).to.eql({ name: 'test-name', homepage: 'test-homepage', authors: [ 'test-author' ], @@ -54,9 +54,9 @@ describe('bower init', function () { }); it('errors on non-interactive mode', function () { - package.prepare(); + mainPackage.prepare(); - return helpers.run(init, { cwd: package.path }).then( + return helpers.run(init, { cwd: mainPackage.path }).then( function () { throw 'should fail'; }, function (reason) { expect(reason.message).to.be('Register requires an interactive shell'); @@ -66,13 +66,13 @@ describe('bower init', function () { }); it('warns about existing bower.json', function () { - package.prepare({ + mainPackage.prepare({ 'bower.json': { name: 'foobar' } }); - var logger = init({ cwd: package.path, interactive: true }); + var logger = init({ cwd: mainPackage.path, interactive: true }); return helpers.expectEvent(logger, 'log').spread(function(event) { expect(event.level).to.be('warn'); @@ -83,7 +83,7 @@ describe('bower init', function () { }); it('gets defaults from package.json', function () { - package.prepare({ + mainPackage.prepare({ 'package.json': { 'name': 'name from npm', 'description': 'description from npm', @@ -98,7 +98,7 @@ describe('bower init', function () { }); var logger = init({ - cwd: package.path, + cwd: mainPackage.path, interactive: true }); @@ -131,7 +131,7 @@ describe('bower init', function () { return helpers.expectEvent(logger, 'end'); }) .then(function () { - expect(package.readJson('bower.json')).to.eql({ + expect(mainPackage.readJson('bower.json')).to.eql({ 'name': 'name from npm', 'description': 'description from npm', 'main': 'index.js', diff --git a/test/commands/install.js b/test/commands/install.js index 1ec32793a..18cadf2f3 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -5,230 +5,230 @@ var fs = require('../../lib/util/fs'); describe('bower install', function () { - var tempDir = new helpers.TempDir(); + var tempDir = new helpers.TempDir(); - var install = helpers.command('install', { cwd: tempDir.path }); + var install = helpers.command('install', { cwd: tempDir.path }); - it('correctly reads arguments', function() { - expect(install.readOptions(['jquery', 'angular', '-F', '-p', '-S', '-D', '-E'])) + it('correctly reads arguments', function() { + expect(install.readOptions(['jquery', 'angular', '-F', '-p', '-S', '-D', '-E'])) .to.eql([['jquery', 'angular'], { - forceLatest: true, - production: true, - save: true, - saveDev: true, - saveExact: true + forceLatest: true, + production: true, + save: true, + saveDev: true, + saveExact: true }]); - }); + }); - it('correctly reads long arguments', function() { - expect(install.readOptions([ - 'jquery', 'angular', - '--force-latest', '--production', '--save', '--save-dev', '--save-exact' + it('correctly reads long arguments', function() { + expect(install.readOptions([ + 'jquery', 'angular', + '--force-latest', '--production', '--save', '--save-dev', '--save-exact' ])).to.eql([['jquery', 'angular'], { - forceLatest: true, - production: true, - save: true, - saveDev: true, - saveExact: true + forceLatest: true, + production: true, + save: true, + saveDev: true, + saveExact: true }]); - }); - - var package = new helpers.TempDir({ - 'bower.json': { - name: 'package' - } - }).prepare(); - - var gitPackage = new helpers.TempDir(); - - it('writes to bower.json if --save flag is used', function () { - package.prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test' - } - }); - - return helpers.run(install, [[package.path], { save: true }]).then(function() { - expect(tempDir.read('bower.json')).to.contain('dependencies'); - }); - }); - - it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function () { - package.prepare({ - 'bower.json': { - name: 'package', - version: '1.2.3' - } - }); - - tempDir.prepare({ - 'bower.json': { - name: 'test' - } - }); - - return helpers.run(install, [ - [package.path], - { saveExact: true, save: true } - ]).then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(package.path + '#1.2.3'); - }); - }); - - it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function () { - package.prepare({ - 'bower.json': { - name: 'package', - version: '0.1.0' - } }); - tempDir.prepare({ - 'bower.json': { - name: 'test' - } - }); - - return helpers.run(install, [ - [package.path], - { saveExact: true, saveDev: true } - ]).then(function() { - expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(package.path + '#0.1.0'); - }); - }); - - it('reads .bowerrc from cwd', function () { - package.prepare({ foo: 'bar' }); - - tempDir.prepare({ - '.bowerrc': { directory: 'assets' }, - 'bower.json': { - name: 'test', - dependencies: { - package: package.path + var mainPackage = new helpers.TempDir({ + 'bower.json': { + name: 'package' } - } - }); - - return helpers.run(install).then(function() { - expect(tempDir.read('assets/package/foo')).to.be('bar'); - }); - }); - - it('runs preinstall hook', function () { - package.prepare(); + }).prepare(); - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package: package.path - } - }, - '.bowerrc': { - scripts: { - preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' - } - } - }); + var gitPackage = new helpers.TempDir(); - return helpers.run(install).then(function() { - expect(tempDir.read('preinstall.txt')).to.be('package'); - }); - }); + it('writes to bower.json if --save flag is used', function () { + mainPackage.prepare(); - it('runs preinstall hook', function () { - package.prepare(); + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package: package.path - } - }, - '.bowerrc': { - scripts: { - postinstall: 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' - } - } + return helpers.run(install, [[mainPackage.path], { save: true }]).then(function() { + expect(tempDir.read('bower.json')).to.contain('dependencies'); + }); }); - return helpers.run(install).then(function() { - expect(tempDir.read('postinstall.txt')).to.be('package'); - }); - }); + it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function () { + mainPackage.prepare({ + 'bower.json': { + name: 'package', + version: '1.2.3' + } + }); - // To be discussed, but that's the implementation now - it('does not run hooks if nothing is installed', function () { - tempDir.prepare({ - 'bower.json': { - name: 'test' - }, - '.bowerrc': { - scripts: { - postinstall: 'node -e \'require("fs").writeFileSync("hooks.txt", "%")\'', - preinstall: 'node -e \'require("fs").writeFileSync("hooks.txt", "%")\'' - } - } - }); + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); - return helpers.run(install).then(function() { - expect(tempDir.exists('hooks.txt')).to.be(false); + return helpers.run(install, [ + [mainPackage.path], + { saveExact: true, save: true } + ]).then(function() { + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(mainPackage.path + '#1.2.3'); }); - }); - - it('runs postinstall after bower.json is written', function () { - package.prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test' - }, - '.bowerrc': { - scripts: { - postinstall: 'node -e \'var fs = require("fs"); fs.writeFileSync("hook.txt", fs.readFileSync("bower.json"));\'' - } - } }); - return helpers.run(install, [[package.path], { save: true }]).then(function() { - expect(tempDir.read('hook.txt')).to.contain('dependencies'); - }); - }); + it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function () { + mainPackage.prepare({ + 'bower.json': { + name: 'package', + version: '0.1.0' + } + }); - it('display the output of hook scripts', function (next) { - package.prepare(); + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package: package.path - } - }, - '.bowerrc': { - scripts: { - postinstall: 'node -e \'process.stdout.write("foobar")\'' - } - } - }); - var lastAction = null; - - helpers.run(install).logger.intercept(function (log) { - if (log.level === 'action') { - lastAction = log; - } - }).on('end', function () { - expect(lastAction.message).to.be('foobar'); - next(); - }); - }); - - it('skips components not installed by bower', function () { - package.prepare({ + return helpers.run(install, [ + [mainPackage.path], + { saveExact: true, saveDev: true } + ]).then(function() { + expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(mainPackage.path + '#0.1.0'); + }); + }); + + it('reads .bowerrc from cwd', function () { + mainPackage.prepare({ foo: 'bar' }); + + tempDir.prepare({ + '.bowerrc': { directory: 'assets' }, + 'bower.json': { + name: 'test', + dependencies: { + package: mainPackage.path + } + } + }); + + return helpers.run(install).then(function() { + expect(tempDir.read('assets/package/foo')).to.be('bar'); + }); + }); + + it('runs preinstall hook', function () { + mainPackage.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: mainPackage.path + } + }, + '.bowerrc': { + scripts: { + preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' + } + } + }); + + return helpers.run(install).then(function() { + expect(tempDir.read('preinstall.txt')).to.be('package'); + }); + }); + + it('runs preinstall hook', function () { + mainPackage.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: mainPackage.path + } + }, + '.bowerrc': { + scripts: { + postinstall: 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' + } + } + }); + + return helpers.run(install).then(function() { + expect(tempDir.read('postinstall.txt')).to.be('package'); + }); + }); + + // To be discussed, but that's the implementation now + it('does not run hooks if nothing is installed', function () { + tempDir.prepare({ + 'bower.json': { + name: 'test' + }, + '.bowerrc': { + scripts: { + postinstall: 'node -e \'require("fs").writeFileSync("hooks.txt", "%")\'', + preinstall: 'node -e \'require("fs").writeFileSync("hooks.txt", "%")\'' + } + } + }); + + return helpers.run(install).then(function() { + expect(tempDir.exists('hooks.txt')).to.be(false); + }); + }); + + it('runs postinstall after bower.json is written', function () { + mainPackage.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test' + }, + '.bowerrc': { + scripts: { + postinstall: 'node -e \'var fs = require("fs"); fs.writeFileSync("hook.txt", fs.readFileSync("bower.json"));\'' + } + } + }); + + return helpers.run(install, [[mainPackage.path], { save: true }]).then(function() { + expect(tempDir.read('hook.txt')).to.contain('dependencies'); + }); + }); + + it('display the output of hook scripts', function (next) { + mainPackage.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: mainPackage.path + } + }, + '.bowerrc': { + scripts: { + postinstall: 'node -e \'process.stdout.write("foobar")\'' + } + } + }); + var lastAction = null; + + helpers.run(install).logger.intercept(function (log) { + if (log.level === 'action') { + lastAction = log; + } + }).on('end', function () { + expect(lastAction.message).to.be('foobar'); + next(); + }); + }); + + it('skips components not installed by bower', function () { + mainPackage.prepare({ '.git': {} //Make a dummy file instead of using slower gitPrepare() }); @@ -236,165 +236,165 @@ describe('bower install', function () { 'bower.json': { name: 'test', dependencies: { - package: package.path + package: mainPackage.path } } }); return helpers.run(install).then(function() { - var packageFiles = fs.readdirSync(package.path); + var packageFiles = fs.readdirSync(mainPackage.path); //presence of .git file implies folder was not overwritten expect(packageFiles).to.contain('.git'); }); }); - it('works for git repositories', function () { - gitPackage.prepareGit({ - '1.0.0': { - 'bower.json': { - name: 'package' - }, - 'version.txt': '1.0.0' - }, - '1.0.1': { - 'bower.json': { - name: 'package' - }, - 'version.txt': '1.0.1' - } - }); - - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package: gitPackage.path + '#1.0.0' - } - } - }); - - return helpers.run(install).then(function() { - expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); - }); - }); - - it('does not install ignored dependencies', function() { - package.prepare(); - var package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - } - }).prepare(); - - var package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3', - dependencies: { - package2: package2.path, - package: package.path, - } - } - }).prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test_tw', - dependencies: { - package3: package3.path - } - }, - '.bowerrc': { - ignoredDependencies: ['package'] - } - }); - - return helpers.run(install).then(function() { - expect(tempDir.exists('bower_components/package')).to.be(false); - expect(tempDir.exists('bower_components/package2')).to.be(true); - }); - - }); - - it('does not install ignored dependencies if run multiple times', function() { - package.prepare(); - var package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - } - }).prepare(); - - var package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3', - dependencies: { - package2: package2.path, - package: package.path, - } - } - }).prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test_tw', - dependencies: { - package3: package3.path - } - }, - '.bowerrc': { - ignoredDependencies: ['package'] - } - }); - return helpers.run(install).then(function() { - return helpers.run(install).then(function() { - expect(tempDir.exists('bower_components/package')).to.be(false); - expect(tempDir.exists('bower_components/package2')).to.be(true); - }); - }); - - }); - - it('recognizes proxy option in config', function (done) { - this.timeout(10000); - - tempDir.prepare({ - 'bower.json': { - name: 'test_tw', - dependencies: { - pure: 'http://github.com/yahoo/pure/archive/v0.6.0.tar.gz' - } - } + it('works for git repositories', function () { + gitPackage.prepareGit({ + '1.0.0': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '1.0.0' + }, + '1.0.1': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '1.0.1' + } + }); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: gitPackage.path + '#1.0.0' + } + } + }); + + return helpers.run(install).then(function() { + expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); + }); + }); + + it('does not install ignored dependencies', function() { + mainPackage.prepare(); + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + } + }).prepare(); + + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3', + dependencies: { + package2: package2.path, + package: mainPackage.path, + } + } + }).prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test_tw', + dependencies: { + package3: package3.path + } + }, + '.bowerrc': { + ignoredDependencies: ['package'] + } + }); + + return helpers.run(install).then(function() { + expect(tempDir.exists('bower_components/package')).to.be(false); + expect(tempDir.exists('bower_components/package2')).to.be(true); + }); + + }); + + it('does not install ignored dependencies if run multiple times', function() { + mainPackage.prepare(); + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + } + }).prepare(); + + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3', + dependencies: { + package2: package2.path, + package: mainPackage.path, + } + } + }).prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test_tw', + dependencies: { + package3: package3.path + } + }, + '.bowerrc': { + ignoredDependencies: ['package'] + } + }); + return helpers.run(install).then(function() { + return helpers.run(install).then(function() { + expect(tempDir.exists('bower_components/package')).to.be(false); + expect(tempDir.exists('bower_components/package2')).to.be(true); + }); + }); + + }); + + it('recognizes proxy option in config', function (done) { + this.timeout(10000); + + tempDir.prepare({ + 'bower.json': { + name: 'test_tw', + dependencies: { + pure: 'http://github.com/yahoo/pure/archive/v0.6.0.tar.gz' + } + } + }); + + var install = helpers.command('install', { + cwd: tempDir.path + }); + + nock('http://dummy.local') + .get('http://github.com/yahoo/pure/archive/v0.6.0.tar.gz') + .reply(500); + + return helpers.run(install, [ + undefined, + undefined, + { proxy: 'http://dummy.local/' } + ]) + .fail(function(error) { + expect(error.message).to.equal('Status code of 500'); + done(); }); - - var install = helpers.command('install', { - cwd: tempDir.path }); - nock('http://dummy.local') - .get('http://github.com/yahoo/pure/archive/v0.6.0.tar.gz') - .reply(500); - return helpers.run(install, [ - undefined, - undefined, - { proxy: 'http://dummy.local/' } - ]) - .fail(function(error) { - expect(error.message).to.equal('Status code of 500'); - done(); - }); - }); + it('errors if the components directory is not a directory', function () { + tempDir.prepare({ + '.bowerrc': { + directory: '.bowerrc' + } + }); - - it('errors if the components directory is not a directory', function () { - tempDir.prepare({ - '.bowerrc': { - directory: '.bowerrc' - } - }); - - return helpers.run(install).fail(function(error) { - expect(error.code).to.equal('ENOTDIR'); + return helpers.run(install).fail(function(error) { + expect(error.code).to.equal('ENOTDIR'); + }); }); - }); }); diff --git a/test/commands/link.js b/test/commands/link.js index f221352eb..f818610fe 100644 --- a/test/commands/link.js +++ b/test/commands/link.js @@ -5,7 +5,7 @@ var link = helpers.command('link'); describe('bower link', function () { - var package = new helpers.TempDir({ + var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package', }, @@ -22,7 +22,7 @@ describe('bower link', function () { var linksDir = new helpers.TempDir(); beforeEach(function() { - package.prepare(); + mainPackage.prepare(); otherPackage.prepare(); linksDir.prepare(); }); @@ -35,7 +35,7 @@ describe('bower link', function () { it('creates self link', function () { return helpers.run(link, [undefined, undefined, { - cwd: package.path, + cwd: mainPackage.path, storage: { links: linksDir.path } @@ -49,7 +49,7 @@ describe('bower link', function () { it('creates inter-link', function () { return helpers.run(link, [undefined, undefined, { - cwd: package.path, + cwd: mainPackage.path, storage: { links: linksDir.path } @@ -72,7 +72,7 @@ describe('bower link', function () { it('creates inter-link with custom local name', function () { return helpers.run(link, [undefined, undefined, { - cwd: package.path, + cwd: mainPackage.path, storage: { links: linksDir.path } diff --git a/test/commands/list.js b/test/commands/list.js index a1c00cb25..fb506cad1 100644 --- a/test/commands/list.js +++ b/test/commands/list.js @@ -63,20 +63,20 @@ describe('bower list', function () { it('lists 1 dependency when 1 local package installed', function () { - var package = new helpers.TempDir({ + var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package', main: 'test.txt' } }).prepare(); - package.prepare(); + mainPackage.prepare(); - return install([package.path]).then(function() { + return install([mainPackage.path]).then(function() { return list().spread(function(results) { expect(results).to.be.an(Object); expect(results.canonicalDir).to.equal(tempDir.path); expect(results.pkgMeta.dependencies).to.eql({ - package: package.path + '#*' + package: mainPackage.path + '#*' }); expect(results.pkgMeta.devDependencies).to.eql({}); expect(results.dependencies.package).to.be.an(Object); @@ -96,15 +96,15 @@ describe('bower list', function () { it('lists 1 dependency with relative paths when 1 local package installed', function () { - var package = new helpers.TempDir({ + var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package', main: 'test.txt' } }).prepare(); - package.prepare(); + mainPackage.prepare(); - return install([package.path]).then(function() { + return install([mainPackage.path]).then(function() { return list({relative: true}).spread(function(results) { expect(results).to.be.an(Object); expect(results.canonicalDir).to.equal(tempDir.path); @@ -113,7 +113,7 @@ describe('bower list', function () { expect(results.dependencies.package.pkgMeta).to.be.an(Object); expect(results.dependencies.package.pkgMeta.main).to.equal('test.txt'); expect(results.pkgMeta.dependencies).to.eql({ - package: package.path + '#*' + package: mainPackage.path + '#*' }); expect(results.dependencies.package.canonicalDir).to.equal( path.normalize('bower_components/package') @@ -124,15 +124,15 @@ describe('bower list', function () { it('lists 1 dependency with 1 source relative source mapping when 1 local package installed', function () { - var package = new helpers.TempDir({ + var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package', main: 'test.txt' } }).prepare(); - package.prepare(); + mainPackage.prepare(); - return install([package.path]).then(function() { + return install([mainPackage.path]).then(function() { return list({paths: true}).spread(function(results) { expect(results).to.be.an(Object); expect(results.package).to.equal( @@ -144,15 +144,15 @@ describe('bower list', function () { it('lists 1 dependency with 2 source relative source mapping when 1 local package installed', function () { - var package = new helpers.TempDir({ + var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package', main: ['test.txt', 'test2.txt'] } }).prepare(); - package.prepare(); + mainPackage.prepare(); - return install([package.path]).then(function() { + return install([mainPackage.path]).then(function() { return list({paths: true}).spread(function(results) { expect(results).to.be.an(Object); expect(results.package).to.be.an(Object); @@ -181,7 +181,7 @@ describe('bower list', function () { 'version.txt': '1.0.1' } }); - + tempDir.prepare({ 'bower.json': { name: 'test', @@ -231,7 +231,7 @@ describe('bower list', function () { 'version.txt': '1.0.1' } }); - + tempDir.prepare({ 'bower.json': { name: 'test', diff --git a/test/commands/prune.js b/test/commands/prune.js index ee3068d93..cf2d2218d 100644 --- a/test/commands/prune.js +++ b/test/commands/prune.js @@ -5,7 +5,7 @@ var prune = helpers.command('prune'); describe('bower home', function () { - var package = new helpers.TempDir({ + var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package', dependencies: { @@ -26,30 +26,30 @@ describe('bower home', function () { }); it('removes extraneous packages', function () { - package.prepare({ + mainPackage.prepare({ 'bower_components/angular/angular.js': 'angular source', 'bower_components/angular/.bower.json': { name: 'angular' } }); - return helpers.run(prune, [{}, { cwd: package.path }]).then(function() { - expect(package.exists('bower_components/angular/angular.js')) + return helpers.run(prune, [{}, { cwd: mainPackage.path }]).then(function() { + expect(mainPackage.exists('bower_components/angular/angular.js')) .to.be(false); }); }); it('leaves non-bower packages', function () { - package.prepare({ + mainPackage.prepare({ 'bower_components/angular/angular.js': 'angular source' }); - return helpers.run(prune, [{}, { cwd: package.path }]).then(function() { - expect(package.exists('bower_components/angular/angular.js')) + return helpers.run(prune, [{}, { cwd: mainPackage.path }]).then(function() { + expect(mainPackage.exists('bower_components/angular/angular.js')) .to.be(true); }); }); it('deals with custom directory', function () { - package.prepare({ + mainPackage.prepare({ '.bowerrc': { directory: 'components' }, 'bower_components/angular/.bower.json': { name: 'angular' }, 'bower_components/angular/angular.js': 'angular source', @@ -57,9 +57,9 @@ describe('bower home', function () { 'components/angular/angular.js': 'angular source' }); - return helpers.run(prune, [{}, { cwd: package.path }]).then(function() { - expect(package.exists('components/angular/angular.js')).to.be(false); - expect(package.exists('bower_components/angular/angular.js')).to.be(true); + return helpers.run(prune, [{}, { cwd: mainPackage.path }]).then(function() { + expect(mainPackage.exists('components/angular/angular.js')).to.be(false); + expect(mainPackage.exists('bower_components/angular/angular.js')).to.be(true); }); }); }); diff --git a/test/commands/register.js b/test/commands/register.js index 1c7ccac17..9c0b70860 100644 --- a/test/commands/register.js +++ b/test/commands/register.js @@ -36,7 +36,7 @@ var registerFactory = function (canonicalDir, pkgMeta) { describe('bower register', function () { - var package = new helpers.TempDir({ + var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package' } @@ -63,9 +63,9 @@ describe('bower register', function () { }); it('errors if trying to register private package', function () { - package.prepare({ 'bower.json': { private: true } }); + mainPackage.prepare({ 'bower.json': { private: true } }); - var register = registerFactory(package.path, package.meta()); + var register = registerFactory(mainPackage.path, mainPackage.meta()); return helpers.run(register, ['some-name', 'git://fake-url.git']) .fail(function(reason) { expect(reason.message).to.be('The package you are trying to register is marked as private'); @@ -74,9 +74,9 @@ describe('bower register', function () { }); it('should call registry client with name and url', function () { - package.prepare(); + mainPackage.prepare(); - var register = registerFactory(package.path, package.meta()); + var register = registerFactory(mainPackage.path, mainPackage.meta()); return helpers.run(register, ['some-name', 'git://fake-url.git']) .spread(function(result) { expect(result).to.eql({ @@ -87,9 +87,9 @@ describe('bower register', function () { }); it('should confirm in interactive mode', function () { - package.prepare(); + mainPackage.prepare(); - var register = registerFactory(package.path, package.meta()); + var register = registerFactory(mainPackage.path, mainPackage.meta()); var promise = helpers.run(register, ['some-name', 'git://fake-url.git', { interactive: true }] @@ -104,9 +104,9 @@ describe('bower register', function () { }); it('should skip confirming when forcing', function () { - package.prepare(); + mainPackage.prepare(); - var register = registerFactory(package.path, package.meta()); + var register = registerFactory(mainPackage.path, mainPackage.meta()); return helpers.run(register, ['some-name', 'git://fake-url.git', diff --git a/test/commands/update.js b/test/commands/update.js index ed4eaa77f..eec771f13 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -11,9 +11,9 @@ describe('bower update', function () { var tempDir = new helpers.TempDir(); var subPackage = new helpers.TempDir({ - 'bower.json': { - name: 'subPackage' - } + 'bower.json': { + name: 'subPackage' + } }).prepare(); var gitPackage = new helpers.TempDir(); @@ -29,14 +29,14 @@ describe('bower update', function () { 'bower.json': { name: 'package', dependencies: { - subPackage: subPackage.path + subPackage: subPackage.path } }, 'version.txt': '1.0.1' } }); - var package = new helpers.TempDir({ + var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package' } @@ -69,21 +69,21 @@ describe('bower update', function () { it('correctly reads arguments', function() { expect(updateCmd.readOptions(['jquery', '-F', '-p', '-S', '-D'])) .to.eql([['jquery'], { - forceLatest: true, - production: true, - save: true, - saveDev: true + forceLatest: true, + production: true, + save: true, + saveDev: true }]); }); it('install missing packages', function () { - package.prepare(); + mainPackage.prepare(); tempDir.prepare({ 'bower.json': { name: 'test', dependencies: { - package: package.path + package: mainPackage.path } } }); @@ -95,22 +95,22 @@ describe('bower update', function () { }); it('does not install ignored dependencies', function() { - var package3 = new helpers.TempDir({ + var package3 = new helpers.TempDir({ 'bower.json': { name: 'package3' } }).prepare(); - var package2 = new helpers.TempDir({ + var package2 = new helpers.TempDir({ 'bower.json': { name: 'package2', dependencies: { - package3: package3.path + package3: package3.path } } }).prepare(); - tempDir.prepare({ + tempDir.prepare({ 'bower.json': { name: 'test', dependencies: { @@ -122,7 +122,7 @@ describe('bower update', function () { } }); - return update().then(function() { + return update().then(function() { expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); expect(tempDir.exists('bower_components/package3')).to.equal(false); }); @@ -130,22 +130,22 @@ describe('bower update', function () { }); it('does not install ignored dependencies if run multiple times', function() { - var package3 = new helpers.TempDir({ + var package3 = new helpers.TempDir({ 'bower.json': { name: 'package3' } }).prepare(); - var package2 = new helpers.TempDir({ + var package2 = new helpers.TempDir({ 'bower.json': { name: 'package2', dependencies: { - package3: package3.path + package3: package3.path } } }).prepare(); - tempDir.prepare({ + tempDir.prepare({ 'bower.json': { name: 'test', dependencies: { @@ -157,23 +157,23 @@ describe('bower update', function () { } }); - return update().then(function() { + return update().then(function() { return update().then(function() { - expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); - expect(tempDir.exists('bower_components/package3')).to.equal(false); + expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); + expect(tempDir.exists('bower_components/package3')).to.equal(false); }); }); }); it('runs preinstall hook when installing missing package', function () { - package.prepare(); + mainPackage.prepare(); tempDir.prepare({ 'bower.json': { name: 'test', dependencies: { - package: package.path + package: mainPackage.path } }, '.bowerrc': { @@ -189,13 +189,13 @@ describe('bower update', function () { }); it('runs postinstall hook when installing missing package', function () { - package.prepare(); + mainPackage.prepare(); tempDir.prepare({ 'bower.json': { name: 'test', dependencies: { - package: package.path + package: mainPackage.path } }, '.bowerrc': { @@ -211,13 +211,13 @@ describe('bower update', function () { }); it('doesn\'t runs postinstall when no package is update', function () { - package.prepare(); + mainPackage.prepare(); tempDir.prepare({ 'bower.json': { name: 'test', dependencies: { - package: package.path + package: mainPackage.path } }, '.bowerrc': { @@ -250,7 +250,7 @@ describe('bower update', function () { expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); - tempDir.prepare({ + tempDir.prepare({ 'bower.json': { name: 'test', dependencies: { @@ -579,7 +579,7 @@ describe('bower update', function () { }); return install().then(function() { - tempDir.prepare({ + tempDir.prepare({ 'bower.json': { name: 'test', dependencies: { diff --git a/test/commands/version.js b/test/commands/version.js index 679f3129e..64b30acc5 100644 --- a/test/commands/version.js +++ b/test/commands/version.js @@ -5,7 +5,7 @@ var version = helpers.require('lib/commands').version; describe('bower list', function () { - var package = new helpers.TempDir({ + var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'foobar', version: '0.0.0' @@ -22,41 +22,41 @@ describe('bower list', function () { }); it('bumps patch version', function() { - package.prepare(); + mainPackage.prepare(); - return helpers.run(version, ['patch', {}, { cwd: package.path }]).then(function() { - expect(package.readJson('bower.json').version).to.be('0.0.1'); + return helpers.run(version, ['patch', {}, { cwd: mainPackage.path }]).then(function() { + expect(mainPackage.readJson('bower.json').version).to.be('0.0.1'); }); }); it('bumps minor version', function() { - package.prepare(); + mainPackage.prepare(); - return helpers.run(version, ['minor', {}, { cwd: package.path }]).then(function() { - expect(package.readJson('bower.json').version).to.be('0.1.0'); + return helpers.run(version, ['minor', {}, { cwd: mainPackage.path }]).then(function() { + expect(mainPackage.readJson('bower.json').version).to.be('0.1.0'); }); }); it('bumps major version', function() { - package.prepare(); + mainPackage.prepare(); - return helpers.run(version, ['major', {}, { cwd: package.path }]).then(function() { - expect(package.readJson('bower.json').version).to.be('1.0.0'); + return helpers.run(version, ['major', {}, { cwd: mainPackage.path }]).then(function() { + expect(mainPackage.readJson('bower.json').version).to.be('1.0.0'); }); }); it('changes version', function() { - package.prepare(); + mainPackage.prepare(); - return helpers.run(version, ['1.2.3', {}, { cwd: package.path }]).then(function() { - expect(package.readJson('bower.json').version).to.be('1.2.3'); + return helpers.run(version, ['1.2.3', {}, { cwd: mainPackage.path }]).then(function() { + expect(mainPackage.readJson('bower.json').version).to.be('1.2.3'); }); }); it('returns the new version', function() { - package.prepare(); + mainPackage.prepare(); - return helpers.run(version, ['major', {}, { cwd: package.path }]).then(function(results) { + return helpers.run(version, ['major', {}, { cwd: mainPackage.path }]).then(function(results) { expect(results[0]).to.be('1.0.0'); }); }); diff --git a/test/core/scripts.js b/test/core/scripts.js index b31b84870..95bca2e50 100644 --- a/test/core/scripts.js +++ b/test/core/scripts.js @@ -14,12 +14,12 @@ describe('scripts', function () { // We cannot use pure touch, because Windows var touch = function (file) { - return 'node -e "var fs = require(\'fs\'); fs.closeSync(fs.openSync(\'' + file + '\', \'w\'));"'; + return 'node -e "var fs = require(\'fs\'); fs.closeSync(fs.openSync(\'' + file + '\', \'w\'));"'; }; // We cannot use pure touch, because Windows var touchWithPid = function (file) { - return 'node -e "var fs = require(\'fs\'); fs.closeSync(fs.openSync(process.env.BOWER_PID + \'' + file + '\', \'w\'));"'; + return 'node -e "var fs = require(\'fs\'); fs.closeSync(fs.openSync(process.env.BOWER_PID + \'' + file + '\', \'w\'));"'; }; var config = { diff --git a/test/util/download.js b/test/util/download.js index 86479bf34..ff5dd7d7a 100644 --- a/test/util/download.js +++ b/test/util/download.js @@ -29,14 +29,14 @@ describe('download', function () { deferred.resolve(); } else { deferred.reject(new Error('Error expected. Got successful response.')); - } + } }, function (error) { if (opts.expectError) { opts.expectError(error); deferred.resolve(); } else { deferred.reject(error); - } + } }) .done(); From 12258324d3962def121764be06f0b3025df0958a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 30 Nov 2015 11:06:57 +0100 Subject: [PATCH 0767/1021] More code style rules to enforce --- .jscsrc | 14 +++++++- lib/core/Project.js | 8 ++--- lib/util/analytics.js | 10 +++--- test/commands/init.js | 2 +- test/helpers.js | 2 +- test/renderers/JsonRenderer.js | 6 ++-- test/renderers/StandardRenderer.js | 52 +++++++++++++++--------------- 7 files changed, 53 insertions(+), 41 deletions(-) diff --git a/.jscsrc b/.jscsrc index 51545d4ce..99b1f9806 100644 --- a/.jscsrc +++ b/.jscsrc @@ -11,5 +11,17 @@ 'requireDotNotation': true, 'disallowTabs': true, 'disallowNewlineBeforeBlockStatements': true, - 'disallowTrailingWhitespace': true + 'disallowTrailingWhitespace': true, + 'disallowMixedSpacesAndTabs': true, + 'requireSpaceBeforeBinaryOperators': true, + 'requireSpaceBeforeBlockStatements': true, + 'requireSpaceBeforeObjectValues': true, + 'requireSpaceBetweenArguments': true, + 'requireSpacesInFunctionDeclaration': { + 'beforeOpeningCurlyBrace': true + }, + 'requireSpacesInNamedFunctionExpression': { + 'beforeOpeningCurlyBrace': true, + 'beforeOpeningRoundBrace': true + } } diff --git a/lib/core/Project.js b/lib/core/Project.js index 67bbee34b..f49b4612e 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -577,11 +577,11 @@ Project.prototype._readJson = function () { return Q.resolve(this._json); } - return Q.fcall(function(){ + return Q.fcall(function() { // This will throw if package.json does not exist return fs.readFileSync(path.join(that._config.cwd, 'package.json')); }) - .then(function(buffer){ + .then(function(buffer) { // If package.json exists, use it's values as defaults var defaults = {}, npm = JSON.parse(buffer.toString()); @@ -594,11 +594,11 @@ Project.prototype._readJson = function () { return defaults; }) - .catch(function(err){ + .catch(function(err) { // Most likely no package.json so just set default name return { name: path.basename(that._config.cwd) || 'root' }; }) - .then(function(defaults){ + .then(function(defaults) { return that._json = readJson(that._config.cwd, { assume: defaults }); }) .spread(function (json, deprecated, assumed) { diff --git a/lib/util/analytics.js b/lib/util/analytics.js index a48c25fc8..f4c0cd5ac 100644 --- a/lib/util/analytics.js +++ b/lib/util/analytics.js @@ -82,7 +82,7 @@ analytics.setup = function setup (config) { }); }; -var Tracker = analytics.Tracker = function Tracker(config) { +var Tracker = analytics.Tracker = function Tracker (config) { function analyticsEnabled () { // Allow for overriding analytics default if (config && config.analytics !== undefined) { @@ -103,24 +103,24 @@ var Tracker = analytics.Tracker = function Tracker(config) { } }; -Tracker.prototype.track = function track() { +Tracker.prototype.track = function track () { insight.track.apply(insight, arguments); }; -Tracker.prototype.trackDecomposedEndpoints = function trackDecomposedEndpoints(command, endpoints) { +Tracker.prototype.trackDecomposedEndpoints = function trackDecomposedEndpoints (command, endpoints) { endpoints.forEach(function (endpoint) { this.track(command, endpoint.source, endpoint.target); }.bind(this)); }; -Tracker.prototype.trackPackages = function trackPackages(command, packages) { +Tracker.prototype.trackPackages = function trackPackages (command, packages) { mout.object.forOwn(packages, function (_package) { var meta = _package.pkgMeta; this.track(command, meta.name, meta.version); }.bind(this)); }; -Tracker.prototype.trackNames = function trackNames(command, names) { +Tracker.prototype.trackNames = function trackNames (command, names) { names.forEach(function (name) { this.track(command, name); }.bind(this)); diff --git a/test/commands/init.js b/test/commands/init.js index ffc80f807..60acf0f59 100644 --- a/test/commands/init.js +++ b/test/commands/init.js @@ -106,7 +106,7 @@ describe('bower init', function () { .spread(function (prompt, answer) { // Get defaults from prompt - var defaults = prompt.reduce(function(memo, obj){ + var defaults = prompt.reduce(function(memo, obj) { memo[obj.name] = obj['default']; return memo; }, {}); diff --git a/test/helpers.js b/test/helpers.js index 42f0f6df1..05c0e3e36 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -162,7 +162,7 @@ exports.TempDir = (function() { return TempDir; })(); -exports.expectEvent = function expectEvent(emitter, eventName) { +exports.expectEvent = function expectEvent (emitter, eventName) { var deferred = Q.defer(); emitter.once(eventName, function () { diff --git a/test/renderers/JsonRenderer.js b/test/renderers/JsonRenderer.js index 0e43ad44d..3bc065bcb 100644 --- a/test/renderers/JsonRenderer.js +++ b/test/renderers/JsonRenderer.js @@ -27,7 +27,7 @@ describe('JsonRenderer', function () { renderer.end(); }).spread(function(stdout, stderr) { - expect(stderr).to.eq(normalize(multiline(function(){/* + expect(stderr).to.eq(normalize(multiline(function() {/* [{ "id": "foobar", "message": "hello world" @@ -52,7 +52,7 @@ describe('JsonRenderer', function () { ] }); }).spread(function(stdout, stderr) { - expect(stderr).to.eq(normalize(multiline(function(){/* + expect(stderr).to.eq(normalize(multiline(function() {/* [{ "id": "error", "data": { @@ -89,7 +89,7 @@ describe('JsonRenderer', function () { renderer.end(); }); }).spread(function(stdout, stderr) { - expect(stderr).to.eq(normalize(multiline(function(){/* + expect(stderr).to.eq(normalize(multiline(function() {/* [{ "type": "input", "name": "field", diff --git a/test/renderers/StandardRenderer.js b/test/renderers/StandardRenderer.js index 31bfe290f..3cd25fed8 100644 --- a/test/renderers/StandardRenderer.js +++ b/test/renderers/StandardRenderer.js @@ -17,7 +17,7 @@ describe('StandardRenderer', function () { message: 'hello world' }); }).spread(function(stdout, stderr) { - expect(stdout).to.eq(multiline(function(){/* + expect(stdout).to.eq(multiline(function() {/* bower foobar hello world */})); @@ -32,7 +32,7 @@ describe('StandardRenderer', function () { message: 'Hello error' }); }).spread(function(stdout, stderr) { - expect(stderr).to.eq(multiline(function(){/* + expect(stderr).to.eq(multiline(function() {/* bower EFOOBAR Hello error */})); @@ -48,7 +48,7 @@ describe('StandardRenderer', function () { details: ' Some awesome details\nMultiline! ' }); }).spread(function(stdout, stderr) { - expect(stderr).to.eq(multiline(function(){/* + expect(stderr).to.eq(multiline(function() {/* bower EFOOBAR Hello error Additional error details: @@ -68,7 +68,7 @@ describe('StandardRenderer', function () { details: ' Some awesome details\nMultiline! ' }); }).spread(function(stdout, stderr) { - expect(stderr).to.match(new RegExp(multiline(function(){/* + expect(stderr).to.match(new RegExp(multiline(function() {/* System info: Bower version: [^\r\n]+ Node version: [^\r\n]+ @@ -91,7 +91,7 @@ describe('StandardRenderer', function () { ] }); }).spread(function(stdout, stderr) { - expect(stderr).to.string(multiline(function(){/* + expect(stderr).to.string(multiline(function() {/* Stack trace: ./one.js:1 ./two.js:2 @@ -109,7 +109,7 @@ describe('StandardRenderer', function () { details: ' Some awesome details\nMultiline! ' }); }).spread(function(stdout, stderr) { - expect(stderr).to.match(new RegExp(multiline(function(){/* + expect(stderr).to.match(new RegExp(multiline(function() {/* Console trace: Error at StandardRenderer.error \(.+?\) @@ -127,7 +127,7 @@ describe('StandardRenderer', function () { message: 'foobar' }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* bower checkout jquery#foobar */})); @@ -143,7 +143,7 @@ describe('StandardRenderer', function () { message: 'foobar' }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* bower jquery#master progress foobar */})); @@ -159,7 +159,7 @@ describe('StandardRenderer', function () { message: 'foobar' }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* bower progress jquery#master foobar */})); @@ -175,7 +175,7 @@ describe('StandardRenderer', function () { message: 'foobar' }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* bower jquery#master extract foobar */})); @@ -244,7 +244,7 @@ describe('StandardRenderer', function () { } }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* Please note that, dependant1#release1, dependant2#release2 depends on fizfuz#~0.0.0 which resolved to fizfuz#0.0.0 @@ -311,7 +311,7 @@ describe('StandardRenderer', function () { } }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* Unable to find a suitable version for , please choose one: 1) fizfuz#~0.0.0 which resolved to 0.0.0 and is required by dependant1#release1, dependant2#release2 @@ -339,7 +339,7 @@ describe('StandardRenderer', function () { } }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* { foo: 'bar', @@ -362,7 +362,7 @@ describe('StandardRenderer', function () { message: 'message' }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* bower origin cached message */})); @@ -390,7 +390,7 @@ describe('StandardRenderer', function () { message: 'message' }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* bower short-origin generic message bower very-very-long-origin-string generic message bower short-origin generic message @@ -534,7 +534,7 @@ describe('StandardRenderer', function () { ]); }).spread(function(stdout, stderr) { if (helpers.isWin()) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* jquery#0.1.2 components\jquery @@ -558,7 +558,7 @@ describe('StandardRenderer', function () { */})); } else { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* jquery#0.1.2 components/jquery @@ -592,7 +592,7 @@ describe('StandardRenderer', function () { version: '1.2.3' }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* { version: '1.2.3' @@ -617,7 +617,7 @@ describe('StandardRenderer', function () { ] }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* { version: '1.2.3' @@ -644,7 +644,7 @@ describe('StandardRenderer', function () { name: 'bower' }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* bower http://bower.io Package not found. @@ -670,14 +670,14 @@ describe('StandardRenderer', function () { }); }).spread(function(stdout, stderr) { if (helpers.isWin()) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* bower link ./bar > ./foo jquery#0.1.2 components\jquery */})); } else { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* bower link ./bar > ./foo jquery#0.1.2 components/jquery @@ -701,7 +701,7 @@ describe('StandardRenderer', function () { } ]); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* Search results: jquery http://jquery.io @@ -719,7 +719,7 @@ describe('StandardRenderer', function () { url: 'http://jquery.io' }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* Package jquery registered successfully! All valid semver tags on http://jquery.io will be available as versions. @@ -744,7 +744,7 @@ describe('StandardRenderer', function () { } ]); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* awesome-jquery=jquery#0.1.1 */})); @@ -779,7 +779,7 @@ describe('StandardRenderer', function () { ] }); }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function(){/* + expect(stdout).to.equal(multiline(function() {/* Usage: From 3a37202dc526b65736b0067ed39a283cd54e858a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 1 Dec 2015 15:58:18 +0100 Subject: [PATCH 0768/1021] Rollback to original fs-write-stream-atomic --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ad13fa7a9..7a00cb0af 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "configstore": "^0.3.2", "decompress-zip": "^0.1.0", "destroy": "^1.0.3", - "fs-write-stream-atomic": "sheerun/fs-write-stream-atomic#v1.0.4-fix", + "fs-write-stream-atomic": "^1.0.4", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", "github": "^0.2.3", From ba4a1a9d4531fb53b3bc31d9b37df3f542332542 Mon Sep 17 00:00:00 2001 From: Manas Date: Wed, 2 Dec 2015 13:30:45 +0530 Subject: [PATCH 0769/1021] Adds instructions for squashing commits --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a1b830539..57a9168c2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -160,6 +160,8 @@ included in the project: force push to your remote feature branch. You may also be asked to squash commits. +10. If you are asked to squash your commits, then please use `git rebase -i master`. It will ask you to pick your commits - pick the major commits and squash the rest. + **IMPORTANT**: By submitting a patch, you agree to license your work under the same license as that used by the project. From 6616d09f47ac50c2d3877aca7ecdbe8fb0b241d5 Mon Sep 17 00:00:00 2001 From: Chris Contolini Date: Tue, 1 Dec 2015 00:38:24 -0500 Subject: [PATCH 0770/1021] Add failing tests for single package updates, optimize older tests --- lib/core/Project.js | 3 +- test/commands/install.js | 180 ++++++++++++++++++++++++++++---- test/commands/update.js | 217 +++++++++++++++++++++++++++++++-------- 3 files changed, 340 insertions(+), 60 deletions(-) diff --git a/lib/core/Project.js b/lib/core/Project.js index f49b4612e..39725d096 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -206,8 +206,9 @@ Project.prototype.update = function (names, options) { } var jsonEndpoint = endpointParser.decomposed2json(target); + var src = target.name !== target.source ? target.source + '#' : ''; // Bower uses the ~ range specifier for new installs - jsonEndpoint[target.name] = '~' + target.pkgMeta.version; + jsonEndpoint[target.name] = src + '~' + target.pkgMeta.version; if (that._options.saveDev && mout.object.has(that._json, 'devDependencies.' + target.name)) { that._json.devDependencies = mout.object.mixIn(that._json.devDependencies || {}, jsonEndpoint); diff --git a/test/commands/install.js b/test/commands/install.js index 18cadf2f3..63ec57498 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -41,6 +41,21 @@ describe('bower install', function () { var gitPackage = new helpers.TempDir(); + gitPackage.prepareGit({ + '1.0.0': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '1.0.0' + }, + '1.0.1': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '1.0.1' + } + }); + it('writes to bower.json if --save flag is used', function () { mainPackage.prepare(); @@ -250,20 +265,6 @@ describe('bower install', function () { }); it('works for git repositories', function () { - gitPackage.prepareGit({ - '1.0.0': { - 'bower.json': { - name: 'package' - }, - 'version.txt': '1.0.0' - }, - '1.0.1': { - 'bower.json': { - name: 'package' - }, - 'version.txt': '1.0.1' - } - }); tempDir.prepare({ 'bower.json': { @@ -379,10 +380,10 @@ describe('bower install', function () { undefined, { proxy: 'http://dummy.local/' } ]) - .fail(function(error) { - expect(error.message).to.equal('Status code of 500'); - done(); - }); + .fail(function(error) { + expect(error.message).to.equal('Status code of 500'); + done(); + }); }); @@ -397,4 +398,147 @@ describe('bower install', function () { expect(error.code).to.equal('ENOTDIR'); }); }); + + it('installs only the specified dependencies', function() { + var package4 = new helpers.TempDir({ + 'bower.json': { + name: 'package3' + } + }).prepare(); + + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3' + } + }).prepare(); + + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2' + } + }).prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package2: package2.path, + package3: package3.path, + package4: package4.path + } + } + }); + + return helpers.run(install, [[package2.path, package3.path]]).then(function() { + expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); + expect(tempDir.exists('bower_components/package3/bower.json')).to.equal(true); + expect(tempDir.exists('bower_components/package4')).to.equal(false); + }); + + }); + + it('installs sub deps of only the specified packages', function() { + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3', + dependencies: { + package: gitPackage.path + '#~1.0.1' + } + } + }).prepare(); + + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + dependencies: { + package: gitPackage.path + '#1.0.0' + } + } + }).prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package2: package2.path, + package3: package3.path + } + } + }); + + return helpers.run(install, [ + [package2.path] + ]).then(function() { + expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('1.0.0'); + }); + + }); + + it('doesn\'t update other deps when installing a specified dep', function() { + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + version: '1.2.3' + } + }).prepare(); + + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3', + version: '4.5.6' + } + }).prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package2: package2.path, + package3: package3.path + } + } + }); + + // Install both dependencies, they should equal the latest release matching + // the ranges above. + return helpers.run(install).then(function() { + expect(tempDir.readJson('bower_components/package2/.bower.json').version).to.equal('1.2.3'); + expect(tempDir.readJson('bower_components/package3/.bower.json').version).to.equal('4.5.6'); + // Override first dep with older version + package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + version: '1.0.0' + } + }).prepare(); + return helpers.run(install, [ + [package2.path] + ]).then(function() { + expect(tempDir.readJson('bower_components/package2/.bower.json').version).to.equal('1.0.0'); + expect(tempDir.readJson('bower_components/package3/.bower.json').version).to.equal('4.5.6'); + // Override second dep with older version, the first dep should remain old + // and *not* get updated. + package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + version: '1.2.3' + } + }).prepare(); + package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3', + version: '4.0.0' + } + }).prepare(); + return helpers.run(install, [ + [package3.path] + ]).then(function() { + expect(tempDir.readJson('bower_components/package2/.bower.json').version).to.equal('1.0.0'); + expect(tempDir.readJson('bower_components/package3/.bower.json').version).to.equal('4.0.0'); + }); + }); + }); + + }); + }); diff --git a/test/commands/update.js b/test/commands/update.js index eec771f13..a7b571df0 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -3,11 +3,12 @@ var object = require('mout').object; var semver = require('semver'); var helpers = require('../helpers'); +var rimraf = require('../../lib/util/rimraf'); var updateCmd = helpers.command('update'); var commands = helpers.require('lib/index').commands; describe('bower update', function () { - this.timeout(10000); + var tempDir = new helpers.TempDir(); var subPackage = new helpers.TempDir({ @@ -17,8 +18,16 @@ describe('bower update', function () { }).prepare(); var gitPackage = new helpers.TempDir(); + var gitPackage2 = new helpers.TempDir(); + var gitPackage3 = new helpers.TempDir(); gitPackage.prepareGit({ + '0.1.1': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '0.9.0' + }, '1.0.0': { 'bower.json': { name: 'package' @@ -36,6 +45,36 @@ describe('bower update', function () { } }); + gitPackage2.prepareGit({ + '2.0.0': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '2.0.0' + }, + '2.0.1': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '2.0.1' + } + }); + + gitPackage3.prepareGit({ + '3.0.0': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '3.0.0' + }, + '3.0.1': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '3.0.1' + } + }); + var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package' @@ -265,6 +304,101 @@ describe('bower update', function () { }); }); + it('updates only the specified packages', function() { + var package4 = new helpers.TempDir({ + 'bower.json': { + name: 'package4' + } + }).prepare(); + + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3' + } + }).prepare(); + + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2' + } + }).prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package2: package2.path, + package3: package3.path, + package4: package4.path + } + } + }); + + return install().then(function() { + + rimraf.sync(tempDir.path + '/bower_components/'); + + return update(['package4']).then(function() { + expect(tempDir.exists('bower_components/package2')).to.equal(false); + expect(tempDir.exists('bower_components/package3')).to.equal(false); + expect(tempDir.exists('bower_components/package4/bower.json')).to.equal(true); + + rimraf.sync(tempDir.path + '/bower_components/'); + + return update(['package2', 'package3']).then(function() { + expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); + expect(tempDir.exists('bower_components/package3/bower.json')).to.equal(true); + expect(tempDir.exists('bower_components/package4')).to.equal(false); + }); + + }); + + }); + + }); + + it('updates sub deps of only the specified packages', function() { + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3', + dependencies: { + package: gitPackage.path + '#~1.0.0' + } + } + }).prepare(); + + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + dependencies: { + package: gitPackage2.path + '#~2.0.0' + } + } + }).prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package2: package2.path, + package3: package3.path + } + } + }); + + return install([package2.path]).then(function() { + expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('2.0.1'); + + rimraf.sync(tempDir.path + '/bower_components/'); + + return update(['package3']).then(function() { + expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('1.0.1'); + }); + + }); + + }); + it('doesn\'t update extraneous packages', function () { tempDir.prepare({ 'bower.json': { @@ -272,12 +406,12 @@ describe('bower update', function () { } }); - return install(['underscore#1.5.0']).then(function() { + return install(['package=' + gitPackage.path + '#1.0.0']).then(function() { - expect(tempDir.readJson('bower_components/underscore/package.json').version).to.equal('1.5.0'); + expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('1.0.0'); return update(null, {save: true}).then(function() { - expect(tempDir.readJson('bower_components/underscore/package.json').version).to.equal('1.5.0'); + expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('1.0.0'); expect(tempDir.readJson('bower.json')).to.not.have.property('dependencies'); }); }); @@ -288,17 +422,17 @@ describe('bower update', function () { 'bower.json': { name: 'test', dependencies: { - underscore: '~1.5.0' + package: gitPackage.path + '#~1.0.0' } } }); return install().then(function() { - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.0'); + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.0'); return update(null, {save: true}).then(function() { - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.2'); + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.1'); }); }); @@ -309,17 +443,17 @@ describe('bower update', function () { 'bower.json': { name: 'test', devDependencies: { - underscore: '~1.5.0' + package: gitPackage.path + '#~1.0.0' } } }); return install().then(function() { - expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.0'); + expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(gitPackage.path + '#~1.0.0'); return update(null, {saveDev: true}).then(function() { - expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.2'); + expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(gitPackage.path + '#~1.0.1'); }); }); @@ -330,17 +464,18 @@ describe('bower update', function () { 'bower.json': { name: 'test', dependencies: { - underscore: '*' + package: gitPackage.path + '#*' } } }); return install().then(function() { - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('*'); + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#*'); return update(null, {save: true}).then(function() { - var version = semver.gte(tempDir.readJson('bower.json').dependencies.underscore.replace('~', ''), '1.8.3'); + var version = tempDir.readJson('bower.json').dependencies.package.replace(gitPackage.path + '#~', ''); + version = semver.gte(version, '1.0.1'); expect(version).to.be.ok(); }); @@ -352,27 +487,27 @@ describe('bower update', function () { 'bower.json': { name: 'test', dependencies: { - underscore: '~1.5.0', - lodash: '~1.0.0' + package: gitPackage.path + '#~1.0.0', + package2: gitPackage2.path + '#~2.0.0' }, devDependencies: { - neat: '~1.5.0' + package3: gitPackage3.path + '#~3.0.0' }, } }); return install().then(function() { - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.0'); - expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.0.0'); - expect(tempDir.readJson('bower.json').devDependencies.neat).to.equal('~1.5.0'); + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.0'); + expect(tempDir.readJson('bower.json').dependencies.package2).to.equal(gitPackage2.path + '#~2.0.0'); + expect(tempDir.readJson('bower.json').devDependencies.package3).to.equal(gitPackage3.path + '#~3.0.0'); return update(null, {save: true}).then(function() { // Normal deps should have changed - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.2'); - expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.0.2'); + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.1'); + expect(tempDir.readJson('bower.json').dependencies.package2).to.equal(gitPackage2.path + '#~2.0.1'); // Dev deps should not have changed - expect(tempDir.readJson('bower.json').devDependencies.neat).to.equal('~1.5.0'); + expect(tempDir.readJson('bower.json').devDependencies.package3).to.equal(gitPackage3.path + '#~3.0.0'); }); }); @@ -383,27 +518,27 @@ describe('bower update', function () { 'bower.json': { name: 'test', dependencies: { - neat: '~1.5.0' + package: gitPackage.path + '#~1.0.0' }, devDependencies: { - underscore: '~1.5.0', - lodash: '~1.0.0' - } + package2: gitPackage2.path + '#~2.0.0', + package3: gitPackage3.path + '#~3.0.0' + }, } }); return install().then(function() { - expect(tempDir.readJson('bower.json').dependencies.neat).to.equal('~1.5.0'); - expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.0'); - expect(tempDir.readJson('bower.json').devDependencies.lodash).to.equal('~1.0.0'); + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.0'); + expect(tempDir.readJson('bower.json').devDependencies.package2).to.equal(gitPackage2.path + '#~2.0.0'); + expect(tempDir.readJson('bower.json').devDependencies.package3).to.equal(gitPackage3.path + '#~3.0.0'); return update(null, {saveDev: true}).then(function() { // Normal deps should not have changed - expect(tempDir.readJson('bower.json').dependencies.neat).to.equal('~1.5.0'); + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.0'); // Dev deps should have changed - expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.2'); - expect(tempDir.readJson('bower.json').devDependencies.lodash).to.equal('~1.0.2'); + expect(tempDir.readJson('bower.json').devDependencies.package2).to.equal(gitPackage2.path + '#~2.0.1'); + expect(tempDir.readJson('bower.json').devDependencies.package3).to.equal(gitPackage3.path + '#~3.0.1'); }); }); @@ -414,17 +549,17 @@ describe('bower update', function () { 'bower.json': { name: 'test', dependencies: { - underscore: '^0.1.0' + package: gitPackage.path + '#^0.1.0' } } }); return install().then(function() { - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('^0.1.0'); + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#^0.1.0'); return update(null, {save: true}).then(function() { - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~0.1.1'); + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~0.1.1'); }); }); @@ -435,17 +570,17 @@ describe('bower update', function () { 'bower.json': { name: 'test', dependencies: { - lodash: '^1.0.0' + package: gitPackage.path + '#^1.0.0' } } }); return install().then(function() { - expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('^1.0.0'); + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#^1.0.0'); return update(null, {save: true}).then(function() { - expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.3.1'); + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.1'); }); }); @@ -456,17 +591,17 @@ describe('bower update', function () { 'bower.json': { name: 'test', dependencies: { - underscore: '1.5.0' + package: gitPackage.path + '#1.0.0' } } }); return install().then(function() { - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('1.5.0'); + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#1.0.0'); return update(null, {save: true}).then(function() { - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('1.5.0'); + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#1.0.0'); }); }); From e3f402fc66ee49e6ca033fdd43ce7a7cf1a5bb0c Mon Sep 17 00:00:00 2001 From: Chris Contolini Date: Tue, 1 Dec 2015 00:49:40 -0500 Subject: [PATCH 0771/1021] Only update packages requested by the user --- lib/core/Manager.js | 11 ++++++++++- lib/core/Project.js | 5 +++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index cb5a6ae58..d450b3d4d 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -76,6 +76,8 @@ Manager.prototype.configure = function (setup) { // Uniquify targets this._targets = this._uniquify(this._targets); + this._requested = setup.requested || []; + // Force-latest this._forceLatest = !!setup.forceLatest; @@ -94,6 +96,8 @@ Manager.prototype.configure = function (setup) { * */ Manager.prototype.resolve = function () { + var name; + // If already resolving, error out if (this._working) { return Q.reject(createError('Already working', 'EWORKING')); @@ -112,7 +116,12 @@ Manager.prototype.resolve = function () { // Otherwise, fetch each target from the repository // and let the process roll out } else { - this._targets.forEach(this._fetch.bind(this)); + this._targets.forEach(function (target) { + name = target.name || target.source; + if (!this._requested.length || mout.array.contains(this._requested, name)) { + this._fetch(target); + } + }.bind(this)); } // Unset working flag when done diff --git a/lib/core/Project.js b/lib/core/Project.js index 39725d096..9cc6eff44 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -38,6 +38,9 @@ Project.prototype.install = function (decEndpoints, options, config) { this._options = options || {}; this._config = config || {}; this._working = true; + this._endpoints = decEndpoints.map(function (endpoint) { + return endpoint.name || endpoint.source; + }); // Analyse the project return this._analyse() @@ -131,6 +134,7 @@ Project.prototype.update = function (names, options) { this._options = options || {}; this._working = true; + this._endpoints = names; // Analyse the project return this._analyse() @@ -558,6 +562,7 @@ Project.prototype._bootstrap = function (targets, resolved, incompatibles) { targets: targets, resolved: resolved, incompatibles: incompatibles, + requested: this._endpoints, resolutions: this._json.resolutions, installed: installed, forceLatest: this._options.forceLatest From 8c1f30b1c87d22cb9ea8ec296ed9bce9c19e541d Mon Sep 17 00:00:00 2001 From: Chris Contolini Date: Wed, 2 Dec 2015 13:58:14 -0500 Subject: [PATCH 0772/1021] Format test files to comply with new jscs rules --- test/commands/install.js | 375 ++++++++++++++++++++------------------- test/commands/update.js | 318 +++++++++++++++++---------------- 2 files changed, 358 insertions(+), 335 deletions(-) diff --git a/test/commands/install.js b/test/commands/install.js index 63ec57498..858745e99 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -3,34 +3,40 @@ var helpers = require('../helpers'); var nock = require('nock'); var fs = require('../../lib/util/fs'); -describe('bower install', function () { +describe('bower install', function() { var tempDir = new helpers.TempDir(); - var install = helpers.command('install', { cwd: tempDir.path }); + var install = helpers.command('install', { + cwd: tempDir.path + }); it('correctly reads arguments', function() { expect(install.readOptions(['jquery', 'angular', '-F', '-p', '-S', '-D', '-E'])) - .to.eql([['jquery', 'angular'], { - forceLatest: true, - production: true, - save: true, - saveDev: true, - saveExact: true - }]); + .to.eql([ + ['jquery', 'angular'], { + forceLatest: true, + production: true, + save: true, + saveDev: true, + saveExact: true + } + ]); }); it('correctly reads long arguments', function() { expect(install.readOptions([ - 'jquery', 'angular', - '--force-latest', '--production', '--save', '--save-dev', '--save-exact' - ])).to.eql([['jquery', 'angular'], { - forceLatest: true, - production: true, - save: true, - saveDev: true, - saveExact: true - }]); + 'jquery', 'angular', + '--force-latest', '--production', '--save', '--save-dev', '--save-exact' + ])).to.eql([ + ['jquery', 'angular'], { + forceLatest: true, + production: true, + save: true, + saveDev: true, + saveExact: true + } + ]); }); var mainPackage = new helpers.TempDir({ @@ -56,7 +62,7 @@ describe('bower install', function () { } }); - it('writes to bower.json if --save flag is used', function () { + it('writes to bower.json if --save flag is used', function() { mainPackage.prepare(); tempDir.prepare({ @@ -65,12 +71,16 @@ describe('bower install', function () { } }); - return helpers.run(install, [[mainPackage.path], { save: true }]).then(function() { + return helpers.run(install, [ + [mainPackage.path], { + save: true + } + ]).then(function() { expect(tempDir.read('bower.json')).to.contain('dependencies'); }); }); - it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function () { + it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function() { mainPackage.prepare({ 'bower.json': { name: 'package', @@ -85,14 +95,16 @@ describe('bower install', function () { }); return helpers.run(install, [ - [mainPackage.path], - { saveExact: true, save: true } - ]).then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(mainPackage.path + '#1.2.3'); - }); + [mainPackage.path], { + saveExact: true, + save: true + } + ]).then(function() { + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(mainPackage.path + '#1.2.3'); + }); }); - it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function () { + it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function() { mainPackage.prepare({ 'bower.json': { name: 'package', @@ -107,18 +119,24 @@ describe('bower install', function () { }); return helpers.run(install, [ - [mainPackage.path], - { saveExact: true, saveDev: true } - ]).then(function() { - expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(mainPackage.path + '#0.1.0'); - }); + [mainPackage.path], { + saveExact: true, + saveDev: true + } + ]).then(function() { + expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(mainPackage.path + '#0.1.0'); + }); }); - it('reads .bowerrc from cwd', function () { - mainPackage.prepare({ foo: 'bar' }); + it('reads .bowerrc from cwd', function() { + mainPackage.prepare({ + foo: 'bar' + }); tempDir.prepare({ - '.bowerrc': { directory: 'assets' }, + '.bowerrc': { + directory: 'assets' + }, 'bower.json': { name: 'test', dependencies: { @@ -132,7 +150,7 @@ describe('bower install', function () { }); }); - it('runs preinstall hook', function () { + it('runs preinstall hook', function() { mainPackage.prepare(); tempDir.prepare({ @@ -154,7 +172,7 @@ describe('bower install', function () { }); }); - it('runs preinstall hook', function () { + it('runs preinstall hook', function() { mainPackage.prepare(); tempDir.prepare({ @@ -177,7 +195,7 @@ describe('bower install', function () { }); // To be discussed, but that's the implementation now - it('does not run hooks if nothing is installed', function () { + it('does not run hooks if nothing is installed', function() { tempDir.prepare({ 'bower.json': { name: 'test' @@ -195,7 +213,7 @@ describe('bower install', function () { }); }); - it('runs postinstall after bower.json is written', function () { + it('runs postinstall after bower.json is written', function() { mainPackage.prepare(); tempDir.prepare({ @@ -209,12 +227,16 @@ describe('bower install', function () { } }); - return helpers.run(install, [[mainPackage.path], { save: true }]).then(function() { + return helpers.run(install, [ + [mainPackage.path], { + save: true + } + ]).then(function() { expect(tempDir.read('hook.txt')).to.contain('dependencies'); }); }); - it('display the output of hook scripts', function (next) { + it('display the output of hook scripts', function(next) { mainPackage.prepare(); tempDir.prepare({ @@ -232,39 +254,38 @@ describe('bower install', function () { }); var lastAction = null; - helpers.run(install).logger.intercept(function (log) { + helpers.run(install).logger.intercept(function(log) { if (log.level === 'action') { lastAction = log; } - }).on('end', function () { + }).on('end', function() { expect(lastAction.message).to.be('foobar'); next(); }); }); - it('skips components not installed by bower', function () { - mainPackage.prepare({ - '.git': {} //Make a dummy file instead of using slower gitPrepare() - }); - - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package: mainPackage.path - } - } - }); + it('skips components not installed by bower', function() { + mainPackage.prepare({ + '.git': {} //Make a dummy file instead of using slower gitPrepare() + }); - return helpers.run(install).then(function() { - var packageFiles = fs.readdirSync(mainPackage.path); - //presence of .git file implies folder was not overwritten - expect(packageFiles).to.contain('.git'); - }); + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: mainPackage.path + } + } + }); - }); + return helpers.run(install).then(function() { + var packageFiles = fs.readdirSync(mainPackage.path); + //presence of .git file implies folder was not overwritten + expect(packageFiles).to.contain('.git'); + }); + }); - it('works for git repositories', function () { + it('works for git repositories', function() { tempDir.prepare({ 'bower.json': { @@ -314,7 +335,6 @@ describe('bower install', function () { expect(tempDir.exists('bower_components/package')).to.be(false); expect(tempDir.exists('bower_components/package2')).to.be(true); }); - }); it('does not install ignored dependencies if run multiple times', function() { @@ -352,10 +372,9 @@ describe('bower install', function () { expect(tempDir.exists('bower_components/package2')).to.be(true); }); }); - }); - it('recognizes proxy option in config', function (done) { + it('recognizes proxy option in config', function(done) { this.timeout(10000); tempDir.prepare({ @@ -372,22 +391,23 @@ describe('bower install', function () { }); nock('http://dummy.local') - .get('http://github.com/yahoo/pure/archive/v0.6.0.tar.gz') - .reply(500); + .get('http://github.com/yahoo/pure/archive/v0.6.0.tar.gz') + .reply(500); return helpers.run(install, [ - undefined, - undefined, - { proxy: 'http://dummy.local/' } - ]) - .fail(function(error) { - expect(error.message).to.equal('Status code of 500'); - done(); - }); + undefined, + undefined, { + proxy: 'http://dummy.local/' + } + ]) + .fail(function(error) { + expect(error.message).to.equal('Status code of 500'); + done(); + }); }); - it('errors if the components directory is not a directory', function () { + it('errors if the components directory is not a directory', function() { tempDir.prepare({ '.bowerrc': { directory: '.bowerrc' @@ -402,7 +422,7 @@ describe('bower install', function () { it('installs only the specified dependencies', function() { var package4 = new helpers.TempDir({ 'bower.json': { - name: 'package3' + name: 'package4' } }).prepare(); @@ -434,111 +454,108 @@ describe('bower install', function () { expect(tempDir.exists('bower_components/package3/bower.json')).to.equal(true); expect(tempDir.exists('bower_components/package4')).to.equal(false); }); - }); it('installs sub deps of only the specified packages', function() { - var package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3', - dependencies: { - package: gitPackage.path + '#~1.0.1' - } - } - }).prepare(); - - var package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - dependencies: { - package: gitPackage.path + '#1.0.0' - } - } - }).prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package2: package2.path, - package3: package3.path - } - } - }); - - return helpers.run(install, [ - [package2.path] - ]).then(function() { - expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('1.0.0'); - }); - - }); + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3', + dependencies: { + package: gitPackage.path + '#~1.0.1' + } + } + }).prepare(); + + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + dependencies: { + package: gitPackage.path + '#1.0.0' + } + } + }).prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package2: package2.path, + package3: package3.path + } + } + }); + + return helpers.run(install, [[package2.path]]).then(function() { + expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('1.0.0'); + }); + }); it('doesn\'t update other deps when installing a specified dep', function() { - var package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - version: '1.2.3' - } - }).prepare(); - - var package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3', - version: '4.5.6' - } - }).prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package2: package2.path, - package3: package3.path - } - } - }); - - // Install both dependencies, they should equal the latest release matching - // the ranges above. - return helpers.run(install).then(function() { - expect(tempDir.readJson('bower_components/package2/.bower.json').version).to.equal('1.2.3'); - expect(tempDir.readJson('bower_components/package3/.bower.json').version).to.equal('4.5.6'); - // Override first dep with older version - package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - version: '1.0.0' - } - }).prepare(); - return helpers.run(install, [ - [package2.path] - ]).then(function() { - expect(tempDir.readJson('bower_components/package2/.bower.json').version).to.equal('1.0.0'); - expect(tempDir.readJson('bower_components/package3/.bower.json').version).to.equal('4.5.6'); - // Override second dep with older version, the first dep should remain old - // and *not* get updated. - package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - version: '1.2.3' - } - }).prepare(); - package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3', - version: '4.0.0' - } - }).prepare(); - return helpers.run(install, [ - [package3.path] - ]).then(function() { - expect(tempDir.readJson('bower_components/package2/.bower.json').version).to.equal('1.0.0'); - expect(tempDir.readJson('bower_components/package3/.bower.json').version).to.equal('4.0.0'); - }); - }); - }); - - }); + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + version: '1.2.3' + } + }).prepare(); + + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3', + version: '4.5.6' + } + }).prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package2: package2.path, + package3: package3.path + } + } + }); + + // Install both dependencies, they should equal the latest release matching + // the ranges above. + return helpers.run(install).then(function() { + + expect(tempDir.readJson('bower_components/package2/.bower.json').version).to.equal('1.2.3'); + expect(tempDir.readJson('bower_components/package3/.bower.json').version).to.equal('4.5.6'); + // Override first dep with older version + package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + version: '1.0.0' + } + }).prepare(); + + return helpers.run(install, [[package2.path]]).then(function() { + + expect(tempDir.readJson('bower_components/package2/.bower.json').version).to.equal('1.0.0'); + expect(tempDir.readJson('bower_components/package3/.bower.json').version).to.equal('4.5.6'); + + // Override second dep with older version, the first dep should remain old + // and *not* get updated. + package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + version: '1.2.3' + } + }).prepare(); + + package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3', + version: '4.0.0' + } + }).prepare(); + + return helpers.run(install, [[package3.path]]).then(function() { + expect(tempDir.readJson('bower_components/package2/.bower.json').version).to.equal('1.0.0'); + expect(tempDir.readJson('bower_components/package3/.bower.json').version).to.equal('4.0.0'); + }); + }); + }); + }); }); diff --git a/test/commands/update.js b/test/commands/update.js index a7b571df0..fded86287 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -7,7 +7,7 @@ var rimraf = require('../../lib/util/rimraf'); var updateCmd = helpers.command('update'); var commands = helpers.require('lib/index').commands; -describe('bower update', function () { +describe('bower update', function() { var tempDir = new helpers.TempDir(); @@ -107,15 +107,17 @@ describe('bower update', function () { it('correctly reads arguments', function() { expect(updateCmd.readOptions(['jquery', '-F', '-p', '-S', '-D'])) - .to.eql([['jquery'], { - forceLatest: true, - production: true, - save: true, - saveDev: true - }]); + .to.eql([ + ['jquery'], { + forceLatest: true, + production: true, + save: true, + saveDev: true + } + ]); }); - it('install missing packages', function () { + it('install missing packages', function() { mainPackage.prepare(); tempDir.prepare({ @@ -135,77 +137,76 @@ describe('bower update', function () { it('does not install ignored dependencies', function() { var package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3' - } - }).prepare(); + 'bower.json': { + name: 'package3' + } + }).prepare(); var package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - dependencies: { - package3: package3.path - } - } - }).prepare(); + 'bower.json': { + name: 'package2', + dependencies: { + package3: package3.path + } + } + }).prepare(); tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package2: package2.path - } - }, - '.bowerrc': { - ignoredDependencies: ['package3'] - } - }); + 'bower.json': { + name: 'test', + dependencies: { + package2: package2.path + } + }, + '.bowerrc': { + ignoredDependencies: ['package3'] + } + }); return update().then(function() { - expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); - expect(tempDir.exists('bower_components/package3')).to.equal(false); - }); - + expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); + expect(tempDir.exists('bower_components/package3')).to.equal(false); + }); }); it('does not install ignored dependencies if run multiple times', function() { var package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3' - } - }).prepare(); + 'bower.json': { + name: 'package3' + } + }).prepare(); var package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - dependencies: { - package3: package3.path - } - } - }).prepare(); + 'bower.json': { + name: 'package2', + dependencies: { + package3: package3.path + } + } + }).prepare(); tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package2: package2.path - } - }, - '.bowerrc': { - ignoredDependencies: ['package3'] - } - }); + 'bower.json': { + name: 'test', + dependencies: { + package2: package2.path + } + }, + '.bowerrc': { + ignoredDependencies: ['package3'] + } + }); return update().then(function() { - return update().then(function() { - expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); - expect(tempDir.exists('bower_components/package3')).to.equal(false); - }); - }); + return update().then(function() { + expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); + expect(tempDir.exists('bower_components/package3')).to.equal(false); + }); + }); }); - it('runs preinstall hook when installing missing package', function () { + it('runs preinstall hook when installing missing package', function() { mainPackage.prepare(); tempDir.prepare({ @@ -227,7 +228,7 @@ describe('bower update', function () { }); }); - it('runs postinstall hook when installing missing package', function () { + it('runs postinstall hook when installing missing package', function() { mainPackage.prepare(); tempDir.prepare({ @@ -249,7 +250,7 @@ describe('bower update', function () { }); }); - it('doesn\'t runs postinstall when no package is update', function () { + it('doesn\'t runs postinstall when no package is update', function() { mainPackage.prepare(); tempDir.prepare({ @@ -275,7 +276,7 @@ describe('bower update', function () { }); }); - it('updates a package', function () { + it('updates a package', function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -306,100 +307,95 @@ describe('bower update', function () { it('updates only the specified packages', function() { var package4 = new helpers.TempDir({ - 'bower.json': { - name: 'package4' - } - }).prepare(); + 'bower.json': { + name: 'package4' + } + }).prepare(); var package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3' - } - }).prepare(); + 'bower.json': { + name: 'package3' + } + }).prepare(); var package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2' - } - }).prepare(); + 'bower.json': { + name: 'package2' + } + }).prepare(); tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package2: package2.path, - package3: package3.path, - package4: package4.path - } - } - }); + 'bower.json': { + name: 'test', + dependencies: { + package2: package2.path, + package3: package3.path, + package4: package4.path + } + } + }); return install().then(function() { rimraf.sync(tempDir.path + '/bower_components/'); return update(['package4']).then(function() { - expect(tempDir.exists('bower_components/package2')).to.equal(false); - expect(tempDir.exists('bower_components/package3')).to.equal(false); - expect(tempDir.exists('bower_components/package4/bower.json')).to.equal(true); - - rimraf.sync(tempDir.path + '/bower_components/'); - - return update(['package2', 'package3']).then(function() { - expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); - expect(tempDir.exists('bower_components/package3/bower.json')).to.equal(true); - expect(tempDir.exists('bower_components/package4')).to.equal(false); - }); + expect(tempDir.exists('bower_components/package2')).to.equal(false); + expect(tempDir.exists('bower_components/package3')).to.equal(false); + expect(tempDir.exists('bower_components/package4/bower.json')).to.equal(true); - }); + rimraf.sync(tempDir.path + '/bower_components/'); + return update(['package2', 'package3']).then(function() { + expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); + expect(tempDir.exists('bower_components/package3/bower.json')).to.equal(true); + expect(tempDir.exists('bower_components/package4')).to.equal(false); + }); + }); }); - }); it('updates sub deps of only the specified packages', function() { var package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3', - dependencies: { - package: gitPackage.path + '#~1.0.0' - } - } - }).prepare(); + 'bower.json': { + name: 'package3', + dependencies: { + package: gitPackage.path + '#~1.0.0' + } + } + }).prepare(); var package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - dependencies: { - package: gitPackage2.path + '#~2.0.0' - } - } - }).prepare(); + 'bower.json': { + name: 'package2', + dependencies: { + package: gitPackage2.path + '#~2.0.0' + } + } + }).prepare(); tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package2: package2.path, - package3: package3.path - } - } - }); + 'bower.json': { + name: 'test', + dependencies: { + package2: package2.path, + package3: package3.path + } + } + }); return install([package2.path]).then(function() { - expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('2.0.1'); - - rimraf.sync(tempDir.path + '/bower_components/'); - - return update(['package3']).then(function() { - expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('1.0.1'); - }); + expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('2.0.1'); - }); + rimraf.sync(tempDir.path + '/bower_components/'); + return update(['package3']).then(function() { + expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('1.0.1'); + }); + }); }); - it('doesn\'t update extraneous packages', function () { + it('doesn\'t update extraneous packages', function() { tempDir.prepare({ 'bower.json': { name: 'test' @@ -410,14 +406,16 @@ describe('bower update', function () { expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('1.0.0'); - return update(null, {save: true}).then(function() { + return update(null, { + save: true + }).then(function() { expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('1.0.0'); expect(tempDir.readJson('bower.json')).to.not.have.property('dependencies'); }); }); }); - it('updates bower.json dep after updating with --save flag', function () { + it('updates bower.json dep after updating with --save flag', function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -431,14 +429,15 @@ describe('bower update', function () { expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.0'); - return update(null, {save: true}).then(function() { + return update(null, { + save: true + }).then(function() { expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.1'); }); - }); }); - it('updates bower.json dev dep after updating with --save-dev flag', function () { + it('updates bower.json dev dep after updating with --save-dev flag', function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -452,14 +451,15 @@ describe('bower update', function () { expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(gitPackage.path + '#~1.0.0'); - return update(null, {saveDev: true}).then(function() { + return update(null, { + saveDev: true + }).then(function() { expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(gitPackage.path + '#~1.0.1'); }); - }); }); - it('replaces "any" range with latest version', function () { + it('replaces "any" range with latest version', function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -473,16 +473,17 @@ describe('bower update', function () { expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#*'); - return update(null, {save: true}).then(function() { + return update(null, { + save: true + }).then(function() { var version = tempDir.readJson('bower.json').dependencies.package.replace(gitPackage.path + '#~', ''); version = semver.gte(version, '1.0.1'); expect(version).to.be.ok(); }); - }); }); - it('updates multiple components in bower.json after updating with --save flag', function () { + it('updates multiple components in bower.json after updating with --save flag', function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -502,18 +503,19 @@ describe('bower update', function () { expect(tempDir.readJson('bower.json').dependencies.package2).to.equal(gitPackage2.path + '#~2.0.0'); expect(tempDir.readJson('bower.json').devDependencies.package3).to.equal(gitPackage3.path + '#~3.0.0'); - return update(null, {save: true}).then(function() { + return update(null, { + save: true + }).then(function() { // Normal deps should have changed expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.1'); expect(tempDir.readJson('bower.json').dependencies.package2).to.equal(gitPackage2.path + '#~2.0.1'); // Dev deps should not have changed expect(tempDir.readJson('bower.json').devDependencies.package3).to.equal(gitPackage3.path + '#~3.0.0'); }); - }); }); - it('updates multiple components in bower.json after updating with --save-dev flag', function () { + it('updates multiple components in bower.json after updating with --save-dev flag', function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -533,18 +535,19 @@ describe('bower update', function () { expect(tempDir.readJson('bower.json').devDependencies.package2).to.equal(gitPackage2.path + '#~2.0.0'); expect(tempDir.readJson('bower.json').devDependencies.package3).to.equal(gitPackage3.path + '#~3.0.0'); - return update(null, {saveDev: true}).then(function() { + return update(null, { + saveDev: true + }).then(function() { // Normal deps should not have changed expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.0'); // Dev deps should have changed expect(tempDir.readJson('bower.json').devDependencies.package2).to.equal(gitPackage2.path + '#~2.0.1'); expect(tempDir.readJson('bower.json').devDependencies.package3).to.equal(gitPackage3.path + '#~3.0.1'); }); - }); }); - it('correctly interprets semver range specifier pre-1.0', function () { + it('correctly interprets semver range specifier pre-1.0', function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -558,14 +561,15 @@ describe('bower update', function () { expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#^0.1.0'); - return update(null, {save: true}).then(function() { + return update(null, { + save: true + }).then(function() { expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~0.1.1'); }); - }); }); - it('correctly interprets semver range specifier post-1.0', function () { + it('correctly interprets semver range specifier post-1.0', function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -579,14 +583,15 @@ describe('bower update', function () { expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#^1.0.0'); - return update(null, {save: true}).then(function() { + return update(null, { + save: true + }).then(function() { expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.1'); }); - }); }); - it('doesn\'t update bower.json if versions are identical', function () { + it('doesn\'t update bower.json if versions are identical', function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -600,14 +605,15 @@ describe('bower update', function () { expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#1.0.0'); - return update(null, {save: true}).then(function() { + return update(null, { + save: true + }).then(function() { expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#1.0.0'); }); - }); }); - it('does not install ignored dependencies when updating a package', function () { + it('does not install ignored dependencies when updating a package', function() { var package3 = new helpers.TempDir({ 'bower.json': { name: 'package3' @@ -671,7 +677,7 @@ describe('bower update', function () { }); }); - it('runs preinstall hook when updating a package', function () { + it('runs preinstall hook when updating a package', function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -703,7 +709,7 @@ describe('bower update', function () { }); }); - it('runs postinstall hook when updating a package', function () { + it('runs postinstall hook when updating a package', function() { tempDir.prepare({ 'bower.json': { name: 'test', From 5a1e5eb9c717b4210d6a4af77eca1951bdd9f288 Mon Sep 17 00:00:00 2001 From: Edward Peters Date: Mon, 30 Nov 2015 17:40:06 -0500 Subject: [PATCH 0773/1021] Make 'bower search' show the help display when a user does not enter a search term. Keep current behavior when running with config.json enabled, or in non-interactive mode. Rewrite bower search tests to cover the different cases of using the command without a query parameter (interactive w/o config.json, interactive w/ config.json, and non-interactive) --- lib/commands/index.js | 26 +++++++++++++++++--- lib/commands/search.js | 24 ++++++++++++------ lib/util/cli.js | 16 ++++++++++++ test/commands/search.js | 54 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 108 insertions(+), 12 deletions(-) diff --git a/lib/commands/index.js b/lib/commands/index.js index 9511c9203..90761ebe5 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -1,6 +1,7 @@ var Q = require('q'); var Logger = require('bower-logger'); var config = require('../config'); +var cli = require('../util/cli'); /** * Require commands only when called. @@ -24,12 +25,31 @@ function commandFactory(id) { } function runFromArgv(argv) { + var commandArgs; + var errorForLogger; + var command = require(id); + + try { + commandArgs = command.readOptions(argv); + } + catch (e) { + if (e.code === cli.READ_OPTIONS_ERROR_CODE) { + return null; + } + else { + // Delay raising the error until the logger is set up so the + // logger can handle it. + errorForLogger = e; + } + } + return withLogger(function (logger) { - var command = require(id); + // Raise any non-read-options error so the logger can handle it. + if (errorForLogger) { + throw errorForLogger; + } - var commandArgs = command.readOptions(argv); commandArgs.unshift(logger); - return command.apply(undefined, commandArgs); }); } diff --git a/lib/commands/search.js b/lib/commands/search.js index 58e04c6bb..a6bcc4c7d 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -2,6 +2,8 @@ var Q = require('q'); var RegistryClient = require('bower-registry-client'); var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); +var bowerConfig = require('../../lib').config; +var cli = require('../util/cli'); function search(logger, name, config) { var registryClient; @@ -14,21 +16,29 @@ function search(logger, name, config) { tracker = new Tracker(config); tracker.track('search', name); - // If no name was specified, list all packages - if (!name) { - return Q.nfcall(registryClient.list.bind(registryClient)); - // Otherwise search it - } else { + // Search if the user has given a name query + if (name) { return Q.nfcall(registryClient.search.bind(registryClient), name); } + // List all packages when in interactive mode + json enabled, and + // always when in non-interactive mode + else if (bowerConfig.json || !config.interactive) { + return Q.nfcall(registryClient.list.bind(registryClient)); + } } // ------------------- search.readOptions = function (argv) { - var cli = require('../util/cli'); var options = cli.readOptions(argv); - var name = options.argv.remain.slice(1).join(' '); + var terms = options.argv.remain.slice(1); + + // When searching from the CLI, we expect at least one search term. + if (terms.length <= 0) { + throw cli.createReadOptionsError('search'); + } + + var name = terms.join(' '); return [name]; }; diff --git a/lib/util/cli.js b/lib/util/cli.js index a537c75c7..e9a68ca4a 100644 --- a/lib/util/cli.js +++ b/lib/util/cli.js @@ -1,6 +1,9 @@ var mout = require('mout'); var nopt = require('nopt'); var renderers = require('../renderers'); +var createError = require('./createError'); + +var READ_OPTIONS_ERROR_CODE = 'EREADOPTIONS'; function readOptions(options, argv) { var types; @@ -37,6 +40,16 @@ function readOptions(options, argv) { return parsedOptions; } +/** + * Creates an error for the case where a command has trouble parsing command + * line options. + **/ +function createReadOptionsError(commandName) { + var errorString = commandName + ' syntax error'; + + return createError(errorString, READ_OPTIONS_ERROR_CODE); +} + function getRenderer(command, json, config) { if (config.json || json) { return new renderers.Json(command, config); @@ -47,3 +60,6 @@ function getRenderer(command, json, config) { module.exports.readOptions = readOptions; module.exports.getRenderer = getRenderer; + +module.exports.createReadOptionsError = createReadOptionsError; +module.exports.READ_OPTIONS_ERROR_CODE = READ_OPTIONS_ERROR_CODE; diff --git a/test/commands/search.js b/test/commands/search.js index 6a903b876..347d2657d 100644 --- a/test/commands/search.js +++ b/test/commands/search.js @@ -27,7 +27,29 @@ describe('bower search', function () { }); }); - it('lists all repositories if no query given', function () { + it('lists all repositories when no query given in non-interactive mode', function () { + var nonInteractiveConfig = { interactive: false }; + + return Q.Promise(function(resolve) { + var search = helpers.command('search', { + 'bower-registry-client': function() { + return { + list: resolve + }; + } + }); + + helpers.run(search, [null, nonInteractiveConfig]); + }); + }); + + it('lists all repositories when no query given and config.json is enabled in interactive mode', function () { + // Set the json config globally as if it were entered on the command line + var bowerConfig = require('../../lib').config; + bowerConfig.json = true; + + var interactiveConfig = { interactive: true }; + return Q.Promise(function(resolve) { var search = helpers.command('search', { 'bower-registry-client': function() { @@ -37,8 +59,36 @@ describe('bower search', function () { } }); - helpers.run(search, [], {}); + helpers.run(search, [null, interactiveConfig]); + }).then(function() { + // Reset the global json config value + bowerConfig.json = false; }); }); + it('does not list any repositories in interactive mode if no query given and config.json is disabled', function (done) { + var interactiveConfig = { interactive: true }; + return Q.Promise(function(resolve, reject) { + var search = helpers.command('search', { + 'bower-registry-client': function() { + return { + list: reject + }; + } + }); + + helpers.run(search, [null, interactiveConfig]).then(function(loggerEndData) { + var commandResult = loggerEndData[0]; + resolve(commandResult); + }); + }) + .then(function(commandResult) { + // No work should have been done, so no value should be returned. + expect(commandResult).to.be(undefined); + }) + .catch(function() { + expect().fail('should not list repositories'); + }) + .done(done); + }); }); From e9657668a9c1d530f3a0f9aca43d2c5339cdcabc Mon Sep 17 00:00:00 2001 From: Mithun Ayachit Date: Mon, 30 Nov 2015 06:40:44 -0600 Subject: [PATCH 0774/1021] Allow the use of environment variables in .bowerrc Similar to npmrc Expand '~/' to user's home directory --- packages/bower-config/lib/util/expand.js | 47 +++++++++++++++++++ packages/bower-config/package.json | 3 +- .../test/assets/env-variables-values/.bowerrc | 7 +++ packages/bower-config/test/test.js | 21 +++++++++ 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 packages/bower-config/test/assets/env-variables-values/.bowerrc diff --git a/packages/bower-config/lib/util/expand.js b/packages/bower-config/lib/util/expand.js index d1b356c29..929b4b10c 100644 --- a/packages/bower-config/lib/util/expand.js +++ b/packages/bower-config/lib/util/expand.js @@ -19,8 +19,55 @@ function camelCase(config) { return camelCased; } +// Function to replace ${VAR} - style variables +// with values set in the environment +// This function expects to be passed a string +function doEnvReplaceStr (f) { + + // Un-tildify + var untildify = require('untildify'); + f = untildify(f); + + // replace any ${ENV} values with the appropriate environ. + var envExpr = /(\\*)\$\{([^}]+)\}/g; + return f.replace(envExpr, function (orig, esc, name) { + esc = esc.length && esc.length % 2; + if (esc) return orig; + if (undefined === process.env[name]) { + throw new Error('Environment variable used in .bowerrc is not defined: ' + orig); + } + + return process.env[name]; +}); +} + +function envReplace(config) { + var envReplaced = {}; + + object.forOwn(config, function (value, key) { + // Ignore null values + if (value == null) { + return; + } + + // Perform variable replacements based on var type + if ( lang.isPlainObject(value) ) { + envReplaced[key] = envReplace(value); + } + else if ( lang.isString(value) ) { + envReplaced[key] = doEnvReplaceStr(value); + } + else { + envReplaced[key] = value; + } + }); + + return envReplaced; +} + function expand(config) { config = camelCase(config); + config = envReplace(config); if (typeof config.registry === 'string') { config.registry = { diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 84ac88a10..72350ac39 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -14,7 +14,8 @@ "graceful-fs": "^4.0.0", "mout": ">=0.9.0 <1.0.0", "optimist": "^0.6.1", - "osenv": "^0.1.3" + "osenv": "^0.1.3", + "untildify": "2.1.0" }, "devDependencies": { "expect.js": "^0.3.1", diff --git a/packages/bower-config/test/assets/env-variables-values/.bowerrc b/packages/bower-config/test/assets/env-variables-values/.bowerrc new file mode 100644 index 000000000..96948d18e --- /dev/null +++ b/packages/bower-config/test/assets/env-variables-values/.bowerrc @@ -0,0 +1,7 @@ +{ + "storage" : { + "packages" : "${_BOWERRC_MY_PACKAGES}", + "registry" : "~/.bower-test/registry" + }, + "tmp" : "${_BOWERRC_MY_TMP}" +} diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index 357c31924..c66565822 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -212,7 +212,28 @@ describe('NPM Config on package.json', function () { assert.equal(process.env.HTTPS_PROXY, 'http://other-proxy.local'); }); }); +}); + +describe('Allow ${ENV} variables in .bowerrc', function() { + + it('sets values from process.env', function() { + process.env._BOWERRC_MY_PACKAGES = 'a'; + process.env._BOWERRC_MY_TMP = '/tmp/b'; + var config = require('../lib/Config').read('test/assets/env-variables-values'); + assert.equal('a', config.storage.packages); + assert.equal('/tmp/b', config.tmp); + }); +}); + +describe('untildify paths in .bowerrc', function() { + + it('resolve ~/ in .bowerrc', function() { + var config = require('../lib/Config').read('test/assets/env-variables-values'); + var untildify = require('untildify'); + + assert.equal(untildify('~/.bower-test/registry') , config.storage.registry); + }); }); require('./util/index'); From 4ffdb500b99fca464ca6f36f76279d9feea84c1a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 4 Dec 2015 21:19:19 +0100 Subject: [PATCH 0775/1021] Update to npm version of fs-write-stream-atomic --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7a00cb0af..4655feb85 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "configstore": "^0.3.2", "decompress-zip": "^0.1.0", "destroy": "^1.0.3", - "fs-write-stream-atomic": "^1.0.4", + "fs-write-stream-atomic": "^1.0.5", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", "github": "^0.2.3", From b81ba140e32c9ee8c7680edecf1bbd45472c134d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 4 Dec 2015 21:21:20 +0100 Subject: [PATCH 0776/1021] Bump to 1.6.9 and release --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6676b9f8d..51c3e2517 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.6.9 - 2015-12-04 + +- Change git version of fs-write-stream-atomic back to npm version ([#2079](https://github.com/bower/bower/issues/2079)) + ## 1.6.8 - 2015-11-27 - Use fs-write-stream-atomic for downloads diff --git a/package.json b/package.json index 4655feb85..679faba54 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.8", + "version": "1.6.9", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From b94c20b8da736e4088d5ddd7660de357262e9e2f Mon Sep 17 00:00:00 2001 From: Manas Date: Sat, 5 Dec 2015 22:28:18 +0530 Subject: [PATCH 0777/1021] Release 1.7.0 --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51c3e2517..56be1d370 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 1.7.0 - 2015-12-05 +- Bower search shows a help display when no package name is specified. Fixes [#2066](https://github.com/bower/bower/issues/2066) +- Updates only those packages that are explicitly requested by the user + Related Issues + - [#256](https://github.com/bower/bower/issues/256) + - [#924](https://github.com/bower/bower/issues/924) + - [#1770](https://github.com/bower/bower/issues/1770) +- Adds `bower --save` functionality ([#2035](https://github.com/bower/bower/issues/2035)) +- Allow for @ in username for SVN on windows ([#1650](https://github.com/bower/bower/issues/1650)) +- Update bower config + - Loads the .bowerrc file from the cwd specified on the command line + - Allow the use of environment variables in .bowerrc. Issue [#41](https://github.com/bower/config/issues/41) + ## 1.6.9 - 2015-12-04 - Change git version of fs-write-stream-atomic back to npm version ([#2079](https://github.com/bower/bower/issues/2079)) From 5a2272cab11ef43103b2fdebf2bc3542e7d74688 Mon Sep 17 00:00:00 2001 From: Manas Date: Sat, 5 Dec 2015 20:31:06 +0530 Subject: [PATCH 0778/1021] Adds CHANGELOG.md --- packages/bower-config/CHANGELOG.md | 92 ++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 packages/bower-config/CHANGELOG.md diff --git a/packages/bower-config/CHANGELOG.md b/packages/bower-config/CHANGELOG.md new file mode 100644 index 000000000..3a25e689e --- /dev/null +++ b/packages/bower-config/CHANGELOG.md @@ -0,0 +1,92 @@ +# Changelog + +## 1.2.4 - 2015-12-05 +- Allow the use of environment variables in .bowerrc. Fixes [#41](https://github.com/bower/config/issues/41) +- Loads the .bowerrc file from the cwd specified on the command line. Fixes [bower/bower#1993](https://github.com/bower/bower/issues/1993) + +## 1.2.3 - 2015-11-27 +- Restores env variables if they are undefined at the beginning +- Handles default setting for config.ca. Together with [bower/bower PR #1972](https://github.com/bower/bower/pull/1972), fixes downloading with `strict-ssl` using custom CA +- Displays an error message if .bowerrc is a directory instead of file. Fixes [bower/bower#2022](https://github.com/bower/bower/issues/2022) + +## 1.2.2 - 2015-10-16 +- Fixes registry configurartion expanding [bower/bower#1950](https://github.com/bower/bower/issues/1950) + +## 1.2.1 - 2015-10-15 +- Fixes case insenstivity HTTP_PROXY setting issue on Windows + +## 1.2.0 - 2015-09-28 +- Prevent defaulting cwd to process.cwd() + +## 1.1.2 - 2015-09-27 +- Performs only camel case normalisation before merging + +## 1.1.1 - 2015-09-27 +- Fix: Merge extra options after camel-case normalisation, instead of before it + +## 1.1.0 - 2015-09-27 +- Allow for overwriting options with .load(overwrites) / .read(cwd, overwrites) + +## 1.0.1 - 2015-09-27 +- Update dependencies and relax "mout" version range +- Most significant changes: + - graceful-fs updated from 2.x version to 4.x + - osenv updated to from 0.0.x to 0.1.x, [tmp location changed](https://github.com/npm/osenv/commit/d6eddbc026538b09026b1dbd60fbc081a8c67e03) + +## 1.0.0 - 2015-09-27 +- Support for no-proxy configuration variable +- Overwrite HTTP_PROXY, HTTPS_PROXY, and NO_PROXY env variables in load method +- Normalise paths to certificates with contents of them, [#28](https://github.com/bower/config/pull/28) + +## 0.6.1 - 2015-04-1 +- Fixes merging .bowerrc files upward directory tree. [#25](https://github.com/bower/config/issues/25) + +## 0.6.0 - 2015-03-30 +- Merge .bowerrc files upward directory tree (fixes [bower/bower#1689](https://github.com/bower/bower/issues/1689)) [#24](https://github.com/bower/config/pull/24) +- Allow NPM config variables (resolves [bower/bower#1711](https://github.com/bower/bower/issues/1711)) [#23](https://github.com/bower/config/pull/23) + +## 0.5.2 - 2014-06-09 +- Fixes downloading of bower modules with ignores when .bowerrc is overridden with a relative tmp path. [#17](https://github.com/bower/config/issues/17) [bower/bower#1299](https://github.com/bower/bower/issues/1299) + +## 0.5.1 - 2014-05-21 +- [perf] Uses the same mout version as bower +- [perf] Uses only relevant parts of mout. Related [bower/bower#1134](https://github.com/bower/bower/pull/1134) + +## 0.5.0 - 2013-08-30 +- Adds a DEFAULT_REGISTRY key to the Config class that exposes the bower registry UR. [#6](https://github.com/bower/config/issues/6) + +## 0.4.5 - 2013-08-28 +- Fixes crashing when home is not set + +## 0.4.4 - 2013-08-21 +- Supports nested environment variables [#8](https://github.com/bower/config/issues/8) + +## 0.4.3 - 2013-08-19 +- Improvement in argv.config parsing + +## 0.4.2 - 2013-08-18 +- Sets interative to auto + +## 0.4.1 - 2013-08-18 +- Generates a fake user instead of using 'unknown' + +## 0.4.0 - 2013-08-16 +- Suffixes temp folder with the user and 'bower' + +## 0.3.5 - 2013-08-14 +- Casts buffer to string + +## 0.3.4 - 2013-08-11 +- Empty .bowerrc files no longer throw an error. + +## 0.3.3 - 2013-08-11 +- Changes git folder to empty (was not being used anyway) + +## 0.3.2 - 2013-08-07 +- Uses a known user agent by default when a proxy. + +## 0.3.1 - 2013-08-06 +- Fixes Typo + +## 0.3.0 - 2013-08-06 +- Appends the username when using the temporary folder. From 20a223a959977ef9831386ec8ef28ea3b7c243b8 Mon Sep 17 00:00:00 2001 From: Rob Simpson Date: Sun, 6 Dec 2015 06:10:13 -0500 Subject: [PATCH 0779/1021] adding eslintrc for new ruleset option --- .eslintrc | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .eslintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000..9f79d1133 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,45 @@ +env: + node: true + +# enable ECMAScript features +ecmaFeatures: + arrowFunctions: true + binaryLiterals: true + blockBindings: true + classes: true + forOf: true + generators: true + objectLiteralShorthandMethods: true + objectLiteralShorthandProperties: true + octalLiterals: true + templateStrings: true + +rules: + no-debugger: 2 + no-dupe-args: 2 + no-dupe-keys: 2 + no-duplicate-case: 2 + no-ex-assign: 2 + no-reserved-keys: 2 + no-unreachable: 2 + valid-typeof: 2 + no-fallthrough: 2 + quotes: [2, "single", "avoid-escape"] + indent: [2, 2] + comma-spacing: 2 + semi: 2 + space-infix-ops: 2 + space-return-throw-case: 2 + space-before-function-paren: [2, "never"] + space-before-blocks: [2, "always"] + new-parens: 2 + max-len: [2, 80, 2] + no-multiple-empty-lines: [2, {max: 2}] + eol-last: 2 + no-trailing-spaces: 2 + space-after-keywords: 2 + + # ECMAScript 6 + prefer-const: 2 + strict: [2, "global"] + no-undef: 2 From 0e27b6f81392ae2e1030a8b6f009896ba06afba5 Mon Sep 17 00:00:00 2001 From: Peng Wang Date: Wed, 25 Nov 2015 14:53:00 -0600 Subject: [PATCH 0780/1021] restore spacing and code formating --- packages/bower-config/lib/util/rc.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index f2cc3d8df..a1815f353 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -116,7 +116,20 @@ function env(prefix) { .substr(prefixLength) .replace(/__/g, '.') // __ is used for nesting .replace(/_/g, '-'); // _ is used as a - separator - object.set(obj, parsedKey, value); + + //use a convention patern to accept array from process.env + //e.g. export bower_registry__search='["http://abc.com","http://def.com"]' + var match = /\[([^\]]*)\]/g.exec(value); + var targetValue; + if (!match || match.length === 0) { + targetValue = value; + } else { + targetValue = match[1].split(',') + .map(function(m) { + return m.trim().slice(1, m.length - 1); + }); + } + object.set(obj, parsedKey, targetValue); } }); From 844cc5a52784b3d9886d36140f245a70944d51ce Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 7 Dec 2015 11:30:18 +0100 Subject: [PATCH 0781/1021] Add test for accept array from process env feature --- packages/bower-config/lib/util/rc.js | 2 +- packages/bower-config/test/test.js | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index a1815f353..76afbac0d 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -126,7 +126,7 @@ function env(prefix) { } else { targetValue = match[1].split(',') .map(function(m) { - return m.trim().slice(1, m.length - 1); + return m.trim(); }); } object.set(obj, parsedKey, targetValue); diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index c66565822..c315ef601 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -5,6 +5,7 @@ describe('NPM Config on package.json', function () { beforeEach(function () { delete process.env.npm_package_config_bower_directory; delete process.env.npm_package_config_bower_colors; + delete process.env.npm_package_config_bower_resolvers; }); it('defaults registry entries to default registry', function () { @@ -102,7 +103,8 @@ describe('NPM Config on package.json', function () { describe('Setting process.env.npm_package_config', function () { process.env.npm_package_config_bower_directory = 'npm-path'; - process.env.npm_package_config_bower_colors = false; + process.env.npm_package_config_bower_colors = 'false'; + process.env.npm_package_config_bower_resolvers = '[foo,bar,baz]'; var config = require('../lib/Config').read(); @@ -112,6 +114,9 @@ describe('NPM Config on package.json', function () { it('should return "false" for "bower_colors"', function () { assert.equal('false', config.colors); }); + it('should expand array "false" for "bower_resolvers"', function () { + assert.deepEqual(['foo', 'bar', 'baz'], config.resolvers); + }); }); describe('Specifying custom CA', function() { From bd2c253f99a08e761889e51fddc56bc8a61b9a4e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 7 Dec 2015 11:43:12 +0100 Subject: [PATCH 0782/1021] Bump to 1.3.0 --- packages/bower-config/CHANGELOG.md | 4 +++- packages/bower-config/package.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/bower-config/CHANGELOG.md b/packages/bower-config/CHANGELOG.md index 3a25e689e..0a5b0f7cf 100644 --- a/packages/bower-config/CHANGELOG.md +++ b/packages/bower-config/CHANGELOG.md @@ -1,10 +1,12 @@ # Changelog -## 1.2.4 - 2015-12-05 +## 1.3.0 - 2015-12-07 + - Allow the use of environment variables in .bowerrc. Fixes [#41](https://github.com/bower/config/issues/41) - Loads the .bowerrc file from the cwd specified on the command line. Fixes [bower/bower#1993](https://github.com/bower/bower/issues/1993) ## 1.2.3 - 2015-11-27 + - Restores env variables if they are undefined at the beginning - Handles default setting for config.ca. Together with [bower/bower PR #1972](https://github.com/bower/bower/pull/1972), fixes downloading with `strict-ssl` using custom CA - Displays an error message if .bowerrc is a directory instead of file. Fixes [bower/bower#2022](https://github.com/bower/bower/issues/2022) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 72350ac39..61a332994 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "1.2.2", + "version": "1.3.0", "description": "The Bower config reader and writer.", "author": "Twitter", "license": "MIT", From 7bc97a1241ef4bff3417b61ed10986d03bd09d53 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 7 Dec 2015 11:45:24 +0100 Subject: [PATCH 0783/1021] Add changelog entry for array notation in env --- packages/bower-config/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/bower-config/CHANGELOG.md b/packages/bower-config/CHANGELOG.md index 0a5b0f7cf..9da87a95a 100644 --- a/packages/bower-config/CHANGELOG.md +++ b/packages/bower-config/CHANGELOG.md @@ -4,6 +4,7 @@ - Allow the use of environment variables in .bowerrc. Fixes [#41](https://github.com/bower/config/issues/41) - Loads the .bowerrc file from the cwd specified on the command line. Fixes [bower/bower#1993](https://github.com/bower/bower/issues/1993) +- Allwow for array notation in ENV variables [#44](https://github.com/bower/config/issues/44) ## 1.2.3 - 2015-11-27 From 9605bbea5f6f77e680f6b60ba1a066dff72ccaad Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 7 Dec 2015 13:08:58 +0100 Subject: [PATCH 0784/1021] Bump bower-config to 1.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 679faba54..332bbceed 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dependencies": { "abbrev": "^1.0.5", "archy": "1.0.0", - "bower-config": "^1.2.3", + "bower-config": "^1.3.0", "bower-endpoint-parser": "^0.2.2", "bower-json": "^0.4.0", "bower-logger": "^0.2.2", From 338ac99080d464cbc7c2c27cddae31207da6e527 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 7 Dec 2015 13:34:01 +0100 Subject: [PATCH 0785/1021] Bump to 1.7.0 --- CHANGELOG.md | 13 +++++++------ package.json | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56be1d370..d5d1c9e23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,18 @@ # Changelog -## 1.7.0 - 2015-12-05 -- Bower search shows a help display when no package name is specified. Fixes [#2066](https://github.com/bower/bower/issues/2066) -- Updates only those packages that are explicitly requested by the user - Related Issues +## 1.7.0 - 2015-12-07 + +- Add `bower update --save` functionality ([#2035](https://github.com/bower/bower/issues/2035)) +- `bower search` shows help message when no package name is specified ([#2066](https://github.com/bower/bower/issues/2066)) +- Update only those packages that are explicitly requested by the user. Related Issues - [#256](https://github.com/bower/bower/issues/256) - [#924](https://github.com/bower/bower/issues/924) - [#1770](https://github.com/bower/bower/issues/1770) -- Adds `bower --save` functionality ([#2035](https://github.com/bower/bower/issues/2035)) - Allow for @ in username for SVN on windows ([#1650](https://github.com/bower/bower/issues/1650)) - Update bower config - Loads the .bowerrc file from the cwd specified on the command line - - Allow the use of environment variables in .bowerrc. Issue [#41](https://github.com/bower/config/issues/41) + - Allow the use of environment variables in .bowerrc ([#41](https://github.com/bower/config/issues/41)) + - Allow for array notation in ENV variables ([#44](https://github.com/bower/config/issues/44)) ## 1.6.9 - 2015-12-04 diff --git a/package.json b/package.json index 332bbceed..76cf86e6d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.6.9", + "version": "1.7.0", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 612aaa88eb4d4b268b2d8665c338ac086af3a5b0 Mon Sep 17 00:00:00 2001 From: David DeSandro Date: Mon, 7 Dec 2015 08:42:17 -0500 Subject: [PATCH 0786/1021] add help menu for update --save, update --save-dev Ref #2035 --- templates/json/help-update.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/templates/json/help-update.json b/templates/json/help-update.json index 2d9825566..fdcb7fcd3 100644 --- a/templates/json/help-update.json +++ b/templates/json/help-update.json @@ -19,6 +19,16 @@ "shorthand": "-p", "flag": "--production", "description": "Do not install project devDependencies" + }, + { + "shorthand": "-S", + "flag": "--save", + "description": "Update dependencies in bower.json" + }, + { + "shorthand": "-D", + "flag": "--save-dev", + "description": "Update devDependencies in bower.json" } ] } From accdab3ece334b8f8f511e9bbe7b0240ca7a60c1 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 7 Dec 2015 16:34:26 +0100 Subject: [PATCH 0787/1021] Link bug reports to wiki --- CONTRIBUTING.md | 41 +---------------------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 57a9168c2..8b4fbfe83 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,46 +36,7 @@ requests](#pull-requests), but please respect the following restrictions: respect the opinions of others. -## Bug reports - -A bug is a _demonstrable problem_ that is caused by the code in the repository. -Good bug reports are extremely helpful - thank you! - -Guidelines for bug reports: - -1. **Use the GitHub issue search** — check if the issue has already been - reported. - -2. **Check if the issue has been fixed** — try to reproduce it using the - latest `master` or development branch in the repository. - -3. **Isolate the problem** — ideally create a [reduced test - case](http://css-tricks.com/6263-reduced-test-cases/). - -A good bug report shouldn't leave others needing to chase you up for more -information. Please try to be as detailed as possible in your report. What is -your environment? What steps will reproduce the issue? What OS experiences the -problem? What would you expect to be the outcome? All these details will help -people to fix any potential bugs. - -Example: - -> Short and descriptive example bug report title -> -> A summary of the issue and the browser/OS environment in which it occurs. If -> suitable, include the steps required to reproduce the bug. -> -> 1. This is the first step -> 2. This is the second step -> 3. Further steps, etc. -> -> `` - a link to the reduced test case -> -> Any other information you want to share that is relevant to the issue being -> reported. This might include the lines of code that you have identified as -> causing the bug, and potential solutions (and your opinions on their -> merits). - +## 🐛 [Bug reports](https://github.com/bower/bower/wiki/Report-a-Bug) ## Feature requests From 7897ad7dba772bef03fad96c36da9b8e54d840b4 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 7 Dec 2015 16:35:19 +0100 Subject: [PATCH 0788/1021] Move bug reports to the top --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8b4fbfe83..609514160 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,6 +2,9 @@ Bower is a large community project with many different developers contributing at all levels to the project. We're **actively** looking for more contributors right now. If you're interested in becoming Bower maintainer or supporting in in any way, please full the following form: http://goo.gl/forms/P1ndzCNoiG. There is more information about [contributing](https://github.com/bower/bower/wiki/Contributor-Guidelines) in the Wiki. + +## 🐛 [Bug reports](https://github.com/bower/bower/wiki/Report-a-Bug) + ## Casual Involvement * Improve the bower.io site ([tickets](https://github.com/bower/bower.github.io/issues)) @@ -35,9 +38,6 @@ requests](#pull-requests), but please respect the following restrictions: * Please **do not** derail or troll issues. Keep the discussion on topic and respect the opinions of others. - -## 🐛 [Bug reports](https://github.com/bower/bower/wiki/Report-a-Bug) - ## Feature requests From de3e1089da80f47ea3667c5ab80d301cddfd8c3e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 7 Dec 2015 20:32:25 +0100 Subject: [PATCH 0789/1021] Better formatting of help message --- templates/json/help-search.json | 1 - templates/std/help-generic.std | 1 + test/renderers/StandardRenderer.js | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/json/help-search.json b/templates/json/help-search.json index 7298b8287..11059ffe0 100644 --- a/templates/json/help-search.json +++ b/templates/json/help-search.json @@ -2,7 +2,6 @@ "command": "search", "description": "Finds all packages or a specific package.", "usage": [ - "search []", "search []" ], "options": [ diff --git a/templates/std/help-generic.std b/templates/std/help-generic.std index b573a97ec..dd772e5de 100644 --- a/templates/std/help-generic.std +++ b/templates/std/help-generic.std @@ -7,6 +7,7 @@ Usage: {{/each}} {{/condense}} + Options: {{#condense}} diff --git a/test/renderers/StandardRenderer.js b/test/renderers/StandardRenderer.js index 3cd25fed8..1d5422830 100644 --- a/test/renderers/StandardRenderer.js +++ b/test/renderers/StandardRenderer.js @@ -784,6 +784,7 @@ describe('StandardRenderer', function () { Usage: bower uninstall [ ..] [] + Options: -h, --help Show this help message From 977e0ddc52fd33ebe478f9ee48152a54e6b6cc8a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 7 Dec 2015 20:34:47 +0100 Subject: [PATCH 0790/1021] Update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5d1c9e23..2e8f71694 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.8.0 + +- Better formatting of help messages https://github.com/bower/bower/commit/de3e1089da80f47ea3667c5ab80d301cddfd8c3e +- Add help menu for update --save and update --save-dev https://github.com/bower/bower/commit/612aaa88eb4d4b268b2d8665c338ac086af3a5b0 + ## 1.7.0 - 2015-12-07 - Add `bower update --save` functionality ([#2035](https://github.com/bower/bower/issues/2035)) From 3030469c595e0822cc9a8e7c2fce189d95d8d718 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 8 Dec 2015 11:00:51 +0100 Subject: [PATCH 0791/1021] Update update-notifier to 0.6.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 76cf86e6d..8622d4f8a 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", "tmp": "0.0.24", - "update-notifier": "^0.3.0", + "update-notifier": "^0.6.0", "user-home": "^1.1.0", "which": "^1.0.8" }, From d50e50f3b553a38936f87a4f0876d53285ff7c91 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 8 Dec 2015 11:14:33 +0100 Subject: [PATCH 0792/1021] Add discord chat link, closes #2088 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 763aca770..a401d4533 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)](https://ci.appveyor.com/project/sheerun/bower/history) [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) -[![Join the chat at https://gitter.im/bower/bower](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/bower/bower?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Discord chat](https://img.shields.io/badge/discord-join%20chat%20%E2%86%92-brightgreen.svg?style=flat)](https://discord.gg/0fFM7QF0KpZRh2cY) [![Issue Stats](http://issuestats.com/github/bower/bower/badge/pr?style=flat)](http://issuestats.com/github/bower/bower) [![Issue Stats](http://issuestats.com/github/bower/bower/badge/issue?style=flat)](http://issuestats.com/github/bower/bower) From 027a0694f7a23193c4d8e34a3ff9ca355e9b05cb Mon Sep 17 00:00:00 2001 From: Paulo Pires Date: Tue, 8 Dec 2015 04:16:44 -0800 Subject: [PATCH 0793/1021] Added coverage --- packages/bower-json/.gitignore | 4 +++- packages/bower-json/.travis.yml | 6 +++++- packages/bower-json/Gruntfile.js | 23 +++++++++++++++-------- packages/bower-json/package.json | 5 +++++ 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/packages/bower-json/.gitignore b/packages/bower-json/.gitignore index 1b6c50d99..61c242c46 100644 --- a/packages/bower-json/.gitignore +++ b/packages/bower-json/.gitignore @@ -1,2 +1,4 @@ /node_modules -/npm-debug.* \ No newline at end of file +/npm-debug.* + +/test/reports diff --git a/packages/bower-json/.travis.yml b/packages/bower-json/.travis.yml index dedfc07f2..aba44319d 100644 --- a/packages/bower-json/.travis.yml +++ b/packages/bower-json/.travis.yml @@ -1,6 +1,10 @@ sudo: false language: node_js node_js: - - 'iojs' + - '5' + - '4' - '0.12' - '0.10' + +script: + - grunt travis diff --git a/packages/bower-json/Gruntfile.js b/packages/bower-json/Gruntfile.js index 7f8e1f52f..2d34d078b 100644 --- a/packages/bower-json/Gruntfile.js +++ b/packages/bower-json/Gruntfile.js @@ -1,11 +1,7 @@ -module.exports = function (grunt) { - - 'use strict'; - - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-simple-mocha'); +'use strict'; +module.exports = function (grunt) { + require('load-grunt-tasks')(grunt); // Project configuration. grunt.initConfig({ @@ -13,7 +9,8 @@ module.exports = function (grunt) { files: [ 'Gruntfile.js', 'lib/**/*.js', - 'test/**/*.js' + 'test/**/*.js', + '!test/reports/**/*' ], options: { jshintrc: '.jshintrc' @@ -39,6 +36,15 @@ module.exports = function (grunt) { } }, + exec: { + cover: { + command: 'STRICT_REQUIRE=1 node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' + }, + coveralls: { + command: 'node node_modules/.bin/coveralls < test/reports/lcov.info' + } + }, + watch: { files: ['<%= jshint.files %>'], @@ -50,4 +56,5 @@ module.exports = function (grunt) { // Default task. grunt.registerTask('test', ['simplemocha:full']); grunt.registerTask('default', ['jshint', 'test']); + grunt.registerTask('travis', ['jshint', 'exec:cover', 'exec:coveralls']); }; diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 261ff2244..86d50f7eb 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -16,12 +16,17 @@ "intersect": "^1.0.1" }, "devDependencies": { + "coveralls": "^2.11.2", "expect.js": "^0.3.1", "grunt": "^0.4.4", "grunt-cli": "^0.1.13", "grunt-contrib-jshint": "^0.11.2", "grunt-contrib-watch": "^0.6.1", + "grunt-coveralls": "^1.0.0", + "grunt-exec": "^0.4.6", "grunt-simple-mocha": "^0.4.0", + "istanbul": "^0.3.5", + "load-grunt-tasks": "^3.3.0", "mocha": "*", "underscore.string": "^3.0.3" }, From ac244a14006e34b258f9cba498f5216e325aef08 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 8 Dec 2015 14:21:05 +0100 Subject: [PATCH 0794/1021] Run coverage on appveyor as well --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index a4cb95397..d8ac602b0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -33,7 +33,7 @@ install: # Post-install test scripts. test_script: - - cmd: npm test + - cmd: grunt travis # Don't actually build. build: off From 1605374a25b484fceff3e180192c818246b60052 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 8 Dec 2015 14:32:05 +0100 Subject: [PATCH 0795/1021] Properly run code coverage on appveyor --- appveyor.yml | 2 +- package.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index d8ac602b0..440de4bc9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -33,7 +33,7 @@ install: # Post-install test scripts. test_script: - - cmd: grunt travis + - cmd: npm run ci # Don't actually build. build: off diff --git a/package.json b/package.json index 8622d4f8a..52ebd464c 100644 --- a/package.json +++ b/package.json @@ -130,7 +130,8 @@ "which" ], "scripts": { - "test": "grunt test" + "test": "grunt test", + "ci": "grunt travis" }, "bin": "bin/bower", "files": [ From 376a2de60024ee118b4025ffa35f101615aa5096 Mon Sep 17 00:00:00 2001 From: Paulo Pires Date: Mon, 7 Dec 2015 12:19:15 -0800 Subject: [PATCH 0796/1021] added synchronous functions to read and find added .readSync function Added coverage --- packages/bower-json/.gitignore | 4 +- packages/bower-json/.travis.yml | 6 +- packages/bower-json/Gruntfile.js | 23 +++++--- packages/bower-json/lib/json.js | 69 ++++++++++++++++++++++- packages/bower-json/package.json | 5 ++ packages/bower-json/test/test.js | 94 ++++++++++++++++++++++++++++++++ 6 files changed, 190 insertions(+), 11 deletions(-) diff --git a/packages/bower-json/.gitignore b/packages/bower-json/.gitignore index 1b6c50d99..61c242c46 100644 --- a/packages/bower-json/.gitignore +++ b/packages/bower-json/.gitignore @@ -1,2 +1,4 @@ /node_modules -/npm-debug.* \ No newline at end of file +/npm-debug.* + +/test/reports diff --git a/packages/bower-json/.travis.yml b/packages/bower-json/.travis.yml index dedfc07f2..aba44319d 100644 --- a/packages/bower-json/.travis.yml +++ b/packages/bower-json/.travis.yml @@ -1,6 +1,10 @@ sudo: false language: node_js node_js: - - 'iojs' + - '5' + - '4' - '0.12' - '0.10' + +script: + - grunt travis diff --git a/packages/bower-json/Gruntfile.js b/packages/bower-json/Gruntfile.js index 7f8e1f52f..2d34d078b 100644 --- a/packages/bower-json/Gruntfile.js +++ b/packages/bower-json/Gruntfile.js @@ -1,11 +1,7 @@ -module.exports = function (grunt) { - - 'use strict'; - - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-simple-mocha'); +'use strict'; +module.exports = function (grunt) { + require('load-grunt-tasks')(grunt); // Project configuration. grunt.initConfig({ @@ -13,7 +9,8 @@ module.exports = function (grunt) { files: [ 'Gruntfile.js', 'lib/**/*.js', - 'test/**/*.js' + 'test/**/*.js', + '!test/reports/**/*' ], options: { jshintrc: '.jshintrc' @@ -39,6 +36,15 @@ module.exports = function (grunt) { } }, + exec: { + cover: { + command: 'STRICT_REQUIRE=1 node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' + }, + coveralls: { + command: 'node node_modules/.bin/coveralls < test/reports/lcov.info' + } + }, + watch: { files: ['<%= jshint.files %>'], @@ -50,4 +56,5 @@ module.exports = function (grunt) { // Default task. grunt.registerTask('test', ['simplemocha:full']); grunt.registerTask('default', ['jshint', 'test']); + grunt.registerTask('travis', ['jshint', 'exec:cover', 'exec:coveralls']); }; diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index aa3949138..3f8fe8eb5 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -59,6 +59,45 @@ function read(file, options, callback) { }); } +function readSync(file, options) { + var stat; + var filename; + var contents; + var json; + + if (!options) { + options = {}; + } + try { + stat = fs.statSync(file); + } catch (err) { + return err; + } + if (stat.isDirectory()) { + filename = findSync(file); + return readSync(filename); + } + + contents = fs.readFileSync(file); + + try { + json = JSON.parse(contents.toString()); + } catch (err) { + err.file = path.resolve(file); + err.code = 'EMALFORMED'; + return err; + } + + try { + json = parse(json, options); + } catch (err) { + err.file = path.resolve(file); + return err; + } + + return json; +} + function parse(json, options) { options = deepExtend({ normalize: false, @@ -104,7 +143,7 @@ function validate(json) { if (!/[a-z]$/.test(json.name)) { throw createError('The name has to end with a lower case character from a to z', 'EINVALID'); } - + if (json.description && json.description.length > 140) { throw createError('The description is too long. 140 characters should be more than enough', 'EINVALID'); } @@ -199,9 +238,37 @@ function find(folder, files, callback) { }); } +function findSync(folder, files) { + var file; + var exists; + + if (files === undefined) { + files = possibleJsons; + } + + if (!files.length) { + return createError('None of ' + possibleJsons.join(', ') + ' were found in ' + folder, 'ENOENT'); + } + + file = path.resolve(path.join(folder, files[0])); + try{ + exists = fs.statSync(file); + } + catch (err) { + exists = false; + } + if (exists && exists.isFile()) { + return file; + } else { + return findSync(folder, files.slice(1)); + } +} + module.exports = read; module.exports.read = read; +module.exports.readSync = readSync; module.exports.parse = parse; module.exports.validate = validate; module.exports.normalize = normalize; module.exports.find = find; +module.exports.findSync = findSync; diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 261ff2244..86d50f7eb 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -16,12 +16,17 @@ "intersect": "^1.0.1" }, "devDependencies": { + "coveralls": "^2.11.2", "expect.js": "^0.3.1", "grunt": "^0.4.4", "grunt-cli": "^0.1.13", "grunt-contrib-jshint": "^0.11.2", "grunt-contrib-watch": "^0.6.1", + "grunt-coveralls": "^1.0.0", + "grunt-exec": "^0.4.6", "grunt-simple-mocha": "^0.4.0", + "istanbul": "^0.3.5", + "load-grunt-tasks": "^3.3.0", "mocha": "*", "underscore.string": "^3.0.3" }, diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index becdb4218..b0f1628fd 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -56,6 +56,41 @@ describe('.find', function () { }); }); +describe('.findSync', function () { + + it('should find the bower.json file', function (done) { + var file = bowerJson.findSync(__dirname + '/pkg-bower-json'); + + expect(file).to.equal(path.resolve(__dirname + '/pkg-bower-json/bower.json')); + done(); + }); + + it('should fallback to the component.json file', function (done) { + var file = bowerJson.findSync(__dirname + '/pkg-component-json'); + + expect(file).to.equal(path.resolve(__dirname + '/pkg-component-json/component.json')); + done(); + }); + + it('should fallback to the .bower.json file', function (done) { + var file = bowerJson.findSync(__dirname + '/pkg-dot-bower-json'); + + expect(file).to.equal(path.resolve(__dirname + '/pkg-dot-bower-json/.bower.json')); + done(); + }); + + it('should error if no component.json / bower.json / .bower.json is found', function (done) { + var err = bowerJson.findSync(__dirname); + expect(err).to.be.an(Error); + expect(err.code).to.equal('ENOENT'); + expect(err.message).to.equal('None of bower.json, component.json, .bower.json were found in ' + __dirname); + done(); + }); + + + +}); + describe('.read', function () { it('should give error if file does not exists', function (done) { bowerJson.read(__dirname + '/willneverexist', function (err) { @@ -146,6 +181,65 @@ describe('.read', function () { }); }); +describe('.readSync', function () { + it('should give error if file does not exists', function (done) { + var err = bowerJson.readSync(__dirname + '/willneverexist'); + expect(err).to.be.an(Error); + expect(err.code).to.equal('ENOENT'); + done(); + }); + + it('should give error if when reading an invalid json', function (done) { + var err = bowerJson.readSync(__dirname + '/pkg-bower-json-malformed/bower.json'); + expect(err).to.be.an(Error); + expect(err.code).to.equal('EMALFORMED'); + expect(err.file).to.equal(path.resolve(__dirname + '/pkg-bower-json-malformed/bower.json')); + done(); + }); + + it('should read the file and give an object', function (done) { + var json = bowerJson.readSync(__dirname + '/pkg-bower-json/bower.json'); + + expect(json).to.be.an('object'); + expect(json.name).to.equal('some-pkg'); + expect(json.version).to.equal('0.0.0'); + + done(); + }); + + it('should find for a json file if a directory is given', function (done) { + var json = bowerJson.readSync(__dirname + '/pkg-component-json'); + + expect(json).to.be.an('object'); + expect(json.name).to.equal('some-pkg'); + expect(json.version).to.equal('0.0.0'); + done(); + }); + + it('should validate the returned object unless validate is false', function (done) { + var err = bowerJson.readSync(__dirname + '/pkg-bower-json-invalid/bower.json'); + expect(err).to.be.an(Error); + expect(err.message).to.contain('name'); + expect(err.file).to.equal(path.resolve(__dirname + '/pkg-bower-json-invalid/bower.json')); + + err = bowerJson.readSync(__dirname + '/pkg-bower-json-invalid/bower.json', { validate: false }); + expect(err).to.not.be.an(Error); + done(); + }); + + it('should normalize the returned object if normalize is true', function (done) { + var json = bowerJson.readSync(__dirname + '/pkg-bower-json/bower.json'); + expect(json.main).to.equal('foo.js'); + + json = bowerJson.readSync(__dirname + '/pkg-bower-json/bower.json', { normalize: true }); + + expect(json.main).to.eql(['foo.js']); + done(); + }); + + +}); + describe('.parse', function () { it('should return the same object, unless clone is true', function () { var json = { name: 'foo' }; From 304bb36bbc05245f82a8a02f5c4e53e9192655d5 Mon Sep 17 00:00:00 2001 From: Paulo Pires Date: Tue, 8 Dec 2015 06:55:14 -0800 Subject: [PATCH 0797/1021] Added coveralls support added missing packages added test coverage files to gitignore remove unecessary files added missing coveralls package --- packages/bower-config/.gitignore | 1 + packages/bower-config/.travis.yml | 2 ++ packages/bower-config/Gruntfile.js | 2 +- packages/bower-config/package.json | 4 ++++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/bower-config/.gitignore b/packages/bower-config/.gitignore index 1743854da..efbfac7c4 100644 --- a/packages/bower-config/.gitignore +++ b/packages/bower-config/.gitignore @@ -4,3 +4,4 @@ npm-debug.log test/assets/github-test-package test/assets/github-test-package-copy test/assets/temp +test/reports diff --git a/packages/bower-config/.travis.yml b/packages/bower-config/.travis.yml index a78e23d5e..fef566a62 100644 --- a/packages/bower-config/.travis.yml +++ b/packages/bower-config/.travis.yml @@ -5,3 +5,5 @@ node_js: - '4' - '0.12' - '0.10' +script: + - grunt travis diff --git a/packages/bower-config/Gruntfile.js b/packages/bower-config/Gruntfile.js index d2bc8f705..018ecd5d0 100644 --- a/packages/bower-config/Gruntfile.js +++ b/packages/bower-config/Gruntfile.js @@ -50,4 +50,4 @@ module.exports = function (grunt) { grunt.registerTask('cover', 'exec:cover'); grunt.registerTask('travis', ['jshint', 'exec:cover', 'exec:coveralls']); grunt.registerTask('default', 'test'); -}; \ No newline at end of file +}; diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 61a332994..102999259 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -18,13 +18,17 @@ "untildify": "2.1.0" }, "devDependencies": { + "coveralls": "^2.11.4", "expect.js": "^0.3.1", "glob": "^4.5.3", "grunt": "^0.4.5", "grunt-cli": "^0.1.13", "grunt-contrib-jshint": "^0.10.0", "grunt-contrib-watch": "^0.6.1", + "grunt-coveralls": "^1.0.0", + "grunt-exec": "^0.4.6", "grunt-simple-mocha": "^0.4.0", + "istanbul": "^0.4.1", "load-grunt-tasks": "^2.0.0", "mkdirp": "^0.5.0", "mocha": "~1.12.0", From fe9b27a64773e40538e2757c2d195728baca27f2 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 8 Dec 2015 19:15:06 +0100 Subject: [PATCH 0798/1021] Try to fix appveyor build with npm-env --- Gruntfile.js | 2 +- package.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index b63cea675..136cee16a 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -55,7 +55,7 @@ module.exports = function (grunt) { command: 'node test/packages.js --force && node test/packages-svn.js --force' }, cover: { - command: 'STRICT_REQUIRE=1 node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' + command: 'env STRICT_REQUIRE=1 node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' }, coveralls: { command: 'node node_modules/.bin/coveralls < test/reports/lcov.info' diff --git a/package.json b/package.json index 52ebd464c..ccdb6315b 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "multiline": "^1.0.2", "nock": "^3.1.0", "node-uuid": "^1.4.2", + "npm-env": "^1.0.0", "proxyquire": "^1.3.0", "spawn-sync": "1.0.13" }, From 322c49edf49bba8cc35f7720a707f81c6d30b34a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 8 Dec 2015 19:52:10 +0100 Subject: [PATCH 0799/1021] Get rid of STRICT_REQUIRE flag for coverage testing --- Gruntfile.js | 2 +- package.json | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 136cee16a..0144fe627 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -55,7 +55,7 @@ module.exports = function (grunt) { command: 'node test/packages.js --force && node test/packages-svn.js --force' }, cover: { - command: 'env STRICT_REQUIRE=1 node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' + command: 'node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' }, coveralls: { command: 'node node_modules/.bin/coveralls < test/reports/lcov.info' diff --git a/package.json b/package.json index ccdb6315b..52ebd464c 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,6 @@ "multiline": "^1.0.2", "nock": "^3.1.0", "node-uuid": "^1.4.2", - "npm-env": "^1.0.0", "proxyquire": "^1.3.0", "spawn-sync": "1.0.13" }, From c559432c1957b9ea9ebc8e9194428cd065d5a373 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 8 Dec 2015 20:05:04 +0100 Subject: [PATCH 0800/1021] Properly call coveralls script --- Gruntfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index 0144fe627..239b9f68e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -58,7 +58,7 @@ module.exports = function (grunt) { command: 'node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' }, coveralls: { - command: 'node node_modules/.bin/coveralls < test/reports/lcov.info' + command: 'coveralls < test/reports/lcov.info' } }, watch: { From a532c55dca1815a8a881235357dc09ad8c7a9550 Mon Sep 17 00:00:00 2001 From: Chris Contolini Date: Tue, 8 Dec 2015 12:15:08 -0500 Subject: [PATCH 0801/1021] Hide prereleases when showing package info --- lib/renderers/StandardRenderer.js | 13 +++++++++++++ package.json | 1 + templates/std/info.std | 4 ++++ 3 files changed, 18 insertions(+) diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index f8b580308..e91ee54fe 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -5,6 +5,7 @@ var archy = require('archy'); var Q = require('q'); var stringifyObject = require('stringify-object'); var os = require('os'); +var semverUtils = require('semver-utils'); var pkg = require(path.join(__dirname, '../..', 'package.json')); var template = require('../util/template'); @@ -209,6 +210,18 @@ StandardRenderer.prototype._info = function (data) { // Render the versions at the end if (includeVersions) { + data.hidePreReleases = false; + data.numPreReleases = 0; + // If output isn't verbose, hide prereleases + if (!this._config.verbose) { + data.versions = mout.array.filter(data.versions, function(val) { + if (!semverUtils.parse(val).build) { + return true; + } + data.numPreReleases++; + }); + data.hidePreReleases = !!data.numPreReleases; + } str += '\n' + template.render('std/info.std', data); } diff --git a/package.json b/package.json index 52ebd464c..4ce566575 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "retry": "0.6.1", "rimraf": "^2.2.8", "semver": "^2.3.0", + "semver-utils": "^1.1.1", "shell-quote": "^1.4.2", "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", diff --git a/templates/std/info.std b/templates/std/info.std index ffa9ab675..40a034489 100644 --- a/templates/std/info.std +++ b/templates/std/info.std @@ -5,6 +5,10 @@ {{/versions}} {{/condense}} + +{{#if hidePreReleases}} +Show {{numPreReleases}} additional prereleases with ‘bower info {{name}} --verbose’ +{{/if}} You can request info for a specific version with 'bower info {{name}}#' {{else}}No versions available. {{/if}} \ No newline at end of file From 7cb88ab49fa2f212a191d905cf0ad699068b19db Mon Sep 17 00:00:00 2001 From: Chris Contolini Date: Tue, 8 Dec 2015 17:34:09 -0500 Subject: [PATCH 0802/1021] Add renderer tests for prereleases --- lib/renderers/StandardRenderer.js | 5 ++-- test/renderers/StandardRenderer.js | 48 +++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index e91ee54fe..60f0c7553 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -214,8 +214,9 @@ StandardRenderer.prototype._info = function (data) { data.numPreReleases = 0; // If output isn't verbose, hide prereleases if (!this._config.verbose) { - data.versions = mout.array.filter(data.versions, function(val) { - if (!semverUtils.parse(val).build) { + data.versions = mout.array.filter(data.versions, function(version) { + version = semverUtils.parse(version); + if (!version.release && !version.build) { return true; } data.numPreReleases++; diff --git a/test/renderers/StandardRenderer.js b/test/renderers/StandardRenderer.js index 1d5422830..620adf7bd 100644 --- a/test/renderers/StandardRenderer.js +++ b/test/renderers/StandardRenderer.js @@ -613,7 +613,11 @@ describe('StandardRenderer', function () { versions: [ '1.2.0', '1.2.1', - '1.2.2' + '1.2.2', + '1.2.3+build-1234', + '1.2.8-build.2098+sha.cb9c0f2', + '1.3.0-rc.5', + '1.3.0-beta.18' ] }); }).spread(function(stdout, stderr) { @@ -627,6 +631,48 @@ describe('StandardRenderer', function () { - 1.2.0 - 1.2.1 - 1.2.2 + + Show 4 additional prereleases with ‘bower info foo --verbose’ + You can request info for a specific version with 'bower info foo#' + + */})); + }); + }); + + it('outputs full info command log with prereleases', function() { + return helpers.capture(function() { + var renderer = new StandardRenderer('info', { verbose: true }); + renderer.end({ + name: 'foo', + latest: { + version: '1.2.3' + }, + versions: [ + '1.2.0', + '1.2.1', + '1.2.2', + '1.2.3+build-1234', + '1.2.8-build.2098+sha.cb9c0f2', + '1.3.0-rc.5', + '1.3.0-beta.18' + ] + }); + }).spread(function(stdout, stderr) { + expect(stdout).to.equal(multiline(function() {/* + + { + version: '1.2.3' + } + + Available versions: + - 1.2.0 + - 1.2.1 + - 1.2.2 + - 1.2.3+build-1234 + - 1.2.8-build.2098+sha.cb9c0f2 + - 1.3.0-rc.5 + - 1.3.0-beta.18 + You can request info for a specific version with 'bower info foo#' */})); From 9e4bdd270d53c2ec101a99b66401eca733a563a0 Mon Sep 17 00:00:00 2001 From: Accommodavid Date: Wed, 9 Dec 2015 00:01:10 +0100 Subject: [PATCH 0803/1021] Add test for tar archives Adds a test that checks if dependencies that point to tar archives (not tar.gz) are handled and extracted correctly. Also removes a test from `test/commands/install.js` that was duplicated. Re-add postinstall test --- test/assets/package-tar.tar | Bin 0 -> 3584 bytes test/commands/install.js | 20 ++++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 test/assets/package-tar.tar diff --git a/test/assets/package-tar.tar b/test/assets/package-tar.tar new file mode 100644 index 0000000000000000000000000000000000000000..186dbe5f59127312a8d9fd6ddb8dd12d4fbd97fd GIT binary patch literal 3584 zcmeHH%}T>S5FP~)Pu}#pFVJ;%H@m5L^59Vf&B2>2`6)r0gf=bpU3>#y(pej58*1wz zDS|sNEc3I&%=a-<+4$9t(m`z}SJ0CnVyHC(_Zsv4q70TV`J6BzjS@yHrIDe~s1z{W zQ$HJJXHy!TTC;Inj>lzU=XtV`&={1KW!nOcubIOQNy2ty{;5#4#y@|Vr;}-37Q9~6 z9d=20m|)5GR{o_{EB=Kd{=*>Dz_7y}ek}FR`G=E>Q#b~=w=sKoV$ZA*=Yum+N%~Ie z>`&5P$ZZroHfiq12kCk1+tJE@Nqfg_RlTJ=N*DEA5tm6`j3{ANXM^F5P=OTT^)P6a z@MaeXtnYt6+Yjy}?%aPw-QIsX34Z^(;CEjQ!I2;2&hBf($2|fb0gr%3;GhV60Xt)E AOaK4? literal 0 HcmV?d00001 diff --git a/test/commands/install.js b/test/commands/install.js index 858745e99..bcf57020d 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -1,4 +1,5 @@ var expect = require('expect.js'); +var path = require('path'); var helpers = require('../helpers'); var nock = require('nock'); var fs = require('../../lib/util/fs'); @@ -172,7 +173,7 @@ describe('bower install', function() { }); }); - it('runs preinstall hook', function() { + it('runs postinstall hook', function() { mainPackage.prepare(); tempDir.prepare({ @@ -301,6 +302,22 @@ describe('bower install', function() { }); }); + it('works for dependencies that point to tar files', function() { + var packageDir = path.join(__dirname, '../assets/package-tar.tar'); + tempDir.prepare({ + 'bower.json': { + name: 'test', + dependencies: { + package: packageDir + } + } + }); + + return helpers.run(install).then(function() { + expect(tempDir.read('bower_components/package/index.txt')).to.contain('1.0.0'); + }); + }); + it('does not install ignored dependencies', function() { mainPackage.prepare(); var package2 = new helpers.TempDir({ @@ -406,7 +423,6 @@ describe('bower install', function() { }); }); - it('errors if the components directory is not a directory', function() { tempDir.prepare({ '.bowerrc': { From 42107e6feac8c92b5540390d31f9a005b34791ba Mon Sep 17 00:00:00 2001 From: Paulo Pires Date: Wed, 9 Dec 2015 03:52:47 -0800 Subject: [PATCH 0804/1021] added coveralls badge --- packages/bower-config/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index b30c222c0..e0e3f9445 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -1,4 +1,4 @@ -# bower-config [![Build Status](https://secure.travis-ci.org/bower/config.png?branch=master)](http://travis-ci.org/bower/config) +# bower-config [![Build Status](https://secure.travis-ci.org/bower/config.png?branch=master)](http://travis-ci.org/bower/config)[![Coverage Status](https://coveralls.io/repos/bower/config/badge.svg?branch=master&service=github)](https://coveralls.io/github/bower/config?branch=master) > The Bower config (`.bowerrc`) reader and writer. From 57478d86c787527d56dceaadbfaa3d91e355dd7b Mon Sep 17 00:00:00 2001 From: Paulo Pires Date: Wed, 9 Dec 2015 03:53:47 -0800 Subject: [PATCH 0805/1021] added --- packages/bower-json/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index 7b80c911f..bace32abb 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -1,4 +1,4 @@ -# bower-json [![Build Status](https://secure.travis-ci.org/bower/json.png?branch=master)](http://travis-ci.org/bower/json) +# bower-json [![Build Status](https://secure.travis-ci.org/bower/json.png?branch=master)](http://travis-ci.org/bower/json) [![Coverage Status](https://coveralls.io/repos/bower/json/badge.svg?branch=master&service=github)](https://coveralls.io/github/bower/json?branch=master) Read `bower.json` files with semantics, normalisation, defaults and validation. From 5af929f0be555c2a142aa009ab46f4d1ab2b7b25 Mon Sep 17 00:00:00 2001 From: Chris Contolini Date: Wed, 9 Dec 2015 20:08:44 -0500 Subject: [PATCH 0806/1021] Clean up readme --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a401d4533..714c339ed 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bower - A package manager for the web -> Bower needs resources for its maintenance. Please fill [Support Declaration](http://goo.gl/forms/P1ndzCNoiG) if you think you can help. +> Bower needs resources for its maintenance. Please see [our blog](http://bower.io/blog/) if you think you can help. [![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)](https://ci.appveyor.com/project/sheerun/bower/history) @@ -52,7 +52,7 @@ $ bower install # --save We discourage using bower components statically for performance and security reasons (if component has an `upload.php` file that is not ignored, that can be easily exploited to do malicious stuff). -The best approach is to process components installed by bower with build tool (like [Grunt](http://gruntjs.com/) or [gulp](http://gulpjs.com/)), and serve them concatenated or using module loader (like [RequireJS](http://requirejs.org/)). +The best approach is to process components installed by bower with build tool (like [Grunt](http://gruntjs.com/) or [gulp](http://gulpjs.com/)), and serve them concatenated or using a module loader (like [RequireJS](http://requirejs.org/)). ### Uninstalling packages @@ -68,7 +68,7 @@ On `prezto` or `oh-my-zsh`, do not forget to `alias bower='noglob bower'` or `bo ### Never run Bower with sudo -Bower is a user command, there is no need to execute it with superuser permissions. +Bower is a user command; there is no need to execute it with superuser permissions. ### Windows users @@ -100,6 +100,7 @@ Bower can be configured using JSON in a `.bowerrc` file. Read over available opt ## Support +* [Discord chat](https://discord.gg/0fFM7QF0KpZRh2cY) * [StackOverflow](http://stackoverflow.com/questions/tagged/bower) * [Mailinglist](http://groups.google.com/group/twitter-bower) - twitter-bower@googlegroups.com * [\#bower](http://webchat.freenode.net/?channels=bower) on Freenode @@ -107,8 +108,7 @@ Bower can be configured using JSON in a `.bowerrc` file. Read over available opt ## Contributing -We welcome [contributions](https://github.com/bower/bower/graphs/contributors) of all kinds from anyone. Please take a moment to -review the [guidelines for contributing](CONTRIBUTING.md). +We welcome [contributions](https://github.com/bower/bower/graphs/contributors) of all kinds from anyone. Please take a moment to review the [guidelines for contributing](CONTRIBUTING.md). * [Bug reports](https://github.com/bower/bower/wiki/Report-a-Bug) * [Feature requests](CONTRIBUTING.md#features) From 26f609e6144ce5f9f876815a8179cdf6e24bb66b Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 10 Dec 2015 21:24:46 +0100 Subject: [PATCH 0807/1021] Ignore for now failing windows build on node 5 --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 440de4bc9..c2892675a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,6 +18,7 @@ environment: matrix: allow_failures: - nodejs_version: "0.10" + - nodejs_version: "5" # Install scripts. (runs after repo cloning) install: From b9718bb30982dc32c44836d5a49baa28d823dd16 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Dec 2015 20:14:13 +0100 Subject: [PATCH 0808/1021] Fix search command on no arguments, fixes #2066 --- Gruntfile.js | 2 +- bin/bower | 56 +++++++++++++++++++++--------------- lib/commands/index.js | 38 ++++++------------------- lib/commands/search.js | 20 ++++++------- test/commands/search.js | 63 +++++++++++++++++------------------------ test/helpers.js | 4 +-- 6 files changed, 80 insertions(+), 103 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 239b9f68e..a27e5c80c 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -68,7 +68,7 @@ module.exports = function (grunt) { }); grunt.registerTask('assets', ['exec:assets-force']); - grunt.registerTask('test', ['jshint', 'jscs', 'exec:assets', 'simplemocha:full']); + grunt.registerTask('test', ['jscs', 'jshint', 'exec:assets', 'simplemocha:full']); grunt.registerTask('cover', 'exec:cover'); grunt.registerTask('travis', ['jshint', 'exec:assets', 'exec:cover', 'exec:coveralls']); grunt.registerTask('default', 'test'); diff --git a/bin/bower b/bin/bower index 2768bbd6e..2a6129138 100755 --- a/bin/bower +++ b/bin/bower @@ -99,30 +99,40 @@ analytics.setup(bower.config).then(function () { // Get the renderer and configure it with the executed command renderer = cli.getRenderer(command, logger.json, bower.config); - logger - .on('end', function (data) { - if (!bower.config.silent && !bower.config.quiet) { - renderer.end(data); - } - }) - .on('error', function (err) { - if (levels.error >= loglevel) { - renderer.error(err); - } - - process.exit(1); - }) - .on('log', function (log) { - if (levels[log.level] >= loglevel) { - renderer.log(log); - } - }) - .on('prompt', function (prompt, callback) { - renderer.prompt(prompt) - .then(function (answer) { - callback(answer); + function handleLogger(logger, renderer) { + logger + .on('end', function (data) { + if (!bower.config.silent && !bower.config.quiet) { + renderer.end(data); + } + }) + .on('error', function (err) { + if (command !== 'help' && err.code === cli.READ_OPTIONS_ERROR_CODE) { + logger = bower.commands.help(command); + renderer = cli.getRenderer('help', logger.json, bower.config); + handleLogger(logger, renderer); + } else { + if (levels.error >= loglevel) { + renderer.error(err); + } + + process.exit(1); + } + }) + .on('log', function (log) { + if (levels[log.level] >= loglevel) { + renderer.log(log); + } + }) + .on('prompt', function (prompt, callback) { + renderer.prompt(prompt) + .then(function (answer) { + callback(answer); + }); }); - }); + } + + handleLogger(logger, renderer); // Warn if HOME is not SET if (!userHome) { diff --git a/lib/commands/index.js b/lib/commands/index.js index 90761ebe5..9be35bf98 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -1,7 +1,6 @@ var Q = require('q'); var Logger = require('bower-logger'); var config = require('../config'); -var cli = require('../util/cli'); /** * Require commands only when called. @@ -11,45 +10,26 @@ var cli = require('../util/cli'); * return as soon as possible and load and execute the command asynchronously. */ function commandFactory(id) { - if (process.env.STRICT_REQUIRE) { - require(id); - } - - function command() { + function runApi() { + var command = require(id); var commandArgs = [].slice.call(arguments); return withLogger(function (logger) { commandArgs.unshift(logger); - return require(id).apply(undefined, commandArgs); + + return command.apply(undefined, commandArgs); }); } function runFromArgv(argv) { var commandArgs; - var errorForLogger; var command = require(id); - try { - commandArgs = command.readOptions(argv); - } - catch (e) { - if (e.code === cli.READ_OPTIONS_ERROR_CODE) { - return null; - } - else { - // Delay raising the error until the logger is set up so the - // logger can handle it. - errorForLogger = e; - } - } + commandArgs = command.readOptions(argv); return withLogger(function (logger) { - // Raise any non-read-options error so the logger can handle it. - if (errorForLogger) { - throw errorForLogger; - } - commandArgs.unshift(logger); + return command.apply(undefined, commandArgs); }); } @@ -58,7 +38,7 @@ function commandFactory(id) { var logger = new Logger(); Q.try(func, logger) - .done(function () { + .then(function () { config.restore(); var args = [].slice.call(arguments); args.unshift('end'); @@ -71,9 +51,9 @@ function commandFactory(id) { return logger; } - command.line = runFromArgv; + runApi.line = runFromArgv; - return command; + return runApi; } diff --git a/lib/commands/search.js b/lib/commands/search.js index a6bcc4c7d..06f77f739 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -2,27 +2,30 @@ var Q = require('q'); var RegistryClient = require('bower-registry-client'); var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); -var bowerConfig = require('../../lib').config; var cli = require('../util/cli'); function search(logger, name, config) { var registryClient; var tracker; + var json = config ? config.json : undefined; config = defaultConfig(config); + config.json = config.json || json; // Hack until bower-config is fixed... config.cache = config.storage.registry; registryClient = new RegistryClient(config, logger); tracker = new Tracker(config); tracker.track('search', name); - // Search if the user has given a name query if (name) { return Q.nfcall(registryClient.search.bind(registryClient), name); - } - // List all packages when in interactive mode + json enabled, and - // always when in non-interactive mode - else if (bowerConfig.json || !config.interactive) { + } else { + // List all packages when in interactive mode + json enabled, and + // always when in non-interactive mode + if (config.interactive && !config.json) { + throw cli.createReadOptionsError('search'); + } + return Q.nfcall(registryClient.list.bind(registryClient)); } } @@ -33,11 +36,6 @@ search.readOptions = function (argv) { var options = cli.readOptions(argv); var terms = options.argv.remain.slice(1); - // When searching from the CLI, we expect at least one search term. - if (terms.length <= 0) { - throw cli.createReadOptionsError('search'); - } - var name = terms.join(' '); return [name]; diff --git a/test/commands/search.js b/test/commands/search.js index 347d2657d..553df9b4b 100644 --- a/test/commands/search.js +++ b/test/commands/search.js @@ -44,51 +44,40 @@ describe('bower search', function () { }); it('lists all repositories when no query given and config.json is enabled in interactive mode', function () { - // Set the json config globally as if it were entered on the command line - var bowerConfig = require('../../lib').config; - bowerConfig.json = true; + var interactiveConfig = { interactive: true, json: true }; - var interactiveConfig = { interactive: true }; - - return Q.Promise(function(resolve) { - var search = helpers.command('search', { - 'bower-registry-client': function() { - return { - list: resolve - }; - } - }); + var search = helpers.command('search', { + 'bower-registry-client': function() { + return { + list: function (cb) { return cb(null, 'foobar'); } + }; + } + }); - helpers.run(search, [null, interactiveConfig]); - }).then(function() { - // Reset the global json config value - bowerConfig.json = false; + return helpers.run(search, [null, interactiveConfig]) + .spread(function(result) { + expect(result).to.be('foobar'); }); }); - it('does not list any repositories in interactive mode if no query given and config.json is disabled', function (done) { + it('does not list any repositories in interactive mode if no query given and config.json is disabled', function () { var interactiveConfig = { interactive: true }; - return Q.Promise(function(resolve, reject) { - var search = helpers.command('search', { - 'bower-registry-client': function() { - return { - list: reject - }; - } - }); - helpers.run(search, [null, interactiveConfig]).then(function(loggerEndData) { - var commandResult = loggerEndData[0]; - resolve(commandResult); - }); - }) + var search = helpers.command('search', { + 'bower-registry-client': function() { + return { + list: function() { throw 'list called'; }, + search: function() { throw 'search called'; } + }; + } + }); + + return helpers.run(search, [null, interactiveConfig]) .then(function(commandResult) { - // No work should have been done, so no value should be returned. - expect(commandResult).to.be(undefined); + expect().fail('should fail'); }) - .catch(function() { - expect().fail('should not list repositories'); - }) - .done(done); + .catch(function(e) { + expect(e.code).to.be('EREADOPTIONS'); + }); }); }); diff --git a/test/helpers.js b/test/helpers.js index 05c0e3e36..70c3dd6b3 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -220,7 +220,7 @@ exports.command = function (command, stubs) { }; exports.run = function (command, args) { - var logger = command.apply(command, args || []); + var logger = command.apply(null, args || []); // Hack so we can intercept prompring for data logger.prompt = function(data) { @@ -310,4 +310,4 @@ exports.runBin = function (args) { afterEach(function () { nock.cleanAll(); -}); \ No newline at end of file +}); From 2db983dba303ff3f7d49ec74c44a0c18294f836c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Dec 2015 20:16:54 +0100 Subject: [PATCH 0809/1021] Better formatting of help --- templates/std/help-generic.std | 1 + templates/std/help.std | 1 + 2 files changed, 2 insertions(+) diff --git a/templates/std/help-generic.std b/templates/std/help-generic.std index dd772e5de..9bbf86754 100644 --- a/templates/std/help-generic.std +++ b/templates/std/help-generic.std @@ -21,3 +21,4 @@ Options: Description: {{#indent level="4"}}{{description}}{{/indent}} + diff --git a/templates/std/help.std b/templates/std/help.std index 7f1127eb6..83f8a6615 100644 --- a/templates/std/help.std +++ b/templates/std/help.std @@ -24,3 +24,4 @@ Options: {{/condense}} See 'bower help ' for more information on a specific command. + From 7792b6d35d619b04c93ac3c7301e5f7f96adaffd Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Dec 2015 20:24:40 +0100 Subject: [PATCH 0810/1021] Use coveralls as npm script (fix certain versions of node) --- Gruntfile.js | 2 +- package.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index a27e5c80c..7d6584101 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -58,7 +58,7 @@ module.exports = function (grunt) { command: 'node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' }, coveralls: { - command: 'coveralls < test/reports/lcov.info' + command: 'npm run coveralls < test/reports/lcov.info' } }, watch: { diff --git a/package.json b/package.json index 4ce566575..c92ccfcd7 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,8 @@ ], "scripts": { "test": "grunt test", - "ci": "grunt travis" + "ci": "grunt travis", + "coveralls": "coveralls" }, "bin": "bin/bower", "files": [ From 7c714901d47f209c9cf29da496a9720199accf32 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Dec 2015 20:33:54 +0100 Subject: [PATCH 0811/1021] Fix test for StandardRenderer --- test/renderers/StandardRenderer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/renderers/StandardRenderer.js b/test/renderers/StandardRenderer.js index 620adf7bd..4762b4a87 100644 --- a/test/renderers/StandardRenderer.js +++ b/test/renderers/StandardRenderer.js @@ -842,6 +842,7 @@ describe('StandardRenderer', function () { Uninstalls a package locally from your bower_components directory + */})); }); }); From d3eef5772af9d2c06036abe84f932b6a7d9e9ca7 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Dec 2015 21:25:15 +0100 Subject: [PATCH 0812/1021] Revert "Only update packages requested by the user" This reverts commit e3f402fc66ee49e6ca033fdd43ce7a7cf1a5bb0c. --- lib/core/Manager.js | 11 +---------- lib/core/Project.js | 5 ----- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index d450b3d4d..cb5a6ae58 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -76,8 +76,6 @@ Manager.prototype.configure = function (setup) { // Uniquify targets this._targets = this._uniquify(this._targets); - this._requested = setup.requested || []; - // Force-latest this._forceLatest = !!setup.forceLatest; @@ -96,8 +94,6 @@ Manager.prototype.configure = function (setup) { * */ Manager.prototype.resolve = function () { - var name; - // If already resolving, error out if (this._working) { return Q.reject(createError('Already working', 'EWORKING')); @@ -116,12 +112,7 @@ Manager.prototype.resolve = function () { // Otherwise, fetch each target from the repository // and let the process roll out } else { - this._targets.forEach(function (target) { - name = target.name || target.source; - if (!this._requested.length || mout.array.contains(this._requested, name)) { - this._fetch(target); - } - }.bind(this)); + this._targets.forEach(this._fetch.bind(this)); } // Unset working flag when done diff --git a/lib/core/Project.js b/lib/core/Project.js index 9cc6eff44..39725d096 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -38,9 +38,6 @@ Project.prototype.install = function (decEndpoints, options, config) { this._options = options || {}; this._config = config || {}; this._working = true; - this._endpoints = decEndpoints.map(function (endpoint) { - return endpoint.name || endpoint.source; - }); // Analyse the project return this._analyse() @@ -134,7 +131,6 @@ Project.prototype.update = function (names, options) { this._options = options || {}; this._working = true; - this._endpoints = names; // Analyse the project return this._analyse() @@ -562,7 +558,6 @@ Project.prototype._bootstrap = function (targets, resolved, incompatibles) { targets: targets, resolved: resolved, incompatibles: incompatibles, - requested: this._endpoints, resolutions: this._json.resolutions, installed: installed, forceLatest: this._options.forceLatest From 3bd2d62e671f4a3c7cc20b3dd97410170c5f39b1 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Dec 2015 21:32:47 +0100 Subject: [PATCH 0813/1021] Revert "Add failing tests for single package updates, optimize older tests" This reverts commit 6616d09f47ac50c2d3877aca7ecdbe8fb0b241d5. --- lib/core/Project.js | 3 +- test/commands/install.js | 172 ++++----------------------- test/commands/update.js | 243 ++++++++------------------------------- 3 files changed, 73 insertions(+), 345 deletions(-) diff --git a/lib/core/Project.js b/lib/core/Project.js index 39725d096..f49b4612e 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -206,9 +206,8 @@ Project.prototype.update = function (names, options) { } var jsonEndpoint = endpointParser.decomposed2json(target); - var src = target.name !== target.source ? target.source + '#' : ''; // Bower uses the ~ range specifier for new installs - jsonEndpoint[target.name] = src + '~' + target.pkgMeta.version; + jsonEndpoint[target.name] = '~' + target.pkgMeta.version; if (that._options.saveDev && mout.object.has(that._json, 'devDependencies.' + target.name)) { that._json.devDependencies = mout.object.mixIn(that._json.devDependencies || {}, jsonEndpoint); diff --git a/test/commands/install.js b/test/commands/install.js index bcf57020d..0e035e1f9 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -286,7 +286,21 @@ describe('bower install', function() { }); }); - it('works for git repositories', function() { + it('works for git repositories', function () { + gitPackage.prepareGit({ + '1.0.0': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '1.0.0' + }, + '1.0.1': { + 'bower.json': { + name: 'package' + }, + 'version.txt': '1.0.1' + } + }); tempDir.prepare({ 'bower.json': { @@ -412,15 +426,13 @@ describe('bower install', function() { .reply(500); return helpers.run(install, [ - undefined, - undefined, { - proxy: 'http://dummy.local/' - } - ]) - .fail(function(error) { - expect(error.message).to.equal('Status code of 500'); - done(); - }); + undefined, + undefined, + { proxy: 'http://dummy.local/' } + ]) + .fail(function(error) { + expect(error.message).to.equal('Status code of 500'); + done(); }); it('errors if the components directory is not a directory', function() { @@ -434,144 +446,4 @@ describe('bower install', function() { expect(error.code).to.equal('ENOTDIR'); }); }); - - it('installs only the specified dependencies', function() { - var package4 = new helpers.TempDir({ - 'bower.json': { - name: 'package4' - } - }).prepare(); - - var package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3' - } - }).prepare(); - - var package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2' - } - }).prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package2: package2.path, - package3: package3.path, - package4: package4.path - } - } - }); - - return helpers.run(install, [[package2.path, package3.path]]).then(function() { - expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); - expect(tempDir.exists('bower_components/package3/bower.json')).to.equal(true); - expect(tempDir.exists('bower_components/package4')).to.equal(false); - }); - }); - - it('installs sub deps of only the specified packages', function() { - var package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3', - dependencies: { - package: gitPackage.path + '#~1.0.1' - } - } - }).prepare(); - - var package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - dependencies: { - package: gitPackage.path + '#1.0.0' - } - } - }).prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package2: package2.path, - package3: package3.path - } - } - }); - - return helpers.run(install, [[package2.path]]).then(function() { - expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('1.0.0'); - }); - }); - - it('doesn\'t update other deps when installing a specified dep', function() { - var package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - version: '1.2.3' - } - }).prepare(); - - var package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3', - version: '4.5.6' - } - }).prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package2: package2.path, - package3: package3.path - } - } - }); - - // Install both dependencies, they should equal the latest release matching - // the ranges above. - return helpers.run(install).then(function() { - - expect(tempDir.readJson('bower_components/package2/.bower.json').version).to.equal('1.2.3'); - expect(tempDir.readJson('bower_components/package3/.bower.json').version).to.equal('4.5.6'); - - // Override first dep with older version - package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - version: '1.0.0' - } - }).prepare(); - - return helpers.run(install, [[package2.path]]).then(function() { - - expect(tempDir.readJson('bower_components/package2/.bower.json').version).to.equal('1.0.0'); - expect(tempDir.readJson('bower_components/package3/.bower.json').version).to.equal('4.5.6'); - - // Override second dep with older version, the first dep should remain old - // and *not* get updated. - package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - version: '1.2.3' - } - }).prepare(); - - package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3', - version: '4.0.0' - } - }).prepare(); - - return helpers.run(install, [[package3.path]]).then(function() { - expect(tempDir.readJson('bower_components/package2/.bower.json').version).to.equal('1.0.0'); - expect(tempDir.readJson('bower_components/package3/.bower.json').version).to.equal('4.0.0'); - }); - }); - }); - }); }); diff --git a/test/commands/update.js b/test/commands/update.js index fded86287..31750775b 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -3,11 +3,11 @@ var object = require('mout').object; var semver = require('semver'); var helpers = require('../helpers'); -var rimraf = require('../../lib/util/rimraf'); var updateCmd = helpers.command('update'); var commands = helpers.require('lib/index').commands; -describe('bower update', function() { +describe('bower update', function () { + this.timeout(10000); var tempDir = new helpers.TempDir(); @@ -18,16 +18,8 @@ describe('bower update', function() { }).prepare(); var gitPackage = new helpers.TempDir(); - var gitPackage2 = new helpers.TempDir(); - var gitPackage3 = new helpers.TempDir(); gitPackage.prepareGit({ - '0.1.1': { - 'bower.json': { - name: 'package' - }, - 'version.txt': '0.9.0' - }, '1.0.0': { 'bower.json': { name: 'package' @@ -45,36 +37,6 @@ describe('bower update', function() { } }); - gitPackage2.prepareGit({ - '2.0.0': { - 'bower.json': { - name: 'package' - }, - 'version.txt': '2.0.0' - }, - '2.0.1': { - 'bower.json': { - name: 'package' - }, - 'version.txt': '2.0.1' - } - }); - - gitPackage3.prepareGit({ - '3.0.0': { - 'bower.json': { - name: 'package' - }, - 'version.txt': '3.0.0' - }, - '3.0.1': { - 'bower.json': { - name: 'package' - }, - 'version.txt': '3.0.1' - } - }); - var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package' @@ -305,111 +267,19 @@ describe('bower update', function() { }); }); - it('updates only the specified packages', function() { - var package4 = new helpers.TempDir({ - 'bower.json': { - name: 'package4' - } - }).prepare(); - - var package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3' - } - }).prepare(); - - var package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2' - } - }).prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package2: package2.path, - package3: package3.path, - package4: package4.path - } - } - }); - - return install().then(function() { - - rimraf.sync(tempDir.path + '/bower_components/'); - - return update(['package4']).then(function() { - expect(tempDir.exists('bower_components/package2')).to.equal(false); - expect(tempDir.exists('bower_components/package3')).to.equal(false); - expect(tempDir.exists('bower_components/package4/bower.json')).to.equal(true); - - rimraf.sync(tempDir.path + '/bower_components/'); - - return update(['package2', 'package3']).then(function() { - expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); - expect(tempDir.exists('bower_components/package3/bower.json')).to.equal(true); - expect(tempDir.exists('bower_components/package4')).to.equal(false); - }); - }); - }); - }); - - it('updates sub deps of only the specified packages', function() { - var package3 = new helpers.TempDir({ - 'bower.json': { - name: 'package3', - dependencies: { - package: gitPackage.path + '#~1.0.0' - } - } - }).prepare(); - - var package2 = new helpers.TempDir({ - 'bower.json': { - name: 'package2', - dependencies: { - package: gitPackage2.path + '#~2.0.0' - } - } - }).prepare(); - - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - package2: package2.path, - package3: package3.path - } - } - }); - - return install([package2.path]).then(function() { - expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('2.0.1'); - - rimraf.sync(tempDir.path + '/bower_components/'); - - return update(['package3']).then(function() { - expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('1.0.1'); - }); - }); - }); - - it('doesn\'t update extraneous packages', function() { + it('doesn\'t update extraneous packages', function () { tempDir.prepare({ 'bower.json': { name: 'test' } }); - return install(['package=' + gitPackage.path + '#1.0.0']).then(function() { + return install(['underscore#1.5.0']).then(function() { - expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('1.0.0'); + expect(tempDir.readJson('bower_components/underscore/package.json').version).to.equal('1.5.0'); - return update(null, { - save: true - }).then(function() { - expect(tempDir.readJson('bower_components/package/.bower.json').version).to.equal('1.0.0'); + return update(null, {save: true}).then(function() { + expect(tempDir.readJson('bower_components/underscore/package.json').version).to.equal('1.5.0'); expect(tempDir.readJson('bower.json')).to.not.have.property('dependencies'); }); }); @@ -420,19 +290,17 @@ describe('bower update', function() { 'bower.json': { name: 'test', dependencies: { - package: gitPackage.path + '#~1.0.0' + underscore: '~1.5.0' } } }); return install().then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.0'); + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.0'); - return update(null, { - save: true - }).then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.1'); + return update(null, {save: true}).then(function() { + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.2'); }); }); }); @@ -442,19 +310,17 @@ describe('bower update', function() { 'bower.json': { name: 'test', devDependencies: { - package: gitPackage.path + '#~1.0.0' + underscore: '~1.5.0' } } }); return install().then(function() { - expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(gitPackage.path + '#~1.0.0'); + expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.0'); - return update(null, { - saveDev: true - }).then(function() { - expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(gitPackage.path + '#~1.0.1'); + return update(null, {saveDev: true}).then(function() { + expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.2'); }); }); }); @@ -464,20 +330,17 @@ describe('bower update', function() { 'bower.json': { name: 'test', dependencies: { - package: gitPackage.path + '#*' + underscore: '*' } } }); return install().then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#*'); + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('*'); - return update(null, { - save: true - }).then(function() { - var version = tempDir.readJson('bower.json').dependencies.package.replace(gitPackage.path + '#~', ''); - version = semver.gte(version, '1.0.1'); + return update(null, {save: true}).then(function() { + var version = semver.gte(tempDir.readJson('bower.json').dependencies.underscore.replace('~', ''), '1.8.3'); expect(version).to.be.ok(); }); }); @@ -488,29 +351,29 @@ describe('bower update', function() { 'bower.json': { name: 'test', dependencies: { - package: gitPackage.path + '#~1.0.0', - package2: gitPackage2.path + '#~2.0.0' + underscore: '~1.5.0', + lodash: '~1.0.0' }, devDependencies: { - package3: gitPackage3.path + '#~3.0.0' + neat: '~1.5.0' }, } }); return install().then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.0'); - expect(tempDir.readJson('bower.json').dependencies.package2).to.equal(gitPackage2.path + '#~2.0.0'); - expect(tempDir.readJson('bower.json').devDependencies.package3).to.equal(gitPackage3.path + '#~3.0.0'); + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.0'); + expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.0.0'); + expect(tempDir.readJson('bower.json').devDependencies.neat).to.equal('~1.5.0'); return update(null, { save: true }).then(function() { // Normal deps should have changed - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.1'); - expect(tempDir.readJson('bower.json').dependencies.package2).to.equal(gitPackage2.path + '#~2.0.1'); + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.2'); + expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.0.2'); // Dev deps should not have changed - expect(tempDir.readJson('bower.json').devDependencies.package3).to.equal(gitPackage3.path + '#~3.0.0'); + expect(tempDir.readJson('bower.json').devDependencies.neat).to.equal('~1.5.0'); }); }); }); @@ -520,29 +383,29 @@ describe('bower update', function() { 'bower.json': { name: 'test', dependencies: { - package: gitPackage.path + '#~1.0.0' + neat: '~1.5.0' }, devDependencies: { - package2: gitPackage2.path + '#~2.0.0', - package3: gitPackage3.path + '#~3.0.0' - }, + underscore: '~1.5.0', + lodash: '~1.0.0' + } } }); return install().then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.0'); - expect(tempDir.readJson('bower.json').devDependencies.package2).to.equal(gitPackage2.path + '#~2.0.0'); - expect(tempDir.readJson('bower.json').devDependencies.package3).to.equal(gitPackage3.path + '#~3.0.0'); + expect(tempDir.readJson('bower.json').dependencies.neat).to.equal('~1.5.0'); + expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.0'); + expect(tempDir.readJson('bower.json').devDependencies.lodash).to.equal('~1.0.0'); return update(null, { saveDev: true }).then(function() { // Normal deps should not have changed - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.0'); + expect(tempDir.readJson('bower.json').dependencies.neat).to.equal('~1.5.0'); // Dev deps should have changed - expect(tempDir.readJson('bower.json').devDependencies.package2).to.equal(gitPackage2.path + '#~2.0.1'); - expect(tempDir.readJson('bower.json').devDependencies.package3).to.equal(gitPackage3.path + '#~3.0.1'); + expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.2'); + expect(tempDir.readJson('bower.json').devDependencies.lodash).to.equal('~1.0.2'); }); }); }); @@ -552,19 +415,17 @@ describe('bower update', function() { 'bower.json': { name: 'test', dependencies: { - package: gitPackage.path + '#^0.1.0' + underscore: '^0.1.0' } } }); return install().then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#^0.1.0'); + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('^0.1.0'); - return update(null, { - save: true - }).then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~0.1.1'); + return update(null, {save: true}).then(function() { + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~0.1.1'); }); }); }); @@ -574,19 +435,17 @@ describe('bower update', function() { 'bower.json': { name: 'test', dependencies: { - package: gitPackage.path + '#^1.0.0' + lodash: '^1.0.0' } } }); return install().then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#^1.0.0'); + expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('^1.0.0'); - return update(null, { - save: true - }).then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#~1.0.1'); + return update(null, {save: true}).then(function() { + expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.3.1'); }); }); }); @@ -596,19 +455,17 @@ describe('bower update', function() { 'bower.json': { name: 'test', dependencies: { - package: gitPackage.path + '#1.0.0' + underscore: '1.5.0' } } }); return install().then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#1.0.0'); + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('1.5.0'); - return update(null, { - save: true - }).then(function() { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(gitPackage.path + '#1.0.0'); + return update(null, {save: true}).then(function() { + expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('1.5.0'); }); }); }); From 88758cd98c933cdfad724165066e477ed9745d75 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Dec 2015 21:33:45 +0100 Subject: [PATCH 0814/1021] Revert "Add `bower update --save` functionality" This reverts commit d2ba80e6e97b13483bf113514ec1e6d1b8f8a03f. --- lib/commands/update.js | 4 +- lib/core/Project.js | 21 ---- test/commands/update.js | 227 ++-------------------------------------- 3 files changed, 10 insertions(+), 242 deletions(-) diff --git a/lib/commands/update.js b/lib/commands/update.js index ed7972c12..9d2d65e97 100644 --- a/lib/commands/update.js +++ b/lib/commands/update.js @@ -23,9 +23,7 @@ update.readOptions = function (argv) { var options = cli.readOptions({ 'force-latest': { type: Boolean, shorthand: 'F' }, - 'production': { type: Boolean, shorthand: 'p' }, - 'save': { type: Boolean, shorthand: 'S' }, - 'save-dev': { type: Boolean, shorthand: 'D' } + 'production': { type: Boolean, shorthand: 'p' } }, argv); var names = options.argv.remain.slice(1); diff --git a/lib/core/Project.js b/lib/core/Project.js index f49b4612e..575281a31 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -197,27 +197,6 @@ Project.prototype.update = function (names, options) { return that._manager.install(that._json); }) .then(function (installed) { - if (that._options.save || that._options.saveDev) { - // Cycle through the specified endpoints - targets.forEach(function (target) { - // Abort if current and new version are identical - if (target.target === target.pkgMeta.version) { - return false; - } - - var jsonEndpoint = endpointParser.decomposed2json(target); - // Bower uses the ~ range specifier for new installs - jsonEndpoint[target.name] = '~' + target.pkgMeta.version; - - if (that._options.saveDev && mout.object.has(that._json, 'devDependencies.' + target.name)) { - that._json.devDependencies = mout.object.mixIn(that._json.devDependencies || {}, jsonEndpoint); - } - - if (that._options.save && mout.object.has(that._json, 'dependencies.' + target.name)) { - that._json.dependencies = mout.object.mixIn(that._json.dependencies || {}, jsonEndpoint); - } - }); - } // Save JSON, might contain changes to resolutions return that.saveJson() .then(function () { diff --git a/test/commands/update.js b/test/commands/update.js index 31750775b..7e2d31e91 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -1,6 +1,5 @@ var expect = require('expect.js'); var object = require('mout').object; -var semver = require('semver'); var helpers = require('../helpers'); var updateCmd = helpers.command('update'); @@ -43,14 +42,16 @@ describe('bower update', function () { } }).prepare(); - var update = function(packages, options, config) { + var updateLogger = function(packages, options, config) { config = object.merge(config || {}, { cwd: tempDir.path }); - var logger = commands.update( - packages, options, config - ); + return commands.update(packages, options, config); + }; + + var update = function(packages, options, config) { + var logger = updateLogger(packages, options, config); return helpers.expectEvent(logger, 'end'); }; @@ -68,15 +69,8 @@ describe('bower update', function () { }; it('correctly reads arguments', function() { - expect(updateCmd.readOptions(['jquery', '-F', '-p', '-S', '-D'])) - .to.eql([ - ['jquery'], { - forceLatest: true, - production: true, - save: true, - saveDev: true - } - ]); + expect(updateCmd.readOptions(['jquery', '-F', '-p'])) + .to.eql([['jquery'], { forceLatest: true, production: true }]); }); it('install missing packages', function() { @@ -267,210 +261,7 @@ describe('bower update', function () { }); }); - it('doesn\'t update extraneous packages', function () { - tempDir.prepare({ - 'bower.json': { - name: 'test' - } - }); - - return install(['underscore#1.5.0']).then(function() { - - expect(tempDir.readJson('bower_components/underscore/package.json').version).to.equal('1.5.0'); - - return update(null, {save: true}).then(function() { - expect(tempDir.readJson('bower_components/underscore/package.json').version).to.equal('1.5.0'); - expect(tempDir.readJson('bower.json')).to.not.have.property('dependencies'); - }); - }); - }); - - it('updates bower.json dep after updating with --save flag', function() { - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - underscore: '~1.5.0' - } - } - }); - - return install().then(function() { - - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.0'); - - return update(null, {save: true}).then(function() { - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.2'); - }); - }); - }); - - it('updates bower.json dev dep after updating with --save-dev flag', function() { - tempDir.prepare({ - 'bower.json': { - name: 'test', - devDependencies: { - underscore: '~1.5.0' - } - } - }); - - return install().then(function() { - - expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.0'); - - return update(null, {saveDev: true}).then(function() { - expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.2'); - }); - }); - }); - - it('replaces "any" range with latest version', function() { - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - underscore: '*' - } - } - }); - - return install().then(function() { - - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('*'); - - return update(null, {save: true}).then(function() { - var version = semver.gte(tempDir.readJson('bower.json').dependencies.underscore.replace('~', ''), '1.8.3'); - expect(version).to.be.ok(); - }); - }); - }); - - it('updates multiple components in bower.json after updating with --save flag', function() { - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - underscore: '~1.5.0', - lodash: '~1.0.0' - }, - devDependencies: { - neat: '~1.5.0' - }, - } - }); - - return install().then(function() { - - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.0'); - expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.0.0'); - expect(tempDir.readJson('bower.json').devDependencies.neat).to.equal('~1.5.0'); - - return update(null, { - save: true - }).then(function() { - // Normal deps should have changed - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~1.5.2'); - expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.0.2'); - // Dev deps should not have changed - expect(tempDir.readJson('bower.json').devDependencies.neat).to.equal('~1.5.0'); - }); - }); - }); - - it('updates multiple components in bower.json after updating with --save-dev flag', function() { - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - neat: '~1.5.0' - }, - devDependencies: { - underscore: '~1.5.0', - lodash: '~1.0.0' - } - } - }); - - return install().then(function() { - - expect(tempDir.readJson('bower.json').dependencies.neat).to.equal('~1.5.0'); - expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.0'); - expect(tempDir.readJson('bower.json').devDependencies.lodash).to.equal('~1.0.0'); - - return update(null, { - saveDev: true - }).then(function() { - // Normal deps should not have changed - expect(tempDir.readJson('bower.json').dependencies.neat).to.equal('~1.5.0'); - // Dev deps should have changed - expect(tempDir.readJson('bower.json').devDependencies.underscore).to.equal('~1.5.2'); - expect(tempDir.readJson('bower.json').devDependencies.lodash).to.equal('~1.0.2'); - }); - }); - }); - - it('correctly interprets semver range specifier pre-1.0', function() { - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - underscore: '^0.1.0' - } - } - }); - - return install().then(function() { - - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('^0.1.0'); - - return update(null, {save: true}).then(function() { - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('~0.1.1'); - }); - }); - }); - - it('correctly interprets semver range specifier post-1.0', function() { - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - lodash: '^1.0.0' - } - } - }); - - return install().then(function() { - - expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('^1.0.0'); - - return update(null, {save: true}).then(function() { - expect(tempDir.readJson('bower.json').dependencies.lodash).to.equal('~1.3.1'); - }); - }); - }); - - it('doesn\'t update bower.json if versions are identical', function() { - tempDir.prepare({ - 'bower.json': { - name: 'test', - dependencies: { - underscore: '1.5.0' - } - } - }); - - return install().then(function() { - - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('1.5.0'); - - return update(null, {save: true}).then(function() { - expect(tempDir.readJson('bower.json').dependencies.underscore).to.equal('1.5.0'); - }); - }); - }); - - it('does not install ignored dependencies when updating a package', function() { + it('does not install ignored dependencies when updating a package', function () { var package3 = new helpers.TempDir({ 'bower.json': { name: 'package3' From baf8f7bf6b0775a9536b001f1a8aa389a9a7f330 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Dec 2015 21:37:08 +0100 Subject: [PATCH 0815/1021] Fix missing parenthesis --- test/commands/install.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/commands/install.js b/test/commands/install.js index 0e035e1f9..e619819de 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -430,9 +430,10 @@ describe('bower install', function() { undefined, { proxy: 'http://dummy.local/' } ]) - .fail(function(error) { - expect(error.message).to.equal('Status code of 500'); - done(); + .fail(function(error) { + expect(error.message).to.equal('Status code of 500'); + done(); + }); }); it('errors if the components directory is not a directory', function() { From 75e366137101018b75c4402f3427c9dc1b0461c2 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Dec 2015 21:42:34 +0100 Subject: [PATCH 0816/1021] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e8f71694..ea5800427 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## 1.8.0 +- Rollback "Add `bower update --save` functionality", it causes issues and needs more testing - Better formatting of help messages https://github.com/bower/bower/commit/de3e1089da80f47ea3667c5ab80d301cddfd8c3e - Add help menu for update --save and update --save-dev https://github.com/bower/bower/commit/612aaa88eb4d4b268b2d8665c338ac086af3a5b0 From e168c894a2a810b2e89c21320914029193a82c42 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Dec 2015 21:43:21 +0100 Subject: [PATCH 0817/1021] Bump to 1.7.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c92ccfcd7..d8cb737e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.7.0", + "version": "1.7.1", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 3ead440c7c3c19157cd1317cec2a024d0d913bc7 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Dec 2015 21:50:50 +0100 Subject: [PATCH 0818/1021] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea5800427..9886d1c7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 1.8.0 +## 1.7.1 - 2015-12-11 - Rollback "Add `bower update --save` functionality", it causes issues and needs more testing - Better formatting of help messages https://github.com/bower/bower/commit/de3e1089da80f47ea3667c5ab80d301cddfd8c3e From 87cf578ba82e3d0eca4e5869469be85c4669cd23 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Dec 2015 21:51:30 +0100 Subject: [PATCH 0819/1021] Update changelog --- CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9886d1c7f..77fbd57c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,11 @@ ## 1.7.1 - 2015-12-11 - Rollback "Add `bower update --save` functionality", it causes issues and needs more testing -- Better formatting of help messages https://github.com/bower/bower/commit/de3e1089da80f47ea3667c5ab80d301cddfd8c3e -- Add help menu for update --save and update --save-dev https://github.com/bower/bower/commit/612aaa88eb4d4b268b2d8665c338ac086af3a5b0 +- Fix backward-compatibility of `bower search --json` ([#2066](https://github.com/bower/bower/issues/2066)) +- Ignore prerelease versions from `bower info` output +- Update update-notifier to 0.6.0 +- Better formatting of help messages (https://github.com/bower/bower/commit/de3e1089da80f47ea3667c5ab80d301cddfd8c3e) +- Add help menu for update `--save` and `update --save-dev` (https://github.com/bower/bower/commit/612aaa88eb4d4b268b2d8665c338ac086af3a5b0) ## 1.7.0 - 2015-12-07 From d1ae0b1982c2db0e66a2b78110429c4979d63068 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Dec 2015 21:53:00 +0100 Subject: [PATCH 0820/1021] Change entry in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77fbd57c5..0f3f5c27c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ - Rollback "Add `bower update --save` functionality", it causes issues and needs more testing - Fix backward-compatibility of `bower search --json` ([#2066](https://github.com/bower/bower/issues/2066)) -- Ignore prerelease versions from `bower info` output +- Ignore prerelease versions from `bower list` output - Update update-notifier to 0.6.0 - Better formatting of help messages (https://github.com/bower/bower/commit/de3e1089da80f47ea3667c5ab80d301cddfd8c3e) - Add help menu for update `--save` and `update --save-dev` (https://github.com/bower/bower/commit/612aaa88eb4d4b268b2d8665c338ac086af3a5b0) From 8b2fad32f642a75560527c9f8aaaed91906846c3 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 11 Dec 2015 21:53:31 +0100 Subject: [PATCH 0821/1021] Revert "Change entry in changelog" This reverts commit d1ae0b1982c2db0e66a2b78110429c4979d63068. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f3f5c27c..77fbd57c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ - Rollback "Add `bower update --save` functionality", it causes issues and needs more testing - Fix backward-compatibility of `bower search --json` ([#2066](https://github.com/bower/bower/issues/2066)) -- Ignore prerelease versions from `bower list` output +- Ignore prerelease versions from `bower info` output - Update update-notifier to 0.6.0 - Better formatting of help messages (https://github.com/bower/bower/commit/de3e1089da80f47ea3667c5ab80d301cddfd8c3e) - Add help menu for update `--save` and `update --save-dev` (https://github.com/bower/bower/commit/612aaa88eb4d4b268b2d8665c338ac086af3a5b0) From cdf45239f4853ce7d9ccd6b146ea84194bcf52fa Mon Sep 17 00:00:00 2001 From: Utsav Shah Date: Tue, 8 Dec 2015 14:11:54 -0600 Subject: [PATCH 0822/1021] Decompress gzip files Update request lib --- lib/util/download.js | 3 ++- package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/util/download.js b/lib/util/download.js index 3ee428f7c..7fede62f5 100644 --- a/lib/util/download.js +++ b/lib/util/download.js @@ -26,7 +26,8 @@ function download(url, file, options) { minTimeout: 1000, maxTimeout: 35000, randomize: true, - progressDelay: progressDelay + progressDelay: progressDelay, + gzip: true }, options || {}); // Retry on network errors diff --git a/package.json b/package.json index d8cb737e6..dbcb81bcd 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "p-throttler": "0.1.1", "promptly": "0.2.0", "q": "^1.1.2", - "request": "2.53.0", + "request": "2.67.0", "request-progress": "0.3.1", "retry": "0.6.1", "rimraf": "^2.2.8", From 4255d7d4a8d37e10e02056de6a6bb86ff230ac76 Mon Sep 17 00:00:00 2001 From: Utsav Shah Date: Sat, 12 Dec 2015 18:06:37 -0600 Subject: [PATCH 0823/1021] Add tests for decoding gzipped files --- test/assets/test-gz.txt | Bin 0 -> 48 bytes test/assets/test-gz.txt.gz | Bin 0 -> 48 bytes test/util/download.js | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 test/assets/test-gz.txt create mode 100644 test/assets/test-gz.txt.gz diff --git a/test/assets/test-gz.txt b/test/assets/test-gz.txt new file mode 100644 index 0000000000000000000000000000000000000000..957ceb93a05e1fb1fa7aa6d31471904c9ad9b28a GIT binary patch literal 48 zcmb2|=HU1hmJ!ClT#%TYotU1gn_i_?Qc=S2+2icVli?ia^-p;QK4D_Gdsn2Emw|x+ E0JDS<%>V!Z literal 0 HcmV?d00001 diff --git a/test/assets/test-gz.txt.gz b/test/assets/test-gz.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..957ceb93a05e1fb1fa7aa6d31471904c9ad9b28a GIT binary patch literal 48 zcmb2|=HU1hmJ!ClT#%TYotU1gn_i_?Qc=S2+2icVli?ia^-p;QK4D_Gdsn2Emw|x+ E0JDS<%>V!Z literal 0 HcmV?d00001 diff --git a/test/util/download.js b/test/util/download.js index ff5dd7d7a..a8176627a 100644 --- a/test/util/download.js +++ b/test/util/download.js @@ -22,7 +22,7 @@ describe('download', function () { nock('http://bower.io', opts.nockOpts) ); - download('http://bower.io/package.tar.gz', destination, opts.downloadOpts) + download(opts.sourceUrl || 'http://bower.io/package.tar.gz', opts.destinationPath || destination, opts.downloadOpts) .then(function (result) { if (opts.expect) { opts.expect(result); @@ -174,4 +174,36 @@ describe('download', function () { } }); }); + + describe('gzipped files', function () { + + function testGzip(sourceFilename) { + var sourceFile = path.resolve(__dirname, '../assets/' + sourceFilename); + var destinationPath = tempDir.getPath(sourceFilename); + + return downloadTest({ + response: function(nock) { + nock + .get('/' + sourceFilename) + .replyWithFile(200, sourceFile, { + 'Content-Encoding' : 'gzip' + }); + }, + expect: function() { + expect(fs.readFileSync(destinationPath, 'ascii')) + .to.be('Hello World!\n'); + }, + sourceUrl: 'http://bower.io/' + sourceFilename, + destinationPath: destinationPath + }); + } + + it('correctly decodes gzipped files without gz extension', function () { + return testGzip('test-gz.txt'); + }); + + it('correctly decodes gzipped files with gz extension', function () { + return testGzip('test-gz.txt.gz'); + }); + }); }); From b1ba9be7f63c50df2db2b8e194ab5c8089118bd1 Mon Sep 17 00:00:00 2001 From: Iain Monro Date: Mon, 14 Dec 2015 16:58:02 +0000 Subject: [PATCH 0824/1021] Fix name clashes in package extraction Prevent extraction failing if a package archive contains a file with the same name as the archive, or a single directory with a subdirectory with the same name. --- lib/util/extract.js | 84 +++++++++++++++++++++------------------- test/commands/install.js | 72 ++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 39 deletions(-) diff --git a/lib/util/extract.js b/lib/util/extract.js index bc7a80bf1..1f3b4ec9b 100644 --- a/lib/util/extract.js +++ b/lib/util/extract.js @@ -9,6 +9,7 @@ var junk = require('junk'); var createError = require('./createError'); var createWriteStream = require('fs-write-stream-atomic'); var destroy = require('destroy'); +var tmp = require('tmp'); // This forces the default chunk size to something small in an attempt // to avoid issue #314 @@ -164,15 +165,11 @@ function isSingleDir(dir) { }); } -function moveSingleDirContents(dir) { - var destDir = path.dirname(dir); - - return Q.nfcall(fs.readdir, dir) - .then(function (files) { - var promises; - - promises = files.map(function (file) { - var src = path.join(dir, file); +function moveDirectory(srcDir, destDir) { + return Q.nfcall(fs.readdir, srcDir) + .then(function(files) { + var promises = files.map(function (file) { + var src = path.join(srcDir, file); var dst = path.join(destDir, file); return Q.nfcall(fs.rename, src, dst); @@ -181,7 +178,7 @@ function moveSingleDirContents(dir) { return Q.all(promises); }) .then(function () { - return Q.nfcall(fs.rmdir, dir); + return Q.nfcall(fs.rmdir, srcDir); }); } @@ -215,44 +212,53 @@ function extract(src, dst, opts) { return Q.reject(createError('File ' + src + ' is not a known archive', 'ENOTARCHIVE')); } - // Check archive file size - promise = Q.nfcall(fs.stat, src) - .then(function (stat) { - if (stat.size <= 8) { - throw createError('File ' + src + ' is an invalid archive', 'ENOTARCHIVE'); - } - - // Extract archive - return extractor(src, dst); - }); - - // TODO: There's an issue here if the src and dst are the same and - // The zip name is the same as some of the zip file contents - // Maybe create a temp directory inside dst, unzip it there, - // unlink zip and then move contents + // Extract to a temporary directory in case of file name clashes + return Q.nfcall(tmp.dir, { + template: dst + '-XXXXXX', + mode: 0777 & ~process.umask() + }).then(function (tempDir) { + // nfcall may return multiple callback arguments as an array + return Array.isArray(tempDir) ? tempDir[0] : tempDir; + }).then(function (tempDir) { + + // Check archive file size + promise = Q.nfcall(fs.stat, src) + .then(function (stat) { + if (stat.size <= 8) { + throw createError('File ' + src + ' is an invalid archive', 'ENOTARCHIVE'); + } - // Remove archive - if (!opts.keepArchive) { - promise = promise - .then(function () { - return Q.nfcall(fs.unlink, src); + // Extract archive + return extractor(src, tempDir); }); - } - // Move contents if a single directory was extracted - if (!opts.keepStructure) { + // Remove archive + if (!opts.keepArchive) { + promise = promise + .then(function () { + return Q.nfcall(fs.unlink, src); + }); + } + + // Move contents from the temporary directory + // If the contents are a single directory (and we're not preserving structure), + // move its contents directly instead. promise = promise .then(function () { - return isSingleDir(dst); + return isSingleDir(tempDir); }) .then(function (singleDir) { - return singleDir ? moveSingleDirContents(singleDir) : null; + if (singleDir && !opts.keepStructure) { + return moveDirectory(singleDir, dst); + } else { + return moveDirectory(tempDir, dst); + } }); - } - // Resolve promise to the dst dir - return promise.then(function () { - return dst; + // Resolve promise to the dst dir + return promise.then(function () { + return dst; + }); }); } diff --git a/test/commands/install.js b/test/commands/install.js index e619819de..abc8b0347 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -3,6 +3,9 @@ var path = require('path'); var helpers = require('../helpers'); var nock = require('nock'); var fs = require('../../lib/util/fs'); +var tar = require('tar-fs'); +var destroy = require('destroy'); +var Q = require('q'); describe('bower install', function() { @@ -447,4 +450,73 @@ describe('bower install', function() { expect(error.code).to.equal('ENOTDIR'); }); }); + + it('works if the package is a compressed single directory containing another directory with the same name', function() { + var mainPackageBaseName = path.basename(mainPackage.path); + var parentDir = path.dirname(mainPackage.path); + + // Setup the main package with a directory with the same name + var mainPackageFiles = {}; + mainPackageFiles[mainPackageBaseName + '/test.js'] = 'test'; + mainPackage.prepare(mainPackageFiles); + + // Create an archive containing the main package + var archiveDeferred = Q.defer(); + var archivePath = path.join(parentDir, mainPackageBaseName + ".tar") + var stream = tar.pack(parentDir, { entries: [mainPackageBaseName] }); + stream + .pipe(fs.createWriteStream(archivePath)) + .on('finish', function(result) { + destroy(stream); + archiveDeferred.resolve(result); + }); + + //// Attempt to install the package from the archive + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); + + return archiveDeferred.promise + .then(function() { + return helpers.run(install, [[archivePath]]); + }) + .then(function() { + expect(tempDir.read(path.join('bower_components', 'package', mainPackageBaseName, "test.js"))).to.contain('test'); + }); + }); + + it('works if the package is an archive containing a file with an identical name', function() { + var parentDir = path.dirname(mainPackage.path); + + mainPackage.prepare({ + 'package.tar': 'test' + }); + + var archiveDeferred = Q.defer(); + var archivePath = path.join(parentDir, "package.tar") + var stream = tar.pack(mainPackage.path); + stream + .pipe(fs.createWriteStream(archivePath)) + .on('finish', function(result) { + destroy(stream); + archiveDeferred.resolve(result); + }); + + + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); + + return archiveDeferred.promise + .then(function() { + return helpers.run(install, [[archivePath]]); + }) + .then(function() { + expect(tempDir.read(path.join('bower_components', 'package', "package.tar"))).to.contain('test'); + }); + }); }); From d3ab3c1fa77d502dcfb15161ecee5f6b0153af03 Mon Sep 17 00:00:00 2001 From: Rob Simpson Date: Mon, 14 Dec 2015 12:57:24 -0500 Subject: [PATCH 0825/1021] remove freenode as support option --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 714c339ed..8f13ca7ee 100644 --- a/README.md +++ b/README.md @@ -103,8 +103,6 @@ Bower can be configured using JSON in a `.bowerrc` file. Read over available opt * [Discord chat](https://discord.gg/0fFM7QF0KpZRh2cY) * [StackOverflow](http://stackoverflow.com/questions/tagged/bower) * [Mailinglist](http://groups.google.com/group/twitter-bower) - twitter-bower@googlegroups.com -* [\#bower](http://webchat.freenode.net/?channels=bower) on Freenode - ## Contributing From 6c3b7dbf58be35aabb24c13b70bcc5c3254de97b Mon Sep 17 00:00:00 2001 From: Roger Rodriguez Texido Date: Mon, 14 Dec 2015 17:12:30 -0500 Subject: [PATCH 0826/1021] Fixed typo. --- lib/core/resolverFactory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index 79463b5f1..e486c161a 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -25,7 +25,7 @@ function getConstructor(decEndpoint, options, registryClient) { // Below we try a series of async tests to guess the type of resolver to use // If a step was unable to guess the resolver, it returns undefined - // If a step can guess the resolver, it returns with construcotor of resolver + // If a step can guess the resolver, it returns with constructor of resolver var promise = Q.resolve(); From 3cf597fccf78a35c1f1fd288a8386cee27c6358c Mon Sep 17 00:00:00 2001 From: Iain Monro Date: Tue, 15 Dec 2015 15:32:13 +0000 Subject: [PATCH 0827/1021] Fix jshint errors Add missing semicolons to test file. --- test/commands/install.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/commands/install.js b/test/commands/install.js index abc8b0347..f4a370240 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -462,7 +462,7 @@ describe('bower install', function() { // Create an archive containing the main package var archiveDeferred = Q.defer(); - var archivePath = path.join(parentDir, mainPackageBaseName + ".tar") + var archivePath = path.join(parentDir, mainPackageBaseName + '.tar'); var stream = tar.pack(parentDir, { entries: [mainPackageBaseName] }); stream .pipe(fs.createWriteStream(archivePath)) @@ -483,7 +483,7 @@ describe('bower install', function() { return helpers.run(install, [[archivePath]]); }) .then(function() { - expect(tempDir.read(path.join('bower_components', 'package', mainPackageBaseName, "test.js"))).to.contain('test'); + expect(tempDir.read(path.join('bower_components', 'package', mainPackageBaseName, 'test.js'))).to.contain('test'); }); }); @@ -495,7 +495,7 @@ describe('bower install', function() { }); var archiveDeferred = Q.defer(); - var archivePath = path.join(parentDir, "package.tar") + var archivePath = path.join(parentDir, 'package.tar'); var stream = tar.pack(mainPackage.path); stream .pipe(fs.createWriteStream(archivePath)) @@ -516,7 +516,7 @@ describe('bower install', function() { return helpers.run(install, [[archivePath]]); }) .then(function() { - expect(tempDir.read(path.join('bower_components', 'package', "package.tar"))).to.contain('test'); + expect(tempDir.read(path.join('bower_components', 'package', 'package.tar'))).to.contain('test'); }); }); }); From 2b31f6c07aaafce637be1dcc095714d5b7f9e4b2 Mon Sep 17 00:00:00 2001 From: Mithun Ayachit Date: Thu, 17 Dec 2015 20:38:48 -0600 Subject: [PATCH 0828/1021] Ignore hook scripts for environment variable expansion --- packages/bower-config/lib/util/expand.js | 9 +++++++++ .../test/assets/env-variables-values/.bowerrc | 3 +++ packages/bower-config/test/test.js | 1 + 3 files changed, 13 insertions(+) diff --git a/packages/bower-config/lib/util/expand.js b/packages/bower-config/lib/util/expand.js index 929b4b10c..6dbeb2cbb 100644 --- a/packages/bower-config/lib/util/expand.js +++ b/packages/bower-config/lib/util/expand.js @@ -45,11 +45,20 @@ function envReplace(config) { var envReplaced = {}; object.forOwn(config, function (value, key) { + // Ignore null values if (value == null) { return; } + // Ignore 'scripts' + // These hooks run within the shell + // environment variable expansion is not required + if ( key === 'scripts' && lang.isPlainObject(value) ){ + envReplaced[key] = value; + return; + } + // Perform variable replacements based on var type if ( lang.isPlainObject(value) ) { envReplaced[key] = envReplace(value); diff --git a/packages/bower-config/test/assets/env-variables-values/.bowerrc b/packages/bower-config/test/assets/env-variables-values/.bowerrc index 96948d18e..dae163d47 100644 --- a/packages/bower-config/test/assets/env-variables-values/.bowerrc +++ b/packages/bower-config/test/assets/env-variables-values/.bowerrc @@ -1,4 +1,7 @@ { + "scripts" : { + "postinstall" : "${_myshellvar}" + }, "storage" : { "packages" : "${_BOWERRC_MY_PACKAGES}", "registry" : "~/.bower-test/registry" diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index c315ef601..e29a5e6e5 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -228,6 +228,7 @@ describe('Allow ${ENV} variables in .bowerrc', function() { var config = require('../lib/Config').read('test/assets/env-variables-values'); assert.equal('a', config.storage.packages); assert.equal('/tmp/b', config.tmp); + assert.equal('${_myshellvar}', config.scripts.postinstall); }); }); From 848e401efd2d9ae9f5e25b5087b544d66044a5d5 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 21 Dec 2015 05:18:45 +0100 Subject: [PATCH 0829/1021] Link back to invitation form --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f13ca7ee..7a1ee6c65 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bower - A package manager for the web -> Bower needs resources for its maintenance. Please see [our blog](http://bower.io/blog/) if you think you can help. +> Bower needs resources for its maintenance. Please fill [this form](https://docs.google.com/forms/d/1i-Opb-uPdqUBBZQSbngv3Y3bfolG1gbBvtRLfxMnzRE/viewform?c=0&w=1) if you think you can help. [![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)](https://ci.appveyor.com/project/sheerun/bower/history) From db087dfe13f2bf97d130ea3476dc8a06b322e16b Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 21 Dec 2015 06:13:59 +0100 Subject: [PATCH 0830/1021] Log-level is actually loglevel, closes #2112 --- templates/json/help.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/json/help.json b/templates/json/help.json index 21a5d7a27..6525c9b08 100644 --- a/templates/json/help.json +++ b/templates/json/help.json @@ -34,7 +34,7 @@ }, { "shorthand": "-l", - "flag": "--log-level", + "flag": "--loglevel", "description": "What level of logs to report" }, { From daa5b8ddf98f0c95ccaa10a41535b894e0b7bd7b Mon Sep 17 00:00:00 2001 From: Kevin H Date: Mon, 28 Dec 2015 21:27:13 -0800 Subject: [PATCH 0831/1021] Added the --force documentation to the --help command --- templates/json/help-install.json | 5 +++++ templates/json/help-register.json | 5 +++++ templates/json/help-uninstall.json | 5 +++++ templates/json/help-unregister.json | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/templates/json/help-install.json b/templates/json/help-install.json index d150801cd..45e665267 100644 --- a/templates/json/help-install.json +++ b/templates/json/help-install.json @@ -11,6 +11,11 @@ "flag": "--force-latest", "description": "Force latest version on conflict" }, + { + "shorthand": "-f", + "flag": "--force", + "description": "If dependencies are installed, it reinstalls all installed components. It also forces installation even when there are non-bower directories with the same name in the components directory. Also bypasses the cache and overwrites to the cache anyway." + }, { "shorthand": "-h", "flag": "--help", diff --git a/templates/json/help-register.json b/templates/json/help-register.json index 8e01ce47e..03912e525 100644 --- a/templates/json/help-register.json +++ b/templates/json/help-register.json @@ -5,6 +5,11 @@ "register []" ], "options": [ + { + "shorthand": "-f", + "flag": "--force", + "description": "Bypasses confirmation. Bower login is still needed." + }, { "shorthand": "-h", "flag": "--help", diff --git a/templates/json/help-uninstall.json b/templates/json/help-uninstall.json index 318f8999a..9d39a3c1f 100644 --- a/templates/json/help-uninstall.json +++ b/templates/json/help-uninstall.json @@ -5,6 +5,11 @@ "uninstall [ ..] []" ], "options": [ + { + "shorthand": "-f", + "flag": "--force", + "description": "Continues uninstallation even after a dependency conflict" + }, { "shorthand": "-h", "flag": "--help", diff --git a/templates/json/help-unregister.json b/templates/json/help-unregister.json index f6c311645..c2d0364ec 100644 --- a/templates/json/help-unregister.json +++ b/templates/json/help-unregister.json @@ -5,6 +5,11 @@ "unregister []" ], "options": [ + { + "shorthand": "-f", + "flag": "--force", + "description": "Bypasses confirmation. Bower login is still needed." + }, { "shorthand": "-h", "flag": "--help", From d8f166a9339a22f3991707058f45f532b98db9e3 Mon Sep 17 00:00:00 2001 From: Sam Saccone Date: Wed, 30 Dec 2015 16:22:54 -0800 Subject: [PATCH 0832/1021] Lock fs-write-steam-atomic to 1.0.5 context: https://github.com/bower/bower/issues/2118#issuecomment-168097858 Fixes #2118 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dbcb81bcd..7f8defeda 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "configstore": "^0.3.2", "decompress-zip": "^0.1.0", "destroy": "^1.0.3", - "fs-write-stream-atomic": "^1.0.5", + "fs-write-stream-atomic": "1.0.5", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", "github": "^0.2.3", From ed881e3f2989e56cac5050ebb11ffec6cbf6725b Mon Sep 17 00:00:00 2001 From: Raja Sekar Date: Mon, 21 Dec 2015 18:26:46 +0530 Subject: [PATCH 0833/1021] Display login message when user login via normal and 2 factor auth mode. Displaying info message when user login via bower login Login message added for 2 factor authentication also Fix unreachable code Fix code quality issues --- lib/commands/install.js | 5 +++++ lib/commands/login.js | 4 ++-- lib/util/git.js | 14 ++++++++++++++ test/util/git.js | 8 ++++++++ test/util/index.js | 1 + 5 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 lib/util/git.js create mode 100644 test/util/git.js diff --git a/lib/commands/install.js b/lib/commands/install.js index f934b63e5..af2c1f1d2 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -2,8 +2,13 @@ var endpointParser = require('bower-endpoint-parser'); var Project = require('../core/Project'); var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); +var hasGit = require('../util/git')(); +var createError = require('../util/createError'); function install(logger, endpoints, options, config) { + if (!hasGit) { + throw createError('Git is not installed or not in the right PATH', 'ENOGIT'); + } var project; var decEndpoints; var tracker; diff --git a/lib/commands/login.js b/lib/commands/login.js index 2087efa9e..4a7777d03 100644 --- a/lib/commands/login.js +++ b/lib/commands/login.js @@ -63,7 +63,7 @@ function login(logger, options, config) { return promise.then(function (result) { configstore.set('accessToken', result.token); - + logger.info('EAUTH', 'Logged in as ' +configstore.get('username'), {}); return result; }, function (error) { var message; @@ -95,7 +95,7 @@ function login(logger, options, config) { }) .then(function (result) { configstore.set('accessToken', result.token); - + logger.info('EAUTH', 'Logged in as ' +configstore.get('username'), {}); return result; }, function () { logger.emit('error', createError(message, 'EAUTH')); diff --git a/lib/util/git.js b/lib/util/git.js new file mode 100644 index 000000000..a68dfc9cc --- /dev/null +++ b/lib/util/git.js @@ -0,0 +1,14 @@ +var which = require('which'); + +// Check if git is installed +function hasGit() { + var checkGit; + try { + which.sync('git'); + checkGit = true; + } catch (ex) { + checkGit = false; + } + return checkGit; +} +module.exports = hasGit; diff --git a/test/util/git.js b/test/util/git.js new file mode 100644 index 000000000..21f0beffc --- /dev/null +++ b/test/util/git.js @@ -0,0 +1,8 @@ +var expect = require('expect.js'); +var hasGit = require('../../lib/util/git'); +describe('Git installation check', function () { + it('Git should be installed', function (done) { + expect(hasGit()).to.be(true); + done(); + }); +}); diff --git a/test/util/index.js b/test/util/index.js index ca9d3d464..fe0343f13 100644 --- a/test/util/index.js +++ b/test/util/index.js @@ -2,4 +2,5 @@ describe('util', function () { require('./removeIgnores'); require('./analytics'); require('./download'); + require('./git'); }); From afc4bfbd42d17113bf816666a2d08caff82e5f80 Mon Sep 17 00:00:00 2001 From: Alireza Bashiri Date: Mon, 4 Jan 2016 00:58:03 +0330 Subject: [PATCH 0834/1021] Revert "Display login message when user login via normal and 2 factor auth mode." This reverts commit ed881e3f2989e56cac5050ebb11ffec6cbf6725b. --- lib/commands/install.js | 5 ----- lib/commands/login.js | 4 ++-- lib/util/git.js | 14 -------------- test/util/git.js | 8 -------- test/util/index.js | 1 - 5 files changed, 2 insertions(+), 30 deletions(-) delete mode 100644 lib/util/git.js delete mode 100644 test/util/git.js diff --git a/lib/commands/install.js b/lib/commands/install.js index af2c1f1d2..f934b63e5 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -2,13 +2,8 @@ var endpointParser = require('bower-endpoint-parser'); var Project = require('../core/Project'); var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); -var hasGit = require('../util/git')(); -var createError = require('../util/createError'); function install(logger, endpoints, options, config) { - if (!hasGit) { - throw createError('Git is not installed or not in the right PATH', 'ENOGIT'); - } var project; var decEndpoints; var tracker; diff --git a/lib/commands/login.js b/lib/commands/login.js index 4a7777d03..2087efa9e 100644 --- a/lib/commands/login.js +++ b/lib/commands/login.js @@ -63,7 +63,7 @@ function login(logger, options, config) { return promise.then(function (result) { configstore.set('accessToken', result.token); - logger.info('EAUTH', 'Logged in as ' +configstore.get('username'), {}); + return result; }, function (error) { var message; @@ -95,7 +95,7 @@ function login(logger, options, config) { }) .then(function (result) { configstore.set('accessToken', result.token); - logger.info('EAUTH', 'Logged in as ' +configstore.get('username'), {}); + return result; }, function () { logger.emit('error', createError(message, 'EAUTH')); diff --git a/lib/util/git.js b/lib/util/git.js deleted file mode 100644 index a68dfc9cc..000000000 --- a/lib/util/git.js +++ /dev/null @@ -1,14 +0,0 @@ -var which = require('which'); - -// Check if git is installed -function hasGit() { - var checkGit; - try { - which.sync('git'); - checkGit = true; - } catch (ex) { - checkGit = false; - } - return checkGit; -} -module.exports = hasGit; diff --git a/test/util/git.js b/test/util/git.js deleted file mode 100644 index 21f0beffc..000000000 --- a/test/util/git.js +++ /dev/null @@ -1,8 +0,0 @@ -var expect = require('expect.js'); -var hasGit = require('../../lib/util/git'); -describe('Git installation check', function () { - it('Git should be installed', function (done) { - expect(hasGit()).to.be(true); - done(); - }); -}); diff --git a/test/util/index.js b/test/util/index.js index fe0343f13..ca9d3d464 100644 --- a/test/util/index.js +++ b/test/util/index.js @@ -2,5 +2,4 @@ describe('util', function () { require('./removeIgnores'); require('./analytics'); require('./download'); - require('./git'); }); From 2110148830f1850a09ab4de088ca3355003c2710 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Gr=C3=B6nke?= Date: Sat, 2 Jan 2016 16:43:25 +0100 Subject: [PATCH 0835/1021] support absolute path in .bowerrc 'directory' option fixes #1914 --- lib/core/Manager.js | 7 ++++--- lib/core/Project.js | 5 +++-- lib/util/isPathAbsolute.js | 5 +++++ test/commands/install.js | 32 ++++++++++++++++++++++++++++++++ test/util/index.js | 1 + test/util/isPathAbsolute.js | 14 ++++++++++++++ 6 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 lib/util/isPathAbsolute.js create mode 100644 test/util/isPathAbsolute.js diff --git a/lib/core/Manager.js b/lib/core/Manager.js index cb5a6ae58..8228caae1 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -10,6 +10,7 @@ var semver = require('../util/semver'); var copy = require('../util/copy'); var createError = require('../util/createError'); var scripts = require('./scripts'); +var isPathAbsolute = require('../util/isPathAbsolute'); function Manager(config, logger) { this._config = config; @@ -124,7 +125,7 @@ Manager.prototype.resolve = function () { Manager.prototype.preinstall = function (json) { var that = this; - var componentsDir = path.join(this._config.cwd, this._config.directory); + var componentsDir = isPathAbsolute(this._config.directory) ? this._config.directory : path.join(this._config.cwd, this._config.directory); // If nothing to install, skip the code bellow if (mout.lang.isEmpty(that._dissected)) { @@ -141,7 +142,7 @@ Manager.prototype.preinstall = function (json) { Manager.prototype.postinstall = function (json) { var that = this; - var componentsDir = path.join(this._config.cwd, this._config.directory); + var componentsDir = isPathAbsolute(this._config.directory) ? this._config.directory : path.join(this._config.cwd, this._config.directory); // If nothing to install, skip the code bellow if (mout.lang.isEmpty(that._dissected)) { @@ -171,7 +172,7 @@ Manager.prototype.install = function (json) { return Q.resolve({}); } - componentsDir = path.join(this._config.cwd, this._config.directory); + componentsDir = isPathAbsolute(this._config.directory) ? this._config.directory : path.join(this._config.cwd, this._config.directory); return Q.nfcall(mkdirp, componentsDir) .then(function () { var promises = []; diff --git a/lib/core/Project.js b/lib/core/Project.js index 575281a31..0db789039 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -13,6 +13,7 @@ var createError = require('../util/createError'); var readJson = require('../util/readJson'); var validLink = require('../util/validLink'); var scripts = require('./scripts'); +var isPathAbsolute = require('../util/isPathAbsolute'); function Project(config, logger) { this._config = config; @@ -607,7 +608,7 @@ Project.prototype._readInstalled = function () { // Gather all folders that are actual packages by // looking for the package metadata file - componentsDir = path.join(this._config.cwd, this._config.directory); + componentsDir = isPathAbsolute(this._config.directory) ? this._config.directory : path.join(this._config.cwd, this._config.directory); return this._installed = Q.nfcall(glob, '*/.bower.json', { cwd: componentsDir, dot: true @@ -648,7 +649,7 @@ Project.prototype._readLinks = function () { var that = this; // Read directory, looking for links - componentsDir = path.join(this._config.cwd, this._config.directory); + componentsDir = isPathAbsolute(this._config.directory) ? this._config.directory : path.join(this._config.cwd, this._config.directory); return Q.nfcall(fs.readdir, componentsDir) .then(function (filenames) { var promises; diff --git a/lib/util/isPathAbsolute.js b/lib/util/isPathAbsolute.js new file mode 100644 index 000000000..19a48edcf --- /dev/null +++ b/lib/util/isPathAbsolute.js @@ -0,0 +1,5 @@ +function isAbsolutePath(filePath) { + return filePath.charAt(0) === '/'; +} + +module.exports = isAbsolutePath; diff --git a/test/commands/install.js b/test/commands/install.js index f4a370240..566f82810 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -2,6 +2,7 @@ var expect = require('expect.js'); var path = require('path'); var helpers = require('../helpers'); var nock = require('nock'); +var rimraf = require('rimraf'); var fs = require('../../lib/util/fs'); var tar = require('tar-fs'); var destroy = require('destroy'); @@ -154,6 +155,37 @@ describe('bower install', function() { }); }); + it('.bowerrc directory can be an absolute path', function() { + mainPackage.prepare({ + foo: 'bar' + }); + + tempDir.prepare({ + '.bowerrc': { + directory: '/tmp/bower-absolute-destination-directory' + }, + 'bower.json': { + name: 'test', + dependencies: { + package: mainPackage.path + } + } + }); + + return helpers.run(install).then(function() { + expect(require('fs').readFileSync('/tmp/bower-absolute-destination-directory/package/foo', 'utf8').toString()).to.be('bar'); + var deferred = Q.defer(); + rimraf('/tmp/bower-absolute-destination-directory', function(err) { + if(err) { + deferred.reject(err); + } else { + deferred.resolve(); + } + }); + return deferred; + }); + }); + it('runs preinstall hook', function() { mainPackage.prepare(); diff --git a/test/util/index.js b/test/util/index.js index ca9d3d464..5f3930907 100644 --- a/test/util/index.js +++ b/test/util/index.js @@ -2,4 +2,5 @@ describe('util', function () { require('./removeIgnores'); require('./analytics'); require('./download'); + require('./isPathAbsolute'); }); diff --git a/test/util/isPathAbsolute.js b/test/util/isPathAbsolute.js new file mode 100644 index 000000000..68c578cb0 --- /dev/null +++ b/test/util/isPathAbsolute.js @@ -0,0 +1,14 @@ +var expect = require('expect.js'); +var isPathAbsolute = require('../../lib/util/isPathAbsolute'); + +describe('isPathAbsolute', function () { + + it('returns true when a path begins with /', function() { + expect(isPathAbsolute('/tmp/foo')).to.be.ok(); + }); + + it('returns false when a path does not begin with /', function() { + expect(isPathAbsolute('./tmp/foo')).to.not.be.ok(); + }); + +}); From 55d78f7928754132fdcc935a9891ed4a7c754438 Mon Sep 17 00:00:00 2001 From: Alireza Bashiri Date: Tue, 5 Jan 2016 02:24:08 +0330 Subject: [PATCH 0836/1021] Display the logged in user's name --- lib/commands/login.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/commands/login.js b/lib/commands/login.js index 2087efa9e..990ba088f 100644 --- a/lib/commands/login.js +++ b/lib/commands/login.js @@ -63,6 +63,7 @@ function login(logger, options, config) { return promise.then(function (result) { configstore.set('accessToken', result.token); + logger.info('EAUTH', 'Logged in as ' + configstore.get('username'), {}); return result; }, function (error) { @@ -95,6 +96,7 @@ function login(logger, options, config) { }) .then(function (result) { configstore.set('accessToken', result.token); + logger.info('EAUTH', 'Logged in as ' + configstore.get('username'), {}); return result; }, function () { From 5384fa54b1da3e6a00af59c5a693c07b54105578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Gr=C3=B6nke?= Date: Tue, 5 Jan 2016 04:08:22 +0100 Subject: [PATCH 0837/1021] refactor, address feedback and add more unit tests --- lib/commands/link.js | 3 +- lib/core/Manager.js | 10 +++--- lib/core/Project.js | 6 ++-- lib/util/isPathAbsolute.js | 4 +-- lib/util/relativeToBaseDir.js | 14 +++++++++ test/commands/link.js | 50 +++++++++++++++++++++++++++++ test/commands/uninstall.js | 35 +++++++++++++++++++++ test/util/createLink.js | 57 ++++++++++++++++++++++++++++++++++ test/util/index.js | 2 ++ test/util/relativeToBaseDir.js | 18 +++++++++++ 10 files changed, 188 insertions(+), 11 deletions(-) create mode 100644 lib/util/relativeToBaseDir.js create mode 100644 test/util/createLink.js create mode 100644 test/util/relativeToBaseDir.js diff --git a/lib/commands/link.js b/lib/commands/link.js index 6747db10a..7cf12cf8f 100644 --- a/lib/commands/link.js +++ b/lib/commands/link.js @@ -4,6 +4,7 @@ var Q = require('q'); var Project = require('../core/Project'); var createLink = require('../util/createLink'); var defaultConfig = require('../config'); +var relativeToBaseDir = require('../util/relativeToBaseDir'); function link(logger, name, localName, config) { if (name) { @@ -49,7 +50,7 @@ function linkTo(logger, name, localName, config) { localName = localName || name; src = path.join(config.storage.links, name); - dst = path.join(config.cwd, config.directory, localName); + dst = path.join(relativeToBaseDir(config.cwd)(config.directory), localName); // Delete destination folder if any return Q.nfcall(rimraf, dst) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 8228caae1..4577171b4 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -10,7 +10,7 @@ var semver = require('../util/semver'); var copy = require('../util/copy'); var createError = require('../util/createError'); var scripts = require('./scripts'); -var isPathAbsolute = require('../util/isPathAbsolute'); +var relativeToBaseDir = require('../util/relativeToBaseDir'); function Manager(config, logger) { this._config = config; @@ -125,7 +125,7 @@ Manager.prototype.resolve = function () { Manager.prototype.preinstall = function (json) { var that = this; - var componentsDir = isPathAbsolute(this._config.directory) ? this._config.directory : path.join(this._config.cwd, this._config.directory); + var componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory); // If nothing to install, skip the code bellow if (mout.lang.isEmpty(that._dissected)) { @@ -142,7 +142,7 @@ Manager.prototype.preinstall = function (json) { Manager.prototype.postinstall = function (json) { var that = this; - var componentsDir = isPathAbsolute(this._config.directory) ? this._config.directory : path.join(this._config.cwd, this._config.directory); + var componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory); // If nothing to install, skip the code bellow if (mout.lang.isEmpty(that._dissected)) { @@ -172,7 +172,7 @@ Manager.prototype.install = function (json) { return Q.resolve({}); } - componentsDir = isPathAbsolute(this._config.directory) ? this._config.directory : path.join(this._config.cwd, this._config.directory); + componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory); return Q.nfcall(mkdirp, componentsDir) .then(function () { var promises = []; @@ -635,7 +635,7 @@ Manager.prototype._dissect = function () { }, this); // Filter only packages that need to be installed - componentsDir = path.resolve(that._config.cwd, that._config.directory); + componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory); this._dissected = mout.object.filter(suitables, function (decEndpoint, name) { var installedMeta = this._installed[name]; var dst; diff --git a/lib/core/Project.js b/lib/core/Project.js index 0db789039..30b930726 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -13,7 +13,7 @@ var createError = require('../util/createError'); var readJson = require('../util/readJson'); var validLink = require('../util/validLink'); var scripts = require('./scripts'); -var isPathAbsolute = require('../util/isPathAbsolute'); +var relativeToBaseDir = require('../util/relativeToBaseDir'); function Project(config, logger) { this._config = config; @@ -608,7 +608,7 @@ Project.prototype._readInstalled = function () { // Gather all folders that are actual packages by // looking for the package metadata file - componentsDir = isPathAbsolute(this._config.directory) ? this._config.directory : path.join(this._config.cwd, this._config.directory); + componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory); return this._installed = Q.nfcall(glob, '*/.bower.json', { cwd: componentsDir, dot: true @@ -649,7 +649,7 @@ Project.prototype._readLinks = function () { var that = this; // Read directory, looking for links - componentsDir = isPathAbsolute(this._config.directory) ? this._config.directory : path.join(this._config.cwd, this._config.directory); + componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory); return Q.nfcall(fs.readdir, componentsDir) .then(function (filenames) { var promises; diff --git a/lib/util/isPathAbsolute.js b/lib/util/isPathAbsolute.js index 19a48edcf..67add744a 100644 --- a/lib/util/isPathAbsolute.js +++ b/lib/util/isPathAbsolute.js @@ -1,5 +1,5 @@ -function isAbsolutePath(filePath) { +function isPathAbsolute(filePath) { return filePath.charAt(0) === '/'; } -module.exports = isAbsolutePath; +module.exports = isPathAbsolute; diff --git a/lib/util/relativeToBaseDir.js b/lib/util/relativeToBaseDir.js new file mode 100644 index 000000000..07556f960 --- /dev/null +++ b/lib/util/relativeToBaseDir.js @@ -0,0 +1,14 @@ +var path = require('path'); +var isPathAbsolute = require('./isPathAbsolute'); + +function relativeToBaseDir(baseDir) { + return function(filePath) { + if(isPathAbsolute(filePath)) { + return path.resolve(filePath); + } else { + return path.resolve(baseDir, filePath); + } + }; +} + +module.exports = relativeToBaseDir; diff --git a/test/commands/link.js b/test/commands/link.js index f818610fe..9751baef5 100644 --- a/test/commands/link.js +++ b/test/commands/link.js @@ -1,3 +1,4 @@ +var path = require('path'); var expect = require('expect.js'); var helpers = require('../helpers'); @@ -69,6 +70,55 @@ describe('bower link', function () { }); }); + it('creates inter-link to relative config.directory', function () { + return helpers.run(link, [undefined, undefined, + { + cwd: mainPackage.path, + storage: { + links: linksDir.path + } + } + ]).then(function () { + return helpers.run(link, ['package', undefined, + { + cwd: otherPackage.path, + directory: 'valid-extend', + storage: { + links: linksDir.path + } + } + ]); + }).then(function() { + expect(otherPackage.read('valid-extend/package/index.js')) + .to.be('Hello World!'); + }); + }); + + + it('creates inter-link to absolute config.directory', function () { + return helpers.run(link, [undefined, undefined, + { + cwd: mainPackage.path, + storage: { + links: linksDir.path + } + } + ]).then(function () { + return helpers.run(link, ['package', undefined, + { + cwd: path.join(otherPackage.path, 'invalid'), + directory: path.join(otherPackage.path, 'valid-override'), + storage: { + links: linksDir.path + } + } + ]); + }).then(function() { + expect(otherPackage.read('valid-override/package/index.js')) + .to.be('Hello World!'); + }); + }); + it('creates inter-link with custom local name', function () { return helpers.run(link, [undefined, undefined, { diff --git a/test/commands/uninstall.js b/test/commands/uninstall.js index 729e16586..f26a6c5fc 100644 --- a/test/commands/uninstall.js +++ b/test/commands/uninstall.js @@ -1,4 +1,5 @@ var path = require('path'); +var mkdirp = require('mkdirp'); var expect = require('expect.js'); var fs = require('../../lib/util/fs'); @@ -53,4 +54,38 @@ describe('bower uninstall', function () { }); }); + it('removes dependency from relative config.directory', function () { + var targetPath = path.resolve(tempDir.path, 'other_directory/underscore'); + mkdirp.sync(targetPath); + fs.writeFileSync(path.join(targetPath, '.bower.json'), '{ "name": "underscore" }'); + + return helpers.run(uninstall, [['underscore'], undefined, { + cwd: tempDir.path, + directory: 'other_directory', + interactive: true + }]) + .then(function() { + expect(function() { + fs.statSync(targetPath); + }).to.throwException(/no such file or directory/); + }); + }); + + it('removes dependency from absolute config.directory', function () { + var targetPath = path.resolve(tempDir.path, 'other_directory/underscore'); + mkdirp.sync(targetPath); + fs.writeFileSync(path.join(targetPath, '.bower.json'), '{ "name": "underscore" }'); + + return helpers.run(uninstall, [['underscore'], undefined, { + cwd: tempDir.path, + directory: path.resolve(tempDir.path, 'other_directory'), + interactive: true + }]) + .then(function() { + expect(function() { + fs.statSync(targetPath); + }).to.throwException(/no such file or directory/); + }); + }); + }); diff --git a/test/util/createLink.js b/test/util/createLink.js new file mode 100644 index 000000000..2133a14fa --- /dev/null +++ b/test/util/createLink.js @@ -0,0 +1,57 @@ +var path = require('path'); +var Q = require('q'); +var fs = require('fs'); +var expect = require('expect.js'); +var helpers = require('../helpers'); +var createLink = require('../../lib/util/createLink'); + +describe('createLink', function () { + + var srcDir = new helpers.TempDir({ + someFile: 'Hello World', + someDirectory: { + otherFile: 'Hello World' + } + }); + + var dstDir = new helpers.TempDir(); + + beforeEach(function() { + srcDir.prepare(); + dstDir.prepare(); + }); + + it('creates a symlink to a file', function() { + + var src = path.join(srcDir.path, 'someFile'), + dst = path.join(dstDir.path, 'someFile'); + + return createLink(src, dst) + .then(function() { + return Q.nfcall(fs.readlink, dst) + .then(function(linkString) { + expect(linkString).to.be.equal(src); + }); + }); + }); + + it('throws an error when destination already exists', function() { + + var src = path.join(srcDir.path, 'someFile'), + dst = path.join(dstDir.path); + + var deferred = Q.defer(); + + createLink(src, dst) + .catch(function(err) { + expect(err.code).to.be.equal('EEXIST'); + deferred.resolve(); + }) + .then(function() { + deferred.reject(); + }); + + return deferred.promise; + }); + +}); diff --git a/test/util/index.js b/test/util/index.js index 5f3930907..c98765f10 100644 --- a/test/util/index.js +++ b/test/util/index.js @@ -3,4 +3,6 @@ describe('util', function () { require('./analytics'); require('./download'); require('./isPathAbsolute'); + require('./relativeToBaseDir'); + require('./createLink'); }); diff --git a/test/util/relativeToBaseDir.js b/test/util/relativeToBaseDir.js new file mode 100644 index 000000000..98cfdbc0a --- /dev/null +++ b/test/util/relativeToBaseDir.js @@ -0,0 +1,18 @@ +var path = require('path'); +var expect = require('expect.js'); +var relativeToBaseDir = require('../../lib/util/relativeToBaseDir'); + +describe('relativeToBaseDir', function () { + + var joinOrReturnAbsolutePath = relativeToBaseDir('/tmp'); + + it('returns a partial function that joins paths of the partials first arguments', function() { + expect(joinOrReturnAbsolutePath('foo')).to.be.equal(path.resolve('/tmp/foo')); + expect(joinOrReturnAbsolutePath('./foo')).to.be.equal(path.resolve('/tmp/foo')); + }); + + it('returns a partial function that returns it\'s first argument when it begins with /', function() { + expect(joinOrReturnAbsolutePath('/foo')).to.be.equal(path.resolve('/foo')); + expect(joinOrReturnAbsolutePath('/foo/bar')).to.be.equal(path.resolve('/foo/bar')); + }); +}); From fe6b6863ea8179f3efaa835ad41cbbc96507294a Mon Sep 17 00:00:00 2001 From: Jaime Olmo Date: Thu, 7 Jan 2016 01:49:41 -0400 Subject: [PATCH 0838/1021] Update package.json Version updated as per [1.7.2](https://github.com/bower/bower/releases/tag/v1.7.2) release. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7f8defeda..cc8d457d8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.7.1", + "version": "1.7.2", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 24f8b913b9cf5a8d47f3cf29e5bb9b8171abc213 Mon Sep 17 00:00:00 2001 From: Jaime Olmo Date: Thu, 7 Jan 2016 01:50:58 -0400 Subject: [PATCH 0839/1021] Update LICENSE Update license year to 2016. --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index cc4f84880..f25dbe841 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015 Twitter and other contributors +Copyright (c) 2016 Twitter and other contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in From 31544445569b15810b9b69eb218345b178be5799 Mon Sep 17 00:00:00 2001 From: Jaime Olmo Date: Thu, 7 Jan 2016 01:59:49 -0400 Subject: [PATCH 0840/1021] Update CHANGELOG.md Updated as per 1.7.2 release --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77fbd57c5..3e6416c1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.7.2 - 2015-12-31 + +- Lock "fs-write-stream-atomic" to 1.0.5 + ## 1.7.1 - 2015-12-11 - Rollback "Add `bower update --save` functionality", it causes issues and needs more testing From d06af7a3d718011c7d5dd37714790db796bb5dd4 Mon Sep 17 00:00:00 2001 From: Sam Saccone Date: Sun, 10 Jan 2016 18:09:59 -0800 Subject: [PATCH 0841/1021] Default to ^ operator on --save This fix brings us inline with how npm installs work and also brings us more inline with how semver is supposed to be used. Fixes #2144 --- lib/core/Manager.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 4577171b4..677ef84c9 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -386,7 +386,7 @@ Manager.prototype._onFetchSuccess = function (decEndpoint, canonicalDir, pkgMeta // If the package is not targetable, flag it // It will be needed later so that untargetable endpoints - // will not get * converted to ~version + // will not get * converted to ^version if (!isTargetable) { decEndpoint.untargetable = true; } @@ -595,7 +595,7 @@ Manager.prototype._dissect = function () { // If they are not, the resolver is incapable of handling targets semvers.forEach(function (decEndpoint) { if (decEndpoint.newly && decEndpoint.target === '*' && !decEndpoint.untargetable) { - decEndpoint.target = '~' + decEndpoint.pkgMeta.version; + decEndpoint.target = '^' + decEndpoint.pkgMeta.version; decEndpoint.originalTarget = '*'; } }); From a4ea05800d484ed54ce90f08c9a238eabb8e6cea Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 17 Jan 2016 00:13:07 +0100 Subject: [PATCH 0842/1021] Add prepublish script for easy and reliable bower releasing --- .gitignore | 2 + Gruntfile.js | 160 +++++++++++++++++++++++++++++++++++++++++ package.json | 6 +- test/sample/bower.json | 49 +++++++++++++ 4 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 test/sample/bower.json diff --git a/.gitignore b/.gitignore index ee50eb4be..5ad35aeea 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ /bower.json /component.json /bower_components +/test/sample +!/test/sample/bower.json diff --git a/Gruntfile.js b/Gruntfile.js index 7d6584101..965f6e3f3 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,4 +1,10 @@ 'use strict'; + +var childProcess = require('child_process'); +var arraydiff = require('arr-diff'); +var fs = require('fs'); +var inquirer = require('inquirer'); + module.exports = function (grunt) { require('load-grunt-tasks')(grunt); @@ -14,6 +20,7 @@ module.exports = function (grunt) { 'test/**/*.js', '!test/assets/**/*', '!test/reports/**/*', + '!test/sample/**/*', '!test/tmp/**/*' ] }, @@ -29,6 +36,7 @@ module.exports = function (grunt) { 'test/**/*.js', '!test/assets/**/*', '!test/reports/**/*', + '!test/sample/**/*', '!test/tmp/**/*' ] }, @@ -72,4 +80,156 @@ module.exports = function (grunt) { grunt.registerTask('cover', 'exec:cover'); grunt.registerTask('travis', ['jshint', 'exec:assets', 'exec:cover', 'exec:coveralls']); grunt.registerTask('default', 'test'); + + grunt.task.registerTask('prepublish', 'Prepublish checks', function () { + var npmVersion = JSON.parse(childProcess.execSync('npm version --json').toString()).npm.split('.'); + var npmMajor = parseInt(npmVersion[0], 10); + var npmMinor = parseInt(npmVersion[1], 10); + + if (npmMajor !== 3 || npmMinor < 5) { + grunt.log.writeln('You need to use at least npm@3.5 to publish bower.'); + grunt.log.writeln('It is because npm 2.x produces too long paths that Windows does not handle.'); + grunt.log.writeln('Please upgrade it: npm install -g npm'); + process.exit(1); + } + + var bundledDependencies = require('./package').bundledDependencies; + var dependencies = Object.keys(require('./package').dependencies); + var missing = arraydiff(dependencies, bundledDependencies); + + if (missing.length > 0) { + grunt.log.writeln('You need to add all bower\'s dependencies to bundledDependencies in package.json'); + grunt.log.writeln('It is to freeze all dependencies so bower does not randomly break'); + grunt.log.writeln('Following dependencies need to be added to bundledDependencies:'); + + for(var i = 0; i < missing.length; i++) { + grunt.log.writeln(' "' + missing[i] + '",\n'); + } + + process.exit(1); + } + + var version = require('./package').version; + var changelog = fs.readFileSync('./CHANGELOG.md'); + + if (changelog.indexOf('## ' + version) === -1) { + grunt.log.writeln('Please add changelog.md entry for this bower version (' + version + ')'); + + var lastRelease = childProcess.execSync('git tag | tail -1').toString().trim(); + + grunt.log.writeln('Commits since last release (' + lastRelease + '): \n'); + + grunt.log.writeln(childProcess.execSync('git log --oneline ' + lastRelease + '..').toString()); + + process.exit(1); + } + + if (childProcess.execSync('git rev-parse --abbrev-ref HEAD').toString().trim() !== 'master') { + grunt.log.writeln('You need to release bower from the "master" branch'); + + process.exit(1); + } + + grunt.log.writeln('Reinstalling dependencies...'); + childProcess.execSync('rm -rf node_modules && npm install', { stdio: [0, 1, 2] }); + + grunt.log.writeln('Running test suite...'); + childProcess.execSync('grunt test', { stdio: [0, 1, 2] }); + + var questions = [ + { + type: 'confirm', + name: 'review', + message: 'Did you review all the changes with "git diff"?', + default: false + }, + { + type: 'confirm', + name: 'changelog', + message: 'Are you sure the CHANGELOG.md contains all changes?', + default: false + }, + { + type: 'confirm', + name: 'tests', + message: 'Are you sure all tests are passing on Travis and Appveyor?', + default: false + } + ]; + + var done = this.async(); + + inquirer.prompt(questions, function (answers) { + if (!answers.review || !answers.changelog || !answers.tests) { + grunt.log.writeln('Please publish bower after you fix this issue'); + + process.exit(1); + } + + try { + grunt.log.writeln('Reinstalling dependencies in production mode...'); + + childProcess.execSync('rm -rf node_modules && npm install --production', { stdio: [0, 1, 2] }); + + grunt.log.writeln('Testing bower on sample project...'); + + childProcess.execSync( + 'cd test/sample && rm -rf bower_components && ../../bin/bower install --force', { stdio: [0, 1, 2] } + ); + + var expectedPackages = ( + 'SHA-1 ace-builds almond angular angular-animate angular-bootstrap angular-charts angular-contenteditable ' + + 'angular-deckgrid angular-fullscreen angular-gravatar angular-hotkeys angular-local-storage angular-marked ' + + 'angular-moment angular-sanitize angular-touch angular-ui-router angular-ui-sortable ' + + 'angulartics asEvented bootstrap coffee-script d3 es6-shim font-awesome howler jquery ' + + 'jquery-ui jquery-waypoints js-beautify lodash lz-string marked moment ng-file-upload peerjs ' + + 'requirejs restangular slimScroll slimScrollHorizontal venturocket-angular-slider' + ).split(' '); + + var installedPackages = fs.readdirSync('./test/sample/bower_components'); + + var installedDiff = arraydiff(expectedPackages, installedPackages); + + if (installedDiff.length > 0) { + grunt.log.writeln('ERROR. Some packages were not installed by bower: '); + grunt.log.writeln(installedDiff.join(', ')); + + process.exit(1); + } + } catch (e) { + grunt.log.writeln('There was an error. Reverting development dependencies...'); + + childProcess.execSync('npm install', { stdio: [0, 1, 2] }); + + process.exit(1); + } + + grunt.log.writeln('Everything seems OK! You are likely good to publish bower.'); + + var questions = [ + { + type: 'confirm', + name: 'publish', + message: 'Are you SURE you want to publish bower@' + require('./package').version + '?', + default: false + } + ]; + + inquirer.prompt(questions, function (answers) { + if (!answers.publish) { + grunt.log.writeln('Bower publishing cancelled..'); + + childProcess.execSync('npm install', { stdio: [0, 1, 2] }); + + process.exit(1); + } + + grunt.log.writeln('\nPlease remember to tag this relese, and add a release on Github!'); + grunt.log.writeln('\nAlso, please remember to test published Bower one more time!'); + grunt.log.writeln('\nPublishing Bower...'); + + done(); + }); + }); + }); }; diff --git a/package.json b/package.json index cc8d457d8..09c4c0934 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "which": "^1.0.8" }, "devDependencies": { + "arr-diff": "^2.0.0", "chai": "^1.10.0", "coveralls": "^2.11.2", "expect.js": "^0.3.1", @@ -73,6 +74,7 @@ "grunt-exec": "^0.4.6", "grunt-jscs": "^2.3.0", "grunt-simple-mocha": "^0.4.0", + "in-publish": "^2.0.0", "istanbul": "^0.3.5", "load-grunt-tasks": "^2.0.0", "mocha": "^2.1.0", @@ -122,6 +124,7 @@ "retry", "rimraf", "semver", + "semver-utils", "shell-quote", "stringify-object", "tar-fs", @@ -133,7 +136,8 @@ "scripts": { "test": "grunt test", "ci": "grunt travis", - "coveralls": "coveralls" + "coveralls": "coveralls", + "prepublish": "in-publish && grunt prepublish || not-in-publish" }, "bin": "bin/bower", "files": [ diff --git a/test/sample/bower.json b/test/sample/bower.json new file mode 100644 index 000000000..d6b5ee49b --- /dev/null +++ b/test/sample/bower.json @@ -0,0 +1,49 @@ +{ + "name": "platform", + "version": "0.0.1", + "ignore": [ + "**/.*", + "node_modules", + "components" + ], + "dependencies": { + "angular": "~1.2.14", + "bootstrap": "~3.1.1", + "ace-builds": "~1.1.3", + "font-awesome": "~4.2.0", + "slimScroll": "~1.3.1", + "slimScrollHorizontal": "https://github.com/rochal/jQuery-slimScroll.git", + "requirejs": "~2.1.11", + "lodash": "~2.4.1", + "angular-sanitize": "~1.2.14", + "asEvented": "https://github.com/mkuklis/asEvented.git#0.4.3", + "restangular": "~1.3.1", + "angular-animate": "~1.2.16", + "angular-ui-sortable": "~0.12.6", + "howler": "~1.1.20", + "es6-shim": "~0.10.1", + "venturocket-angular-slider": "~0.3.2", + "almond": "~0.2.9", + "peerjs": "~0.3.8", + "angular-gravatar": "~0.1.5", + "angular-deckgrid": "~0.4.4", + "angular-ui-router": "~0.2.10", + "angular-moment": "~0.7.1", + "lz-string": "https://github.com/pieroxy/lz-string.git#4cc031b68e3a6db202c467396a01429629666122", + "angular-local-storage": "~0.0.5", + "angular-hotkeys": "chieffancypants/angular-hotkeys#~1.4.0", + "coffee-script": "~1.7.1", + "jquery-ui": "~1.11.0", + "angular-contenteditable": "~0.3.7", + "angulartics": "~0.16.4", + "angular-marked": "Hypercubed/angular-marked#~0.0.12", + "angular-bootstrap": "~0.11.0", + "angular-charts": "~0.2.6", + "ng-file-upload": "~1.6.12", + "js-beautify": "~1.5.4", + "angular-fullscreen": "~1.0.0" + }, + "resolutions": { + "angular": ">= 1.3.0" + } +} From 64db869bd4c1aae8af7617cfeb050f9567a5722d Mon Sep 17 00:00:00 2001 From: Manas Date: Fri, 25 Dec 2015 00:17:46 +0530 Subject: [PATCH 0843/1021] Adds tests for pluginResolverFactory.js --- test/core/resolvers/pluginResolverFactory.js | 481 +++++++++++++++++++ 1 file changed, 481 insertions(+) create mode 100644 test/core/resolvers/pluginResolverFactory.js diff --git a/test/core/resolvers/pluginResolverFactory.js b/test/core/resolvers/pluginResolverFactory.js new file mode 100644 index 000000000..0558cb9e0 --- /dev/null +++ b/test/core/resolvers/pluginResolverFactory.js @@ -0,0 +1,481 @@ +var expect = require('expect.js'); +var path = require('path'); +var Logger = require('bower-logger'); +var createError = require('../../../lib/util/createError'); +var pluginResolverFactory = require('../../../lib/core/resolvers/pluginResolverFactory'); +var defaultConfig = require('../../../lib/config'); +var Q = require('q'); + +describe('pluginResolverFactory', function () { + var testPackage = path.resolve(__dirname, '../../assets/package-a'); + var logger; + + before(function () { + logger = new Logger(); + }); + + afterEach(function () { + logger.removeAllListeners(); + }); + + var mockPluginResolver = function resolver (bower) { + + return { + + match: function (source) { + return true; + }, + + locate: function (source) { + return source; + }, + + releases: function (source) { + return [ + { target: 'v1.0.0', version: '1.0.0' }, + { target: 'v1.0.1', version: '1.0.1' } + ]; + }, + + fetch: function (endpoint, cached) { + if (cached && cached.version) { + return; + } + + return { + tempPath: 'some/temp/path', + removeIgnores: true + }; + } + }; + }; + + function create(decEndpoint) { + if (typeof decEndpoint === 'string') { + decEndpoint = { source: decEndpoint }; + } + var PluginResolver = pluginResolverFactory(mockPluginResolver, + defaultConfig()); + return new PluginResolver(decEndpoint); + } + + describe('.constructor', function () { + it('should internally add decEndpoint', function () { + var resolver; + resolver = create('file://' + testPackage); + expect(typeof resolver._decEndpoint).to.equal('object'); + expect(resolver._decEndpoint.source).to.equal('file://' + testPackage); + }); + + it('should throw when invalid resolverFactory is provided', function () { + expect(function () { + pluginResolverFactory('not-a-function', + defaultConfig()); + }).to.throwException(createError('Resolver has "string" type instead of "function" type.', 'ERESOLERAPI')); + }); + }); + + describe('.getEndpoint', function () { + it('should return endpoint', function () { + var resolver, endPoint; + resolver = create('file://' + testPackage); + endPoint = resolver.getEndpoint(); + expect(endPoint).to.have.property('source'); + expect(endPoint.source).to.equal('file://' + testPackage); + expect(endPoint).to.have.property('name'); + expect(endPoint.name).to.equal('package-a'); + expect(endPoint).to.have.property('target'); + expect(endPoint.target).to.equal('*'); + }); + }); + + describe('.getSource', function () { + it('should return endpoint', function () { + var resolver, source; + resolver = create('file://' + testPackage); + source = resolver.getSource(); + expect(source).to.equal('file://' + testPackage); + }); + }); + + describe('.getTarget', function () { + it('should return target', function () { + var resolver, source; + resolver = create({ + source: 'file://' + testPackage, + target: 'some-target' + }); + source = resolver.getTarget(); + expect(source).to.equal('some-target'); + }); + it('should return * when no target is specified', function () { + var resolver, source; + resolver = create('file://' + testPackage); + source = resolver.getTarget(); + expect(source).to.equal('*'); + }); + }); + + describe('.getName', function () { + it('should return target', function () { + }); + }); + + describe('.getPkgMeta', function () { + it('should return package meta', function () { + var resolver, pkgMeta; + resolver = create('file://' + testPackage); + resolver._pkgMeta = { version: 'v1.0.1' }; + pkgMeta = resolver.getPkgMeta(); + console.log(pkgMeta); + expect(pkgMeta).to.have.property('version'); + expect(pkgMeta.version).to.equal('v1.0.1'); + }); + }); + + describe('.isCacheable', function () { + it('should always return true', function () { + var resolver, isCacheable; + resolver = create('file://' + testPackage); + isCacheable = resolver.isCacheable(); + expect(isCacheable).to.be.ok(); + }); + }); + + describe('.hasNew', function () { + it('should return existing hasNewPromise if its set', function () { + var resolver; + resolver = create('file://' + testPackage); + resolver.hasNewPromise = Q.fcall(function () { + return 'some-dummy-value'; + }); + resolver.hasNew().then(function (resolvedtestValue) { + expect(resolvedtestValue).to.be('some-dummy-value'); + }); + }); + it('should return target', function () { + }); + }); + + describe('.resolve', function () { + it('should throw \'Resolver did not provide releases of package.\'', function (next) { + var mockPluginResolverWithEmptyReleases = function resolver (bower) { + return { + + match: function (source) { + return true; + }, + + releases: function (source) { + return null; + }, + + fetch: function (endpoint, cached) { + if (cached && cached.version) { + return; + } + + return { + tempPath: '/temp/path', + removeIgnores: true + }; + } + }; + }; + + var PluginResolver = pluginResolverFactory(mockPluginResolverWithEmptyReleases, + defaultConfig()); + var path = 'file://' + testPackage; + var resolver = new PluginResolver(path); + resolver.resolve() + .catch(function (e) { + expect(e.message).to + .equal('Resolver did not provide releases of package.'); + next(); + }); + }); + + it('should throw \'No version found that was able to satisfy *.\'', function (next) { + var mockPluginResolverWithNoMatchingTarget = function resolver (bower) { + + return { + + match: function (source) { + return true; + }, + + releases: function (source) { + return []; + }, + + fetch: function (endpoint, cached) { + if (cached && cached.version) { + return; + } + + return { + tempPath: '/temp/path', + removeIgnores: true + }; + } + }; + }; + + var PluginResolver = pluginResolverFactory( + mockPluginResolverWithNoMatchingTarget, + defaultConfig() + ); + var path = 'file://' + testPackage; + var resolver = new PluginResolver(path); + resolver.resolve() + .catch(function (e) { + expect(e.message).to + .equal('No version found that was able to satisfy *'); + expect(e.code).to + .equal('ENORESTARGET'); + next(); + }); + }); + + it('should throw \'Resolver does not accept version ranges\'', function (next) { + var mockPluginResolverWithInvalidTarget = function resolver (bower) { + return { + match: function (source) { + return true; + }, + releases: null, + fetch: function (endpoint, cached) { + if (cached && cached.version) { + return; + } + return { + tempPath: '/temp/path', + removeIgnores: true + }; + } + }; + }; + + var PluginResolver = pluginResolverFactory( + mockPluginResolverWithInvalidTarget, + defaultConfig() + ); + var path = 'file://' + testPackage; + var resolver = new PluginResolver({ + source: path, + target: '2.0.0' + }); + resolver.resolve() + .catch(function (e) { + expect(e.message).to + .equal('Resolver does not accept version ranges (2.0.0)'); + next(); + }); + }); + + + it('should throw \'Resolver does not implement the "fetch" method.\'', function (next) { + var mockPluginResolverWithoutFetch = function resolver (bower) { + return { + match: function (source) { + return true; + }, + releases: function (source) { + return [ + { target: 'v1.0.0', version: '1.0.0' }, + { target: 'v1.0.1', version: '1.0.1' } + ]; + }, + fetch: null + }; + }; + var PluginResolver = pluginResolverFactory( + mockPluginResolverWithoutFetch, + defaultConfig() + ); + var path = 'file://' + testPackage; + var resolver = new PluginResolver(path); + resolver.resolve() + .catch(function (e) { + expect(e.message).to + .equal('Resolver does not implement the "fetch" method.'); + next(); + }); + }); + + it('should throw \'Resolver did not provide path to extracted contents of package\'', + function (next) { + var mockPluginResolverWithoutTempPath = function resolver (bower) { + return { + + match: function (source) { + return true; + }, + + releases: function (source) { + return [ + { target: 'v1.0.0', version: '1.0.0' }, + { target: 'v1.0.1', version: '1.0.1' } + ]; + }, + + fetch: function (endpoint, cached) { + if (cached && cached.version) { + return; + } + + return { + tempPath: null, + removeIgnores: true + }; + } + }; + }; + var PluginResolver = pluginResolverFactory( + mockPluginResolverWithoutTempPath, + defaultConfig() + ); + var path = 'file://' + testPackage; + var resolver = new PluginResolver(path); + resolver.resolve() + .catch(function (e) { + expect(e.message).to + .equal('Resolver did not provide path to extracted contents of package.'); + next(); + }); + }); + + }); + + describe('.isTargetable', function () { + it('should accept mockPluginResolverWithReleasesFn', function () { + var PluginResolver = pluginResolverFactory(mockPluginResolver, + defaultConfig()); + expect(PluginResolver.isTargetable()).to.be.ok(); + }); + it('should reject mockPluginResolverWithoutReleasesFn', function () { + var mockPluginResolverWithoutReleasesFn = function resolver (bower) { + return { + match: function (source) { + return true; + }, + locate: function (source) { + return source; + }, + fetch: function (endpoint, cached) { + if (cached && cached.version) { + return; + } + + return { + tempPath: 'some/tmp/path', + removeIgnores: true + }; + } + }; + }; + var PluginResolver = pluginResolverFactory(mockPluginResolverWithoutReleasesFn, + defaultConfig()); + expect(PluginResolver.isTargetable()).to.not.be.ok(); + }); + }); + + describe('.clearRuntimeCache', function () { + it('', function () { + //Unable to test private variable `resolver` + }); + }); + + describe('.match', function () { + it('should throw when plugin does not implement .match', function () { + var mockPluginResolverWithoutMatch = function resolver (bower) { + + return { + + releases: function (source) { + return [ + { target: 'v1.0.0', version: '1.0.0' }, + { target: 'v1.0.1', version: '1.0.1' } + ]; + }, + + fetch: function (endpoint, cached) { + if (cached && cached.version) { + return; + } + + return { + tempPath: 'some/temp/path', + removeIgnores: true + }; + } + }; + }; + + var PluginResolver = pluginResolverFactory(mockPluginResolverWithoutMatch, + defaultConfig()); + var source = 'git://github.com/jquery/jquery.git'; + expect(function () { + PluginResolver.match(source); + }).to.throwException(createError('Resolver is missing "match"' + + 'method.', + 'ERESOLVERAPI')); + }); + + it('should match given source', function () { + var PluginResolver = pluginResolverFactory(mockPluginResolver, + defaultConfig()); + var source = 'git://github.com/jquery/jquery.git'; + PluginResolver.match(source).then(function (result) { + expect(result).to.be.ok(); + }); + }); + }); + + describe('.locate', function () { + it('should return source when plugin does not implement .locate', function () { + + var mockPluginResolverWithoutLocate = function resolver (bower) { + + return { + + match: function (source) { + return true; + }, + + releases: function (source) { + return [ + { target: 'v1.0.0', version: '1.0.0' }, + { target: 'v1.0.1', version: '1.0.1' } + ]; + }, + + fetch: function (endpoint, cached) { + if (cached && cached.version) { + return; + } + + return { + tempPath: '/temp/path', + removeIgnores: true + }; + } + }; + }; + + var PluginResolver = pluginResolverFactory(mockPluginResolverWithoutLocate, + defaultConfig()); + var path = 'file://' + testPackage; + expect(PluginResolver.locate(path)).to.be(path); + }); + + it('should locate the source', function () { + var PluginResolver = pluginResolverFactory(mockPluginResolver, + defaultConfig()); + var source = 'jquery/jquery'; + PluginResolver.locate(source).then(function (result) { + expect(result).to.be(source); + }); + }); + }); +}); From afe76e57f8cac7dbfc0edfda02d8725a70b1b2a9 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 18 Jan 2016 22:05:17 +0100 Subject: [PATCH 0844/1021] Remove HOOKS.md as they are now properly documented, thanks @dvidsilva! --- HOOKS.md | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 HOOKS.md diff --git a/HOOKS.md b/HOOKS.md deleted file mode 100644 index 7022b7607..000000000 --- a/HOOKS.md +++ /dev/null @@ -1,21 +0,0 @@ -# Install and Uninstall Hooks - -Bower provides 3 separate hooks that can be used to trigger other automated tools during Bower usage. Importantly, these hooks are intended to allow external tools to help wire up the newly installed components into the parent project and other similar tasks. These hooks are not intended to provide a post-installation build step for component authors. As such, the configuration for these hooks is provided in the `.bowerrc` file in the parent project's directory. - -## Configuring - -In `.bowerrc` do: - -```js -{ - "scripts": { - "preinstall": "", - "postinstall": "", - "preuninstall": "" - } -} -``` - -The value of each script hook may contain a % character. When your script is called, the % will be replaced with a space-separated list of components being installed or uninstalled. - -Your script will also include an environment variable `BOWER_PID` containing the PID of the parent Bower process that triggered the script. This can be used to verify that a `preinstall` and `postinstall` steps are part of the same Bower process. \ No newline at end of file From 3e3b64218d0a266a900cdcffcc7ef6b8f568aee9 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 19 Jan 2016 20:27:35 +0100 Subject: [PATCH 0845/1021] Remove analytics from Bower, fixes #1102 They caused more issues than useful they were. Instead, we'll focus on fetching statistics from NPM registry to watch Bower's popularity, and GitHub stars over time to watch packages' popularity. --- bin/bower | 134 ++++++++++++++--------------- lib/commands/info.js | 4 - lib/commands/install.js | 4 - lib/commands/register.js | 5 -- lib/commands/search.js | 4 - lib/commands/uninstall.js | 5 -- lib/commands/unregister.js | 6 -- lib/util/analytics.js | 127 --------------------------- package.json | 2 - test/util/analytics.js | 170 ------------------------------------- test/util/index.js | 1 - 11 files changed, 65 insertions(+), 397 deletions(-) delete mode 100644 lib/util/analytics.js delete mode 100644 test/util/analytics.js diff --git a/bin/bower b/bin/bower index 2a6129138..aeedd77d4 100755 --- a/bin/bower +++ b/bin/bower @@ -11,7 +11,6 @@ var bower = require('../lib'); var pkg = require('../package.json'); var cli = require('../lib/util/cli'); var rootCheck = require('../lib/util/rootCheck'); -var analytics = require('../lib/util/analytics'); var options; var renderer; @@ -68,85 +67,82 @@ while (options.argv.remain.length) { options.argv.remain.pop(); } -// Ask for Insights on first run. -analytics.setup(bower.config).then(function () { - // Execute the command - commandFunc = command && mout.object.get(bower.commands, command); - command = command && command.replace(/\./g, ' '); +// Execute the command +commandFunc = command && mout.object.get(bower.commands, command); +command = command && command.replace(/\./g, ' '); + +// If no command was specified, show bower help +// Do the same if the command is unknown +if (!commandFunc) { + logger = bower.commands.help(); + command = 'help'; +// If the user requested help, show the command's help +// Do the same if the actual command is a group of other commands (e.g.: cache) +} else if (options.help || !commandFunc.line) { + logger = bower.commands.help(command); + command = 'help'; +// Call the line method +} else { + logger = commandFunc.line(process.argv); - // If no command was specified, show bower help - // Do the same if the command is unknown - if (!commandFunc) { - logger = bower.commands.help(); - command = 'help'; - // If the user requested help, show the command's help - // Do the same if the actual command is a group of other commands (e.g.: cache) - } else if (options.help || !commandFunc.line) { + // If the method failed to interpret the process arguments + // show the command help + if (!logger) { logger = bower.commands.help(command); command = 'help'; - // Call the line method - } else { - logger = commandFunc.line(process.argv); - - // If the method failed to interpret the process arguments - // show the command help - if (!logger) { - logger = bower.commands.help(command); - command = 'help'; - } } +} - // Get the renderer and configure it with the executed command - renderer = cli.getRenderer(command, logger.json, bower.config); +// Get the renderer and configure it with the executed command +renderer = cli.getRenderer(command, logger.json, bower.config); - function handleLogger(logger, renderer) { - logger - .on('end', function (data) { - if (!bower.config.silent && !bower.config.quiet) { - renderer.end(data); - } - }) - .on('error', function (err) { - if (command !== 'help' && err.code === cli.READ_OPTIONS_ERROR_CODE) { - logger = bower.commands.help(command); - renderer = cli.getRenderer('help', logger.json, bower.config); - handleLogger(logger, renderer); - } else { - if (levels.error >= loglevel) { - renderer.error(err); - } - - process.exit(1); - } - }) - .on('log', function (log) { - if (levels[log.level] >= loglevel) { - renderer.log(log); +function handleLogger(logger, renderer) { + logger + .on('end', function (data) { + if (!bower.config.silent && !bower.config.quiet) { + renderer.end(data); + } + }) + .on('error', function (err) { + if (command !== 'help' && err.code === cli.READ_OPTIONS_ERROR_CODE) { + logger = bower.commands.help(command); + renderer = cli.getRenderer('help', logger.json, bower.config); + handleLogger(logger, renderer); + } else { + if (levels.error >= loglevel) { + renderer.error(err); } - }) - .on('prompt', function (prompt, callback) { - renderer.prompt(prompt) - .then(function (answer) { - callback(answer); - }); + + process.exit(1); + } + }) + .on('log', function (log) { + if (levels[log.level] >= loglevel) { + renderer.log(log); + } + }) + .on('prompt', function (prompt, callback) { + renderer.prompt(prompt) + .then(function (answer) { + callback(answer); }); - } + }); +} - handleLogger(logger, renderer); +handleLogger(logger, renderer); - // Warn if HOME is not SET - if (!userHome) { - logger.warn('no-home', 'HOME environment variable not set. User config will not be loaded.'); - } +// Warn if HOME is not SET +if (!userHome) { + logger.warn('no-home', 'HOME environment variable not set. User config will not be loaded.'); +} - if (bower.config.interactive) { - var updateNotifier = require('update-notifier'); +if (bower.config.interactive) { + var updateNotifier = require('update-notifier'); - // Check for newer version of Bower - var notifier = updateNotifier({pkg: pkg}); + // Check for newer version of Bower + var notifier = updateNotifier({pkg: pkg}); - if (notifier.update && levels.info >= loglevel) { - notifier.notify(); - } + if (notifier.update && levels.info >= loglevel) { + notifier.notify(); } -}); +} diff --git a/lib/commands/info.js b/lib/commands/info.js index 8430c71f8..850360ef8 100644 --- a/lib/commands/info.js +++ b/lib/commands/info.js @@ -2,7 +2,6 @@ var mout = require('mout'); var Q = require('q'); var endpointParser = require('bower-endpoint-parser'); var PackageRepository = require('../core/PackageRepository'); -var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); function info(logger, endpoint, property, config) { @@ -12,14 +11,11 @@ function info(logger, endpoint, property, config) { var repository; var decEndpoint; - var tracker; config = defaultConfig(config); repository = new PackageRepository(config, logger); - tracker = new Tracker(config); decEndpoint = endpointParser.decompose(endpoint); - tracker.trackDecomposedEndpoints('info', [decEndpoint]); return Q.all([ getPkgMeta(repository, decEndpoint, property), diff --git a/lib/commands/install.js b/lib/commands/install.js index f934b63e5..c3d0489e1 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -1,12 +1,10 @@ var endpointParser = require('bower-endpoint-parser'); var Project = require('../core/Project'); -var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); function install(logger, endpoints, options, config) { var project; var decEndpoints; - var tracker; options = options || {}; config = defaultConfig(config); @@ -14,14 +12,12 @@ function install(logger, endpoints, options, config) { options.save = config.defaultSave; } project = new Project(config, logger); - tracker = new Tracker(config); // Convert endpoints to decomposed endpoints endpoints = endpoints || []; decEndpoints = endpoints.map(function (endpoint) { return endpointParser.decompose(endpoint); }); - tracker.trackDecomposedEndpoints('install', decEndpoints); return project.install(decEndpoints, options, config); } diff --git a/lib/commands/register.js b/lib/commands/register.js index fe2451ac8..9c096a3b7 100644 --- a/lib/commands/register.js +++ b/lib/commands/register.js @@ -1,19 +1,16 @@ var Q = require('q'); var chalk = require('chalk'); var PackageRepository = require('../core/PackageRepository'); -var Tracker = require('../util/analytics').Tracker; var createError = require('../util/createError'); var defaultConfig = require('../config'); function register(logger, name, url, config) { var repository; var registryClient; - var tracker; var force; config = defaultConfig(config); force = config.force; - tracker = new Tracker(config); name = (name || '').trim(); url = (url || '').trim(); @@ -28,8 +25,6 @@ function register(logger, name, url, config) { throw createError('Usage: bower register ', 'EINVFORMAT'); } - tracker.track('register'); - // Attempt to resolve the package referenced by the URL to ensure // everything is ok before registering repository = new PackageRepository(config, logger); diff --git a/lib/commands/search.js b/lib/commands/search.js index 06f77f739..bb2e9c550 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -1,12 +1,10 @@ var Q = require('q'); var RegistryClient = require('bower-registry-client'); -var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); var cli = require('../util/cli'); function search(logger, name, config) { var registryClient; - var tracker; var json = config ? config.json : undefined; config = defaultConfig(config); @@ -14,8 +12,6 @@ function search(logger, name, config) { config.cache = config.storage.registry; registryClient = new RegistryClient(config, logger); - tracker = new Tracker(config); - tracker.track('search', name); if (name) { return Q.nfcall(registryClient.search.bind(registryClient), name); diff --git a/lib/commands/uninstall.js b/lib/commands/uninstall.js index d14854e6d..9fd7d07aa 100644 --- a/lib/commands/uninstall.js +++ b/lib/commands/uninstall.js @@ -1,7 +1,6 @@ var mout = require('mout'); var Q = require('q'); var Project = require('../core/Project'); -var Tracker = require('../util/analytics').Tracker; var defaultConfig = require('../config'); function uninstall(logger, names, options, config) { @@ -10,14 +9,10 @@ function uninstall(logger, names, options, config) { } var project; - var tracker; options = options || {}; config = defaultConfig(config); project = new Project(config, logger); - tracker = new Tracker(config); - - tracker.trackNames('uninstall', names); return project.getTree(options) .spread(function (tree, flattened) { diff --git a/lib/commands/unregister.js b/lib/commands/unregister.js index 3cdba091b..4d9676d70 100644 --- a/lib/commands/unregister.js +++ b/lib/commands/unregister.js @@ -3,7 +3,6 @@ var Q = require('q'); var defaultConfig = require('../config'); var PackageRepository = require('../core/PackageRepository'); -var Tracker = require('../util/analytics').Tracker; var createError = require('../util/createError'); function unregister(logger, name, config) { @@ -14,12 +13,10 @@ function unregister(logger, name, config) { var repository; var registryClient; - var tracker; var force; config = defaultConfig(config); force = config.force; - tracker = new Tracker(config); // Bypass any cache config.offline = false; @@ -30,8 +27,6 @@ function unregister(logger, name, config) { repository = new PackageRepository(config, logger); - tracker.track('unregister'); - if (!config.accessToken) { return logger.emit('error', createError('Use "bower login" with collaborator credentials', 'EFORBIDDEN') @@ -64,7 +59,6 @@ function unregister(logger, name, config) { return Q.nfcall(registryClient.unregister.bind(registryClient), name); }) .then(function (result) { - tracker.track('unregistered'); logger.info('Package unregistered', name); return result; diff --git a/lib/util/analytics.js b/lib/util/analytics.js deleted file mode 100644 index f4c0cd5ac..000000000 --- a/lib/util/analytics.js +++ /dev/null @@ -1,127 +0,0 @@ -var Q = require('q'); -var mout = require('mout'); - -var analytics = module.exports; - -var insight; - -var enableAnalytics = false; - -// Insight takes long to load, and often causes problems -// in non-interactive environment, so we load it lazily -// -// Insight is used in two cases: -// -// 1. Read insight configuration (whether track user actions) -// 2. Track user actions (Tracker.track method) -// -// We don't want to instantiate Insight in non-interactive mode -// because it takes time to read config and configstore has concurrency issues: -// -// https://github.com/yeoman/configstore/issues/20 - -function ensureInsight () { - if (!insight) { - var Insight = require('insight'); - - if (process.env.NODE_ENV === 'test') { - insight = new Insight({ - trackingCode: 'UA-00000000-0', - pkg: { - name: 'bower-test', - version: '1.0.0' - } - }); - - insight.config.clear(); - } else { - insight = new Insight({ - trackingCode: 'UA-43531210-1', - pkg: require('../../package.json') - }); - } - } -} - -// Initializes the application-wide insight singleton and asks for the -// permission on the CLI during the first run. -// -// This method is called only from bin/bower. Programmatic API skips it. -analytics.setup = function setup (config) { - var deferred = Q.defer(); - - // No need for asking if analytics is set in bower config - if (config.analytics === undefined) { - ensureInsight(); - - // For non-interactive call from bin/bower we disable analytics - if (config.interactive) { - if (insight.optOut !== undefined) { - deferred.resolve(!insight.optOut); - } else { - insight.askPermission(null, function(err, optIn) { - // optIn callback param was exactly opposite before 0.4.3 - // so we force at least insight@0.4.3 in package.json - deferred.resolve(optIn); - }); - } - } else { - // no specified value, no stored value, and can't prompt for one - // most likely CI environment; defaults to false to reduce data noise - deferred.resolve(false); - } - } else { - // use the specified value - deferred.resolve(config.analytics); - } - - return deferred.promise.then(function (enabled) { - enableAnalytics = enabled; - - return enabled; - }); -}; - -var Tracker = analytics.Tracker = function Tracker (config) { - function analyticsEnabled () { - // Allow for overriding analytics default - if (config && config.analytics !== undefined) { - return config.analytics; - } - - // TODO: let bower pass this variable from bin/bower instead closure - return enableAnalytics; - } - - if (analyticsEnabled()) { - ensureInsight(); - } else { - this.track = function noop () {}; - this.trackDecomposedEndpoints = function noop () {}; - this.trackPackages = function noop () {}; - this.trackNames = function noop () {}; - } -}; - -Tracker.prototype.track = function track () { - insight.track.apply(insight, arguments); -}; - -Tracker.prototype.trackDecomposedEndpoints = function trackDecomposedEndpoints (command, endpoints) { - endpoints.forEach(function (endpoint) { - this.track(command, endpoint.source, endpoint.target); - }.bind(this)); -}; - -Tracker.prototype.trackPackages = function trackPackages (command, packages) { - mout.object.forOwn(packages, function (_package) { - var meta = _package.pkgMeta; - this.track(command, meta.name, meta.version); - }.bind(this)); -}; - -Tracker.prototype.trackNames = function trackNames (command, names) { - names.forEach(function (name) { - this.track(command, name); - }.bind(this)); -}; diff --git a/package.json b/package.json index 09c4c0934..fea5a2e15 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "graceful-fs": "^3.0.5", "handlebars": "^2.0.0", "inquirer": "0.10.0", - "insight": "^0.7.0", "is-root": "^1.0.0", "junk": "^1.0.0", "lockfile": "^1.0.0", @@ -106,7 +105,6 @@ "graceful-fs", "handlebars", "inquirer", - "insight", "is-root", "junk", "lockfile", diff --git a/test/util/analytics.js b/test/util/analytics.js deleted file mode 100644 index bd8857f1a..000000000 --- a/test/util/analytics.js +++ /dev/null @@ -1,170 +0,0 @@ -var expect = require('expect.js'); -var proxyquire = require('proxyquire'); -var object = require('mout').object; - -describe('analytics', function () { - - var mockAnalytics = function(stubs, promptResponse) { - return proxyquire('../../lib/util/analytics', { - insight: function () { - return object.merge(stubs || {}, { - askPermission: function (message, callback) { - callback(undefined, promptResponse); - }, - config: { - clear: function () {} - } - }); - } - }); - }; - - describe('#setup', function () { - // Reset process.env.CI after tests are done - var oldCI; - beforeEach(function () { - oldCI = process.env.CI; - }); - afterEach(function () { - process.env.CI = oldCI; - }); - - it('leaves analytics enabled if provided', function () { - return mockAnalytics() - .setup({ analytics: true }) - .then(function (enabled) { - expect(enabled).to.be(true); - }); - }); - - it('leaves analytics disabled if provided', function () { - return mockAnalytics() - .setup({ analytics: false }) - .then(function (enabled) { - expect(enabled).to.be(false); - }); - }); - - it('disables analytics for non-interactive mode', function () { - return mockAnalytics() - .setup({ interactive: false }) - .then(function (enabled) { - expect(enabled).to.be(false); - }); - }); - - it('disables if insight.optOut is true and interactive', function () { - return mockAnalytics({ optOut: true }) - .setup({ interactive: true }) - .then(function (enabled) { - expect(enabled).to.be(false); - }); - }); - - it('enables if insight.optOut is false and interactive', function () { - return mockAnalytics({ optOut: false }) - .setup({ interactive: true }) - .then(function (enabled) { - expect(enabled).to.be(true); - }); - }); - - it('disables if insight.optOut is false and non-interactive', function () { - return mockAnalytics({ optOut: false }) - .setup({ interactive: false }) - .then(function (enabled) { - expect(enabled).to.be(false); - }); - }); - - it('enables if interactive insights return true from prompt', function () { - return mockAnalytics({ optOut: undefined }, true) - .setup({ interactive: true }) - .then(function (enabled) { - expect(enabled).to.be(true); - }); - }); - - it('disables if interactive insights return false from prompt', function () { - return mockAnalytics({ optOut: undefined }, false) - .setup({ interactive: true }) - .then(function (enabled) { - expect(enabled).to.be(false); - }); - }); - - it('disables if process.env.CI is true', function () { - process.env.CI = true; - - // Clear cache set by proxyquire - delete require.cache[require.resolve('../../lib/util/analytics')]; - - var analytics = require('../../lib/util/analytics'); - return analytics.setup({ interactive: true }) - .then(function (enabled) { - expect(enabled).to.be(false); - }); - }); - - it('disables if prompt times out', function () { - // Create mock insight with very low permission timeout - var Insight = require('insight'); - var mockInsight = new Insight({ - trackingCode: 'mock', - pkg: require('../../package.json') - }); - mockInsight._permissionTimeout = 0.1; - var mockAnalyticsWithInsight = proxyquire('../../lib/util/analytics', { - insight: function () { - return mockInsight; - } - }); - - return mockAnalyticsWithInsight - .setup({ interactive: true }) - .then(function (enabled) { - expect(enabled).to.be(false); - }); - }); - }); - - describe('Tracker', function (next) { - it('tracks if analytics = true', function(next) { - var analytics = mockAnalytics({ - track: function (arg) { - expect(arg).to.be('foo'); - next(); - } - }); - - new analytics.Tracker({ analytics: true }).track('foo'); - }); - - it('does not track if analytics = false', function () { - var analytics = mockAnalytics({ - track: function (arg) { - throw new Error(); - } - }); - - expect(function () { - new analytics.Tracker({ analytics: false }).track('foo'); - }).to.not.throwError(); - }); - - it('tracks if analytics = undefined and setup returns true', function(next) { - var analytics = mockAnalytics({ - track: function (arg) { - expect(arg).to.be('foo'); - next(); - } - }); - - analytics - .setup({ analytics: true }) - .then(function () { - new analytics.Tracker({}).track('foo'); - }); - }); - }); -}); diff --git a/test/util/index.js b/test/util/index.js index c98765f10..c955d56f7 100644 --- a/test/util/index.js +++ b/test/util/index.js @@ -1,6 +1,5 @@ describe('util', function () { require('./removeIgnores'); - require('./analytics'); require('./download'); require('./isPathAbsolute'); require('./relativeToBaseDir'); From 35e73a619a8a3bee600cdfc9ae31cf9ee50578ba Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 20 Jan 2016 14:06:48 +0100 Subject: [PATCH 0846/1021] Tolerate failure in covealls reporting --- Gruntfile.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index 965f6e3f3..b70a95602 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -66,7 +66,8 @@ module.exports = function (grunt) { command: 'node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' }, coveralls: { - command: 'npm run coveralls < test/reports/lcov.info' + command: 'npm run coveralls < test/reports/lcov.info', + exitCodes: [0,1,2,3] // Alow for failure for coverage report } }, watch: { From 11996c04b76d39d4048cc9d16af80fb41e95a781 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 20 Jan 2016 13:46:11 +0100 Subject: [PATCH 0847/1021] Update to fs-write-stream@1.0.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fea5a2e15..a136e11d5 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "configstore": "^0.3.2", "decompress-zip": "^0.1.0", "destroy": "^1.0.3", - "fs-write-stream-atomic": "1.0.5", + "fs-write-stream-atomic": "1.0.8", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", "github": "^0.2.3", From f3330e8612074604e5c2e55ea4fd7bec5283aeb0 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 20 Jan 2016 18:23:27 +0100 Subject: [PATCH 0848/1021] Update changelog and bump to 1.7.3 --- CHANGELOG.md | 12 ++++++++++++ package.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e6416c1f..4ab121fc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 1.7.3 - 2015-01-20 + +- Remove analytics from Bower, fixes ([#2150](https://github.com/bower/bower/pull/2150)) +- Default to ^ operator on `bower install --save` ([#2145](https://github.com/bower/bower/pull/2145)) +- Support absolute path in .bowerrc directory option ([#2130](https://github.com/bower/bower/pull/2130)) +- Display user's name upon `bower login` command ([#2133](https://github.com/bower/bower/pull/2133)) +- Decompress gzip files ([#2092](https://github.com/bower/bower/pull/2092)) +- Prevent name clashes in package extraction ([#2102](https://github.com/bower/bower/pull/2102)) +- Update request to 2.67.0 +- Update fs-write-stream-atomic to 1.0.8 +- Documentation improvements + ## 1.7.2 - 2015-12-31 - Lock "fs-write-stream-atomic" to 1.0.5 diff --git a/package.json b/package.json index a136e11d5..5f68168f3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.7.2", + "version": "1.7.3", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 9d2681b0c4c02c7abd4a273b3188491840ed6341 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 21 Jan 2016 13:43:17 +0100 Subject: [PATCH 0849/1021] Ignore test files in published package --- .npmignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .npmignore diff --git a/.npmignore b/.npmignore new file mode 100644 index 000000000..ba1a9eb6b --- /dev/null +++ b/.npmignore @@ -0,0 +1,4 @@ +test +appveyor.yml +Gruntfile.js +CONTRIBUTING.md From 1d73764788324de4241037b0cf34b2ec235eeb70 Mon Sep 17 00:00:00 2001 From: Piotr Wielgolaski Date: Wed, 6 Jan 2016 13:12:26 +0100 Subject: [PATCH 0850/1021] when strictSsl is false set GIT_SSL_NO_VERIFY=true for git command Solves #2129 --- lib/core/resolvers/GitResolver.js | 3 +++ test/core/resolvers/gitResolver.js | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/lib/core/resolvers/GitResolver.js b/lib/core/resolvers/GitResolver.js index cf66d3c4b..8d5ea13bd 100644 --- a/lib/core/resolvers/GitResolver.js +++ b/lib/core/resolvers/GitResolver.js @@ -26,6 +26,9 @@ function GitResolver(decEndpoint, config, logger) { // anyway mkdirp.sync(config.storage.empty); process.env.GIT_TEMPLATE_DIR = config.storage.empty; + if (!config.strictSsl) { + process.env.GIT_SSL_NO_VERIFY = 'true'; + } Resolver.call(this, decEndpoint, config, logger); diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index 0db338899..7dcd93f1c 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -15,6 +15,7 @@ var defaultConfig = require('../../../lib/config'); describe('GitResolver', function () { var tempDir = path.resolve(__dirname, '../../tmp/tmp'); var originalrefs = GitResolver.refs; + var originalEnv = process.env; var logger; before(function () { @@ -23,6 +24,7 @@ describe('GitResolver', function () { afterEach(function () { logger.removeAllListeners(); + process.env = originalEnv; }); function clearResolverRuntimeCache() { @@ -41,6 +43,18 @@ describe('GitResolver', function () { describe('misc', function () { it.skip('should error out if git is not installed'); it.skip('should setup git template dir to an empty folder'); + it('should set process.env.GIT_SSL_NO_VERIFY when strictSSL is false', function () { + var resolver; + var decEndpoint = { source: 'foo'}; + + expect(process.env).to.not.have.property('GIT_SSL_NO_VERIFY'); + + resolver = new GitResolver(decEndpoint, defaultConfig(), logger); + expect(process.env).to.not.have.property('GIT_SSL_NO_VERIFY'); + + resolver = new GitResolver(decEndpoint, defaultConfig({strictSsl: false}), logger); + expect(process.env).to.have.property('GIT_SSL_NO_VERIFY','true'); + }); }); describe('.hasNew', function () { From f0a54d0018927f8f1cf85cb6c7e12a37cea49333 Mon Sep 17 00:00:00 2001 From: Piotr Wielgolaski Date: Fri, 22 Jan 2016 20:17:45 +0100 Subject: [PATCH 0851/1021] set GIT_SSL_NO_VERIFY for opposite value than strictSsl --- lib/core/resolvers/GitResolver.js | 4 +--- test/core/resolvers/gitResolver.js | 8 +++++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/core/resolvers/GitResolver.js b/lib/core/resolvers/GitResolver.js index 8d5ea13bd..aa41ef29d 100644 --- a/lib/core/resolvers/GitResolver.js +++ b/lib/core/resolvers/GitResolver.js @@ -26,9 +26,7 @@ function GitResolver(decEndpoint, config, logger) { // anyway mkdirp.sync(config.storage.empty); process.env.GIT_TEMPLATE_DIR = config.storage.empty; - if (!config.strictSsl) { - process.env.GIT_SSL_NO_VERIFY = 'true'; - } + process.env.GIT_SSL_NO_VERIFY = (!config.strictSsl).toString(); Resolver.call(this, decEndpoint, config, logger); diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index 7dcd93f1c..4d7eba270 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -50,10 +50,16 @@ describe('GitResolver', function () { expect(process.env).to.not.have.property('GIT_SSL_NO_VERIFY'); resolver = new GitResolver(decEndpoint, defaultConfig(), logger); - expect(process.env).to.not.have.property('GIT_SSL_NO_VERIFY'); + expect(process.env).to.have.property('GIT_SSL_NO_VERIFY','false'); + delete process.env.GIT_SSL_NO_VERIFY; resolver = new GitResolver(decEndpoint, defaultConfig({strictSsl: false}), logger); expect(process.env).to.have.property('GIT_SSL_NO_VERIFY','true'); + delete process.env.GIT_SSL_NO_VERIFY; + + resolver = new GitResolver(decEndpoint, defaultConfig({strictSsl: true}), logger); + expect(process.env).to.have.property('GIT_SSL_NO_VERIFY','false'); + delete process.env.GIT_SSL_NO_VERIFY; }); }); From b485c5d3cbcad1c3ac5b1167a0716fcbadc51e0c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 25 Jan 2016 13:12:13 +0100 Subject: [PATCH 0852/1021] Remove bundledDependencies from package.json bundledDependencies will be filled only just before publish --- .gitignore | 1 + package.json | 48 ------------------------------------------------ 2 files changed, 1 insertion(+), 48 deletions(-) diff --git a/.gitignore b/.gitignore index 5ad35aeea..7984ffa59 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ /bower_components /test/sample !/test/sample/bower.json +/npm-shrinkwrap.json diff --git a/package.json b/package.json index 5f68168f3..e129be3db 100644 --- a/package.json +++ b/package.json @@ -83,54 +83,6 @@ "proxyquire": "^1.3.0", "spawn-sync": "1.0.13" }, - "bundledDependencies": [ - "abbrev", - "archy", - "bower-config", - "bower-endpoint-parser", - "bower-json", - "bower-logger", - "bower-registry-client", - "cardinal", - "chalk", - "chmodr", - "configstore", - "decompress-zip", - "destroy", - "fs-write-stream-atomic", - "fstream", - "fstream-ignore", - "github", - "glob", - "graceful-fs", - "handlebars", - "inquirer", - "is-root", - "junk", - "lockfile", - "lru-cache", - "md5-hex", - "mkdirp", - "mout", - "nopt", - "opn", - "p-throttler", - "promptly", - "q", - "request", - "request-progress", - "retry", - "rimraf", - "semver", - "semver-utils", - "shell-quote", - "stringify-object", - "tar-fs", - "tmp", - "update-notifier", - "user-home", - "which" - ], "scripts": { "test": "grunt test", "ci": "grunt travis", From 38c3cee1a71ee1d259c445a20cb8e98cc47f0d7f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 25 Jan 2016 16:50:06 +0100 Subject: [PATCH 0853/1021] Perform test on fake .git directory --- test/core/resolvers/gitResolver.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index 4d7eba270..db397d139 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -889,10 +889,8 @@ describe('GitResolver', function () { var resolver = create('foo'); var dst = path.join(tempDir, '.git'); - this.timeout(30000); // Give some time to copy - // Copy .git folder to the tempDir - copy.copyDir(path.resolve(__dirname, '../../../.git'), dst, { + copy.copyDir(path.resolve(__dirname, '../../assets/package-a/.git'), dst, { mode: 0777 }) .then(function () { From ad27112b586ddcaa5cb54050e05c3a0280f29807 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 25 Jan 2016 18:48:02 +0100 Subject: [PATCH 0854/1021] Do not assume package.json location --- bin/bower | 6 +++--- lib/core/resolverFactory.js | 2 +- lib/index.js | 4 ++-- lib/renderers/StandardRenderer.js | 4 ++-- lib/util/userAgent.js | 4 ++-- lib/version.js | 3 +++ package.json | 13 +++++-------- 7 files changed, 18 insertions(+), 18 deletions(-) create mode 100644 lib/version.js diff --git a/bin/bower b/bin/bower index aeedd77d4..cf4a63c9c 100755 --- a/bin/bower +++ b/bin/bower @@ -8,7 +8,7 @@ var mout = require('mout'); var Logger = require('bower-logger'); var userHome = require('user-home'); var bower = require('../lib'); -var pkg = require('../package.json'); +var version = require('../lib/version'); var cli = require('../lib/util/cli'); var rootCheck = require('../lib/util/rootCheck'); @@ -28,7 +28,7 @@ options = cli.readOptions({ // Handle print of version if (options.version) { - process.stdout.write(pkg.version + '\n'); + process.stdout.write(version + '\n'); process.exit(); } @@ -140,7 +140,7 @@ if (bower.config.interactive) { var updateNotifier = require('update-notifier'); // Check for newer version of Bower - var notifier = updateNotifier({pkg: pkg}); + var notifier = updateNotifier({ pkg: { name: 'bower', version: version } }); if (notifier.update && levels.info >= loglevel) { notifier.notify(); diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index e486c161a..4dbba7f35 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -11,7 +11,7 @@ var pluginResolverFactory = require('./resolvers/pluginResolverFactory'); function createInstance(decEndpoint, options, registryClient) { decEndpoint = mout.object.pick(decEndpoint, ['name', 'target', 'source']); - options.version = require('../../package.json').version; + options.version = require('../version'); return getConstructor(decEndpoint, options, registryClient) .spread(function (ConcreteResolver, decEndpoint) { diff --git a/lib/index.js b/lib/index.js index 28710aa89..a7ffe9df2 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,5 +1,5 @@ var commands = require('./commands'); -var pkg = require('../package.json'); +var version = require('./version'); var abbreviations = require('./abbreviations')(commands); function clearRuntimeCache() { @@ -11,7 +11,7 @@ function clearRuntimeCache() { } module.exports = { - version: pkg.version, + version: version, commands: commands, config: require('./config')(), abbreviations: abbreviations, diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index 60f0c7553..15c3f38be 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -6,7 +6,7 @@ var Q = require('q'); var stringifyObject = require('stringify-object'); var os = require('os'); var semverUtils = require('semver-utils'); -var pkg = require(path.join(__dirname, '../..', 'package.json')); +var version = require('../version'); var template = require('../util/template'); function StandardRenderer(command, config) { @@ -84,7 +84,7 @@ StandardRenderer.prototype.error = function (err) { // Print bower version, node version and system info. this._write(process.stderr, chalk.yellow('\nSystem info:\n')); - this._write(process.stderr, 'Bower version: ' + pkg.version + '\n'); + this._write(process.stderr, 'Bower version: ' + version + '\n'); this._write(process.stderr, 'Node version: ' + process.versions.node + '\n'); this._write(process.stderr, 'OS: ' + os.type() + ' ' + os.release() + ' ' + os.arch() + '\n'); } diff --git a/lib/util/userAgent.js b/lib/util/userAgent.js index b5200144e..3400b5bab 100644 --- a/lib/util/userAgent.js +++ b/lib/util/userAgent.js @@ -1,3 +1,3 @@ -var pkg = require('../../package.json'); +var version = require('../version'); -module.exports = 'node/' + process.version + ' ' + process.platform + ' ' + process.arch + ' ' + ';Bower ' + pkg.version; +module.exports = 'node/' + process.version + ' ' + process.platform + ' ' + process.arch + ' ' + ';Bower ' + version; diff --git a/lib/version.js b/lib/version.js new file mode 100644 index 000000000..2623cc007 --- /dev/null +++ b/lib/version.js @@ -0,0 +1,3 @@ +var findup = require('findup-sync'); + +module.exports = require(findup('package.json', { cwd: __dirname })).version; diff --git a/package.json b/package.json index e129be3db..d322a2cd4 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "license": "MIT", "repository": "bower/bower", "main": "lib", + "bin": "bin/bower", "homepage": "http://bower.io", "engines": { "node": ">=0.10.0" @@ -27,6 +28,7 @@ "configstore": "^0.3.2", "decompress-zip": "^0.1.0", "destroy": "^1.0.3", + "findup-sync": "^0.3.0", "fs-write-stream-atomic": "1.0.8", "fstream": "^1.0.3", "fstream-ignore": "^1.0.2", @@ -56,7 +58,7 @@ "shell-quote": "^1.4.2", "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", - "tmp": "0.0.24", + "tmp": "0.0.28", "update-notifier": "^0.6.0", "user-home": "^1.1.0", "which": "^1.0.8" @@ -66,6 +68,7 @@ "chai": "^1.10.0", "coveralls": "^2.11.2", "expect.js": "^0.3.1", + "fs-extra": "^0.26.4", "grunt": "^0.4.5", "grunt-cli": "^0.1.13", "grunt-contrib-jshint": "^0.10.0", @@ -88,11 +91,5 @@ "ci": "grunt travis", "coveralls": "coveralls", "prepublish": "in-publish && grunt prepublish || not-in-publish" - }, - "bin": "bin/bower", - "files": [ - "bin", - "lib", - "templates" - ] + } } From bbaaee67a1344739f1e88a201aedaf4cec83d812 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 25 Jan 2016 22:57:07 +0100 Subject: [PATCH 0855/1021] Update publishing script to bundle all modules --- Gruntfile.js | 156 ++++++++++++++--------------- package.json | 6 +- test/commands/update.js | 2 + test/core/resolvers/gitResolver.js | 6 +- 4 files changed, 84 insertions(+), 86 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index b70a95602..513fb913b 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,9 +1,12 @@ 'use strict'; +var tmp = require('tmp'); var childProcess = require('child_process'); var arraydiff = require('arr-diff'); var fs = require('fs'); +var wrench = require('wrench'); var inquirer = require('inquirer'); +var path = require('path'); module.exports = function (grunt) { require('load-grunt-tasks')(grunt); @@ -82,7 +85,7 @@ module.exports = function (grunt) { grunt.registerTask('travis', ['jshint', 'exec:assets', 'exec:cover', 'exec:coveralls']); grunt.registerTask('default', 'test'); - grunt.task.registerTask('prepublish', 'Prepublish checks', function () { + grunt.task.registerTask('publish', 'Perform final checks and publish Bower', function () { var npmVersion = JSON.parse(childProcess.execSync('npm version --json').toString()).npm.split('.'); var npmMajor = parseInt(npmVersion[0], 10); var npmMinor = parseInt(npmVersion[1], 10); @@ -94,22 +97,6 @@ module.exports = function (grunt) { process.exit(1); } - var bundledDependencies = require('./package').bundledDependencies; - var dependencies = Object.keys(require('./package').dependencies); - var missing = arraydiff(dependencies, bundledDependencies); - - if (missing.length > 0) { - grunt.log.writeln('You need to add all bower\'s dependencies to bundledDependencies in package.json'); - grunt.log.writeln('It is to freeze all dependencies so bower does not randomly break'); - grunt.log.writeln('Following dependencies need to be added to bundledDependencies:'); - - for(var i = 0; i < missing.length; i++) { - grunt.log.writeln(' "' + missing[i] + '",\n'); - } - - process.exit(1); - } - var version = require('./package').version; var changelog = fs.readFileSync('./CHANGELOG.md'); @@ -137,6 +124,66 @@ module.exports = function (grunt) { grunt.log.writeln('Running test suite...'); childProcess.execSync('grunt test', { stdio: [0, 1, 2] }); + var dir = tmp.dirSync().name; + var pkgDir = path.resolve(dir, 'lib'); + + wrench.copyDirSyncRecursive(__dirname, pkgDir, { + forceDelete: true, + include: function (path) { + return !path.match(/node_modules|\.git|test/); + } + }); + + grunt.log.writeln('Installing dependencies'); + childProcess.execSync('npm install --production --silent', { cwd: pkgDir, stdio: [0, 1, 2] }); + + fs.createReadStream( + path.resolve(__dirname, 'README.md') + ).pipe( + fs.createWriteStream(path.resolve(dir, 'README.md')) + ); + + var json = require('./package'); + json.bin = 'lib/' + json.bin; + json.main = 'lib/' + json.main; + delete json.dependencies; + delete json.devDependencies; + delete json.scripts; + delete json.files; + + fs.writeFileSync(path.resolve(dir, 'package.json'), JSON.stringify(json, null, ' ')); + + // So node_modules are not ignored + fs.unlinkSync(path.resolve(pkgDir, 'package.json')); + + childProcess.execSync('npm install --production --silent', { cwd: pkgDir, stdio: [0, 1, 2] }); + + grunt.log.writeln('Testing bower on sample project...'); + + childProcess.execSync( + 'cd test/sample && rm -rf bower_components && ' + pkgDir + '/bin/bower install --force', { stdio: [0, 1, 2] } + ); + + var expectedPackages = ( + 'SHA-1 ace-builds almond angular angular-animate angular-bootstrap angular-charts angular-contenteditable ' + + 'angular-deckgrid angular-fullscreen angular-gravatar angular-hotkeys angular-local-storage angular-marked ' + + 'angular-moment angular-sanitize angular-touch angular-ui-router angular-ui-sortable ' + + 'angulartics asEvented bootstrap coffee-script d3 es6-shim font-awesome howler jquery ' + + 'jquery-ui jquery-waypoints js-beautify lodash lz-string marked moment ng-file-upload peerjs ' + + 'requirejs restangular slimScroll slimScrollHorizontal venturocket-angular-slider' + ).split(' '); + + var installedPackages = fs.readdirSync('./test/sample/bower_components'); + + var installedDiff = arraydiff(expectedPackages, installedPackages); + + if (installedDiff.length > 0) { + grunt.log.writeln('ERROR. Some packages were not installed by bower: '); + grunt.log.writeln(installedDiff.join(', ')); + + process.exit(1); + } + var questions = [ { type: 'confirm', @@ -155,82 +202,31 @@ module.exports = function (grunt) { name: 'tests', message: 'Are you sure all tests are passing on Travis and Appveyor?', default: false + }, + { + type: 'confirm', + name: 'publish', + message: 'Are you SURE you want to publish ' + require('./package').name + '@' + require('./package').version + '?', + default: false } ]; var done = this.async(); inquirer.prompt(questions, function (answers) { - if (!answers.review || !answers.changelog || !answers.tests) { + if (!answers.review || !answers.changelog || !answers.tests || !answers.publish) { grunt.log.writeln('Please publish bower after you fix this issue'); process.exit(1); } - try { - grunt.log.writeln('Reinstalling dependencies in production mode...'); - - childProcess.execSync('rm -rf node_modules && npm install --production', { stdio: [0, 1, 2] }); - - grunt.log.writeln('Testing bower on sample project...'); - - childProcess.execSync( - 'cd test/sample && rm -rf bower_components && ../../bin/bower install --force', { stdio: [0, 1, 2] } - ); - - var expectedPackages = ( - 'SHA-1 ace-builds almond angular angular-animate angular-bootstrap angular-charts angular-contenteditable ' + - 'angular-deckgrid angular-fullscreen angular-gravatar angular-hotkeys angular-local-storage angular-marked ' + - 'angular-moment angular-sanitize angular-touch angular-ui-router angular-ui-sortable ' + - 'angulartics asEvented bootstrap coffee-script d3 es6-shim font-awesome howler jquery ' + - 'jquery-ui jquery-waypoints js-beautify lodash lz-string marked moment ng-file-upload peerjs ' + - 'requirejs restangular slimScroll slimScrollHorizontal venturocket-angular-slider' - ).split(' '); - - var installedPackages = fs.readdirSync('./test/sample/bower_components'); - - var installedDiff = arraydiff(expectedPackages, installedPackages); - - if (installedDiff.length > 0) { - grunt.log.writeln('ERROR. Some packages were not installed by bower: '); - grunt.log.writeln(installedDiff.join(', ')); - - process.exit(1); - } - } catch (e) { - grunt.log.writeln('There was an error. Reverting development dependencies...'); - - childProcess.execSync('npm install', { stdio: [0, 1, 2] }); - - process.exit(1); - } - - grunt.log.writeln('Everything seems OK! You are likely good to publish bower.'); - - var questions = [ - { - type: 'confirm', - name: 'publish', - message: 'Are you SURE you want to publish bower@' + require('./package').version + '?', - default: false - } - ]; - - inquirer.prompt(questions, function (answers) { - if (!answers.publish) { - grunt.log.writeln('Bower publishing cancelled..'); - - childProcess.execSync('npm install', { stdio: [0, 1, 2] }); - - process.exit(1); - } + grunt.log.writeln('\nPlease remember to tag this relese, and add a release on Github!'); + grunt.log.writeln('\nAlso, please remember to test published Bower one more time!'); + grunt.log.writeln('\nPublishing Bower...'); - grunt.log.writeln('\nPlease remember to tag this relese, and add a release on Github!'); - grunt.log.writeln('\nAlso, please remember to test published Bower one more time!'); - grunt.log.writeln('\nPublishing Bower...'); + childProcess.execSync('npm publish', { cwd: dir, stdio: [0, 1, 2] }); - done(); - }); + done(); }); }); }; diff --git a/package.json b/package.json index d322a2cd4..06f5acd72 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,6 @@ "chai": "^1.10.0", "coveralls": "^2.11.2", "expect.js": "^0.3.1", - "fs-extra": "^0.26.4", "grunt": "^0.4.5", "grunt-cli": "^0.1.13", "grunt-contrib-jshint": "^0.10.0", @@ -84,12 +83,13 @@ "nock": "^3.1.0", "node-uuid": "^1.4.2", "proxyquire": "^1.3.0", - "spawn-sync": "1.0.13" + "spawn-sync": "1.0.13", + "wrench": "^1.5.8" }, "scripts": { "test": "grunt test", "ci": "grunt travis", "coveralls": "coveralls", - "prepublish": "in-publish && grunt prepublish || not-in-publish" + "prepublish": "in-publish && echo 'You need to use \"grunt publush\" to publish bower' && false || not-in-publish" } } diff --git a/test/commands/update.js b/test/commands/update.js index 7e2d31e91..d889809c8 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -262,6 +262,8 @@ describe('bower update', function () { }); it('does not install ignored dependencies when updating a package', function () { + this.timeout(15000); + var package3 = new helpers.TempDir({ 'bower.json': { name: 'package3' diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index db397d139..2ec33ad8f 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -50,15 +50,15 @@ describe('GitResolver', function () { expect(process.env).to.not.have.property('GIT_SSL_NO_VERIFY'); resolver = new GitResolver(decEndpoint, defaultConfig(), logger); - expect(process.env).to.have.property('GIT_SSL_NO_VERIFY','false'); + expect(process.env).to.have.property('GIT_SSL_NO_VERIFY', 'false'); delete process.env.GIT_SSL_NO_VERIFY; resolver = new GitResolver(decEndpoint, defaultConfig({strictSsl: false}), logger); - expect(process.env).to.have.property('GIT_SSL_NO_VERIFY','true'); + expect(process.env).to.have.property('GIT_SSL_NO_VERIFY', 'true'); delete process.env.GIT_SSL_NO_VERIFY; resolver = new GitResolver(decEndpoint, defaultConfig({strictSsl: true}), logger); - expect(process.env).to.have.property('GIT_SSL_NO_VERIFY','false'); + expect(process.env).to.have.property('GIT_SSL_NO_VERIFY', 'false'); delete process.env.GIT_SSL_NO_VERIFY; }); }); From e5d478a1cc15f01a916b67d30198d6dea0a6a788 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 26 Jan 2016 22:35:11 +0100 Subject: [PATCH 0856/1021] Bump to 1.7.5 and update changelog --- CHANGELOG.md | 19 +++++++++++++++---- package.json | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ab121fc8..5630324b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,28 @@ # Changelog -## 1.7.3 - 2015-01-20 +## 1.7.5 - 2015-01-26 -- Remove analytics from Bower, fixes ([#2150](https://github.com/bower/bower/pull/2150)) +- Remove analytics from Bower, fixes ([#2150](https://github.com/bower/bower/pull/2150)) - Default to ^ operator on `bower install --save` ([#2145](https://github.com/bower/bower/pull/2145)) - Support absolute path in .bowerrc directory option ([#2130](https://github.com/bower/bower/pull/2130)) - Display user's name upon `bower login` command ([#2133](https://github.com/bower/bower/pull/2133)) - Decompress gzip files ([#2092](https://github.com/bower/bower/pull/2092)) - Prevent name clashes in package extraction ([#2102](https://github.com/bower/bower/pull/2102)) -- Update request to 2.67.0 -- Update fs-write-stream-atomic to 1.0.8 +- When strictSsl is false, set GIT_SSL_NO_VERIFY=true ([#2129](https://github.com/bower/bower/issues/2129)) +- Distribute bower with npm@3 for better Windows support ([#2146](https://github.com/bower/bower/issues/2146)) +- Update request to 2.67.0 and fs-write-stream-atomic to 1.0.8 - Documentation improvements +## 1.7.4 - 2015-01-21 + +Unpublished because of issue with npm distribution: +https://github.com/npm/npm/issues/11227 + +## 1.7.3 - 2015-01-20 + +Unpublished because of issue with npm distribution: +https://github.com/npm/npm/issues/11227 + ## 1.7.2 - 2015-12-31 - Lock "fs-write-stream-atomic" to 1.0.5 diff --git a/package.json b/package.json index 06f5acd72..3a73b7c32 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.7.3", + "version": "1.7.5", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 8194bcb4c6aa597da2af2d4cf9f811f17f8bda3f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 27 Jan 2016 11:51:42 +0100 Subject: [PATCH 0857/1021] Revert bin/bower location and bump to 1.7.6 --- CHANGELOG.md | 5 +++++ Gruntfile.js | 8 +++++--- package.json | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5630324b8..fc6e2cc06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.7.6 - 2015-01-27 + +- Revert location of "bin/bower" as developers are using it directly ([#2157](https://github.com/bower/bower/issues/2157)) + Note: Correctly, you should use an alias created in `npm bin --global`. + ## 1.7.5 - 2015-01-26 - Remove analytics from Bower, fixes ([#2150](https://github.com/bower/bower/pull/2150)) diff --git a/Gruntfile.js b/Gruntfile.js index 513fb913b..68c740636 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -144,14 +144,16 @@ module.exports = function (grunt) { ); var json = require('./package'); - json.bin = 'lib/' + json.bin; - json.main = 'lib/' + json.main; delete json.dependencies; delete json.devDependencies; delete json.scripts; delete json.files; fs.writeFileSync(path.resolve(dir, 'package.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync(path.resolve(dir, 'lib/index.js'), 'module.exports = require(\'./lib\');\n'); + fs.mkdirSync(path.resolve(dir, 'bin')); + fs.writeFileSync(path.resolve(dir, 'bin/bower'), '#!/usr/bin/env node\nrequire(\'../lib/bin/bower\');\n'); + fs.chmodSync(path.resolve(dir, 'bin/bower'), '0755'); // So node_modules are not ignored fs.unlinkSync(path.resolve(pkgDir, 'package.json')); @@ -224,7 +226,7 @@ module.exports = function (grunt) { grunt.log.writeln('\nAlso, please remember to test published Bower one more time!'); grunt.log.writeln('\nPublishing Bower...'); - childProcess.execSync('npm publish', { cwd: dir, stdio: [0, 1, 2] }); + childProcess.execSync('npm publish --tag beta', { cwd: dir, stdio: [0, 1, 2] }); done(); }); diff --git a/package.json b/package.json index 3a73b7c32..206383534 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.7.5", + "version": "1.7.6", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 4b4a854ed84db51d5540374ba4b411451dfad736 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 27 Jan 2016 14:47:18 +0100 Subject: [PATCH 0858/1021] Restore directory structure for published bower It's because people are depending on internals of bower, like "bower/lib/renderers/StandardRenderer" Instead we move templates and bin to lib directory and leave paths intact. Additionally we alias bin/bower to lib/bin/bower. --- .npmignore | 4 - Gruntfile.js | 42 +++-- bin/bower | 147 +----------------- lib/commands/help.js | 4 +- .../templates}/helpers/colors.js | 0 .../templates}/helpers/condense.js | 0 .../templates}/helpers/indent.js | 0 {templates => lib/templates}/helpers/index.js | 0 {templates => lib/templates}/helpers/rpad.js | 0 {templates => lib/templates}/helpers/sum.js | 0 .../templates}/json/help-cache.json | 0 .../templates}/json/help-cache/clean.json | 0 .../templates}/json/help-cache/list.json | 0 .../templates}/json/help-home.json | 0 .../templates}/json/help-info.json | 0 .../templates}/json/help-init.json | 0 .../templates}/json/help-install.json | 0 .../templates}/json/help-link.json | 0 .../templates}/json/help-list.json | 0 .../templates}/json/help-login.json | 0 .../templates}/json/help-lookup.json | 0 .../templates}/json/help-prune.json | 0 .../templates}/json/help-register.json | 0 .../templates}/json/help-search.json | 0 .../templates}/json/help-uninstall.json | 0 .../templates}/json/help-unregister.json | 0 .../templates}/json/help-update.json | 0 .../templates}/json/help-version.json | 0 {templates => lib/templates}/json/help.json | 0 .../templates}/std/conflict-resolved.std | 0 {templates => lib/templates}/std/conflict.std | 0 .../templates}/std/help-cache.std | 0 .../templates}/std/help-generic.std | 0 {templates => lib/templates}/std/help.std | 0 {templates => lib/templates}/std/info.std | 0 {templates => lib/templates}/std/lookup.std | 0 {templates => lib/templates}/std/register.std | 0 .../templates}/std/search-results.std | 0 lib/util/template.js | 4 +- package.json | 5 +- 40 files changed, 26 insertions(+), 180 deletions(-) delete mode 100644 .npmignore rename {templates => lib/templates}/helpers/colors.js (100%) rename {templates => lib/templates}/helpers/condense.js (100%) rename {templates => lib/templates}/helpers/indent.js (100%) rename {templates => lib/templates}/helpers/index.js (100%) rename {templates => lib/templates}/helpers/rpad.js (100%) rename {templates => lib/templates}/helpers/sum.js (100%) rename {templates => lib/templates}/json/help-cache.json (100%) rename {templates => lib/templates}/json/help-cache/clean.json (100%) rename {templates => lib/templates}/json/help-cache/list.json (100%) rename {templates => lib/templates}/json/help-home.json (100%) rename {templates => lib/templates}/json/help-info.json (100%) rename {templates => lib/templates}/json/help-init.json (100%) rename {templates => lib/templates}/json/help-install.json (100%) rename {templates => lib/templates}/json/help-link.json (100%) rename {templates => lib/templates}/json/help-list.json (100%) rename {templates => lib/templates}/json/help-login.json (100%) rename {templates => lib/templates}/json/help-lookup.json (100%) rename {templates => lib/templates}/json/help-prune.json (100%) rename {templates => lib/templates}/json/help-register.json (100%) rename {templates => lib/templates}/json/help-search.json (100%) rename {templates => lib/templates}/json/help-uninstall.json (100%) rename {templates => lib/templates}/json/help-unregister.json (100%) rename {templates => lib/templates}/json/help-update.json (100%) rename {templates => lib/templates}/json/help-version.json (100%) rename {templates => lib/templates}/json/help.json (100%) rename {templates => lib/templates}/std/conflict-resolved.std (100%) rename {templates => lib/templates}/std/conflict.std (100%) rename {templates => lib/templates}/std/help-cache.std (100%) rename {templates => lib/templates}/std/help-generic.std (100%) rename {templates => lib/templates}/std/help.std (100%) rename {templates => lib/templates}/std/info.std (100%) rename {templates => lib/templates}/std/lookup.std (100%) rename {templates => lib/templates}/std/register.std (100%) rename {templates => lib/templates}/std/search-results.std (100%) diff --git a/.npmignore b/.npmignore deleted file mode 100644 index ba1a9eb6b..000000000 --- a/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -test -appveyor.yml -Gruntfile.js -CONTRIBUTING.md diff --git a/Gruntfile.js b/Gruntfile.js index 68c740636..f70f8c022 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -118,52 +118,43 @@ module.exports = function (grunt) { process.exit(1); } - grunt.log.writeln('Reinstalling dependencies...'); - childProcess.execSync('rm -rf node_modules && npm install', { stdio: [0, 1, 2] }); + if (process.env.SKIP_TESTS !== '1') { + grunt.log.writeln('Reinstalling dependencies...'); + childProcess.execSync('rm -rf node_modules && npm install', { stdio: [0, 1, 2] }); - grunt.log.writeln('Running test suite...'); - childProcess.execSync('grunt test', { stdio: [0, 1, 2] }); + grunt.log.writeln('Running test suite...'); + childProcess.execSync('grunt test', { stdio: [0, 1, 2] }); + } var dir = tmp.dirSync().name; - var pkgDir = path.resolve(dir, 'lib'); - wrench.copyDirSyncRecursive(__dirname, pkgDir, { + wrench.copyDirSyncRecursive(__dirname, dir, { forceDelete: true, include: function (path) { return !path.match(/node_modules|\.git|test/); } }); - grunt.log.writeln('Installing dependencies'); - childProcess.execSync('npm install --production --silent', { cwd: pkgDir, stdio: [0, 1, 2] }); - - fs.createReadStream( - path.resolve(__dirname, 'README.md') - ).pipe( - fs.createWriteStream(path.resolve(dir, 'README.md')) - ); + grunt.log.writeln('Installing production dependencies...'); + childProcess.execSync('npm install --production --silent', { cwd: dir, stdio: [0, 1, 2] }); var json = require('./package'); delete json.dependencies; delete json.devDependencies; delete json.scripts; - delete json.files; - fs.writeFileSync(path.resolve(dir, 'package.json'), JSON.stringify(json, null, ' ')); - fs.writeFileSync(path.resolve(dir, 'lib/index.js'), 'module.exports = require(\'./lib\');\n'); - fs.mkdirSync(path.resolve(dir, 'bin')); - fs.writeFileSync(path.resolve(dir, 'bin/bower'), '#!/usr/bin/env node\nrequire(\'../lib/bin/bower\');\n'); - fs.chmodSync(path.resolve(dir, 'bin/bower'), '0755'); + fs.writeFileSync(path.resolve(dir, 'package.json'), JSON.stringify(json, null, ' ') + '\n'); - // So node_modules are not ignored - fs.unlinkSync(path.resolve(pkgDir, 'package.json')); - childProcess.execSync('npm install --production --silent', { cwd: pkgDir, stdio: [0, 1, 2] }); + grunt.log.writeln('Moving node_modules to lib directory...'); + + wrench.copyDirSyncRecursive(path.resolve(dir, 'node_modules'), path.resolve(dir, 'lib', 'node_modules')); + wrench.rmdirSyncRecursive(path.resolve(dir, 'node_modules')); grunt.log.writeln('Testing bower on sample project...'); childProcess.execSync( - 'cd test/sample && rm -rf bower_components && ' + pkgDir + '/bin/bower install --force', { stdio: [0, 1, 2] } + 'cd test/sample && rm -rf bower_components && ' + dir + '/bin/bower install --force', { stdio: [0, 1, 2] } ); var expectedPackages = ( @@ -186,6 +177,9 @@ module.exports = function (grunt) { process.exit(1); } + grunt.log.writeln('\nBower production bundle installed in:'); + grunt.log.writeln(dir + '\n'); + var questions = [ { type: 'confirm', diff --git a/bin/bower b/bin/bower index cf4a63c9c..9ec5153c1 100755 --- a/bin/bower +++ b/bin/bower @@ -1,148 +1,3 @@ #!/usr/bin/env node -'use strict'; -process.bin = process.title = 'bower'; - -var Q = require('q'); -var mout = require('mout'); -var Logger = require('bower-logger'); -var userHome = require('user-home'); -var bower = require('../lib'); -var version = require('../lib/version'); -var cli = require('../lib/util/cli'); -var rootCheck = require('../lib/util/rootCheck'); - -var options; -var renderer; -var loglevel; -var command; -var commandFunc; -var logger; -var levels = Logger.LEVELS; - -options = cli.readOptions({ - version: { type: Boolean, shorthand: 'v' }, - help: { type: Boolean, shorthand: 'h' }, - 'allow-root': { type: Boolean } -}); - -// Handle print of version -if (options.version) { - process.stdout.write(version + '\n'); - process.exit(); -} - -// Root check -rootCheck(options, bower.config); - -// Set loglevel -if (bower.config.silent) { - loglevel = levels.error; -} else if (bower.config.verbose) { - loglevel = -Infinity; - Q.longStackSupport = true; -} else if (bower.config.quiet) { - loglevel = levels.warn; -} else { - loglevel = levels[bower.config.loglevel] || levels.info; -} - -// Get the command to execute -while (options.argv.remain.length) { - command = options.argv.remain.join(' '); - - // Alias lookup - if (bower.abbreviations[command]) { - command = bower.abbreviations[command].replace(/\s/g, '.'); - break; - } - - command = command.replace(/\s/g, '.'); - - // Direct lookup - if (mout.object.has(bower.commands, command)) { - break; - } - - options.argv.remain.pop(); -} - -// Execute the command -commandFunc = command && mout.object.get(bower.commands, command); -command = command && command.replace(/\./g, ' '); - -// If no command was specified, show bower help -// Do the same if the command is unknown -if (!commandFunc) { - logger = bower.commands.help(); - command = 'help'; -// If the user requested help, show the command's help -// Do the same if the actual command is a group of other commands (e.g.: cache) -} else if (options.help || !commandFunc.line) { - logger = bower.commands.help(command); - command = 'help'; -// Call the line method -} else { - logger = commandFunc.line(process.argv); - - // If the method failed to interpret the process arguments - // show the command help - if (!logger) { - logger = bower.commands.help(command); - command = 'help'; - } -} - -// Get the renderer and configure it with the executed command -renderer = cli.getRenderer(command, logger.json, bower.config); - -function handleLogger(logger, renderer) { - logger - .on('end', function (data) { - if (!bower.config.silent && !bower.config.quiet) { - renderer.end(data); - } - }) - .on('error', function (err) { - if (command !== 'help' && err.code === cli.READ_OPTIONS_ERROR_CODE) { - logger = bower.commands.help(command); - renderer = cli.getRenderer('help', logger.json, bower.config); - handleLogger(logger, renderer); - } else { - if (levels.error >= loglevel) { - renderer.error(err); - } - - process.exit(1); - } - }) - .on('log', function (log) { - if (levels[log.level] >= loglevel) { - renderer.log(log); - } - }) - .on('prompt', function (prompt, callback) { - renderer.prompt(prompt) - .then(function (answer) { - callback(answer); - }); - }); -} - -handleLogger(logger, renderer); - -// Warn if HOME is not SET -if (!userHome) { - logger.warn('no-home', 'HOME environment variable not set. User config will not be loaded.'); -} - -if (bower.config.interactive) { - var updateNotifier = require('update-notifier'); - - // Check for newer version of Bower - var notifier = updateNotifier({ pkg: { name: 'bower', version: version } }); - - if (notifier.update && levels.info >= loglevel) { - notifier.notify(); - } -} +require('../lib/bin/bower'); diff --git a/lib/commands/help.js b/lib/commands/help.js index e8d5a8a58..4501daf76 100644 --- a/lib/commands/help.js +++ b/lib/commands/help.js @@ -7,9 +7,9 @@ function help(logger, name, config) { var json; if (name) { - json = path.resolve(__dirname, '../../templates/json/help-' + name.replace(/\s+/g, '/') + '.json'); + json = path.resolve(__dirname, '../templates/json/help-' + name.replace(/\s+/g, '/') + '.json'); } else { - json = path.resolve(__dirname, '../../templates/json/help.json'); + json = path.resolve(__dirname, '../templates/json/help.json'); } return Q.promise(function (resolve) { diff --git a/templates/helpers/colors.js b/lib/templates/helpers/colors.js similarity index 100% rename from templates/helpers/colors.js rename to lib/templates/helpers/colors.js diff --git a/templates/helpers/condense.js b/lib/templates/helpers/condense.js similarity index 100% rename from templates/helpers/condense.js rename to lib/templates/helpers/condense.js diff --git a/templates/helpers/indent.js b/lib/templates/helpers/indent.js similarity index 100% rename from templates/helpers/indent.js rename to lib/templates/helpers/indent.js diff --git a/templates/helpers/index.js b/lib/templates/helpers/index.js similarity index 100% rename from templates/helpers/index.js rename to lib/templates/helpers/index.js diff --git a/templates/helpers/rpad.js b/lib/templates/helpers/rpad.js similarity index 100% rename from templates/helpers/rpad.js rename to lib/templates/helpers/rpad.js diff --git a/templates/helpers/sum.js b/lib/templates/helpers/sum.js similarity index 100% rename from templates/helpers/sum.js rename to lib/templates/helpers/sum.js diff --git a/templates/json/help-cache.json b/lib/templates/json/help-cache.json similarity index 100% rename from templates/json/help-cache.json rename to lib/templates/json/help-cache.json diff --git a/templates/json/help-cache/clean.json b/lib/templates/json/help-cache/clean.json similarity index 100% rename from templates/json/help-cache/clean.json rename to lib/templates/json/help-cache/clean.json diff --git a/templates/json/help-cache/list.json b/lib/templates/json/help-cache/list.json similarity index 100% rename from templates/json/help-cache/list.json rename to lib/templates/json/help-cache/list.json diff --git a/templates/json/help-home.json b/lib/templates/json/help-home.json similarity index 100% rename from templates/json/help-home.json rename to lib/templates/json/help-home.json diff --git a/templates/json/help-info.json b/lib/templates/json/help-info.json similarity index 100% rename from templates/json/help-info.json rename to lib/templates/json/help-info.json diff --git a/templates/json/help-init.json b/lib/templates/json/help-init.json similarity index 100% rename from templates/json/help-init.json rename to lib/templates/json/help-init.json diff --git a/templates/json/help-install.json b/lib/templates/json/help-install.json similarity index 100% rename from templates/json/help-install.json rename to lib/templates/json/help-install.json diff --git a/templates/json/help-link.json b/lib/templates/json/help-link.json similarity index 100% rename from templates/json/help-link.json rename to lib/templates/json/help-link.json diff --git a/templates/json/help-list.json b/lib/templates/json/help-list.json similarity index 100% rename from templates/json/help-list.json rename to lib/templates/json/help-list.json diff --git a/templates/json/help-login.json b/lib/templates/json/help-login.json similarity index 100% rename from templates/json/help-login.json rename to lib/templates/json/help-login.json diff --git a/templates/json/help-lookup.json b/lib/templates/json/help-lookup.json similarity index 100% rename from templates/json/help-lookup.json rename to lib/templates/json/help-lookup.json diff --git a/templates/json/help-prune.json b/lib/templates/json/help-prune.json similarity index 100% rename from templates/json/help-prune.json rename to lib/templates/json/help-prune.json diff --git a/templates/json/help-register.json b/lib/templates/json/help-register.json similarity index 100% rename from templates/json/help-register.json rename to lib/templates/json/help-register.json diff --git a/templates/json/help-search.json b/lib/templates/json/help-search.json similarity index 100% rename from templates/json/help-search.json rename to lib/templates/json/help-search.json diff --git a/templates/json/help-uninstall.json b/lib/templates/json/help-uninstall.json similarity index 100% rename from templates/json/help-uninstall.json rename to lib/templates/json/help-uninstall.json diff --git a/templates/json/help-unregister.json b/lib/templates/json/help-unregister.json similarity index 100% rename from templates/json/help-unregister.json rename to lib/templates/json/help-unregister.json diff --git a/templates/json/help-update.json b/lib/templates/json/help-update.json similarity index 100% rename from templates/json/help-update.json rename to lib/templates/json/help-update.json diff --git a/templates/json/help-version.json b/lib/templates/json/help-version.json similarity index 100% rename from templates/json/help-version.json rename to lib/templates/json/help-version.json diff --git a/templates/json/help.json b/lib/templates/json/help.json similarity index 100% rename from templates/json/help.json rename to lib/templates/json/help.json diff --git a/templates/std/conflict-resolved.std b/lib/templates/std/conflict-resolved.std similarity index 100% rename from templates/std/conflict-resolved.std rename to lib/templates/std/conflict-resolved.std diff --git a/templates/std/conflict.std b/lib/templates/std/conflict.std similarity index 100% rename from templates/std/conflict.std rename to lib/templates/std/conflict.std diff --git a/templates/std/help-cache.std b/lib/templates/std/help-cache.std similarity index 100% rename from templates/std/help-cache.std rename to lib/templates/std/help-cache.std diff --git a/templates/std/help-generic.std b/lib/templates/std/help-generic.std similarity index 100% rename from templates/std/help-generic.std rename to lib/templates/std/help-generic.std diff --git a/templates/std/help.std b/lib/templates/std/help.std similarity index 100% rename from templates/std/help.std rename to lib/templates/std/help.std diff --git a/templates/std/info.std b/lib/templates/std/info.std similarity index 100% rename from templates/std/info.std rename to lib/templates/std/info.std diff --git a/templates/std/lookup.std b/lib/templates/std/lookup.std similarity index 100% rename from templates/std/lookup.std rename to lib/templates/std/lookup.std diff --git a/templates/std/register.std b/lib/templates/std/register.std similarity index 100% rename from templates/std/register.std rename to lib/templates/std/register.std diff --git a/templates/std/search-results.std b/lib/templates/std/search-results.std similarity index 100% rename from templates/std/search-results.std rename to lib/templates/std/search-results.std diff --git a/lib/util/template.js b/lib/util/template.js index 660f7e109..23fe1310c 100644 --- a/lib/util/template.js +++ b/lib/util/template.js @@ -2,9 +2,9 @@ var path = require('path'); var fs = require('./fs'); var Handlebars = require('handlebars'); var mout = require('mout'); -var helpers = require('../../templates/helpers'); +var helpers = require('../templates/helpers'); -var templatesDir = path.resolve(__dirname, '../../templates'); +var templatesDir = path.resolve(__dirname, '../templates'); var cache = {}; // Register helpers diff --git a/package.json b/package.json index 206383534..dac0685af 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,7 @@ "test": "grunt test", "ci": "grunt travis", "coveralls": "coveralls", - "prepublish": "in-publish && echo 'You need to use \"grunt publush\" to publish bower' && false || not-in-publish" - } + "prepublish": "in-publish && echo 'You need to use \"grunt publish\" to publish bower' && false || not-in-publish" + }, + "files": [ "bin", "lib" ] } From cd7bbab31081f4aaa2679b215fbb279bfeaed75f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 27 Jan 2016 15:05:27 +0100 Subject: [PATCH 0859/1021] Bump to 1.7.7 --- CHANGELOG.md | 9 +++++++++ package.json | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc6e2cc06..4ce5321f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 1.7.7 - 2015-01-27 + +Revert locations of all files while still packaging `node_modules`. + +It's because people are depending on internals of bower, like +`bower/lib/renderers/StandardRenderer`. We want to preserve this +implicit contract, but we discourage it. The only official way +to use bower programmatically is through `require('bower')`. + ## 1.7.6 - 2015-01-27 - Revert location of "bin/bower" as developers are using it directly ([#2157](https://github.com/bower/bower/issues/2157)) diff --git a/package.json b/package.json index dac0685af..81efd4aef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.7.6", + "version": "1.7.7", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 6c67d07cc84ffa3ead9b0de671ddf29702e19e38 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 27 Jan 2016 15:37:13 +0100 Subject: [PATCH 0860/1021] Add missing lib/bin/bower.js file --- lib/bin/bower.js | 145 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 lib/bin/bower.js diff --git a/lib/bin/bower.js b/lib/bin/bower.js new file mode 100644 index 000000000..e5f399760 --- /dev/null +++ b/lib/bin/bower.js @@ -0,0 +1,145 @@ +process.bin = process.title = 'bower'; + +var Q = require('q'); +var mout = require('mout'); +var Logger = require('bower-logger'); +var userHome = require('user-home'); +var bower = require('../'); +var version = require('../version'); +var cli = require('../util/cli'); +var rootCheck = require('../util/rootCheck'); + +var options; +var renderer; +var loglevel; +var command; +var commandFunc; +var logger; +var levels = Logger.LEVELS; + +options = cli.readOptions({ + version: { type: Boolean, shorthand: 'v' }, + help: { type: Boolean, shorthand: 'h' }, + 'allow-root': { type: Boolean } +}); + +// Handle print of version +if (options.version) { + process.stdout.write(version + '\n'); + process.exit(); +} + +// Root check +rootCheck(options, bower.config); + +// Set loglevel +if (bower.config.silent) { + loglevel = levels.error; +} else if (bower.config.verbose) { + loglevel = -Infinity; + Q.longStackSupport = true; +} else if (bower.config.quiet) { + loglevel = levels.warn; +} else { + loglevel = levels[bower.config.loglevel] || levels.info; +} + +// Get the command to execute +while (options.argv.remain.length) { + command = options.argv.remain.join(' '); + + // Alias lookup + if (bower.abbreviations[command]) { + command = bower.abbreviations[command].replace(/\s/g, '.'); + break; + } + + command = command.replace(/\s/g, '.'); + + // Direct lookup + if (mout.object.has(bower.commands, command)) { + break; + } + + options.argv.remain.pop(); +} + +// Execute the command +commandFunc = command && mout.object.get(bower.commands, command); +command = command && command.replace(/\./g, ' '); + +// If no command was specified, show bower help +// Do the same if the command is unknown +if (!commandFunc) { + logger = bower.commands.help(); + command = 'help'; +// If the user requested help, show the command's help +// Do the same if the actual command is a group of other commands (e.g.: cache) +} else if (options.help || !commandFunc.line) { + logger = bower.commands.help(command); + command = 'help'; +// Call the line method +} else { + logger = commandFunc.line(process.argv); + + // If the method failed to interpret the process arguments + // show the command help + if (!logger) { + logger = bower.commands.help(command); + command = 'help'; + } +} + +// Get the renderer and configure it with the executed command +renderer = cli.getRenderer(command, logger.json, bower.config); + +function handleLogger(logger, renderer) { + logger + .on('end', function (data) { + if (!bower.config.silent && !bower.config.quiet) { + renderer.end(data); + } + }) + .on('error', function (err) { + if (command !== 'help' && err.code === cli.READ_OPTIONS_ERROR_CODE) { + logger = bower.commands.help(command); + renderer = cli.getRenderer('help', logger.json, bower.config); + handleLogger(logger, renderer); + } else { + if (levels.error >= loglevel) { + renderer.error(err); + } + + process.exit(1); + } + }) + .on('log', function (log) { + if (levels[log.level] >= loglevel) { + renderer.log(log); + } + }) + .on('prompt', function (prompt, callback) { + renderer.prompt(prompt) + .then(function (answer) { + callback(answer); + }); + }); +} + +handleLogger(logger, renderer); + +// Warn if HOME is not SET +if (!userHome) { + logger.warn('no-home', 'HOME environment variable not set. User config will not be loaded.'); +} + +if (bower.config.interactive) { + var updateNotifier = require('update-notifier'); + + // Check for newer version of Bower + var notifier = updateNotifier({ pkg: { name: 'bower', version: version } }); + + if (notifier.update && levels.info >= loglevel) { + notifier.notify(); + } +} From 394dd7c8d26cd031da9237d591406f6f76c5e690 Mon Sep 17 00:00:00 2001 From: blcook223 Date: Thu, 28 Jan 2016 20:49:30 -0600 Subject: [PATCH 0861/1021] add support for save and save-exact in .bowerrc The install command now supports designating "save" and "save-exact" values in .bowerrc. If the `--save` flag is not used, but the config file sets "save" to true, the command will behave as if the `--save` option was specified. The same is true of `--save-exact` if "save-exact" is set to true in `.bowerrc`. The uninstall command will also behave as if the `--save` flag had been specified if "save" is set to true in `.bowerrc`. --- lib/core/Project.js | 6 ++-- test/commands/install.js | 67 ++++++++++++++++++++++++++++++++++++++ test/commands/uninstall.js | 11 +++++++ 3 files changed, 81 insertions(+), 3 deletions(-) diff --git a/lib/core/Project.js b/lib/core/Project.js index 30b930726..bc988ae6f 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -82,14 +82,14 @@ Project.prototype.install = function (decEndpoints, options, config) { }) .then(function (installed) { // Handle save and saveDev options - if (that._options.save || that._options.saveDev || that._options.saveExact) { + if (that._options.save || that._options.saveDev || that._options.saveExact || that._config.save || that._config.saveExact) { // Cycle through the specified endpoints decEndpoints.forEach(function (decEndpoint) { var jsonEndpoint; jsonEndpoint = endpointParser.decomposed2json(decEndpoint); - if (that._options.saveExact) { + if (that._options.saveExact || that._config.saveExact) { if (decEndpoint.name !== decEndpoint.source) { jsonEndpoint[decEndpoint.name] = decEndpoint.source + '#' + decEndpoint.pkgMeta.version; } else { @@ -741,7 +741,7 @@ Project.prototype._removePackages = function (packages) { } // Remove from json only if successfully deleted - if (that._options.save && that._json.dependencies) { + if ((that._options.save || that._config.save) && that._json.dependencies) { promise = promise .then(function () { delete that._json.dependencies[name]; diff --git a/test/commands/install.js b/test/commands/install.js index 566f82810..e94f42d2f 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -85,6 +85,24 @@ describe('bower install', function() { }); }); + it('writes to bower.json if save config setting is set to true', function() { + mainPackage.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); + + return helpers.run(install, [ + [mainPackage.path], {}, { + save: true + } + ]).then(function() { + expect(tempDir.read('bower.json')).to.contain('dependencies'); + }); + }); + it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function() { mainPackage.prepare({ 'bower.json': { @@ -109,6 +127,30 @@ describe('bower install', function() { }); }); + it('writes an exact version number to dependencies in bower.json if save and save-exact config settings are set to true', function() { + mainPackage.prepare({ + 'bower.json': { + name: 'package', + version: '1.2.3' + } + }); + + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); + + return helpers.run(install, [ + [mainPackage.path], {}, { + saveExact: true, + save: true + } + ]).then(function() { + expect(tempDir.readJson('bower.json').dependencies.package).to.equal(mainPackage.path + '#1.2.3'); + }); + }); + it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function() { mainPackage.prepare({ 'bower.json': { @@ -133,6 +175,31 @@ describe('bower install', function() { }); }); + it('writes an exact version number to devDependencies in bower.json if save-exact config setting is true and --save-dev flag is used', function() { + mainPackage.prepare({ + 'bower.json': { + name: 'package', + version: '0.1.0' + } + }); + + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); + + return helpers.run(install, [ + [mainPackage.path], { + saveDev: true + }, { + saveExact: true + } + ]).then(function() { + expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(mainPackage.path + '#0.1.0'); + }); + }); + it('reads .bowerrc from cwd', function() { mainPackage.prepare({ foo: 'bar' diff --git a/test/commands/uninstall.js b/test/commands/uninstall.js index f26a6c5fc..838f7674a 100644 --- a/test/commands/uninstall.js +++ b/test/commands/uninstall.js @@ -54,6 +54,17 @@ describe('bower uninstall', function () { }); }); + it('removes dependency from bower.json if save config setting is true', function () { + var configWithSave = { + cwd: tempDir.path, + interactive: true, + save: true + }; + return helpers.run(uninstall, [['underscore'], {}, configWithSave]).then(function () { + expect(bowerJson().dependencies).to.eql({}); + }); + }); + it('removes dependency from relative config.directory', function () { var targetPath = path.resolve(tempDir.path, 'other_directory/underscore'); mkdirp.sync(targetPath); From 36a14b9b37c16a469e114e55f93b423952c7055d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 10 Feb 2016 01:54:31 +0100 Subject: [PATCH 0862/1021] Add getIssues function and make validate less restrictive --- packages/bower-json/README.md | 42 ++++++--- packages/bower-json/lib/json.js | 117 +++++++++++++---------- packages/bower-json/test/test.js | 154 ++++++++++++++++++------------- 3 files changed, 189 insertions(+), 124 deletions(-) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index bace32abb..995b97aef 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -8,12 +8,12 @@ Install via [npm](https://www.npmjs.org/package/bower-json): `npm install --save #### .read(file, options, callback) -Reads `file` and applies normalisation, defaults and validation according to the `bower.json` spec. -If the passed `file` does not exist, the callback is called with `error.code` equal to `ENOENT`. -If the passed `file` contents are not valid JSON, the callback is called with `error.code` equal to `EMALFORMED`. +Reads `file` and applies normalisation, defaults and validation according to the `bower.json` spec. +If the passed `file` does not exist, the callback is called with `error.code` equal to `ENOENT`. +If the passed `file` contents are not valid JSON, the callback is called with `error.code` equal to `EMALFORMED`. If the `json` does not comply with the `bower.json` spec, the callback is called with `error.code` equal to `EINVALID`. -If `file` is a directory, `find()` will be used to search for the json file. +If `file` is a directory, `find()` will be used to search for the json file. The `options` argument is optional and can be omitted. These options will be passed to `parse` method. @@ -35,7 +35,7 @@ bowerJson.read('/path/to/bower.json', function (err, json) { #### .parse(json, options) -Parses an object. Useful when you want to apply normalisation and validation directly to an object. +Parses an object. Useful when you want to apply normalisation and validation directly to an object. If the `json` does not comply with the `bower.json` spec, an error is thrown with `error.code` equal to `EINVALID`. The `options` arguments is optional and can be omitted. Available options: @@ -61,18 +61,39 @@ try { } ``` +#### .getIssues(json) - DEPRECATED + +Validates the passed `json` object. + +Returns an object with errors and warnings of this bower.json contents. + +```js +var bowerJson = require('bower-json'); + +var json = { + name: 'myPackage', + version: '0.0.1', + main: {} +}; + +var issues = bowerJson.getIssues(json); + +expect(issues).toEqual({ + errors: ['The "main" field has to be either an Array or a String'], + warnings: ['The "name" must be lowercase'] +}); #### .validate(json) -Validates the passed `json` object. -Throws an error with `error.code` equal to `EINVALID` if it does not comply with the spec. +Validates the passed `json` object. +Throws an error with `error.code` equal to `EINVALID` if it does not comply with the spec. ```js var bowerJson = require('bower-json'); var json = { - name: 'my-package', + name: 'myPackage', version: '0.0.1' }; @@ -84,7 +105,6 @@ try { } ``` - #### .normalize(json) ```js @@ -103,8 +123,8 @@ json.main // ['foo.js', 'bar.js'] #### .find(folder, callback) -Finds the `json` filename inside a folder. -Checks if a `bower.json` exists, falling back to `component.json` (deprecated) and `.bower.json`. +Finds the `json` filename inside a folder. +Checks if a `bower.json` exists, falling back to `component.json` (deprecated) and `.bower.json`. If no file was found, the callback is called with a `error.code` of `ENOENT`. ```js diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index 3f8fe8eb5..65de3b7d6 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -123,29 +123,38 @@ function parse(json, options) { return json; } -function validate(json) { - if (!json.name) { - throw createError('No name property set', 'EINVALID'); - } +// This function implements: +// +// https://github.com/bower/bower.json-spec +function getIssues(json) { + // For things that shouldn't happen + var errors = []; - if (json.name.length > 50) { - throw createError('The name is too long. 50 characters should be more than enough', 'EINVALID'); - } + // For things that happen but they shoudn't + var warnings = []; - if (/[A-Z]/.test(json.name)) { - throw createError('The name contains upper case letters', 'EINVALID'); - } + if (!json.name) { + errors.push('No "name" property set'); + } else { + if (json.name.length > 50) { + warnings.push('The "name" is too long, the limit is 50 characters'); + } - if (!/^[a-z]/.test(json.name)) { - throw createError('The name has to start with a lower case character from a to z', 'EINVALID'); - } + if (/[A-Z]/.test(json.name)) { + warnings.push('The "name" must be lowercase'); + } + + if (/^[\.-]/.test(json.name)) { + warnings.push('The "name" cannot start with dot or dash'); + } - if (!/[a-z]$/.test(json.name)) { - throw createError('The name has to end with a lower case character from a to z', 'EINVALID'); + if (/[\.-]$/.test(json.name)) { + warnings.push('The "name" cannot end with dot or dash'); + } } if (json.description && json.description.length > 140) { - throw createError('The description is too long. 140 characters should be more than enough', 'EINVALID'); + warnings.push('The "description" is too long, the limit is 140 characters'); } if (json.main !== undefined) { @@ -154,42 +163,53 @@ function validate(json) { main = [main]; } if (!(main instanceof Array)) { - throw createError('The "main" field has to be either an Array or a String', 'EINVALID'); - } - var ext2files = {}; - main.forEach(function (filename) { - if (typeof filename !== 'string') { - throw createError('The "main" Array has to contain only Strings', 'EINVALID'); - } - if (/[*]/.test(filename)) { - throw createError('The "main" field cannot contain globs (example: "*.js")', 'EINVALID'); - } - if (/[.]min[.][^/]+$/.test(filename)) { - throw createError('The "main" field cannot contain minified files', 'EINVALID'); - } - if (isAsset(filename)) { - throw createError('The "main" field cannot contain font, image, audio, or video files', 'EINVALID'); - } - var ext = path.extname(filename); - if (ext.length >= 2) { + errors.push('The "main" field has to be either an Array or a String'); + } else { + var ext2files = {}; + main.forEach(function (filename) { + if (typeof filename !== 'string') { + errors.push('The "main" Array has to contain only Strings'); + } + if (/[*]/.test(filename)) { + warnings.push('The "main" field cannot contain globs (example: "*.js")'); + } + if (/[.]min[.][^/]+$/.test(filename)) { + warnings.push('The "main" field cannot contain minified files'); + } + if (isAsset(filename)) { + warnings.push('The "main" field cannot contain font, image, audio, or video files'); + } + var ext = path.extname(filename); + if (ext.length >= 2) { + var files = ext2files[ext]; + if (!files) { + files = ext2files[ext] = []; + } + files.push(filename); + } + }); + Object.keys(ext2files).forEach(function (ext) { var files = ext2files[ext]; - if (!files) { - files = ext2files[ext] = []; + if (files.length > 1) { + warnings.push('The "main" field has to contain only 1 file per filetype; found multiple ' + ext + ' files: ' + JSON.stringify(files)); } - files.push(filename); - } - }); - Object.keys(ext2files).forEach(function (ext) { - var files = ext2files[ext]; - if (files.length > 1) { - throw createError('The "main" field has to contain only 1 file per filetype; found multiple ' + ext + ' files: ' + JSON.stringify(files), 'EINVALID'); - } - }); + }); + } } - // TODO https://github.com/bower/bower.json-spec + return { + errors: errors, + warnings: warnings + }; +} - return json; +// For backward compatibility, it throws first error +function validate(json) { + var issues = getIssues(json); + + if (issues.errors && issues.errors.length > 0) { + throw createError(issues.errors[0], 'EINVALID'); + } } function normalize(json) { @@ -197,8 +217,6 @@ function normalize(json) { json.main = [json.main]; } - // TODO - return json; } @@ -268,6 +286,7 @@ module.exports = read; module.exports.read = read; module.exports.readSync = readSync; module.exports.parse = parse; +module.exports.getIssues = getIssues; module.exports.validate = validate; module.exports.normalize = normalize; module.exports.find = find; diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index b0f1628fd..ede999210 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -270,131 +270,157 @@ describe('.parse', function () { }); }); -describe('.validate', function () { - it('should validate the name property', function () { - expect(function () { - bowerJson.validate({}); - }).to.throwException(/name/); - }); - +describe('.getIssues', function () { it('should validate the name length', function () { var json = { name: 'a_123456789_123456789_123456789_123456789_123456789_z' }; - expect(function () { - bowerJson.validate(json); - }).to.throwException(); + + expect(bowerJson.getIssues(json).warnings).to.contain( + 'The "name" is too long, the limit is 50 characters' + ); }); + it('should validate the name is lowercase', function () { var json = { name: 'gruNt' }; - expect(function () { - bowerJson.validate(json); - }).to.throwException(); + + expect(bowerJson.getIssues(json).warnings).to.contain( + 'The "name" must be lowercase' + ); }); + it('should validate the name starts with lowercase', function () { - var json = { name: 'Grunt' }; - expect(function () { - bowerJson.validate(json); - }).to.throwException(); + var json = { name: '-runt' }; + + expect(bowerJson.getIssues(json).warnings).to.contain( + 'The "name" cannot start with dot or dash' + ); }); + it('should validate the name starts with lowercase', function () { var json = { name: '.grunt' }; - expect(function () { - bowerJson.validate(json); - }).to.throwException(); + + expect(bowerJson.getIssues(json).warnings).to.contain( + 'The "name" cannot start with dot or dash' + ); }); + it('should validate the name ends with lowercase', function () { - var json = { name: 'grunT' }; - expect(function () { - bowerJson.validate(json); - }).to.throwException(); + var json = { name: 'grun-' }; + + expect(bowerJson.getIssues(json).warnings).to.contain( + 'The "name" cannot end with dot or dash' + ); }); + it('should validate the name ends with lowercase', function () { var json = { name: 'grun.' }; - expect(function () { - bowerJson.validate(json); - }).to.throwException(); + + expect(bowerJson.getIssues(json).warnings).to.contain( + 'The "name" cannot end with dot or dash' + ); }); + it('should validate the name is valid', function () { var json = { name: 'gru.n-t' }; - expect(function () { - bowerJson.validate(json); - }).to.not.throwException(); + + expect(bowerJson.getIssues(json).warnings).to.eql([]); }); + it('should validate the description length', function () { var json = { name: 'foo', description: _s.repeat('æ', 141) }; - expect(function () { - bowerJson.validate(json); - }).to.throwException(); + + expect(bowerJson.getIssues(json).warnings).to.contain( + 'The "description" is too long, the limit is 140 characters' + ); }); + it('should validate the description is valid', function () { var json = { name: 'foo', description: _s.repeat('æ', 140) }; - expect(function () { - bowerJson.validate(json); - }).to.not.throwException(); + + expect(bowerJson.getIssues(json).warnings).to.eql([]); }); - it('should validate the type of main', function () { + + it('should validate that main does not contain globs', function () { var json = { name: 'foo', - main: {} + main: ['js/*.js'] }; - expect(function () { - bowerJson.validate(json); - }).to.throwException(); + + expect(bowerJson.getIssues(json).warnings).to.contain( + 'The "main" field cannot contain globs (example: "*.js")' + ); }); - it('should validate the type of items of an Array main', function () { + + it('should validate that main does not contain minified files', function () { var json = { name: 'foo', - main: [{}] + main: ['foo.min.css'] }; - expect(function () { - bowerJson.validate(json); - }).to.throwException(); + + expect(bowerJson.getIssues(json).warnings).to.contain( + 'The "main" field cannot contain minified files' + ); }); - it('should validate that main does not contain globs', function () { + + it('should validate that main does not contain fonts', function () { var json = { name: 'foo', - main: ['js/*.js'] + main: ['foo.woff'] }; - expect(function () { - bowerJson.validate(json); - }).to.throwException(); + + expect(bowerJson.getIssues(json).warnings).to.contain( + 'The "main" field cannot contain font, image, audio, or video files' + ); }); - it('should validate that main does not contain minified files', function () { - expect(function () { - bowerJson.validate(json); - }).to.throwException(); + + it('should validate that main does not contain images', function () { var json = { name: 'foo', - main: ['foo.min.css'] + main: ['foo.png'] }; + + expect(bowerJson.getIssues(json).warnings).to.contain( + 'The "main" field cannot contain font, image, audio, or video files' + ); }); - it('should validate that main does not contain fonts', function () { + + it('should validate that main does not contain multiple files of the same filetype', function () { var json = { name: 'foo', - main: ['foo.woff'] + main: ['foo.js', 'bar.js'] }; + + expect(bowerJson.getIssues(json).warnings).to.contain( + 'The "main" field has to contain only 1 file per filetype; found multiple .js files: ["foo.js","bar.js"]' + ); + }); +}); + +describe('.validate', function () { + it('should validate the name property', function () { expect(function () { - bowerJson.validate(json); - }).to.throwException(); + bowerJson.validate({}); + }).to.throwException(/name/); }); - it('should validate that main does not contain images', function () { + + it('should validate the type of main', function () { var json = { name: 'foo', - main: ['foo.png'] + main: {} }; expect(function () { bowerJson.validate(json); }).to.throwException(); }); - it('should validate that main does not contain multiple files of the same filetype', function () { + it('should validate the type of items of an Array main', function () { var json = { name: 'foo', - main: ['foo.js', 'bar.js'] + main: [{}] }; expect(function () { bowerJson.validate(json); From ef67955c2196b64b96bfe11cd66d310e05612566 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 10 Feb 2016 02:22:34 +0100 Subject: [PATCH 0863/1021] Bump to 0.7.0 --- packages/bower-json/CHANGELOG.md | 4 ++++ packages/bower-json/package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 packages/bower-json/CHANGELOG.md diff --git a/packages/bower-json/CHANGELOG.md b/packages/bower-json/CHANGELOG.md new file mode 100644 index 000000000..8d4650198 --- /dev/null +++ b/packages/bower-json/CHANGELOG.md @@ -0,0 +1,4 @@ +# 0.7.0 + +- Add getIssues function to retrieve all errors and warnings +- Add readSync and findSync functions for synchronous read diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 86d50f7eb..cd7435652 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,6 +1,6 @@ { "name": "bower-json", - "version": "0.6.0", + "version": "0.7.0", "description": "Read bower.json files with semantics, normalisation, defaults and validation", "author": "Twitter", "license": "MIT", From 573b84f7f4de852260a6f5604e90c8883bcbdb69 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 10 Feb 2016 02:34:30 +0100 Subject: [PATCH 0864/1021] Update bower-json to 0.7.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 81efd4aef..faacb3e6c 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "archy": "1.0.0", "bower-config": "^1.3.0", "bower-endpoint-parser": "^0.2.2", - "bower-json": "^0.4.0", + "bower-json": "^0.7.0", "bower-logger": "^0.2.2", "bower-registry-client": "^1.0.0", "cardinal": "0.4.4", From c8a6ff38a07f7c40011b36c2982f5891a34bd2b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Gro=CC=88nke?= Date: Mon, 28 Sep 2015 19:23:54 +0200 Subject: [PATCH 0865/1021] test validation against all registred packages --- packages/bower-json/package.json | 1 + packages/bower-json/test/test.js | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index cd7435652..292482152 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -28,6 +28,7 @@ "istanbul": "^0.3.5", "load-grunt-tasks": "^3.3.0", "mocha": "*", + "request": "^2.64.0", "underscore.string": "^3.0.3" }, "scripts": { diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index ede999210..b1c278b26 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -2,6 +2,7 @@ var path = require('path'); var expect = require('expect.js'); var _s = require('underscore.string'); var bowerJson = require('../lib/json'); +var request = require('request'); describe('.find', function () { it('should find the bower.json file', function (done) { @@ -436,3 +437,59 @@ describe('.normalize', function () { expect(json.main).to.eql(['foo.js']); }); }); + +describe('packages from bower registry', function () { + + var packageList, + packageListUrl = 'https://bower-component-list.herokuapp.com/'; + + this.timeout(60000); + + it('can be downloaded from online source ' + packageListUrl, function(done) { + request({ + url: packageListUrl, + json: true + }, function(error, response, body) { + + if(error) { + throw error; + } + + expect(body).to.be.an('array'); + expect(body).to.not.be.empty; + packageList = body; + + done(); + + }); + }); + + it('should validate each listed package', function (done) { + + expect(packageList).to.be.an('array'); + + var invalidPackageCount = 0; + + packageList.forEach(function(package) { + + if(package.name.indexOf('10digit')===0) { + return; + } + + try { + bowerJson.validate(package); + } catch(e) { + invalidPackageCount++; + console.error('validation of "' + package.name + '" failed: ' + e.message); + } + + }); + + if(invalidPackageCount) { + throw new Error(invalidPackageCount + '/' + packageList.length + ' package names do not validate'); + } + done(); + + }); +}); + From b33041c3ec026d3fa9b645f4443207ba5fa8657d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 10 Feb 2016 02:42:33 +0100 Subject: [PATCH 0866/1021] [test] Remove unnecessary check --- packages/bower-json/test/test.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index b1c278b26..e0fec6890 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -442,7 +442,7 @@ describe('packages from bower registry', function () { var packageList, packageListUrl = 'https://bower-component-list.herokuapp.com/'; - + this.timeout(60000); it('can be downloaded from online source ' + packageListUrl, function(done) { @@ -450,7 +450,7 @@ describe('packages from bower registry', function () { url: packageListUrl, json: true }, function(error, response, body) { - + if(error) { throw error; } @@ -471,11 +471,6 @@ describe('packages from bower registry', function () { var invalidPackageCount = 0; packageList.forEach(function(package) { - - if(package.name.indexOf('10digit')===0) { - return; - } - try { bowerJson.validate(package); } catch(e) { @@ -488,6 +483,7 @@ describe('packages from bower registry', function () { if(invalidPackageCount) { throw new Error(invalidPackageCount + '/' + packageList.length + ' package names do not validate'); } + done(); }); From 878a228a7d448641d4564178c134bcc2c421ee35 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 10 Feb 2016 02:44:53 +0100 Subject: [PATCH 0867/1021] Fix linting error --- packages/bower-json/test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index e0fec6890..a911d74ee 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -456,7 +456,7 @@ describe('packages from bower registry', function () { } expect(body).to.be.an('array'); - expect(body).to.not.be.empty; + expect(body).to.not.be.empty(); packageList = body; done(); From db1453f7c032bdd739d3d7b0092c865c52c538d4 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 10 Feb 2016 02:55:24 +0100 Subject: [PATCH 0868/1021] Add findSync and readSync to the README --- packages/bower-json/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/bower-json/README.md b/packages/bower-json/README.md index 995b97aef..37f7d7d35 100644 --- a/packages/bower-json/README.md +++ b/packages/bower-json/README.md @@ -7,6 +7,7 @@ Install via [npm](https://www.npmjs.org/package/bower-json): `npm install --save ## Usage #### .read(file, options, callback) +#### .readSync(file, options) Reads `file` and applies normalisation, defaults and validation according to the `bower.json` spec. If the passed `file` does not exist, the callback is called with `error.code` equal to `ENOENT`. @@ -122,6 +123,7 @@ json.main // ['foo.js', 'bar.js'] #### .find(folder, callback) +#### .findSync(folder) Finds the `json` filename inside a folder. Checks if a `bower.json` exists, falling back to `component.json` (deprecated) and `.bower.json`. From 5283a132bca51c83b286e1abf38846060879f65c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 10 Feb 2016 04:33:26 +0100 Subject: [PATCH 0869/1021] Add name check that reflects reality --- packages/bower-json/lib/json.js | 4 ++++ packages/bower-json/test/test.js | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index 65de3b7d6..7467f49cf 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -136,6 +136,10 @@ function getIssues(json) { if (!json.name) { errors.push('No "name" property set'); } else { + if (!/^[a-zA-Z0-9_][a-zA-Z0-9\.\-_]*$/.test(json.name)) { + errors.push('Name must be lowercase string, with dots, dashes, or @'); + } + if (json.name.length > 50) { warnings.push('The "name" is too long, the limit is 50 characters'); } diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index a911d74ee..9344fba85 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -441,7 +441,7 @@ describe('.normalize', function () { describe('packages from bower registry', function () { var packageList, - packageListUrl = 'https://bower-component-list.herokuapp.com/'; + packageListUrl = 'http://bower.herokuapp.com/packages'; this.timeout(60000); From e85a5f778fc74e91862caa5bad2817d6bf475d1c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 13 Feb 2016 21:41:24 +0100 Subject: [PATCH 0870/1021] Update opn package to 4.0.0, fixes #2169 --- lib/commands/home.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/commands/home.js b/lib/commands/home.js index b9323f026..028c922a4 100644 --- a/lib/commands/home.js +++ b/lib/commands/home.js @@ -40,7 +40,7 @@ function home(logger, name, config) { throw createError('No homepage set for ' + pkgMeta.name, 'ENOHOME'); } - open(homepage); + open(homepage, { wait: false }); return homepage; }); } diff --git a/package.json b/package.json index faacb3e6c..fec451d53 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "mkdirp": "0.5.0", "mout": "^0.11.0", "nopt": "^3.0.1", - "opn": "^1.0.1", + "opn": "^4.0.0", "p-throttler": "0.1.1", "promptly": "0.2.0", "q": "^1.1.2", From 9f4c2384ea9295accf0143a7f8fce2941d1c2e3a Mon Sep 17 00:00:00 2001 From: Sivakumar Kailasam Date: Mon, 15 Feb 2016 20:34:01 +0530 Subject: [PATCH 0871/1021] Replace all occurrences of % character in hook commands. Fixes #2174 % character replaced once in .bowerrc scripts --- lib/core/scripts.js | 3 ++- test/core/scripts.js | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/core/scripts.js b/lib/core/scripts.js index 94be8ff6a..23499d21c 100644 --- a/lib/core/scripts.js +++ b/lib/core/scripts.js @@ -83,7 +83,8 @@ var hook = function (action, ordered, config, logger, packages, installed, json) } var orderedPackages = ordered ? orderByDependencies(packages, installed, json) : mout.object.keys(packages); - var cmdString = mout.string.replace(config.scripts[action], '%', orderedPackages.join(' ')); + var placeholder = new RegExp('%', 'g'); + var cmdString = mout.string.replace(config.scripts[action], placeholder, orderedPackages.join(' ')); return run(cmdString, action, logger, config); }; diff --git a/test/core/scripts.js b/test/core/scripts.js index 95bca2e50..2f191ccfa 100644 --- a/test/core/scripts.js +++ b/test/core/scripts.js @@ -25,9 +25,9 @@ describe('scripts', function () { var config = { cwd: tempDir, scripts: { - preinstall: touch('preinstall_%'), - postinstall: touch('postinstall_%'), - preuninstall: touch('preuninstall_%') + preinstall: touch('preinstall_%_%'), + postinstall: touch('postinstall_%_%'), + preuninstall: touch('preuninstall_%_%') } }; @@ -45,8 +45,8 @@ describe('scripts', function () { .install([packageDir], undefined, config) .on('end', function (installed) { - expect(fs.existsSync(path.join(tempDir, 'preinstall_' + packageName))).to.be(true); - expect(fs.existsSync(path.join(tempDir, 'postinstall_' + packageName))).to.be(true); + expect(fs.existsSync(path.join(tempDir, 'preinstall_' + packageName + '_' + packageName))).to.be(true); + expect(fs.existsSync(path.join(tempDir, 'postinstall_' + packageName + '_' + packageName))).to.be(true); next(); }); @@ -59,7 +59,7 @@ describe('scripts', function () { .uninstall([packageName], undefined, config) .on('end', function (installed) { - expect(fs.existsSync(path.join(tempDir, 'preuninstall_' + packageName))).to.be(true); + expect(fs.existsSync(path.join(tempDir, 'preuninstall_' + packageName + '_' + packageName))).to.be(true); next(); }); From f4620b28ab1acc78448568143bfba8c10fda6954 Mon Sep 17 00:00:00 2001 From: Olivier Amblet Date: Tue, 16 Feb 2016 23:22:46 +0100 Subject: [PATCH 0872/1021] [eslint] fix indentation to 4 spaces Changed the indentation from 2 to 4 spaces in .eslintrc files. All the code is using this convention and .jscsrc already define 4 as the right value. --- .eslintrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc b/.eslintrc index 9f79d1133..1eab521c7 100644 --- a/.eslintrc +++ b/.eslintrc @@ -25,7 +25,7 @@ rules: valid-typeof: 2 no-fallthrough: 2 quotes: [2, "single", "avoid-escape"] - indent: [2, 2] + indent: [2, 4] comma-spacing: 2 semi: 2 space-infix-ops: 2 From a6ca2ae9bbe36e733f1074e636d6c0d4fac59ce1 Mon Sep 17 00:00:00 2001 From: yash14123 Date: Wed, 24 Feb 2016 05:34:44 +0530 Subject: [PATCH 0873/1021] Changelog is still in 2015 --- CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ce5321f2..4c6111878 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 1.7.7 - 2015-01-27 +## 1.7.7 - 2016-01-27 Revert locations of all files while still packaging `node_modules`. @@ -9,12 +9,12 @@ It's because people are depending on internals of bower, like implicit contract, but we discourage it. The only official way to use bower programmatically is through `require('bower')`. -## 1.7.6 - 2015-01-27 +## 1.7.6 - 2016-01-27 - Revert location of "bin/bower" as developers are using it directly ([#2157](https://github.com/bower/bower/issues/2157)) Note: Correctly, you should use an alias created in `npm bin --global`. -## 1.7.5 - 2015-01-26 +## 1.7.5 - 2016-01-26 - Remove analytics from Bower, fixes ([#2150](https://github.com/bower/bower/pull/2150)) - Default to ^ operator on `bower install --save` ([#2145](https://github.com/bower/bower/pull/2145)) @@ -27,12 +27,12 @@ to use bower programmatically is through `require('bower')`. - Update request to 2.67.0 and fs-write-stream-atomic to 1.0.8 - Documentation improvements -## 1.7.4 - 2015-01-21 +## 1.7.4 - 2016-01-21 Unpublished because of issue with npm distribution: https://github.com/npm/npm/issues/11227 -## 1.7.3 - 2015-01-20 +## 1.7.3 - 2016-01-20 Unpublished because of issue with npm distribution: https://github.com/npm/npm/issues/11227 From 529d70295954eb102b82ac4b43724249f738cc82 Mon Sep 17 00:00:00 2001 From: Niraj Kaushal Date: Mon, 29 Feb 2016 11:13:06 +0530 Subject: [PATCH 0874/1021] Update Copyright Year from 2015 to 2016 This commit will change copyright year from 2015 to current year(2016) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a1ee6c65..b0e8d493b 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,6 @@ git config --global core.autocrlf input ## License -Copyright (c) 2015 Twitter and [other contributors](https://github.com/bower/bower/graphs/contributors) +Copyright (c) 2016 Twitter and [other contributors](https://github.com/bower/bower/graphs/contributors) Licensed under the MIT License From 6fff6fa7076c701e61d8f4f74182b2d24d5e6bab Mon Sep 17 00:00:00 2001 From: Manas Date: Sat, 5 Mar 2016 12:32:04 +0530 Subject: [PATCH 0875/1021] Upgrades handlebars to 4.0.5 to address #2195 Adds test for template util methods Upgrades handlebars Fixes RangeError due to `length` attribute in rpad helper --- lib/templates/helpers/rpad.js | 5 ++- lib/templates/std/help-generic.std | 3 +- lib/templates/std/help.std | 5 ++- package.json | 2 +- test/renderers/StandardRenderer.js | 1 - test/util/template.js | 53 ++++++++++++++++++++++++++++++ 6 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 test/util/template.js diff --git a/lib/templates/helpers/rpad.js b/lib/templates/helpers/rpad.js index d5201d241..f1aba4f91 100644 --- a/lib/templates/helpers/rpad.js +++ b/lib/templates/helpers/rpad.js @@ -3,10 +3,9 @@ var mout = require('mout'); function rpad(Handlebars) { Handlebars.registerHelper('rpad', function (context) { var hash = context.hash; - var length = parseInt(hash.length, 10); + var minLength = parseInt(hash.minLength, 10); var chr = hash.char; - - return mout.string.rpad(context.fn(this), length, chr); + return mout.string.rpad(context.fn(this), minLength, chr); }); } diff --git a/lib/templates/std/help-generic.std b/lib/templates/std/help-generic.std index 9bbf86754..1958a7369 100644 --- a/lib/templates/std/help-generic.std +++ b/lib/templates/std/help-generic.std @@ -12,7 +12,7 @@ Options: {{#condense}} {{#each options}} - {{#yellow}}{{#rpad length="23"}}{{#if shorthand}}{{shorthand}}, {{/if}}{{flag}}{{/rpad}}{{/yellow}} {{description}} + {{#yellow}}{{#rpad minLength="23"}}{{#if shorthand}}{{shorthand}}, {{/if}}{{flag}}{{/rpad}}{{/yellow}} {{description}} {{/each}} {{/condense}} @@ -21,4 +21,3 @@ Options: Description: {{#indent level="4"}}{{description}}{{/indent}} - diff --git a/lib/templates/std/help.std b/lib/templates/std/help.std index 83f8a6615..b54063934 100644 --- a/lib/templates/std/help.std +++ b/lib/templates/std/help.std @@ -11,7 +11,7 @@ Commands: {{#condense}} {{#each commands}} - {{#rpad length="23"}}{{@key}}{{/rpad}} {{.}} + {{#rpad minLength="23"}}{{@key}}{{/rpad}} {{.}} {{/each}} {{/condense}} @@ -19,9 +19,8 @@ Options: {{#condense}} {{#each options}} - {{#yellow}}{{#rpad length="23"}}{{#if shorthand}}{{shorthand}}, {{/if}}{{flag}}{{/rpad}}{{/yellow}} {{description}} + {{#yellow}}{{#rpad minLength="23"}}{{#if shorthand}}{{shorthand}}, {{/if}}{{flag}}{{/rpad}}{{/yellow}} {{description}} {{/each}} {{/condense}} See 'bower help ' for more information on a specific command. - diff --git a/package.json b/package.json index fec451d53..22595fe01 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "github": "^0.2.3", "glob": "^4.3.2", "graceful-fs": "^3.0.5", - "handlebars": "^2.0.0", + "handlebars": "^4.0.5", "inquirer": "0.10.0", "is-root": "^1.0.0", "junk": "^1.0.0", diff --git a/test/renderers/StandardRenderer.js b/test/renderers/StandardRenderer.js index 4762b4a87..620adf7bd 100644 --- a/test/renderers/StandardRenderer.js +++ b/test/renderers/StandardRenderer.js @@ -842,7 +842,6 @@ describe('StandardRenderer', function () { Uninstalls a package locally from your bower_components directory - */})); }); }); diff --git a/test/util/template.js b/test/util/template.js new file mode 100644 index 000000000..3d17fa7d5 --- /dev/null +++ b/test/util/template.js @@ -0,0 +1,53 @@ +var expect = require('expect.js'); +var template = require('../../lib/util/template'); +var fs = require('fs'); + +describe('template: util template methods for templates in lib/templates', function () { + describe('.render() - Renders a handlebars template', function () { + var testTemplateName = 'test-template.tpl'; + var testTemplatePath = __dirname + '/../../lib/templates/' + testTemplateName; + beforeEach(function () { + fs.writeFileSync(testTemplatePath, '{{foo}}'); + console.log(); + }); + it('.render() returns a compiled test-template template', function () { + var compiledStr = template.render( + testTemplateName, + { foo: 'foo value' } + ); + expect(compiledStr).to.be.equal( + 'foo value' + ); + }); + it('.render() throws when a non existent template is provided', function () { + expect(function () { + template.render( + 'test-template.not-present.tpl', + { foo: 'foo value' } + ); + }).to.throwException(); + }); + afterEach(function () { + fs.unlinkSync(testTemplatePath); + }); + }); + + describe('.exists() - Checks existence of a template', function () { + var testTemplateName = 'test-template.tpl'; + var testTemplatePath = __dirname + '/../../lib/templates/' + testTemplateName; + beforeEach(function () { + fs.writeFileSync(testTemplatePath, '{{foo}}'); + }); + it('.exists() returns true for an existing template', function () { + var templateExists = template.exists(testTemplateName); + expect(templateExists).to.be.ok(); + }); + it('.exists() returns false for a non existing template', function () { + var templateExists = template.exists('test-template.not-present.tpl'); + expect(templateExists).to.not.be.ok(); + }); + afterEach(function () { + fs.unlinkSync(testTemplatePath); + }); + }); +}); From 8d76b87d656cd922299a3bb1f9581555f6c10c3e Mon Sep 17 00:00:00 2001 From: Albertina Durante Date: Sat, 5 Mar 2016 21:48:43 -0300 Subject: [PATCH 0876/1021] Supporting shell operators in hooks scripts. - Removing module "shell-quote" - Adding tests for hooks scripts with shell operators - This fixes issue #1594 --- lib/core/scripts.js | 5 ++--- package.json | 1 - test/core/scripts.js | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/lib/core/scripts.js b/lib/core/scripts.js index 23499d21c..4aa5b1da9 100644 --- a/lib/core/scripts.js +++ b/lib/core/scripts.js @@ -1,7 +1,6 @@ var mout = require('mout'); var cmd = require('../util/cmd'); var Q = require('q'); -var shellquote = require('shell-quote'); var orderByDependencies = function (packages, installed, json) { var ordered = []; @@ -54,8 +53,8 @@ var run = function (cmdString, action, logger, config) { //pass env + BOWER_PID so callees can identify a preinstall+postinstall from the same bower instance var env = mout.object.mixIn({ 'BOWER_PID': process.pid }, process.env); - var args = shellquote.parse(cmdString, env); - var cmdName = args[0]; + var cmdName = 'sh'; + var args = ['-c', cmdString]; mout.array.remove(args, cmdName); //no rest() in mout var options = { diff --git a/package.json b/package.json index 22595fe01..7c0043f86 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,6 @@ "rimraf": "^2.2.8", "semver": "^2.3.0", "semver-utils": "^1.1.1", - "shell-quote": "^1.4.2", "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", "tmp": "0.0.28", diff --git a/test/core/scripts.js b/test/core/scripts.js index 2f191ccfa..cdb2020fb 100644 --- a/test/core/scripts.js +++ b/test/core/scripts.js @@ -135,4 +135,39 @@ describe('scripts', function () { }); + it('should process preuninstall hooks with shell operators properly.', function (next) { + + config.scripts.preuninstall = touch('preuninstall_test_ping_%') + ' && ' + touch('preuninstall_test_pong'); + + bower.commands + .uninstall([packageName], undefined, config) + .on('end', function (installed) { + + expect(fs.existsSync(path.join(tempDir, 'preuninstall_test_ping_' + packageName))).to.be(true); + expect(fs.existsSync(path.join(tempDir, 'preuninstall_test_pong'))).to.be(true); + + next(); + }); + + }); + + it('should process preinstall and postinstall hooks with shell operators properly.', function (next) { + + config.scripts.preinstall = touch('preinstall_test_ping_%') + ' && ' + touch('preinstall_test_pong'); + config.scripts.postinstall = touch('postinstall_test_ping') + ' && ' + touch('postinstall_test_pong_%'); + + bower.commands + .install([packageDir], undefined, config) + .on('end', function (installed) { + + expect(fs.existsSync(path.join(tempDir, 'preinstall_test_ping_' + packageName))).to.be(true); + expect(fs.existsSync(path.join(tempDir, 'preinstall_test_pong'))).to.be(true); + expect(fs.existsSync(path.join(tempDir, 'postinstall_test_ping'))).to.be(true); + expect(fs.existsSync(path.join(tempDir, 'postinstall_test_pong_' + packageName))).to.be(true); + + next(); + }); + + }); + }); From 3241e8ed62611c8f0d8164aaf0cb5daceda24c7d Mon Sep 17 00:00:00 2001 From: Jorge Chavez Date: Wed, 16 Mar 2016 18:12:43 -0700 Subject: [PATCH 0877/1021] Add jsonPackage for refactoring purposes --- Gruntfile.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index f70f8c022..a474f150e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -90,6 +90,8 @@ module.exports = function (grunt) { var npmMajor = parseInt(npmVersion[0], 10); var npmMinor = parseInt(npmVersion[1], 10); + var jsonPackage = require('./package'); + if (npmMajor !== 3 || npmMinor < 5) { grunt.log.writeln('You need to use at least npm@3.5 to publish bower.'); grunt.log.writeln('It is because npm 2.x produces too long paths that Windows does not handle.'); @@ -97,7 +99,7 @@ module.exports = function (grunt) { process.exit(1); } - var version = require('./package').version; + var version = jsonPackage.version; var changelog = fs.readFileSync('./CHANGELOG.md'); if (changelog.indexOf('## ' + version) === -1) { @@ -138,10 +140,9 @@ module.exports = function (grunt) { grunt.log.writeln('Installing production dependencies...'); childProcess.execSync('npm install --production --silent', { cwd: dir, stdio: [0, 1, 2] }); - var json = require('./package'); - delete json.dependencies; - delete json.devDependencies; - delete json.scripts; + delete jsonPackage.dependencies; + delete jsonPackage.devDependencies; + delete jsonPackage.scripts; fs.writeFileSync(path.resolve(dir, 'package.json'), JSON.stringify(json, null, ' ') + '\n'); @@ -202,7 +203,7 @@ module.exports = function (grunt) { { type: 'confirm', name: 'publish', - message: 'Are you SURE you want to publish ' + require('./package').name + '@' + require('./package').version + '?', + message: 'Are you SURE you want to publish ' + jsonPackage.name + '@' + jsonPackage.version + '?', default: false } ]; From 73171766e7884ad7a86d9f55a50b7c71647b0eae Mon Sep 17 00:00:00 2001 From: Kun Yan Date: Mon, 21 Mar 2016 11:16:51 +0800 Subject: [PATCH 0878/1021] Fix Gruntfile error --- Gruntfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index a474f150e..e67dca2c3 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -144,7 +144,7 @@ module.exports = function (grunt) { delete jsonPackage.devDependencies; delete jsonPackage.scripts; - fs.writeFileSync(path.resolve(dir, 'package.json'), JSON.stringify(json, null, ' ') + '\n'); + fs.writeFileSync(path.resolve(dir, 'package.json'), JSON.stringify(jsonPackage, null, ' ') + '\n'); grunt.log.writeln('Moving node_modules to lib directory...'); From f9ea3846e220e99f5754c6038f740450f34f8fac Mon Sep 17 00:00:00 2001 From: echavezNS Date: Sat, 26 Mar 2016 01:25:10 -0700 Subject: [PATCH 0879/1021] Extend conflict message --- lib/templates/std/conflict.std | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/templates/std/conflict.std b/lib/templates/std/conflict.std index cf5142781..997931b18 100644 --- a/lib/templates/std/conflict.std +++ b/lib/templates/std/conflict.std @@ -1,4 +1,4 @@ -{{#yellow}}Unable to find a suitable version for {{name}}, please choose one:{{/yellow}} +{{#yellow}}Unable to find a suitable version for {{name}}, please choose one by typing one of the number below:{{/yellow}} {{#condense}} {{#each picks}} {{#magenta}}{{sum @index 1}}){{/magenta}} {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#green}}{{pkgMeta._release}}{{/green}}{{/if}}{{#if dependants}} and is required by {{#green}}{{dependants}}{{/green}}{{/if}} From 84d8d8c57f1abb42313bc77b95f64432b8bf7240 Mon Sep 17 00:00:00 2001 From: echavezNS Date: Sat, 26 Mar 2016 12:39:35 -0700 Subject: [PATCH 0880/1021] Typo --- lib/templates/std/conflict.std | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/templates/std/conflict.std b/lib/templates/std/conflict.std index 997931b18..ce85f92a9 100644 --- a/lib/templates/std/conflict.std +++ b/lib/templates/std/conflict.std @@ -1,4 +1,4 @@ -{{#yellow}}Unable to find a suitable version for {{name}}, please choose one by typing one of the number below:{{/yellow}} +{{#yellow}}Unable to find a suitable version for {{name}}, please choose one by typing one of the numbers below:{{/yellow}} {{#condense}} {{#each picks}} {{#magenta}}{{sum @index 1}}){{/magenta}} {{#cyan}}{{endpoint.name}}#{{endpoint.target}}{{/cyan}}{{#if pkgMeta._release}} which resolved to {{#green}}{{pkgMeta._release}}{{/green}}{{/if}}{{#if dependants}} and is required by {{#green}}{{dependants}}{{/green}}{{/if}} From a3ae3b66b7b840824946a73a915af0006780d51b Mon Sep 17 00:00:00 2001 From: Kun Yan Date: Mon, 28 Mar 2016 14:10:54 +0800 Subject: [PATCH 0881/1021] Fix message unit test error --- test/renderers/StandardRenderer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/renderers/StandardRenderer.js b/test/renderers/StandardRenderer.js index 620adf7bd..582dff0ed 100644 --- a/test/renderers/StandardRenderer.js +++ b/test/renderers/StandardRenderer.js @@ -313,7 +313,7 @@ describe('StandardRenderer', function () { }).spread(function(stdout, stderr) { expect(stdout).to.equal(multiline(function() {/* - Unable to find a suitable version for , please choose one: + Unable to find a suitable version for , please choose one by typing one of the numbers below: 1) fizfuz#~0.0.0 which resolved to 0.0.0 and is required by dependant1#release1, dependant2#release2 2) fizfuz2# and is required by jquery2 From 233f685c617fb3968614248bf07e7f4551358ca1 Mon Sep 17 00:00:00 2001 From: echavezNS Date: Mon, 28 Mar 2016 00:39:05 -0700 Subject: [PATCH 0882/1021] Reuse the files selected in jshint for jscs --- Gruntfile.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index e67dca2c3..c6a47af48 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -32,16 +32,7 @@ module.exports = function (grunt) { config: '.jscsrc', fix: true }, - files: [ - 'Gruntfile.js', - 'bin/*', - 'lib/**/*.js', - 'test/**/*.js', - '!test/assets/**/*', - '!test/reports/**/*', - '!test/sample/**/*', - '!test/tmp/**/*' - ] + files: ['<%= jshint.files %>'] }, simplemocha: { options: { From 2052ba3eedafcf9874700f1a8278cbafa17651c6 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 30 Mar 2016 22:12:24 +0200 Subject: [PATCH 0883/1021] Remove jshint --- .jshintrc | 50 ------------------------- Gruntfile.js | 20 ++++------ lib/core/resolverFactory.js | 1 - lib/core/resolvers/GitRemoteResolver.js | 1 - lib/core/scripts.js | 1 - lib/util/rootCheck.js | 1 - package.json | 6 ++- 7 files changed, 11 insertions(+), 69 deletions(-) delete mode 100644 .jshintrc diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 99614890b..000000000 --- a/.jshintrc +++ /dev/null @@ -1,50 +0,0 @@ -{ - "predef": [ - "console", - "describe", - "it", - "after", - "afterEach", - "before", - "beforeEach" - ], - - "node": true, - "devel": true, - - "bitwise": false, - "curly": false, - "eqeqeq": true, - "forin": false, - "latedef": false, - "noarg": true, - "nonew": true, - "plusplus": false, - "regexp": false, - "undef": true, - "unused": "vars", - "strict": false, - - "asi": false, - "boss": true, - "debug": false, - "eqnull": true, - "esnext": false, - "evil": false, - "expr": false, - "funcscope": false, - "globalstrict": false, - "iterator": false, - "lastsemic": false, - "loopfunc": true, - "onecase": true, - "regexdash": false, - "scripturl": false, - "smarttabs": false, - "shadow": false, - "supernew": true, - "validthis": false, - - "nomen": false, - "white": true -} diff --git a/Gruntfile.js b/Gruntfile.js index c6a47af48..77292cf4e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -12,9 +12,10 @@ module.exports = function (grunt) { require('load-grunt-tasks')(grunt); grunt.initConfig({ - jshint: { + jscs: { options: { - jshintrc: '.jshintrc' + config: '.jscsrc', + fix: true }, files: [ 'Gruntfile.js', @@ -27,13 +28,6 @@ module.exports = function (grunt) { '!test/tmp/**/*' ] }, - jscs: { - options: { - config: '.jscsrc', - fix: true - }, - files: ['<%= jshint.files %>'] - }, simplemocha: { options: { reporter: 'spec', @@ -65,15 +59,15 @@ module.exports = function (grunt) { } }, watch: { - files: ['<%= jshint.files %>'], - tasks: ['jshint', 'simplemocha:short'] + files: ['<%= jscs.files %>'], + tasks: ['jscs', 'simplemocha:short'] } }); grunt.registerTask('assets', ['exec:assets-force']); - grunt.registerTask('test', ['jscs', 'jshint', 'exec:assets', 'simplemocha:full']); + grunt.registerTask('test', ['jscs', 'exec:assets', 'simplemocha:full']); grunt.registerTask('cover', 'exec:cover'); - grunt.registerTask('travis', ['jshint', 'exec:assets', 'exec:cover', 'exec:coveralls']); + grunt.registerTask('travis', ['jscs', 'exec:assets', 'exec:cover', 'exec:coveralls']); grunt.registerTask('default', 'test'); grunt.task.registerTask('publish', 'Perform final checks and publish Bower', function () { diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index 4dbba7f35..a3f4d3422 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -1,4 +1,3 @@ -/*jshint laxbreak:true*/ var Q = require('q'); var fs = require('../util/fs'); var path = require('path'); diff --git a/lib/core/resolvers/GitRemoteResolver.js b/lib/core/resolvers/GitRemoteResolver.js index 46f19debe..1a8e9be90 100644 --- a/lib/core/resolvers/GitRemoteResolver.js +++ b/lib/core/resolvers/GitRemoteResolver.js @@ -1,4 +1,3 @@ -/*jshint laxbreak:true*/ var util = require('util'); var url = require('url'); var Q = require('q'); diff --git a/lib/core/scripts.js b/lib/core/scripts.js index 4aa5b1da9..caf25d787 100644 --- a/lib/core/scripts.js +++ b/lib/core/scripts.js @@ -77,7 +77,6 @@ var run = function (cmdString, action, logger, config) { var hook = function (action, ordered, config, logger, packages, installed, json) { if (mout.object.keys(packages).length === 0 || !config.scripts || !config.scripts[action]) { - /*jshint newcap: false */ return Q(); } diff --git a/lib/util/rootCheck.js b/lib/util/rootCheck.js index 3fbb8190e..e54c3ab22 100644 --- a/lib/util/rootCheck.js +++ b/lib/util/rootCheck.js @@ -1,4 +1,3 @@ -/*jshint multistr:true*/ // jscs:disable disallowMultipleLineStrings 'use strict'; var isRoot = require('is-root'); diff --git a/package.json b/package.json index 7c0043f86..df9638b11 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,6 @@ "expect.js": "^0.3.1", "grunt": "^0.4.5", "grunt-cli": "^0.1.13", - "grunt-contrib-jshint": "^0.10.0", "grunt-contrib-watch": "^0.6.1", "grunt-exec": "^0.4.6", "grunt-jscs": "^2.3.0", @@ -91,5 +90,8 @@ "coveralls": "coveralls", "prepublish": "in-publish && echo 'You need to use \"grunt publish\" to publish bower' && false || not-in-publish" }, - "files": [ "bin", "lib" ] + "files": [ + "bin", + "lib" + ] } From 9201a379d68bb1b19f3db61296c3f0192c6b655e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 30 Mar 2016 22:30:57 +0200 Subject: [PATCH 0884/1021] Update to grunt 1.0 --- package.json | 10 +++++----- test/renderers/StandardRenderer.js | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index df9638b11..3de40c1d6 100644 --- a/package.json +++ b/package.json @@ -67,12 +67,12 @@ "chai": "^1.10.0", "coveralls": "^2.11.2", "expect.js": "^0.3.1", - "grunt": "^0.4.5", - "grunt-cli": "^0.1.13", - "grunt-contrib-watch": "^0.6.1", + "grunt": "1.0.0-rc1", + "grunt-cli": "^1.1.0", + "grunt-contrib-watch": "^1.0.0", "grunt-exec": "^0.4.6", - "grunt-jscs": "^2.3.0", - "grunt-simple-mocha": "^0.4.0", + "grunt-jscs": "^2.8.0", + "grunt-simple-mocha": "^0.4.1", "in-publish": "^2.0.0", "istanbul": "^0.3.5", "load-grunt-tasks": "^2.0.0", diff --git a/test/renderers/StandardRenderer.js b/test/renderers/StandardRenderer.js index 582dff0ed..f446798a1 100644 --- a/test/renderers/StandardRenderer.js +++ b/test/renderers/StandardRenderer.js @@ -112,7 +112,7 @@ describe('StandardRenderer', function () { expect(stderr).to.match(new RegExp(multiline(function() {/* Console trace: Error - at StandardRenderer.error \(.+?\) + \s+at StandardRenderer.error \(.+?\) */}))); }); From 53eeca97d38945751075932ac6e6841ebeaeeb0a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 31 Mar 2016 00:27:17 +0200 Subject: [PATCH 0885/1021] Use eslint instead jscs --- .eslintrc | 84 ++++---- .jscsrc | 27 --- Gruntfile.js | 11 +- lib/abbreviations.js | 2 +- lib/config.js | 6 +- lib/core/Manager.js | 2 +- lib/core/PackageRepository.js | 2 +- lib/core/Project.js | 8 +- lib/core/resolverFactory.js | 2 +- lib/core/resolvers/GitHubResolver.js | 2 +- lib/core/resolvers/pluginResolverFactory.js | 8 +- lib/renderers/StandardRenderer.js | 2 +- lib/util/download.js | 2 +- lib/util/extract.js | 2 +- lib/util/relativeToBaseDir.js | 2 +- package.json | 2 +- test/commands/bower.js | 2 +- test/commands/cache/clean.js | 10 +- test/commands/cache/list.js | 6 +- test/commands/help.js | 14 +- test/commands/home.js | 14 +- test/commands/info.js | 6 +- test/commands/init.js | 6 +- test/commands/install.js | 106 +++++----- test/commands/link.js | 18 +- test/commands/list.js | 34 ++-- test/commands/login.js | 8 +- test/commands/lookup.js | 12 +- test/commands/prune.js | 10 +- test/commands/register.js | 16 +- test/commands/search.js | 26 +-- test/commands/uninstall.js | 14 +- test/commands/unregister.js | 10 +- test/commands/update.js | 58 +++--- test/commands/version.js | 28 +-- test/core/Manager.js | 8 +- test/core/resolverFactory.js | 2 +- test/core/resolvers/gitRemoteResolver.js | 8 +- test/core/resolvers/pluginResolverFactory.js | 18 +- test/core/resolvers/svnResolver.js | 2 +- test/helpers.js | 24 +-- test/packages-svn.js | 2 +- test/renderers/JsonRenderer.js | 22 +-- test/renderers/StandardRenderer.js | 192 +++++++++---------- test/util/createLink.js | 14 +- test/util/download.js | 4 +- test/util/isPathAbsolute.js | 4 +- test/util/relativeToBaseDir.js | 4 +- test/util/removeIgnores.js | 12 +- 49 files changed, 422 insertions(+), 456 deletions(-) delete mode 100644 .jscsrc diff --git a/.eslintrc b/.eslintrc index 1eab521c7..c75767200 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,45 +1,39 @@ -env: - node: true - -# enable ECMAScript features -ecmaFeatures: - arrowFunctions: true - binaryLiterals: true - blockBindings: true - classes: true - forOf: true - generators: true - objectLiteralShorthandMethods: true - objectLiteralShorthandProperties: true - octalLiterals: true - templateStrings: true - -rules: - no-debugger: 2 - no-dupe-args: 2 - no-dupe-keys: 2 - no-duplicate-case: 2 - no-ex-assign: 2 - no-reserved-keys: 2 - no-unreachable: 2 - valid-typeof: 2 - no-fallthrough: 2 - quotes: [2, "single", "avoid-escape"] - indent: [2, 4] - comma-spacing: 2 - semi: 2 - space-infix-ops: 2 - space-return-throw-case: 2 - space-before-function-paren: [2, "never"] - space-before-blocks: [2, "always"] - new-parens: 2 - max-len: [2, 80, 2] - no-multiple-empty-lines: [2, {max: 2}] - eol-last: 2 - no-trailing-spaces: 2 - space-after-keywords: 2 - - # ECMAScript 6 - prefer-const: 2 - strict: [2, "global"] - no-undef: 2 +{ + "env": { + "node": true, + "mocha": true + }, + "rules": { + "no-bitwise": 0, + "curly": 0, + "eqeqeq": 0, + "guard-for-in": 0, + "no-use-before-define": 0, + "no-caller": 2, + "no-new": 2, + "no-plusplus": 0, + "no-undef": 2, + "no-unused-vars": 0, + "strict": 0, + "semi": 0, + "no-cond-assign": [ + 2, + "except-parens" + ], + "no-debugger": 0, + "no-eq-null": 0, + "no-eval": 0, + "no-unused-expressions": 0, + "block-scoped-var": 0, + "no-iterator": 0, + "no-loop-func": 2, + "no-script-url": 0, + "no-shadow": 0, + "no-new-func": 2, + "no-new-wrappers": 2, + "no-invalid-this": 0, + "space-before-blocks": 2, + "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}], + "space-infix-ops": 2 + } +} diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index 99b1f9806..000000000 --- a/.jscsrc +++ /dev/null @@ -1,27 +0,0 @@ -{ - 'validateIndentation': 4, - 'requireCamelCaseOrUpperCaseIdentifiers': true, - 'requireParenthesesAroundIIFE': true, - 'requireCapitalizedConstructors': true, - 'disallowEmptyBlocks': false, - 'validateQuoteMarks': "'", - 'requireOperatorBeforeLineBreak': false, - 'requireCommaBeforeLineBreak': true, - 'disallowMultipleLineStrings': true, - 'requireDotNotation': true, - 'disallowTabs': true, - 'disallowNewlineBeforeBlockStatements': true, - 'disallowTrailingWhitespace': true, - 'disallowMixedSpacesAndTabs': true, - 'requireSpaceBeforeBinaryOperators': true, - 'requireSpaceBeforeBlockStatements': true, - 'requireSpaceBeforeObjectValues': true, - 'requireSpaceBetweenArguments': true, - 'requireSpacesInFunctionDeclaration': { - 'beforeOpeningCurlyBrace': true - }, - 'requireSpacesInNamedFunctionExpression': { - 'beforeOpeningCurlyBrace': true, - 'beforeOpeningRoundBrace': true - } -} diff --git a/Gruntfile.js b/Gruntfile.js index 77292cf4e..e1fc22abe 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -12,9 +12,8 @@ module.exports = function (grunt) { require('load-grunt-tasks')(grunt); grunt.initConfig({ - jscs: { + eslint: { options: { - config: '.jscsrc', fix: true }, files: [ @@ -59,15 +58,15 @@ module.exports = function (grunt) { } }, watch: { - files: ['<%= jscs.files %>'], - tasks: ['jscs', 'simplemocha:short'] + files: ['<%= eslint.files %>'], + tasks: ['eslint', 'simplemocha:short'] } }); grunt.registerTask('assets', ['exec:assets-force']); - grunt.registerTask('test', ['jscs', 'exec:assets', 'simplemocha:full']); + grunt.registerTask('test', ['eslint', 'exec:assets', 'simplemocha:full']); grunt.registerTask('cover', 'exec:cover'); - grunt.registerTask('travis', ['jscs', 'exec:assets', 'exec:cover', 'exec:coveralls']); + grunt.registerTask('travis', ['eslint', 'exec:assets', 'exec:cover', 'exec:coveralls']); grunt.registerTask('default', 'test'); grunt.task.registerTask('publish', 'Perform final checks and publish Bower', function () { diff --git a/lib/abbreviations.js b/lib/abbreviations.js index 52660f70b..a0b5a938f 100644 --- a/lib/abbreviations.js +++ b/lib/abbreviations.js @@ -18,7 +18,7 @@ function expandNames(obj, prefix, stack) { return stack; } -module.exports = function(commands) { +module.exports = function (commands) { var abbreviations = abbrev(expandNames(commands)); abbreviations.i = 'install'; diff --git a/lib/config.js b/lib/config.js index af0a27849..854392bf2 100644 --- a/lib/config.js +++ b/lib/config.js @@ -25,7 +25,7 @@ function readCachedConfig(cwd, overwrites) { delete config.json; // If interactive is auto (null), guess its value - if (config.interactive == null) { + if(config.interactive == null) { config.interactive = ( process.bin === 'bower' && tty.isatty(1) && @@ -51,13 +51,13 @@ function readCachedConfig(cwd, overwrites) { return config; } -function restoreConfig () { +function restoreConfig() { if (current) { current.restore(); } } -function resetCache () { +function resetCache() { restoreConfig(); current = undefined; } diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 677ef84c9..ebd543515 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -27,7 +27,7 @@ Manager.prototype.configure = function (setup) { this._conflicted = {}; // Targets - ignore those specified in ignoredDependencies - this._targets = mout.array.reject(setup.targets || [], function(target) { + this._targets = mout.array.reject(setup.targets || [], function (target) { return mout.array.contains(this._config.ignoredDependencies, target.name ); }, this); diff --git a/lib/core/PackageRepository.js b/lib/core/PackageRepository.js index 25084ed81..df971a72f 100644 --- a/lib/core/PackageRepository.js +++ b/lib/core/PackageRepository.js @@ -87,7 +87,7 @@ PackageRepository.prototype.fetch = function (decEndpoint) { } // Otherwise check for new contents - logger.action('validate', (pkgMeta._release ? pkgMeta._release + ' against ': '') + + logger.action('validate', (pkgMeta._release ? pkgMeta._release + ' against ' : '') + resolver.getSource() + (resolver.getTarget() ? '#' + resolver.getTarget() : '')); return resolver.hasNew(pkgMeta) diff --git a/lib/core/Project.js b/lib/core/Project.js index bc988ae6f..b9c5294ff 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -557,11 +557,11 @@ Project.prototype._readJson = function () { return Q.resolve(this._json); } - return Q.fcall(function() { + return Q.fcall(function () { // This will throw if package.json does not exist return fs.readFileSync(path.join(that._config.cwd, 'package.json')); }) - .then(function(buffer) { + .then(function (buffer) { // If package.json exists, use it's values as defaults var defaults = {}, npm = JSON.parse(buffer.toString()); @@ -574,11 +574,11 @@ Project.prototype._readJson = function () { return defaults; }) - .catch(function(err) { + .catch(function (err) { // Most likely no package.json so just set default name return { name: path.basename(that._config.cwd) || 'root' }; }) - .then(function(defaults) { + .then(function (defaults) { return that._json = readJson(that._config.cwd, { assume: defaults }); }) .spread(function (json, deprecated, assumed) { diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index a3f4d3422..c339f3388 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -91,7 +91,7 @@ function getConstructor(decEndpoint, options, registryClient) { // Git case: git git+ssh, git+http, git+https // .git at the end (probably ssh shorthand) // git@ at the start - addResolver(function() { + addResolver(function () { if (/^git(\+(ssh|https?))?:\/\//i.test(source) || /\.git\/?$/i.test(source) || /^git@/i.test(source)) { decEndpoint.source = source.replace(/^git\+/, ''); diff --git a/lib/core/resolvers/GitHubResolver.js b/lib/core/resolvers/GitHubResolver.js index 1335de19b..2644ecbcf 100644 --- a/lib/core/resolvers/GitHubResolver.js +++ b/lib/core/resolvers/GitHubResolver.js @@ -38,7 +38,7 @@ function GitHubResolver(decEndpoint, config, logger) { } // Enable shallow clones for GitHub repos - this._shallowClone = function() { + this._shallowClone = function () { return Q.resolve(true); }; } diff --git a/lib/core/resolvers/pluginResolverFactory.js b/lib/core/resolvers/pluginResolverFactory.js index cfe245696..0cef6f280 100644 --- a/lib/core/resolvers/pluginResolverFactory.js +++ b/lib/core/resolvers/pluginResolverFactory.js @@ -52,7 +52,7 @@ function pluginResolverFactory(resolverFactory, bower) { return this._decEndpoint.target || '*'; }; - PluginResolver.prototype.getName = function() { + PluginResolver.prototype.getName = function () { if (!this._decEndpoint.name && typeof resolver.getName === 'function') { return resolver.getName.call(resolver, this.getSource()); } else if (!this._decEndpoint.name) { @@ -70,7 +70,7 @@ function pluginResolverFactory(resolverFactory, bower) { // Plugin Resolver is always considered potentially cacheable // The "resolve" method decides whether to use cached or fetch new version. - PluginResolver.prototype.isCacheable = function() { + PluginResolver.prototype.isCacheable = function () { return true; }; @@ -95,7 +95,7 @@ function pluginResolverFactory(resolverFactory, bower) { var that = this; - return this.resolvePromise = Q.fcall(function() { + return this.resolvePromise = Q.fcall(function () { var target = that.getTarget(); // It means that we can accept ranges as targets @@ -275,7 +275,7 @@ function pluginResolverFactory(resolverFactory, bower) { }); }; - PluginResolver.isTargetable = function() { + PluginResolver.isTargetable = function () { // If resolver doesn't define versions function, it's not targetable.. return typeof resolver.releases === 'function'; }; diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index 15c3f38be..234457fe6 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -214,7 +214,7 @@ StandardRenderer.prototype._info = function (data) { data.numPreReleases = 0; // If output isn't verbose, hide prereleases if (!this._config.verbose) { - data.versions = mout.array.filter(data.versions, function(version) { + data.versions = mout.array.filter(data.versions, function (version) { version = semverUtils.parse(version); if (!version.release && !version.build) { return true; diff --git a/lib/util/download.js b/lib/util/download.js index 7fede62f5..4b451e892 100644 --- a/lib/util/download.js +++ b/lib/util/download.js @@ -35,7 +35,7 @@ function download(url, file, options) { operation.attempt(function () { Q.fcall(fetch, url, file, options) - .then(function(response) { + .then(function (response) { deferred.resolve(response); }) .progress(function (status) { diff --git a/lib/util/extract.js b/lib/util/extract.js index 1f3b4ec9b..0c7851b95 100644 --- a/lib/util/extract.js +++ b/lib/util/extract.js @@ -167,7 +167,7 @@ function isSingleDir(dir) { function moveDirectory(srcDir, destDir) { return Q.nfcall(fs.readdir, srcDir) - .then(function(files) { + .then(function (files) { var promises = files.map(function (file) { var src = path.join(srcDir, file); var dst = path.join(destDir, file); diff --git a/lib/util/relativeToBaseDir.js b/lib/util/relativeToBaseDir.js index 07556f960..a02a5b344 100644 --- a/lib/util/relativeToBaseDir.js +++ b/lib/util/relativeToBaseDir.js @@ -2,7 +2,7 @@ var path = require('path'); var isPathAbsolute = require('./isPathAbsolute'); function relativeToBaseDir(baseDir) { - return function(filePath) { + return function (filePath) { if(isPathAbsolute(filePath)) { return path.resolve(filePath); } else { diff --git a/package.json b/package.json index 3de40c1d6..4ea1c5402 100644 --- a/package.json +++ b/package.json @@ -70,8 +70,8 @@ "grunt": "1.0.0-rc1", "grunt-cli": "^1.1.0", "grunt-contrib-watch": "^1.0.0", + "grunt-eslint": "^18.0.0", "grunt-exec": "^0.4.6", - "grunt-jscs": "^2.8.0", "grunt-simple-mocha": "^0.4.1", "in-publish": "^2.0.0", "istanbul": "^0.3.5", diff --git a/test/commands/bower.js b/test/commands/bower.js index 9368fc8ec..c169ebf34 100644 --- a/test/commands/bower.js +++ b/test/commands/bower.js @@ -14,7 +14,7 @@ describe('bower', function () { }); describe('abbreviations', function () { - it('Returns same value than the full command', function() { + it('Returns same value than the full command', function () { var abbr = runBin(['install']); var full = runBin(['i']); diff --git a/test/commands/cache/clean.js b/test/commands/cache/clean.js index f0e8634c6..3a8e0b73b 100644 --- a/test/commands/cache/clean.js +++ b/test/commands/cache/clean.js @@ -11,7 +11,7 @@ describe('bower cache clean', function () { var cacheFilesFactory = function (spec) { var files = {}; - object.map(spec, function(bowerJson) { + object.map(spec, function (bowerJson) { bowerJson._source = bowerJson.name + '/' + bowerJson.version; var path = md5(bowerJson._source) + '/' + bowerJson.version + '/.bower.json'; files[path] = bowerJson; @@ -38,7 +38,7 @@ describe('bower cache clean', function () { var cacheDir = new helpers.TempDir(cacheFiles); - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(cacheClean.readOptions(['jquery', 'angular'])) .to.eql([['jquery', 'angular'], {}]); }); @@ -50,7 +50,7 @@ describe('bower cache clean', function () { storage: { packages: cacheDir.path } - }]).spread(function(result) { + }]).spread(function (result) { object.map(cacheFiles, function (_, cacheFile) { expect(cacheDir.exists(cacheFile)).to.be(false); }); @@ -64,7 +64,7 @@ describe('bower cache clean', function () { storage: { packages: cacheDir.path } - }]).spread(function(result) { + }]).spread(function (result) { var paths = Object.keys(cacheFiles); expect(cacheDir.exists(paths[0])).to.be(false); expect(cacheDir.exists(paths[1])).to.be(false); @@ -79,7 +79,7 @@ describe('bower cache clean', function () { storage: { packages: cacheDir.path } - }]).spread(function(result) { + }]).spread(function (result) { var paths = Object.keys(cacheFiles); expect(cacheDir.exists(paths[0])).to.be(false); expect(cacheDir.exists(paths[1])).to.be(true); diff --git a/test/commands/cache/list.js b/test/commands/cache/list.js index cea9710e1..89d598a4d 100644 --- a/test/commands/cache/list.js +++ b/test/commands/cache/list.js @@ -20,7 +20,7 @@ describe('bower cache list', function () { } }); - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(cacheList.readOptions(['jquery', 'angular'])) .to.eql([['jquery', 'angular'], {}]); }); @@ -32,7 +32,7 @@ describe('bower cache list', function () { storage: { packages: cacheDir.path } - }]).spread(function(result) { + }]).spread(function (result) { expect(result[0].canonicalDir) .to.be(cacheDir.getPath('87323d6d4e48be291a9616a033d4cc6c/1.3.8')); expect(result[0].pkgMeta.version).to.be('1.3.8'); @@ -49,7 +49,7 @@ describe('bower cache list', function () { storage: { packages: cacheDir.path } - }]).spread(function(result) { + }]).spread(function (result) { expect(result[0].canonicalDir) .to.be(cacheDir.getPath('87323d6d4e48be291a9616a033d4cc6c/1.3.8')); expect(result[0].pkgMeta.version).to.be('1.3.8'); diff --git a/test/commands/help.js b/test/commands/help.js index dfd7e895f..d719fc490 100644 --- a/test/commands/help.js +++ b/test/commands/help.js @@ -4,12 +4,12 @@ var help = helpers.command('help'); describe('bower help', function () { - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(help.readOptions(['foo'])).to.eql(['foo']); }); it('shows general help', function () { - return helpers.run(help).spread(function(result) { + return helpers.run(help).spread(function (result) { expect(result.usage[0]).to.be.a('string'); expect(result.commands).to.be.a('object'); expect(result.options).to.be.a('object'); @@ -23,9 +23,9 @@ describe('bower help', function () { 'cache list', 'cache clean' ]; - commands.forEach(function(command) { - it('shows help for ' + command + ' command', function() { - return helpers.run(help, [command]).spread(function(result) { + commands.forEach(function (command) { + it('shows help for ' + command + ' command', function () { + return helpers.run(help, [command]).spread(function (result) { expect(result.command).to.be(command); expect(result.description).to.be.a('string'); expect(result.usage[0]).to.be.a('string'); @@ -33,8 +33,8 @@ describe('bower help', function () { }); }); - it('displays error for non-existing command', function() { - return helpers.run(help, ['fuu']).fail(function(e) { + it('displays error for non-existing command', function () { + return helpers.run(help, ['fuu']).fail(function (e) { expect(e.message).to.be('Unknown command: fuu'); expect(e.command).to.be('fuu'); expect(e.code).to.be('EUNKNOWNCMD'); diff --git a/test/commands/home.js b/test/commands/home.js index 4383259fc..99f3cf1e6 100644 --- a/test/commands/home.js +++ b/test/commands/home.js @@ -6,7 +6,7 @@ var home = helpers.command('home'); describe('bower home', function () { - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(home.readOptions(['foo'])).to.eql(['foo']); }); @@ -26,10 +26,10 @@ describe('bower home', function () { it('opens repository home page in web browser', function () { mainPackage.prepare(); - return Q.Promise(function(resolve) { + return Q.Promise(function (resolve) { var home = helpers.command('home', { opn: resolve }); helpers.run(home, [mainPackage.path]); - }).then(function(url) { + }).then(function (url) { expect(url).to.be('http://bower.io'); }); }); @@ -37,10 +37,10 @@ describe('bower home', function () { it('opens home page of current repository', function () { mainPackage.prepare(); - return Q.Promise(function(resolve) { + return Q.Promise(function (resolve) { var home = helpers.command('home', { opn: resolve }); helpers.run(home, [undefined, { cwd: mainPackage.path }]); - }).then(function(url) { + }).then(function (url) { expect(url).to.be('http://bower.io'); }); }); @@ -48,10 +48,10 @@ describe('bower home', function () { it('errors if no homepage is set', function () { wrongPackage.prepare(); - return Q.Promise(function(resolve) { + return Q.Promise(function (resolve) { var home = helpers.command('home', { opn: resolve }); helpers.run(home, [wrongPackage.path]).fail(resolve); - }).then(function(reason) { + }).then(function (reason) { expect(reason.message).to.be('No homepage set for package'); expect(reason.code).to.be('ENOHOME'); }); diff --git a/test/commands/info.js b/test/commands/info.js index 436bd5db3..8dcc64696 100644 --- a/test/commands/info.js +++ b/test/commands/info.js @@ -5,7 +5,7 @@ var info = helpers.command('info'); describe('bower info', function () { - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(info.readOptions(['pkg', 'property'])) .to.eql(['pkg', 'property']); }); @@ -30,7 +30,7 @@ describe('bower info', function () { }); it('just returns if not package is specified', function () { - return helpers.run(info).spread(function(results) { + return helpers.run(info).spread(function (results) { expect(results).to.be(undefined); }); }); @@ -38,7 +38,7 @@ describe('bower info', function () { it('shows info about given package', function () { mainPackage.prepareGit({}); - return helpers.run(info, [mainPackage.path]).spread(function(results) { + return helpers.run(info, [mainPackage.path]).spread(function (results) { expect(results).to.eql({ 'latest': meta2, 'name': mainPackage.path, diff --git a/test/commands/init.js b/test/commands/init.js index 60acf0f59..5b74f4215 100644 --- a/test/commands/init.js +++ b/test/commands/init.js @@ -7,7 +7,7 @@ describe('bower init', function () { var mainPackage = new helpers.TempDir(); - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(init.readOptions([])) .to.eql([]); }); @@ -74,7 +74,7 @@ describe('bower init', function () { var logger = init({ cwd: mainPackage.path, interactive: true }); - return helpers.expectEvent(logger, 'log').spread(function(event) { + return helpers.expectEvent(logger, 'log').spread(function (event) { expect(event.level).to.be('warn'); expect(event.message).to.be( 'The existing bower.json file will be used and filled in' @@ -106,7 +106,7 @@ describe('bower init', function () { .spread(function (prompt, answer) { // Get defaults from prompt - var defaults = prompt.reduce(function(memo, obj) { + var defaults = prompt.reduce(function (memo, obj) { memo[obj.name] = obj['default']; return memo; }, {}); diff --git a/test/commands/install.js b/test/commands/install.js index e94f42d2f..33213948f 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -8,7 +8,7 @@ var tar = require('tar-fs'); var destroy = require('destroy'); var Q = require('q'); -describe('bower install', function() { +describe('bower install', function () { var tempDir = new helpers.TempDir(); @@ -16,7 +16,7 @@ describe('bower install', function() { cwd: tempDir.path }); - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(install.readOptions(['jquery', 'angular', '-F', '-p', '-S', '-D', '-E'])) .to.eql([ ['jquery', 'angular'], { @@ -29,7 +29,7 @@ describe('bower install', function() { ]); }); - it('correctly reads long arguments', function() { + it('correctly reads long arguments', function () { expect(install.readOptions([ 'jquery', 'angular', '--force-latest', '--production', '--save', '--save-dev', '--save-exact' @@ -67,7 +67,7 @@ describe('bower install', function() { } }); - it('writes to bower.json if --save flag is used', function() { + it('writes to bower.json if --save flag is used', function () { mainPackage.prepare(); tempDir.prepare({ @@ -80,12 +80,12 @@ describe('bower install', function() { [mainPackage.path], { save: true } - ]).then(function() { + ]).then(function () { expect(tempDir.read('bower.json')).to.contain('dependencies'); }); }); - it('writes to bower.json if save config setting is set to true', function() { + it('writes to bower.json if save config setting is set to true', function () { mainPackage.prepare(); tempDir.prepare({ @@ -98,12 +98,12 @@ describe('bower install', function() { [mainPackage.path], {}, { save: true } - ]).then(function() { + ]).then(function () { expect(tempDir.read('bower.json')).to.contain('dependencies'); }); }); - it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function() { + it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function () { mainPackage.prepare({ 'bower.json': { name: 'package', @@ -122,12 +122,12 @@ describe('bower install', function() { saveExact: true, save: true } - ]).then(function() { + ]).then(function () { expect(tempDir.readJson('bower.json').dependencies.package).to.equal(mainPackage.path + '#1.2.3'); }); }); - it('writes an exact version number to dependencies in bower.json if save and save-exact config settings are set to true', function() { + it('writes an exact version number to dependencies in bower.json if save and save-exact config settings are set to true', function () { mainPackage.prepare({ 'bower.json': { name: 'package', @@ -146,12 +146,12 @@ describe('bower install', function() { saveExact: true, save: true } - ]).then(function() { + ]).then(function () { expect(tempDir.readJson('bower.json').dependencies.package).to.equal(mainPackage.path + '#1.2.3'); }); }); - it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function() { + it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function () { mainPackage.prepare({ 'bower.json': { name: 'package', @@ -170,12 +170,12 @@ describe('bower install', function() { saveExact: true, saveDev: true } - ]).then(function() { + ]).then(function () { expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(mainPackage.path + '#0.1.0'); }); }); - it('writes an exact version number to devDependencies in bower.json if save-exact config setting is true and --save-dev flag is used', function() { + it('writes an exact version number to devDependencies in bower.json if save-exact config setting is true and --save-dev flag is used', function () { mainPackage.prepare({ 'bower.json': { name: 'package', @@ -195,12 +195,12 @@ describe('bower install', function() { }, { saveExact: true } - ]).then(function() { + ]).then(function () { expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(mainPackage.path + '#0.1.0'); }); }); - it('reads .bowerrc from cwd', function() { + it('reads .bowerrc from cwd', function () { mainPackage.prepare({ foo: 'bar' }); @@ -217,12 +217,12 @@ describe('bower install', function() { } }); - return helpers.run(install).then(function() { + return helpers.run(install).then(function () { expect(tempDir.read('assets/package/foo')).to.be('bar'); }); }); - it('.bowerrc directory can be an absolute path', function() { + it('.bowerrc directory can be an absolute path', function () { mainPackage.prepare({ foo: 'bar' }); @@ -239,10 +239,10 @@ describe('bower install', function() { } }); - return helpers.run(install).then(function() { + return helpers.run(install).then(function () { expect(require('fs').readFileSync('/tmp/bower-absolute-destination-directory/package/foo', 'utf8').toString()).to.be('bar'); var deferred = Q.defer(); - rimraf('/tmp/bower-absolute-destination-directory', function(err) { + rimraf('/tmp/bower-absolute-destination-directory', function (err) { if(err) { deferred.reject(err); } else { @@ -253,7 +253,7 @@ describe('bower install', function() { }); }); - it('runs preinstall hook', function() { + it('runs preinstall hook', function () { mainPackage.prepare(); tempDir.prepare({ @@ -270,12 +270,12 @@ describe('bower install', function() { } }); - return helpers.run(install).then(function() { + return helpers.run(install).then(function () { expect(tempDir.read('preinstall.txt')).to.be('package'); }); }); - it('runs postinstall hook', function() { + it('runs postinstall hook', function () { mainPackage.prepare(); tempDir.prepare({ @@ -292,13 +292,13 @@ describe('bower install', function() { } }); - return helpers.run(install).then(function() { + return helpers.run(install).then(function () { expect(tempDir.read('postinstall.txt')).to.be('package'); }); }); // To be discussed, but that's the implementation now - it('does not run hooks if nothing is installed', function() { + it('does not run hooks if nothing is installed', function () { tempDir.prepare({ 'bower.json': { name: 'test' @@ -311,12 +311,12 @@ describe('bower install', function() { } }); - return helpers.run(install).then(function() { + return helpers.run(install).then(function () { expect(tempDir.exists('hooks.txt')).to.be(false); }); }); - it('runs postinstall after bower.json is written', function() { + it('runs postinstall after bower.json is written', function () { mainPackage.prepare(); tempDir.prepare({ @@ -334,12 +334,12 @@ describe('bower install', function() { [mainPackage.path], { save: true } - ]).then(function() { + ]).then(function () { expect(tempDir.read('hook.txt')).to.contain('dependencies'); }); }); - it('display the output of hook scripts', function(next) { + it('display the output of hook scripts', function (next) { mainPackage.prepare(); tempDir.prepare({ @@ -357,17 +357,17 @@ describe('bower install', function() { }); var lastAction = null; - helpers.run(install).logger.intercept(function(log) { + helpers.run(install).logger.intercept(function (log) { if (log.level === 'action') { lastAction = log; } - }).on('end', function() { + }).on('end', function () { expect(lastAction.message).to.be('foobar'); next(); }); }); - it('skips components not installed by bower', function() { + it('skips components not installed by bower', function () { mainPackage.prepare({ '.git': {} //Make a dummy file instead of using slower gitPrepare() }); @@ -381,7 +381,7 @@ describe('bower install', function() { } }); - return helpers.run(install).then(function() { + return helpers.run(install).then(function () { var packageFiles = fs.readdirSync(mainPackage.path); //presence of .git file implies folder was not overwritten expect(packageFiles).to.contain('.git'); @@ -413,12 +413,12 @@ describe('bower install', function() { } }); - return helpers.run(install).then(function() { + return helpers.run(install).then(function () { expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); }); }); - it('works for dependencies that point to tar files', function() { + it('works for dependencies that point to tar files', function () { var packageDir = path.join(__dirname, '../assets/package-tar.tar'); tempDir.prepare({ 'bower.json': { @@ -429,12 +429,12 @@ describe('bower install', function() { } }); - return helpers.run(install).then(function() { + return helpers.run(install).then(function () { expect(tempDir.read('bower_components/package/index.txt')).to.contain('1.0.0'); }); }); - it('does not install ignored dependencies', function() { + it('does not install ignored dependencies', function () { mainPackage.prepare(); var package2 = new helpers.TempDir({ 'bower.json': { @@ -464,13 +464,13 @@ describe('bower install', function() { } }); - return helpers.run(install).then(function() { + return helpers.run(install).then(function () { expect(tempDir.exists('bower_components/package')).to.be(false); expect(tempDir.exists('bower_components/package2')).to.be(true); }); }); - it('does not install ignored dependencies if run multiple times', function() { + it('does not install ignored dependencies if run multiple times', function () { mainPackage.prepare(); var package2 = new helpers.TempDir({ 'bower.json': { @@ -499,15 +499,15 @@ describe('bower install', function() { ignoredDependencies: ['package'] } }); - return helpers.run(install).then(function() { - return helpers.run(install).then(function() { + return helpers.run(install).then(function () { + return helpers.run(install).then(function () { expect(tempDir.exists('bower_components/package')).to.be(false); expect(tempDir.exists('bower_components/package2')).to.be(true); }); }); }); - it('recognizes proxy option in config', function(done) { + it('recognizes proxy option in config', function (done) { this.timeout(10000); tempDir.prepare({ @@ -532,25 +532,25 @@ describe('bower install', function() { undefined, { proxy: 'http://dummy.local/' } ]) - .fail(function(error) { + .fail(function (error) { expect(error.message).to.equal('Status code of 500'); done(); }); }); - it('errors if the components directory is not a directory', function() { + it('errors if the components directory is not a directory', function () { tempDir.prepare({ '.bowerrc': { directory: '.bowerrc' } }); - return helpers.run(install).fail(function(error) { + return helpers.run(install).fail(function (error) { expect(error.code).to.equal('ENOTDIR'); }); }); - it('works if the package is a compressed single directory containing another directory with the same name', function() { + it('works if the package is a compressed single directory containing another directory with the same name', function () { var mainPackageBaseName = path.basename(mainPackage.path); var parentDir = path.dirname(mainPackage.path); @@ -565,7 +565,7 @@ describe('bower install', function() { var stream = tar.pack(parentDir, { entries: [mainPackageBaseName] }); stream .pipe(fs.createWriteStream(archivePath)) - .on('finish', function(result) { + .on('finish', function (result) { destroy(stream); archiveDeferred.resolve(result); }); @@ -578,15 +578,15 @@ describe('bower install', function() { }); return archiveDeferred.promise - .then(function() { + .then(function () { return helpers.run(install, [[archivePath]]); }) - .then(function() { + .then(function () { expect(tempDir.read(path.join('bower_components', 'package', mainPackageBaseName, 'test.js'))).to.contain('test'); }); }); - it('works if the package is an archive containing a file with an identical name', function() { + it('works if the package is an archive containing a file with an identical name', function () { var parentDir = path.dirname(mainPackage.path); mainPackage.prepare({ @@ -598,7 +598,7 @@ describe('bower install', function() { var stream = tar.pack(mainPackage.path); stream .pipe(fs.createWriteStream(archivePath)) - .on('finish', function(result) { + .on('finish', function (result) { destroy(stream); archiveDeferred.resolve(result); }); @@ -611,10 +611,10 @@ describe('bower install', function() { }); return archiveDeferred.promise - .then(function() { + .then(function () { return helpers.run(install, [[archivePath]]); }) - .then(function() { + .then(function () { expect(tempDir.read(path.join('bower_components', 'package', 'package.tar'))).to.contain('test'); }); }); diff --git a/test/commands/link.js b/test/commands/link.js index 9751baef5..9378f5f66 100644 --- a/test/commands/link.js +++ b/test/commands/link.js @@ -22,13 +22,13 @@ describe('bower link', function () { var linksDir = new helpers.TempDir(); - beforeEach(function() { + beforeEach(function () { mainPackage.prepare(); otherPackage.prepare(); linksDir.prepare(); }); - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(link.readOptions(['jquery', 'angular'])) .to.eql(['jquery', 'angular']); }); @@ -41,7 +41,7 @@ describe('bower link', function () { links: linksDir.path } } - ]).then(function() { + ]).then(function () { expect(linksDir.read('package/index.js')) .to.be('Hello World!'); }); @@ -64,7 +64,7 @@ describe('bower link', function () { } } ]); - }).then(function() { + }).then(function () { expect(otherPackage.read('bower_components/package/index.js')) .to.be('Hello World!'); }); @@ -88,7 +88,7 @@ describe('bower link', function () { } } ]); - }).then(function() { + }).then(function () { expect(otherPackage.read('valid-extend/package/index.js')) .to.be('Hello World!'); }); @@ -113,7 +113,7 @@ describe('bower link', function () { } } ]); - }).then(function() { + }).then(function () { expect(otherPackage.read('valid-override/package/index.js')) .to.be('Hello World!'); }); @@ -136,7 +136,7 @@ describe('bower link', function () { } } ]); - }).then(function() { + }).then(function () { expect(otherPackage.read('bower_components/local/index.js')) .to.be('Hello World!'); }); @@ -150,9 +150,9 @@ describe('bower link', function () { links: linksDir.path } } - ]).then(function() { + ]).then(function () { throw 'Should fail creating a link!'; - }).fail(function(reason) { + }).fail(function (reason) { expect(reason.code).to.be('ENOENT'); expect(reason.message).to.be('Failed to create link to package'); }); diff --git a/test/commands/list.js b/test/commands/list.js index fb506cad1..8385ab380 100644 --- a/test/commands/list.js +++ b/test/commands/list.js @@ -15,7 +15,7 @@ describe('bower list', function () { var gitPackage = new helpers.TempDir(); - var install = function(packages, options, config) { + var install = function (packages, options, config) { config = object.merge(config || {}, { cwd: tempDir.path }); @@ -23,7 +23,7 @@ describe('bower list', function () { return helpers.run(commands.install, [packages, options, config]); }; - var list = function(options, config) { + var list = function (options, config) { config = object.merge(config || {}, { cwd: tempDir.path }); @@ -31,7 +31,7 @@ describe('bower list', function () { return helpers.run(commands.list, [options, config]); }; - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(commands.list.readOptions(['-p', '-r'])) .to.eql([{ paths: true, @@ -39,7 +39,7 @@ describe('bower list', function () { }]); }); - it('correctly reads long arguments', function() { + it('correctly reads long arguments', function () { expect(commands.list.readOptions(['--paths', '--relative'])) .to.eql([{ paths: true, @@ -50,7 +50,7 @@ describe('bower list', function () { it('lists no packages when nothing installed', function () { tempDir.prepare(); - return list().spread(function(results) { + return list().spread(function (results) { expect(results).to.be.an(Object); expect(results.canonicalDir).to.equal(tempDir.path); expect(results.pkgMeta.dependencies).to.eql({}); @@ -71,8 +71,8 @@ describe('bower list', function () { }).prepare(); mainPackage.prepare(); - return install([mainPackage.path]).then(function() { - return list().spread(function(results) { + return install([mainPackage.path]).then(function () { + return list().spread(function (results) { expect(results).to.be.an(Object); expect(results.canonicalDir).to.equal(tempDir.path); expect(results.pkgMeta.dependencies).to.eql({ @@ -104,8 +104,8 @@ describe('bower list', function () { }).prepare(); mainPackage.prepare(); - return install([mainPackage.path]).then(function() { - return list({relative: true}).spread(function(results) { + return install([mainPackage.path]).then(function () { + return list({relative: true}).spread(function (results) { expect(results).to.be.an(Object); expect(results.canonicalDir).to.equal(tempDir.path); expect(results.dependencies).to.be.an(Object); @@ -132,8 +132,8 @@ describe('bower list', function () { }).prepare(); mainPackage.prepare(); - return install([mainPackage.path]).then(function() { - return list({paths: true}).spread(function(results) { + return install([mainPackage.path]).then(function () { + return list({paths: true}).spread(function (results) { expect(results).to.be.an(Object); expect(results.package).to.equal( 'bower_components/package/test.txt' @@ -152,8 +152,8 @@ describe('bower list', function () { }).prepare(); mainPackage.prepare(); - return install([mainPackage.path]).then(function() { - return list({paths: true}).spread(function(results) { + return install([mainPackage.path]).then(function () { + return list({paths: true}).spread(function (results) { expect(results).to.be.an(Object); expect(results.package).to.be.an(Object); expect(results.package).to.eql([ @@ -191,8 +191,8 @@ describe('bower list', function () { } }); - return install().then(function() { - return list().spread(function(results) { + return install().then(function () { + return list().spread(function (results) { expect(results).to.be.an(Object); expect(results.canonicalDir).to.equal(tempDir.path); expect(results.pkgMeta.dependencies).to.eql({ @@ -241,8 +241,8 @@ describe('bower list', function () { } }); - return install().then(function() { - return list({relative: true}).spread(function(results) { + return install().then(function () { + return list({relative: true}).spread(function (results) { expect(results.canonicalDir).to.equal(tempDir.path); expect(results.pkgMeta.dependencies).to.eql({ package: gitPackage.path + '#1.0.0' diff --git a/test/commands/login.js b/test/commands/login.js index 1654751bb..aa8242ec7 100644 --- a/test/commands/login.js +++ b/test/commands/login.js @@ -52,13 +52,13 @@ var loginFactory = function (options) { describe('bower login', function () { - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(login.readOptions(['--token', 'foobar'])) .to.eql([{ token: 'foobar' }]); }); it('fails if run in non-interactive shell without token passed', function () { - return helpers.run(login, []).fail(function(reason) { + return helpers.run(login, []).fail(function (reason) { expect(reason.message).to.be('Login requires an interactive shell'); expect(reason.code).to.be('ENOINT'); }); @@ -81,7 +81,7 @@ describe('bower login', function () { }); return helpers.expectEvent(logger, 'end') - .spread(function(options) { + .spread(function (options) { expect(options.token).to.be('faketoken'); }); }); @@ -105,7 +105,7 @@ describe('bower login', function () { }); return helpers.expectEvent(logger, 'end') - .spread(function(options) { + .spread(function (options) { expect(options.token).to.be('faketwoauthtoken'); }); }); diff --git a/test/commands/lookup.js b/test/commands/lookup.js index 3e385f62c..5057ce149 100644 --- a/test/commands/lookup.js +++ b/test/commands/lookup.js @@ -7,9 +7,9 @@ describe('bower lookup', function () { var lookupWithResult = function (response) { return helpers.command('lookup', { - 'bower-registry-client': function() { + 'bower-registry-client': function () { return { - lookup: function(query, callback) { + lookup: function (query, callback) { if (query in response) { callback(null, response[query]); } else { @@ -21,7 +21,7 @@ describe('bower lookup', function () { }); }; - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(lookup.readOptions(['jquery'])) .to.eql(['jquery']); }); @@ -29,7 +29,7 @@ describe('bower lookup', function () { it('lookups package by name', function () { var lookup = lookupWithResult({ jquery: { url: 'http://jquery.org' } }); - return helpers.run(lookup, ['jquery']).spread(function(result) { + return helpers.run(lookup, ['jquery']).spread(function (result) { expect(result).to.eql({ name: 'jquery', url: 'http://jquery.org' @@ -40,7 +40,7 @@ describe('bower lookup', function () { it('returns null if no package is found', function () { var lookup = lookupWithResult({ jquery: { url: 'http://jquery.org' } }); - return helpers.run(lookup, ['foobar']).spread(function(result) { + return helpers.run(lookup, ['foobar']).spread(function (result) { expect(result).to.eql(null); }); }); @@ -48,7 +48,7 @@ describe('bower lookup', function () { it('returns null if called without argument', function () { var lookup = lookupWithResult({ jquery: { url: 'http://jquery.org' } }); - return helpers.run(lookup, []).spread(function(result) { + return helpers.run(lookup, []).spread(function (result) { expect(result).to.eql(null); }); }); diff --git a/test/commands/prune.js b/test/commands/prune.js index cf2d2218d..e9092d767 100644 --- a/test/commands/prune.js +++ b/test/commands/prune.js @@ -15,12 +15,12 @@ describe('bower home', function () { 'bower_components/jquery/jquery.js': 'jquery source' }); - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(prune.readOptions(['-p'])) .to.eql([{ production: true }]); }); - it('correctly reads long arguments', function() { + it('correctly reads long arguments', function () { expect(prune.readOptions(['--production'])) .to.eql([{ production: true }]); }); @@ -31,7 +31,7 @@ describe('bower home', function () { 'bower_components/angular/.bower.json': { name: 'angular' } }); - return helpers.run(prune, [{}, { cwd: mainPackage.path }]).then(function() { + return helpers.run(prune, [{}, { cwd: mainPackage.path }]).then(function () { expect(mainPackage.exists('bower_components/angular/angular.js')) .to.be(false); }); @@ -42,7 +42,7 @@ describe('bower home', function () { 'bower_components/angular/angular.js': 'angular source' }); - return helpers.run(prune, [{}, { cwd: mainPackage.path }]).then(function() { + return helpers.run(prune, [{}, { cwd: mainPackage.path }]).then(function () { expect(mainPackage.exists('bower_components/angular/angular.js')) .to.be(true); }); @@ -57,7 +57,7 @@ describe('bower home', function () { 'components/angular/angular.js': 'angular source' }); - return helpers.run(prune, [{}, { cwd: mainPackage.path }]).then(function() { + return helpers.run(prune, [{}, { cwd: mainPackage.path }]).then(function () { expect(mainPackage.exists('components/angular/angular.js')).to.be(false); expect(mainPackage.exists('bower_components/angular/angular.js')).to.be(true); }); diff --git a/test/commands/register.js b/test/commands/register.js index 9c0b70860..c677ed95d 100644 --- a/test/commands/register.js +++ b/test/commands/register.js @@ -7,13 +7,13 @@ var register = helpers.command('register'); var fakeRepositoryFactory = function (canonicalDir, pkgMeta) { function FakeRepository() { } - FakeRepository.prototype.fetch = function() { + FakeRepository.prototype.fetch = function () { return Q.fcall(function () { return [canonicalDir, pkgMeta]; }); }; - FakeRepository.prototype.getRegistryClient = function() { + FakeRepository.prototype.getRegistryClient = function () { return { register: function (name, url, cb) { cb(null, { name: name, url: url }); @@ -42,13 +42,13 @@ describe('bower register', function () { } }); - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(register.readOptions(['jquery', 'url'])) .to.eql(['jquery', 'url']); }); it('errors if name is not provided', function () { - return helpers.run(register).fail(function(reason) { + return helpers.run(register).fail(function (reason) { expect(reason.message).to.be('Usage: bower register '); expect(reason.code).to.be('EINVFORMAT'); }); @@ -56,7 +56,7 @@ describe('bower register', function () { it('errors if url is not provided', function () { return helpers.run(register, ['some-name']) - .fail(function(reason) { + .fail(function (reason) { expect(reason.message).to.be('Usage: bower register '); expect(reason.code).to.be('EINVFORMAT'); }); @@ -67,7 +67,7 @@ describe('bower register', function () { var register = registerFactory(mainPackage.path, mainPackage.meta()); return helpers.run(register, ['some-name', 'git://fake-url.git']) - .fail(function(reason) { + .fail(function (reason) { expect(reason.message).to.be('The package you are trying to register is marked as private'); expect(reason.code).to.be('EPRIV'); }); @@ -78,7 +78,7 @@ describe('bower register', function () { var register = registerFactory(mainPackage.path, mainPackage.meta()); return helpers.run(register, ['some-name', 'git://fake-url.git']) - .spread(function(result) { + .spread(function (result) { expect(result).to.eql({ // Result from register action on stub name: 'some-name', url: 'git://fake-url.git' @@ -96,7 +96,7 @@ describe('bower register', function () { ); return helpers.expectEvent(promise.logger, 'confirm') - .spread(function(e) { + .spread(function (e) { expect(e.type).to.be('confirm'); expect(e.message).to.be('Registering a package will make it installable via the registry (https://bower.herokuapp.com), continue?'); expect(e.default).to.be(true); diff --git a/test/commands/search.js b/test/commands/search.js index 553df9b4b..57d746daf 100644 --- a/test/commands/search.js +++ b/test/commands/search.js @@ -6,15 +6,15 @@ var search = helpers.command('search'); describe('bower search', function () { - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(search.readOptions(['jquery'])) .to.eql(['jquery']); }); it('searches for single repository', function () { - return Q.Promise(function(resolve) { + return Q.Promise(function (resolve) { var search = helpers.command('search', { - 'bower-registry-client': function() { + 'bower-registry-client': function () { return { search: resolve }; @@ -22,7 +22,7 @@ describe('bower search', function () { }); helpers.run(search, ['jquery'], {}); - }).then(function(query) { + }).then(function (query) { expect(query).to.be('jquery'); }); }); @@ -30,9 +30,9 @@ describe('bower search', function () { it('lists all repositories when no query given in non-interactive mode', function () { var nonInteractiveConfig = { interactive: false }; - return Q.Promise(function(resolve) { + return Q.Promise(function (resolve) { var search = helpers.command('search', { - 'bower-registry-client': function() { + 'bower-registry-client': function () { return { list: resolve }; @@ -47,7 +47,7 @@ describe('bower search', function () { var interactiveConfig = { interactive: true, json: true }; var search = helpers.command('search', { - 'bower-registry-client': function() { + 'bower-registry-client': function () { return { list: function (cb) { return cb(null, 'foobar'); } }; @@ -55,7 +55,7 @@ describe('bower search', function () { }); return helpers.run(search, [null, interactiveConfig]) - .spread(function(result) { + .spread(function (result) { expect(result).to.be('foobar'); }); }); @@ -64,19 +64,19 @@ describe('bower search', function () { var interactiveConfig = { interactive: true }; var search = helpers.command('search', { - 'bower-registry-client': function() { + 'bower-registry-client': function () { return { - list: function() { throw 'list called'; }, - search: function() { throw 'search called'; } + list: function () { throw 'list called'; }, + search: function () { throw 'search called'; } }; } }); return helpers.run(search, [null, interactiveConfig]) - .then(function(commandResult) { + .then(function (commandResult) { expect().fail('should fail'); }) - .catch(function(e) { + .catch(function (e) { expect(e.code).to.be('EREADOPTIONS'); }); }); diff --git a/test/commands/uninstall.js b/test/commands/uninstall.js index 838f7674a..5e02b7e0b 100644 --- a/test/commands/uninstall.js +++ b/test/commands/uninstall.js @@ -17,7 +17,7 @@ describe('bower uninstall', function () { } }); - beforeEach(function() { + beforeEach(function () { tempDir.prepare(); }); @@ -32,12 +32,12 @@ describe('bower uninstall', function () { interactive: true }; - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(uninstall.readOptions(['jquery', '-S', '-D'])) .to.eql([['jquery'], { save: true, saveDev: true }]); }); - it('correctly reads long arguments', function() { + it('correctly reads long arguments', function () { expect(uninstall.readOptions(['jquery', '--save', '--save-dev'])) .to.eql([['jquery'], { save: true, saveDev: true }]); }); @@ -75,8 +75,8 @@ describe('bower uninstall', function () { directory: 'other_directory', interactive: true }]) - .then(function() { - expect(function() { + .then(function () { + expect(function () { fs.statSync(targetPath); }).to.throwException(/no such file or directory/); }); @@ -92,8 +92,8 @@ describe('bower uninstall', function () { directory: path.resolve(tempDir.path, 'other_directory'), interactive: true }]) - .then(function() { - expect(function() { + .then(function () { + expect(function () { fs.statSync(targetPath); }).to.throwException(/no such file or directory/); }); diff --git a/test/commands/unregister.js b/test/commands/unregister.js index fc5a3ad88..2cfdef97c 100644 --- a/test/commands/unregister.js +++ b/test/commands/unregister.js @@ -4,7 +4,7 @@ var helpers = require('../helpers'); var fakeRepositoryFactory = function () { function FakeRepository() { } - FakeRepository.prototype.getRegistryClient = function() { + FakeRepository.prototype.getRegistryClient = function () { return { unregister: function (name, cb) { cb(null, { name: name }); @@ -25,13 +25,13 @@ var unregisterFactory = function () { describe('bower unregister', function () { - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(unregister.readOptions(['jquery'])) .to.eql(['jquery']); }); it('errors if name is not provided', function () { - return helpers.run(unregister).fail(function(reason) { + return helpers.run(unregister).fail(function (reason) { expect(reason.message).to.be('Usage: bower unregister '); expect(reason.code).to.be('EINVFORMAT'); }); @@ -41,7 +41,7 @@ describe('bower unregister', function () { var unregister = unregisterFactory(); return helpers.run(unregister, ['some-name']) - .spread(function(result) { + .spread(function (result) { expect(result).to.eql({ // Result from register action on stub name: 'some-name' @@ -60,7 +60,7 @@ describe('bower unregister', function () { ); return helpers.expectEvent(promise.logger, 'confirm') - .spread(function(e) { + .spread(function (e) { expect(e.type).to.be('confirm'); expect(e.message).to.be('You are about to remove component "some-name" from the bower registry (http://localhost). It is generally considered bad behavior to remove versions of a library that others are depending on. Are you really sure?'); expect(e.default).to.be(false); diff --git a/test/commands/update.js b/test/commands/update.js index d889809c8..d5e31a037 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -42,7 +42,7 @@ describe('bower update', function () { } }).prepare(); - var updateLogger = function(packages, options, config) { + var updateLogger = function (packages, options, config) { config = object.merge(config || {}, { cwd: tempDir.path }); @@ -50,13 +50,13 @@ describe('bower update', function () { return commands.update(packages, options, config); }; - var update = function(packages, options, config) { + var update = function (packages, options, config) { var logger = updateLogger(packages, options, config); return helpers.expectEvent(logger, 'end'); }; - var install = function(packages, options, config) { + var install = function (packages, options, config) { config = object.merge(config || {}, { cwd: tempDir.path }); @@ -68,12 +68,12 @@ describe('bower update', function () { return helpers.expectEvent(logger, 'end'); }; - it('correctly reads arguments', function() { + it('correctly reads arguments', function () { expect(updateCmd.readOptions(['jquery', '-F', '-p'])) .to.eql([['jquery'], { forceLatest: true, production: true }]); }); - it('install missing packages', function() { + it('install missing packages', function () { mainPackage.prepare(); tempDir.prepare({ @@ -85,13 +85,13 @@ describe('bower update', function () { } }); - return update().then(function() { + return update().then(function () { expect(tempDir.exists('bower_components/package/bower.json')).to.equal(true); expect(tempDir.read('bower_components/package/bower.json')).to.contain('"name": "package"'); }); }); - it('does not install ignored dependencies', function() { + it('does not install ignored dependencies', function () { var package3 = new helpers.TempDir({ 'bower.json': { name: 'package3' @@ -119,13 +119,13 @@ describe('bower update', function () { } }); - return update().then(function() { + return update().then(function () { expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); expect(tempDir.exists('bower_components/package3')).to.equal(false); }); }); - it('does not install ignored dependencies if run multiple times', function() { + it('does not install ignored dependencies if run multiple times', function () { var package3 = new helpers.TempDir({ 'bower.json': { name: 'package3' @@ -153,8 +153,8 @@ describe('bower update', function () { } }); - return update().then(function() { - return update().then(function() { + return update().then(function () { + return update().then(function () { expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); expect(tempDir.exists('bower_components/package3')).to.equal(false); }); @@ -162,7 +162,7 @@ describe('bower update', function () { }); - it('runs preinstall hook when installing missing package', function() { + it('runs preinstall hook when installing missing package', function () { mainPackage.prepare(); tempDir.prepare({ @@ -179,12 +179,12 @@ describe('bower update', function () { } }); - return update().then(function() { + return update().then(function () { expect(tempDir.read('preinstall.txt')).to.be('package'); }); }); - it('runs postinstall hook when installing missing package', function() { + it('runs postinstall hook when installing missing package', function () { mainPackage.prepare(); tempDir.prepare({ @@ -201,12 +201,12 @@ describe('bower update', function () { } }); - return update().then(function() { + return update().then(function () { expect(tempDir.read('postinstall.txt')).to.be('package'); }); }); - it('doesn\'t runs postinstall when no package is update', function() { + it('doesn\'t runs postinstall when no package is update', function () { mainPackage.prepare(); tempDir.prepare({ @@ -223,16 +223,16 @@ describe('bower update', function () { } }); - return install().then(function() { + return install().then(function () { tempDir.prepare(); - return update().then(function() { + return update().then(function () { expect(tempDir.exists('postinstall.txt')).to.be(false); }); }); }); - it('updates a package', function() { + it('updates a package', function () { tempDir.prepare({ 'bower.json': { name: 'test', @@ -242,7 +242,7 @@ describe('bower update', function () { } }); - return install().then(function() { + return install().then(function () { expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); @@ -255,7 +255,7 @@ describe('bower update', function () { } }); - return update().then(function() { + return update().then(function () { expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.1'); }); }); @@ -303,7 +303,7 @@ describe('bower update', function () { } }); - return install().then(function() { + return install().then(function () { expect(tempDir.readJson('bower_components/package2/bower.json').version).to.equal('1.0.0'); expect(tempDir.exists('bower_components/package3')).to.equal(false); @@ -320,14 +320,14 @@ describe('bower update', function () { } }); - return update().then(function() { + return update().then(function () { expect(tempDir.readJson('bower_components/package2/bower.json').version).to.equal('1.0.1'); expect(tempDir.exists('bower_components/package3')).to.equal(false); }); }); }); - it('runs preinstall hook when updating a package', function() { + it('runs preinstall hook when updating a package', function () { tempDir.prepare({ 'bower.json': { name: 'test', @@ -337,7 +337,7 @@ describe('bower update', function () { } }); - return install().then(function() { + return install().then(function () { tempDir.prepare({ 'bower.json': { name: 'test', @@ -353,13 +353,13 @@ describe('bower update', function () { }); expect(tempDir.exists('preinstall.txt')).to.be(false); - return update().then(function() { + return update().then(function () { expect(tempDir.read('preinstall.txt')).to.be('subPackage package'); }); }); }); - it('runs postinstall hook when updating a package', function() { + it('runs postinstall hook when updating a package', function () { tempDir.prepare({ 'bower.json': { name: 'test', @@ -369,7 +369,7 @@ describe('bower update', function () { } }); - return install().then(function() { + return install().then(function () { tempDir.prepare({ 'bower.json': { name: 'test', @@ -386,7 +386,7 @@ describe('bower update', function () { }); expect(tempDir.exists('postinstall.txt')).to.be(false); - return update().then(function() { + return update().then(function () { expect(tempDir.read('postinstall.txt')).to.be('subPackage package'); }); }); diff --git a/test/commands/version.js b/test/commands/version.js index 64b30acc5..3eab1aa4b 100644 --- a/test/commands/version.js +++ b/test/commands/version.js @@ -21,50 +21,50 @@ describe('bower list', function () { } }); - it('bumps patch version', function() { + it('bumps patch version', function () { mainPackage.prepare(); - return helpers.run(version, ['patch', {}, { cwd: mainPackage.path }]).then(function() { + return helpers.run(version, ['patch', {}, { cwd: mainPackage.path }]).then(function () { expect(mainPackage.readJson('bower.json').version).to.be('0.0.1'); }); }); - it('bumps minor version', function() { + it('bumps minor version', function () { mainPackage.prepare(); - return helpers.run(version, ['minor', {}, { cwd: mainPackage.path }]).then(function() { + return helpers.run(version, ['minor', {}, { cwd: mainPackage.path }]).then(function () { expect(mainPackage.readJson('bower.json').version).to.be('0.1.0'); }); }); - it('bumps major version', function() { + it('bumps major version', function () { mainPackage.prepare(); - return helpers.run(version, ['major', {}, { cwd: mainPackage.path }]).then(function() { + return helpers.run(version, ['major', {}, { cwd: mainPackage.path }]).then(function () { expect(mainPackage.readJson('bower.json').version).to.be('1.0.0'); }); }); - it('changes version', function() { + it('changes version', function () { mainPackage.prepare(); - return helpers.run(version, ['1.2.3', {}, { cwd: mainPackage.path }]).then(function() { + return helpers.run(version, ['1.2.3', {}, { cwd: mainPackage.path }]).then(function () { expect(mainPackage.readJson('bower.json').version).to.be('1.2.3'); }); }); - it('returns the new version', function() { + it('returns the new version', function () { mainPackage.prepare(); - return helpers.run(version, ['major', {}, { cwd: mainPackage.path }]).then(function(results) { + return helpers.run(version, ['major', {}, { cwd: mainPackage.path }]).then(function (results) { expect(results[0]).to.be('1.0.0'); }); }); - it('bumps patch version, create commit, and tag', function() { + it('bumps patch version, create commit, and tag', function () { gitPackage.prepareGit(); - return helpers.run(version, ['patch', {}, { cwd: gitPackage.path }]).then(function() { + return helpers.run(version, ['patch', {}, { cwd: gitPackage.path }]).then(function () { expect(gitPackage.readJson('bower.json').version).to.be('0.0.1'); var tags = gitPackage.git('tag'); @@ -74,10 +74,10 @@ describe('bower list', function () { }); }); - it('bumps with custom commit message', function() { + it('bumps with custom commit message', function () { gitPackage.prepareGit(); - return helpers.run(version, ['patch', { message: 'Bumping %s, because what'}, { cwd: gitPackage.path }]).then(function() { + return helpers.run(version, ['patch', { message: 'Bumping %s, because what'}, { cwd: gitPackage.path }]).then(function () { expect(gitPackage.readJson('bower.json').version).to.be('0.0.1'); var tags = gitPackage.git('tag'); diff --git a/test/core/Manager.js b/test/core/Manager.js index 93c983bec..e1529291b 100644 --- a/test/core/Manager.js +++ b/test/core/Manager.js @@ -36,7 +36,7 @@ describe('Manager', function () { describe('_areCompatible', function () { - describe('resolved is being fetched', function() { + describe('resolved is being fetched', function () { it('accepts endpoints with same targets', function () { expect(manager._areCompatible( @@ -232,7 +232,7 @@ describe('Manager', function () { ]); }); - it('leaves different targets intact', function() { + it('leaves different targets intact', function () { var unique = manager._uniquify([ { source: 'facebook.com', target: 'a1b2c3' }, { source: 'facebook.com', target: 'ffffff' } @@ -244,7 +244,7 @@ describe('Manager', function () { ]); }); - it('removes if same targets', function() { + it('removes if same targets', function () { var unique = manager._uniquify([ { source: 'facebook.com', target: 'ffffff' }, { source: 'facebook.com', target: 'ffffff' } @@ -255,7 +255,7 @@ describe('Manager', function () { ]); }); - it('ignores other fields', function() { + it('ignores other fields', function () { var unique = manager._uniquify([ { source: 'facebook.com', foo: 12 }, { source: 'facebook.com', bar: 13 } diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 2b0eace16..10c580d9f 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -341,7 +341,7 @@ describe('resolverFactory', function () { }); if (!helpers.hasSvn()) - describe.skip('should recognize svn remote endpoints correctly', function() {}); + describe.skip('should recognize svn remote endpoints correctly', function () {}); else it('should recognize svn remote endpoints correctly', function (next) { var promise = Q.resolve(); var endpoints; diff --git a/test/core/resolvers/gitRemoteResolver.js b/test/core/resolvers/gitRemoteResolver.js index 4bfb72073..6381424eb 100644 --- a/test/core/resolvers/gitRemoteResolver.js +++ b/test/core/resolvers/gitRemoteResolver.js @@ -264,7 +264,7 @@ describe('GitRemoteResolver', function () { }; }); - function createCmdHandlerFn (testSource, stderr) { + function createCmdHandlerFn(testSource, stderr) { return function (cmd, args, options) { expect(cmd).to.be('git'); expect(args).to.eql([ 'ls-remote', '--heads', testSource ]); @@ -394,7 +394,7 @@ describe('GitRemoteResolver', function () { expect(shallowCloningSupported).to.be(true); next(); - }, function(err) { + }, function (err) { next(err); }); }); @@ -439,7 +439,7 @@ describe('GitRemoteResolver', function () { expect(shallowCloningSupported).to.be(true); next(); - }, function(err) { + }, function (err) { next(err); }); }); @@ -493,7 +493,7 @@ describe('GitRemoteResolver', function () { expect(shallowCloningSupported).to.be(true); next(); - }, function(err) { + }, function (err) { next(err); }); }); diff --git a/test/core/resolvers/pluginResolverFactory.js b/test/core/resolvers/pluginResolverFactory.js index 0558cb9e0..0acab2b19 100644 --- a/test/core/resolvers/pluginResolverFactory.js +++ b/test/core/resolvers/pluginResolverFactory.js @@ -18,7 +18,7 @@ describe('pluginResolverFactory', function () { logger.removeAllListeners(); }); - var mockPluginResolver = function resolver (bower) { + var mockPluginResolver = function resolver(bower) { return { @@ -159,7 +159,7 @@ describe('pluginResolverFactory', function () { describe('.resolve', function () { it('should throw \'Resolver did not provide releases of package.\'', function (next) { - var mockPluginResolverWithEmptyReleases = function resolver (bower) { + var mockPluginResolverWithEmptyReleases = function resolver(bower) { return { match: function (source) { @@ -196,7 +196,7 @@ describe('pluginResolverFactory', function () { }); it('should throw \'No version found that was able to satisfy *.\'', function (next) { - var mockPluginResolverWithNoMatchingTarget = function resolver (bower) { + var mockPluginResolverWithNoMatchingTarget = function resolver(bower) { return { @@ -238,7 +238,7 @@ describe('pluginResolverFactory', function () { }); it('should throw \'Resolver does not accept version ranges\'', function (next) { - var mockPluginResolverWithInvalidTarget = function resolver (bower) { + var mockPluginResolverWithInvalidTarget = function resolver(bower) { return { match: function (source) { return true; @@ -275,7 +275,7 @@ describe('pluginResolverFactory', function () { it('should throw \'Resolver does not implement the "fetch" method.\'', function (next) { - var mockPluginResolverWithoutFetch = function resolver (bower) { + var mockPluginResolverWithoutFetch = function resolver(bower) { return { match: function (source) { return true; @@ -305,7 +305,7 @@ describe('pluginResolverFactory', function () { it('should throw \'Resolver did not provide path to extracted contents of package\'', function (next) { - var mockPluginResolverWithoutTempPath = function resolver (bower) { + var mockPluginResolverWithoutTempPath = function resolver(bower) { return { match: function (source) { @@ -354,7 +354,7 @@ describe('pluginResolverFactory', function () { expect(PluginResolver.isTargetable()).to.be.ok(); }); it('should reject mockPluginResolverWithoutReleasesFn', function () { - var mockPluginResolverWithoutReleasesFn = function resolver (bower) { + var mockPluginResolverWithoutReleasesFn = function resolver(bower) { return { match: function (source) { return true; @@ -388,7 +388,7 @@ describe('pluginResolverFactory', function () { describe('.match', function () { it('should throw when plugin does not implement .match', function () { - var mockPluginResolverWithoutMatch = function resolver (bower) { + var mockPluginResolverWithoutMatch = function resolver(bower) { return { @@ -435,7 +435,7 @@ describe('pluginResolverFactory', function () { describe('.locate', function () { it('should return source when plugin does not implement .locate', function () { - var mockPluginResolverWithoutLocate = function resolver (bower) { + var mockPluginResolverWithoutLocate = function resolver(bower) { return { diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index 108c30603..c30b69081 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -11,7 +11,7 @@ var SvnResolver = require('../../../lib/core/resolvers/SvnResolver'); var defaultConfig = require('../../../lib/config'); var helpers = require('../../helpers'); -if (!helpers.hasSvn()) describe.skip('SvnResolver', function() {}); +if (!helpers.hasSvn()) describe.skip('SvnResolver', function () {}); else describe('SvnResolver', function () { var tempDir = path.resolve(__dirname, '../../tmp/tmp'); var testPackage = path.resolve(__dirname, '../../assets/package-svn/repo'); diff --git a/test/helpers.js b/test/helpers.js index 70c3dd6b3..7c3005c50 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -54,8 +54,8 @@ after(function () { rimraf.sync(tmpLocation); }); -exports.TempDir = (function() { - function TempDir (defaults) { +exports.TempDir = (function () { + function TempDir(defaults) { this.path = path.join(tmpLocation, uuid.v4()); this.defaults = defaults; } @@ -66,7 +66,7 @@ exports.TempDir = (function() { defaults = defaults || this.defaults || {}; files = object.merge(files || {}, defaults); - this.meta = function(tag) { + this.meta = function (tag) { if (tag) { return files[tag]['bower.json']; } else { @@ -162,7 +162,7 @@ exports.TempDir = (function() { return TempDir; })(); -exports.expectEvent = function expectEvent (emitter, eventName) { +exports.expectEvent = function expectEvent(emitter, eventName) { var deferred = Q.defer(); emitter.once(eventName, function () { @@ -223,7 +223,7 @@ exports.run = function (command, args) { var logger = command.apply(null, args || []); // Hack so we can intercept prompring for data - logger.prompt = function(data) { + logger.prompt = function (data) { logger.emit('confirm', data); }; @@ -235,27 +235,27 @@ exports.run = function (command, args) { }; // Captures all stdout and stderr -exports.capture = function(callback) { +exports.capture = function (callback) { var oldStdout = process.stdout.write; var oldStderr = process.stderr.write; var stdout = ''; var stderr = ''; - process.stdout.write = function(text) { + process.stdout.write = function (text) { stdout += text; }; - process.stderr.write = function(text) { + process.stderr.write = function (text) { stderr += text; }; - return Q.fcall(callback).then(function() { + return Q.fcall(callback).then(function () { process.stdout.write = oldStdout; process.stderr.write = oldStderr; return [stdout, stderr]; - }).fail(function(e) { + }).fail(function (e) { process.stdout.write = oldStdout; process.stderr.write = oldStderr; @@ -263,7 +263,7 @@ exports.capture = function(callback) { }); }; -exports.hasSvn = function() { +exports.hasSvn = function () { try { which.sync('svn'); return true; @@ -272,7 +272,7 @@ exports.hasSvn = function() { } }; -exports.isWin = function() { +exports.isWin = function () { return process.platform === 'win32'; }; diff --git a/test/packages-svn.js b/test/packages-svn.js index 028db18ce..a0d2ab560 100644 --- a/test/packages-svn.js +++ b/test/packages-svn.js @@ -10,7 +10,7 @@ var cmd = require('../lib/util/cmd'); var packages = require('./packages-svn.json'); var nopt = require('nopt'); -var isWin = function() { +var isWin = function () { return process.platform === 'win32'; }; diff --git a/test/renderers/JsonRenderer.js b/test/renderers/JsonRenderer.js index 3bc065bcb..fe9cf19e2 100644 --- a/test/renderers/JsonRenderer.js +++ b/test/renderers/JsonRenderer.js @@ -18,7 +18,7 @@ var normalize = function (string) { describe('JsonRenderer', function () { it('logs simple message to stderr', function () { - return helpers.capture(function() { + return helpers.capture(function () { var renderer = new JsonRenderer(); renderer.log({ id: 'foobar', @@ -26,8 +26,8 @@ describe('JsonRenderer', function () { }); renderer.end(); - }).spread(function(stdout, stderr) { - expect(stderr).to.eq(normalize(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stderr).to.eq(normalize(multiline(function () {/* [{ "id": "foobar", "message": "hello world" @@ -38,7 +38,7 @@ describe('JsonRenderer', function () { }); it('logs error message to stderr', function () { - return helpers.capture(function() { + return helpers.capture(function () { var renderer = new JsonRenderer(); renderer.error({ id: 'foobar', @@ -51,8 +51,8 @@ describe('JsonRenderer', function () { './bar:23' ] }); - }).spread(function(stdout, stderr) { - expect(stderr).to.eq(normalize(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stderr).to.eq(normalize(multiline(function () {/* [{ "id": "error", "data": { @@ -69,14 +69,14 @@ describe('JsonRenderer', function () { it('prompts for answer', function () { var JsonRenderer = jsonRendererWithPrompt({ - prompt: function(name, opts, callback) { + prompt: function (name, opts, callback) { callback(null, 'something2'); } }); var renderer = new JsonRenderer(); - return helpers.capture(function() { + return helpers.capture(function () { return renderer.prompt([ { type: 'input', @@ -84,12 +84,12 @@ describe('JsonRenderer', function () { message: 'Please enter something', default: 'something' } - ]).then(function(response) { + ]).then(function (response) { expect(response.field).to.eq('something2'); renderer.end(); }); - }).spread(function(stdout, stderr) { - expect(stderr).to.eq(normalize(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stderr).to.eq(normalize(multiline(function () {/* [{ "type": "input", "name": "field", diff --git a/test/renderers/StandardRenderer.js b/test/renderers/StandardRenderer.js index f446798a1..7617302e2 100644 --- a/test/renderers/StandardRenderer.js +++ b/test/renderers/StandardRenderer.js @@ -10,14 +10,14 @@ var StandardRenderer = helpers.require('lib/renderers/StandardRenderer'); describe('StandardRenderer', function () { it('logs generic simple message', function () { - return helpers.capture(function() { + return helpers.capture(function () { var renderer = new StandardRenderer(); renderer.log({ id: 'foobar', message: 'hello world' }); - }).spread(function(stdout, stderr) { - expect(stdout).to.eq(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.eq(multiline(function () {/* bower foobar hello world */})); @@ -25,14 +25,14 @@ describe('StandardRenderer', function () { }); it('logs simple error', function () { - return helpers.capture(function() { + return helpers.capture(function () { var renderer = new StandardRenderer(); renderer.error({ code: 'EFOOBAR', message: 'Hello error' }); - }).spread(function(stdout, stderr) { - expect(stderr).to.eq(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stderr).to.eq(multiline(function () {/* bower EFOOBAR Hello error */})); @@ -40,15 +40,15 @@ describe('StandardRenderer', function () { }); it('logs error with details', function () { - return helpers.capture(function() { + return helpers.capture(function () { var renderer = new StandardRenderer(); renderer.error({ code: 'EFOOBAR', message: 'Hello error', details: ' Some awesome details\nMultiline! ' }); - }).spread(function(stdout, stderr) { - expect(stderr).to.eq(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stderr).to.eq(multiline(function () {/* bower EFOOBAR Hello error Additional error details: @@ -60,15 +60,15 @@ describe('StandardRenderer', function () { }); it('logs system details in verbose mode', function () { - return helpers.capture(function() { + return helpers.capture(function () { var renderer = new StandardRenderer(undefined, { verbose: true }); renderer.error({ code: 'EFOOBAR', message: 'Hello error', details: ' Some awesome details\nMultiline! ' }); - }).spread(function(stdout, stderr) { - expect(stderr).to.match(new RegExp(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stderr).to.match(new RegExp(multiline(function () {/* System info: Bower version: [^\r\n]+ Node version: [^\r\n]+ @@ -79,7 +79,7 @@ describe('StandardRenderer', function () { }); it('logs stack trace in verbose mode', function () { - return helpers.capture(function() { + return helpers.capture(function () { var renderer = new StandardRenderer(undefined, { verbose: true }); renderer.error({ code: 'EFOOBAR', @@ -90,8 +90,8 @@ describe('StandardRenderer', function () { './two.js:2' ] }); - }).spread(function(stdout, stderr) { - expect(stderr).to.string(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stderr).to.string(multiline(function () {/* Stack trace: ./one.js:1 ./two.js:2 @@ -101,15 +101,15 @@ describe('StandardRenderer', function () { }); it('logs console trace in verbose mode', function () { - return helpers.capture(function() { + return helpers.capture(function () { var renderer = new StandardRenderer(undefined, { verbose: true }); renderer.error({ code: 'EFOOBAR', message: 'Hello error', details: ' Some awesome details\nMultiline! ' }); - }).spread(function(stdout, stderr) { - expect(stderr).to.match(new RegExp(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stderr).to.match(new RegExp(multiline(function () {/* Console trace: Error \s+at StandardRenderer.error \(.+?\) @@ -118,72 +118,72 @@ describe('StandardRenderer', function () { }); }); - it('outputs checkout command log', function() { - return helpers.capture(function() { + it('outputs checkout command log', function () { + return helpers.capture(function () { var renderer = new StandardRenderer(); renderer.log({ id: 'checkout', origin: 'jquery#master', message: 'foobar' }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* bower checkout jquery#foobar */})); }); }); - it('outputs full progress for wide command', function() { - return helpers.capture(function() { + it('outputs full progress for wide command', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('install'); renderer.log({ id: 'progress', origin: 'jquery#master', message: 'foobar' }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* bower jquery#master progress foobar */})); }); }); - it('outputs full progress for narrow command', function() { - return helpers.capture(function() { + it('outputs full progress for narrow command', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('help'); renderer.log({ id: 'progress', origin: 'jquery#master', message: 'foobar' }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* bower progress jquery#master foobar */})); }); }); - it('outputs extract log just as progress log', function() { - return helpers.capture(function() { + it('outputs extract log just as progress log', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('install'); renderer.log({ id: 'extract', origin: 'jquery#master', message: 'foobar' }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* bower jquery#master extract foobar */})); }); }); - it('outputs incompatible log with suitable package', function() { - return helpers.capture(function() { + it('outputs incompatible log with suitable package', function () { + return helpers.capture(function () { var renderer = new StandardRenderer(); renderer.log({ id: 'incompatible', @@ -243,8 +243,8 @@ describe('StandardRenderer', function () { ] } }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* Please note that, dependant1#release1, dependant2#release2 depends on fizfuz#~0.0.0 which resolved to fizfuz#0.0.0 @@ -257,8 +257,8 @@ describe('StandardRenderer', function () { }); }); - it('outputs solver log without suitable package', function() { - return helpers.capture(function() { + it('outputs solver log without suitable package', function () { + return helpers.capture(function () { var renderer = new StandardRenderer(); renderer.log({ id: 'solved', @@ -310,8 +310,8 @@ describe('StandardRenderer', function () { ] } }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* Unable to find a suitable version for , please choose one by typing one of the numbers below: 1) fizfuz#~0.0.0 which resolved to 0.0.0 and is required by dependant1#release1, dependant2#release2 @@ -324,8 +324,8 @@ describe('StandardRenderer', function () { }); }); - it('outputs json log', function() { - return helpers.capture(function() { + it('outputs json log', function () { + return helpers.capture(function () { var renderer = new StandardRenderer(); renderer.log({ id: 'json', @@ -338,8 +338,8 @@ describe('StandardRenderer', function () { } } }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* { foo: 'bar', @@ -353,24 +353,24 @@ describe('StandardRenderer', function () { }); }); - it('outputs cached entry log', function() { - return helpers.capture(function() { + it('outputs cached entry log', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('install'); renderer.log({ id: 'cached-entry', origin: 'origin', message: 'message' }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* bower origin cached message */})); }); }); - it('adjusts whitespace when package id too long', function() { - return helpers.capture(function() { + it('adjusts whitespace when package id too long', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('install', {}); renderer.log({ id: 'generic', @@ -389,8 +389,8 @@ describe('StandardRenderer', function () { origin: 'short-origin', message: 'message' }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* bower short-origin generic message bower very-very-long-origin-string generic message bower short-origin generic message @@ -399,8 +399,8 @@ describe('StandardRenderer', function () { }); }); - it('outputs install command log', function() { - return helpers.capture(function() { + it('outputs install command log', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('install', { cwd: '/tmp' }); @@ -532,9 +532,9 @@ describe('StandardRenderer', function () { } } ]); - }).spread(function(stdout, stderr) { + }).spread(function (stdout, stderr) { if (helpers.isWin()) { - expect(stdout).to.equal(multiline(function() {/* + expect(stdout).to.equal(multiline(function () {/* jquery#0.1.2 components\jquery @@ -558,7 +558,7 @@ describe('StandardRenderer', function () { */})); } else { - expect(stdout).to.equal(multiline(function() {/* + expect(stdout).to.equal(multiline(function () {/* jquery#0.1.2 components/jquery @@ -585,14 +585,14 @@ describe('StandardRenderer', function () { }); }); - it('outputs short info command log', function() { - return helpers.capture(function() { + it('outputs short info command log', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('info', {}); renderer.end({ version: '1.2.3' }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* { version: '1.2.3' @@ -602,8 +602,8 @@ describe('StandardRenderer', function () { }); }); - it('outputs full info command log', function() { - return helpers.capture(function() { + it('outputs full info command log', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('info', {}); renderer.end({ name: 'foo', @@ -620,8 +620,8 @@ describe('StandardRenderer', function () { '1.3.0-beta.18' ] }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* { version: '1.2.3' @@ -639,8 +639,8 @@ describe('StandardRenderer', function () { }); }); - it('outputs full info command log with prereleases', function() { - return helpers.capture(function() { + it('outputs full info command log with prereleases', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('info', { verbose: true }); renderer.end({ name: 'foo', @@ -657,8 +657,8 @@ describe('StandardRenderer', function () { '1.3.0-beta.18' ] }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* { version: '1.2.3' @@ -679,8 +679,8 @@ describe('StandardRenderer', function () { }); }); - it('outputs lookup command log', function() { - return helpers.capture(function() { + it('outputs lookup command log', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('lookup', {}); renderer.end({ name: 'bower', @@ -689,8 +689,8 @@ describe('StandardRenderer', function () { renderer.end({ name: 'bower' }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* bower http://bower.io Package not found. @@ -698,8 +698,8 @@ describe('StandardRenderer', function () { }); }); - it('outputs link command log', function() { - return helpers.capture(function() { + it('outputs link command log', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('link', { cwd: '/tmp' }); renderer.end({ src: './foo', @@ -714,16 +714,16 @@ describe('StandardRenderer', function () { } }] }); - }).spread(function(stdout, stderr) { + }).spread(function (stdout, stderr) { if (helpers.isWin()) { - expect(stdout).to.equal(multiline(function() {/* + expect(stdout).to.equal(multiline(function () {/* bower link ./bar > ./foo jquery#0.1.2 components\jquery */})); } else { - expect(stdout).to.equal(multiline(function() {/* + expect(stdout).to.equal(multiline(function () {/* bower link ./bar > ./foo jquery#0.1.2 components/jquery @@ -733,8 +733,8 @@ describe('StandardRenderer', function () { }); }); - it('outputs search command log', function() { - return helpers.capture(function() { + it('outputs search command log', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('search'); renderer.end([ { @@ -746,8 +746,8 @@ describe('StandardRenderer', function () { url: 'http://bower.io' } ]); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* Search results: jquery http://jquery.io @@ -757,15 +757,15 @@ describe('StandardRenderer', function () { }); }); - it('outputs register command log', function() { - return helpers.capture(function() { + it('outputs register command log', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('register'); renderer.end({ name: 'jquery', url: 'http://jquery.io' }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* Package jquery registered successfully! All valid semver tags on http://jquery.io will be available as versions. @@ -777,8 +777,8 @@ describe('StandardRenderer', function () { }); }); - it('outputs cache list command log', function() { - return helpers.capture(function() { + it('outputs cache list command log', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('cache list'); renderer.end([ { @@ -789,16 +789,16 @@ describe('StandardRenderer', function () { } } ]); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* awesome-jquery=jquery#0.1.1 */})); }); }); - it('outputs help command log', function() { - return helpers.capture(function() { + it('outputs help command log', function () { + return helpers.capture(function () { var renderer = new StandardRenderer('help'); renderer.end({ 'command': 'uninstall', @@ -824,8 +824,8 @@ describe('StandardRenderer', function () { } ] }); - }).spread(function(stdout, stderr) { - expect(stdout).to.equal(multiline(function() {/* + }).spread(function (stdout, stderr) { + expect(stdout).to.equal(multiline(function () {/* Usage: diff --git a/test/util/createLink.js b/test/util/createLink.js index 2133a14fa..d56926d6c 100644 --- a/test/util/createLink.js +++ b/test/util/createLink.js @@ -16,26 +16,26 @@ describe('createLink', function () { var dstDir = new helpers.TempDir(); - beforeEach(function() { + beforeEach(function () { srcDir.prepare(); dstDir.prepare(); }); - it('creates a symlink to a file', function() { + it('creates a symlink to a file', function () { var src = path.join(srcDir.path, 'someFile'), dst = path.join(dstDir.path, 'someFile'); return createLink(src, dst) - .then(function() { + .then(function () { return Q.nfcall(fs.readlink, dst) - .then(function(linkString) { + .then(function (linkString) { expect(linkString).to.be.equal(src); }); }); }); - it('throws an error when destination already exists', function() { + it('throws an error when destination already exists', function () { var src = path.join(srcDir.path, 'someFile'), dst = path.join(dstDir.path); @@ -43,11 +43,11 @@ describe('createLink', function () { var deferred = Q.defer(); createLink(src, dst) - .catch(function(err) { + .catch(function (err) { expect(err.code).to.be.equal('EEXIST'); deferred.resolve(); }) - .then(function() { + .then(function () { deferred.reject(); }); diff --git a/test/util/download.js b/test/util/download.js index a8176627a..aa662bcae 100644 --- a/test/util/download.js +++ b/test/util/download.js @@ -182,14 +182,14 @@ describe('download', function () { var destinationPath = tempDir.getPath(sourceFilename); return downloadTest({ - response: function(nock) { + response: function (nock) { nock .get('/' + sourceFilename) .replyWithFile(200, sourceFile, { 'Content-Encoding' : 'gzip' }); }, - expect: function() { + expect: function () { expect(fs.readFileSync(destinationPath, 'ascii')) .to.be('Hello World!\n'); }, diff --git a/test/util/isPathAbsolute.js b/test/util/isPathAbsolute.js index 68c578cb0..0866744b5 100644 --- a/test/util/isPathAbsolute.js +++ b/test/util/isPathAbsolute.js @@ -3,11 +3,11 @@ var isPathAbsolute = require('../../lib/util/isPathAbsolute'); describe('isPathAbsolute', function () { - it('returns true when a path begins with /', function() { + it('returns true when a path begins with /', function () { expect(isPathAbsolute('/tmp/foo')).to.be.ok(); }); - it('returns false when a path does not begin with /', function() { + it('returns false when a path does not begin with /', function () { expect(isPathAbsolute('./tmp/foo')).to.not.be.ok(); }); diff --git a/test/util/relativeToBaseDir.js b/test/util/relativeToBaseDir.js index 98cfdbc0a..c956c2c4c 100644 --- a/test/util/relativeToBaseDir.js +++ b/test/util/relativeToBaseDir.js @@ -6,12 +6,12 @@ describe('relativeToBaseDir', function () { var joinOrReturnAbsolutePath = relativeToBaseDir('/tmp'); - it('returns a partial function that joins paths of the partials first arguments', function() { + it('returns a partial function that joins paths of the partials first arguments', function () { expect(joinOrReturnAbsolutePath('foo')).to.be.equal(path.resolve('/tmp/foo')); expect(joinOrReturnAbsolutePath('./foo')).to.be.equal(path.resolve('/tmp/foo')); }); - it('returns a partial function that returns it\'s first argument when it begins with /', function() { + it('returns a partial function that returns it\'s first argument when it begins with /', function () { expect(joinOrReturnAbsolutePath('/foo')).to.be.equal(path.resolve('/foo')); expect(joinOrReturnAbsolutePath('/foo/bar')).to.be.equal(path.resolve('/foo/bar')); }); diff --git a/test/util/removeIgnores.js b/test/util/removeIgnores.js index 3d79aeb7a..6b0ffc933 100644 --- a/test/util/removeIgnores.js +++ b/test/util/removeIgnores.js @@ -13,13 +13,13 @@ describe('removeIgnores', function () { 'node_modules/underscore/index.js': 'Should be ignored' }); - var ignoreTest = function(dir, meta, leftovers) { + var ignoreTest = function (dir, meta, leftovers) { tempDir.prepare(); var deferred = Q.defer(); - removeIgnores(dir, meta).then(function() { - glob('**/*.*', { cwd: dir }, function(cb, files) { + removeIgnores(dir, meta).then(function () { + glob('**/*.*', { cwd: dir }, function (cb, files) { expect(files).to.eql(leftovers); deferred.resolve(); }); @@ -49,21 +49,21 @@ describe('removeIgnores', function () { ); }); - it('removes all but one file', function() { + it('removes all but one file', function () { return ignoreTest(tempDir.path, { ignore: [ '**/*', '!bower.json' ] }, [ 'bower.json' ] ); }); - it('refuses to ignore bower.json', function() { + it('refuses to ignore bower.json', function () { return ignoreTest(tempDir.path, { ignore: [ '**/*', '!index.js' ] }, [ 'bower.json', 'index.js' ] ); }); - it('removes all but one file deep down the tree', function() { + it('removes all but one file deep down the tree', function () { return ignoreTest(tempDir.path, { ignore: [ '**/*', '!node_modules/underscore/index.js' ] }, [ From 7c2dfc1146f4c4906d432b0e0740ef9f2f3436fa Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 31 Mar 2016 00:55:47 +0200 Subject: [PATCH 0886/1021] Fix peerDependency of grunt-exec --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4ea1c5402..e59e99696 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "grunt-cli": "^1.1.0", "grunt-contrib-watch": "^1.0.0", "grunt-eslint": "^18.0.0", - "grunt-exec": "^0.4.6", + "grunt-exec": "sheerun/grunt-exec", "grunt-simple-mocha": "^0.4.1", "in-publish": "^2.0.0", "istanbul": "^0.3.5", From 16cde3118afaa4d9c93f9d206d094a19659e267e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 31 Mar 2016 01:36:05 +0200 Subject: [PATCH 0887/1021] Revert "Merge pull request #2197 from albertinadx/albertinad/fix-scripts-hooks" This reverts commit 0a81308e982017d6fa6987c4277c6fc559ceb289, reversing changes made to f2884656c053da062071103ca873f3b6a46ea942. --- lib/core/scripts.js | 5 +++-- package.json | 1 + test/core/scripts.js | 35 ----------------------------------- 3 files changed, 4 insertions(+), 37 deletions(-) diff --git a/lib/core/scripts.js b/lib/core/scripts.js index caf25d787..15b9b6473 100644 --- a/lib/core/scripts.js +++ b/lib/core/scripts.js @@ -1,6 +1,7 @@ var mout = require('mout'); var cmd = require('../util/cmd'); var Q = require('q'); +var shellquote = require('shell-quote'); var orderByDependencies = function (packages, installed, json) { var ordered = []; @@ -53,8 +54,8 @@ var run = function (cmdString, action, logger, config) { //pass env + BOWER_PID so callees can identify a preinstall+postinstall from the same bower instance var env = mout.object.mixIn({ 'BOWER_PID': process.pid }, process.env); - var cmdName = 'sh'; - var args = ['-c', cmdString]; + var args = shellquote.parse(cmdString, env); + var cmdName = args[0]; mout.array.remove(args, cmdName); //no rest() in mout var options = { diff --git a/package.json b/package.json index e59e99696..b8251d797 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "rimraf": "^2.2.8", "semver": "^2.3.0", "semver-utils": "^1.1.1", + "shell-quote": "^1.4.2", "stringify-object": "^1.0.0", "tar-fs": "^1.4.1", "tmp": "0.0.28", diff --git a/test/core/scripts.js b/test/core/scripts.js index cdb2020fb..2f191ccfa 100644 --- a/test/core/scripts.js +++ b/test/core/scripts.js @@ -135,39 +135,4 @@ describe('scripts', function () { }); - it('should process preuninstall hooks with shell operators properly.', function (next) { - - config.scripts.preuninstall = touch('preuninstall_test_ping_%') + ' && ' + touch('preuninstall_test_pong'); - - bower.commands - .uninstall([packageName], undefined, config) - .on('end', function (installed) { - - expect(fs.existsSync(path.join(tempDir, 'preuninstall_test_ping_' + packageName))).to.be(true); - expect(fs.existsSync(path.join(tempDir, 'preuninstall_test_pong'))).to.be(true); - - next(); - }); - - }); - - it('should process preinstall and postinstall hooks with shell operators properly.', function (next) { - - config.scripts.preinstall = touch('preinstall_test_ping_%') + ' && ' + touch('preinstall_test_pong'); - config.scripts.postinstall = touch('postinstall_test_ping') + ' && ' + touch('postinstall_test_pong_%'); - - bower.commands - .install([packageDir], undefined, config) - .on('end', function (installed) { - - expect(fs.existsSync(path.join(tempDir, 'preinstall_test_ping_' + packageName))).to.be(true); - expect(fs.existsSync(path.join(tempDir, 'preinstall_test_pong'))).to.be(true); - expect(fs.existsSync(path.join(tempDir, 'postinstall_test_ping'))).to.be(true); - expect(fs.existsSync(path.join(tempDir, 'postinstall_test_pong_' + packageName))).to.be(true); - - next(); - }); - - }); - }); From 46655b7c4ed6fc0fa7fc3f671dafa987fefab249 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 31 Mar 2016 19:27:12 +0200 Subject: [PATCH 0888/1021] Final .eslintrc configuration --- .eslintrc | 27 +++++++--- Gruntfile.js | 8 +-- lib/bin/bower.js | 4 +- lib/config.js | 2 +- lib/core/Project.js | 2 +- lib/core/resolvers/pluginResolverFactory.js | 2 +- lib/util/relativeToBaseDir.js | 2 +- test/commands/install.js | 6 +-- test/commands/login.js | 4 +- test/core/resolvers/pluginResolverFactory.js | 54 ++++++++++---------- 10 files changed, 62 insertions(+), 49 deletions(-) diff --git a/.eslintrc b/.eslintrc index c75767200..14e58a0d8 100644 --- a/.eslintrc +++ b/.eslintrc @@ -16,11 +16,19 @@ "no-unused-vars": 0, "strict": 0, "semi": 0, - "no-cond-assign": [ - 2, - "except-parens" - ], - "no-debugger": 0, + "comma-spacing": 2, + "quote-props": [2, "consistent", { "keywords": true }], + "quotes": [2, "single", "avoid-escape"], + "indent": [2, 4], + "no-cond-assign": [ 2, "except-parens" ], + "no-debugger": 2, + "no-dupe-args": 2, + "no-dupe-keys": 2, + "no-duplicate-case": 2, + "no-unreachable": 2, + "valid-typeof": 2, + "no-fallthrough": 2, + "no-ex-assign": 2, "no-eq-null": 0, "no-eval": 0, "no-unused-expressions": 0, @@ -32,8 +40,13 @@ "no-new-func": 2, "no-new-wrappers": 2, "no-invalid-this": 0, - "space-before-blocks": 2, + "space-before-blocks": [2, "always"], "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}], - "space-infix-ops": 2 + "space-infix-ops": 2, + "keyword-spacing": 2, + "new-parens": 2, + "no-multiple-empty-lines": [2, { max: 2}], + "eol-last": 2, + "no-trailing-spaces": 2 } } diff --git a/Gruntfile.js b/Gruntfile.js index e1fc22abe..34b205d25 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -43,18 +43,18 @@ module.exports = function (grunt) { } }, exec: { - assets: { + 'assets': { command: 'node test/packages.js && node test/packages-svn.js' }, 'assets-force': { command: 'node test/packages.js --force && node test/packages-svn.js --force' }, - cover: { + 'cover': { command: 'node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' }, - coveralls: { + 'coveralls': { command: 'npm run coveralls < test/reports/lcov.info', - exitCodes: [0,1,2,3] // Alow for failure for coverage report + exitCodes: [0, 1, 2, 3] // Alow for failure for coverage report } }, watch: { diff --git a/lib/bin/bower.js b/lib/bin/bower.js index e5f399760..8e04817fc 100644 --- a/lib/bin/bower.js +++ b/lib/bin/bower.js @@ -18,8 +18,8 @@ var logger; var levels = Logger.LEVELS; options = cli.readOptions({ - version: { type: Boolean, shorthand: 'v' }, - help: { type: Boolean, shorthand: 'h' }, + 'version': { type: Boolean, shorthand: 'v' }, + 'help': { type: Boolean, shorthand: 'h' }, 'allow-root': { type: Boolean } }); diff --git a/lib/config.js b/lib/config.js index 854392bf2..03115bdc2 100644 --- a/lib/config.js +++ b/lib/config.js @@ -25,7 +25,7 @@ function readCachedConfig(cwd, overwrites) { delete config.json; // If interactive is auto (null), guess its value - if(config.interactive == null) { + if (config.interactive == null) { config.interactive = ( process.bin === 'bower' && tty.isatty(1) && diff --git a/lib/core/Project.js b/lib/core/Project.js index b9c5294ff..83e6705bf 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -45,7 +45,7 @@ Project.prototype.install = function (decEndpoints, options, config) { .spread(function (json, tree) { // It shows an error when issuing `bower install` // and no bower.json is present in current directory - if(!that._jsonFile && decEndpoints.length === 0 ) { + if (!that._jsonFile && decEndpoints.length === 0 ) { throw createError('No bower.json present', 'ENOENT'); } diff --git a/lib/core/resolvers/pluginResolverFactory.js b/lib/core/resolvers/pluginResolverFactory.js index 0cef6f280..b86c4d885 100644 --- a/lib/core/resolvers/pluginResolverFactory.js +++ b/lib/core/resolvers/pluginResolverFactory.js @@ -99,7 +99,7 @@ function pluginResolverFactory(resolverFactory, bower) { var target = that.getTarget(); // It means that we can accept ranges as targets - if(that.constructor.isTargetable()) { + if (that.constructor.isTargetable()) { that._release = target; if (semver.validRange(target)) { diff --git a/lib/util/relativeToBaseDir.js b/lib/util/relativeToBaseDir.js index a02a5b344..450c2e32d 100644 --- a/lib/util/relativeToBaseDir.js +++ b/lib/util/relativeToBaseDir.js @@ -3,7 +3,7 @@ var isPathAbsolute = require('./isPathAbsolute'); function relativeToBaseDir(baseDir) { return function (filePath) { - if(isPathAbsolute(filePath)) { + if (isPathAbsolute(filePath)) { return path.resolve(filePath); } else { return path.resolve(baseDir, filePath); diff --git a/test/commands/install.js b/test/commands/install.js index 33213948f..1888c2b98 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -243,7 +243,7 @@ describe('bower install', function () { expect(require('fs').readFileSync('/tmp/bower-absolute-destination-directory/package/foo', 'utf8').toString()).to.be('bar'); var deferred = Q.defer(); rimraf('/tmp/bower-absolute-destination-directory', function (err) { - if(err) { + if (err) { deferred.reject(err); } else { deferred.resolve(); @@ -528,8 +528,8 @@ describe('bower install', function () { .reply(500); return helpers.run(install, [ - undefined, - undefined, + undefined, + undefined, { proxy: 'http://dummy.local/' } ]) .fail(function (error) { diff --git a/test/commands/login.js b/test/commands/login.js index aa8242ec7..bff23734f 100644 --- a/test/commands/login.js +++ b/test/commands/login.js @@ -148,7 +148,7 @@ describe('bower login', function () { it('saves username in config', function (done) { var login = loginFactory({ set: function (key, value) { - if(key === 'username') { + if (key === 'username') { expect(value).to.be('user'); done(); } @@ -168,7 +168,7 @@ describe('bower login', function () { it('saves received token in accessToken config', function (done) { var login = loginFactory({ set: function (key, value) { - if(key === 'accessToken') { + if (key === 'accessToken') { expect(value).to.be('faketoken'); done(); } diff --git a/test/core/resolvers/pluginResolverFactory.js b/test/core/resolvers/pluginResolverFactory.js index 0acab2b19..22609bcef 100644 --- a/test/core/resolvers/pluginResolverFactory.js +++ b/test/core/resolvers/pluginResolverFactory.js @@ -305,45 +305,45 @@ describe('pluginResolverFactory', function () { it('should throw \'Resolver did not provide path to extracted contents of package\'', function (next) { - var mockPluginResolverWithoutTempPath = function resolver(bower) { - return { + var mockPluginResolverWithoutTempPath = function resolver(bower) { + return { - match: function (source) { - return true; - }, + match: function (source) { + return true; + }, - releases: function (source) { - return [ + releases: function (source) { + return [ { target: 'v1.0.0', version: '1.0.0' }, { target: 'v1.0.1', version: '1.0.1' } - ]; - }, - - fetch: function (endpoint, cached) { - if (cached && cached.version) { - return; - } - - return { - tempPath: null, - removeIgnores: true - }; - } - }; - }; - var PluginResolver = pluginResolverFactory( + ]; + }, + + fetch: function (endpoint, cached) { + if (cached && cached.version) { + return; + } + + return { + tempPath: null, + removeIgnores: true + }; + } + }; + }; + var PluginResolver = pluginResolverFactory( mockPluginResolverWithoutTempPath, defaultConfig() ); - var path = 'file://' + testPackage; - var resolver = new PluginResolver(path); - resolver.resolve() + var path = 'file://' + testPackage; + var resolver = new PluginResolver(path); + resolver.resolve() .catch(function (e) { expect(e.message).to .equal('Resolver did not provide path to extracted contents of package.'); next(); }); - }); + }); }); From 52aa684949ba483192e3c649182df2bb62cbc0a9 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 31 Mar 2016 19:29:55 +0200 Subject: [PATCH 0889/1021] [refactor] Move abbreviations to utils --- lib/index.js | 2 +- lib/{ => util}/abbreviations.js | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/{ => util}/abbreviations.js (100%) diff --git a/lib/index.js b/lib/index.js index a7ffe9df2..9a15c49dc 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,6 +1,6 @@ var commands = require('./commands'); var version = require('./version'); -var abbreviations = require('./abbreviations')(commands); +var abbreviations = require('./util/abbreviations')(commands); function clearRuntimeCache() { // Note that in edge cases, some architecture components instance's diff --git a/lib/abbreviations.js b/lib/util/abbreviations.js similarity index 100% rename from lib/abbreviations.js rename to lib/util/abbreviations.js From 44e71267c196793ccbb774870f366467c7fc4aaa Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 31 Mar 2016 22:10:06 +0200 Subject: [PATCH 0890/1021] [refactor] Put bower-registry-client instantiation in one place --- lib/commands/lookup.js | 10 +++------- lib/commands/search.js | 10 +++------- lib/core/PackageRepository.js | 4 +++- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/lib/commands/lookup.js b/lib/commands/lookup.js index 94a9d3771..5d095642c 100644 --- a/lib/commands/lookup.js +++ b/lib/commands/lookup.js @@ -1,5 +1,5 @@ var Q = require('q'); -var RegistryClient = require('bower-registry-client'); +var PackageRepository = require('../core/PackageRepository'); var defaultConfig = require('../config'); function lookup(logger, name, config) { @@ -7,17 +7,13 @@ function lookup(logger, name, config) { return new Q(null); } - var registryClient; - config = defaultConfig(config); - config.cache = config.storage.registry; - registryClient = new RegistryClient(config, logger); + var repository = new PackageRepository(config, logger); + var registryClient = repository.getRegistryClient(); return Q.nfcall(registryClient.lookup.bind(registryClient), name) .then(function (entry) { - // TODO: Handle entry.type.. for now it's only 'alias' - // When we got published packages, this needs to be adjusted return !entry ? null : { name: name, url: entry && entry.url diff --git a/lib/commands/search.js b/lib/commands/search.js index bb2e9c550..2d475513c 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -1,17 +1,13 @@ var Q = require('q'); -var RegistryClient = require('bower-registry-client'); +var PackageRepository = require('../core/PackageRepository'); var defaultConfig = require('../config'); var cli = require('../util/cli'); function search(logger, name, config) { - var registryClient; - - var json = config ? config.json : undefined; config = defaultConfig(config); - config.json = config.json || json; // Hack until bower-config is fixed... - config.cache = config.storage.registry; - registryClient = new RegistryClient(config, logger); + var repository = new PackageRepository(config, logger); + var registryClient = repository.getRegistryClient(); if (name) { return Q.nfcall(registryClient.search.bind(registryClient), name); diff --git a/lib/core/PackageRepository.js b/lib/core/PackageRepository.js index df971a72f..574e8e561 100644 --- a/lib/core/PackageRepository.js +++ b/lib/core/PackageRepository.js @@ -1,11 +1,12 @@ var mout = require('mout'); var Q = require('q'); -var RegistryClient = require('bower-registry-client'); var ResolveCache = require('./ResolveCache'); var resolverFactory = require('./resolverFactory'); var createError = require('../util/createError'); +var RegistryClient = require('bower-registry-client'); function PackageRepository(config, logger) { + var registryOptions; this._config = config; @@ -14,6 +15,7 @@ function PackageRepository(config, logger) { // Instantiate the registry registryOptions = mout.object.deepMixIn({}, this._config); registryOptions.cache = this._config.storage.registry; + this._registryClient = new RegistryClient(registryOptions, logger); // Instantiate the resolve cache From f494ae7dddcbc01c7279e44545e59413044cb325 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 1 Apr 2016 01:39:09 +0200 Subject: [PATCH 0891/1021] [refactor] Fix tests for previous commit --- lib/bin/bower.js | 2 +- lib/commands/search.js | 5 ++++- lib/config.js | 4 ---- lib/util/cli.js | 16 ---------------- test/commands/lookup.js | 20 ++++++++++++-------- test/commands/search.js | 42 ++++++++++++++++++++++++++++------------- 6 files changed, 46 insertions(+), 43 deletions(-) diff --git a/lib/bin/bower.js b/lib/bin/bower.js index 8e04817fc..66d266803 100644 --- a/lib/bin/bower.js +++ b/lib/bin/bower.js @@ -101,7 +101,7 @@ function handleLogger(logger, renderer) { } }) .on('error', function (err) { - if (command !== 'help' && err.code === cli.READ_OPTIONS_ERROR_CODE) { + if (command !== 'help' && err.code === 'EREADOPTIONS') { logger = bower.commands.help(command); renderer = cli.getRenderer('help', logger.json, bower.config); handleLogger(logger, renderer); diff --git a/lib/commands/search.js b/lib/commands/search.js index 2d475513c..d9461ff61 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -2,8 +2,11 @@ var Q = require('q'); var PackageRepository = require('../core/PackageRepository'); var defaultConfig = require('../config'); var cli = require('../util/cli'); +var createError = require('../util/createError'); function search(logger, name, config) { + var registryClient; + config = defaultConfig(config); var repository = new PackageRepository(config, logger); @@ -15,7 +18,7 @@ function search(logger, name, config) { // List all packages when in interactive mode + json enabled, and // always when in non-interactive mode if (config.interactive && !config.json) { - throw cli.createReadOptionsError('search'); + throw createError('no parameter to bower search', 'EREADOPTIONS'); } return Q.nfcall(registryClient.list.bind(registryClient)); diff --git a/lib/config.js b/lib/config.js index 03115bdc2..f0dda45fb 100644 --- a/lib/config.js +++ b/lib/config.js @@ -20,10 +20,6 @@ function readCachedConfig(cwd, overwrites) { object.mixIn(config, configstore); - // Delete the json attribute because it is no longer supported - // and conflicts with --json - delete config.json; - // If interactive is auto (null), guess its value if (config.interactive == null) { config.interactive = ( diff --git a/lib/util/cli.js b/lib/util/cli.js index e9a68ca4a..a537c75c7 100644 --- a/lib/util/cli.js +++ b/lib/util/cli.js @@ -1,9 +1,6 @@ var mout = require('mout'); var nopt = require('nopt'); var renderers = require('../renderers'); -var createError = require('./createError'); - -var READ_OPTIONS_ERROR_CODE = 'EREADOPTIONS'; function readOptions(options, argv) { var types; @@ -40,16 +37,6 @@ function readOptions(options, argv) { return parsedOptions; } -/** - * Creates an error for the case where a command has trouble parsing command - * line options. - **/ -function createReadOptionsError(commandName) { - var errorString = commandName + ' syntax error'; - - return createError(errorString, READ_OPTIONS_ERROR_CODE); -} - function getRenderer(command, json, config) { if (config.json || json) { return new renderers.Json(command, config); @@ -60,6 +47,3 @@ function getRenderer(command, json, config) { module.exports.readOptions = readOptions; module.exports.getRenderer = getRenderer; - -module.exports.createReadOptionsError = createReadOptionsError; -module.exports.READ_OPTIONS_ERROR_CODE = READ_OPTIONS_ERROR_CODE; diff --git a/test/commands/lookup.js b/test/commands/lookup.js index 5057ce149..684582a2e 100644 --- a/test/commands/lookup.js +++ b/test/commands/lookup.js @@ -7,16 +7,20 @@ describe('bower lookup', function () { var lookupWithResult = function (response) { return helpers.command('lookup', { - 'bower-registry-client': function () { + '../core/PackageRepository': function () { return { - lookup: function (query, callback) { - if (query in response) { - callback(null, response[query]); - } else { - callback(); - } + getRegistryClient: function () { + return { + lookup: function (query, callback) { + if (query in response) { + callback(null, response[query]); + } else { + callback(); + } + } + }; } - }; + } } }); }; diff --git a/test/commands/search.js b/test/commands/search.js index 57d746daf..8f6a01c92 100644 --- a/test/commands/search.js +++ b/test/commands/search.js @@ -14,10 +14,14 @@ describe('bower search', function () { it('searches for single repository', function () { return Q.Promise(function (resolve) { var search = helpers.command('search', { - 'bower-registry-client': function () { + '../core/PackageRepository': function () { return { - search: resolve - }; + getRegistryClient: function () { + return { + search: resolve + }; + } + } } }); @@ -32,10 +36,14 @@ describe('bower search', function () { return Q.Promise(function (resolve) { var search = helpers.command('search', { - 'bower-registry-client': function () { + '../core/PackageRepository': function () { return { - list: resolve - }; + getRegistryClient: function () { + return { + list: resolve + }; + } + } } }); @@ -47,10 +55,14 @@ describe('bower search', function () { var interactiveConfig = { interactive: true, json: true }; var search = helpers.command('search', { - 'bower-registry-client': function () { + '../core/PackageRepository': function () { return { - list: function (cb) { return cb(null, 'foobar'); } - }; + getRegistryClient: function () { + return { + list: function (cb) { return cb(null, 'foobar'); } + }; + } + } } }); @@ -64,11 +76,15 @@ describe('bower search', function () { var interactiveConfig = { interactive: true }; var search = helpers.command('search', { - 'bower-registry-client': function () { + '../core/PackageRepository': function () { return { - list: function () { throw 'list called'; }, - search: function () { throw 'search called'; } - }; + getRegistryClient: function () { + return { + list: function () { throw 'list called'; }, + search: function () { throw 'search called'; } + }; + } + } } }); From f4cb047e9df55f03e9971ce4f4341c41d99339e3 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 1 Apr 2016 03:22:42 +0200 Subject: [PATCH 0892/1021] Allow to install custom resolver globally, fixes #1919 --- lib/core/resolverFactory.js | 3 ++- package.json | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index c339f3388..daac51764 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -4,6 +4,7 @@ var path = require('path'); var mout = require('mout'); var resolvers = require('./resolvers'); var createError = require('../util/createError'); +var requireg = require('requireg'); var pluginResolverFactory = require('./resolvers/pluginResolverFactory'); @@ -56,7 +57,7 @@ function getConstructor(decEndpoint, options, registryClient) { var resolverPromises = resolverNames.map(function (resolverName) { var resolver = resolvers[resolverName] - || pluginResolverFactory(require(resolverName), options); + || pluginResolverFactory(requireg(resolverName), options); return function () { if (selectedResolver === undefined) { diff --git a/package.json b/package.json index b8251d797..ae6e8df82 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "q": "^1.1.2", "request": "2.67.0", "request-progress": "0.3.1", + "requireg": "^0.1.5", "retry": "0.6.1", "rimraf": "^2.2.8", "semver": "^2.3.0", From b1c45bb58628702cbd8be20fe804af6521fbf08b Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 1 Apr 2016 14:57:36 +0200 Subject: [PATCH 0893/1021] Resolve pluggable resolvers using cwd and fallback to global module --- lib/core/resolverFactory.js | 17 ++++++++++++++--- lib/util/resolve.js | 22 ++++++++++++++++++++++ package.json | 1 + 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 lib/util/resolve.js diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index daac51764..9de177705 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -4,7 +4,7 @@ var path = require('path'); var mout = require('mout'); var resolvers = require('./resolvers'); var createError = require('../util/createError'); -var requireg = require('requireg'); +var resolve = require('../util/resolve'); var pluginResolverFactory = require('./resolvers/pluginResolverFactory'); @@ -56,8 +56,19 @@ function getConstructor(decEndpoint, options, registryClient) { } var resolverPromises = resolverNames.map(function (resolverName) { - var resolver = resolvers[resolverName] - || pluginResolverFactory(requireg(resolverName), options); + + + var resolver = resolvers[resolverName]; + + if (resolver === undefined) { + var resolverPath = resolve(resolverName, { cwd: config.cwd }); + + if (resolverPath === undefined) { + throw createError('Bower resolver not found: ' + resolverName, 'ENORESOLVER') + } + + resolver = pluginResolverFactory(require(resolverPath), options); + } return function () { if (selectedResolver === undefined) { diff --git a/lib/util/resolve.js b/lib/util/resolve.js new file mode 100644 index 000000000..5924d85d7 --- /dev/null +++ b/lib/util/resolve.js @@ -0,0 +1,22 @@ +var requireg = require('requireg'); +var resolve = require('resolve'); + +function startsWith(string, searchString, position) { + position = position || 0; + return string.substr(position, searchString.length) === searchString; +}; + +module.exports = function (id, options) { + var resolvedPath; + + var cwd = (options || {}).cwd || process.cwd(); + + try { + resolvedPath = resolve.sync(id, { basedir: cwd }); + } catch (e) { + // Fallback to global require + resolvedPath = requireg.resolve(id); + } + + return resolvedPath; +} diff --git a/package.json b/package.json index ae6e8df82..030052e0e 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "request": "2.67.0", "request-progress": "0.3.1", "requireg": "^0.1.5", + "resolve": "^1.1.7", "retry": "0.6.1", "rimraf": "^2.2.8", "semver": "^2.3.0", From 7de2e5d601fb4d65a098dba105f0aa419753fcf2 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 1 Apr 2016 16:19:51 +0200 Subject: [PATCH 0894/1021] Remove moduleType from from "bower init" result, fixes #1229 --- lib/commands/init.js | 7 ------- test/commands/init.js | 3 --- 2 files changed, 10 deletions(-) diff --git a/lib/commands/init.js b/lib/commands/init.js index 34a5e33bc..71db0c7fe 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -186,12 +186,6 @@ function promptUser(logger, json) { 'default': json.main, 'type': 'input' }, - { - 'name': 'moduleType', - 'message': 'what types of modules does this package expose?', - 'type': 'checkbox', - 'choices': ['amd', 'es6', 'globals', 'node', 'yui'] - }, { 'name': 'keywords', 'message': 'keywords', @@ -241,7 +235,6 @@ function promptUser(logger, json) { json.name = answers.name; json.description = answers.description; json.main = answers.main; - json.moduleType = answers.moduleType; json.keywords = toArray(answers.keywords); json.authors = toArray(answers.authors, ','); json.license = answers.license; diff --git a/test/commands/init.js b/test/commands/init.js index 5b74f4215..ae125817e 100644 --- a/test/commands/init.js +++ b/test/commands/init.js @@ -25,7 +25,6 @@ describe('bower init', function () { answer({ name: 'test-name', description: 'test-description', - moduleType: 'test-moduleType', keywords: 'test-keyword', authors: 'test-author', license: 'test-license', @@ -45,7 +44,6 @@ describe('bower init', function () { homepage: 'test-homepage', authors: [ 'test-author' ], description: 'test-description', - moduleType: 'test-moduleType', keywords: [ 'test-keyword' ], license: 'test-license', private: true @@ -116,7 +114,6 @@ describe('bower init', function () { name: defaults.name, description: defaults.description, main: defaults.main, - moduleType: defaults.moduleType, keywords: defaults.keywords, authors: defaults.authors, license: defaults.license, From 3a0ea968f4fe8e6511e52e8ef077892c628ce81b Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 1 Apr 2016 17:23:57 +0200 Subject: [PATCH 0895/1021] Update graceful-fs dependency --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 102999259..bcd147511 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -11,7 +11,7 @@ "node": ">=0.8.0" }, "dependencies": { - "graceful-fs": "^4.0.0", + "graceful-fs": "^4.1.3", "mout": ">=0.9.0 <1.0.0", "optimist": "^0.6.1", "osenv": "^0.1.3", From 1e398f999bcc0b2efc17cae0f68211ababded1d4 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 1 Apr 2016 17:27:18 +0200 Subject: [PATCH 0896/1021] Update dependencies --- packages/bower-config/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index bcd147511..838827b3d 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "1.3.0", + "version": "1.3.1", "description": "The Bower config reader and writer.", "author": "Twitter", "license": "MIT", @@ -12,10 +12,10 @@ }, "dependencies": { "graceful-fs": "^4.1.3", - "mout": ">=0.9.0 <1.0.0", + "mout": "^1.0.0", "optimist": "^0.6.1", "osenv": "^0.1.3", - "untildify": "2.1.0" + "untildify": "^2.1.0" }, "devDependencies": { "coveralls": "^2.11.4", From 3853d1297e5f2eb707ceca0be429d0b5cd80053a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 1 Apr 2016 17:28:23 +0200 Subject: [PATCH 0897/1021] Add changelog entry --- packages/bower-config/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/bower-config/CHANGELOG.md b/packages/bower-config/CHANGELOG.md index 9da87a95a..926197a79 100644 --- a/packages/bower-config/CHANGELOG.md +++ b/packages/bower-config/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.3.1 + +- Ignore hook scripts for environment variable expansion + ## 1.3.0 - 2015-12-07 - Allow the use of environment variables in .bowerrc. Fixes [#41](https://github.com/bower/config/issues/41) From e7516e4bcb8214cb513c643277c3d5cbcfb76661 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 1 Apr 2016 17:32:50 +0200 Subject: [PATCH 0898/1021] Bump bower-config to 1.3.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 030052e0e..f6ee7ac04 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "dependencies": { "abbrev": "^1.0.5", "archy": "1.0.0", - "bower-config": "^1.3.0", + "bower-config": "^1.3.1", "bower-endpoint-parser": "^0.2.2", "bower-json": "^0.7.0", "bower-logger": "^0.2.2", From 8f2668a24daed268bb42f1ba4f6a8ff83e3eb9b3 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 1 Apr 2016 17:36:06 +0200 Subject: [PATCH 0899/1021] Bump config-store to 2.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f6ee7ac04..dda4f80f9 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "cardinal": "0.4.4", "chalk": "^1.0.0", "chmodr": "^1.0.2", - "configstore": "^0.3.2", + "configstore": "^2.0.0", "decompress-zip": "^0.1.0", "destroy": "^1.0.3", "findup-sync": "^0.3.0", From 5116fec1abde1b70647a6c58a3e0d7aa2dedfa6a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 1 Apr 2016 17:51:06 +0200 Subject: [PATCH 0900/1021] Update decompress-zip to 0.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dda4f80f9..1a1d44770 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "chalk": "^1.0.0", "chmodr": "^1.0.2", "configstore": "^2.0.0", - "decompress-zip": "^0.1.0", + "decompress-zip": "^0.2.1", "destroy": "^1.0.3", "findup-sync": "^0.3.0", "fs-write-stream-atomic": "1.0.8", From 1cf87041cc3f538fada9cd8c9e0d025d80a3f443 Mon Sep 17 00:00:00 2001 From: Justin Barnes Date: Fri, 1 Apr 2016 19:29:02 -0500 Subject: [PATCH 0901/1021] Fix typos/grammar in first paragraph of contributing file. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 609514160..0210f9179 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to Bower -Bower is a large community project with many different developers contributing at all levels to the project. We're **actively** looking for more contributors right now. If you're interested in becoming Bower maintainer or supporting in in any way, please full the following form: http://goo.gl/forms/P1ndzCNoiG. There is more information about [contributing](https://github.com/bower/bower/wiki/Contributor-Guidelines) in the Wiki. +Bower is a large community project with many different developers contributing at all levels to the project. We're **actively** looking for more contributors right now. If you're interested in becoming a Bower maintainer or supporting in anyway, please fill the following form: http://goo.gl/forms/P1ndzCNoiG. There is more information about [contributing](https://github.com/bower/bower/wiki/Contributor-Guidelines) in the Wiki. ## 🐛 [Bug reports](https://github.com/bower/bower/wiki/Report-a-Bug) From 1b1d8bdad699b6c7236f5b9e3fdf02acc8bac4a8 Mon Sep 17 00:00:00 2001 From: Kyle Pollock Date: Sat, 2 Apr 2016 07:26:04 -0500 Subject: [PATCH 0902/1021] Remove jscs inline error suppression comments. - jscs is removed from the project. --- lib/renderers/JsonRenderer.js | 2 -- lib/renderers/StandardRenderer.js | 2 -- lib/util/rootCheck.js | 1 - 3 files changed, 5 deletions(-) diff --git a/lib/renderers/JsonRenderer.js b/lib/renderers/JsonRenderer.js index 4505e2776..460ff9eb1 100644 --- a/lib/renderers/JsonRenderer.js +++ b/lib/renderers/JsonRenderer.js @@ -31,10 +31,8 @@ JsonRenderer.prototype.error = function (err) { err.message = message; // Stack - // jscs:disable requireCamelCaseOrUpperCaseIdentifiers stack = err.fstream_stack || err.stack || 'N/A'; err.stacktrace = (Array.isArray(stack) ? stack.join('\n') : stack); - // jscs:enable requireCamelCaseOrUpperCaseIdentifiers this.log(err); this.end(); diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index 234457fe6..71c4c65be 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -72,12 +72,10 @@ StandardRenderer.prototype.error = function (err) { // Print trace if verbose, the error has no code // or if the error is a node error if (this._config.verbose || !err.code || err.errno) { - // jscs:disable requireCamelCaseOrUpperCaseIdentifiers stack = err.fstream_stack || err.stack || 'N/A'; str = chalk.yellow('\nStack trace:\n'); str += (Array.isArray(stack) ? stack.join('\n') : stack) + '\n'; str += chalk.yellow('\nConsole trace:\n'); - // jscs:enable requireCamelCaseOrUpperCaseIdentifiers this._write(process.stderr, str); this._write(process.stderr, new Error().stack); diff --git a/lib/util/rootCheck.js b/lib/util/rootCheck.js index e54c3ab22..0c93556b3 100644 --- a/lib/util/rootCheck.js +++ b/lib/util/rootCheck.js @@ -1,4 +1,3 @@ -// jscs:disable disallowMultipleLineStrings 'use strict'; var isRoot = require('is-root'); var createError = require('./createError'); From 8679ad77ae5afee67cf808fe5310e837417d217d Mon Sep 17 00:00:00 2001 From: bamsy Date: Sun, 3 Apr 2016 06:18:06 -0500 Subject: [PATCH 0903/1021] Fix grammar in contributing file. - remove trailing whitespace - "anyway" -> "any way" --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0210f9179..f7e17e9d3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to Bower -Bower is a large community project with many different developers contributing at all levels to the project. We're **actively** looking for more contributors right now. If you're interested in becoming a Bower maintainer or supporting in anyway, please fill the following form: http://goo.gl/forms/P1ndzCNoiG. There is more information about [contributing](https://github.com/bower/bower/wiki/Contributor-Guidelines) in the Wiki. +Bower is a large community project with many different developers contributing at all levels to the project. We're **actively** looking for more contributors right now. If you're interested in becoming a Bower maintainer or supporting in any way, please fill the following form: http://goo.gl/forms/P1ndzCNoiG. There is more information about [contributing](https://github.com/bower/bower/wiki/Contributor-Guidelines) in the Wiki. ## 🐛 [Bug reports](https://github.com/bower/bower/wiki/Report-a-Bug) @@ -12,7 +12,7 @@ Bower is a large community project with many different developers contributing a ## High-impact Involvement -* Maintaining the bower client. +* Maintaining the bower client. * Read [Architecture doc](https://github.com/bower/bower/wiki/Rewrite-architecture) * Triage, close, fix and resolve [issues](https://github.com/bower/bower/issues) From 32cbb5a0e84eb925849a374a013ddcfca71b227e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 13:46:44 +0200 Subject: [PATCH 0904/1021] Update graceful-fs --- packages/bower-json/CHANGELOG.md | 4 ++++ packages/bower-json/package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/bower-json/CHANGELOG.md b/packages/bower-json/CHANGELOG.md index 8d4650198..59394d59e 100644 --- a/packages/bower-json/CHANGELOG.md +++ b/packages/bower-json/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.7.1 + +- Update graceful-fs to 4.x + # 0.7.0 - Add getIssues function to retrieve all errors and warnings diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 292482152..c0c5ad708 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -12,7 +12,7 @@ "dependencies": { "deep-extend": "^0.4.0", "ext-name": "^3.0.0", - "graceful-fs": "^3.0.0", + "graceful-fs": "^4.1.3", "intersect": "^1.0.1" }, "devDependencies": { From 358a73b98ef67ec703af61e9235bc57ea450382f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 13:47:56 +0200 Subject: [PATCH 0905/1021] 0.7.1 --- packages/bower-json/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index c0c5ad708..753040b94 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,6 +1,6 @@ { "name": "bower-json", - "version": "0.7.0", + "version": "0.7.1", "description": "Read bower.json files with semantics, normalisation, defaults and validation", "author": "Twitter", "license": "MIT", From f05cd5fb9452ff49d051db1008627181c645788f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 13:49:22 +0200 Subject: [PATCH 0906/1021] Update bower-json to 0.7.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1a1d44770..24a2d1113 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "archy": "1.0.0", "bower-config": "^1.3.1", "bower-endpoint-parser": "^0.2.2", - "bower-json": "^0.7.0", + "bower-json": "^0.7.1", "bower-logger": "^0.2.2", "bower-registry-client": "^1.0.0", "cardinal": "0.4.4", From 037bbff17eda08723d1340a2a19a83b4d9ffb430 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 14:11:37 +0200 Subject: [PATCH 0907/1021] Update changelog --- packages/bower-json/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/CHANGELOG.md b/packages/bower-json/CHANGELOG.md index 59394d59e..9c8b98cf6 100644 --- a/packages/bower-json/CHANGELOG.md +++ b/packages/bower-json/CHANGELOG.md @@ -1,4 +1,4 @@ -# 0.7.1 +# 0.8.0 - Update graceful-fs to 4.x From 4d7cdb0556497609584a34a036814e112dabb48c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 14:11:41 +0200 Subject: [PATCH 0908/1021] 0.8.0 --- packages/bower-json/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 753040b94..8f621f419 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,6 +1,6 @@ { "name": "bower-json", - "version": "0.7.1", + "version": "0.8.0", "description": "Read bower.json files with semantics, normalisation, defaults and validation", "author": "Twitter", "license": "MIT", From f4e0b3dfba00f473191a8a86fae398be43341070 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 14:18:23 +0200 Subject: [PATCH 0909/1021] Update bower-json to 0.8.0 and update tests --- package.json | 2 +- test/commands/init.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 24a2d1113..9e9951653 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "archy": "1.0.0", "bower-config": "^1.3.1", "bower-endpoint-parser": "^0.2.2", - "bower-json": "^0.7.1", + "bower-json": "^0.8.0", "bower-logger": "^0.2.2", "bower-registry-client": "^1.0.0", "cardinal": "0.4.4", diff --git a/test/commands/init.js b/test/commands/init.js index ae125817e..ea5a718f0 100644 --- a/test/commands/init.js +++ b/test/commands/init.js @@ -83,7 +83,7 @@ describe('bower init', function () { it('gets defaults from package.json', function () { mainPackage.prepare({ 'package.json': { - 'name': 'name from npm', + 'name': 'name-from-npm', 'description': 'description from npm', 'main': 'index.js', 'keywords': [ @@ -129,7 +129,7 @@ describe('bower init', function () { }) .then(function () { expect(mainPackage.readJson('bower.json')).to.eql({ - 'name': 'name from npm', + 'name': 'name-from-npm', 'description': 'description from npm', 'main': 'index.js', 'keywords': [ From fc4446247cf246033104e701563e2d07bc297bc2 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 14:26:26 +0200 Subject: [PATCH 0910/1021] Update graceful-fs to 4.x --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9e9951653..c17fc1576 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "fstream-ignore": "^1.0.2", "github": "^0.2.3", "glob": "^4.3.2", - "graceful-fs": "^3.0.5", + "graceful-fs": "^4.1.3", "handlebars": "^4.0.5", "inquirer": "0.10.0", "is-root": "^1.0.0", From c2e0dc9d23e57a67da3ea85f0f92164d8eebcaca Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 17:33:19 +0200 Subject: [PATCH 0911/1021] Prevent swallowing exceptions with programmatic api, fixes #2187 --- lib/commands/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/commands/index.js b/lib/commands/index.js index 9be35bf98..e55ddf464 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -38,7 +38,7 @@ function commandFactory(id) { var logger = new Logger(); Q.try(func, logger) - .then(function () { + .done(function () { config.restore(); var args = [].slice.call(arguments); args.unshift('end'); From aaaa9cd5307e63cfbdb2ed3968864129c68bde14 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 18:17:04 +0200 Subject: [PATCH 0912/1021] Don't ask for git credentials in non-interactive session This is done by setting GIT_TERMINAL_PROMPT variable - fixes #956 - fixes #1009 --- lib/core/resolvers/GitResolver.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/core/resolvers/GitResolver.js b/lib/core/resolvers/GitResolver.js index aa41ef29d..3c161a3f8 100644 --- a/lib/core/resolvers/GitResolver.js +++ b/lib/core/resolvers/GitResolver.js @@ -27,6 +27,7 @@ function GitResolver(decEndpoint, config, logger) { mkdirp.sync(config.storage.empty); process.env.GIT_TEMPLATE_DIR = config.storage.empty; process.env.GIT_SSL_NO_VERIFY = (!config.strictSsl).toString(); + process.env.GIT_TERMINAL_PROMPT = config.interactive ? '1' : '0'; Resolver.call(this, decEndpoint, config, logger); From 4793fc0d1cba979f6b8c13b8ffea56208ea89420 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 18:38:28 +0200 Subject: [PATCH 0913/1021] Bump year in license --- packages/bower-json/LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/LICENSE b/packages/bower-json/LICENSE index 13e8246fd..f25dbe841 100644 --- a/packages/bower-json/LICENSE +++ b/packages/bower-json/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2012 Twitter and other contributors +Copyright (c) 2016 Twitter and other contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in From 69cd360551720e9fe95d5a98267e7abc94b26d3e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 18:59:44 +0200 Subject: [PATCH 0914/1021] Update changelog --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c6111878..37d146587 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 1.7.8 - 2016-01-04 + +- Don't ask for git credentials in non-interactive session, fixes #956 #1009 +- Prevent swallowing exceptions with programmatic api, fixes #2187 +- Update graceful-fs to 4.x in all dependences, fixes nodejs/node#5213 +- Resolve pluggable resolvers using cwd and fallback to global modules, fixes #1919 +- Upgrade handlebars to 4.0.5, closes #2195 +- Replace all % chatacters in defined scripts, instead of only first one, fixes #2174 +- Update opn package to fix issues with "bower open" command on Windows +- Update bower-config + - Do not interpolate environment variables in script hooks, fixes bower/config#47 +- Add support for "save" and "save-exact" in .bowerrc, #2161 + ## 1.7.7 - 2016-01-27 Revert locations of all files while still packaging `node_modules`. From 9e5cd572f87f4150e43c7800efca4e7b9c79409c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 19:00:08 +0200 Subject: [PATCH 0915/1021] 1.7.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c17fc1576..d4ed77498 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.7.7", + "version": "1.7.8", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From e8e4c8fdbceb05d320771e4ff92e74bfdec81c34 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 19:20:57 +0200 Subject: [PATCH 0916/1021] Fix typo in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37d146587..c8abf7012 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 1.7.8 - 2016-01-04 +## 1.7.8 - 2016-04-04 - Don't ask for git credentials in non-interactive session, fixes #956 #1009 - Prevent swallowing exceptions with programmatic api, fixes #2187 From 9569a8074d9446f84f0b991549e386a9cab045c6 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 20:42:55 +0200 Subject: [PATCH 0917/1021] Add missing changelog entry, #2233 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8abf7012..203a22810 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ - Update opn package to fix issues with "bower open" command on Windows - Update bower-config - Do not interpolate environment variables in script hooks, fixes bower/config#47 +- Update bower-json + - Validate package name more strictly and allow only latin letters, dots, dashes and underscores - Add support for "save" and "save-exact" in .bowerrc, #2161 ## 1.7.7 - 2016-01-27 From 8e181c17921da772d5d2f3895887e7b2d0aed232 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 21:37:50 +0200 Subject: [PATCH 0918/1021] Make name validation far less strict --- packages/bower-json/lib/json.js | 8 ++++---- packages/bower-json/test/test.js | 8 +++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index 7467f49cf..46b12788f 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -136,16 +136,16 @@ function getIssues(json) { if (!json.name) { errors.push('No "name" property set'); } else { - if (!/^[a-zA-Z0-9_][a-zA-Z0-9\.\-_]*$/.test(json.name)) { - errors.push('Name must be lowercase string, with dots, dashes, or @'); + if (!/^[a-zA-Z0-9_@][a-zA-Z0-9_@\.\- \/]*$/.test(json.name)) { + errors.push('Name must be lowercase, can contain digits, dots, dashes, "@" or spaces'); } if (json.name.length > 50) { warnings.push('The "name" is too long, the limit is 50 characters'); } - if (/[A-Z]/.test(json.name)) { - warnings.push('The "name" must be lowercase'); + if (!/^[a-z0-9_][a-z0-9_\.\-]*$/.test(json.name)) { + warnings.push('The "name" is recommended to be lowercase, can contain digits, dots, dashes'); } if (/^[\.-]/.test(json.name)) { diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index 9344fba85..7be7d6abb 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -272,6 +272,12 @@ describe('.parse', function () { }); describe('.getIssues', function () { + it('should print no errors even for weird package names', function () { + var json = { name: '@gruNt/my dependency' }; + + expect(bowerJson.getIssues(json).errors).to.be.empty(); + }); + it('should validate the name length', function () { var json = { name: 'a_123456789_123456789_123456789_123456789_123456789_z' }; @@ -284,7 +290,7 @@ describe('.getIssues', function () { var json = { name: 'gruNt' }; expect(bowerJson.getIssues(json).warnings).to.contain( - 'The "name" must be lowercase' + 'The "name" is recommended to be lowercase, can contain digits, dots, dashes' ); }); From 7ee1686cf4701db4c3cb7cfc50a417c3e8eaba0c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 21:45:39 +0200 Subject: [PATCH 0919/1021] Add changelog for 0.8.1 --- packages/bower-json/CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/bower-json/CHANGELOG.md b/packages/bower-json/CHANGELOG.md index 9c8b98cf6..58bcd7e50 100644 --- a/packages/bower-json/CHANGELOG.md +++ b/packages/bower-json/CHANGELOG.md @@ -1,6 +1,15 @@ +# 0.8.1 + +- Revert strict name validations and allow @, spaces and slashes + # 0.8.0 - Update graceful-fs to 4.x +- Add name validations that reflect what's happening in registry + +# 0.7.1 + +- Unpublished # 0.7.0 From 8c624bbda6ad4d4fce6b733931810518a22db1fe Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 4 Apr 2016 21:45:44 +0200 Subject: [PATCH 0920/1021] 0.8.1 --- packages/bower-json/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index 8f621f419..a145b194a 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -1,6 +1,6 @@ { "name": "bower-json", - "version": "0.8.0", + "version": "0.8.1", "description": "Read bower.json files with semantics, normalisation, defaults and validation", "author": "Twitter", "license": "MIT", From 12d41aeb8ce6560bab069e0a380122b0cdccda54 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 5 Apr 2016 13:34:06 +0200 Subject: [PATCH 0921/1021] Warn instead of erroring for invalida package names, #2233 --- lib/core/Project.js | 2 +- lib/core/resolvers/Resolver.js | 12 ++-------- lib/core/resolvers/pluginResolverFactory.js | 3 ++- lib/util/readJson.js | 8 +++++++ package.json | 2 +- test/commands/init.js | 15 ++++++++++++ test/core/resolvers/resolver.js | 26 --------------------- 7 files changed, 29 insertions(+), 39 deletions(-) diff --git a/lib/core/Project.js b/lib/core/Project.js index 83e6705bf..50bdee4d7 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -579,7 +579,7 @@ Project.prototype._readJson = function () { return { name: path.basename(that._config.cwd) || 'root' }; }) .then(function (defaults) { - return that._json = readJson(that._config.cwd, { assume: defaults }); + return that._json = readJson(that._config.cwd, { assume: defaults, logger: that._logger }); }) .spread(function (json, deprecated, assumed) { var jsonStr; diff --git a/lib/core/resolvers/Resolver.js b/lib/core/resolvers/Resolver.js index 3f9221a7f..6b587dc73 100644 --- a/lib/core/resolvers/Resolver.js +++ b/lib/core/resolvers/Resolver.js @@ -178,7 +178,8 @@ Resolver.prototype._readJson = function (dir) { dir = dir || this._tempDir; return readJson(dir, { - assume: { name: this._name } + assume: { name: this._name }, + logger: that._logger }) .spread(function (json, deprecated) { if (deprecated) { @@ -217,15 +218,6 @@ Resolver.prototype._savePkgMeta = function (meta) { meta._source = this._source; meta._target = this._target; - ['main', 'ignore'].forEach(function (attr) { - if (meta[attr]) return; - - that._logger.log( - 'warn', 'invalid-meta', - (meta.name || 'component') + ' is missing "' + attr + '" entry in bower.json' - ); - }); - // Stringify contents contents = JSON.stringify(meta, null, 2); diff --git a/lib/core/resolvers/pluginResolverFactory.js b/lib/core/resolvers/pluginResolverFactory.js index b86c4d885..799203c8d 100644 --- a/lib/core/resolvers/pluginResolverFactory.js +++ b/lib/core/resolvers/pluginResolverFactory.js @@ -191,7 +191,8 @@ function pluginResolverFactory(resolverFactory, bower) { var that = this; return readJson(dir, { - assume: { name: that.getName() } + assume: { name: that.getName() }, + logger: bower.logger }) .spread(function (json, deprecated) { if (deprecated) { diff --git a/lib/util/readJson.js b/lib/util/readJson.js index 41fe79981..370cb8a10 100644 --- a/lib/util/readJson.js +++ b/lib/util/readJson.js @@ -17,6 +17,14 @@ function readJson(file, options) { .spread(function (json, jsonFile) { var deprecated; + if (options.logger) { + var issues = bowerJson.getIssues(json); + + issues.warnings.forEach(function (warning) { + options.logger.warn('invalid-meta', warning); + }); + } + jsonFile = path.basename(jsonFile); deprecated = jsonFile === 'component.json' ? jsonFile : false; diff --git a/package.json b/package.json index d4ed77498..e485ad7d6 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "archy": "1.0.0", "bower-config": "^1.3.1", "bower-endpoint-parser": "^0.2.2", - "bower-json": "^0.8.0", + "bower-json": "^0.8.1", "bower-logger": "^0.2.2", "bower-registry-client": "^1.0.0", "cardinal": "0.4.4", diff --git a/test/commands/init.js b/test/commands/init.js index ea5a718f0..795c964f9 100644 --- a/test/commands/init.js +++ b/test/commands/init.js @@ -143,4 +143,19 @@ describe('bower init', function () { }); }); }); + + it('can handle strange characters', function () { + mainPackage.prepare({ + 'package.json': { + 'name': 'name/from npm' + } + }); + + var logger = init({ + cwd: mainPackage.path, + interactive: true + }); + + return helpers.expectEvent(logger, 'prompt'); + }); }); diff --git a/test/core/resolvers/resolver.js b/test/core/resolvers/resolver.js index 50b9f8b5b..49abf8515 100644 --- a/test/core/resolvers/resolver.js +++ b/test/core/resolvers/resolver.js @@ -784,32 +784,6 @@ describe('Resolver', function () { }) .done(); }); - - it('should warn user for missing attributes in bower.json', function (next) { - var resolver = create('fooooo'); - resolver._tempDir = tempDir; - var notifiedCount = 0; - logger.on('log', function (log) { - notifiedCount ++; - expect(log).to.be.an('object'); - expect(log.level).to.be('warn'); - if (notifiedCount === 1) { - expect(log.message).to.contain('bar is missing "main" entry in bower.json'); - } else { - expect(log.message).to.contain('bar is missing "ignore" entry in bower.json'); - } - }); - resolver._savePkgMeta({ name: 'bar' }); - expect(notifiedCount).to.be(2); - - resolver._savePkgMeta({ name: 'bar', main: 'foo' }); - expect(notifiedCount).to.be(3); - - // should not warn again - resolver._savePkgMeta({ name: 'bar', main: 'flart', ignore: 'blat' }); - expect(notifiedCount).to.be(3); - next(); - }); }); describe('#isTargetable', function () { From b8e6f36a91e95ea5401126e294a9b228682d44ae Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 5 Apr 2016 13:36:52 +0200 Subject: [PATCH 0922/1021] Add changelog entries for 1.7.9 --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 203a22810..694b508a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.7.8 - 2016-04-05 + +- Show warnings for invalid bower.json fields +- Update bower-json + - Less strict validation on package name (allow spaces, slashes, and "@") + ## 1.7.8 - 2016-04-04 - Don't ask for git credentials in non-interactive session, fixes #956 #1009 @@ -12,7 +18,7 @@ - Update bower-config - Do not interpolate environment variables in script hooks, fixes bower/config#47 - Update bower-json - - Validate package name more strictly and allow only latin letters, dots, dashes and underscores + - Validate package name more strictly and allow only latin letters, dots, dashes and underscores - Add support for "save" and "save-exact" in .bowerrc, #2161 ## 1.7.7 - 2016-01-27 From 8065e5c64a22bd6d60e4df8d9be46b5805ec9355 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 5 Apr 2016 13:44:58 +0200 Subject: [PATCH 0923/1021] 1.7.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e485ad7d6..3978044f2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.7.8", + "version": "1.7.9", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 3aebb34f1d67211af0e3959530f139843277c146 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 5 Apr 2016 13:48:21 +0200 Subject: [PATCH 0924/1021] Fix typo in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 694b508a9..c421a6e5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 1.7.8 - 2016-04-05 +## 1.7.9 - 2016-04-05 - Show warnings for invalid bower.json fields - Update bower-json From bbc9b35cb1dd7e6c4babe941bbc3b747cee783c6 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 6 Apr 2016 13:45:43 +0200 Subject: [PATCH 0925/1021] Update grunt to 1.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3978044f2..47f03ddc6 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "chai": "^1.10.0", "coveralls": "^2.11.2", "expect.js": "^0.3.1", - "grunt": "1.0.0-rc1", + "grunt": "^1.0.1", "grunt-cli": "^1.1.0", "grunt-contrib-watch": "^1.0.0", "grunt-eslint": "^18.0.0", From 7b2fd5dcd1ad50a253cf5713a5ea30e83bedb5ac Mon Sep 17 00:00:00 2001 From: Justin Barnes Date: Sat, 9 Apr 2016 09:14:04 -0500 Subject: [PATCH 0926/1021] Remove unreachable code from parse function --- packages/bower-config/lib/util/rc.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index 76afbac0d..ddfa6f672 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -70,8 +70,6 @@ function parse(content, file) { error.code = 'EMALFORMED'; throw error; } - - return null; } function json(file) { From 3251051d20e52bec278bfe2bf64a6f994bf57ce8 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 10 Apr 2016 13:15:57 +0200 Subject: [PATCH 0927/1021] Fix tests given the new registry --- test/core/resolverFactory.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 10c580d9f..02d02ca10 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -568,7 +568,7 @@ describe('resolverFactory', function () { callFactory({ source: 'pure' }) .then(function (resolver) { expect(resolver).to.be.a(resolvers.GitRemote); - expect(resolver.getSource()).to.equal('git://github.com/yui/pure-release.git'); + expect(resolver.getSource()).to.equal('https://github.com/yui/pure-release.git'); expect(resolver.getTarget()).to.equal('*'); }) .then(function () { @@ -576,7 +576,7 @@ describe('resolverFactory', function () { return callFactory({ source: 'pure', name: 'foo' }) .then(function (resolver) { expect(resolver).to.be.a(resolvers.GitRemote); - expect(resolver.getSource()).to.equal('git://github.com/yui/pure-release.git'); + expect(resolver.getSource()).to.equal('https://github.com/yui/pure-release.git'); expect(resolver.getName()).to.equal('foo'); expect(resolver.getTarget()).to.equal('*'); }); From 7c54812ecf2de4d8061d065f91c858d6ab85dd60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Cie=C5=9Blik?= Date: Sun, 10 Apr 2016 13:24:29 +0200 Subject: [PATCH 0928/1021] Allow to type the entire version when conflict occured (#2243) --- lib/core/Manager.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index ebd543515..dac6333a9 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -678,6 +678,8 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { var save; var choices; var picks = []; + var versionRegex = /(?:[\d\w]\.){2}[\d\w](?:.)*/; + var picksReleases; // If there are both semver and non-semver, there's no way // to figure out the suitable one @@ -833,14 +835,21 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { }); choices = picks.map(function (pick, index) { return index + 1; }); + picksReleases = picks.map(function(pick) { return pick.pkgMeta._release; }); return Q.nfcall(this._logger.prompt.bind(this._logger), { type: 'input', message: 'Answer', validate: function (choice) { + var invalidChoice = 'Invalid choice'; + + if (choice.match(versionRegex)) { + return picksReleases.indexOf(choice) != -1 ? true : invalidChoice; + } + choice = Number(mout.string.trim(choice.trim(), '!')); if (!choice || choice < 1 || choice > picks.length) { - return 'Invalid choice'; + return invalidChoice; } return true; @@ -852,8 +861,13 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { // Sanitize choice choice = choice.trim(); save = /^!/.test(choice) || /!$/.test(choice); // Save if prefixed or suffixed with ! - choice = Number(mout.string.trim(choice, '!')); - pick = picks[choice - 1]; + + if (choice.match(versionRegex)) { + pick = picks[picksReleases.indexOf(choice)]; + } else { + choice = Number(mout.string.trim(choice, '!')); + pick = picks[choice - 1]; + } // Save resolution if (save) { From 8ee2d78779f60fe0293d2e3e170a2f49e04fa26d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Cie=C5=9Blik?= Date: Tue, 12 Apr 2016 18:57:44 +0200 Subject: [PATCH 0929/1021] Add support for registering package with github's orgname/reponame (#2248) --- lib/commands/register.js | 11 +++++++++-- test/commands/register.js | 13 +++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/commands/register.js b/lib/commands/register.js index 9c096a3b7..da9d0d2c4 100644 --- a/lib/commands/register.js +++ b/lib/commands/register.js @@ -4,16 +4,23 @@ var PackageRepository = require('../core/PackageRepository'); var createError = require('../util/createError'); var defaultConfig = require('../config'); -function register(logger, name, url, config) { +function register(logger, name, source, config) { var repository; var registryClient; var force; + var url; + var githubSourceRegex = /^\w[\w-]+\/\w[\w-]+$/; + var getGithubUrl = function(source) { + return 'git@github.com:' + source + '.git'; + }; config = defaultConfig(config); force = config.force; name = (name || '').trim(); - url = (url || '').trim(); + source = (source || '').trim(); + + url = source.match(githubSourceRegex) ? getGithubUrl(source) : source; // Bypass any cache config.offline = false; diff --git a/test/commands/register.js b/test/commands/register.js index c677ed95d..3d3b2d3f8 100644 --- a/test/commands/register.js +++ b/test/commands/register.js @@ -86,6 +86,19 @@ describe('bower register', function () { }); }); + it('should call registry client with name and github source', function () { + mainPackage.prepare(); + + var register = registerFactory(mainPackage.path, mainPackage.meta()); + return helpers.run(register, ['some-name', 'some-repo/package']) + .spread(function (result) { + expect(result).to.eql({ + // Result from register action on stub + name: 'some-name', url: 'git@github.com:some-repo/package.git' + }); + }); + }); + it('should confirm in interactive mode', function () { mainPackage.prepare(); From 40e3ee091b97313dd5bbb346b75795efa22e0421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Cie=C5=9Blik?= Date: Tue, 12 Apr 2016 19:15:24 +0200 Subject: [PATCH 0930/1021] Support single-char repo names and package names (#2249) --- lib/commands/register.js | 2 +- test/commands/register.js | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/commands/register.js b/lib/commands/register.js index da9d0d2c4..72808d3de 100644 --- a/lib/commands/register.js +++ b/lib/commands/register.js @@ -9,7 +9,7 @@ function register(logger, name, source, config) { var registryClient; var force; var url; - var githubSourceRegex = /^\w[\w-]+\/\w[\w-]+$/; + var githubSourceRegex = /^\w[\w-]*\/\w[\w-]*$/; var getGithubUrl = function(source) { return 'git@github.com:' + source + '.git'; }; diff --git a/test/commands/register.js b/test/commands/register.js index 3d3b2d3f8..01f562313 100644 --- a/test/commands/register.js +++ b/test/commands/register.js @@ -90,11 +90,24 @@ describe('bower register', function () { mainPackage.prepare(); var register = registerFactory(mainPackage.path, mainPackage.meta()); - return helpers.run(register, ['some-name', 'some-repo/package']) + return helpers.run(register, ['some-name', 'some-name/repo']) .spread(function (result) { expect(result).to.eql({ // Result from register action on stub - name: 'some-name', url: 'git@github.com:some-repo/package.git' + name: 'some-name', url: 'git@github.com:some-name/repo.git' + }); + }); + }); + + it('should support single-char github names', function () { + mainPackage.prepare(); + + var register = registerFactory(mainPackage.path, mainPackage.meta()); + return helpers.run(register, ['some-name', 'a/b']) + .spread(function (result) { + expect(result).to.eql({ + // Result from register action on stub + name: 'some-name', url: 'git@github.com:a/b.git' }); }); }); From e7298291745b1ed818cd4b1a0b65b31e1e84a543 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 12 Apr 2016 19:18:36 +0200 Subject: [PATCH 0931/1021] Make bower version behavior consistent with spec (#2232) --- lib/commands/version.js | 203 ++++++++++++++++----------- lib/templates/json/help-version.json | 4 +- test/commands/version.js | 100 ++++++++----- test/helpers.js | 15 ++ 4 files changed, 202 insertions(+), 120 deletions(-) diff --git a/lib/commands/version.js b/lib/commands/version.js index 778d907b6..9cb672f27 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -4,116 +4,149 @@ var fs = require('../util/fs'); var path = require('path'); var Q = require('q'); var execFile = require('child_process').execFile; -var Project = require('../core/Project'); var defaultConfig = require('../config'); var createError = require('../util/createError'); function version(logger, versionArg, options, config) { - var project; - options = options || {}; + config = defaultConfig(config); - project = new Project(config, logger); - return bump(project, versionArg, options.message); + return bump(logger, config, versionArg, options.message); } -function bump(project, versionArg, message) { - var cwd = project._config.cwd || process.cwd(); +function bump(logger, config, versionArg, message) { + var cwd = config.cwd || process.cwd(); var newVersion; - var doGitCommit = false; - return checkGit(cwd) - .then(function (hasGit) { - doGitCommit = hasGit; - }) - .then(project.getJson.bind(project)) - .then(function (json) { - newVersion = getNewVersion(json.version, versionArg); - json.version = newVersion; - }) - .then(project.saveJson.bind(project)) + if (!versionArg) { + throw createError('No agrument provided', 'EREADOPTIONS'); + } + + return driver.check(cwd) .then(function () { - if (doGitCommit) { - return gitCommitAndTag(cwd, newVersion, message); + return Q.all([driver.versions(cwd), driver.currentVersion(cwd)]); + }) + .spread(function (versions, currentVersion) { + currentVersion = currentVersion || '0.0.0'; + + if (semver.valid(versionArg)) { + newVersion = semver.valid(versionArg); + } else { + newVersion = semver.inc(currentVersion, versionArg); + + if (!newVersion) { + throw createError('Invalid argument: ' + versionArg, 'EINVALIDVERSION', { version: versionArg }); + } } + + newVersion = (currentVersion[0] === 'v') ? 'v' + newVersion : newVersion; + + if (versions) { + versions.forEach(function (version) { + if (semver.eq(version, newVersion)) { + throw createError('Version exists: ' + newVersion, 'EVERSIONEXISTS', { versions: versions, newVersion: newVersion }); + } + }); + } + + return driver.bump(cwd, newVersion, message).then(function () { + return { + oldVersion: currentVersion, + newVersion: newVersion + } + }); }) - .then(function () { - console.log('v' + newVersion); - return newVersion; + .then(function (result) { + logger.info('version', 'Bumped package version from ' + result.oldVersion + ' to ' + result.newVersion, result); + + return result.newVersion; }); } -function getNewVersion(currentVersion, versionArg) { - var newVersion = semver.valid(versionArg); - if (!newVersion) { - newVersion = semver.inc(currentVersion, versionArg); - } - if (!newVersion) { - throw createError('Invalid version argument: `' + versionArg + '`. Usage: `bower version [ | major | minor | patch]`', 'EINVALIDVERSION'); - } - if (currentVersion === newVersion) { - throw createError('Version not changed', 'EVERSIONNOTCHANGED'); - } - return newVersion; -} +var driver = { + check: function (cwd) { + function checkGit(cwd) { + var gitDir = path.join(cwd, '.git'); + return Q.nfcall(fs.stat, gitDir) + .then(function (stat) { + if (stat.isDirectory()) { + return checkGitStatus(cwd); + } + return false; + }, function () { + //Ignore not found .git directory + return false; + }); + } -function checkGit(cwd) { - var gitDir = path.join(cwd, '.git'); - return Q.nfcall(fs.stat, gitDir) - .then(function (stat) { - if (stat.isDirectory()) { - return checkGitStatus(cwd); + function checkGitStatus(cwd) { + return Q.nfcall(which, 'git') + .fail(function (err) { + err.code = 'ENOGIT'; + throw err; + }) + .then(function () { + return Q.nfcall(execFile, 'git', ['status', '--porcelain'], {env: process.env, cwd: cwd}); + }) + .then(function (value) { + var stdout = value[0]; + var lines = filterModifiedStatusLines(stdout); + if (lines.length) { + throw createError('Version bump requires clean working directory', 'EWORKINGDIRECTORYDIRTY'); + } + return true; + }); } - return false; - }, function () { - //Ignore not found .git directory - return false; - }); -} -function checkGitStatus(cwd) { - return Q.nfcall(which, 'git') - .fail(function (err) { - err.code = 'ENOGIT'; - throw err; - }) - .then(function () { - return Q.nfcall(execFile, 'git', ['status', '--porcelain'], {env: process.env, cwd: cwd}); - }) - .then(function (value) { - var stdout = value[0]; - var lines = filterModifiedStatusLines(stdout); - if (lines.length) { - throw createError('Git working directory not clean.\n' + lines.join('\n'), 'EWORKINGDIRECTORYDIRTY'); + function filterModifiedStatusLines(stdout) { + return stdout.trim().split('\n') + .filter(function (line) { + return line.trim() && !line.match(/^\?\? /); + }).map(function (line) { + return line.trim(); + }); } - return true; - }); -} -function filterModifiedStatusLines(stdout) { - return stdout.trim().split('\n') - .filter(function (line) { - return line.trim() && !line.match(/^\?\? /); - }).map(function (line) { - return line.trim(); - }); -} + return checkGit(cwd).then(function (hasGit) { + if (!hasGit) { + throw createError('Version bump currently supports only git repositories', 'ENOTGITREPOSITORY'); + } + }); + }, + versions: function (cwd) { + return Q.nfcall(execFile, 'git', ['tag'], {env: process.env, cwd: cwd}) + .then(function (res) { + var versions = res[0] + .split(/\r?\n/) + .filter(semver.valid); -function gitCommitAndTag(cwd, newVersion, message) { - var tag = 'v' + newVersion; - message = message || tag; - message = message.replace(/%s/g, newVersion); - return Q.nfcall(execFile, 'git', ['add', 'bower.json'], {env: process.env, cwd: cwd}) - .then(function () { - return Q.nfcall(execFile, 'git', ['commit', '-m', message], {env: process.env, cwd: cwd}); - }) - .then(function () { - return Q.nfcall(execFile, 'git', ['tag', tag, '-am', message], {env: process.env, cwd: cwd}); - }); + return versions; + }, function () { + return []; + }); + }, + currentVersion: function (cwd) { + return Q.nfcall(execFile, 'git', ['describe', '--abbrev=0', '--tags'], {env: process.env, cwd: cwd}) + .then(function (res) { + var version = res[0] + .split(/\r?\n/) + .filter(semver.valid)[0]; + + return version; + }, function () { + return undefined; + }); + }, + bump: function (cwd, tag, message) { + message = message || tag; + message = message.replace(/%s/g, tag); + return Q.nfcall(execFile, 'git', ['commit', '-m', message, '--allow-empty'], {env: process.env, cwd: cwd}) .then(function () { + Q.nfcall(execFile, 'git', ['tag', tag, '-am', message], {env: process.env, cwd: cwd}); + }); + } } -// ------------------- version.readOptions = function (argv) { var cli = require('../util/cli'); diff --git a/lib/templates/json/help-version.json b/lib/templates/json/help-version.json index 605ef200f..d6bc76d0c 100644 --- a/lib/templates/json/help-version.json +++ b/lib/templates/json/help-version.json @@ -1,8 +1,8 @@ { "command": "version", - "description": "Run this in a package directory to bump the version and write the new data back to the bower.json file.\n\nThe newversion argument should be a valid semver string, or a valid second argument to semver.inc (one of \"build\", \"patch\", \"minor\", or \"major\"). In the second case, the existing version will be incremented\nby 1 in the specified field.\n\nIf run in a git repo, it will also create a version commit and tag, and fail if the repo is not clean.\n\nIf supplied with --message (shorthand: -m) config option, bower will use it as a commit message when creating a version commit. If the message config contains %s then that will be replaced with the resulting\nversion number. For example:\n\n bower version patch -m \"Upgrade to %s for reasons\"", + "description": "Creates an empty version commit and tag, and fail if the repo is not clean.\n\nThe argument should be a valid semver string, or one of following:\nbuild, patch, minor, major.\n\nIf supplied with --message (shorthand: -m) config option, bower will use it\nas a commit message when creating a version commit. If the message config\ncontains %s then that will be replaced with the resulting version number.\n\nFor example:\n\n bower version patch -m \"Upgrade to %s for reasons\"", "usage": [ - "version [ | major | minor | patch]" + "version [ | major | minor | patch]" ], "options": [ { diff --git a/test/commands/version.js b/test/commands/version.js index 3eab1aa4b..b70087377 100644 --- a/test/commands/version.js +++ b/test/commands/version.js @@ -3,87 +3,121 @@ var expect = require('expect.js'); var helpers = require('../helpers'); var version = helpers.require('lib/commands').version; -describe('bower list', function () { +describe('bower version', function () { var mainPackage = new helpers.TempDir({ - 'bower.json': { - name: 'foobar', - version: '0.0.0' - } - }); - - var gitPackage = new helpers.TempDir({ 'v0.0.0': { 'bower.json': { name: 'foobar', - version: '0.0.0' } } }); + var packageWithoutTags = new helpers.TempDir({}); + + it('bumps patch version', function () { - mainPackage.prepare(); + mainPackage.prepareGit(); return helpers.run(version, ['patch', {}, { cwd: mainPackage.path }]).then(function () { - expect(mainPackage.readJson('bower.json').version).to.be('0.0.1'); + expect(mainPackage.latestGitTag()).to.be('0.0.1'); }); }); it('bumps minor version', function () { - mainPackage.prepare(); + mainPackage.prepareGit(); return helpers.run(version, ['minor', {}, { cwd: mainPackage.path }]).then(function () { - expect(mainPackage.readJson('bower.json').version).to.be('0.1.0'); + expect(mainPackage.latestGitTag()).to.be('0.1.0'); }); }); it('bumps major version', function () { - mainPackage.prepare(); + mainPackage.prepareGit(); return helpers.run(version, ['major', {}, { cwd: mainPackage.path }]).then(function () { - expect(mainPackage.readJson('bower.json').version).to.be('1.0.0'); + expect(mainPackage.latestGitTag()).to.be('1.0.0'); }); }); it('changes version', function () { - mainPackage.prepare(); + mainPackage.prepareGit(); return helpers.run(version, ['1.2.3', {}, { cwd: mainPackage.path }]).then(function () { - expect(mainPackage.readJson('bower.json').version).to.be('1.2.3'); + expect(mainPackage.latestGitTag()).to.be('1.2.3'); }); }); it('returns the new version', function () { - mainPackage.prepare(); + mainPackage.prepareGit(); return helpers.run(version, ['major', {}, { cwd: mainPackage.path }]).then(function (results) { - expect(results[0]).to.be('1.0.0'); + expect(results[0]).to.be('v1.0.0'); }); }); - it('bumps patch version, create commit, and tag', function () { - gitPackage.prepareGit(); + it('fails on a dirty git repository', function () { + mainPackage.prepareGit(); + mainPackage.create({ + 'dirty.txt': 'This file has not been committed' + }); - return helpers.run(version, ['patch', {}, { cwd: gitPackage.path }]).then(function () { - expect(gitPackage.readJson('bower.json').version).to.be('0.0.1'); + return helpers.run(version, ['patch', {}, { cwd: mainPackage.path }]).then(null, function (err) { + expect(err).to.be.an(Error); + expect(err.code).to.be('ENOTGITREPOSITORY'); + }); + }); - var tags = gitPackage.git('tag'); - expect(tags).to.be('v0.0.0\nv0.0.1\n'); - var message = gitPackage.git('log', '--pretty=format:%s', '-n1'); - expect(message).to.be('v0.0.1'); + it('fails when the version already exists', function () { + mainPackage.prepareGit(); + + return helpers.run(version, ['0.0.0', {}, { cwd: mainPackage.path }]).then(null, function (err) { + expect(err).to.be.an(Error); + expect(err.code).to.be('EVERSIONEXISTS'); + }); + }); + + it('fails with an invalid argument', function () { + mainPackage.prepareGit(); + + return helpers.run(version, ['lol', {}, { cwd: mainPackage.path }]).then(null, function (err) { + expect(err).to.be.an(Error); + expect(err.code).to.be('EINVALIDVERSION'); }); }); it('bumps with custom commit message', function () { - gitPackage.prepareGit(); + mainPackage.prepareGit(); - return helpers.run(version, ['patch', { message: 'Bumping %s, because what'}, { cwd: gitPackage.path }]).then(function () { - expect(gitPackage.readJson('bower.json').version).to.be('0.0.1'); + return helpers.run(version, ['patch', { message: 'Bumping %s, because what'}, { cwd: mainPackage.path }]).then(function () { + var tags = mainPackage.git('tag'); + expect(tags).to.be('v0.0.0\nv0.0.1\n'); + var message = mainPackage.git('log', '--pretty=format:%s', '-n1'); + expect(message).to.be('Bumping v0.0.1, because what'); + }); + }); + + it('creates commit and tags', function () { + mainPackage.prepareGit(); - var tags = gitPackage.git('tag'); + return helpers.run(version, ['patch', {}, { cwd: mainPackage.path }]).then(function () { + var tags = mainPackage.git('tag'); expect(tags).to.be('v0.0.0\nv0.0.1\n'); - var message = gitPackage.git('log', '--pretty=format:%s', '-n1'); - expect(message).to.be('Bumping 0.0.1, because what'); + var message = mainPackage.git('log', '--pretty=format:%s', '-n1'); + expect(message).to.be('v0.0.1'); + }); + }); + + it('assumes v0.0.0 when no tags exist', function () { + packageWithoutTags.prepareGit(); + packageWithoutTags.create({ + 'index.js': 'console.log("hello, world");' + }); + packageWithoutTags.git('add', '-A'); + packageWithoutTags.git('commit', '-m"commit"'); + + return helpers.run(version, ['major', {}, { cwd: packageWithoutTags.path }]).then(function () { + expect(packageWithoutTags.latestGitTag()).to.be('1.0.0'); }); }); }); diff --git a/test/helpers.js b/test/helpers.js index 7c3005c50..9ae69ce69 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -14,6 +14,7 @@ var proxyquire = require('proxyquire').noCallThru().noPreserveCache(); var spawnSync = require('spawn-sync'); var config = require('../lib/config'); var nock = require('nock'); +var semver = require('semver'); // For better promise errors Q.longStackSupport = true; @@ -155,6 +156,20 @@ exports.TempDir = (function () { } }; + TempDir.prototype.latestGitTag = function () { + var versions = this.git('tag') + .split(/\r?\n/) + .map(function (t) { return t[0] == 'v' ? t.slice(1) : t; }) + .filter(semver.valid) + .sort(semver.compare); + + if (versions.length >= 1) { + return versions[versions.length - 1]; + } else { + throw new Error('No valid git version tags found.'); + } + }; + TempDir.prototype.exists = function (name) { return fs.existsSync(path.join(this.path, name)); }; From 343e6ac8bcb3ad69a90b2e8c37bf71796417f7b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Cie=C5=9Blik?= Date: Thu, 14 Apr 2016 15:02:07 +0200 Subject: [PATCH 0932/1021] Implement postuninstall hooks with tests (#2252) --- lib/core/Project.js | 3 +++ lib/core/scripts.js | 1 + test/core/scripts.js | 16 +++++++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/core/Project.js b/lib/core/Project.js index 50bdee4d7..2c4f34101 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -764,6 +764,9 @@ Project.prototype._removePackages = function (packages) { .then(function () { return that.saveJson(); }) + // Run post-uninstall hook before resolving with removed packages. + .then(scripts.postuninstall.bind( + null, that._config, that._logger, packages, that._installed, that._json)) // Resolve with removed packages .then(function () { return mout.object.filter(packages, function (dir) { diff --git a/lib/core/scripts.js b/lib/core/scripts.js index 15b9b6473..d0e7d42a0 100644 --- a/lib/core/scripts.js +++ b/lib/core/scripts.js @@ -89,6 +89,7 @@ var hook = function (action, ordered, config, logger, packages, installed, json) module.exports = { preuninstall: mout.function.partial(hook, 'preuninstall', false), + postuninstall: mout.function.partial(hook, 'postuninstall', false), preinstall: mout.function.partial(hook, 'preinstall', true), postinstall: mout.function.partial(hook, 'postinstall', true), //only exposed for test diff --git a/test/core/scripts.js b/test/core/scripts.js index 2f191ccfa..1e152f233 100644 --- a/test/core/scripts.js +++ b/test/core/scripts.js @@ -27,7 +27,8 @@ describe('scripts', function () { scripts: { preinstall: touch('preinstall_%_%'), postinstall: touch('postinstall_%_%'), - preuninstall: touch('preuninstall_%_%') + preuninstall: touch('preuninstall_%_%'), + postuninstall: touch('postuninstall_%_%') } }; @@ -66,6 +67,19 @@ describe('scripts', function () { }); + it('should run postuninstall hook.', function (next) { + + bower.commands + .uninstall([packageName], undefined, config) + .on('end', function (installed) { + + expect(fs.existsSync(path.join(tempDir, 'postuninstall_' + packageName + '_' + packageName))).to.be(true); + + next(); + }); + + }); + it('should not break anything when no hooks configured.', function (next) { bower.commands From dc59913098a392901d440d42f5527406f9bb2eb5 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 22 Apr 2016 00:35:23 +0200 Subject: [PATCH 0933/1021] Change default shorthandResolver from git:// to https:// --- packages/bower-config/CHANGELOG.md | 4 ++++ packages/bower-config/lib/util/defaults.js | 2 +- packages/bower-config/test/test.js | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/bower-config/CHANGELOG.md b/packages/bower-config/CHANGELOG.md index 926197a79..3954e0f16 100644 --- a/packages/bower-config/CHANGELOG.md +++ b/packages/bower-config/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.4.0 + +- Change default shorthand resolver from git:// to https:// + ## 1.3.1 - Ignore hook scripts for environment variable expansion diff --git a/packages/bower-config/lib/util/defaults.js b/packages/bower-config/lib/util/defaults.js index 01819dbc3..8cabc4cbe 100644 --- a/packages/bower-config/lib/util/defaults.js +++ b/packages/bower-config/lib/util/defaults.js @@ -22,7 +22,7 @@ var userAgent = !proxy && !httpsProxy var defaults = { 'directory': 'bower_components', 'registry': 'https://bower.herokuapp.com', - 'shorthand-resolver': 'git://github.com/{{owner}}/{{package}}.git', + 'shorthand-resolver': 'https://github.com/{{owner}}/{{package}}.git', 'tmp': paths.tmp, 'proxy': proxy, 'https-proxy': httpsProxy, diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index e29a5e6e5..c41a1f438 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -77,7 +77,7 @@ describe('NPM Config on package.json', function () { 'register': 'https://bower.herokuapp.com', 'publish': 'https://bower.herokuapp.com' }, - 'shorthandResolver': 'git://github.com/{{owner}}/{{package}}.git', + 'shorthandResolver': 'https://github.com/{{owner}}/{{package}}.git', 'tmp': '/foo/bar', 'timeout': 30000, 'ca': { From 249ac47b9c3db438db08b05dbef0824c04bfe7ef Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 22 Apr 2016 00:35:39 +0200 Subject: [PATCH 0934/1021] 1.4.0 --- packages/bower-config/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index 838827b3d..cc1f3f915 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -1,6 +1,6 @@ { "name": "bower-config", - "version": "1.3.1", + "version": "1.4.0", "description": "The Bower config reader and writer.", "author": "Twitter", "license": "MIT", From 4757e7353fdf9e39f2e0f7ed2bced77fdbbb0d73 Mon Sep 17 00:00:00 2001 From: Raja Sekar Date: Thu, 28 Apr 2016 10:20:19 +0530 Subject: [PATCH 0935/1021] fix for 2264 --- lib/templates/std/help-cache.std | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/templates/std/help-cache.std b/lib/templates/std/help-cache.std index 18e2803e9..d8e2d6fe9 100644 --- a/lib/templates/std/help-cache.std +++ b/lib/templates/std/help-cache.std @@ -11,7 +11,7 @@ Commands: {{#condense}} {{#each commands}} - {{#rpad length="23"}}{{@key}}{{/rpad}} {{.}} + {{#rpad minLength="23"}}{{@key}}{{/rpad}} {{.}} {{/each}} {{/condense}} - +{{#rpad minLength="23"}}{{/rpad}} From b1f1b8fae35bf2f8a70e46f505001a964face01d Mon Sep 17 00:00:00 2001 From: Raja Sekar Date: Thu, 28 Apr 2016 15:16:10 +0530 Subject: [PATCH 0936/1021] info message added for bower register --- lib/bin/bower.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bin/bower.js b/lib/bin/bower.js index 66d266803..5917bc171 100644 --- a/lib/bin/bower.js +++ b/lib/bin/bower.js @@ -101,7 +101,7 @@ function handleLogger(logger, renderer) { } }) .on('error', function (err) { - if (command !== 'help' && err.code === 'EREADOPTIONS') { + if (command !== 'help' && (err.code === 'EREADOPTIONS' || err.code === 'EINVFORMAT')) { logger = bower.commands.help(command); renderer = cli.getRenderer('help', logger.json, bower.config); handleLogger(logger, renderer); From 3c2562ca0e5e0e1efedc50a713afad02d39f24df Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 28 Apr 2016 12:23:54 +0200 Subject: [PATCH 0937/1021] Fix failing tests --- test/core/resolverFactory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 02d02ca10..8dfa632e5 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -215,7 +215,7 @@ describe('resolverFactory', function () { 'https://user@github.com/project/blah.git/': 'https://user@github.com/project/blah.git', // shorthand - 'bower/bower': 'git://github.com/bower/bower.git' + 'bower/bower': 'https://github.com/bower/bower.git' }; nonGitHub = [ From db1ed1c08f44e39e39d8b46e6228419fcd31caa6 Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 28 Apr 2016 12:32:13 +0200 Subject: [PATCH 0938/1021] Fix build errors #2 Related to the change from git:// to https:// --- test/core/resolverFactory.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 8dfa632e5..426a7253d 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -104,7 +104,7 @@ describe('resolverFactory', function () { 'https://user@hostname.com/project.git/': 'https://user@hostname.com/project.git', // shorthand - 'bower/bower': 'git://github.com/bower/bower.git' + 'bower/bower': 'https://github.com/bower/bower.git' }; mout.object.forOwn(endpoints, function (value, key) { @@ -625,12 +625,12 @@ describe('resolverFactory', function () { shorthandResolver: 'git://bower.io/{{owner}}/{{package}}/{{shorthand}}' }; - expect(resolver.getSource()).to.equal('git://github.com/bower/bower.git'); + expect(resolver.getSource()).to.equal('https://github.com/bower/bower.git'); return callFactory({ source: 'IndigoUnited/promptly' }, config); }) .then(function (resolver) { - expect(resolver.getSource()).to.equal('git://bower.io/IndigoUnited/promptly/IndigoUnited/promptly'); + expect(resolver.getSource()).to.equal('https://bower.io/IndigoUnited/promptly/IndigoUnited/promptly'); next(); }) .done(); From 26902aec270a3b298c16f40c69f4c1aaa041c58a Mon Sep 17 00:00:00 2001 From: Evan Bowling Date: Tue, 3 May 2016 22:18:05 -0500 Subject: [PATCH 0939/1021] Update README.md to be more descriptive --- packages/bower-config/README.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index e0e3f9445..d9e5712cc 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -2,8 +2,21 @@ > The Bower config (`.bowerrc`) reader and writer. -The config spec can be read [here](https://docs.google.com/document/d/1APq7oA9tNao1UYWyOm8dKqlRP2blVkROYLZ2fLIjtWc/). - +[Bower](http://bower.io/) can be configured using JSON in a `.bowerrc` file. For example: + + { + "directory": "app/components/", + "analytics": false, + "timeout": 120000, + "registry": { + "search": [ + "http://localhost:8000", + "https://bower.herokuapp.com" + ] + } + } + +View the complete [.bowerrc specification](http://bower.io/docs/config/#bowerrc-specification) on the website for more details. Both the `bower.json` and `.bowerrc` specifications are maintained at [github.com/bower/spec](https://github.com/bower/spec). ## Install From 2e5acfe076667ebb96e2cefe174968eecd4a0570 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 4 May 2016 19:55:27 +0200 Subject: [PATCH 0940/1021] Remove `analytics` from example config --- packages/bower-config/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index d9e5712cc..34c513359 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -6,7 +6,6 @@ { "directory": "app/components/", - "analytics": false, "timeout": 120000, "registry": { "search": [ From e640d0ec5cb7de39e3d1e49b0802a8f20f73cc90 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 6 May 2016 11:57:26 +0200 Subject: [PATCH 0941/1021] Improve search / lookup command descriptions, closes #2280 --- lib/templates/json/help-lookup.json | 2 +- lib/templates/json/help-search.json | 2 +- lib/templates/json/help.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/templates/json/help-lookup.json b/lib/templates/json/help-lookup.json index 26080b709..f6f1c1304 100644 --- a/lib/templates/json/help-lookup.json +++ b/lib/templates/json/help-lookup.json @@ -1,6 +1,6 @@ { "command": "lookup", - "description": "Looks up a package URL by name.", + "description": "Look up a single package URL by name.", "usage": [ "lookup []" ], diff --git a/lib/templates/json/help-search.json b/lib/templates/json/help-search.json index 11059ffe0..92a55e7b5 100644 --- a/lib/templates/json/help-search.json +++ b/lib/templates/json/help-search.json @@ -1,6 +1,6 @@ { "command": "search", - "description": "Finds all packages or a specific package.", + "description": "Search for packages by name.", "usage": [ "search []" ], diff --git a/lib/templates/json/help.json b/lib/templates/json/help.json index 6525c9b08..d8aa42f40 100644 --- a/lib/templates/json/help.json +++ b/lib/templates/json/help.json @@ -12,10 +12,10 @@ "link": "Symlink a package folder", "list": "List local packages - and possible updates", "login": "Authenticate with GitHub and store credentials", - "lookup": "Look up a package URL by name", + "lookup": "Look up a single package URL by name", "prune": "Removes local extraneous packages", "register": "Register a package", - "search": "Search for a package by name", + "search": "Search for a packages by name", "update": "Update a local package", "uninstall": "Remove a local package", "unregister": "Remove a package from the registry", From 1f4372299acc52580803fb746b5a6cbedb13e8c6 Mon Sep 17 00:00:00 2001 From: Evan Bowling Date: Sun, 8 May 2016 11:39:45 -0500 Subject: [PATCH 0942/1021] Correct typo in command descriptions, followup for #2280 --- lib/templates/json/help.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/templates/json/help.json b/lib/templates/json/help.json index d8aa42f40..14d5a192c 100644 --- a/lib/templates/json/help.json +++ b/lib/templates/json/help.json @@ -15,7 +15,7 @@ "lookup": "Look up a single package URL by name", "prune": "Removes local extraneous packages", "register": "Register a package", - "search": "Search for a packages by name", + "search": "Search for packages by name", "update": "Update a local package", "uninstall": "Remove a local package", "unregister": "Remove a package from the registry", From 353a399f75b85ff9ea727ccc149de4ec4dc3ae9d Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 10 May 2016 10:46:07 +0200 Subject: [PATCH 0943/1021] Fix test & build for shorthand resolver --- test/core/resolverFactory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 426a7253d..96ff56f4b 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -622,7 +622,7 @@ describe('resolverFactory', function () { callFactory({ source: 'bower/bower' }) .then(function (resolver) { var config = { - shorthandResolver: 'git://bower.io/{{owner}}/{{package}}/{{shorthand}}' + shorthandResolver: 'https://bower.io/{{owner}}/{{package}}/{{shorthand}}' }; expect(resolver.getSource()).to.equal('https://github.com/bower/bower.git'); From eb27ae8fdca96b233028ea2a1d65c5b94e53e248 Mon Sep 17 00:00:00 2001 From: Evan Bowling Date: Mon, 30 May 2016 04:16:53 -0500 Subject: [PATCH 0944/1021] Added integration tests for installing nested components (#1513) (#2297) --- test/commands/install.js | 108 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/test/commands/install.js b/test/commands/install.js index 1888c2b98..01c8353d3 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -85,6 +85,23 @@ describe('bower install', function () { }); }); + it('does not write to bower.json if no --save flag is used', function () { + mainPackage.prepare(); + + tempDir.prepare({ + 'bower.json': { + name: 'test' + } + }); + + return helpers.run(install, [ + [mainPackage.path], { + } + ]).then(function () { + expect(tempDir.read('bower.json')).to.not.contain('dependencies'); + }); + }); + it('writes to bower.json if save config setting is set to true', function () { mainPackage.prepare(); @@ -507,6 +524,97 @@ describe('bower install', function () { }); }); + it('works if packages reference each other locally', function () { + mainPackage.prepare(); + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + dependencies : { + package: mainPackage.path + } + } + }).prepare(); + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3', + dependencies: { + package2: package2.path + } + } + }).prepare(); + + var installPackage = helpers.command('install', { + cwd: mainPackage.path + }); + var installPackage2 = helpers.command('install', { + cwd: package2.path + }); + var installPackage3 = helpers.command('install', { + cwd: package3.path + }); + return helpers.run(installPackage).then(function () { + return helpers.run(installPackage2).then(function () { + return helpers.run(installPackage3).then(function() { + expect(package2.exists('bower_components/package')).to.be(true); + expect(package3.exists('bower_components/package2')).to.be(true); + expect(package3.exists('bower_components/package')).to.be(true); + }); + }); + }); + }); + + it('works if packages are nested and reference each other locally', function () { + // root directory for nested components + var rootDir = new helpers.TempDir().prepare(); + + var package = new helpers.TempDir({ + 'bower.json': { + name: 'package' + } + }); + package.path=path.join(rootDir.path,'src/a/b'); + package.prepare(); + var package2 = new helpers.TempDir({ + 'bower.json': { + name: 'package2', + dependencies : { + package: package.path + } + } + }); + package2.path=path.join(rootDir.path,'src/a'); + package2.create(); // run create to avoid deleting nested directories + var package3 = new helpers.TempDir({ + 'bower.json': { + name: 'package3', + dependencies: { + package2: package2.path + } + } + }); + package3.path=rootDir.path; + package3.create(); // run create to avoid deleting nested directories + + var installPackage = helpers.command('install', { + cwd: package.path + }); + var installPackage2 = helpers.command('install', { + cwd: package2.path + }); + var installPackage3 = helpers.command('install', { + cwd: package3.path + }); + return helpers.run(installPackage).then(function () { + return helpers.run(installPackage2).then(function () { + return helpers.run(installPackage3).then(function() { + expect(package2.exists('bower_components/package')).to.be(true); + expect(package3.exists('bower_components/package2')).to.be(true); + expect(package3.exists('bower_components/package')).to.be(true); + }); + }); + }); + }); + it('recognizes proxy option in config', function (done) { this.timeout(10000); From 6ca5d434a43857400dcb0e08b7224a4eb25ab7df Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 2 Jun 2016 12:38:49 +0200 Subject: [PATCH 0945/1021] [docs] Change info at the top of readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0e8d493b..f2f27dea3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bower - A package manager for the web -> Bower needs resources for its maintenance. Please fill [this form](https://docs.google.com/forms/d/1i-Opb-uPdqUBBZQSbngv3Y3bfolG1gbBvtRLfxMnzRE/viewform?c=0&w=1) if you think you can help. +> Bower needs your help. You you're willing to help, please say hello to team@bower.io or [donate](https://salt.bountysource.com/teams/bower) [![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)](https://ci.appveyor.com/project/sheerun/bower/history) From 3235b3c0d3be20416db75743eec0a76621c8bfef Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 2 Jun 2016 13:36:10 +0200 Subject: [PATCH 0946/1021] Fix typo in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f2f27dea3..88317846a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Bower - A package manager for the web -> Bower needs your help. You you're willing to help, please say hello to team@bower.io or [donate](https://salt.bountysource.com/teams/bower) +> Bower needs your help. If you're willing to help, please say hello to team@bower.io or [donate](https://salt.bountysource.com/teams/bower) [![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) [![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)](https://ci.appveyor.com/project/sheerun/bower/history) From c6f7ec36de32afeeff2863f26066ef83ca554e8d Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 9 Jun 2016 20:29:26 +0200 Subject: [PATCH 0947/1021] Add issue template (#2305) --- .github/ISSUE_TEMPLATE.md | 60 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..8ddc53033 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,60 @@ + + +**Output of `bower -v`:** + +``` +(paste your output here) +``` + + +**Output of `npm -v`:** + +``` +(paste your output here) +``` + + +**Output of `node -v`:** + +``` +(paste your output here) +``` + +**Additional environment details (proxy, private registry, etc.):** + + + +**Steps to reproduce the issue:** +1. +2. +3. + + +**Describe the results you received:** + + +**Describe the results you expected:** + + +**Additional information you deem important (e.g. issue happens only occasionally):** From f6be8e5e287d7fce35b0c17b12e775abaf1ef53a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 9 Jun 2016 20:34:14 +0200 Subject: [PATCH 0948/1021] Improve issue template a little --- .github/ISSUE_TEMPLATE.md | 44 +++++++++++++-------------------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 8ddc53033..80c448114 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,41 +1,23 @@ - -**Output of `bower -v`:** - -``` -(paste your output here) -``` - - -**Output of `npm -v`:** +You do NOT have to include this information if this is a FEATURE REQUEST OR DISCUSSION -``` -(paste your output here) -``` +For more information about reporting bugs, see: +https://github.com/bower/bower/wiki/Report-a-Bug +--> -**Output of `node -v`:** +**Output of `bower -v && npm -v && node -v`:** ``` (paste your output here) @@ -46,15 +28,17 @@ You do NOT have to include this information if this is a FEATURE REQUEST **Steps to reproduce the issue:** + 1. 2. 3. - **Describe the results you received:** + **Describe the results you expected:** -**Additional information you deem important (e.g. issue happens only occasionally):** + +**Additional information:** From bcbff3271672cfac08de3b2ca58c632de899004a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 10 Jun 2016 16:40:46 +0200 Subject: [PATCH 0949/1021] Pass through eslint --- lib/commands/register.js | 2 +- lib/core/Manager.js | 2 +- test/commands/install.js | 10 +++++----- test/commands/version.js | 5 ++--- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/commands/register.js b/lib/commands/register.js index 72808d3de..db56a7352 100644 --- a/lib/commands/register.js +++ b/lib/commands/register.js @@ -10,7 +10,7 @@ function register(logger, name, source, config) { var force; var url; var githubSourceRegex = /^\w[\w-]*\/\w[\w-]*$/; - var getGithubUrl = function(source) { + var getGithubUrl = function (source) { return 'git@github.com:' + source + '.git'; }; diff --git a/lib/core/Manager.js b/lib/core/Manager.js index dac6333a9..73f4b3413 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -835,7 +835,7 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { }); choices = picks.map(function (pick, index) { return index + 1; }); - picksReleases = picks.map(function(pick) { return pick.pkgMeta._release; }); + picksReleases = picks.map(function (pick) { return pick.pkgMeta._release; }); return Q.nfcall(this._logger.prompt.bind(this._logger), { type: 'input', message: 'Answer', diff --git a/test/commands/install.js b/test/commands/install.js index 01c8353d3..e37059b26 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -554,7 +554,7 @@ describe('bower install', function () { }); return helpers.run(installPackage).then(function () { return helpers.run(installPackage2).then(function () { - return helpers.run(installPackage3).then(function() { + return helpers.run(installPackage3).then(function () { expect(package2.exists('bower_components/package')).to.be(true); expect(package3.exists('bower_components/package2')).to.be(true); expect(package3.exists('bower_components/package')).to.be(true); @@ -572,7 +572,7 @@ describe('bower install', function () { name: 'package' } }); - package.path=path.join(rootDir.path,'src/a/b'); + package.path = path.join(rootDir.path, 'src/a/b'); package.prepare(); var package2 = new helpers.TempDir({ 'bower.json': { @@ -582,7 +582,7 @@ describe('bower install', function () { } } }); - package2.path=path.join(rootDir.path,'src/a'); + package2.path = path.join(rootDir.path, 'src/a'); package2.create(); // run create to avoid deleting nested directories var package3 = new helpers.TempDir({ 'bower.json': { @@ -592,7 +592,7 @@ describe('bower install', function () { } } }); - package3.path=rootDir.path; + package3.path = rootDir.path; package3.create(); // run create to avoid deleting nested directories var installPackage = helpers.command('install', { @@ -606,7 +606,7 @@ describe('bower install', function () { }); return helpers.run(installPackage).then(function () { return helpers.run(installPackage2).then(function () { - return helpers.run(installPackage3).then(function() { + return helpers.run(installPackage3).then(function () { expect(package2.exists('bower_components/package')).to.be(true); expect(package3.exists('bower_components/package2')).to.be(true); expect(package3.exists('bower_components/package')).to.be(true); diff --git a/test/commands/version.js b/test/commands/version.js index b70087377..f666a5688 100644 --- a/test/commands/version.js +++ b/test/commands/version.js @@ -13,9 +13,6 @@ describe('bower version', function () { } }); - var packageWithoutTags = new helpers.TempDir({}); - - it('bumps patch version', function () { mainPackage.prepareGit(); @@ -109,6 +106,8 @@ describe('bower version', function () { }); it('assumes v0.0.0 when no tags exist', function () { + var packageWithoutTags = new helpers.TempDir({}); + packageWithoutTags.prepareGit(); packageWithoutTags.create({ 'index.js': 'console.log("hello, world");' From 16c134f0f9b094c1b6bf58db4dedd510661a52f1 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 10 Jun 2016 17:14:47 +0200 Subject: [PATCH 0950/1021] Update devDependencies --- package.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 47f03ddc6..b1331c864 100644 --- a/package.json +++ b/package.json @@ -67,24 +67,24 @@ }, "devDependencies": { "arr-diff": "^2.0.0", - "chai": "^1.10.0", - "coveralls": "^2.11.2", + "chai": "^3.5.0", + "coveralls": "^2.11.9", "expect.js": "^0.3.1", "grunt": "^1.0.1", "grunt-cli": "^1.1.0", "grunt-contrib-watch": "^1.0.0", - "grunt-eslint": "^18.0.0", - "grunt-exec": "sheerun/grunt-exec", + "grunt-eslint": "^18.1.0", + "grunt-exec": "^0.4.7", "grunt-simple-mocha": "^0.4.1", "in-publish": "^2.0.0", - "istanbul": "^0.3.5", - "load-grunt-tasks": "^2.0.0", - "mocha": "^2.1.0", + "istanbul": "^0.4.3", + "load-grunt-tasks": "^3.5.0", + "mocha": "^2.5.3", "multiline": "^1.0.2", - "nock": "^3.1.0", - "node-uuid": "^1.4.2", - "proxyquire": "^1.3.0", - "spawn-sync": "1.0.13", + "nock": "^7.7.2", + "node-uuid": "^1.4.7", + "proxyquire": "^1.7.9", + "spawn-sync": "1.0.15", "wrench": "^1.5.8" }, "scripts": { From 85e39cf190c6f0417975217817205bd5d5cfb105 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 10 Jun 2016 17:24:42 +0200 Subject: [PATCH 0951/1021] Try to fix svn tests --- test/packages-svn.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/packages-svn.js b/test/packages-svn.js index a0d2ab560..dabeca980 100644 --- a/test/packages-svn.js +++ b/test/packages-svn.js @@ -113,7 +113,7 @@ function createRelease(admin, dir, release, files) { }) // Attempt to delete tag, ignoring the error .then(function () { - cmd('svn', ['delete', dir + '/tags/' + release], { cwd: dir }) + return cmd('svn', ['delete', dir + '/tags/' + release], { cwd: dir }) .fail(function (err) {}); }) // Create files From e4f0295ef129d05972e42c80c7c8fb37ff88901a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 10 Jun 2016 17:37:53 +0200 Subject: [PATCH 0952/1021] Test node 4, 5, and 6 --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 575173225..614e95bf7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,9 @@ env: - NODE_VERSION=0.10 - NODE_VERSION=0.11 - NODE_VERSION=0.12 - - NODE_VERSION=4.0 - - NODE_VERSION=5.0 + - NODE_VERSION=4 + - NODE_VERSION=5 + - NODE_VERSION=6 install: - test $TRAVIS_OS_NAME = "osx" && brew install nvm && source $(brew --prefix nvm)/nvm.sh || test $TRAVIS_OS_NAME = "linux" From 1f6b32a48e0b0f2425985dabb5a3cb096fda9a24 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 10 Jun 2016 17:41:11 +0200 Subject: [PATCH 0953/1021] Test node 6 also on appveyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index c2892675a..291a78ead 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -13,12 +13,12 @@ environment: - nodejs_version: "0.12" - nodejs_version: "5" - nodejs_version: "4" + - nodejs_version: "6" # Allow failing jobs for bleeding-edge Node.js versions. matrix: allow_failures: - nodejs_version: "0.10" - - nodejs_version: "5" # Install scripts. (runs after repo cloning) install: From 684ab0c0a65562561a6be21652936a3390fbdec1 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Fri, 10 Jun 2016 20:48:44 +0200 Subject: [PATCH 0954/1021] Simplify travis configuration --- .travis.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 614e95bf7..d41ca46f8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,16 @@ sudo: false -env: - - NODE_VERSION=0.10 - - NODE_VERSION=0.11 - - NODE_VERSION=0.12 - - NODE_VERSION=4 - - NODE_VERSION=5 - - NODE_VERSION=6 +language: node_js + +node_js: + - "0.10" + - "0.11" + - "0.12" + - "4" + - "5" + - "6" install: - - test $TRAVIS_OS_NAME = "osx" && brew install nvm && source $(brew --prefix nvm)/nvm.sh || test $TRAVIS_OS_NAME = "linux" - - nvm install $NODE_VERSION - - npm install -g npm@^2.0.0 - node --version - npm --version - git --version From 2309cd80c6f1c372672aec9e697cf5902844dbe9 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 11 Jun 2016 02:49:22 +0200 Subject: [PATCH 0955/1021] Add missing return in promise --- lib/commands/version.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/commands/version.js b/lib/commands/version.js index 9cb672f27..92de54fd1 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -142,7 +142,7 @@ var driver = { message = message || tag; message = message.replace(/%s/g, tag); return Q.nfcall(execFile, 'git', ['commit', '-m', message, '--allow-empty'], {env: process.env, cwd: cwd}) .then(function () { - Q.nfcall(execFile, 'git', ['tag', tag, '-am', message], {env: process.env, cwd: cwd}); + return Q.nfcall(execFile, 'git', ['tag', tag, '-am', message], {env: process.env, cwd: cwd}); }); } } From 44eeb6052944742bf616acd5d744bad34832ee5b Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 12 Jun 2016 01:18:32 +0200 Subject: [PATCH 0956/1021] Improve appveyor.yml --- appveyor.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 291a78ead..4823cdb65 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,6 +2,9 @@ # http://www.appveyor.com/docs/appveyor-yml +# Set build version format here instead of in the admin panel. +version: "{build}" + # Fix line endings in Windows. (runs before repo cloning) init: - git config --global core.autocrlf input @@ -36,8 +39,8 @@ install: test_script: - cmd: npm run ci -# Don't actually build. -build: off +# Make clone much faster +shallow_clone: true -# Set build version format here instead of in the admin panel. -version: "{build}" +# Disable Visual Studio build +build: off From 89474004873edf859c0743fac72450a444fa7ce3 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 12 Jun 2016 01:19:50 +0200 Subject: [PATCH 0957/1021] Disable deploy in appveyor.yml --- appveyor.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 4823cdb65..32492d193 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -42,5 +42,6 @@ test_script: # Make clone much faster shallow_clone: true -# Disable Visual Studio build +# Disable Visual Studio build and deploy build: off +deploy: off From 8368539a939bb351e5c033941eead35b6ff2861a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 12 Jun 2016 01:40:45 +0200 Subject: [PATCH 0958/1021] Change appveyor badge to new project [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 88317846a..0b8485d6e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ > Bower needs your help. If you're willing to help, please say hello to team@bower.io or [donate](https://salt.bountysource.com/teams/bower) [![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) -[![Windows Build](https://ci.appveyor.com/api/projects/status/jr6vfra8w84plh2g/branch/master?svg=true)](https://ci.appveyor.com/project/sheerun/bower/history) +[![Windows Build](https://ci.appveyor.com/api/projects/status/8cjhgfa1d39s2qcy/branch/master?svg=true)](https://ci.appveyor.com/project/bower/bower/branch/master) [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) [![Discord chat](https://img.shields.io/badge/discord-join%20chat%20%E2%86%92-brightgreen.svg?style=flat)](https://discord.gg/0fFM7QF0KpZRh2cY) [![Issue Stats](http://issuestats.com/github/bower/bower/badge/pr?style=flat)](http://issuestats.com/github/bower/bower) From 2693bae8edee9fef40b4b0d7c1bcaf56e8c7d382 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 12 Jun 2016 14:04:28 +0200 Subject: [PATCH 0959/1021] Improve appveyor.yml --- appveyor.yml | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 32492d193..59d6f554f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,3 @@ -# Thanks for Grunt for template of this file! - # http://www.appveyor.com/docs/appveyor-yml # Set build version format here instead of in the admin panel. @@ -18,21 +16,15 @@ environment: - nodejs_version: "4" - nodejs_version: "6" -# Allow failing jobs for bleeding-edge Node.js versions. +# Finish on first failed build matrix: - allow_failures: - - nodejs_version: "0.10" + fast_finish: true -# Install scripts. (runs after repo cloning) +# Install node, display versions, install dependencies install: - # Get the latest stable version of Node 0.STABLE.latest - ps: Install-Product node $env:nodejs_version - # Output useful info for debugging. - - node --version - - npm --version - - git --version - - svn --version - # Install all dependencies + - node --version && npm --version + - git --version && svn --version - npm install # Post-install test scripts. @@ -45,3 +37,7 @@ shallow_clone: true # Disable Visual Studio build and deploy build: off deploy: off + +# Cache node modules, and refresh if package.json changes +cache: + - node_modules -> package.json From 9317bb6e332c0b482393cf969303cc5adcc3e05c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 12 Jun 2016 14:04:50 +0200 Subject: [PATCH 0960/1021] Rename .travis.yml to travis.yml --- .travis.yml => travis.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .travis.yml => travis.yml (100%) diff --git a/.travis.yml b/travis.yml similarity index 100% rename from .travis.yml rename to travis.yml From f26fe38c304aff87f5928c8f68e99f72ffeae70c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 12 Jun 2016 14:18:29 +0200 Subject: [PATCH 0961/1021] Fix CI badges --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0b8485d6e..c46802fda 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ > Bower needs your help. If you're willing to help, please say hello to team@bower.io or [donate](https://salt.bountysource.com/teams/bower) -[![Build Status](https://travis-ci.org/bower/bower.svg?branch=master)](https://travis-ci.org/bower/bower) -[![Windows Build](https://ci.appveyor.com/api/projects/status/8cjhgfa1d39s2qcy/branch/master?svg=true)](https://ci.appveyor.com/project/bower/bower/branch/master) +[![Unix CI](https://img.shields.io/travis/bower/bower/master.svg?maxAge=2592000)](https://travis-ci.org/bower/bower) +[![Windows CI](https://img.shields.io/appveyor/ci/bower/bower/master.svg)](https://ci.appveyor.com/project/bower/bower) [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) [![Discord chat](https://img.shields.io/badge/discord-join%20chat%20%E2%86%92-brightgreen.svg?style=flat)](https://discord.gg/0fFM7QF0KpZRh2cY) [![Issue Stats](http://issuestats.com/github/bower/bower/badge/pr?style=flat)](http://issuestats.com/github/bower/bower) From 58ddb591047a90d51cd20f6020d370d0a3848b20 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 12 Jun 2016 14:19:04 +0200 Subject: [PATCH 0962/1021] Revert "Rename .travis.yml to travis.yml" This reverts commit 9317bb6e332c0b482393cf969303cc5adcc3e05c. --- travis.yml => .travis.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename travis.yml => .travis.yml (100%) diff --git a/travis.yml b/.travis.yml similarity index 100% rename from travis.yml rename to .travis.yml From 8b6c8eeaa93fa1533daf7485726f49155369bb22 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 12 Jun 2016 14:22:08 +0200 Subject: [PATCH 0963/1021] Run tests also on 4.0 and 4.1 --- .travis.yml | 5 ++++- appveyor.yml | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d41ca46f8..443ca24b5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,9 @@ node_js: - "0.10" - "0.11" - "0.12" - - "4" + - "4.0" + - "4.1" + - "4.2" - "5" - "6" @@ -23,6 +25,7 @@ os: - linux matrix: + fast_finish: true allow_failures: - os: osx - env: "NODE_VERSION=0.11" diff --git a/appveyor.yml b/appveyor.yml index 59d6f554f..efe27f0bc 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,8 +12,10 @@ environment: matrix: - nodejs_version: "0.10" - nodejs_version: "0.12" + - nodejs_version: "4.0" + - nodejs_version: "4.1" + - nodejs_version: "4.2" - nodejs_version: "5" - - nodejs_version: "4" - nodejs_version: "6" # Finish on first failed build From 22bbb3fcaf3ff8e1fcf0eba4e7977ef1b770c624 Mon Sep 17 00:00:00 2001 From: Martin Page Date: Mon, 4 Jul 2016 22:31:06 +0100 Subject: [PATCH 0964/1021] Allow `@` to be used as a divider with cli: install and info. (#2322) --- lib/commands/info.js | 3 +++ lib/commands/install.js | 2 ++ test/commands/info.js | 13 +++++++++++++ test/commands/install.js | 9 +++++++++ 4 files changed, 27 insertions(+) diff --git a/lib/commands/info.js b/lib/commands/info.js index 850360ef8..28cac378b 100644 --- a/lib/commands/info.js +++ b/lib/commands/info.js @@ -9,6 +9,9 @@ function info(logger, endpoint, property, config) { return; } + // handle @ as version divider + endpoint = endpoint.replace('@', '#'); + var repository; var decEndpoint; diff --git a/lib/commands/install.js b/lib/commands/install.js index c3d0489e1..6e6b6fc55 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -16,6 +16,8 @@ function install(logger, endpoints, options, config) { // Convert endpoints to decomposed endpoints endpoints = endpoints || []; decEndpoints = endpoints.map(function (endpoint) { + // handle @ as version divider + endpoint = endpoint.replace('@', '#'); return endpointParser.decompose(endpoint); }); diff --git a/test/commands/info.js b/test/commands/info.js index 8dcc64696..60e39135c 100644 --- a/test/commands/info.js +++ b/test/commands/info.js @@ -49,4 +49,17 @@ describe('bower info', function () { }); }); }); + it('should handle @ as a divider', function () { + return helpers.run(info, [mainPackage.path + '@0.1.3']).spread(function (results) { + expect(results).to.eql( + { + name: 'package', + version: '0.1.3', + homepage: 'http://bower.io', + description: 'Hello world! Hello!' + } + ); + }); + + }); }); diff --git a/test/commands/install.js b/test/commands/install.js index e37059b26..c35b66744 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -726,4 +726,13 @@ describe('bower install', function () { expect(tempDir.read(path.join('bower_components', 'package', 'package.tar'))).to.contain('test'); }); }); + it('should handle @ as a divider', function () { + return helpers.run(install, [ + ['empty@1.0.1'], { + save: true + } + ]).then(function () { + expect(tempDir.readJson('bower.json').dependencies).to.eql({empty: '1.0.1'}); + }); + }); }); From d405917b4a6efdeeb24a2087680fd4163896ab8e Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 5 Jul 2016 11:16:26 +0200 Subject: [PATCH 0965/1021] Remove non-working issue stats --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index c46802fda..45c838f02 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,6 @@ [![Windows CI](https://img.shields.io/appveyor/ci/bower/bower/master.svg)](https://ci.appveyor.com/project/bower/bower) [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) [![Discord chat](https://img.shields.io/badge/discord-join%20chat%20%E2%86%92-brightgreen.svg?style=flat)](https://discord.gg/0fFM7QF0KpZRh2cY) -[![Issue Stats](http://issuestats.com/github/bower/bower/badge/pr?style=flat)](http://issuestats.com/github/bower/bower) -[![Issue Stats](http://issuestats.com/github/bower/bower/badge/issue?style=flat)](http://issuestats.com/github/bower/bower) From fc4c260de483b5703c35788793d02e4e26392836 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 6 Nov 2016 22:56:42 +0100 Subject: [PATCH 0966/1021] Update changelog --- CHANGELOG.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c421a6e5d..8c87f4ec7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## Unreleased + +- Allow to type the entire version when conflict occured, #2243 +- Allow `owner/reponame` shorthand for registering components, #2248 +- Allow single-char repo names and package names, #2249 +- Make `bower version` no longer honor `version` in bower.json, #2232 +- Add `postinstall` hook, #2252 +- Allow for `@` instead of `#` for `install` and `info` commands, #2322 +- Upgrade all bundled modules + ## 1.7.9 - 2016-04-05 - Show warnings for invalid bower.json fields @@ -83,7 +93,7 @@ https://github.com/npm/npm/issues/11227 - Update bower config - Loads the .bowerrc file from the cwd specified on the command line - Allow the use of environment variables in .bowerrc ([#41](https://github.com/bower/config/issues/41)) - - Allow for array notation in ENV variables ([#44](https://github.com/bower/config/issues/44)) + - Allow for array notation in ENV variables ([#44](https://github.com/bower/config/issues/44)) ## 1.6.9 - 2015-12-04 From 044896e70837f3a8381f19a1f215de0b0be34744 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 6 Nov 2016 23:03:56 +0100 Subject: [PATCH 0967/1021] Bump bower-config to 1.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b1331c864..0fda14cc9 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "dependencies": { "abbrev": "^1.0.5", "archy": "1.0.0", - "bower-config": "^1.3.1", + "bower-config": "^1.4.0", "bower-endpoint-parser": "^0.2.2", "bower-json": "^0.8.1", "bower-logger": "^0.2.2", From e60d236b25e133be3769f177424457b4937fc490 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 6 Nov 2016 23:04:07 +0100 Subject: [PATCH 0968/1021] Add bower-config changes to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c87f4ec7..6f8afe3b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- Change default shorthand resolver for github from `git://` to `https://` - Allow to type the entire version when conflict occured, #2243 - Allow `owner/reponame` shorthand for registering components, #2248 - Allow single-char repo names and package names, #2249 From 38501a0b93ec740b530fc254b5cd77715fd98cc9 Mon Sep 17 00:00:00 2001 From: Vytautas Jakutis Date: Mon, 7 Nov 2016 02:19:41 +0200 Subject: [PATCH 0969/1021] Fix handling of cached releases pluginResolverFactory (#2356) --- lib/core/resolvers/pluginResolverFactory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/resolvers/pluginResolverFactory.js b/lib/core/resolvers/pluginResolverFactory.js index 799203c8d..d751d1f51 100644 --- a/lib/core/resolvers/pluginResolverFactory.js +++ b/lib/core/resolvers/pluginResolverFactory.js @@ -109,7 +109,7 @@ function pluginResolverFactory(resolverFactory, bower) { throw createError('Resolver did not provide releases of package.'); } - var releases = this._releases = result; + var releases = that._releases = result; var versions = releases.filter(function (target) { return semver.clean(target.version); From 3209cda9755d0fc8d449913b6f179c08f3131359 Mon Sep 17 00:00:00 2001 From: Johannes Faigle Date: Mon, 7 Nov 2016 01:21:27 +0100 Subject: [PATCH 0970/1021] docs: Update package repository information (#2351) --- packages/bower-config/package.json | 2 +- packages/bower-endpoint-parser/package.json | 5 +---- packages/bower-json/package.json | 2 +- packages/bower-logger/package.json | 2 +- packages/bower-registry-client/package.json | 2 +- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/bower-config/package.json b/packages/bower-config/package.json index cc1f3f915..feac48807 100644 --- a/packages/bower-config/package.json +++ b/packages/bower-config/package.json @@ -4,7 +4,7 @@ "description": "The Bower config reader and writer.", "author": "Twitter", "license": "MIT", - "repository": "bower/config", + "repository": "https://github.com/bower/bower/tree/master/packages/bower-config", "main": "lib/Config", "homepage": "http://bower.io", "engines": { diff --git a/packages/bower-endpoint-parser/package.json b/packages/bower-endpoint-parser/package.json index aa726064c..145e25c58 100644 --- a/packages/bower-endpoint-parser/package.json +++ b/packages/bower-endpoint-parser/package.json @@ -9,10 +9,7 @@ "url": "https://github.com/bower/endpoint-parser/blob/master/LICENSE" } ], - "repository": { - "type": "git", - "url": "git://github.com/bower/endpoint-parser.git" - }, + "repository": "https://github.com/bower/bower/tree/master/packages/bower-endpoint-parser", "main": "index.js", "engines": { "node": ">=0.8.0" diff --git a/packages/bower-json/package.json b/packages/bower-json/package.json index a145b194a..e6187cbb8 100644 --- a/packages/bower-json/package.json +++ b/packages/bower-json/package.json @@ -4,7 +4,7 @@ "description": "Read bower.json files with semantics, normalisation, defaults and validation", "author": "Twitter", "license": "MIT", - "repository": "bower/json", + "repository": "https://github.com/bower/bower/tree/master/packages/bower-json", "main": "lib/json", "engines": { "node": ">=0.10.0" diff --git a/packages/bower-logger/package.json b/packages/bower-logger/package.json index a3c781907..26eed8722 100644 --- a/packages/bower-logger/package.json +++ b/packages/bower-logger/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/bower/logger/blob/master/LICENSE" } ], - "repository": "bower/logger", + "repository": "https://github.com/bower/bower/tree/master/packages/bower-logger", "main": "lib/Logger", "engines": { "node": ">=0.10.0" diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index e7eb56586..74c206fa0 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -4,7 +4,7 @@ "description": "Provides easy interaction with the Bower registry", "author": "Twitter", "license": "MIT", - "repository": "bower/registry-client", + "repository": "https://github.com/bower/bower/tree/master/packages/bower-registry-client", "main": "Client", "engines": { "node": ">=0.10.0" From 789622438461adce4d60a5fd94afec57f35b4884 Mon Sep 17 00:00:00 2001 From: GvS Date: Mon, 7 Nov 2016 00:27:14 +0000 Subject: [PATCH 0971/1021] Improve handling of non-semver versions in git resolver (#2316) --- lib/core/resolvers/GitResolver.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/resolvers/GitResolver.js b/lib/core/resolvers/GitResolver.js index 3c161a3f8..9f4917f60 100644 --- a/lib/core/resolvers/GitResolver.js +++ b/lib/core/resolvers/GitResolver.js @@ -206,7 +206,7 @@ GitResolver.prototype._savePkgMeta = function (meta) { version = semver.clean(this._resolution.tag); // Warn if the package meta version is different than the resolved one - if (typeof meta.version === 'string' && semver.neq(meta.version, version)) { + if (typeof meta.version === 'string' && semver.valid(meta.version) && semver.neq(meta.version, version)) { this._logger.warn('mismatch', 'Version declared in the json (' + meta.version + ') is different than the resolved one (' + version + ')', { resolution: this._resolution, pkgMeta: meta From bdabf6a4e61a38c5fa39c115c730392427b18569 Mon Sep 17 00:00:00 2001 From: "Leo.liang" Date: Mon, 7 Nov 2016 11:29:17 +1100 Subject: [PATCH 0972/1021] Show in warning message location of malformed bower.json (#2357) --- lib/util/readJson.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/util/readJson.js b/lib/util/readJson.js index 370cb8a10..09fc38fb6 100644 --- a/lib/util/readJson.js +++ b/lib/util/readJson.js @@ -19,7 +19,9 @@ function readJson(file, options) { if (options.logger) { var issues = bowerJson.getIssues(json); - + if (issues.warnings.length > 0){ + options.logger.warn('invalid-meta', 'for:' + jsonFile); + } issues.warnings.forEach(function (warning) { options.logger.warn('invalid-meta', warning); }); From cba4b2a4cd63f331d0b04982b6172de26bab95b9 Mon Sep 17 00:00:00 2001 From: Ali MoezGholami Date: Sun, 6 Nov 2016 18:48:41 -0600 Subject: [PATCH 0973/1021] Allow for removing components with url instead of name (#2368) --- lib/core/Project.js | 15 +++++++++++++++ test/commands/uninstall.js | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/lib/core/Project.js b/lib/core/Project.js index 2c4f34101..62f649b74 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -213,6 +213,20 @@ Project.prototype.update = function (names, options) { }); }; +function resolveUrlNames(names, flattened) +{ + for (var i = 0; i < names.length; i++) + if (! flattened[names[i]]) + { + var url = names[i].trim().replace(/\/$/, ''); + var packName; + for (packName in flattened) + if (! ( !flattened[packName].source)) + if (url == flattened[packName].source.trim().replace(/\/$/, '')) + names[i] = packName; + } +} + Project.prototype.uninstall = function (names, options) { var that = this; var packages = {}; @@ -230,6 +244,7 @@ Project.prototype.uninstall = function (names, options) { // Fill in the packages to be uninstalled .spread(function (json, tree, flattened) { var promise = Q.resolve(); + resolveUrlNames(names, flattened); names.forEach(function (name) { var decEndpoint = flattened[name]; diff --git a/test/commands/uninstall.js b/test/commands/uninstall.js index 5e02b7e0b..db3ecbb51 100644 --- a/test/commands/uninstall.js +++ b/test/commands/uninstall.js @@ -99,4 +99,21 @@ describe('bower uninstall', function () { }); }); + it('removes a project with url from absolute path', function () { + var targetPath = path.resolve(tempDir.path, 'other_directory/underscore'); + mkdirp.sync(targetPath); + fs.writeFileSync(path.join(targetPath, '.bower.json'), '{ "name": "underscore", "_source": "git://github.com/user/repo.git" }'); + + return helpers.run(uninstall, [['git://github.com/user/repo.git'], undefined, { + cwd: tempDir.path, + directory: path.resolve(tempDir.path, 'other_directory'), + interactive: true + }]) + .then(function () { + expect(function () { + fs.statSync(targetPath); + }).to.throwException(/no such file or directory/); + }); + }); + }); From f7c51544908457f6251f63d4b90c1102de720896 Mon Sep 17 00:00:00 2001 From: Guillermo Ignacio Enriquez Gutierrez Date: Mon, 7 Nov 2016 09:50:57 +0900 Subject: [PATCH 0974/1021] Fix ssl handling by not setting GIT_SSL_NO_VERIFY=false (#2361) --- lib/core/resolvers/GitResolver.js | 4 +++- test/core/resolvers/gitResolver.js | 9 +++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/core/resolvers/GitResolver.js b/lib/core/resolvers/GitResolver.js index 9f4917f60..9c64e7272 100644 --- a/lib/core/resolvers/GitResolver.js +++ b/lib/core/resolvers/GitResolver.js @@ -26,7 +26,9 @@ function GitResolver(decEndpoint, config, logger) { // anyway mkdirp.sync(config.storage.empty); process.env.GIT_TEMPLATE_DIR = config.storage.empty; - process.env.GIT_SSL_NO_VERIFY = (!config.strictSsl).toString(); + if (!config.strictSsl) { + process.env.GIT_SSL_NO_VERIFY = 'true'; + } process.env.GIT_TERMINAL_PROMPT = config.interactive ? '1' : '0'; Resolver.call(this, decEndpoint, config, logger); diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index 2ec33ad8f..92a4242e0 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -50,16 +50,17 @@ describe('GitResolver', function () { expect(process.env).to.not.have.property('GIT_SSL_NO_VERIFY'); resolver = new GitResolver(decEndpoint, defaultConfig(), logger); - expect(process.env).to.have.property('GIT_SSL_NO_VERIFY', 'false'); - delete process.env.GIT_SSL_NO_VERIFY; + expect(process.env).to.not.have.property('GIT_SSL_NO_VERIFY'); resolver = new GitResolver(decEndpoint, defaultConfig({strictSsl: false}), logger); expect(process.env).to.have.property('GIT_SSL_NO_VERIFY', 'true'); delete process.env.GIT_SSL_NO_VERIFY; + // git only checks the existence of GIT_SSL_NO_VERIFY. + // git does NOT check whether is true of false. + // Hence not exporting GIT_SSL_NO_VERIFY is effectively equivalent to 'false' resolver = new GitResolver(decEndpoint, defaultConfig({strictSsl: true}), logger); - expect(process.env).to.have.property('GIT_SSL_NO_VERIFY', 'false'); - delete process.env.GIT_SSL_NO_VERIFY; + expect(process.env).to.not.have.property('GIT_SSL_NO_VERIFY'); }); }); From 47cc2262e144b4355c2b026214f82ee17b169b82 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 7 Nov 2016 02:33:43 +0100 Subject: [PATCH 0975/1021] Download tar archives from https://github when possible (#2263) --- lib/core/resolvers/GitHubResolver.js | 14 +++----------- lib/core/resolvers/GitResolver.js | 10 +++++++++- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/core/resolvers/GitHubResolver.js b/lib/core/resolvers/GitHubResolver.js index 2644ecbcf..b9bb61ebd 100644 --- a/lib/core/resolvers/GitHubResolver.js +++ b/lib/core/resolvers/GitHubResolver.js @@ -29,9 +29,6 @@ function GitHubResolver(decEndpoint, config, logger) { this._source += '.git'; } - // Check if it's public - this._public = mout.string.startsWith(this._source, 'git://'); - // Use https:// rather than git:// if on a proxy if (this._config.proxy || this._config.httpsProxy) { this._source = this._source.replace('git://', 'https://'); @@ -49,14 +46,10 @@ mout.object.mixIn(GitHubResolver, GitRemoteResolver); // ----------------- GitHubResolver.prototype._checkout = function () { - // Only fully works with public repositories and tags - // Could work with https/ssh protocol but not with 100% certainty - if (!this._public || !this._resolution.tag) { - return GitRemoteResolver.prototype._checkout.call(this); - } - var msg; - var tarballUrl = 'https://github.com/' + this._org + '/' + this._repo + '/archive/' + this._resolution.tag + '.tar.gz'; + var name = this._resolution.tag || this._resolution.branch || this._resolution.commit; + var tarballUrl = 'https://github.com/' + this._org + '/' + this._repo + '/archive/' + name + '.tar.gz'; + var file = path.join(this._tempDir, 'archive.tar.gz'); var reqHeaders = {}; var that = this; @@ -121,7 +114,6 @@ GitHubResolver.prototype._checkout = function () { return that._cleanTempDir() .then(GitRemoteResolver.prototype._checkout.bind(that)); - }); }; diff --git a/lib/core/resolvers/GitResolver.js b/lib/core/resolvers/GitResolver.js index 9c64e7272..b34a839a7 100644 --- a/lib/core/resolvers/GitResolver.js +++ b/lib/core/resolvers/GitResolver.js @@ -26,10 +26,18 @@ function GitResolver(decEndpoint, config, logger) { // anyway mkdirp.sync(config.storage.empty); process.env.GIT_TEMPLATE_DIR = config.storage.empty; + if (!config.strictSsl) { process.env.GIT_SSL_NO_VERIFY = 'true'; } - process.env.GIT_TERMINAL_PROMPT = config.interactive ? '1' : '0'; + + if (!config.interactive) { + process.env.GIT_TERMINAL_PROMPT = '0'; + + if (!process.env.SSH_ASKPASS) { + process.env.SSH_ASKPASS = 'echo'; + } + } Resolver.call(this, decEndpoint, config, logger); From 80308a41a6a5bf0653ebc380dd11bbcfc6ae868d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 7 Nov 2016 10:34:39 +0100 Subject: [PATCH 0976/1021] Update changelog --- CHANGELOG.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f8afe3b7..f2b71f239 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,13 +2,19 @@ ## Unreleased -- Change default shorthand resolver for github from `git://` to `https://` -- Allow to type the entire version when conflict occured, #2243 -- Allow `owner/reponame` shorthand for registering components, #2248 -- Allow single-char repo names and package names, #2249 -- Make `bower version` no longer honor `version` in bower.json, #2232 -- Add `postinstall` hook, #2252 -- Allow for `@` instead of `#` for `install` and `info` commands, #2322 +- Download tar archives from GitHub when possible (#2263) + - Change default shorthand resolver for github from `git://` to `https://` +- Fix ssl handling by not setting GIT_SSL_NO_VERIFY=false (#2361) +- Allow for removing components with url instead of name (#2368) +- Show in warning message location of malformed bower.json (#2357) +- Improve handling of non-semver versions in git resolver (#2316) +- Fix handling of cached releases pluginResolverFactory (#2356) +- Allow to type the entire version when conflict occured (#2243) +- Allow `owner/reponame` shorthand for registering components (#2248) +- Allow single-char repo names and package names (#2249) +- Make `bower version` no longer honor `version` in bower.json (#2232) +- Add `postinstall` hook (#2252) +- Allow for `@` instead of `#` for `install` and `info` commands (#2322) - Upgrade all bundled modules ## 1.7.9 - 2016-04-05 From 89902a69199802c6d560520926bb930e5e485351 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 7 Nov 2016 10:46:10 +0100 Subject: [PATCH 0977/1021] Mark release in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2b71f239..da85d254a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 1.8.0 - 2016-11-07 - Download tar archives from GitHub when possible (#2263) - Change default shorthand resolver for github from `git://` to `https://` From b01243ac3c37f46fb7d43199c4201823cebbf816 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 7 Nov 2016 10:47:29 +0100 Subject: [PATCH 0978/1021] Fix eslint issues --- lib/util/readJson.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util/readJson.js b/lib/util/readJson.js index 09fc38fb6..4b3d51fb8 100644 --- a/lib/util/readJson.js +++ b/lib/util/readJson.js @@ -19,7 +19,7 @@ function readJson(file, options) { if (options.logger) { var issues = bowerJson.getIssues(json); - if (issues.warnings.length > 0){ + if (issues.warnings.length > 0) { options.logger.warn('invalid-meta', 'for:' + jsonFile); } issues.warnings.forEach(function (warning) { From bda400634c66cb85e6f5ff42b7f0d55c8ef3e71c Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Mon, 7 Nov 2016 10:53:30 +0100 Subject: [PATCH 0979/1021] Bump to 1.8.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0fda14cc9..6dbe15010 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.7.9", + "version": "1.8.0", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From b716bc4e3a06cfb8e500c012142ab00bcd9863d3 Mon Sep 17 00:00:00 2001 From: Eugene Kenny Date: Tue, 8 Nov 2016 08:11:29 +0000 Subject: [PATCH 0980/1021] Prefer exact versions when dissecting dependencies (#2371) --- lib/core/Manager.js | 11 +++++++++++ test/core/Manager.js | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index 73f4b3413..f1f9fcde4 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -587,6 +587,17 @@ Manager.prototype._dissect = function () { } } + // If they are equal and one of them is an exact target, + // give higher priority + if (!result) { + if (first.target === first.pkgMeta.version) { + return -1; + } + if (second.target === second.pkgMeta.version) { + return 1; + } + } + return result; }); diff --git a/test/core/Manager.js b/test/core/Manager.js index e1529291b..f47ec20c7 100644 --- a/test/core/Manager.js +++ b/test/core/Manager.js @@ -34,6 +34,31 @@ describe('Manager', function () { next(); }); + describe('resolve', function () { + it('prefers exact versions over ranges', function () { + manager._resolved = { + ember: [ + { + target: '>=1.4', + pkgMeta: { version: '2.7.0' } + }, + { + target: '2.7.0', + pkgMeta: { version: '2.7.0' } + } + ] + }; + + return manager.resolve().then(function () { + expect(manager._dissected).to.eql({ + ember: { + target: '2.7.0', + pkgMeta: { version: '2.7.0' } + } + }); + }); + }); + }); describe('_areCompatible', function () { describe('resolved is being fetched', function () { From 2c2e5309fd15e9b0dc76aed34a14511fbc5e97a3 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 22 Mar 2017 14:03:31 +0100 Subject: [PATCH 0981/1021] Run tests on node 7 as well --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 443ca24b5..2a270a9bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ node_js: - "4.2" - "5" - "6" + - "7" install: - node --version @@ -29,6 +30,7 @@ matrix: allow_failures: - os: osx - env: "NODE_VERSION=0.11" + - env: "NODE_VERSION=7" script: - grunt travis From aa6b51edc0159b8457775039718530cbdbaeeb0d Mon Sep 17 00:00:00 2001 From: Juan Olvera Date: Tue, 18 Apr 2017 18:12:36 -0500 Subject: [PATCH 0982/1021] Replace gitter references with discord on documentation (#2453) --- CONTRIBUTING.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7e17e9d3..26f61534e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ Bower is a large community project with many different developers contributing a ## Team Meetings -We communicate through a channel on slack: https://gitter.im/bower +We communicate through a channel on Discord https://discord.gg/0fFM7QF0KpZRh2cY If you'd like to attend the meetings, please fill the [support form](http://goo.gl/forms/P1ndzCNoiG), and you'll get an invite. @@ -29,9 +29,9 @@ The issue tracker is the preferred channel for [bug reports](#bugs), requests](#pull-requests), but please respect the following restrictions: * Please **do not** use the issue tracker for personal support requests. Use - [Stack Overflow](http://stackoverflow.com/questions/tagged/bower) - [Gitter Channel](https://gitter.im/bower/bower) - [Mailing List](http://groups.google.com/group/twitter-bower) + [Stack Overflow](http://stackoverflow.com/questions/tagged/bower), + [Discord Channel](https://discordapp.com/channels/119103197720739842/123728452816732160), + [Mailing List](http://groups.google.com/group/twitter-bower), (twitter-bower@googlegroups.com), or [#bower](http://webchat.freenode.net/?channels=bower) on Freenode. From 0bd318de53daf9dc3b52bfd7bc753d4d2c2c9948 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Fri, 19 May 2017 19:29:15 +0100 Subject: [PATCH 0983/1021] Add yarn and webpack recommendation (#2458) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 45c838f02..64dbda0b2 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ > Bower needs your help. If you're willing to help, please say hello to team@bower.io or [donate](https://salt.bountysource.com/teams/bower) +> ..psst! While Bower is maintained, we recommend [yarn](https://yarnpkg.com/) and [webpack](https://webpack.js.org/) for new front-end projects! + [![Unix CI](https://img.shields.io/travis/bower/bower/master.svg?maxAge=2592000)](https://travis-ci.org/bower/bower) [![Windows CI](https://img.shields.io/appveyor/ci/bower/bower/master.svg)](https://ci.appveyor.com/project/bower/bower) [![Coverage Status](https://img.shields.io/coveralls/bower/bower.svg)](https://coveralls.io/r/bower/bower?branch=master) From 765d8e739dc25bd16dffff856dccc26a8915aae8 Mon Sep 17 00:00:00 2001 From: Xavier Damman Date: Tue, 30 May 2017 12:15:09 -0400 Subject: [PATCH 0984/1021] Activating Open Collective (#2450) --- README.md | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++- package.json | 11 ++++++-- 2 files changed, 85 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 64dbda0b2..fd334a45b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Bower - A package manager for the web -> Bower needs your help. If you're willing to help, please say hello to team@bower.io or [donate](https://salt.bountysource.com/teams/bower) +[![Backers on Open Collective](https://opencollective.com/bower/backers/badge.svg)](#backers) +[![Sponsors on Open Collective](https://opencollective.com/bower/sponsors/badge.svg)](#sponsors) > ..psst! While Bower is maintained, we recommend [yarn](https://yarnpkg.com/) and [webpack](https://webpack.js.org/) for new front-end projects! @@ -119,8 +120,82 @@ Note that on Windows for tests to pass you need to configure Git before cloning: git config --global core.autocrlf input ``` + +## Backers + +Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/bower#backer)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Sponsors + +Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/bower#sponsor)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## License Copyright (c) 2016 Twitter and [other contributors](https://github.com/bower/bower/graphs/contributors) Licensed under the MIT License + diff --git a/package.json b/package.json index 6dbe15010..da4c0d721 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "mkdirp": "0.5.0", "mout": "^0.11.0", "nopt": "^3.0.1", + "opencollective": "^1.0.3", "opn": "^4.0.0", "p-throttler": "0.1.1", "promptly": "0.2.0", @@ -91,10 +92,16 @@ "test": "grunt test", "ci": "grunt travis", "coveralls": "coveralls", - "prepublish": "in-publish && echo 'You need to use \"grunt publish\" to publish bower' && false || not-in-publish" + "prepublish": "in-publish && echo 'You need to use \"grunt publish\" to publish bower' && false || not-in-publish", + "postinstall": "opencollective postinstall" }, "files": [ "bin", "lib" - ] + ], + "collective": { + "type": "opencollective", + "url": "https://opencollective.com/bower", + "logo": "https://opencollective.com/opencollective/logo.txt" + } } From 0d03374dab8cec0531d20c3360092874ae805b1c Mon Sep 17 00:00:00 2001 From: yanca018 Date: Mon, 14 Aug 2017 12:41:32 +0200 Subject: [PATCH 0985/1021] Update LICENSE (#2475) Update year to 2017 --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index f25dbe841..7c08091b3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016 Twitter and other contributors +Copyright (c) 2017 Twitter and other contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in From 0641167b96b18bf0a109a7ab6f142283ab0bdcb5 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 13 Sep 2017 18:55:23 +0200 Subject: [PATCH 0986/1021] Remove opencollective for now to prevent installation issues --- package.json | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index da4c0d721..6dbe15010 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,6 @@ "mkdirp": "0.5.0", "mout": "^0.11.0", "nopt": "^3.0.1", - "opencollective": "^1.0.3", "opn": "^4.0.0", "p-throttler": "0.1.1", "promptly": "0.2.0", @@ -92,16 +91,10 @@ "test": "grunt test", "ci": "grunt travis", "coveralls": "coveralls", - "prepublish": "in-publish && echo 'You need to use \"grunt publish\" to publish bower' && false || not-in-publish", - "postinstall": "opencollective postinstall" + "prepublish": "in-publish && echo 'You need to use \"grunt publish\" to publish bower' && false || not-in-publish" }, "files": [ "bin", "lib" - ], - "collective": { - "type": "opencollective", - "url": "https://opencollective.com/bower", - "logo": "https://opencollective.com/opencollective/logo.txt" - } + ] } From 6500b421ce02abba9259e08f8b31597984c3c83d Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 13 Sep 2017 18:59:52 +0200 Subject: [PATCH 0987/1021] Migrate bower.herokuapp.com to registry.bower.io --- packages/bower-config/README.md | 2 +- packages/bower-config/lib/util/defaults.js | 2 +- packages/bower-config/lib/util/expand.js | 2 +- packages/bower-config/test/test.js | 22 +++++----- packages/bower-json/test/test.js | 2 +- packages/bower-registry-client/test/Client.js | 40 +++++++++---------- test/commands/register.js | 2 +- 7 files changed, 36 insertions(+), 36 deletions(-) diff --git a/packages/bower-config/README.md b/packages/bower-config/README.md index 34c513359..5cc3179e9 100644 --- a/packages/bower-config/README.md +++ b/packages/bower-config/README.md @@ -10,7 +10,7 @@ "registry": { "search": [ "http://localhost:8000", - "https://bower.herokuapp.com" + "https://registry.bower.io" ] } } diff --git a/packages/bower-config/lib/util/defaults.js b/packages/bower-config/lib/util/defaults.js index 8cabc4cbe..3d58502d4 100644 --- a/packages/bower-config/lib/util/defaults.js +++ b/packages/bower-config/lib/util/defaults.js @@ -21,7 +21,7 @@ var userAgent = !proxy && !httpsProxy var defaults = { 'directory': 'bower_components', - 'registry': 'https://bower.herokuapp.com', + 'registry': 'https://registry.bower.io', 'shorthand-resolver': 'https://github.com/{{owner}}/{{package}}.git', 'tmp': paths.tmp, 'proxy': proxy, diff --git a/packages/bower-config/lib/util/expand.js b/packages/bower-config/lib/util/expand.js index 6dbeb2cbb..f3d453fd3 100644 --- a/packages/bower-config/lib/util/expand.js +++ b/packages/bower-config/lib/util/expand.js @@ -86,7 +86,7 @@ function expand(config) { publish: config.registry }; } else if (typeof config.registry === 'object') { - config.registry.default = config.registry.default || 'https://bower.herokuapp.com'; + config.registry.default = config.registry.default || 'https://registry.bower.io'; config.registry = { default: config.registry.default, diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index c41a1f438..967eaf3f2 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -12,12 +12,12 @@ describe('NPM Config on package.json', function () { var config = require('../lib/Config').read(null, {}); assert.deepEqual(config.registry, { - 'default': 'https://bower.herokuapp.com', + 'default': 'https://registry.bower.io', 'search': [ - 'https://bower.herokuapp.com' + 'https://registry.bower.io' ], - 'register': 'https://bower.herokuapp.com', - 'publish': 'https://bower.herokuapp.com' + 'register': 'https://registry.bower.io', + 'publish': 'https://registry.bower.io' }); }); @@ -38,12 +38,12 @@ describe('NPM Config on package.json', function () { var config = require('../lib/Config').read(null, { registry: { search: 'https://foobar' } }); assert.deepEqual(config.registry, { - 'default': 'https://bower.herokuapp.com', + 'default': 'https://registry.bower.io', 'search': [ 'https://foobar', ], - 'register': 'https://bower.herokuapp.com', - 'publish': 'https://bower.herokuapp.com' + 'register': 'https://registry.bower.io', + 'publish': 'https://registry.bower.io' }); }); @@ -70,12 +70,12 @@ describe('NPM Config on package.json', function () { assert.deepEqual(config, { 'directory': 'bower_components', 'registry': { - 'default': 'https://bower.herokuapp.com', + 'default': 'https://registry.bower.io', 'search': [ - 'https://bower.herokuapp.com' + 'https://registry.bower.io' ], - 'register': 'https://bower.herokuapp.com', - 'publish': 'https://bower.herokuapp.com' + 'register': 'https://registry.bower.io', + 'publish': 'https://registry.bower.io' }, 'shorthandResolver': 'https://github.com/{{owner}}/{{package}}.git', 'tmp': '/foo/bar', diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index 7be7d6abb..9f7cce31d 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -447,7 +447,7 @@ describe('.normalize', function () { describe('packages from bower registry', function () { var packageList, - packageListUrl = 'http://bower.herokuapp.com/packages'; + packageListUrl = 'http://registry.bower.io/packages'; this.timeout(60000); diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index 91cbdb34b..a25b6435f 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -8,7 +8,7 @@ var Config = require('bower-config'); describe('RegistryClient', function () { beforeEach(function () { - this.uri = 'https://bower.herokuapp.com'; + this.uri = 'https://registry.bower.io'; this.timeoutVal = 5000; this.registry = new RegistryClient(Config.read(process.cwd(), { strictSsl: false, @@ -104,7 +104,7 @@ describe('RegistryClient', function () { describe('cache', function () { beforeEach(function () { - nock('https://bower.herokuapp.com:443') + nock('https://registry.bower.io:443') .get('/packages/search/jquery') .replyWithFile(200, __dirname + '/fixtures/search.json'); @@ -114,7 +114,7 @@ describe('RegistryClient', function () { })); this.cacheDir = this.client._config.cache; - this.host = 'bower.herokuapp.com'; + this.host = 'registry.bower.io'; this.method = 'search'; this.pkg = 'jquery'; @@ -164,7 +164,7 @@ describe('RegistryClient', function () { // describe('calling the lookup instance method with argument', function () { beforeEach(function () { - nock('https://bower.herokuapp.com:443') + nock('https://registry.bower.io:443') .get('/packages/jquery') .reply(200, { name: 'jquery', @@ -260,7 +260,7 @@ describe('RegistryClient', function () { describe('calling the lookup instance method with three registries', function () { beforeEach(function () { - nock('https://bower.herokuapp.com:443') + nock('https://registry.bower.io:443') .get('/packages/jquery') .reply(404); @@ -283,7 +283,7 @@ describe('RegistryClient', function () { force: true, registry: { search: [ - 'https://bower.herokuapp.com', + 'https://registry.bower.io', 'http://custom-registry.com', 'http://custom-registry2.com' ] @@ -311,7 +311,7 @@ describe('RegistryClient', function () { it('should respect order', function (next) { this.registry._config.registry.search = [ - 'https://bower.herokuapp.com', + 'https://registry.bower.io', 'http://custom-registry2.com', 'http://custom-registry.com' ]; @@ -330,7 +330,7 @@ describe('RegistryClient', function () { // describe('calling the register instance method with argument', function () { beforeEach(function () { - nock('https://bower.herokuapp.com:443') + nock('https://registry.bower.io:443') .post('/packages', 'name=test-ba&url=git%3A%2F%2Fgithub.com%2Ftest-ba%2Ftest-ba.git') .reply(201); @@ -368,7 +368,7 @@ describe('RegistryClient', function () { describe('calling the register instance method without arguments', function () { beforeEach(function () { - nock('https://bower.herokuapp.com:443') + nock('https://registry.bower.io:443') .post('/packages', 'name=&url=') .reply(400); }); @@ -392,7 +392,7 @@ describe('RegistryClient', function () { this.accessToken = '12345678'; this.registry._config.accessToken = this.accessToken; - nock('https://bower.herokuapp.com:443') + nock('https://registry.bower.io:443') .delete('/packages/' + this.pkg + '?access_token=' + this.accessToken) .reply(204); }); @@ -420,7 +420,7 @@ describe('RegistryClient', function () { this.pkg = 'testfoo'; this.registry._config.accessToken = ''; - nock('https://bower.herokuapp.com:443') + nock('https://registry.bower.io:443') .delete('/packages/' + this.pkg) .reply(403); }); @@ -440,7 +440,7 @@ describe('RegistryClient', function () { this.accessToken = '12345678'; this.registry._config.accessToken = this.accessToken; - nock('https://bower.herokuapp.com:443') + nock('https://registry.bower.io:443') .delete('/packages/' + this.notpkg + '?access_token=' + this.accessToken) .reply(404); }); @@ -459,7 +459,7 @@ describe('RegistryClient', function () { // describe('calling the search instance method with argument', function () { beforeEach(function () { - nock('https://bower.herokuapp.com:443') + nock('https://registry.bower.io:443') .get('/packages/search/jquery') .replyWithFile(200, __dirname + '/fixtures/search.json'); @@ -505,7 +505,7 @@ describe('RegistryClient', function () { describe('calling the search instance method with two registries', function () { beforeEach(function () { - nock('https://bower.herokuapp.com:443') + nock('https://registry.bower.io:443') .get('/packages/search/jquery') .reply(200, []); @@ -526,7 +526,7 @@ describe('RegistryClient', function () { force: true, registry: { search: [ - 'https://bower.herokuapp.com', + 'https://registry.bower.io', 'http://custom-registry.com' ] } @@ -566,7 +566,7 @@ describe('RegistryClient', function () { describe('calling the search instance method without argument', function () { beforeEach(function () { - nock('https://bower.herokuapp.com:443') + nock('https://registry.bower.io:443') .get('/packages/search/') .reply(404); }); @@ -585,7 +585,7 @@ describe('RegistryClient', function () { // describe('calling the list instance method', function () { beforeEach(function () { - nock('https://bower.herokuapp.com:443') + nock('https://registry.bower.io:443') .get('/packages') .reply(200, [], {}); @@ -610,7 +610,7 @@ describe('RegistryClient', function () { describe('calling the list instance method with two registries', function () { beforeEach(function () { - nock('https://bower.herokuapp.com:443') + nock('https://registry.bower.io:443') .get('/packages') .reply(200, []); @@ -628,7 +628,7 @@ describe('RegistryClient', function () { force: true, registry: { search: [ - 'https://bower.herokuapp.com', + 'https://registry.bower.io', 'http://custom-registry.com' ] } @@ -669,7 +669,7 @@ describe('RegistryClient', function () { describe('calling the list instance method', function () { beforeEach(function () { - nock('https://bower.herokuapp.com:443') + nock('https://registry.bower.io:443') .get('/packages') .reply(200, [], {}); }); diff --git a/test/commands/register.js b/test/commands/register.js index 01f562313..4083373fe 100644 --- a/test/commands/register.js +++ b/test/commands/register.js @@ -124,7 +124,7 @@ describe('bower register', function () { return helpers.expectEvent(promise.logger, 'confirm') .spread(function (e) { expect(e.type).to.be('confirm'); - expect(e.message).to.be('Registering a package will make it installable via the registry (https://bower.herokuapp.com), continue?'); + expect(e.message).to.be('Registering a package will make it installable via the registry (https://registry.bower.io, continue?'); expect(e.default).to.be(true); }); }); From a969a9c5574480b25a05b9e4ae700ed650a598f4 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 14 Sep 2017 18:04:12 +0200 Subject: [PATCH 0988/1021] Bump bower-config --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6dbe15010..99cfb9806 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "dependencies": { "abbrev": "^1.0.5", "archy": "1.0.0", - "bower-config": "^1.4.0", + "bower-config": "^1.4.1", "bower-endpoint-parser": "^0.2.2", "bower-json": "^0.8.1", "bower-logger": "^0.2.2", From 975f9bdcdbb2ab50f694131e47070d49e64be5b1 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 14 Sep 2017 18:05:08 +0200 Subject: [PATCH 0989/1021] Lock dependencies --- yarn.lock | 2881 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2881 insertions(+) create mode 100644 yarn.lock diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..00a326ce8 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,2881 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +abbrev@1, abbrev@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" + +abbrev@1.0.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +acorn@^5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.2.tgz#911cb53e036807cf0fa778dc5d370fbd864246d7" + +ajv-keywords@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + +ajv@^4.7.0, ajv@^4.9.1: + version "4.11.8" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +ansi-escapes@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansicolors@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef" + +archy@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + +argparse@^1.0.2, argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + +array-filter@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + +array-map@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" + +array-reduce@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +assertion-error@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" + +async@1.x, async@^1.4.0, async@^1.5.0, async@~1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +async@^0.2.8: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + +async@^2.0.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" + dependencies: + lodash "^4.14.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws4@^1.2.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +binary@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" + dependencies: + buffers "~0.1.1" + chainsaw "~0.1.0" + +bl@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.1.tgz#cac328f7bee45730d404b692203fcb590e172d5e" + dependencies: + readable-stream "^2.0.5" + +bl@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.0.3.tgz#fc5421a28fd4226036c3b3891a66a25bc64d226e" + dependencies: + readable-stream "~2.0.5" + +body-parser@~1.14.0: + version "1.14.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.14.2.tgz#1015cb1fe2c443858259581db53332f8d0cf50f9" + dependencies: + bytes "2.2.0" + content-type "~1.0.1" + debug "~2.2.0" + depd "~1.1.0" + http-errors "~1.3.1" + iconv-lite "0.4.13" + on-finished "~2.3.0" + qs "5.2.0" + raw-body "~2.1.5" + type-is "~1.6.10" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +bower-config@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/bower-config/-/bower-config-1.4.1.tgz#85fd9df367c2b8dbbd0caa4c5f2bad40cd84c2cc" + dependencies: + graceful-fs "^4.1.3" + mout "^1.0.0" + optimist "^0.6.1" + osenv "^0.1.3" + untildify "^2.1.0" + +bower-endpoint-parser@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz#00b565adbfab6f2d35addde977e97962acbcb3f6" + +bower-json@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/bower-json/-/bower-json-0.8.1.tgz#96c14723241ae6466a9c52e16caa32623a883843" + dependencies: + deep-extend "^0.4.0" + ext-name "^3.0.0" + graceful-fs "^4.1.3" + intersect "^1.0.1" + +bower-logger@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/bower-logger/-/bower-logger-0.2.2.tgz#39be07e979b2fc8e03a94634205ed9422373d381" + +bower-registry-client@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/bower-registry-client/-/bower-registry-client-1.0.0.tgz#697c3499067549a106b49f26d03e6dd1017a9241" + dependencies: + async "^0.2.8" + graceful-fs "^4.0.0" + lru-cache "^2.3.0" + mkdirp "^0.3.5" + request "^2.51.0" + request-replay "^0.2.0" + rimraf "^2.2.0" + +boxen@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-0.3.1.tgz#a7d898243ae622f7abb6bb604d740a76c6a5461b" + dependencies: + chalk "^1.1.1" + filled-array "^1.0.0" + object-assign "^4.0.1" + repeating "^2.0.0" + string-width "^1.0.1" + widest-line "^1.0.0" + +brace-expansion@^1.0.0, brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +buffers@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +bytes@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.2.0.tgz#fd35464a403f6f9117c2de3609ecff9cae000588" + +bytes@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + +capture-stack-trace@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" + +cardinal@0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-0.4.4.tgz#ca5bb68a5b511b90fe93b9acea49bdee5c32bfe2" + dependencies: + ansicolors "~0.2.1" + redeyed "~0.4.0" + +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +"chai@>=1.9.2 <4.0.0", chai@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" + dependencies: + assertion-error "^1.0.1" + deep-eql "^0.1.3" + type-detect "^1.0.0" + +chainsaw@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" + dependencies: + traverse ">=0.3.0 <0.4" + +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3, chalk@~1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chmodr@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/chmodr/-/chmodr-1.0.2.tgz#04662b932d0f02ec66deaa2b0ea42811968e3eb9" + +chownr@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + +cli-cursor@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + +cli-width@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-1.1.1.tgz#a4d293ef67ebb7b88d4a4d42c0ccf00c4d1e366d" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +coffee-script@~1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.10.0.tgz#12938bcf9be1948fa006f92e0c4c9e81705108c0" + +colors@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +commander@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" + +commander@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" + +commander@^2.9.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.4.6, concat-stream@^1.4.7: + version "1.6.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +configstore@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-2.1.0.tgz#737a3a7036e9886102aa6099e47bb33ab1aba1a1" + dependencies: + dot-prop "^3.0.0" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + object-assign "^4.0.1" + os-tmpdir "^1.0.0" + osenv "^0.1.0" + uuid "^2.0.1" + write-file-atomic "^1.1.2" + xdg-basedir "^2.0.0" + +content-type@~1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +coveralls@^2.11.9: + version "2.13.1" + resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-2.13.1.tgz#d70bb9acc1835ec4f063ff9dac5423c17b11f178" + dependencies: + js-yaml "3.6.1" + lcov-parse "0.0.10" + log-driver "1.2.5" + minimist "1.2.0" + request "2.79.0" + +create-error-class@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + dependencies: + capture-stack-trace "^1.0.0" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + dependencies: + array-find-index "^1.0.1" + +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + dependencies: + es5-ext "^0.10.9" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +dateformat@~1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" + dependencies: + get-stdin "^4.0.1" + meow "^3.3.0" + +debug@2.2.0, debug@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +debug@^2.1.1, debug@^2.2.0: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + dependencies: + ms "2.0.0" + +decamelize@^1.0.0, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +decompress-zip@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/decompress-zip/-/decompress-zip-0.2.1.tgz#5c2a2d06136f26ebb458453c2efb2ead8b593fed" + dependencies: + binary "^0.3.0" + graceful-fs "^4.1.3" + mkpath "^0.1.0" + nopt "^3.0.1" + q "^1.1.2" + readable-stream "^1.1.8" + touch "0.0.3" + +deep-eql@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" + dependencies: + type-detect "0.1.1" + +deep-equal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + +deep-extend@^0.4.0, deep-extend@~0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" + +deep-extend@~0.2.5: + version "0.2.11" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.2.11.tgz#7a16ba69729132340506170494bc83f7076fe08f" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +depd@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" + +destroy@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + +diff@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" + +doctrine@^1.2.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +dot-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" + dependencies: + is-obj "^1.0.0" + +duplexer2@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + dependencies: + readable-stream "^2.0.2" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" + dependencies: + once "^1.4.0" + +ends-with@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ends-with/-/ends-with-0.2.0.tgz#2f9da98d57a50cfda4571ce4339000500f4e6b8a" + +error-ex@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + dependencies: + is-arrayish "^0.2.1" + +es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: + version "0.10.30" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.30.tgz#7141a16836697dbabfaaaeee41495ce29f52c939" + dependencies: + es6-iterator "2" + es6-symbol "~3.1" + +es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" + dependencies: + d "1" + es5-ext "^0.10.14" + es6-symbol "^3.1" + +es6-map@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-weak-map@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + dependencies: + d "1" + es5-ext "^0.10.14" + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + +escape-string-regexp@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +escodegen@1.8.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +escope@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint@^2.0.0: + version "2.13.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-2.13.1.tgz#e4cc8fa0f009fb829aaae23855a29360be1f6c11" + dependencies: + chalk "^1.1.3" + concat-stream "^1.4.6" + debug "^2.1.1" + doctrine "^1.2.2" + es6-map "^0.1.3" + escope "^3.6.0" + espree "^3.1.6" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^1.1.1" + glob "^7.0.3" + globals "^9.2.0" + ignore "^3.1.2" + imurmurhash "^0.1.4" + inquirer "^0.12.0" + is-my-json-valid "^2.10.0" + is-resolvable "^1.0.0" + js-yaml "^3.5.1" + json-stable-stringify "^1.0.0" + levn "^0.3.0" + lodash "^4.0.0" + mkdirp "^0.5.0" + optionator "^0.8.1" + path-is-absolute "^1.0.0" + path-is-inside "^1.0.1" + pluralize "^1.2.1" + progress "^1.1.8" + require-uncached "^1.0.2" + shelljs "^0.6.0" + strip-json-comments "~1.0.1" + table "^3.7.8" + text-table "~0.2.0" + user-home "^2.0.0" + +espree@^3.1.6: + version "3.5.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.0.tgz#98358625bdd055861ea27e2867ea729faf463d8d" + dependencies: + acorn "^5.1.1" + acorn-jsx "^3.0.0" + +esprima@2.7.x, esprima@^2.6.0, esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + +esprima@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + +esprima@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad" + +esrecurse@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" + dependencies: + estraverse "^4.1.0" + object-assign "^4.0.1" + +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + +estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + dependencies: + d "1" + es5-ext "~0.10.14" + +eventemitter2@~0.4.13: + version "0.4.14" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab" + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + +exit@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + +expect.js@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/expect.js/-/expect.js-0.3.1.tgz#b0a59a0d2eff5437544ebf0ceaa6015841d09b5b" + +ext-list@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" + dependencies: + mime-db "^1.28.0" + +ext-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-3.0.0.tgz#07e4418737cb1f513c32c6ea48d8b8c8e0471abb" + dependencies: + ends-with "^0.2.0" + ext-list "^2.0.0" + meow "^3.1.0" + sort-keys-length "^1.0.0" + +extend@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +extsprintf@1.3.0, extsprintf@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +faye-websocket@~0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + dependencies: + websocket-driver ">=0.5.1" + +figures@^1.3.5: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +file-entry-cache@^1.1.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-1.3.1.tgz#44c61ea607ae4be9c1402f41f44270cbfe334ff8" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +fill-keys@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/fill-keys/-/fill-keys-1.0.2.tgz#9a8fa36f4e8ad634e3bf6b4f3c8882551452eb20" + dependencies: + is-object "~1.0.1" + merge-descriptors "~1.0.0" + +filled-array@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/filled-array/-/filled-array-1.1.0.tgz#c3c4f6c663b923459a9aa29912d2d031f1507f84" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +findup-sync@^0.3.0, findup-sync@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.3.0.tgz#37930aa5d816b777c03445e1966cc6790a4c0b16" + dependencies: + glob "~5.0.0" + +flat-cache@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~1.0.0-rc3: + version "1.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.1.tgz#ae315db9a4907fa065502304a66d7733475ee37c" + dependencies: + async "^2.0.1" + combined-stream "^1.0.5" + mime-types "^2.1.11" + +form-data@~2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +fs-write-stream-atomic@1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.8.tgz#e49aaddf288f87d46ff9e882f216a13abc40778b" + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fstream-ignore@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.3: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +gaze@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.2.tgz#847224677adb8870d679257ed3388fdb61e40105" + dependencies: + globule "^1.0.0" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + dependencies: + is-property "^1.0.0" + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + +getobject@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/getobject/-/getobject-0.1.0.tgz#047a449789fa160d018f5486ed91320b6ec7885c" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + +github@^0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/github/-/github-0.2.4.tgz#24fa7f0e13fa11b946af91134c51982a91ce538b" + dependencies: + mime "^1.2.11" + +glob@3.2.11: + version "3.2.11" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" + dependencies: + inherits "2" + minimatch "0.3" + +glob@^4.3.2: + version "4.5.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "^2.0.1" + once "^1.3.0" + +glob@^5.0.15, glob@~5.0.0: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.3, glob@^7.0.5, glob@~7.1.1: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@~7.0.0: + version "7.0.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^9.2.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globule@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.0.tgz#1dc49c6822dd9e8a2fa00ba2a295006e8664bd09" + dependencies: + glob "~7.1.1" + lodash "~4.17.4" + minimatch "~3.0.2" + +got@^5.0.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-5.7.1.tgz#5f81635a61e4a6589f180569ea4e381680a51f35" + dependencies: + create-error-class "^3.0.1" + duplexer2 "^0.1.4" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + node-status-codes "^1.0.0" + object-assign "^4.0.1" + parse-json "^2.1.0" + pinkie-promise "^2.0.0" + read-all-stream "^3.0.0" + readable-stream "^2.0.5" + timed-out "^3.0.0" + unzip-response "^1.0.2" + url-parse-lax "^1.0.0" + +graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + +grunt-cli@^1.1.0, grunt-cli@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/grunt-cli/-/grunt-cli-1.2.0.tgz#562b119ebb069ddb464ace2845501be97b35b6a8" + dependencies: + findup-sync "~0.3.0" + grunt-known-options "~1.1.0" + nopt "~3.0.6" + resolve "~1.1.0" + +grunt-contrib-watch@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/grunt-contrib-watch/-/grunt-contrib-watch-1.0.0.tgz#84a1a7a1d6abd26ed568413496c73133e990018f" + dependencies: + async "^1.5.0" + gaze "^1.0.0" + lodash "^3.10.1" + tiny-lr "^0.2.1" + +grunt-eslint@^18.1.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/grunt-eslint/-/grunt-eslint-18.1.0.tgz#ea700e220ecddf962ae8c317f15ebedb65a97c86" + dependencies: + chalk "^1.0.0" + eslint "^2.0.0" + +grunt-exec@^0.4.7: + version "0.4.7" + resolved "https://registry.yarnpkg.com/grunt-exec/-/grunt-exec-0.4.7.tgz#40051ffa4eb0c9657e053b95e88d44352a1c2c25" + +grunt-known-options@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/grunt-known-options/-/grunt-known-options-1.1.0.tgz#a4274eeb32fa765da5a7a3b1712617ce3b144149" + +grunt-legacy-log-utils@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/grunt-legacy-log-utils/-/grunt-legacy-log-utils-1.0.0.tgz#a7b8e2d0fb35b5a50f4af986fc112749ebc96f3d" + dependencies: + chalk "~1.1.1" + lodash "~4.3.0" + +grunt-legacy-log@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/grunt-legacy-log/-/grunt-legacy-log-1.0.0.tgz#fb86f1809847bc07dc47843f9ecd6cacb62df2d5" + dependencies: + colors "~1.1.2" + grunt-legacy-log-utils "~1.0.0" + hooker "~0.2.3" + lodash "~3.10.1" + underscore.string "~3.2.3" + +grunt-legacy-util@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/grunt-legacy-util/-/grunt-legacy-util-1.0.0.tgz#386aa78dc6ed50986c2b18957265b1b48abb9b86" + dependencies: + async "~1.5.2" + exit "~0.1.1" + getobject "~0.1.0" + hooker "~0.2.3" + lodash "~4.3.0" + underscore.string "~3.2.3" + which "~1.2.1" + +grunt-simple-mocha@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/grunt-simple-mocha/-/grunt-simple-mocha-0.4.1.tgz#579449249eaf0a81878fa72f3edab5145d45fd77" + dependencies: + mocha "^2.3.4" + +grunt@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/grunt/-/grunt-1.0.1.tgz#e8778764e944b18f32bb0f10b9078475c9dfb56b" + dependencies: + coffee-script "~1.10.0" + dateformat "~1.0.12" + eventemitter2 "~0.4.13" + exit "~0.1.1" + findup-sync "~0.3.0" + glob "~7.0.0" + grunt-cli "~1.2.0" + grunt-known-options "~1.1.0" + grunt-legacy-log "~1.0.0" + grunt-legacy-util "~1.0.0" + iconv-lite "~0.4.13" + js-yaml "~3.5.2" + minimatch "~3.0.0" + nopt "~3.0.6" + path-is-absolute "~1.0.0" + rimraf "~2.2.8" + +handlebars@^4.0.1, handlebars@^4.0.5: + version "4.0.10" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f" + dependencies: + async "^1.4.0" + optimist "^0.6.1" + source-map "^0.4.4" + optionalDependencies: + uglify-js "^2.6" + +har-schema@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + +har-validator@~2.0.2, har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + +har-validator@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + dependencies: + ajv "^4.9.1" + har-schema "^1.0.5" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +hawk@~3.1.0, hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +hooker@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/hooker/-/hooker-0.2.3.tgz#b834f723cc4a242aa65963459df6d984c5d3d959" + +hosted-git-info@^2.1.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" + +http-errors@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.3.1.tgz#197e22cdebd4198585e8694ef6786197b91ed942" + dependencies: + inherits "~2.0.1" + statuses "1" + +http-parser-js@>=0.4.0: + version "0.4.6" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.6.tgz#195273f58704c452d671076be201329dd341dc55" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +iconv-lite@0.4.13: + version "0.4.13" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" + +iconv-lite@~0.4.13: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + +ignore@^3.1.2: + version "3.3.5" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.5.tgz#c4e715455f6073a8d7e5dae72d2fc9d71663dba6" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +in-publish@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +ini@~1.3.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + +inquirer@0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.10.0.tgz#48cd3e23f8d989a52d47dc5e10ec75324387e908" + dependencies: + ansi-escapes "^1.1.0" + ansi-regex "^2.0.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^1.0.1" + figures "^1.3.5" + lodash "^3.3.1" + readline2 "^1.0.1" + run-async "^0.1.0" + rx-lite "^3.1.2" + strip-ansi "^3.0.0" + through "^2.3.6" + +inquirer@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + dependencies: + ansi-escapes "^1.1.0" + ansi-regex "^2.0.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + figures "^1.3.5" + lodash "^4.3.0" + readline2 "^1.0.1" + run-async "^0.1.0" + rx-lite "^3.1.2" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + +intersect@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/intersect/-/intersect-1.0.1.tgz#332650e10854d8c0ac58c192bdc27a8bf7e7a30c" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-buffer@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + +is-object@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + dependencies: + path-is-inside "^1.0.1" + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + +is-resolvable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" + dependencies: + tryit "^1.0.1" + +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + +is-root@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-root/-/is-root-1.0.0.tgz#07b6c233bc394cd9d02ba15c966bd6660d6342d5" + +is-stream@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +istanbul@^0.4.3: + version "0.4.5" + resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" + dependencies: + abbrev "1.0.x" + async "1.x" + escodegen "1.8.x" + esprima "2.7.x" + glob "^5.0.15" + handlebars "^4.0.1" + js-yaml "3.x" + mkdirp "0.5.x" + nopt "3.x" + once "1.x" + resolve "1.1.x" + supports-color "^3.1.0" + which "^1.1.1" + wordwrap "^1.0.0" + +jade@0.26.3: + version "0.26.3" + resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c" + dependencies: + commander "0.6.1" + mkdirp "0.3.0" + +js-yaml@3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30" + dependencies: + argparse "^1.0.7" + esprima "^2.6.0" + +js-yaml@3.x, js-yaml@^3.5.1: + version "3.10.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@~3.5.2: + version "3.5.5" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.5.5.tgz#0377c38017cabc7322b0d1fbcd25a491641f2fbe" + dependencies: + argparse "^1.0.2" + esprima "^2.6.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +junk@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/junk/-/junk-1.0.3.tgz#87be63488649cbdca6f53ab39bec9ccd2347f592" + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +latest-version@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-2.0.0.tgz#56f8d6139620847b8017f8f1f4d78e211324168b" + dependencies: + package-json "^2.0.0" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +lcov-parse@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +livereload-js@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.2.2.tgz#6c87257e648ab475bc24ea257457edcc1f8d0bc2" + +load-grunt-tasks@^3.5.0: + version "3.5.2" + resolved "https://registry.yarnpkg.com/load-grunt-tasks/-/load-grunt-tasks-3.5.2.tgz#0728561180fd20ff8a6927505852fc58aaea0c88" + dependencies: + arrify "^1.0.0" + multimatch "^2.0.0" + pkg-up "^1.0.0" + resolve-pkg "^0.1.0" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +lockfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.3.tgz#2638fc39a0331e9cac1a04b71799931c9c50df79" + +lodash@^3.10.1, lodash@^3.3.1, lodash@~3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + +lodash@^4.0.0, lodash@^4.14.0, lodash@^4.3.0, lodash@~4.17.4: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +lodash@~4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.3.0.tgz#efd9c4a6ec53f3b05412429915c3e4824e4d25a4" + +log-driver@1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + +lru-cache@2, lru-cache@^2.3.0, lru-cache@^2.5.0: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + +md5-hex@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" + dependencies: + md5-o-matic "^0.1.1" + +md5-o-matic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + +meow@^3.1.0, meow@^3.3.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-descriptors@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + +mime-db@^1.28.0, mime-db@~1.30.0: + version "1.30.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" + +mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.7: + version "2.1.17" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" + dependencies: + mime-db "~1.30.0" + +mime@^1.2.11: + version "1.4.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.0.tgz#69e9e0db51d44f2a3b56e48b7817d7d137f1a343" + +minimatch@0.3: + version "0.3.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.0, minimatch@~3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimatch@^2.0.1: + version "2.0.10" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" + dependencies: + brace-expansion "^1.0.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@1.2.0, minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +minimist@~0.0.1, minimist@~0.0.7: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + +mkdirp@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" + +mkdirp@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12" + dependencies: + minimist "0.0.8" + +mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +mkdirp@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7" + +mkpath@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/mkpath/-/mkpath-0.1.0.tgz#7554a6f8d871834cc97b5462b122c4c124d6de91" + +mocha@^2.3.4, mocha@^2.5.3: + version "2.5.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-2.5.3.tgz#161be5bdeb496771eb9b35745050b622b5aefc58" + dependencies: + commander "2.3.0" + debug "2.2.0" + diff "1.4.0" + escape-string-regexp "1.0.2" + glob "3.2.11" + growl "1.9.2" + jade "0.26.3" + mkdirp "0.5.1" + supports-color "1.2.0" + to-iso-string "0.0.2" + +module-not-found-error@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/module-not-found-error/-/module-not-found-error-1.0.1.tgz#cf8b4ff4f29640674d6cdd02b0e3bc523c2bbdc0" + +mout@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/mout/-/mout-0.11.1.tgz#ba3611df5f0e5b1ffbfd01166b8f02d1f5fa2b99" + +mout@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mout/-/mout-1.0.0.tgz#9bdf1d4af57d66d47cb353a6335a3281098e1501" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +multiline@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/multiline/-/multiline-1.0.2.tgz#69b1f25ff074d2828904f244ddd06b7d96ef6c93" + dependencies: + strip-indent "^1.0.0" + +multimatch@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +mute-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" + +mute-stream@~0.0.4: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + +nested-error-stacks@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.0.0.tgz#98b2ffaefb4610fa3936f1e71435d30700de2840" + dependencies: + inherits "~2.0.1" + +nock@^7.7.2: + version "7.7.3" + resolved "https://registry.yarnpkg.com/nock/-/nock-7.7.3.tgz#d0600980a4443edf6e50b5ed3314602cb7ccc489" + dependencies: + chai ">=1.9.2 <4.0.0" + debug "^2.2.0" + deep-equal "^1.0.0" + json-stringify-safe "^5.0.1" + lodash "^3.10.1" + mkdirp "^0.5.0" + propagate "0.3.x" + qs "^6.0.2" + +node-status-codes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-status-codes/-/node-status-codes-1.0.0.tgz#5ae5541d024645d32a58fcddc9ceecea7ae3ac2f" + +node-uuid@^1.4.7, node-uuid@~1.4.7: + version "1.4.8" + resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" + +nopt@3.x, nopt@^3.0.1, nopt@~3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +oauth-sign@~0.8.0, oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + +once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + +opn@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optionator@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-shim@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" + +os-tmpdir@^1.0.0, os-tmpdir@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.0, osenv@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-throttler@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/p-throttler/-/p-throttler-0.1.1.tgz#15246409d225d3eefca85c50de710a83a78cca6a" + dependencies: + q "~0.9.2" + +package-json@^2.0.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-2.4.0.tgz#0d15bd67d1cbbddbb2ca222ff2edb86bcb31a8bb" + dependencies: + got "^5.0.0" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +parse-json@^2.1.0, parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parseurl@~1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-is-absolute@^1.0.0, path-is-absolute@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkg-up@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26" + dependencies: + find-up "^1.0.0" + +pluralize@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + +promptly@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/promptly/-/promptly-0.2.0.tgz#73ef200fa8329d5d3a8df41798950b8646ca46d9" + dependencies: + read "~1.0.4" + +propagate@0.3.x: + version "0.3.1" + resolved "https://registry.yarnpkg.com/propagate/-/propagate-0.3.1.tgz#e3a84404a7ece820dd6bbea9f6d924e3135ae09c" + +proxyquire@^1.7.9: + version "1.8.0" + resolved "https://registry.yarnpkg.com/proxyquire/-/proxyquire-1.8.0.tgz#02d514a5bed986f04cbb2093af16741535f79edc" + dependencies: + fill-keys "^1.0.2" + module-not-found-error "^1.0.0" + resolve "~1.1.7" + +pump@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.2.tgz#3b3ee6512f94f0e575538c17995f9f16990a5d51" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +q@^1.1.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" + +q@~0.9.2: + version "0.9.7" + resolved "https://registry.yarnpkg.com/q/-/q-0.9.7.tgz#4de2e6cb3b29088c9e4cbc03bf9d42fb96ce2f75" + +qs@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.0.tgz#a9f31142af468cb72b25b30136ba2456834916be" + +qs@^6.0.2: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + +qs@~5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-5.1.0.tgz#4d932e5c7ea411cca76a312d39a606200fd50cd9" + +qs@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.1.tgz#801fee030e0b9450d6385adc48a4cc55b44aedfc" + +qs@~6.3.0: + version "6.3.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" + +qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + +raw-body@~2.1.5: + version "2.1.7" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.1.7.tgz#adfeace2e4fb3098058014d08c072dcc59758774" + dependencies: + bytes "2.4.0" + iconv-lite "0.4.13" + unpipe "1.0.0" + +rc@^1.0.1, rc@^1.1.6: + version "1.2.1" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +rc@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.0.3.tgz#51bf28d21f13a9324528a9633460161ad9a39f77" + dependencies: + deep-extend "~0.2.5" + ini "~1.3.0" + minimist "~0.0.7" + strip-json-comments "0.1.x" + +read-all-stream@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/read-all-stream/-/read-all-stream-3.1.0.tgz#35c3e177f2078ef789ee4bfafa4373074eaef4fa" + dependencies: + pinkie-promise "^2.0.0" + readable-stream "^2.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read@~1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + dependencies: + mute-stream "~0.0.4" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.2.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + safe-buffer "~5.1.1" + string_decoder "~1.0.3" + util-deprecate "~1.0.1" + +readable-stream@^1.1.8: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readline2@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + mute-stream "0.0.5" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +redeyed@~0.4.0: + version "0.4.4" + resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-0.4.4.tgz#37e990a6f2b21b2a11c2e6a48fd4135698cba97f" + dependencies: + esprima "~1.0.4" + +registry-auth-token@^3.0.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006" + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + dependencies: + rc "^1.0.1" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +request-progress@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-0.3.1.tgz#0721c105d8a96ac6b2ce8b2c89ae2d5ecfcf6b3a" + dependencies: + throttleit "~0.0.2" + +request-replay@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/request-replay/-/request-replay-0.2.0.tgz#9b693a5d118b39f5c596ead5ed91a26444057f60" + dependencies: + retry "~0.6.0" + +request@2.67.0: + version "2.67.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.67.0.tgz#8af74780e2bf11ea0ae9aa965c11f11afd272742" + dependencies: + aws-sign2 "~0.6.0" + bl "~1.0.0" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~1.0.0-rc3" + har-validator "~2.0.2" + hawk "~3.1.0" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + node-uuid "~1.4.7" + oauth-sign "~0.8.0" + qs "~5.2.0" + stringstream "~0.0.4" + tough-cookie "~2.2.0" + tunnel-agent "~0.4.1" + +request@2.79.0: + version "2.79.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + qs "~6.3.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + uuid "^3.0.0" + +request@^2.51.0: + version "2.81.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~4.2.1" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + performance-now "^0.2.0" + qs "~6.4.0" + safe-buffer "^5.0.1" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "^0.6.0" + uuid "^3.0.0" + +require-uncached@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +requireg@^0.1.5: + version "0.1.7" + resolved "https://registry.yarnpkg.com/requireg/-/requireg-0.1.7.tgz#9d5210d2af9c718bdaba3c2a0cefebbc846b56c5" + dependencies: + nested-error-stacks "~2.0.0" + rc "~1.0.0" + resolve "~0.6.1" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + +resolve-from@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" + +resolve-pkg@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/resolve-pkg/-/resolve-pkg-0.1.0.tgz#02cc993410e2936962bd97166a1b077da9725531" + dependencies: + resolve-from "^2.0.0" + +resolve@1.1.x, resolve@~1.1.0, resolve@~1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + +resolve@^1.1.7: + version "1.4.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86" + dependencies: + path-parse "^1.0.5" + +resolve@~0.6.1: + version "0.6.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +retry@0.6.1, retry@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.6.1.tgz#fdc90eed943fde11b893554b8cc63d0e899ba918" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +rimraf@2, rimraf@^2.2.0, rimraf@^2.2.8: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +rimraf@~2.2.8: + version "2.2.8" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" + +run-async@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + dependencies: + once "^1.3.0" + +rx-lite@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + +safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + dependencies: + semver "^5.0.3" + +semver-utils@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/semver-utils/-/semver-utils-1.1.1.tgz#27d92fec34d27cfa42707d3b40d025ae9855f2df" + +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + +semver@^2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-2.3.2.tgz#b9848f25d6cf36333073ec9ef8856d42f1233e52" + +shell-quote@^1.4.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" + +shelljs@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.6.1.tgz#ec6211bed1920442088fe0f70b2837232ed2c8a8" + +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + +slide@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +sort-keys-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" + dependencies: + sort-keys "^1.0.0" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + dependencies: + is-plain-obj "^1.0.0" + +source-map@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + dependencies: + amdefine ">=0.0.4" + +source-map@~0.5.1: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +spawn-sync@1.0.15: + version "1.0.15" + resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476" + dependencies: + concat-stream "^1.4.7" + os-shim "^0.1.2" + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sshpk@^1.7.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +statuses@1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string-width@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +string_decoder@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + dependencies: + safe-buffer "~5.1.0" + +stringify-object@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-1.0.1.tgz#86d35e7dbfbce9aa45637d7ecdd7847e159db8a2" + +stringstream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-indent@^1.0.0, strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@0.1.x: + version "0.1.3" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-0.1.3.tgz#164c64e370a8a3cc00c9e01b539e569823f0ee54" + +strip-json-comments@~1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +supports-color@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-1.2.0.tgz#ff1ed1e61169d06b3cf2d588e188b18d8847e17e" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.1.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + dependencies: + has-flag "^1.0.0" + +table@^3.7.8: + version "3.8.3" + resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + +tar-fs@^1.4.1: + version "1.15.3" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.15.3.tgz#eccf935e941493d8151028e636e51ce4c3ca7f20" + dependencies: + chownr "^1.0.1" + mkdirp "^0.5.1" + pump "^1.0.0" + tar-stream "^1.1.2" + +tar-stream@^1.1.2: + version "1.5.4" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.4.tgz#36549cf04ed1aee9b2a30c0143252238daf94016" + dependencies: + bl "^1.0.0" + end-of-stream "^1.0.0" + readable-stream "^2.0.0" + xtend "^4.0.0" + +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +throttleit@~0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +timed-out@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.1.3.tgz#95860bfcc5c76c277f8f8326fd0f5b2e20eba217" + +tiny-lr@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-0.2.1.tgz#b3fdba802e5d56a33c2f6f10794b32e477ac729d" + dependencies: + body-parser "~1.14.0" + debug "~2.2.0" + faye-websocket "~0.10.0" + livereload-js "^2.2.0" + parseurl "~1.3.0" + qs "~5.1.0" + +tmp@0.0.28: + version "0.0.28" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120" + dependencies: + os-tmpdir "~1.0.1" + +to-iso-string@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/to-iso-string/-/to-iso-string-0.0.2.tgz#4dc19e664dfccbe25bd8db508b00c6da158255d1" + +touch@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/touch/-/touch-0.0.3.tgz#51aef3d449571d4f287a5d87c9c8b49181a0db1d" + dependencies: + nopt "~1.0.10" + +tough-cookie@~2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.2.2.tgz#c83a1830f4e5ef0b93ef2a3488e724f8de016ac7" + +tough-cookie@~2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" + dependencies: + punycode "^1.4.1" + +"traverse@>=0.3.0 <0.4": + version "0.3.9" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + +tryit@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +type-detect@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" + +type-detect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" + +type-is@~1.6.10: + version "1.6.15" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.15" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +uglify-js@^2.6: + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + dependencies: + source-map "~0.5.1" + yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +underscore.string@~3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.2.3.tgz#806992633665d5e5fcb4db1fb3a862eb68e9e6da" + +unpipe@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +untildify@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" + dependencies: + os-homedir "^1.0.0" + +unzip-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" + +update-notifier@^0.6.0: + version "0.6.3" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-0.6.3.tgz#776dec8daa13e962a341e8a1d98354306b67ae08" + dependencies: + boxen "^0.3.1" + chalk "^1.0.0" + configstore "^2.0.0" + is-npm "^1.0.0" + latest-version "^2.0.0" + semver-diff "^2.0.0" + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + +user-home@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + +user-home@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + dependencies: + os-homedir "^1.0.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +uuid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + +uuid@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" + +validate-npm-package-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +websocket-driver@>=0.5.1: + version "0.7.0" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" + dependencies: + http-parser-js ">=0.4.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.2.tgz#0e18781de629a18308ce1481650f67ffa2693a5d" + +which@^1.0.8, which@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" + dependencies: + isexe "^2.0.0" + +which@~1.2.1: + version "1.2.14" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" + dependencies: + isexe "^2.0.0" + +widest-line@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-1.0.0.tgz#0c09c85c2a94683d0d7eaf8ee097d564bf0e105c" + dependencies: + string-width "^1.0.1" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wordwrap@^1.0.0, wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +wrench@^1.5.8: + version "1.5.9" + resolved "https://registry.yarnpkg.com/wrench/-/wrench-1.5.9.tgz#411691c63a9b2531b1700267279bdeca23b2142a" + +write-file-atomic@^1.1.2: + version "1.3.4" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + +xdg-basedir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2" + dependencies: + os-homedir "^1.0.0" + +xtend@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" From d4345bb254cd0583700f2e9751c8be19c757ca33 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 14 Sep 2017 18:08:16 +0200 Subject: [PATCH 0990/1021] Use Yarn on travis and appveyor --- .travis.yml | 4 ++-- appveyor.yml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a270a9bc..f08872751 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,8 +18,8 @@ install: - npm --version - git --version - svn --version | head -n 1 - - npm install -g grunt-cli - - npm install + - npm install -g grunt-cli yarn + - yarn os: - osx diff --git a/appveyor.yml b/appveyor.yml index efe27f0bc..a38372691 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -27,7 +27,8 @@ install: - ps: Install-Product node $env:nodejs_version - node --version && npm --version - git --version && svn --version - - npm install + - npm install -g yarn + - yarn # Post-install test scripts. test_script: From e6d1b2d82ed14af8a90e3a80258dc57db5d057b5 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 26 Sep 2017 10:36:09 +0200 Subject: [PATCH 0991/1021] Try to fix appveyor build --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f08872751..10674d9de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ install: - npm --version - git --version - svn --version | head -n 1 - - npm install -g grunt-cli yarn + - npm install -g grunt yarn - yarn os: From b0c3859699cfcbe2eb059d9f02532cc1b8d3af0a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 26 Sep 2017 10:37:59 +0200 Subject: [PATCH 0992/1021] Fix a test --- test/commands/register.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/commands/register.js b/test/commands/register.js index 4083373fe..afb43321a 100644 --- a/test/commands/register.js +++ b/test/commands/register.js @@ -124,7 +124,7 @@ describe('bower register', function () { return helpers.expectEvent(promise.logger, 'confirm') .spread(function (e) { expect(e.type).to.be('confirm'); - expect(e.message).to.be('Registering a package will make it installable via the registry (https://registry.bower.io, continue?'); + expect(e.message).to.be('Registering a package will make it installable via the registry (https://registry.bower.io), continue?'); expect(e.default).to.be(true); }); }); From e483e9bc2ca09110f448215ee1412a6b2b31b204 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 26 Sep 2017 10:48:43 +0200 Subject: [PATCH 0993/1021] Reduce tested node versions --- .travis.yml | 7 +------ appveyor.yml | 5 +---- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 10674d9de..19be01814 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,11 +4,7 @@ language: node_js node_js: - "0.10" - - "0.11" - - "0.12" - - "4.0" - - "4.1" - - "4.2" + - "4" - "5" - "6" - "7" @@ -29,7 +25,6 @@ matrix: fast_finish: true allow_failures: - os: osx - - env: "NODE_VERSION=0.11" - env: "NODE_VERSION=7" script: diff --git a/appveyor.yml b/appveyor.yml index a38372691..b9ba0b75f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,10 +11,7 @@ init: environment: matrix: - nodejs_version: "0.10" - - nodejs_version: "0.12" - - nodejs_version: "4.0" - - nodejs_version: "4.1" - - nodejs_version: "4.2" + - nodejs_version: "4" - nodejs_version: "5" - nodejs_version: "6" From ce210e4f165b68bbc55c34e436212def6bc6274f Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 26 Sep 2017 10:55:11 +0200 Subject: [PATCH 0994/1021] Install grunt on appveyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index b9ba0b75f..dfa13139c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -24,7 +24,7 @@ install: - ps: Install-Product node $env:nodejs_version - node --version && npm --version - git --version && svn --version - - npm install -g yarn + - npm install -g yarn grunt - yarn # Post-install test scripts. From e1dc0105d2e588b7b701ee44c391450d8a4f6fac Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Tue, 26 Sep 2017 10:57:16 +0200 Subject: [PATCH 0995/1021] Reduce node versions on appveyor --- appveyor.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index dfa13139c..2c9f778f2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,6 @@ init: # Test against these versions of Node.js. environment: matrix: - - nodejs_version: "0.10" - nodejs_version: "4" - nodejs_version: "5" - nodejs_version: "6" From a6308bf8f8aa25c82129e71ffaaad4b9993dcf89 Mon Sep 17 00:00:00 2001 From: Guido Bouman Date: Tue, 26 Sep 2017 15:11:42 +0200 Subject: [PATCH 0996/1021] Remove duplicate space setting from .editorconfig. (#2480) --- .editorconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index dda07ce8d..5bc17b8fd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -15,5 +15,4 @@ trim_trailing_whitespace = false insert_final_newline = false [{package,bower}.json] -indent_style = space indent_size = 2 From 74af42c176025fe2490d4637ac562da9fcc5e185 Mon Sep 17 00:00:00 2001 From: Martin Page Date: Wed, 28 Mar 2018 12:16:09 +0100 Subject: [PATCH 0997/1021] Only replace last `@` after (if any) last `/` with `#` (#2395) --- lib/commands/info.js | 45 ++++++++++++++++++++++------------------- lib/commands/install.js | 16 +++++++++------ 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/lib/commands/info.js b/lib/commands/info.js index 28cac378b..ae9b9ab6f 100644 --- a/lib/commands/info.js +++ b/lib/commands/info.js @@ -10,7 +10,10 @@ function info(logger, endpoint, property, config) { } // handle @ as version divider - endpoint = endpoint.replace('@', '#'); + var splitParts = endpoint.split('/'); + splitParts[splitParts.length - 1] = splitParts[splitParts.length - 1].replace('@', '#'); + endpoint = splitParts.join('/'); + var repository; var decEndpoint; @@ -24,33 +27,33 @@ function info(logger, endpoint, property, config) { getPkgMeta(repository, decEndpoint, property), decEndpoint.target === '*' && !property ? repository.versions(decEndpoint.source) : null ]) - .spread(function (pkgMeta, versions) { - if (versions) { - return { - name: decEndpoint.source, - versions: versions, - latest: pkgMeta - }; - } + .spread(function (pkgMeta, versions) { + if (versions) { + return { + name: decEndpoint.source, + versions: versions, + latest: pkgMeta + }; + } - return pkgMeta; - }); + return pkgMeta; + }); } function getPkgMeta(repository, decEndpoint, property) { return repository.fetch(decEndpoint) - .spread(function (canonicalDir, pkgMeta) { - pkgMeta = mout.object.filter(pkgMeta, function (value, key) { - return key.charAt(0) !== '_'; - }); + .spread(function (canonicalDir, pkgMeta) { + pkgMeta = mout.object.filter(pkgMeta, function (value, key) { + return key.charAt(0) !== '_'; + }); - // Retrieve specific property - if (property) { - pkgMeta = mout.object.get(pkgMeta, property); - } + // Retrieve specific property + if (property) { + pkgMeta = mout.object.get(pkgMeta, property); + } - return pkgMeta; - }); + return pkgMeta; + }); } // ------------------- diff --git a/lib/commands/install.js b/lib/commands/install.js index 6e6b6fc55..c2b87dedf 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -16,8 +16,12 @@ function install(logger, endpoints, options, config) { // Convert endpoints to decomposed endpoints endpoints = endpoints || []; decEndpoints = endpoints.map(function (endpoint) { + // handle @ as version divider - endpoint = endpoint.replace('@', '#'); + var splitParts = endpoint.split('/'); + splitParts[splitParts.length - 1] = splitParts[splitParts.length - 1].replace('@', '#'); + endpoint = splitParts.join('/'); + return endpointParser.decompose(endpoint); }); @@ -30,11 +34,11 @@ install.readOptions = function (argv) { var cli = require('../util/cli'); var options = cli.readOptions({ - 'force-latest': { type: Boolean, shorthand: 'F'}, - 'production': { type: Boolean, shorthand: 'p' }, - 'save': { type: Boolean, shorthand: 'S' }, - 'save-dev': { type: Boolean, shorthand: 'D' }, - 'save-exact': { type: Boolean, shorthand: 'E' } + 'force-latest': {type: Boolean, shorthand: 'F'}, + 'production': {type: Boolean, shorthand: 'p'}, + 'save': {type: Boolean, shorthand: 'S'}, + 'save-dev': {type: Boolean, shorthand: 'D'}, + 'save-exact': {type: Boolean, shorthand: 'E'} }, argv); var packages = options.argv.remain.slice(1); From dd19bafa37d97388debfbbb7dd0b31b2a86d0064 Mon Sep 17 00:00:00 2001 From: Madan Date: Wed, 28 Mar 2018 16:47:55 +0530 Subject: [PATCH 0998/1021] docs: highlight "-allow-root" (#2496) --- lib/util/rootCheck.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util/rootCheck.js b/lib/util/rootCheck.js index 0c93556b3..b391ea965 100644 --- a/lib/util/rootCheck.js +++ b/lib/util/rootCheck.js @@ -18,7 +18,7 @@ sudo, please spend a few minutes learning more about how your system should work make any necessary repairs.\n\n\ http://www.joyent.com/blog/installing-node-and-npm\n\ https://gist.github.com/isaacs/579814\n\n\ -You can however run a command with sudo using --allow-root option'; +You can however run a command with sudo using "--allow-root" option'; if (isRoot()) { var cli = require('./cli'); From c3e9c94833b53df392b7abfad539ec844b805f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20K=C3=BChnel?= Date: Wed, 28 Mar 2018 13:20:11 +0200 Subject: [PATCH 0999/1021] Expose non-interactive option to CLI help (#2404) --- lib/templates/json/help.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/templates/json/help.json b/lib/templates/json/help.json index 14d5a192c..06aadaa34 100644 --- a/lib/templates/json/help.json +++ b/lib/templates/json/help.json @@ -69,6 +69,10 @@ { "flag": "--no-color", "description": "Disable colors" + }, + { + "flag": "--config.interactive=false", + "description": "Disable prompts" } ] } From 8e3432846658ff59ba298b3ac5669ac178568ce1 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 28 Mar 2018 15:17:31 +0200 Subject: [PATCH 1000/1021] Run tests on all node versions and fix test suite, closes #2495 (#2505) --- appveyor.yml => .appveyor.yml | 10 +++-- .travis.yml | 34 +++++++++++----- package.json | 2 +- test/util/download.js | 2 +- yarn.lock | 76 ++++++++++++++++++++++++++++------- 5 files changed, 94 insertions(+), 30 deletions(-) rename appveyor.yml => .appveyor.yml (83%) diff --git a/appveyor.yml b/.appveyor.yml similarity index 83% rename from appveyor.yml rename to .appveyor.yml index 2c9f778f2..605282694 100644 --- a/appveyor.yml +++ b/.appveyor.yml @@ -10,9 +10,12 @@ init: # Test against these versions of Node.js. environment: matrix: + - nodejs_version: "0.10" + - nodejs_version: "0.12" - nodejs_version: "4" - - nodejs_version: "5" - nodejs_version: "6" + - nodejs_version: "8" + - nodejs_version: "9" # Finish on first failed build matrix: @@ -20,11 +23,12 @@ matrix: # Install node, display versions, install dependencies install: - - ps: Install-Product node $env:nodejs_version + - ps: Install-Product node 8 - node --version && npm --version - git --version && svn --version - npm install -g yarn grunt - yarn + - ps: Install-Product node $env:nodejs_version # Post-install test scripts. test_script: @@ -39,4 +43,4 @@ deploy: off # Cache node modules, and refresh if package.json changes cache: - - node_modules -> package.json + - "%LOCALAPPDATA%\\Yarn" diff --git a/.travis.yml b/.travis.yml index 19be01814..84f7d03c4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,20 +2,31 @@ sudo: false language: node_js +# Use node 8 for build node_js: - - "0.10" - - "4" - - "5" - - "6" - - "7" + - "8" -install: +# Then test with specific node version +env: + - TEST_NODE_VERSION="0.10" + - TEST_NODE_VERSION="0.12" + - TEST_NODE_VERSION="4" + - TEST_NODE_VERSION="6" + - TEST_NODE_VERSION="8" + - TEST_NODE_VERSION="9" + +before_install: - node --version - - npm --version - - git --version - - svn --version | head -n 1 - - npm install -g grunt yarn + - curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.5.1 + - export PATH=$HOME/.yarn/bin:$PATH + +cache: + yarn: true + +install: - yarn + - nvm install $TEST_NODE_VERSION + - npm install -g grunt os: - osx @@ -25,7 +36,8 @@ matrix: fast_finish: true allow_failures: - os: osx - - env: "NODE_VERSION=7" script: + - nvm use $TEST_NODE_VERSION + - node --version && npm --version && git --version && svn --version | head -n 1 - grunt travis diff --git a/package.json b/package.json index 99cfb9806..7284231fb 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "load-grunt-tasks": "^3.5.0", "mocha": "^2.5.3", "multiline": "^1.0.2", - "nock": "^7.7.2", + "nock": "^9.2.3", "node-uuid": "^1.4.7", "proxyquire": "^1.7.9", "spawn-sync": "1.0.15", diff --git a/test/util/download.js b/test/util/download.js index aa662bcae..4df551a7a 100644 --- a/test/util/download.js +++ b/test/util/download.js @@ -108,7 +108,7 @@ describe('download', function () { nock.get('/package.tar.gz').times(6).delayConnection(1000).replyWithFile(200, source); }, expectError: function (e) { - expect(e.code).to.be('ETIMEDOUT'); + expect(e.code).to.be('ESOCKETTIMEDOUT'); expect(fs.readdirSync(tempDir.path)).to.be.empty(); }, downloadOpts: { diff --git a/yarn.lock b/yarn.lock index 00a326ce8..03aae3237 100644 --- a/yarn.lock +++ b/yarn.lock @@ -337,7 +337,7 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" -"chai@>=1.9.2 <4.0.0", chai@^3.5.0: +chai@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" dependencies: @@ -345,6 +345,17 @@ center-align@^0.1.1: deep-eql "^0.1.3" type-detect "^1.0.0" +chai@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" + dependencies: + assertion-error "^1.0.1" + check-error "^1.0.1" + deep-eql "^3.0.0" + get-func-name "^2.0.0" + pathval "^1.0.0" + type-detect "^4.0.0" + chainsaw@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" @@ -361,6 +372,10 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3, chalk@~1.1.1: strip-ansi "^3.0.0" supports-color "^2.0.0" +check-error@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + chmodr@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/chmodr/-/chmodr-1.0.2.tgz#04662b932d0f02ec66deaa2b0ea42811968e3eb9" @@ -516,12 +531,18 @@ debug@2.2.0, debug@~2.2.0: dependencies: ms "0.7.1" -debug@^2.1.1, debug@^2.2.0: +debug@^2.1.1: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: ms "2.0.0" +debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + decamelize@^1.0.0, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -544,6 +565,12 @@ deep-eql@^0.1.3: dependencies: type-detect "0.1.1" +deep-eql@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + dependencies: + type-detect "^4.0.0" + deep-equal@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" @@ -958,6 +985,10 @@ generate-object-property@^1.1.0: dependencies: is-property "^1.0.0" +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" @@ -1599,6 +1630,10 @@ lodash@^4.0.0, lodash@^4.14.0, lodash@^4.3.0, lodash@~4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" +lodash@^4.17.5: + version "4.17.5" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" + lodash@~4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.3.0.tgz#efd9c4a6ec53f3b05412429915c3e4824e4d25a4" @@ -1796,18 +1831,19 @@ nested-error-stacks@~2.0.0: dependencies: inherits "~2.0.1" -nock@^7.7.2: - version "7.7.3" - resolved "https://registry.yarnpkg.com/nock/-/nock-7.7.3.tgz#d0600980a4443edf6e50b5ed3314602cb7ccc489" +nock@^9.2.3: + version "9.2.3" + resolved "https://registry.yarnpkg.com/nock/-/nock-9.2.3.tgz#39738087d6a0497d3a165fb352612b38a2f9b92f" dependencies: - chai ">=1.9.2 <4.0.0" - debug "^2.2.0" + chai "^4.1.2" + debug "^3.1.0" deep-equal "^1.0.0" json-stringify-safe "^5.0.1" - lodash "^3.10.1" + lodash "^4.17.5" mkdirp "^0.5.0" - propagate "0.3.x" - qs "^6.0.2" + propagate "^1.0.0" + qs "^6.5.1" + semver "^5.5.0" node-status-codes@^1.0.0: version "1.0.0" @@ -1961,6 +1997,10 @@ path-type@^1.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +pathval@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" @@ -2011,9 +2051,9 @@ promptly@0.2.0: dependencies: read "~1.0.4" -propagate@0.3.x: - version "0.3.1" - resolved "https://registry.yarnpkg.com/propagate/-/propagate-0.3.1.tgz#e3a84404a7ece820dd6bbea9f6d924e3135ae09c" +propagate@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/propagate/-/propagate-1.0.0.tgz#00c2daeedda20e87e3782b344adba1cddd6ad709" proxyquire@^1.7.9: version "1.8.0" @@ -2046,7 +2086,7 @@ qs@5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.0.tgz#a9f31142af468cb72b25b30136ba2456834916be" -qs@^6.0.2: +qs@^6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" @@ -2387,6 +2427,10 @@ semver@^2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-2.3.2.tgz#b9848f25d6cf36333073ec9ef8856d42f1233e52" +semver@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + shell-quote@^1.4.2: version "1.6.1" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" @@ -2698,6 +2742,10 @@ type-detect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" +type-detect@^4.0.0: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + type-is@~1.6.10: version "1.6.15" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" From add601795f41376bac7a94af42312e54e4e5f1dd Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 28 Mar 2018 15:25:36 +0200 Subject: [PATCH 1001/1021] Update year in licenses one last time, fixes #2476 --- LICENSE | 2 +- README.md | 3 +-- packages/bower-json/LICENSE | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/LICENSE b/LICENSE index 7c08091b3..01e1e9358 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2017 Twitter and other contributors +Copyright (c) 2013-present Twitter and other contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/README.md b/README.md index fd334a45b..f5a5388dd 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,6 @@ Become a sponsor and get your logo on our README on Github with a link to your s ## License -Copyright (c) 2016 Twitter and [other contributors](https://github.com/bower/bower/graphs/contributors) +Copyright (c) 2012-present Twitter and [other contributors](https://github.com/bower/bower/graphs/contributors) Licensed under the MIT License - diff --git a/packages/bower-json/LICENSE b/packages/bower-json/LICENSE index f25dbe841..42f679057 100644 --- a/packages/bower-json/LICENSE +++ b/packages/bower-json/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016 Twitter and other contributors +Copyright (c) 2012-present Twitter and other contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in From 19357166601cc2a587e04f1a05c4f4a3ea1aaf5d Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Wed, 28 Mar 2018 14:51:53 +0100 Subject: [PATCH 1002/1021] Fix issues found by lgtm (#2493) --- lib/commands/lookup.js | 2 +- lib/core/Manager.js | 2 -- lib/core/resolvers/GitResolver.js | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/commands/lookup.js b/lib/commands/lookup.js index 5d095642c..9027836db 100644 --- a/lib/commands/lookup.js +++ b/lib/commands/lookup.js @@ -16,7 +16,7 @@ function lookup(logger, name, config) { .then(function (entry) { return !entry ? null : { name: name, - url: entry && entry.url + url: entry.url }; }); } diff --git a/lib/core/Manager.js b/lib/core/Manager.js index f1f9fcde4..ed66c4ba8 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -687,7 +687,6 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { var unresolvable; var dataPicks; var save; - var choices; var picks = []; var versionRegex = /(?:[\d\w]\.){2}[\d\w](?:.)*/; var picksReleases; @@ -845,7 +844,6 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { picks: dataPicks }); - choices = picks.map(function (pick, index) { return index + 1; }); picksReleases = picks.map(function (pick) { return pick.pkgMeta._release; }); return Q.nfcall(this._logger.prompt.bind(this._logger), { type: 'input', diff --git a/lib/core/resolvers/GitResolver.js b/lib/core/resolvers/GitResolver.js index b34a839a7..90d58c03a 100644 --- a/lib/core/resolvers/GitResolver.js +++ b/lib/core/resolvers/GitResolver.js @@ -121,8 +121,6 @@ GitResolver.prototype._findResolution = function (target) { version, index; - versionsArr = versions.map(function (obj) { return obj.version; }); - // If there are no tags and target is *, // fallback to the latest commit on master if (!versions.length && target === '*') { From 5a6ae540f9dcbec34e1f589b1ba3664078a93637 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Wed, 28 Mar 2018 11:05:13 -0400 Subject: [PATCH 1003/1021] Adding support for Arrays in Environment Variable replacement (#2411) --- packages/bower-config/lib/util/expand.js | 6 ++++++ .../bower-config/test/assets/env-variables-values/.bowerrc | 7 ++++++- packages/bower-config/test/test.js | 5 ++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/bower-config/lib/util/expand.js b/packages/bower-config/lib/util/expand.js index f3d453fd3..303fadef2 100644 --- a/packages/bower-config/lib/util/expand.js +++ b/packages/bower-config/lib/util/expand.js @@ -43,6 +43,9 @@ function doEnvReplaceStr (f) { function envReplace(config) { var envReplaced = {}; + if ( lang.isArray(config) ) { + envReplaced = []; + } object.forOwn(config, function (value, key) { @@ -63,6 +66,9 @@ function envReplace(config) { if ( lang.isPlainObject(value) ) { envReplaced[key] = envReplace(value); } + else if ( lang.isArray(value) ) { + envReplaced[key] = envReplace(value); + } else if ( lang.isString(value) ) { envReplaced[key] = doEnvReplaceStr(value); } diff --git a/packages/bower-config/test/assets/env-variables-values/.bowerrc b/packages/bower-config/test/assets/env-variables-values/.bowerrc index dae163d47..339447ed9 100644 --- a/packages/bower-config/test/assets/env-variables-values/.bowerrc +++ b/packages/bower-config/test/assets/env-variables-values/.bowerrc @@ -4,7 +4,12 @@ }, "storage" : { "packages" : "${_BOWERRC_MY_PACKAGES}", - "registry" : "~/.bower-test/registry" + "registry" : { + "register": "~/.bower-test/registry", + "search": [ + "${_BOWERRC_MY_USER}:${_BOWERRC_MY_PASS}" + ] + } }, "tmp" : "${_BOWERRC_MY_TMP}" } diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index 967eaf3f2..d9a810e28 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -224,10 +224,13 @@ describe('Allow ${ENV} variables in .bowerrc', function() { it('sets values from process.env', function() { process.env._BOWERRC_MY_PACKAGES = 'a'; process.env._BOWERRC_MY_TMP = '/tmp/b'; + process.env._BOWERRC_MY_USER = 'username'; + process.env._BOWERRC_MY_PASS = 'password'; var config = require('../lib/Config').read('test/assets/env-variables-values'); assert.equal('a', config.storage.packages); assert.equal('/tmp/b', config.tmp); + assert.equal('username:password', config.storage.registry.search[0]); assert.equal('${_myshellvar}', config.scripts.postinstall); }); }); @@ -238,7 +241,7 @@ describe('untildify paths in .bowerrc', function() { var config = require('../lib/Config').read('test/assets/env-variables-values'); var untildify = require('untildify'); - assert.equal(untildify('~/.bower-test/registry') , config.storage.registry); + assert.equal(untildify('~/.bower-test/registry') , config.storage.registry.register); }); }); From bb17839bc21bc7e0a912e9c55934495258c7b017 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 28 Mar 2018 17:37:34 +0200 Subject: [PATCH 1004/1021] Allow shallow cloning when source is a ssh protocol (#2506) --- lib/core/resolvers/GitRemoteResolver.js | 10 +++++----- test/core/resolvers/gitRemoteResolver.js | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/core/resolvers/GitRemoteResolver.js b/lib/core/resolvers/GitRemoteResolver.js index 1a8e9be90..b8f32f8be 100644 --- a/lib/core/resolvers/GitRemoteResolver.js +++ b/lib/core/resolvers/GitRemoteResolver.js @@ -19,14 +19,14 @@ function GitRemoteResolver(decEndpoint, config, logger) { this._name = this._name.slice(0, -4); } - // Get the host of this source + // Get the remote of this source if (!/:\/\//.test(this._source)) { - this._host = url.parse('ssh://' + this._source).host; + this._remote = url.parse('ssh://' + this._source); } else { - this._host = url.parse(this._source).host; + this._remote = url.parse(this._source); } - - this._remote = url.parse(this._source); + + this._host = this._remote.host; // Verify whether the server supports shallow cloning this._shallowClone = this._supportsShallowCloning; diff --git a/test/core/resolvers/gitRemoteResolver.js b/test/core/resolvers/gitRemoteResolver.js index 6381424eb..30c7a0bd6 100644 --- a/test/core/resolvers/gitRemoteResolver.js +++ b/test/core/resolvers/gitRemoteResolver.js @@ -356,6 +356,26 @@ describe('GitRemoteResolver', function () { }); }); + it('should evaluate to true when source is a ssh protocol and host is defined to support shallow cloning', function (next) { + var testSource = 'git@foo:bar.git'; + + var MyGitRemoteResolver = gitRemoteResolverFactory( + createCmdHandlerFn(testSource, multiline(function () {/* + foo: bar + Content-Type: application/x-git-upload-pack-advertisement + 1234: 5678 + */})) + ); + + var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); + + resolver._shallowClone().then(function (shallowCloningSupported) { + expect(shallowCloningSupported).to.be(true); + + next(); + }); + }); + it('should cache hosts that support shallow cloning', function (next) { var testSource = 'https://foo/bar.git'; From 50ee729ea2cc6115f144583443d6df95b0e2967b Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 28 Mar 2018 17:58:56 +0200 Subject: [PATCH 1005/1021] Allow to disable shorthand resolver (#2507) --- lib/core/resolverFactory.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index 9de177705..f015fb485 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -176,6 +176,12 @@ function getConstructor(decEndpoint, options, registryClient) { // Check if is a shorthand and expand it addResolver(function () { + + // Check if the shorthandResolver is falsy + if (!config.shorthandResolver) { + return; + } + // Skip ssh and/or URL with auth if (/[:@]/.test(source)) { return; From b62faa19a6a24844abc6a0df8b6ffa614bb70c04 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 28 Mar 2018 16:53:32 +0200 Subject: [PATCH 1006/1021] Update request version in bower-registry-client #2336 --- packages/bower-registry-client/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index 74c206fa0..b46536286 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "1.0.0", + "version": "1.0.1", "description": "Provides easy interaction with the Bower registry", "author": "Twitter", "license": "MIT", @@ -13,8 +13,8 @@ "async": "^0.2.8", "graceful-fs": "^4.0.0", "lru-cache": "^2.3.0", - "request": "^2.51.0", - "request-replay": "^0.2.0", + "request": "^2.74.0", + "request-replay": "^1.0.4", "rimraf": "^2.2.0", "mkdirp": "^0.3.5" }, From d6a18ae7ee244a65f38f0ffcddb653bb1c3a3c18 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 28 Mar 2018 18:08:50 +0200 Subject: [PATCH 1007/1021] Revert "Update request version in bower-registry-client #2336" This reverts commit 1e2c27f338265f9f601f6abfbc5621e1089d03b5. --- packages/bower-registry-client/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bower-registry-client/package.json b/packages/bower-registry-client/package.json index b46536286..74c206fa0 100644 --- a/packages/bower-registry-client/package.json +++ b/packages/bower-registry-client/package.json @@ -1,6 +1,6 @@ { "name": "bower-registry-client", - "version": "1.0.1", + "version": "1.0.0", "description": "Provides easy interaction with the Bower registry", "author": "Twitter", "license": "MIT", @@ -13,8 +13,8 @@ "async": "^0.2.8", "graceful-fs": "^4.0.0", "lru-cache": "^2.3.0", - "request": "^2.74.0", - "request-replay": "^1.0.4", + "request": "^2.51.0", + "request-replay": "^0.2.0", "rimraf": "^2.2.0", "mkdirp": "^0.3.5" }, From 451c60ec20b8df66511cca2add64633f0d7389ec Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 28 Mar 2018 18:15:30 +0200 Subject: [PATCH 1008/1021] Do not store resolutions if --save is not used, fixes #2344 (#2508) --- lib/core/Manager.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/core/Manager.js b/lib/core/Manager.js index ed66c4ba8..e5f3b7736 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -825,7 +825,9 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { }); // Save resolution - this._storeResolution(picks[suitable]); + if (this._config.argv.cooked.includes('--save')) { + this._storeResolution(picks[suitable]); + } return Q.resolve(picks[suitable]); } From 6bc778df32c0276300f0ca782a92b576b8ca6a06 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 28 Mar 2018 19:28:43 +0200 Subject: [PATCH 1009/1021] Format with prettier (#2510) --- .eslintrc | 4 +- .gitignore | 1 + .prettierignore | 2 + Gruntfile.js | 340 +-- lib/bin/bower.js | 71 +- lib/commands/cache/clean.js | 128 +- lib/commands/cache/list.js | 9 +- lib/commands/help.js | 12 +- lib/commands/home.js | 17 +- lib/commands/index.js | 29 +- lib/commands/info.js | 39 +- lib/commands/init.js | 243 ++- lib/commands/install.js | 26 +- lib/commands/link.js | 63 +- lib/commands/list.js | 109 +- lib/commands/login.js | 146 +- lib/commands/lookup.js | 19 +- lib/commands/prune.js | 49 +- lib/commands/register.js | 86 +- lib/commands/search.js | 2 +- lib/commands/uninstall.js | 119 +- lib/commands/unregister.js | 75 +- lib/commands/update.js | 13 +- lib/commands/version.js | 245 ++- lib/config.js | 28 +- lib/core/Manager.js | 968 +++++---- lib/core/PackageRepository.js | 301 ++- lib/core/Project.js | 1314 ++++++----- lib/core/ResolveCache.js | 444 ++-- lib/core/resolverFactory.js | 193 +- lib/core/resolvers/FsResolver.js | 103 +- lib/core/resolvers/GitFsResolver.js | 69 +- lib/core/resolvers/GitHubResolver.js | 150 +- lib/core/resolvers/GitRemoteResolver.js | 257 ++- lib/core/resolvers/GitResolver.js | 346 +-- lib/core/resolvers/Resolver.js | 168 +- lib/core/resolvers/SvnResolver.js | 386 ++-- lib/core/resolvers/UrlResolver.js | 225 +- lib/core/resolvers/pluginResolverFactory.js | 252 ++- lib/core/scripts.js | 55 +- lib/renderers/JsonRenderer.js | 51 +- lib/renderers/StandardRenderer.js | 171 +- lib/templates/helpers/colors.js | 13 +- lib/templates/helpers/condense.js | 4 +- lib/templates/helpers/indent.js | 2 +- lib/templates/helpers/rpad.js | 2 +- lib/templates/helpers/sum.js | 2 +- lib/util/abbreviations.js | 4 +- lib/util/cli.js | 6 +- lib/util/cmd.js | 31 +- lib/util/copy.js | 53 +- lib/util/createLink.js | 76 +- lib/util/download.js | 190 +- lib/util/extract.js | 210 +- lib/util/fs.js | 8 +- lib/util/readJson.js | 60 +- lib/util/relativeToBaseDir.js | 2 +- lib/util/removeIgnores.js | 39 +- lib/util/resolve.js | 6 +- lib/util/rimraf.js | 12 +- lib/util/rootCheck.js | 10 +- lib/util/semver.js | 11 +- lib/util/template.js | 2 +- lib/util/userAgent.js | 11 +- lib/util/validLink.js | 22 +- package.json | 13 +- packages/bower-config/Gruntfile.js | 9 +- packages/bower-config/lib/Config.js | 36 +- packages/bower-config/lib/util/defaults.js | 43 +- packages/bower-config/lib/util/expand.js | 56 +- packages/bower-config/lib/util/paths.js | 14 +- packages/bower-config/lib/util/proxy.js | 114 +- packages/bower-config/lib/util/rc.js | 19 +- packages/bower-config/test/helpers.js | 63 +- packages/bower-config/test/test.js | 180 +- packages/bower-config/test/util/index.js | 4 +- packages/bower-config/test/util/rc.js | 10 +- packages/bower-endpoint-parser/index.js | 10 +- packages/bower-endpoint-parser/test/test.js | 329 ++- packages/bower-json/Gruntfile.js | 13 +- packages/bower-json/lib/json.js | 77 +- packages/bower-json/lib/util/isAsset.js | 12 +- packages/bower-json/lib/util/isComponent.js | 2 +- packages/bower-json/test/test.js | 353 +-- packages/bower-logger/lib/Logger.js | 47 +- packages/bower-logger/test/test.js | 314 +-- packages/bower-registry-client/Client.js | 29 +- packages/bower-registry-client/Gruntfile.js | 9 +- packages/bower-registry-client/lib/list.js | 180 +- packages/bower-registry-client/lib/lookup.js | 221 +- .../bower-registry-client/lib/register.js | 84 +- packages/bower-registry-client/lib/search.js | 183 +- .../bower-registry-client/lib/unregister.js | 58 +- .../bower-registry-client/lib/util/Cache.js | 106 +- .../bower-registry-client/lib/util/md5.js | 5 +- packages/bower-registry-client/test/Client.js | 608 +++--- .../bower-registry-client/test/core/index.js | 12 +- .../bower-registry-client/test/core/list.js | 12 +- .../bower-registry-client/test/core/lookup.js | 12 +- .../test/core/register.js | 6 +- .../bower-registry-client/test/core/search.js | 12 +- .../test/core/util/Cache.js | 46 +- .../test/core/util/createError.js | 23 +- test/commands/bower.js | 8 +- test/commands/cache/clean.js | 102 +- test/commands/cache/list.js | 73 +- test/commands/help.js | 38 +- test/commands/home.js | 23 +- test/commands/index.js | 2 +- test/commands/info.js | 43 +- test/commands/init.js | 183 +- test/commands/install.js | 457 ++-- test/commands/link.js | 243 ++- test/commands/list.js | 94 +- test/commands/login.js | 102 +- test/commands/lookup.js | 30 +- test/commands/prune.js | 57 +- test/commands/register.js | 139 +- test/commands/search.js | 82 +- test/commands/uninstall.js | 164 +- test/commands/unregister.js | 68 +- test/commands/update.js | 142 +- test/commands/version.js | 145 +- test/core/Manager.js | 237 +- test/core/packageRepository.js | 576 ++--- test/core/resolveCache.js | 1300 ++++++----- test/core/resolverFactory.js | 995 +++++---- test/core/resolvers/fsResolver.js | 450 ++-- test/core/resolvers/gitFsResolver.js | 303 +-- test/core/resolvers/gitHubResolver.js | 177 +- test/core/resolvers/gitRemoteResolver.js | 643 ++++-- test/core/resolvers/gitResolver.js | 1777 ++++++++------- test/core/resolvers/pluginResolverFactory.js | 324 +-- test/core/resolvers/resolver.js | 1014 +++++---- test/core/resolvers/svnResolver.js | 1936 +++++++++-------- test/core/resolvers/urlResolver.js | 1179 ++++++---- test/core/scripts.js | 228 +- test/helpers.js | 139 +- test/packages-svn.js | 282 ++- test/packages.js | 301 +-- test/renderers/JsonRenderer.js | 126 +- test/renderers/StandardRenderer.js | 1323 ++++++----- test/util/createLink.js | 32 +- test/util/download.js | 154 +- test/util/index.js | 2 +- test/util/isPathAbsolute.js | 8 +- test/util/relativeToBaseDir.js | 23 +- test/util/removeIgnores.js | 70 +- test/util/template.js | 54 +- yarn.lock | 1713 ++++++++++++++- 150 files changed, 17241 insertions(+), 11748 deletions(-) create mode 100644 .prettierignore diff --git a/.eslintrc b/.eslintrc index 14e58a0d8..00b4c4049 100644 --- a/.eslintrc +++ b/.eslintrc @@ -17,7 +17,7 @@ "strict": 0, "semi": 0, "comma-spacing": 2, - "quote-props": [2, "consistent", { "keywords": true }], + "quote-props": [2, "as-needed"], "quotes": [2, "single", "avoid-escape"], "indent": [2, 4], "no-cond-assign": [ 2, "except-parens" ], @@ -41,7 +41,7 @@ "no-new-wrappers": 2, "no-invalid-this": 0, "space-before-blocks": [2, "always"], - "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}], + "space-before-function-paren": [2, "never"], "space-infix-ops": 2, "keyword-spacing": 2, "new-parens": 2, diff --git a/.gitignore b/.gitignore index 7984ffa59..88977d511 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +!lib/bin /node_modules /npm-debug.log diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..292058982 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +**/node_modules/** +**/test/assets/** diff --git a/Gruntfile.js b/Gruntfile.js index 34b205d25..850c79594 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,5 +1,3 @@ -'use strict'; - var tmp = require('tmp'); var childProcess = require('child_process'); var arraydiff = require('arr-diff'); @@ -8,14 +6,11 @@ var wrench = require('wrench'); var inquirer = require('inquirer'); var path = require('path'); -module.exports = function (grunt) { +module.exports = function(grunt) { require('load-grunt-tasks')(grunt); grunt.initConfig({ eslint: { - options: { - fix: true - }, files: [ 'Gruntfile.js', 'bin/*', @@ -43,16 +38,18 @@ module.exports = function (grunt) { } }, exec: { - 'assets': { + assets: { command: 'node test/packages.js && node test/packages-svn.js' }, 'assets-force': { - command: 'node test/packages.js --force && node test/packages-svn.js --force' + command: + 'node test/packages.js --force && node test/packages-svn.js --force' }, - 'cover': { - command: 'node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' + cover: { + command: + 'node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' }, - 'coveralls': { + coveralls: { command: 'npm run coveralls < test/reports/lcov.info', exitCodes: [0, 1, 2, 3] // Alow for failure for coverage report } @@ -66,148 +63,221 @@ module.exports = function (grunt) { grunt.registerTask('assets', ['exec:assets-force']); grunt.registerTask('test', ['eslint', 'exec:assets', 'simplemocha:full']); grunt.registerTask('cover', 'exec:cover'); - grunt.registerTask('travis', ['eslint', 'exec:assets', 'exec:cover', 'exec:coveralls']); + grunt.registerTask('travis', [ + 'eslint', + 'exec:assets', + 'exec:cover', + 'exec:coveralls' + ]); grunt.registerTask('default', 'test'); - grunt.task.registerTask('publish', 'Perform final checks and publish Bower', function () { - var npmVersion = JSON.parse(childProcess.execSync('npm version --json').toString()).npm.split('.'); - var npmMajor = parseInt(npmVersion[0], 10); - var npmMinor = parseInt(npmVersion[1], 10); - - var jsonPackage = require('./package'); - - if (npmMajor !== 3 || npmMinor < 5) { - grunt.log.writeln('You need to use at least npm@3.5 to publish bower.'); - grunt.log.writeln('It is because npm 2.x produces too long paths that Windows does not handle.'); - grunt.log.writeln('Please upgrade it: npm install -g npm'); - process.exit(1); - } - - var version = jsonPackage.version; - var changelog = fs.readFileSync('./CHANGELOG.md'); - - if (changelog.indexOf('## ' + version) === -1) { - grunt.log.writeln('Please add changelog.md entry for this bower version (' + version + ')'); - - var lastRelease = childProcess.execSync('git tag | tail -1').toString().trim(); - - grunt.log.writeln('Commits since last release (' + lastRelease + '): \n'); - - grunt.log.writeln(childProcess.execSync('git log --oneline ' + lastRelease + '..').toString()); - - process.exit(1); - } - - if (childProcess.execSync('git rev-parse --abbrev-ref HEAD').toString().trim() !== 'master') { - grunt.log.writeln('You need to release bower from the "master" branch'); - - process.exit(1); - } - - if (process.env.SKIP_TESTS !== '1') { - grunt.log.writeln('Reinstalling dependencies...'); - childProcess.execSync('rm -rf node_modules && npm install', { stdio: [0, 1, 2] }); - - grunt.log.writeln('Running test suite...'); - childProcess.execSync('grunt test', { stdio: [0, 1, 2] }); - } - - var dir = tmp.dirSync().name; - - wrench.copyDirSyncRecursive(__dirname, dir, { - forceDelete: true, - include: function (path) { - return !path.match(/node_modules|\.git|test/); + grunt.task.registerTask( + 'publish', + 'Perform final checks and publish Bower', + function() { + var npmVersion = JSON.parse( + childProcess.execSync('npm version --json').toString() + ).npm.split('.'); + var npmMajor = parseInt(npmVersion[0], 10); + var npmMinor = parseInt(npmVersion[1], 10); + + var jsonPackage = require('./package'); + + if (npmMajor !== 3 || npmMinor < 5) { + grunt.log.writeln( + 'You need to use at least npm@3.5 to publish bower.' + ); + grunt.log.writeln( + 'It is because npm 2.x produces too long paths that Windows does not handle.' + ); + grunt.log.writeln('Please upgrade it: npm install -g npm'); + process.exit(1); } - }); - - grunt.log.writeln('Installing production dependencies...'); - childProcess.execSync('npm install --production --silent', { cwd: dir, stdio: [0, 1, 2] }); - - delete jsonPackage.dependencies; - delete jsonPackage.devDependencies; - delete jsonPackage.scripts; - - fs.writeFileSync(path.resolve(dir, 'package.json'), JSON.stringify(jsonPackage, null, ' ') + '\n'); - - - grunt.log.writeln('Moving node_modules to lib directory...'); - wrench.copyDirSyncRecursive(path.resolve(dir, 'node_modules'), path.resolve(dir, 'lib', 'node_modules')); - wrench.rmdirSyncRecursive(path.resolve(dir, 'node_modules')); + var version = jsonPackage.version; + var changelog = fs.readFileSync('./CHANGELOG.md'); - grunt.log.writeln('Testing bower on sample project...'); + if (changelog.indexOf('## ' + version) === -1) { + grunt.log.writeln( + 'Please add changelog.md entry for this bower version (' + + version + + ')' + ); - childProcess.execSync( - 'cd test/sample && rm -rf bower_components && ' + dir + '/bin/bower install --force', { stdio: [0, 1, 2] } - ); + var lastRelease = childProcess + .execSync('git tag | tail -1') + .toString() + .trim(); - var expectedPackages = ( - 'SHA-1 ace-builds almond angular angular-animate angular-bootstrap angular-charts angular-contenteditable ' + - 'angular-deckgrid angular-fullscreen angular-gravatar angular-hotkeys angular-local-storage angular-marked ' + - 'angular-moment angular-sanitize angular-touch angular-ui-router angular-ui-sortable ' + - 'angulartics asEvented bootstrap coffee-script d3 es6-shim font-awesome howler jquery ' + - 'jquery-ui jquery-waypoints js-beautify lodash lz-string marked moment ng-file-upload peerjs ' + - 'requirejs restangular slimScroll slimScrollHorizontal venturocket-angular-slider' - ).split(' '); + grunt.log.writeln( + 'Commits since last release (' + lastRelease + '): \n' + ); - var installedPackages = fs.readdirSync('./test/sample/bower_components'); + grunt.log.writeln( + childProcess + .execSync('git log --oneline ' + lastRelease + '..') + .toString() + ); - var installedDiff = arraydiff(expectedPackages, installedPackages); + process.exit(1); + } - if (installedDiff.length > 0) { - grunt.log.writeln('ERROR. Some packages were not installed by bower: '); - grunt.log.writeln(installedDiff.join(', ')); + if ( + childProcess + .execSync('git rev-parse --abbrev-ref HEAD') + .toString() + .trim() !== 'master' + ) { + grunt.log.writeln( + 'You need to release bower from the "master" branch' + ); - process.exit(1); - } + process.exit(1); + } - grunt.log.writeln('\nBower production bundle installed in:'); - grunt.log.writeln(dir + '\n'); + if (process.env.SKIP_TESTS !== '1') { + grunt.log.writeln('Reinstalling dependencies...'); + childProcess.execSync('rm -rf node_modules && npm install', { + stdio: [0, 1, 2] + }); - var questions = [ - { - type: 'confirm', - name: 'review', - message: 'Did you review all the changes with "git diff"?', - default: false - }, - { - type: 'confirm', - name: 'changelog', - message: 'Are you sure the CHANGELOG.md contains all changes?', - default: false - }, - { - type: 'confirm', - name: 'tests', - message: 'Are you sure all tests are passing on Travis and Appveyor?', - default: false - }, - { - type: 'confirm', - name: 'publish', - message: 'Are you SURE you want to publish ' + jsonPackage.name + '@' + jsonPackage.version + '?', - default: false + grunt.log.writeln('Running test suite...'); + childProcess.execSync('grunt test', { stdio: [0, 1, 2] }); } - ]; - var done = this.async(); - - inquirer.prompt(questions, function (answers) { - if (!answers.review || !answers.changelog || !answers.tests || !answers.publish) { - grunt.log.writeln('Please publish bower after you fix this issue'); + var dir = tmp.dirSync().name; + + wrench.copyDirSyncRecursive(__dirname, dir, { + forceDelete: true, + include: function(path) { + return !path.match(/node_modules|\.git|test/); + } + }); + + grunt.log.writeln('Installing production dependencies...'); + childProcess.execSync('npm install --production --silent', { + cwd: dir, + stdio: [0, 1, 2] + }); + + delete jsonPackage.dependencies; + delete jsonPackage.devDependencies; + delete jsonPackage.scripts; + + fs.writeFileSync( + path.resolve(dir, 'package.json'), + JSON.stringify(jsonPackage, null, ' ') + '\n' + ); + + grunt.log.writeln('Moving node_modules to lib directory...'); + + wrench.copyDirSyncRecursive( + path.resolve(dir, 'node_modules'), + path.resolve(dir, 'lib', 'node_modules') + ); + wrench.rmdirSyncRecursive(path.resolve(dir, 'node_modules')); + + grunt.log.writeln('Testing bower on sample project...'); + + childProcess.execSync( + 'cd test/sample && rm -rf bower_components && ' + + dir + + '/bin/bower install --force', + { stdio: [0, 1, 2] } + ); + + var expectedPackages = ( + 'SHA-1 ace-builds almond angular angular-animate angular-bootstrap angular-charts angular-contenteditable ' + + 'angular-deckgrid angular-fullscreen angular-gravatar angular-hotkeys angular-local-storage angular-marked ' + + 'angular-moment angular-sanitize angular-touch angular-ui-router angular-ui-sortable ' + + 'angulartics asEvented bootstrap coffee-script d3 es6-shim font-awesome howler jquery ' + + 'jquery-ui jquery-waypoints js-beautify lodash lz-string marked moment ng-file-upload peerjs ' + + 'requirejs restangular slimScroll slimScrollHorizontal venturocket-angular-slider' + ).split(' '); + + var installedPackages = fs.readdirSync( + './test/sample/bower_components' + ); + + var installedDiff = arraydiff(expectedPackages, installedPackages); + + if (installedDiff.length > 0) { + grunt.log.writeln( + 'ERROR. Some packages were not installed by bower: ' + ); + grunt.log.writeln(installedDiff.join(', ')); process.exit(1); } - grunt.log.writeln('\nPlease remember to tag this relese, and add a release on Github!'); - grunt.log.writeln('\nAlso, please remember to test published Bower one more time!'); - grunt.log.writeln('\nPublishing Bower...'); - - childProcess.execSync('npm publish --tag beta', { cwd: dir, stdio: [0, 1, 2] }); + grunt.log.writeln('\nBower production bundle installed in:'); + grunt.log.writeln(dir + '\n'); - done(); - }); - }); + var questions = [ + { + type: 'confirm', + name: 'review', + message: 'Did you review all the changes with "git diff"?', + default: false + }, + { + type: 'confirm', + name: 'changelog', + message: + 'Are you sure the CHANGELOG.md contains all changes?', + default: false + }, + { + type: 'confirm', + name: 'tests', + message: + 'Are you sure all tests are passing on Travis and Appveyor?', + default: false + }, + { + type: 'confirm', + name: 'publish', + message: + 'Are you SURE you want to publish ' + + jsonPackage.name + + '@' + + jsonPackage.version + + '?', + default: false + } + ]; + + var done = this.async(); + + inquirer.prompt(questions, function(answers) { + if ( + !answers.review || + !answers.changelog || + !answers.tests || + !answers.publish + ) { + grunt.log.writeln( + 'Please publish bower after you fix this issue' + ); + + process.exit(1); + } + + grunt.log.writeln( + '\nPlease remember to tag this relese, and add a release on Github!' + ); + grunt.log.writeln( + '\nAlso, please remember to test published Bower one more time!' + ); + grunt.log.writeln('\nPublishing Bower...'); + + childProcess.execSync('npm publish --tag beta', { + cwd: dir, + stdio: [0, 1, 2] + }); + + done(); + }); + } + ); }; diff --git a/lib/bin/bower.js b/lib/bin/bower.js index 5917bc171..e04ac4cc4 100644 --- a/lib/bin/bower.js +++ b/lib/bin/bower.js @@ -18,8 +18,8 @@ var logger; var levels = Logger.LEVELS; options = cli.readOptions({ - 'version': { type: Boolean, shorthand: 'v' }, - 'help': { type: Boolean, shorthand: 'h' }, + version: { type: Boolean, shorthand: 'v' }, + help: { type: Boolean, shorthand: 'h' }, 'allow-root': { type: Boolean } }); @@ -73,12 +73,12 @@ command = command && command.replace(/\./g, ' '); if (!commandFunc) { logger = bower.commands.help(); command = 'help'; -// If the user requested help, show the command's help -// Do the same if the actual command is a group of other commands (e.g.: cache) + // If the user requested help, show the command's help + // Do the same if the actual command is a group of other commands (e.g.: cache) } else if (options.help || !commandFunc.line) { logger = bower.commands.help(command); command = 'help'; -// Call the line method + // Call the line method } else { logger = commandFunc.line(process.argv); @@ -95,42 +95,47 @@ renderer = cli.getRenderer(command, logger.json, bower.config); function handleLogger(logger, renderer) { logger - .on('end', function (data) { - if (!bower.config.silent && !bower.config.quiet) { - renderer.end(data); - } - }) - .on('error', function (err) { - if (command !== 'help' && (err.code === 'EREADOPTIONS' || err.code === 'EINVFORMAT')) { - logger = bower.commands.help(command); - renderer = cli.getRenderer('help', logger.json, bower.config); - handleLogger(logger, renderer); - } else { - if (levels.error >= loglevel) { - renderer.error(err); + .on('end', function(data) { + if (!bower.config.silent && !bower.config.quiet) { + renderer.end(data); } - - process.exit(1); - } - }) - .on('log', function (log) { - if (levels[log.level] >= loglevel) { - renderer.log(log); - } - }) - .on('prompt', function (prompt, callback) { - renderer.prompt(prompt) - .then(function (answer) { - callback(answer); + }) + .on('error', function(err) { + if ( + command !== 'help' && + (err.code === 'EREADOPTIONS' || err.code === 'EINVFORMAT') + ) { + logger = bower.commands.help(command); + renderer = cli.getRenderer('help', logger.json, bower.config); + handleLogger(logger, renderer); + } else { + if (levels.error >= loglevel) { + renderer.error(err); + } + + process.exit(1); + } + }) + .on('log', function(log) { + if (levels[log.level] >= loglevel) { + renderer.log(log); + } + }) + .on('prompt', function(prompt, callback) { + renderer.prompt(prompt).then(function(answer) { + callback(answer); + }); }); - }); } handleLogger(logger, renderer); // Warn if HOME is not SET if (!userHome) { - logger.warn('no-home', 'HOME environment variable not set. User config will not be loaded.'); + logger.warn( + 'no-home', + 'HOME environment variable not set. User config will not be loaded.' + ); } if (bower.config.interactive) { diff --git a/lib/commands/cache/clean.js b/lib/commands/cache/clean.js index 5a6e3ef31..22b792c37 100644 --- a/lib/commands/cache/clean.js +++ b/lib/commands/cache/clean.js @@ -22,10 +22,10 @@ function clean(logger, endpoints, options, config) { // Generate decomposed endpoints and names based on the endpoints if (endpoints) { - decEndpoints = endpoints.map(function (endpoint) { + decEndpoints = endpoints.map(function(endpoint) { return endpointParser.decompose(endpoint); }); - names = decEndpoints.map(function (decEndpoint) { + names = decEndpoints.map(function(decEndpoint) { return decEndpoint.name || decEndpoint.source; }); } @@ -33,27 +33,26 @@ function clean(logger, endpoints, options, config) { return Q.all([ clearPackages(decEndpoints, config, logger), clearLinks(names, config, logger) - ]) - .spread(function (entries) { + ]).spread(function(entries) { return entries; }); } function clearPackages(decEndpoints, config, logger) { - var repository = new PackageRepository(config, logger); + var repository = new PackageRepository(config, logger); - return repository.list() - .then(function (entries) { + return repository.list().then(function(entries) { var promises; // Filter entries according to the specified packages if (decEndpoints) { - entries = entries.filter(function (entry) { - return !!mout.array.find(decEndpoints, function (decEndpoint) { + entries = entries.filter(function(entry) { + return !!mout.array.find(decEndpoints, function(decEndpoint) { var entryPkgMeta = entry.pkgMeta; // Check if name or source match the entry - if (decEndpoint.name !== entryPkgMeta.name && + if ( + decEndpoint.name !== entryPkgMeta.name && decEndpoint.source !== entryPkgMeta.name && decEndpoint.source !== entryPkgMeta._source ) { @@ -67,36 +66,47 @@ function clearPackages(decEndpoints, config, logger) { // If it's a semver target, compare using semver spec if (semver.validRange(decEndpoint.target)) { - return semver.satisfies(entryPkgMeta.version, decEndpoint.target); + return semver.satisfies( + entryPkgMeta.version, + decEndpoint.target + ); } // Otherwise, compare against target/release - return decEndpoint.target === entryPkgMeta._target || - decEndpoint.target === entryPkgMeta._release; + return ( + decEndpoint.target === entryPkgMeta._target || + decEndpoint.target === entryPkgMeta._release + ); }); }); } - promises = entries.map(function (entry) { - return repository.eliminate(entry.pkgMeta) - .then(function () { - logger.info('deleted', 'Cached package ' + entry.pkgMeta.name + ': ' + entry.canonicalDir, { - file: entry.canonicalDir - }); + promises = entries.map(function(entry) { + return repository.eliminate(entry.pkgMeta).then(function() { + logger.info( + 'deleted', + 'Cached package ' + + entry.pkgMeta.name + + ': ' + + entry.canonicalDir, + { + file: entry.canonicalDir + } + ); }); }); return Q.all(promises) - .then(function () { - if (!decEndpoints) { - // Ensure that everything is cleaned, - // even invalid packages in the cache - return repository.clear(); - } - }) - .then(function () { - return entries; - }); + .then(function() { + if (!decEndpoints) { + // Ensure that everything is cleaned, + // even invalid packages in the cache + return repository.clear(); + } + }) + .then(function() { + return entries; + }); }); } @@ -106,59 +116,59 @@ function clearLinks(names, config, logger) { // If no names are passed, grab all links if (!names) { - promise = Q.nfcall(fs.readdir, dir) - .fail(function (err) { + promise = Q.nfcall(fs.readdir, dir).fail(function(err) { if (err.code === 'ENOENT') { return []; } throw err; }); - // Otherwise use passed ones + // Otherwise use passed ones } else { promise = Q.resolve(names); } - return promise - .then(function (names) { + return promise.then(function(names) { var promises; var linksToRemove = []; // Decide which links to delete - promises = names.map(function (name) { + promises = names.map(function(name) { var link = path.join(config.storage.links, name); - return Q.nfcall(fs.readlink, link) - .then(function (linkTarget) { - // Link exists, check if it points to a folder - // that still exists - return Q.nfcall(fs.stat, linkTarget) - .then(function (stat) { - // Target is not a folder.. - if (!stat.isDirectory()) { + return Q.nfcall(fs.readlink, link).then( + function(linkTarget) { + // Link exists, check if it points to a folder + // that still exists + return ( + Q.nfcall(fs.stat, linkTarget) + .then(function(stat) { + // Target is not a folder.. + if (!stat.isDirectory()) { + linksToRemove.push(link); + } + }) + // Error occurred reading the link + .fail(function() { + linksToRemove.push(link); + }) + ); + // Ignore if link does not exist + }, + function(err) { + if (err.code !== 'ENOENT') { linksToRemove.push(link); } - }) - // Error occurred reading the link - .fail(function () { - linksToRemove.push(link); - }); - // Ignore if link does not exist - }, function (err) { - if (err.code !== 'ENOENT') { - linksToRemove.push(link); } - }); + ); }); - return Q.all(promises) - .then(function () { + return Q.all(promises).then(function() { var promises; // Remove each link that was declared as invalid - promises = linksToRemove.map(function (link) { - return Q.nfcall(rimraf, link) - .then(function () { + promises = linksToRemove.map(function(link) { + return Q.nfcall(rimraf, link).then(function() { logger.info('deleted', 'Invalid link: ' + link, { file: link }); @@ -172,7 +182,7 @@ function clearLinks(names, config, logger) { // ------------------- -clean.readOptions = function (argv) { +clean.readOptions = function(argv) { var cli = require('../../util/cli'); var options = cli.readOptions(argv); var endpoints = options.argv.remain.slice(2); diff --git a/lib/commands/cache/list.js b/lib/commands/cache/list.js index f5b2fb3f4..fe12bc143 100644 --- a/lib/commands/cache/list.js +++ b/lib/commands/cache/list.js @@ -13,12 +13,11 @@ function list(logger, packages, options, config) { packages = null; } - return repository.list() - .then(function (entries) { + return repository.list().then(function(entries) { if (packages) { // Filter entries according to the specified packages - entries = entries.filter(function (entry) { - return !!mout.array.find(packages, function (pkg) { + entries = entries.filter(function(entry) { + return !!mout.array.find(packages, function(pkg) { return pkg === entry.pkgMeta.name; }); }); @@ -30,7 +29,7 @@ function list(logger, packages, options, config) { // ------------------- -list.readOptions = function (argv) { +list.readOptions = function(argv) { var cli = require('../../util/cli'); var options = cli.readOptions(argv); var packages = options.argv.remain.slice(2); diff --git a/lib/commands/help.js b/lib/commands/help.js index 4501daf76..24141d1a7 100644 --- a/lib/commands/help.js +++ b/lib/commands/help.js @@ -7,15 +7,17 @@ function help(logger, name, config) { var json; if (name) { - json = path.resolve(__dirname, '../templates/json/help-' + name.replace(/\s+/g, '/') + '.json'); + json = path.resolve( + __dirname, + '../templates/json/help-' + name.replace(/\s+/g, '/') + '.json' + ); } else { json = path.resolve(__dirname, '../templates/json/help.json'); } - return Q.promise(function (resolve) { + return Q.promise(function(resolve) { fs.exists(json, resolve); - }) - .then(function (exists) { + }).then(function(exists) { if (!exists) { throw createError('Unknown command: ' + name, 'EUNKNOWNCMD', { command: name @@ -28,7 +30,7 @@ function help(logger, name, config) { // ------------------- -help.readOptions = function (argv) { +help.readOptions = function(argv) { var cli = require('../util/cli'); var options = cli.readOptions(argv); var name = options.argv.remain.slice(1).join(' '); diff --git a/lib/commands/home.js b/lib/commands/home.js index 028c922a4..76a40e472 100644 --- a/lib/commands/home.js +++ b/lib/commands/home.js @@ -16,8 +16,7 @@ function home(logger, name, config) { // If no name is specified, read the project json // If a name is specified, fetch from the package repository if (!name) { - promise = project.hasJson() - .then(function (json) { + promise = project.hasJson().then(function(json) { if (!json) { throw createError('You are not inside a package', 'ENOENT'); } @@ -26,14 +25,16 @@ function home(logger, name, config) { }); } else { decEndpoint = endpointParser.decompose(name); - promise = project.getPackageRepository().fetch(decEndpoint) - .spread(function (canonicalDir, pkgMeta) { - return pkgMeta; - }); + promise = project + .getPackageRepository() + .fetch(decEndpoint) + .spread(function(canonicalDir, pkgMeta) { + return pkgMeta; + }); } // Get homepage and open it - return promise.then(function (pkgMeta) { + return promise.then(function(pkgMeta) { var homepage = pkgMeta.homepage; if (!homepage) { @@ -47,7 +48,7 @@ function home(logger, name, config) { // ------------------- -home.readOptions = function (argv) { +home.readOptions = function(argv) { var cli = require('../util/cli'); var options = cli.readOptions(argv); var name = options.argv.remain[1]; diff --git a/lib/commands/index.js b/lib/commands/index.js index e55ddf464..622e53a17 100644 --- a/lib/commands/index.js +++ b/lib/commands/index.js @@ -14,7 +14,7 @@ function commandFactory(id) { var command = require(id); var commandArgs = [].slice.call(arguments); - return withLogger(function (logger) { + return withLogger(function(logger) { commandArgs.unshift(logger); return command.apply(undefined, commandArgs); @@ -27,7 +27,7 @@ function commandFactory(id) { commandArgs = command.readOptions(argv); - return withLogger(function (logger) { + return withLogger(function(logger) { commandArgs.unshift(logger); return command.apply(undefined, commandArgs); @@ -37,16 +37,18 @@ function commandFactory(id) { function withLogger(func) { var logger = new Logger(); - Q.try(func, logger) - .done(function () { - config.restore(); - var args = [].slice.call(arguments); - args.unshift('end'); - logger.emit.apply(logger, args); - }, function (error) { - config.restore(); - logger.emit('error', error); - }); + Q.try(func, logger).done( + function() { + config.restore(); + var args = [].slice.call(arguments); + args.unshift('end'); + logger.emit.apply(logger, args); + }, + function(error) { + config.restore(); + logger.emit('error', error); + } + ); return logger; } @@ -56,11 +58,10 @@ function commandFactory(id) { return runApi; } - module.exports = { cache: { clean: commandFactory('./cache/clean'), - list: commandFactory('./cache/list'), + list: commandFactory('./cache/list') }, help: commandFactory('./help'), home: commandFactory('./home'), diff --git a/lib/commands/info.js b/lib/commands/info.js index ae9b9ab6f..4d5332491 100644 --- a/lib/commands/info.js +++ b/lib/commands/info.js @@ -11,10 +11,11 @@ function info(logger, endpoint, property, config) { // handle @ as version divider var splitParts = endpoint.split('/'); - splitParts[splitParts.length - 1] = splitParts[splitParts.length - 1].replace('@', '#'); + splitParts[splitParts.length - 1] = splitParts[ + splitParts.length - 1 + ].replace('@', '#'); endpoint = splitParts.join('/'); - var repository; var decEndpoint; @@ -25,25 +26,27 @@ function info(logger, endpoint, property, config) { return Q.all([ getPkgMeta(repository, decEndpoint, property), - decEndpoint.target === '*' && !property ? repository.versions(decEndpoint.source) : null - ]) - .spread(function (pkgMeta, versions) { - if (versions) { - return { - name: decEndpoint.source, - versions: versions, - latest: pkgMeta - }; - } + decEndpoint.target === '*' && !property + ? repository.versions(decEndpoint.source) + : null + ]).spread(function(pkgMeta, versions) { + if (versions) { + return { + name: decEndpoint.source, + versions: versions, + latest: pkgMeta + }; + } - return pkgMeta; - }); + return pkgMeta; + }); } function getPkgMeta(repository, decEndpoint, property) { - return repository.fetch(decEndpoint) - .spread(function (canonicalDir, pkgMeta) { - pkgMeta = mout.object.filter(pkgMeta, function (value, key) { + return repository + .fetch(decEndpoint) + .spread(function(canonicalDir, pkgMeta) { + pkgMeta = mout.object.filter(pkgMeta, function(value, key) { return key.charAt(0) !== '_'; }); @@ -58,7 +61,7 @@ function getPkgMeta(repository, decEndpoint, property) { // ------------------- -info.readOptions = function (argv) { +info.readOptions = function(argv) { var cli = require('../util/cli'); var options = cli.readOptions(argv); var pkg = options.argv.remain[1]; diff --git a/lib/commands/init.js b/lib/commands/init.js index 71db0c7fe..6526821d3 100644 --- a/lib/commands/init.js +++ b/lib/commands/init.js @@ -23,31 +23,38 @@ function init(logger, config) { // This command requires interactive to be enabled if (!config.interactive) { throw createError('Register requires an interactive shell', 'ENOINT', { - details: 'Note that you can manually force an interactive shell with --config.interactive' + details: + 'Note that you can manually force an interactive shell with --config.interactive' }); } project = new Project(config, logger); // Start with existing JSON details - return readJson(project, logger) - // Fill in defaults - .then(setDefaults.bind(null, config)) - // Now prompt user to make changes - .then(promptUser.bind(null, logger)) - // Set ignore based on the response - .spread(setIgnore.bind(null, config)) - // Set dependencies based on the response - .spread(setDependencies.bind(null, project)) - // All done! - .spread(saveJson.bind(null, project, logger)); + return ( + readJson(project, logger) + // Fill in defaults + .then(setDefaults.bind(null, config)) + // Now prompt user to make changes + .then(promptUser.bind(null, logger)) + // Set ignore based on the response + .spread(setIgnore.bind(null, config)) + // Set dependencies based on the response + .spread(setDependencies.bind(null, project)) + // All done! + .spread(saveJson.bind(null, project, logger)) + ); } function readJson(project, logger) { - return project.hasJson() - .then(function (json) { + return project.hasJson().then(function(json) { if (json) { - logger.warn('existing', 'The existing ' + path.basename(json) + ' file will be used and filled in'); + logger.warn( + 'existing', + 'The existing ' + + path.basename(json) + + ' file will be used and filled in' + ); } return project.getJson(); @@ -56,7 +63,7 @@ function readJson(project, logger) { function saveJson(project, logger, json) { // Cleanup empty props (null values, empty strings, objects and arrays) - mout.object.forOwn(json, function (value, key) { + mout.object.forOwn(json, function(value, key) { if (!validConfigValue(value)) { delete json[key]; } @@ -69,8 +76,7 @@ function saveJson(project, logger, json) { type: 'confirm', message: 'Looks good?', default: true - }) - .then(function (good) { + }).then(function(good) { if (!good) { return null; } @@ -84,9 +90,9 @@ function saveJson(project, logger, json) { // [0]: https://github.com/bower/bower.json-spec function validConfigValue(val) { return ( - mout.lang.isObject(val) || - mout.lang.isArray(val) || - mout.lang.isString(val) || + mout.lang.isObject(val) || + mout.lang.isArray(val) || + mout.lang.isString(val) || mout.lang.isBoolean(val) || mout.lang.isNumber(val) ); @@ -116,52 +122,70 @@ function setDefaults(config, json) { // Homepage if (!json.homepage) { // Set as GitHub homepage if it's a GitHub repository - promise = promise.then(function () { + promise = promise.then(function() { return cmd('git', ['config', '--get', 'remote.origin.url']) - .spread(function (stdout) { - var pair; - - stdout = stdout.trim(); - if (!stdout) { - return; - } - - pair = GitHubResolver.getOrgRepoPair(stdout); - if (pair) { - json.homepage = 'https://github.com/' + pair.org + '/' + pair.repo; - } - }) - .fail(function () { }); + .spread(function(stdout) { + var pair; + + stdout = stdout.trim(); + if (!stdout) { + return; + } + + pair = GitHubResolver.getOrgRepoPair(stdout); + if (pair) { + json.homepage = + 'https://github.com/' + pair.org + '/' + pair.repo; + } + }) + .fail(function() {}); }); } if (!json.authors) { - promise = promise.then(function () { + promise = promise.then(function() { // Get the user name configured in git - return cmd('git', ['config', '--get', '--global', 'user.name']) - .spread(function (stdout) { - var gitEmail; - var gitName = stdout.trim(); - - // Abort if no name specified - if (!gitName) { - return; - } - - // Get the user email configured in git - return cmd('git', ['config', '--get', '--global', 'user.email']) - .spread(function (stdout) { - gitEmail = stdout.trim(); - }, function () {}) - .then(function () { - json.authors = gitName; - json.authors += gitEmail ? ' <' + gitEmail + '>' : ''; - }); - }, function () {}); + return cmd('git', [ + 'config', + '--get', + '--global', + 'user.name' + ]).spread( + function(stdout) { + var gitEmail; + var gitName = stdout.trim(); + + // Abort if no name specified + if (!gitName) { + return; + } + + // Get the user email configured in git + return cmd('git', [ + 'config', + '--get', + '--global', + 'user.email' + ]) + .spread( + function(stdout) { + gitEmail = stdout.trim(); + }, + function() {} + ) + .then(function() { + json.authors = gitName; + json.authors += gitEmail + ? ' <' + gitEmail + '>' + : ''; + }); + }, + function() {} + ); }); } - return promise.then(function () { + return promise.then(function() { return json; }); } @@ -169,69 +193,73 @@ function setDefaults(config, json) { function promptUser(logger, json) { var questions = [ { - 'name': 'name', - 'message': 'name', - 'default': json.name, - 'type': 'input' + name: 'name', + message: 'name', + default: json.name, + type: 'input' }, { - 'name': 'description', - 'message': 'description', - 'default': json.description, - 'type': 'input' + name: 'description', + message: 'description', + default: json.description, + type: 'input' }, { - 'name': 'main', - 'message': 'main file', - 'default': json.main, - 'type': 'input' + name: 'main', + message: 'main file', + default: json.main, + type: 'input' }, { - 'name': 'keywords', - 'message': 'keywords', - 'default': json.keywords ? json.keywords.toString() : null, - 'type': 'input' + name: 'keywords', + message: 'keywords', + default: json.keywords ? json.keywords.toString() : null, + type: 'input' }, { - 'name': 'authors', - 'message': 'authors', - 'default': json.authors ? json.authors.toString() : null, - 'type': 'input' + name: 'authors', + message: 'authors', + default: json.authors ? json.authors.toString() : null, + type: 'input' }, { - 'name': 'license', - 'message': 'license', - 'default': json.license || 'MIT', - 'type': 'input' + name: 'license', + message: 'license', + default: json.license || 'MIT', + type: 'input' }, { - 'name': 'homepage', - 'message': 'homepage', - 'default': json.homepage, - 'type': 'input' + name: 'homepage', + message: 'homepage', + default: json.homepage, + type: 'input' }, { - 'name': 'dependencies', - 'message': 'set currently installed components as dependencies?', - 'default': !mout.object.size(json.dependencies) && !mout.object.size(json.devDependencies), - 'type': 'confirm' + name: 'dependencies', + message: 'set currently installed components as dependencies?', + default: + !mout.object.size(json.dependencies) && + !mout.object.size(json.devDependencies), + type: 'confirm' }, { - 'name': 'ignore', - 'message': 'add commonly ignored files to ignore list?', - 'default': true, - 'type': 'confirm' + name: 'ignore', + message: 'add commonly ignored files to ignore list?', + default: true, + type: 'confirm' }, { - 'name': 'private', - 'message': 'would you like to mark this package as private which prevents it from being accidentally published to the registry?', - 'default': !!json.private, - 'type': 'confirm' + name: 'private', + message: + 'would you like to mark this package as private which prevents it from being accidentally published to the registry?', + default: !!json.private, + type: 'confirm' } ]; - return Q.nfcall(logger.prompt.bind(logger), questions) - .then(function (answers) { + return Q.nfcall(logger.prompt.bind(logger), questions).then(function( + answers + ) { json.name = answers.name; json.description = answers.description; json.main = answers.main; @@ -249,12 +277,12 @@ function toArray(value, splitter) { var arr = value.split(splitter || /[\s,]/); // Trim values - arr = arr.map(function (item) { + arr = arr.map(function(item) { return item.trim(); }); // Filter empty values - arr = arr.filter(function (item) { + arr = arr.filter(function(item) { return !!item; }); @@ -278,13 +306,12 @@ function setIgnore(config, json, answers) { function setDependencies(project, json, answers) { if (answers.dependencies) { - return project.getTree() - .spread(function (tree, flattened, extraneous) { + return project.getTree().spread(function(tree, flattened, extraneous) { if (extraneous.length) { json.dependencies = {}; // Add extraneous as dependencies - extraneous.forEach(function (extra) { + extraneous.forEach(function(extra) { var jsonEndpoint; // Skip linked packages @@ -292,7 +319,9 @@ function setDependencies(project, json, answers) { return; } - jsonEndpoint = endpointParser.decomposed2json(extra.endpoint); + jsonEndpoint = endpointParser.decomposed2json( + extra.endpoint + ); mout.object.mixIn(json.dependencies, jsonEndpoint); }); } @@ -306,7 +335,7 @@ function setDependencies(project, json, answers) { // ------------------- -init.readOptions = function (argv) { +init.readOptions = function(argv) { return []; }; diff --git a/lib/commands/install.js b/lib/commands/install.js index c2b87dedf..47ba130b5 100644 --- a/lib/commands/install.js +++ b/lib/commands/install.js @@ -15,11 +15,12 @@ function install(logger, endpoints, options, config) { // Convert endpoints to decomposed endpoints endpoints = endpoints || []; - decEndpoints = endpoints.map(function (endpoint) { - + decEndpoints = endpoints.map(function(endpoint) { // handle @ as version divider var splitParts = endpoint.split('/'); - splitParts[splitParts.length - 1] = splitParts[splitParts.length - 1].replace('@', '#'); + splitParts[splitParts.length - 1] = splitParts[ + splitParts.length - 1 + ].replace('@', '#'); endpoint = splitParts.join('/'); return endpointParser.decompose(endpoint); @@ -30,16 +31,19 @@ function install(logger, endpoints, options, config) { // ------------------- -install.readOptions = function (argv) { +install.readOptions = function(argv) { var cli = require('../util/cli'); - var options = cli.readOptions({ - 'force-latest': {type: Boolean, shorthand: 'F'}, - 'production': {type: Boolean, shorthand: 'p'}, - 'save': {type: Boolean, shorthand: 'S'}, - 'save-dev': {type: Boolean, shorthand: 'D'}, - 'save-exact': {type: Boolean, shorthand: 'E'} - }, argv); + var options = cli.readOptions( + { + 'force-latest': { type: Boolean, shorthand: 'F' }, + production: { type: Boolean, shorthand: 'p' }, + save: { type: Boolean, shorthand: 'S' }, + 'save-dev': { type: Boolean, shorthand: 'D' }, + 'save-exact': { type: Boolean, shorthand: 'E' } + }, + argv + ); var packages = options.argv.remain.slice(1); diff --git a/lib/commands/link.js b/lib/commands/link.js index 7cf12cf8f..d7f77b261 100644 --- a/lib/commands/link.js +++ b/lib/commands/link.js @@ -20,23 +20,24 @@ function linkSelf(logger, config) { config = defaultConfig(config); project = new Project(config, logger); - return project.getJson() - .then(function (json) { + return project.getJson().then(function(json) { var src = config.cwd; var dst = path.join(config.storage.links, json.name); // Delete previous link if any - return Q.nfcall(rimraf, dst) - // Link globally - .then(function () { - return createLink(src, dst); - }) - .then(function () { - return { - src: src, - dst: dst - }; - }); + return ( + Q.nfcall(rimraf, dst) + // Link globally + .then(function() { + return createLink(src, dst); + }) + .then(function() { + return { + src: src, + dst: dst + }; + }) + ); }); } @@ -53,27 +54,29 @@ function linkTo(logger, name, localName, config) { dst = path.join(relativeToBaseDir(config.cwd)(config.directory), localName); // Delete destination folder if any - return Q.nfcall(rimraf, dst) - // Link locally - .then(function () { - return createLink(src, dst); - }) - // Install linked package deps - .then(function () { - return project.update([localName]); - }) - .then(function (installed) { - return { - src: src, - dst: dst, - installed: installed - }; - }); + return ( + Q.nfcall(rimraf, dst) + // Link locally + .then(function() { + return createLink(src, dst); + }) + // Install linked package deps + .then(function() { + return project.update([localName]); + }) + .then(function(installed) { + return { + src: src, + dst: dst, + installed: installed + }; + }) + ); } // ------------------- -link.readOptions = function (argv) { +link.readOptions = function(argv) { var cli = require('../util/cli'); var options = cli.readOptions(argv); var name = options.argv.remain[1]; diff --git a/lib/commands/list.js b/lib/commands/list.js index a9afcb54c..9ade305ea 100644 --- a/lib/commands/list.js +++ b/lib/commands/list.js @@ -11,39 +11,48 @@ function list(logger, options, config) { options = options || {}; // Make relative option true by default when used with paths - if (options.paths && options.relative == null) { + if (options.paths && options.relative == null) { options.relative = true; } config = defaultConfig(config); project = new Project(config, logger); - return project.getTree(options) - .spread(function (tree, flattened) { + return project.getTree(options).spread(function(tree, flattened) { // Relativize paths // Also normalize paths on windows - project.walkTree(tree, function (node) { - if (node.missing) { - return; - } - - if (options.relative) { - node.canonicalDir = path.relative(config.cwd, node.canonicalDir); - } - if (options.paths) { - node.canonicalDir = normalize(node.canonicalDir); - } - }, true); + project.walkTree( + tree, + function(node) { + if (node.missing) { + return; + } + + if (options.relative) { + node.canonicalDir = path.relative( + config.cwd, + node.canonicalDir + ); + } + if (options.paths) { + node.canonicalDir = normalize(node.canonicalDir); + } + }, + true + ); // Note that we need to to parse the flattened tree because it might // contain additional packages - mout.object.forOwn(flattened, function (node) { + mout.object.forOwn(flattened, function(node) { if (node.missing) { return; } if (options.relative) { - node.canonicalDir = path.relative(config.cwd, node.canonicalDir); + node.canonicalDir = path.relative( + config.cwd, + node.canonicalDir + ); } if (options.paths) { node.canonicalDir = normalize(node.canonicalDir); @@ -61,8 +70,7 @@ function list(logger, options, config) { } // Check for new versions - return checkVersions(project, tree, logger) - .then(function () { + return checkVersions(project, tree, logger).then(function() { return tree; }); }); @@ -74,32 +82,40 @@ function checkVersions(project, tree, logger) { var repository = project.getPackageRepository(); // Gather all nodes, ignoring linked nodes - project.walkTree(tree, function (node) { - if (!node.linked) { - nodes.push(node); - } - }, true); + project.walkTree( + tree, + function(node) { + if (!node.linked) { + nodes.push(node); + } + }, + true + ); if (nodes.length) { - logger.info('check-new', 'Checking for new versions of the project dependencies...'); + logger.info( + 'check-new', + 'Checking for new versions of the project dependencies...' + ); } // Check for new versions for each node - promises = nodes.map(function (node) { + promises = nodes.map(function(node) { var target = node.endpoint.target; - return repository.versions(node.endpoint.source) - .then(function (versions) { - node.versions = versions; - - // Do not check if node's target is not a valid semver one - if (versions.length && semver.validRange(target)) { - node.update = { - target: semver.maxSatisfying(versions, target), - latest: semver.maxSatisfying(versions, '*') - }; - } - }); + return repository + .versions(node.endpoint.source) + .then(function(versions) { + node.versions = versions; + + // Do not check if node's target is not a valid semver one + if (versions.length && semver.validRange(target)) { + node.update = { + target: semver.maxSatisfying(versions, target), + latest: semver.maxSatisfying(versions, '*') + }; + } + }); }); // Set the versions also for the root node @@ -111,7 +127,7 @@ function checkVersions(project, tree, logger) { function paths(flattened) { var ret = {}; - mout.object.forOwn(flattened, function (pkg, name) { + mout.object.forOwn(flattened, function(pkg, name) { var main; if (pkg.missing) { @@ -132,7 +148,7 @@ function paths(flattened) { } // Concatenate each main entry with the canonical dir - main = main.map(function (part) { + main = main.map(function(part) { return normalize(path.join(pkg.canonicalDir, part).trim()); }); @@ -150,13 +166,16 @@ function normalize(src) { // ------------------- -list.readOptions = function (argv) { +list.readOptions = function(argv) { var cli = require('../util/cli'); - var options = cli.readOptions({ - 'paths': { type: Boolean, shorthand: 'p' }, - 'relative': { type: Boolean, shorthand: 'r' } - }, argv); + var options = cli.readOptions( + { + paths: { type: Boolean, shorthand: 'p' }, + relative: { type: Boolean, shorthand: 'r' } + }, + argv + ); delete options.argv; diff --git a/lib/commands/login.js b/lib/commands/login.js index 990ba088f..1230165c4 100644 --- a/lib/commands/login.js +++ b/lib/commands/login.js @@ -19,24 +19,28 @@ function login(logger, options, config) { } else { // This command requires interactive to be enabled if (!config.interactive) { - logger.emit('error', createError('Login requires an interactive shell', 'ENOINT', { - details: 'Note that you can manually force an interactive shell with --config.interactive' - })); + logger.emit( + 'error', + createError('Login requires an interactive shell', 'ENOINT', { + details: + 'Note that you can manually force an interactive shell with --config.interactive' + }) + ); return; } var questions = [ { - 'name': 'username', - 'message': 'Username', - 'type': 'input', - 'default': configstore.get('username') + name: 'username', + message: 'Username', + type: 'input', + default: configstore.get('username') }, { - 'name': 'password', - 'message': 'Password', - 'type': 'password' + name: 'password', + message: 'Password', + type: 'password' } ]; @@ -44,8 +48,9 @@ function login(logger, options, config) { version: '3.0.0' }); - promise = Q.nfcall(logger.prompt.bind(logger), questions) - .then(function (answers) { + promise = Q.nfcall(logger.prompt.bind(logger), questions).then(function( + answers + ) { configstore.set('username', answers.username); github.authenticate({ @@ -56,66 +61,91 @@ function login(logger, options, config) { return Q.ninvoke(github.authorization, 'create', { scopes: ['user', 'repo'], - note: 'Bower command line client (' + (new Date()).toISOString() + ')' + note: + 'Bower command line client (' + + new Date().toISOString() + + ')' }); }); } - return promise.then(function (result) { - configstore.set('accessToken', result.token); - logger.info('EAUTH', 'Logged in as ' + configstore.get('username'), {}); - - return result; - }, function (error) { - var message; - - try { - message = JSON.parse(error.message).message; - } catch (e) { - message = 'Authorization failed'; - } - - var questions = [ - { - 'name': 'otpcode', - 'message': 'Two-Factor Auth Code', - 'type': 'input' + return promise.then( + function(result) { + configstore.set('accessToken', result.token); + logger.info( + 'EAUTH', + 'Logged in as ' + configstore.get('username'), + {} + ); + + return result; + }, + function(error) { + var message; + + try { + message = JSON.parse(error.message).message; + } catch (e) { + message = 'Authorization failed'; } - ]; - if (message === 'Must specify two-factor authentication OTP code.') { - return Q.nfcall(logger.prompt.bind(logger), questions) - .then(function (answers) { - return Q.ninvoke(github.authorization, 'create', { - scopes: ['user', 'repo'], - note: 'Bower command line client (' + (new Date()).toISOString() + ')', - headers: { - 'X-GitHub-OTP': answers.otpcode - } - }); - }) - .then(function (result) { - configstore.set('accessToken', result.token); - logger.info('EAUTH', 'Logged in as ' + configstore.get('username'), {}); - - return result; - }, function () { + var questions = [ + { + name: 'otpcode', + message: 'Two-Factor Auth Code', + type: 'input' + } + ]; + + if ( + message === 'Must specify two-factor authentication OTP code.' + ) { + return Q.nfcall(logger.prompt.bind(logger), questions) + .then(function(answers) { + return Q.ninvoke(github.authorization, 'create', { + scopes: ['user', 'repo'], + note: + 'Bower command line client (' + + new Date().toISOString() + + ')', + headers: { + 'X-GitHub-OTP': answers.otpcode + } + }); + }) + .then( + function(result) { + configstore.set('accessToken', result.token); + logger.info( + 'EAUTH', + 'Logged in as ' + configstore.get('username'), + {} + ); + + return result; + }, + function() { + logger.emit('error', createError(message, 'EAUTH')); + } + ); + } else { logger.emit('error', createError(message, 'EAUTH')); - }); - } else { - logger.emit('error', createError(message, 'EAUTH')); + } } - }); + ); } // ------------------- -login.readOptions = function (argv) { +login.readOptions = function(argv) { var cli = require('../util/cli'); - var options = cli.readOptions({ - token: { type: String, shorthand: 't' }, - }, argv); + var options = cli.readOptions( + { + token: { type: String, shorthand: 't' } + }, + argv + ); delete options.argv; diff --git a/lib/commands/lookup.js b/lib/commands/lookup.js index 9027836db..883751046 100644 --- a/lib/commands/lookup.js +++ b/lib/commands/lookup.js @@ -12,18 +12,21 @@ function lookup(logger, name, config) { var repository = new PackageRepository(config, logger); var registryClient = repository.getRegistryClient(); - return Q.nfcall(registryClient.lookup.bind(registryClient), name) - .then(function (entry) { - return !entry ? null : { - name: name, - url: entry.url - }; - }); + return Q.nfcall(registryClient.lookup.bind(registryClient), name).then( + function(entry) { + return !entry + ? null + : { + name: name, + url: entry.url + }; + } + ); } // ------------------- -lookup.readOptions = function (argv) { +lookup.readOptions = function(argv) { var cli = require('../util/cli'); var options = cli.readOptions(argv); var name = options.argv.remain[1]; diff --git a/lib/commands/prune.js b/lib/commands/prune.js index c57bbe484..2e71be584 100644 --- a/lib/commands/prune.js +++ b/lib/commands/prune.js @@ -17,35 +17,40 @@ function clean(project, options, removed) { // Continually call clean until there is no more extraneous // dependencies to remove - return project.getTree(options) - .spread(function (tree, flattened, extraneous) { - var names = extraneous.map(function (extra) { - return extra.endpoint.name; + return project + .getTree(options) + .spread(function(tree, flattened, extraneous) { + var names = extraneous.map(function(extra) { + return extra.endpoint.name; + }); + + // Uninstall extraneous + return project + .uninstall(names, options) + .then(function(uninstalled) { + // Are we done? + if (!mout.object.size(uninstalled)) { + return removed; + } + + // Not yet, recurse! + mout.object.mixIn(removed, uninstalled); + return clean(project, options, removed); + }); }); - - // Uninstall extraneous - return project.uninstall(names, options) - .then(function (uninstalled) { - // Are we done? - if (!mout.object.size(uninstalled)) { - return removed; - } - - // Not yet, recurse! - mout.object.mixIn(removed, uninstalled); - return clean(project, options, removed); - }); - }); } // ------------------- -prune.readOptions = function (argv) { +prune.readOptions = function(argv) { var cli = require('../util/cli'); - var options = cli.readOptions({ - 'production': { type: Boolean, shorthand: 'p' }, - }, argv); + var options = cli.readOptions( + { + production: { type: Boolean, shorthand: 'p' } + }, + argv + ); delete options.argv; diff --git a/lib/commands/register.js b/lib/commands/register.js index db56a7352..d01780118 100644 --- a/lib/commands/register.js +++ b/lib/commands/register.js @@ -10,7 +10,7 @@ function register(logger, name, source, config) { var force; var url; var githubSourceRegex = /^\w[\w-]*\/\w[\w-]*$/; - var getGithubUrl = function (source) { + var getGithubUrl = function(source) { return 'git@github.com:' + source + '.git'; }; @@ -26,10 +26,13 @@ function register(logger, name, source, config) { config.offline = false; config.force = true; - return Q.try(function () { + return Q.try(function() { // Verify name and url if (!name || !url) { - throw createError('Usage: bower register ', 'EINVFORMAT'); + throw createError( + 'Usage: bower register ', + 'EINVFORMAT' + ); } // Attempt to resolve the package referenced by the URL to ensure @@ -37,45 +40,54 @@ function register(logger, name, source, config) { repository = new PackageRepository(config, logger); return repository.fetch({ name: name, source: url, target: '*' }); }) - .spread(function (canonicalDir, pkgMeta) { - if (pkgMeta.private) { - throw createError('The package you are trying to register is marked as private', 'EPRIV'); - } - - // If non interactive or user forced, bypass confirmation - if (!config.interactive || force) { - return true; - } - - // Confirm if the user really wants to register - return Q.nfcall(logger.prompt.bind(logger), { - type: 'confirm', - message: 'Registering a package will make it installable via the registry (' + - chalk.cyan.underline(config.registry.register) + '), continue?', - default: true - }); - }) - .then(function (result) { - // If user response was negative, abort - if (!result) { - return; - } - - // Register - registryClient = repository.getRegistryClient(); - - logger.action('register', url, { - name: name, - url: url + .spread(function(canonicalDir, pkgMeta) { + if (pkgMeta.private) { + throw createError( + 'The package you are trying to register is marked as private', + 'EPRIV' + ); + } + + // If non interactive or user forced, bypass confirmation + if (!config.interactive || force) { + return true; + } + + // Confirm if the user really wants to register + return Q.nfcall(logger.prompt.bind(logger), { + type: 'confirm', + message: + 'Registering a package will make it installable via the registry (' + + chalk.cyan.underline(config.registry.register) + + '), continue?', + default: true + }); + }) + .then(function(result) { + // If user response was negative, abort + if (!result) { + return; + } + + // Register + registryClient = repository.getRegistryClient(); + + logger.action('register', url, { + name: name, + url: url + }); + + return Q.nfcall( + registryClient.register.bind(registryClient), + name, + url + ); }); - - return Q.nfcall(registryClient.register.bind(registryClient), name, url); - }); } // ------------------- -register.readOptions = function (argv) { +register.readOptions = function(argv) { var cli = require('../util/cli'); var options = cli.readOptions(argv); diff --git a/lib/commands/search.js b/lib/commands/search.js index d9461ff61..f9937ea35 100644 --- a/lib/commands/search.js +++ b/lib/commands/search.js @@ -27,7 +27,7 @@ function search(logger, name, config) { // ------------------- -search.readOptions = function (argv) { +search.readOptions = function(argv) { var options = cli.readOptions(argv); var terms = options.argv.remain.slice(1); diff --git a/lib/commands/uninstall.js b/lib/commands/uninstall.js index 9fd7d07aa..2a5a7f0c9 100644 --- a/lib/commands/uninstall.js +++ b/lib/commands/uninstall.js @@ -14,54 +14,62 @@ function uninstall(logger, names, options, config) { config = defaultConfig(config); project = new Project(config, logger); - return project.getTree(options) - .spread(function (tree, flattened) { + return project.getTree(options).spread(function(tree, flattened) { // Uninstall nodes - return project.uninstall(names, options) - // Clean out non-shared uninstalled dependencies - .then(function (uninstalled) { - var names = Object.keys(uninstalled); - var children = []; - - // Grab the dependencies of packages that were uninstalled - mout.object.forOwn(flattened, function (node) { - if (names.indexOf(node.endpoint.name) !== -1) { - children.push.apply(children, mout.object.keys(node.dependencies)); - } - }); - - // Clean them! - return clean(project, children, uninstalled); - }); + return ( + project + .uninstall(names, options) + // Clean out non-shared uninstalled dependencies + .then(function(uninstalled) { + var names = Object.keys(uninstalled); + var children = []; + + // Grab the dependencies of packages that were uninstalled + mout.object.forOwn(flattened, function(node) { + if (names.indexOf(node.endpoint.name) !== -1) { + children.push.apply( + children, + mout.object.keys(node.dependencies) + ); + } + }); + + // Clean them! + return clean(project, children, uninstalled); + }) + ); }); } function clean(project, names, removed) { removed = removed || {}; - return project.getTree() - .spread(function (tree, flattened) { + return project.getTree().spread(function(tree, flattened) { var nodes = []; var dependantsCounter = {}; // Grab the nodes of each specified name - mout.object.forOwn(flattened, function (node) { + mout.object.forOwn(flattened, function(node) { if (names.indexOf(node.endpoint.name) !== -1) { nodes.push(node); } }); // Walk the down the tree, gathering dependants of the packages - project.walkTree(tree, function (node, nodeName) { - if (names.indexOf(nodeName) !== -1) { - dependantsCounter[nodeName] = dependantsCounter[nodeName] || 0; - dependantsCounter[nodeName] += node.nrDependants; - } - }, true); - + project.walkTree( + tree, + function(node, nodeName) { + if (names.indexOf(nodeName) !== -1) { + dependantsCounter[nodeName] = + dependantsCounter[nodeName] || 0; + dependantsCounter[nodeName] += node.nrDependants; + } + }, + true + ); // Filter out those that have no dependants - nodes = nodes.filter(function (node) { + nodes = nodes.filter(function(node) { return !dependantsCounter[node.endpoint.name]; }); @@ -71,39 +79,48 @@ function clean(project, names, removed) { } // Grab the nodes after filtering - names = nodes.map(function (node) { + names = nodes.map(function(node) { return node.endpoint.name; }); // Uninstall them - return project.uninstall(names) - // Clean out non-shared uninstalled dependencies - .then(function (uninstalled) { - var children; - - mout.object.mixIn(removed, uninstalled); - - // Grab the dependencies of packages that were uninstalled - children = []; - nodes.forEach(function (node) { - children.push.apply(children, mout.object.keys(node.dependencies)); - }); - - // Recurse! - return clean(project, children, removed); - }); + return ( + project + .uninstall(names) + // Clean out non-shared uninstalled dependencies + .then(function(uninstalled) { + var children; + + mout.object.mixIn(removed, uninstalled); + + // Grab the dependencies of packages that were uninstalled + children = []; + nodes.forEach(function(node) { + children.push.apply( + children, + mout.object.keys(node.dependencies) + ); + }); + + // Recurse! + return clean(project, children, removed); + }) + ); }); } // ------------------- -uninstall.readOptions = function (argv) { +uninstall.readOptions = function(argv) { var cli = require('../util/cli'); - var options = cli.readOptions({ - 'save': { type: Boolean, shorthand: 'S' }, - 'save-dev': { type: Boolean, shorthand: 'D' } - }, argv); + var options = cli.readOptions( + { + save: { type: Boolean, shorthand: 'S' }, + 'save-dev': { type: Boolean, shorthand: 'D' } + }, + argv + ); var names = options.argv.remain.slice(1); diff --git a/lib/commands/unregister.js b/lib/commands/unregister.js index 4d9676d70..f7ef66f07 100644 --- a/lib/commands/unregister.js +++ b/lib/commands/unregister.js @@ -6,7 +6,6 @@ var PackageRepository = require('../core/PackageRepository'); var createError = require('../util/createError'); function unregister(logger, name, config) { - if (!name) { return; } @@ -28,46 +27,58 @@ function unregister(logger, name, config) { repository = new PackageRepository(config, logger); if (!config.accessToken) { - return logger.emit('error', - createError('Use "bower login" with collaborator credentials', 'EFORBIDDEN') + return logger.emit( + 'error', + createError( + 'Use "bower login" with collaborator credentials', + 'EFORBIDDEN' + ) ); } return Q.resolve() - .then(function () { - // If non interactive or user forced, bypass confirmation - if (!config.interactive || force) { - return true; - } - - return Q.nfcall(logger.prompt.bind(logger), { - type: 'confirm', - message: 'You are about to remove component "' + chalk.cyan.underline(name) + '" from the bower registry (' + chalk.cyan.underline(config.registry.register) + '). It is generally considered bad behavior to remove versions of a library that others are depending on. Are you really sure?', - default: false + .then(function() { + // If non interactive or user forced, bypass confirmation + if (!config.interactive || force) { + return true; + } + + return Q.nfcall(logger.prompt.bind(logger), { + type: 'confirm', + message: + 'You are about to remove component "' + + chalk.cyan.underline(name) + + '" from the bower registry (' + + chalk.cyan.underline(config.registry.register) + + '). It is generally considered bad behavior to remove versions of a library that others are depending on. Are you really sure?', + default: false + }); + }) + .then(function(result) { + // If user response was negative, abort + if (!result) { + return; + } + + registryClient = repository.getRegistryClient(); + + logger.action('unregister', name, { name: name }); + + return Q.nfcall( + registryClient.unregister.bind(registryClient), + name + ); + }) + .then(function(result) { + logger.info('Package unregistered', name); + + return result; }); - }) - .then(function (result) { - // If user response was negative, abort - if (!result) { - return; - } - - registryClient = repository.getRegistryClient(); - - logger.action('unregister', name, { name: name }); - - return Q.nfcall(registryClient.unregister.bind(registryClient), name); - }) - .then(function (result) { - logger.info('Package unregistered', name); - - return result; - }); } // ------------------- -unregister.readOptions = function (argv) { +unregister.readOptions = function(argv) { var cli = require('../util/cli'); var options = cli.readOptions(argv); diff --git a/lib/commands/update.js b/lib/commands/update.js index 9d2d65e97..a5c6f200d 100644 --- a/lib/commands/update.js +++ b/lib/commands/update.js @@ -18,13 +18,16 @@ function update(logger, names, options, config) { // ------------------- -update.readOptions = function (argv) { +update.readOptions = function(argv) { var cli = require('../util/cli'); - var options = cli.readOptions({ - 'force-latest': { type: Boolean, shorthand: 'F' }, - 'production': { type: Boolean, shorthand: 'p' } - }, argv); + var options = cli.readOptions( + { + 'force-latest': { type: Boolean, shorthand: 'F' }, + production: { type: Boolean, shorthand: 'p' } + }, + argv + ); var names = options.argv.remain.slice(1); diff --git a/lib/commands/version.js b/lib/commands/version.js index 92de54fd1..a9c33bd86 100644 --- a/lib/commands/version.js +++ b/lib/commands/version.js @@ -23,137 +23,186 @@ function bump(logger, config, versionArg, message) { throw createError('No agrument provided', 'EREADOPTIONS'); } - return driver.check(cwd) - .then(function () { - return Q.all([driver.versions(cwd), driver.currentVersion(cwd)]); - }) - .spread(function (versions, currentVersion) { - currentVersion = currentVersion || '0.0.0'; - - if (semver.valid(versionArg)) { - newVersion = semver.valid(versionArg); - } else { - newVersion = semver.inc(currentVersion, versionArg); - - if (!newVersion) { - throw createError('Invalid argument: ' + versionArg, 'EINVALIDVERSION', { version: versionArg }); + return driver + .check(cwd) + .then(function() { + return Q.all([driver.versions(cwd), driver.currentVersion(cwd)]); + }) + .spread(function(versions, currentVersion) { + currentVersion = currentVersion || '0.0.0'; + + if (semver.valid(versionArg)) { + newVersion = semver.valid(versionArg); + } else { + newVersion = semver.inc(currentVersion, versionArg); + + if (!newVersion) { + throw createError( + 'Invalid argument: ' + versionArg, + 'EINVALIDVERSION', + { version: versionArg } + ); + } } - } - newVersion = (currentVersion[0] === 'v') ? 'v' + newVersion : newVersion; + newVersion = + currentVersion[0] === 'v' ? 'v' + newVersion : newVersion; + + if (versions) { + versions.forEach(function(version) { + if (semver.eq(version, newVersion)) { + throw createError( + 'Version exists: ' + newVersion, + 'EVERSIONEXISTS', + { versions: versions, newVersion: newVersion } + ); + } + }); + } - if (versions) { - versions.forEach(function (version) { - if (semver.eq(version, newVersion)) { - throw createError('Version exists: ' + newVersion, 'EVERSIONEXISTS', { versions: versions, newVersion: newVersion }); - } + return driver.bump(cwd, newVersion, message).then(function() { + return { + oldVersion: currentVersion, + newVersion: newVersion + }; }); - } - - return driver.bump(cwd, newVersion, message).then(function () { - return { - oldVersion: currentVersion, - newVersion: newVersion - } + }) + .then(function(result) { + logger.info( + 'version', + 'Bumped package version from ' + + result.oldVersion + + ' to ' + + result.newVersion, + result + ); + + return result.newVersion; }); - }) - .then(function (result) { - logger.info('version', 'Bumped package version from ' + result.oldVersion + ' to ' + result.newVersion, result); - - return result.newVersion; - }); } var driver = { - check: function (cwd) { + check: function(cwd) { function checkGit(cwd) { var gitDir = path.join(cwd, '.git'); - return Q.nfcall(fs.stat, gitDir) - .then(function (stat) { - if (stat.isDirectory()) { - return checkGitStatus(cwd); + return Q.nfcall(fs.stat, gitDir).then( + function(stat) { + if (stat.isDirectory()) { + return checkGitStatus(cwd); + } + return false; + }, + function() { + //Ignore not found .git directory + return false; } - return false; - }, function () { - //Ignore not found .git directory - return false; - }); + ); } function checkGitStatus(cwd) { return Q.nfcall(which, 'git') - .fail(function (err) { - err.code = 'ENOGIT'; - throw err; - }) - .then(function () { - return Q.nfcall(execFile, 'git', ['status', '--porcelain'], {env: process.env, cwd: cwd}); - }) - .then(function (value) { - var stdout = value[0]; - var lines = filterModifiedStatusLines(stdout); - if (lines.length) { - throw createError('Version bump requires clean working directory', 'EWORKINGDIRECTORYDIRTY'); - } - return true; - }); + .fail(function(err) { + err.code = 'ENOGIT'; + throw err; + }) + .then(function() { + return Q.nfcall( + execFile, + 'git', + ['status', '--porcelain'], + { env: process.env, cwd: cwd } + ); + }) + .then(function(value) { + var stdout = value[0]; + var lines = filterModifiedStatusLines(stdout); + if (lines.length) { + throw createError( + 'Version bump requires clean working directory', + 'EWORKINGDIRECTORYDIRTY' + ); + } + return true; + }); } function filterModifiedStatusLines(stdout) { - return stdout.trim().split('\n') - .filter(function (line) { - return line.trim() && !line.match(/^\?\? /); - }).map(function (line) { - return line.trim(); - }); + return stdout + .trim() + .split('\n') + .filter(function(line) { + return line.trim() && !line.match(/^\?\? /); + }) + .map(function(line) { + return line.trim(); + }); } - return checkGit(cwd).then(function (hasGit) { + return checkGit(cwd).then(function(hasGit) { if (!hasGit) { - throw createError('Version bump currently supports only git repositories', 'ENOTGITREPOSITORY'); + throw createError( + 'Version bump currently supports only git repositories', + 'ENOTGITREPOSITORY' + ); } }); }, - versions: function (cwd) { - return Q.nfcall(execFile, 'git', ['tag'], {env: process.env, cwd: cwd}) - .then(function (res) { - var versions = res[0] - .split(/\r?\n/) - .filter(semver.valid); - - return versions; - }, function () { - return []; - }); + versions: function(cwd) { + return Q.nfcall(execFile, 'git', ['tag'], { + env: process.env, + cwd: cwd + }).then( + function(res) { + var versions = res[0].split(/\r?\n/).filter(semver.valid); + + return versions; + }, + function() { + return []; + } + ); }, - currentVersion: function (cwd) { - return Q.nfcall(execFile, 'git', ['describe', '--abbrev=0', '--tags'], {env: process.env, cwd: cwd}) - .then(function (res) { - var version = res[0] - .split(/\r?\n/) - .filter(semver.valid)[0]; - - return version; - }, function () { - return undefined; - }); + currentVersion: function(cwd) { + return Q.nfcall(execFile, 'git', ['describe', '--abbrev=0', '--tags'], { + env: process.env, + cwd: cwd + }).then( + function(res) { + var version = res[0].split(/\r?\n/).filter(semver.valid)[0]; + + return version; + }, + function() { + return undefined; + } + ); }, - bump: function (cwd, tag, message) { + bump: function(cwd, tag, message) { message = message || tag; message = message.replace(/%s/g, tag); - return Q.nfcall(execFile, 'git', ['commit', '-m', message, '--allow-empty'], {env: process.env, cwd: cwd}) .then(function () { - return Q.nfcall(execFile, 'git', ['tag', tag, '-am', message], {env: process.env, cwd: cwd}); + return Q.nfcall( + execFile, + 'git', + ['commit', '-m', message, '--allow-empty'], + { env: process.env, cwd: cwd } + ).then(function() { + return Q.nfcall(execFile, 'git', ['tag', tag, '-am', message], { + env: process.env, + cwd: cwd + }); }); } -} - +}; -version.readOptions = function (argv) { +version.readOptions = function(argv) { var cli = require('../util/cli'); - var options = cli.readOptions({ - 'message': { type: String, shorthand: 'm'} - }, argv); + var options = cli.readOptions( + { + message: { type: String, shorthand: 'm' } + }, + argv + ); return [options.argv.remain[1], options]; }; diff --git a/lib/config.js b/lib/config.js index f0dda45fb..0192a2c66 100644 --- a/lib/config.js +++ b/lib/config.js @@ -22,26 +22,26 @@ function readCachedConfig(cwd, overwrites) { // If interactive is auto (null), guess its value if (config.interactive == null) { - config.interactive = ( - process.bin === 'bower' && - tty.isatty(1) && - !process.env.CI - ); + config.interactive = + process.bin === 'bower' && tty.isatty(1) && !process.env.CI; } // Merge common CLI options into the config if (process.bin === 'bower') { var cli = require('./util/cli'); - object.mixIn(config, cli.readOptions({ - force: { type: Boolean, shorthand: 'f' }, - offline: { type: Boolean, shorthand: 'o' }, - verbose: { type: Boolean, shorthand: 'V' }, - quiet: { type: Boolean, shorthand: 'q' }, - loglevel: { type: String, shorthand: 'l' }, - json: { type: Boolean, shorthand: 'j' }, - silent: { type: Boolean, shorthand: 's' } - })); + object.mixIn( + config, + cli.readOptions({ + force: { type: Boolean, shorthand: 'f' }, + offline: { type: Boolean, shorthand: 'o' }, + verbose: { type: Boolean, shorthand: 'V' }, + quiet: { type: Boolean, shorthand: 'q' }, + loglevel: { type: String, shorthand: 'l' }, + json: { type: Boolean, shorthand: 'j' }, + silent: { type: Boolean, shorthand: 's' } + }) + ); } return config; diff --git a/lib/core/Manager.js b/lib/core/Manager.js index e5f3b7736..8d00b85a9 100644 --- a/lib/core/Manager.js +++ b/lib/core/Manager.js @@ -22,16 +22,23 @@ function Manager(config, logger) { // ----------------- -Manager.prototype.configure = function (setup) { +Manager.prototype.configure = function(setup) { var targetsHash = {}; this._conflicted = {}; // Targets - ignore those specified in ignoredDependencies - this._targets = mout.array.reject(setup.targets || [], function (target) { - return mout.array.contains(this._config.ignoredDependencies, target.name ); - }, this); - - this._targets.forEach(function (decEndpoint) { + this._targets = mout.array.reject( + setup.targets || [], + function(target) { + return mout.array.contains( + this._config.ignoredDependencies, + target.name + ); + }, + this + ); + + this._targets.forEach(function(decEndpoint) { decEndpoint.initialName = decEndpoint.name; decEndpoint.dependants = mout.object.values(decEndpoint.dependants); targetsHash[decEndpoint.name] = true; @@ -43,11 +50,15 @@ Manager.prototype.configure = function (setup) { // Resolved & installed this._resolved = {}; this._installed = {}; - mout.object.forOwn(setup.resolved, function (decEndpoint, name) { - decEndpoint.dependants = mout.object.values(decEndpoint.dependants); - this._resolved[name] = [decEndpoint]; - this._installed[name] = decEndpoint.pkgMeta; - }, this); + mout.object.forOwn( + setup.resolved, + function(decEndpoint, name) { + decEndpoint.dependants = mout.object.values(decEndpoint.dependants); + this._resolved[name] = [decEndpoint]; + this._installed[name] = decEndpoint.pkgMeta; + }, + this + ); // Installed mout.object.mixIn(this._installed, setup.installed); @@ -55,7 +66,7 @@ Manager.prototype.configure = function (setup) { // Incompatibles this._incompatibles = {}; setup.incompatibles = this._uniquify(setup.incompatibles || []); - setup.incompatibles.forEach(function (decEndpoint) { + setup.incompatibles.forEach(function(decEndpoint) { var name = decEndpoint.name; this._incompatibles[name] = this._incompatibles[name] || []; @@ -94,7 +105,7 @@ Manager.prototype.configure = function (setup) { * Fetching and parsing of dependencies continues until all dependencies are fetched. * */ -Manager.prototype.resolve = function () { +Manager.prototype.resolve = function() { // If already resolving, error out if (this._working) { return Q.reject(createError('Already working', 'EWORKING')); @@ -110,54 +121,65 @@ Manager.prototype.resolve = function () { // If there's nothing to resolve, simply dissect if (!this._targets.length) { process.nextTick(this._dissect.bind(this)); - // Otherwise, fetch each target from the repository - // and let the process roll out + // Otherwise, fetch each target from the repository + // and let the process roll out } else { this._targets.forEach(this._fetch.bind(this)); } // Unset working flag when done - return this._deferred.promise - .fin(function () { - this._working = false; - }.bind(this)); + return this._deferred.promise.fin( + function() { + this._working = false; + }.bind(this) + ); }; -Manager.prototype.preinstall = function (json) { +Manager.prototype.preinstall = function(json) { var that = this; - var componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory); + var componentsDir = relativeToBaseDir(this._config.cwd)( + this._config.directory + ); // If nothing to install, skip the code bellow if (mout.lang.isEmpty(that._dissected)) { return Q.resolve({}); } - return Q.nfcall(mkdirp, componentsDir) - .then(function () { + return Q.nfcall(mkdirp, componentsDir).then(function() { return scripts.preinstall( - that._config, that._logger, that._dissected, that._installed, json + that._config, + that._logger, + that._dissected, + that._installed, + json ); }); }; -Manager.prototype.postinstall = function (json) { +Manager.prototype.postinstall = function(json) { var that = this; - var componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory); + var componentsDir = relativeToBaseDir(this._config.cwd)( + this._config.directory + ); // If nothing to install, skip the code bellow if (mout.lang.isEmpty(that._dissected)) { return Q.resolve({}); } - return Q.nfcall(mkdirp, componentsDir) - .then(function () { + return Q.nfcall(mkdirp, componentsDir).then(function() { return scripts.postinstall( - that._config, that._logger, that._dissected, that._installed, json + that._config, + that._logger, + that._dissected, + that._installed, + json ); }); }; -Manager.prototype.install = function (json) { +Manager.prototype.install = function(json) { var componentsDir; var componentsDirContents; var that = this; @@ -174,86 +196,121 @@ Manager.prototype.install = function (json) { componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory); return Q.nfcall(mkdirp, componentsDir) - .then(function () { - var promises = []; - componentsDirContents = fs.readdirSync(componentsDir); - - mout.object.forOwn(that._dissected, function (decEndpoint, name) { - var promise; - var dst; - var release = decEndpoint.pkgMeta._release; - var exists = mout.array.contains(componentsDirContents, name); - - that._logger.action('install', name + (release ? '#' + release : ''), that.toData(decEndpoint)); - - dst = path.join(componentsDir, name); - - if (exists && !that._installed[name] && !that._config.force) { - // There is a folder in the components directory that has - // this name, but it was not installed by bower. - that._logger.warn('skipped', name + ' was not installed because there is already a non-bower directory with that name in the components directory (' + path.relative(that._config.cwd, dst) + '). You can force installation with --force.'); - return; - } - - // Remove existent and copy canonical dir - promise = Q.nfcall(rimraf, dst) - .then(copy.copyDir.bind(copy, decEndpoint.canonicalDir, dst)) - .then(function () { - var metaFile = path.join(dst, '.bower.json'); - - decEndpoint.canonicalDir = dst; - - // Store additional metadata in bower.json - return Q.nfcall(fs.readFile, metaFile) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - - json._target = decEndpoint.target; - json._originalSource = decEndpoint.source; - if (decEndpoint.newly) { - json._direct = true; - } + .then(function() { + var promises = []; + componentsDirContents = fs.readdirSync(componentsDir); + + mout.object.forOwn(that._dissected, function(decEndpoint, name) { + var promise; + var dst; + var release = decEndpoint.pkgMeta._release; + var exists = mout.array.contains(componentsDirContents, name); + + that._logger.action( + 'install', + name + (release ? '#' + release : ''), + that.toData(decEndpoint) + ); + + dst = path.join(componentsDir, name); + + if (exists && !that._installed[name] && !that._config.force) { + // There is a folder in the components directory that has + // this name, but it was not installed by bower. + that._logger.warn( + 'skipped', + name + + ' was not installed because there is already a non-bower directory with that name in the components directory (' + + path.relative(that._config.cwd, dst) + + '). You can force installation with --force.' + ); + return; + } - json = JSON.stringify(json, null, ' '); - return Q.nfcall(fs.writeFile, metaFile, json); - }); + // Remove existent and copy canonical dir + promise = Q.nfcall(rimraf, dst) + .then( + copy.copyDir.bind(copy, decEndpoint.canonicalDir, dst) + ) + .then(function() { + var metaFile = path.join(dst, '.bower.json'); + + decEndpoint.canonicalDir = dst; + + // Store additional metadata in bower.json + return Q.nfcall(fs.readFile, metaFile).then(function( + contents + ) { + var json = JSON.parse(contents.toString()); + + json._target = decEndpoint.target; + json._originalSource = decEndpoint.source; + if (decEndpoint.newly) { + json._direct = true; + } + + json = JSON.stringify(json, null, ' '); + return Q.nfcall(fs.writeFile, metaFile, json); + }); + }); + + promises.push(promise); }); - promises.push(promise); - }); - - return Q.all(promises); - }) - .then(function () { - // Sync up dissected dependencies and dependants - // See: https://github.com/bower/bower/issues/879 - mout.object.forOwn(that._dissected, function (pkg) { - // Sync dependencies - mout.object.forOwn(pkg.dependencies, function (dependency, name) { - var dissected = this._dissected[name] || (this._resolved[name] ? this._resolved[name][0] : dependency); - pkg.dependencies[name] = dissected; - }, this); - - // Sync dependants - pkg.dependants = pkg.dependants.map(function (dependant) { - var name = dependant.name; - var dissected = this._dissected[name] || (this._resolved[name] ? this._resolved[name][0] : dependant); - - return dissected; - }, this); - }, that); - - // Resolve with meaningful data - return mout.object.map(that._dissected, function (decEndpoint) { - return this.toData(decEndpoint); - }, that); - }) - .fin(function () { - this._working = false; - }.bind(this)); + return Q.all(promises); + }) + .then(function() { + // Sync up dissected dependencies and dependants + // See: https://github.com/bower/bower/issues/879 + mout.object.forOwn( + that._dissected, + function(pkg) { + // Sync dependencies + mout.object.forOwn( + pkg.dependencies, + function(dependency, name) { + var dissected = + this._dissected[name] || + (this._resolved[name] + ? this._resolved[name][0] + : dependency); + pkg.dependencies[name] = dissected; + }, + this + ); + + // Sync dependants + pkg.dependants = pkg.dependants.map(function(dependant) { + var name = dependant.name; + var dissected = + this._dissected[name] || + (this._resolved[name] + ? this._resolved[name][0] + : dependant); + + return dissected; + }, this); + }, + that + ); + + // Resolve with meaningful data + return mout.object.map( + that._dissected, + function(decEndpoint) { + return this.toData(decEndpoint); + }, + that + ); + }) + .fin( + function() { + this._working = false; + }.bind(this) + ); }; -Manager.prototype.toData = function (decEndpoint, extraKeys, upperDeps) { +Manager.prototype.toData = function(decEndpoint, extraKeys, upperDeps) { var names; var extra; @@ -269,7 +326,7 @@ Manager.prototype.toData = function (decEndpoint, extraKeys, upperDeps) { if (extraKeys) { extra = mout.object.pick(decEndpoint, extraKeys); - extra = mout.object.filter(extra, function (value) { + extra = mout.object.filter(extra, function(value) { return !!value; }); mout.object.mixIn(data, extra); @@ -281,14 +338,15 @@ Manager.prototype.toData = function (decEndpoint, extraKeys, upperDeps) { // Call recursively for each dependency but ordered // by dependency names names = Object.keys(decEndpoint.dependencies).sort(); - names.forEach(function (name) { - + names.forEach(function(name) { // Prevent from infinite recursion when installing cyclic // dependencies if (!mout.array.contains(upperDeps, name)) { - data.dependencies[name] = this.toData(decEndpoint.dependencies[name], + data.dependencies[name] = this.toData( + decEndpoint.dependencies[name], extraKeys, - upperDeps.concat(decEndpoint.name)); + upperDeps.concat(decEndpoint.name) + ); } }, this); } @@ -298,13 +356,13 @@ Manager.prototype.toData = function (decEndpoint, extraKeys, upperDeps) { return data; }; -Manager.prototype.getPackageRepository = function () { +Manager.prototype.getPackageRepository = function() { return this._repository; }; // ----------------- -Manager.prototype._fetch = function (decEndpoint) { +Manager.prototype._fetch = function(decEndpoint) { var name = decEndpoint.name; // Check if the whole process started to fail fast @@ -320,19 +378,28 @@ Manager.prototype._fetch = function (decEndpoint) { // Fetch it from the repository // Note that the promise is stored in the decomposed endpoint // because it might be reused if a similar endpoint needs to be resolved - return decEndpoint.promise = this._repository.fetch(decEndpoint) - // When done, call onFetchSuccess - .spread(this._onFetchSuccess.bind(this, decEndpoint)) - // If it fails, call onFetchFailure - .fail(this._onFetchError.bind(this, decEndpoint)); + return (decEndpoint.promise = this._repository + .fetch(decEndpoint) + // When done, call onFetchSuccess + .spread(this._onFetchSuccess.bind(this, decEndpoint)) + // If it fails, call onFetchFailure + .fail(this._onFetchError.bind(this, decEndpoint))); }; -Manager.prototype._onFetchSuccess = function (decEndpoint, canonicalDir, pkgMeta, isTargetable) { +Manager.prototype._onFetchSuccess = function( + decEndpoint, + canonicalDir, + pkgMeta, + isTargetable +) { var name; var resolved; var index; var incompatibles; - var initialName = decEndpoint.initialName != null ? decEndpoint.initialName : decEndpoint.name; + var initialName = + decEndpoint.initialName != null + ? decEndpoint.initialName + : decEndpoint.name; var fetching = this._fetching[initialName]; // Remove from being fetched list @@ -349,12 +416,15 @@ Manager.prototype._onFetchSuccess = function (decEndpoint, canonicalDir, pkgMeta // If there's an exact equal endpoint, replace instead of adding // This can happen because the name might not be known from the start resolved = this._resolved[name] = this._resolved[name] || []; - index = mout.array.findIndex(resolved, function (resolved) { + index = mout.array.findIndex(resolved, function(resolved) { return resolved.target === decEndpoint.target; }); if (index !== -1) { // Merge dependants - decEndpoint.dependants.push.apply(decEndpoint.dependants, resolved[index.dependants]); + decEndpoint.dependants.push.apply( + decEndpoint.dependants, + resolved[index.dependants] + ); decEndpoint.dependants = this._uniquify(decEndpoint.dependants); resolved.splice(index, 1); } @@ -368,14 +438,14 @@ Manager.prototype._onFetchSuccess = function (decEndpoint, canonicalDir, pkgMeta incompatibles = this._incompatibles[name]; if (incompatibles) { // Filter already resolved - incompatibles = incompatibles.filter(function (incompatible) { - return !resolved.some(function (decEndpoint) { + incompatibles = incompatibles.filter(function(incompatible) { + return !resolved.some(function(decEndpoint) { return incompatible.target === decEndpoint.target; }); }, this); // Filter being resolved - incompatibles = incompatibles.filter(function (incompatible) { - return !fetching.some(function (decEndpoint) { + incompatibles = incompatibles.filter(function(incompatible) { + return !fetching.some(function(decEndpoint) { return incompatible.target === decEndpoint.target; }); }, this); @@ -398,11 +468,15 @@ Manager.prototype._onFetchSuccess = function (decEndpoint, canonicalDir, pkgMeta } }; -Manager.prototype._onFetchError = function (decEndpoint, err) { +Manager.prototype._onFetchError = function(decEndpoint, err) { var name = decEndpoint.name; err.data = err.data || {}; - err.data.endpoint = mout.object.pick(decEndpoint, ['name', 'source', 'target']); + err.data.endpoint = mout.object.pick(decEndpoint, [ + 'name', + 'source', + 'target' + ]); // Remove from being fetched list mout.array.remove(this._fetching[name], decEndpoint); @@ -423,7 +497,7 @@ Manager.prototype._onFetchError = function (decEndpoint, err) { } }; -Manager.prototype._failFast = function () { +Manager.prototype._failFast = function() { if (this._hasFailed) { return; } @@ -432,10 +506,13 @@ Manager.prototype._failFast = function () { // If after some amount of time all pending tasks haven't finished, // we force the process to end - this._failFastTimeout = setTimeout(function () { - this._nrFetching = Infinity; - this._dissect(); - }.bind(this), 20000); + this._failFastTimeout = setTimeout( + function() { + this._nrFetching = Infinity; + this._dissect(); + }.bind(this), + 20000 + ); }; /** @@ -446,89 +523,117 @@ Manager.prototype._failFast = function () { * * @param {string} pkgMeta Metadata of package to resolve dependencies. */ -Manager.prototype._parseDependencies = function (decEndpoint, pkgMeta) { +Manager.prototype._parseDependencies = function(decEndpoint, pkgMeta) { var pending = []; decEndpoint.dependencies = decEndpoint.dependencies || {}; // Parse package dependencies - mout.object.forOwn(pkgMeta.dependencies, function (value, key) { - var resolved; - var fetching; - var compatible; - var childDecEndpoint = endpointParser.json2decomposed(key, value); - - // Check if this depdendency should be skipped. - if (mout.array.contains(this._config.ignoredDependencies, childDecEndpoint.name)) { - this._logger.action('skipped', childDecEndpoint.name, this.toData(decEndpoint)); - return; - } - - // Check if a compatible one is already resolved - // If there's one, we don't need to resolve it twice - resolved = this._resolved[key]; - if (resolved) { - // Find if there's one with the exact same target - compatible = mout.array.find(resolved, function (resolved) { - return childDecEndpoint.target === resolved.target; - }, this); - - // If we found one, merge stuff instead of adding as resolved - if (compatible) { - decEndpoint.dependencies[key] = compatible; - compatible.dependants.push(decEndpoint); - compatible.dependants = this._uniquify(compatible.dependants); - + mout.object.forOwn( + pkgMeta.dependencies, + function(value, key) { + var resolved; + var fetching; + var compatible; + var childDecEndpoint = endpointParser.json2decomposed(key, value); + + // Check if this depdendency should be skipped. + if ( + mout.array.contains( + this._config.ignoredDependencies, + childDecEndpoint.name + ) + ) { + this._logger.action( + 'skipped', + childDecEndpoint.name, + this.toData(decEndpoint) + ); return; } - // Find one that is compatible - compatible = mout.array.find(resolved, function (resolved) { - return this._areCompatible(childDecEndpoint, resolved); - }, this); - - // If we found one, add as resolved - // and copy resolved properties from the compatible one - if (compatible) { - decEndpoint.dependencies[key] = compatible; - childDecEndpoint.canonicalDir = compatible.canonicalDir; - childDecEndpoint.pkgMeta = compatible.pkgMeta; - childDecEndpoint.dependencies = compatible.dependencies; - childDecEndpoint.dependants = [decEndpoint]; - this._resolved[key].push(childDecEndpoint); + // Check if a compatible one is already resolved + // If there's one, we don't need to resolve it twice + resolved = this._resolved[key]; + if (resolved) { + // Find if there's one with the exact same target + compatible = mout.array.find( + resolved, + function(resolved) { + return childDecEndpoint.target === resolved.target; + }, + this + ); + + // If we found one, merge stuff instead of adding as resolved + if (compatible) { + decEndpoint.dependencies[key] = compatible; + compatible.dependants.push(decEndpoint); + compatible.dependants = this._uniquify( + compatible.dependants + ); + + return; + } - return; + // Find one that is compatible + compatible = mout.array.find( + resolved, + function(resolved) { + return this._areCompatible(childDecEndpoint, resolved); + }, + this + ); + + // If we found one, add as resolved + // and copy resolved properties from the compatible one + if (compatible) { + decEndpoint.dependencies[key] = compatible; + childDecEndpoint.canonicalDir = compatible.canonicalDir; + childDecEndpoint.pkgMeta = compatible.pkgMeta; + childDecEndpoint.dependencies = compatible.dependencies; + childDecEndpoint.dependants = [decEndpoint]; + this._resolved[key].push(childDecEndpoint); + + return; + } } - } - // Check if a compatible one is being fetched - // If there's one, we wait and reuse it to avoid resolving it twice - fetching = this._fetching[key]; - if (fetching) { - compatible = mout.array.find(fetching, function (fetching) { - return this._areCompatible(childDecEndpoint, fetching); - }, this); - - if (compatible) { - pending.push(compatible.promise); - return; + // Check if a compatible one is being fetched + // If there's one, we wait and reuse it to avoid resolving it twice + fetching = this._fetching[key]; + if (fetching) { + compatible = mout.array.find( + fetching, + function(fetching) { + return this._areCompatible(childDecEndpoint, fetching); + }, + this + ); + + if (compatible) { + pending.push(compatible.promise); + return; + } } - } - // Mark endpoint as unresolvable if the parent is also unresolvable - childDecEndpoint.unresolvable = !!decEndpoint.unresolvable; + // Mark endpoint as unresolvable if the parent is also unresolvable + childDecEndpoint.unresolvable = !!decEndpoint.unresolvable; - // Otherwise, just fetch it from the repository - decEndpoint.dependencies[key] = childDecEndpoint; - childDecEndpoint.dependants = [decEndpoint]; - this._fetch(childDecEndpoint); - }, this); + // Otherwise, just fetch it from the repository + decEndpoint.dependencies[key] = childDecEndpoint; + childDecEndpoint.dependants = [decEndpoint]; + this._fetch(childDecEndpoint); + }, + this + ); if (pending.length > 0) { - Q.all(pending) - .then(function () { - this._parseDependencies(decEndpoint, pkgMeta); - }.bind(this)); + Q.all(pending).then( + function() { + this._parseDependencies(decEndpoint, pkgMeta); + }.bind(this) + ); } }; @@ -545,7 +650,7 @@ Manager.prototype._parseDependencies = function (decEndpoint, pkgMeta) { * * The _dissected array is used later on by install method to move packages to config.directory. */ -Manager.prototype._dissect = function () { +Manager.prototype._dissect = function() { var err; var componentsDir; var promise = Q.resolve(); @@ -563,125 +668,159 @@ Manager.prototype._dissect = function () { } // Find a suitable version for each package name - mout.object.forOwn(this._resolved, function (decEndpoints, name) { - var semvers; - var nonSemvers; - - // Filter out non-semver ones - semvers = decEndpoints.filter(function (decEndpoint) { - return !!decEndpoint.pkgMeta.version; - }); - - // Sort semver ones DESC - semvers.sort(function (first, second) { - var result = semver.rcompare(first.pkgMeta.version, second.pkgMeta.version); + mout.object.forOwn( + this._resolved, + function(decEndpoints, name) { + var semvers; + var nonSemvers; + + // Filter out non-semver ones + semvers = decEndpoints.filter(function(decEndpoint) { + return !!decEndpoint.pkgMeta.version; + }); - // If they are equal and one of them is a wildcard target, - // give lower priority - if (!result) { - if (first.target === '*') { - return 1; - } - if (second.target === '*') { - return -1; + // Sort semver ones DESC + semvers.sort(function(first, second) { + var result = semver.rcompare( + first.pkgMeta.version, + second.pkgMeta.version + ); + + // If they are equal and one of them is a wildcard target, + // give lower priority + if (!result) { + if (first.target === '*') { + return 1; + } + if (second.target === '*') { + return -1; + } } - } - // If they are equal and one of them is an exact target, - // give higher priority - if (!result) { - if (first.target === first.pkgMeta.version) { - return -1; - } - if (second.target === second.pkgMeta.version) { - return 1; + // If they are equal and one of them is an exact target, + // give higher priority + if (!result) { + if (first.target === first.pkgMeta.version) { + return -1; + } + if (second.target === second.pkgMeta.version) { + return 1; + } } - } - return result; - }); + return result; + }); - // Convert wildcard targets to semver range targets if they are newly - // Note that this can only be made if they can be targetable - // If they are not, the resolver is incapable of handling targets - semvers.forEach(function (decEndpoint) { - if (decEndpoint.newly && decEndpoint.target === '*' && !decEndpoint.untargetable) { - decEndpoint.target = '^' + decEndpoint.pkgMeta.version; - decEndpoint.originalTarget = '*'; - } - }); + // Convert wildcard targets to semver range targets if they are newly + // Note that this can only be made if they can be targetable + // If they are not, the resolver is incapable of handling targets + semvers.forEach(function(decEndpoint) { + if ( + decEndpoint.newly && + decEndpoint.target === '*' && + !decEndpoint.untargetable + ) { + decEndpoint.target = '^' + decEndpoint.pkgMeta.version; + decEndpoint.originalTarget = '*'; + } + }); - // Filter non-semver ones - nonSemvers = decEndpoints.filter(function (decEndpoint) { - return !decEndpoint.pkgMeta.version; - }); + // Filter non-semver ones + nonSemvers = decEndpoints.filter(function(decEndpoint) { + return !decEndpoint.pkgMeta.version; + }); - promise = promise.then(function () { - return that._electSuitable(name, semvers, nonSemvers) - .then(function (suitable) { - suitables[name] = suitable; + promise = promise.then(function() { + return that + ._electSuitable(name, semvers, nonSemvers) + .then(function(suitable) { + suitables[name] = suitable; + }); }); - }); - }, this); + }, + this + ); // After a suitable version has been elected for every package promise - .then(function () { - // Look for extraneous resolutions - mout.object.forOwn(this._resolutions, function (resolution, name) { - if (this._conflicted[name]) { - return; - } - - // Packages that didn't have any conflicts in resolution yet have - // "resolution" entry in bower.json are deemed unnecessary - // - // Probably in future we want to use them for force given resolution, but for now... - // See: https://github.com/bower/bower/issues/1362 - this._logger.warn('extra-resolution', 'Unnecessary resolution: ' + name + '#' + resolution, { - name: name, - resolution: resolution, - action: 'delete' - }); - }, this); - - // Filter only packages that need to be installed - componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory); - this._dissected = mout.object.filter(suitables, function (decEndpoint, name) { - var installedMeta = this._installed[name]; - var dst; - - // Skip linked dependencies - if (decEndpoint.linked) { - return false; - } - - // Skip if source is the same as dest - // FIXME: Shoudn't we force installation if force flag is used here? - dst = path.join(componentsDir, name); - if (dst === decEndpoint.canonicalDir) { - return false; - } - - // We skip installing decEndpoint, if: - // 1. We have installed package with the same name - // 2. Packages have matching meta fields (needs explanation) - // 3. We didn't force the installation - if (installedMeta && - installedMeta._target === decEndpoint.target && - installedMeta._originalSource === decEndpoint.source && - installedMeta._release === decEndpoint.pkgMeta._release - ) { - return this._config.force; - } - - return true; - }, this); - }.bind(this)) - .then(this._deferred.resolve, this._deferred.reject); + .then( + function() { + // Look for extraneous resolutions + mout.object.forOwn( + this._resolutions, + function(resolution, name) { + if (this._conflicted[name]) { + return; + } + + // Packages that didn't have any conflicts in resolution yet have + // "resolution" entry in bower.json are deemed unnecessary + // + // Probably in future we want to use them for force given resolution, but for now... + // See: https://github.com/bower/bower/issues/1362 + this._logger.warn( + 'extra-resolution', + 'Unnecessary resolution: ' + + name + + '#' + + resolution, + { + name: name, + resolution: resolution, + action: 'delete' + } + ); + }, + this + ); + + // Filter only packages that need to be installed + componentsDir = relativeToBaseDir(this._config.cwd)( + this._config.directory + ); + this._dissected = mout.object.filter( + suitables, + function(decEndpoint, name) { + var installedMeta = this._installed[name]; + var dst; + + // Skip linked dependencies + if (decEndpoint.linked) { + return false; + } + + // Skip if source is the same as dest + // FIXME: Shoudn't we force installation if force flag is used here? + dst = path.join(componentsDir, name); + if (dst === decEndpoint.canonicalDir) { + return false; + } + + // We skip installing decEndpoint, if: + // 1. We have installed package with the same name + // 2. Packages have matching meta fields (needs explanation) + // 3. We didn't force the installation + if ( + installedMeta && + installedMeta._target === decEndpoint.target && + installedMeta._originalSource === + decEndpoint.source && + installedMeta._release === + decEndpoint.pkgMeta._release + ) { + return this._config.force; + } + + return true; + }, + this + ); + }.bind(this) + ) + .then(this._deferred.resolve, this._deferred.reject); }; -Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { +Manager.prototype._electSuitable = function(name, semvers, nonSemvers) { var suitable; var resolution; var unresolvable; @@ -696,21 +835,26 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { if (semvers.length && nonSemvers.length) { picks.push.apply(picks, semvers); picks.push.apply(picks, nonSemvers); - // If there are only non-semver ones, the suitable is elected - // only if there's one + // If there are only non-semver ones, the suitable is elected + // only if there's one } else if (nonSemvers.length) { if (nonSemvers.length === 1) { return Q.resolve(nonSemvers[0]); } picks.push.apply(picks, nonSemvers); - // If there are only semver ones, figure out which one is - // compatible with every requirement + // If there are only semver ones, figure out which one is + // compatible with every requirement } else { - suitable = mout.array.find(semvers, function (subject) { - return semvers.every(function (decEndpoint) { - return subject === decEndpoint || - semver.satisfies(subject.pkgMeta.version, decEndpoint.target); + suitable = mout.array.find(semvers, function(subject) { + return semvers.every(function(decEndpoint) { + return ( + subject === decEndpoint || + semver.satisfies( + subject.pkgMeta.version, + decEndpoint.target + ) + ); }); }); @@ -726,7 +870,7 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { // Prepare data to be sent bellow // 1 - Sort picks by version/release - picks.sort(function (pick1, pick2) { + picks.sort(function(pick1, pick2) { var version1 = pick1.pkgMeta.version; var version2 = pick2.pkgMeta.version; var comp; @@ -759,11 +903,13 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { }); // 2 - Transform data - dataPicks = picks.map(function (pick) { + dataPicks = picks.map(function(pick) { var dataPick = this.toData(pick); dataPick.dependants = pick.dependants.map(this.toData, this); - dataPick.dependants.sort(function (dependant1, dependant2) { - return dependant1.endpoint.name.localeCompare(dependant2.endpoint.name); + dataPick.dependants.sort(function(dependant1, dependant2) { + return dependant1.endpoint.name.localeCompare( + dependant2.endpoint.name + ); }); return dataPick; }, this); @@ -772,7 +918,7 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { // Note that if one of them is marked as unresolvable, // the resolution has no effect resolution = this._resolutions[name]; - unresolvable = mout.object.find(picks, function (pick) { + unresolvable = mout.object.find(picks, function(pick) { return pick.unresolvable; }); @@ -781,33 +927,48 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { // Range resolution if (semver.validRange(resolution)) { - suitable = mout.array.findIndex(picks, function (pick) { - return pick.pkgMeta.version && - semver.satisfies(pick.pkgMeta.version, resolution); + suitable = mout.array.findIndex(picks, function(pick) { + return ( + pick.pkgMeta.version && + semver.satisfies(pick.pkgMeta.version, resolution) + ); }); } // Exact match resolution (e.g. branches/tags) if (suitable === -1) { - suitable = mout.array.findIndex(picks, function (pick) { - return pick.target === resolution || - pick.pkgMeta._release === resolution; + suitable = mout.array.findIndex(picks, function(pick) { + return ( + pick.target === resolution || + pick.pkgMeta._release === resolution + ); }); } if (suitable === -1) { - this._logger.warn('resolution', 'Unsuitable resolution declared for ' + name + ': ' + resolution, { - name: name, - picks: dataPicks, - resolution: resolution - }); + this._logger.warn( + 'resolution', + 'Unsuitable resolution declared for ' + + name + + ': ' + + resolution, + { + name: name, + picks: dataPicks, + resolution: resolution + } + ); } else { - this._logger.conflict('solved', 'Unable to find suitable version for ' + name, { - name: name, - picks: dataPicks, - resolution: resolution, - suitable: dataPicks[suitable] - }); + this._logger.conflict( + 'solved', + 'Unable to find suitable version for ' + name, + { + name: name, + picks: dataPicks, + resolution: resolution, + suitable: dataPicks[suitable] + } + ); return Q.resolve(picks[suitable]); } } @@ -817,16 +978,20 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { if (this._forceLatest) { suitable = picks.length - 1; - this._logger.conflict('solved', 'Unable to find suitable version for ' + name, { - name: name, - picks: dataPicks, - suitable: dataPicks[suitable], - forced: true - }); + this._logger.conflict( + 'solved', + 'Unable to find suitable version for ' + name, + { + name: name, + picks: dataPicks, + suitable: dataPicks[suitable], + forced: true + } + ); // Save resolution if (this._config.argv.cooked.includes('--save')) { - this._storeResolution(picks[suitable]); + this._storeResolution(picks[suitable]); } return Q.resolve(picks[suitable]); @@ -834,27 +999,39 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { // If interactive is disabled, error out if (!this._config.interactive) { - throw createError('Unable to find suitable version for ' + name, 'ECONFLICT', { - name: name, - picks: dataPicks - }); + throw createError( + 'Unable to find suitable version for ' + name, + 'ECONFLICT', + { + name: name, + picks: dataPicks + } + ); } // At this point the user needs to make a decision - this._logger.conflict('incompatible', 'Unable to find suitable version for ' + name, { - name: name, - picks: dataPicks - }); + this._logger.conflict( + 'incompatible', + 'Unable to find suitable version for ' + name, + { + name: name, + picks: dataPicks + } + ); - picksReleases = picks.map(function (pick) { return pick.pkgMeta._release; }); + picksReleases = picks.map(function(pick) { + return pick.pkgMeta._release; + }); return Q.nfcall(this._logger.prompt.bind(this._logger), { type: 'input', message: 'Answer', - validate: function (choice) { + validate: function(choice) { var invalidChoice = 'Invalid choice'; if (choice.match(versionRegex)) { - return picksReleases.indexOf(choice) != -1 ? true : invalidChoice; + return picksReleases.indexOf(choice) != -1 + ? true + : invalidChoice; } choice = Number(mout.string.trim(choice.trim(), '!')); @@ -865,31 +1042,32 @@ Manager.prototype._electSuitable = function (name, semvers, nonSemvers) { return true; } - }) - .then(function (choice) { - var pick; + }).then( + function(choice) { + var pick; - // Sanitize choice - choice = choice.trim(); - save = /^!/.test(choice) || /!$/.test(choice); // Save if prefixed or suffixed with ! + // Sanitize choice + choice = choice.trim(); + save = /^!/.test(choice) || /!$/.test(choice); // Save if prefixed or suffixed with ! - if (choice.match(versionRegex)) { - pick = picks[picksReleases.indexOf(choice)]; - } else { - choice = Number(mout.string.trim(choice, '!')); - pick = picks[choice - 1]; - } + if (choice.match(versionRegex)) { + pick = picks[picksReleases.indexOf(choice)]; + } else { + choice = Number(mout.string.trim(choice, '!')); + pick = picks[choice - 1]; + } - // Save resolution - if (save) { - this._storeResolution(pick); - } + // Save resolution + if (save) { + this._storeResolution(pick); + } - return pick; - }.bind(this)); + return pick; + }.bind(this) + ); }; -Manager.prototype._storeResolution = function (pick) { +Manager.prototype._storeResolution = function(pick) { var resolution; var name = pick.name; @@ -899,11 +1077,15 @@ Manager.prototype._storeResolution = function (pick) { resolution = pick.target; } - this._logger.info('resolution', 'Saved ' + name + '#' + resolution + ' as resolution', { - name: name, - resolution: resolution, - action: this._resolutions[name] ? 'edit' : 'add' - }); + this._logger.info( + 'resolution', + 'Saved ' + name + '#' + resolution + ' as resolution', + { + name: name, + resolution: resolution, + action: this._resolutions[name] ? 'edit' : 'add' + } + ); this._resolutions[name] = resolution; }; @@ -921,7 +1103,7 @@ Manager.prototype._storeResolution = function (pick) { * * @return {Boolean} */ -Manager.prototype._areCompatible = function (candidate, resolved) { +Manager.prototype._areCompatible = function(candidate, resolved) { var resolvedVersion; var highestCandidate; var highestResolved; @@ -956,18 +1138,24 @@ Manager.prototype._areCompatible = function (candidate, resolved) { // If both targets are range, check that both have same // higher cap if (resolvedIsRange && candidateIsRange) { - highestCandidate = - this._getCap(semver.toComparators(candidate.target), 'highest'); - highestResolved = - this._getCap(semver.toComparators(resolved.target), 'highest'); + highestCandidate = this._getCap( + semver.toComparators(candidate.target), + 'highest' + ); + highestResolved = this._getCap( + semver.toComparators(resolved.target), + 'highest' + ); // This never happens, but you can't be sure without tests if (!highestResolved.version || !highestCandidate.version) { return false; } - return semver.eq(highestCandidate.version, highestResolved.version) && - highestCandidate.comparator === highestResolved.comparator; + return ( + semver.eq(highestCandidate.version, highestResolved.version) && + highestCandidate.comparator === highestResolved.comparator + ); } return false; } @@ -1007,13 +1195,13 @@ Manager.prototype._areCompatible = function (candidate, resolved) { * * @return {{ comparator: string, version: string }} */ -Manager.prototype._getCap = function (comparators, side) { +Manager.prototype._getCap = function(comparators, side) { var matches; var candidate; var cap = {}; var compare = side === 'lowest' ? semver.lt : semver.gt; - comparators.forEach(function (comparator) { + comparators.forEach(function(comparator) { // Get version of this comparator // If it's an array, call recursively if (Array.isArray(comparator)) { @@ -1023,8 +1211,8 @@ Manager.prototype._getCap = function (comparators, side) { if (!cap.version || compare(candidate.version, cap.version)) { cap = candidate; } - // Otherwise extract the version from the comparator - // using a simple regexp + // Otherwise extract the version from the comparator + // using a simple regexp } else { matches = comparator.match(/(.*?)(\d+\.\d+\.\d+.*)$/); if (!matches) { @@ -1059,10 +1247,10 @@ Manager.prototype._getCap = function (comparators, side) { * @return {Array.} Filtered elements of decEndpoints * */ -Manager.prototype._uniquify = function (decEndpoints) { +Manager.prototype._uniquify = function(decEndpoints) { var length = decEndpoints.length; - return decEndpoints.filter(function (decEndpoint, index) { + return decEndpoints.filter(function(decEndpoint, index) { var x; var current; diff --git a/lib/core/PackageRepository.js b/lib/core/PackageRepository.js index 574e8e561..2ab15f603 100644 --- a/lib/core/PackageRepository.js +++ b/lib/core/PackageRepository.js @@ -6,7 +6,6 @@ var createError = require('../util/createError'); var RegistryClient = require('bower-registry-client'); function PackageRepository(config, logger) { - var registryOptions; this._config = config; @@ -24,7 +23,7 @@ function PackageRepository(config, logger) { // ----------------- -PackageRepository.prototype.fetch = function (decEndpoint) { +PackageRepository.prototype.fetch = function(decEndpoint) { var logger; var that = this; var isTargetable; @@ -36,132 +35,192 @@ PackageRepository.prototype.fetch = function (decEndpoint) { // used to fetch logger = this._logger.geminate(); // Intercept all logs, adding additional information - logger.intercept(function (log) { + logger.intercept(function(log) { that._extendLog(log, info); }); - return this._getResolver(decEndpoint, logger) - // Decide if we retrieve from the cache or not - // Also decide if we validate the cached entry or not - .then(function (resolver) { - info.resolver = resolver; - isTargetable = resolver.constructor.isTargetable; - - if (!resolver.isCacheable()) { - return that._resolve(resolver, logger); - } - - // If force flag is used, bypass cache, but write to cache anyway - if (that._config.force) { - logger.action('resolve', resolver.getSource() + '#' + resolver.getTarget()); - return that._resolve(resolver, logger); - } - - // Note that we use the resolver methods to query the - // cache because transformations/normalisations can occur - return that._resolveCache.retrieve(resolver.getSource(), resolver.getTarget()) - // Decide if we can use the one from the resolve cache - .spread(function (canonicalDir, pkgMeta) { - // If there's no package in the cache - if (!canonicalDir) { - // And the offline flag is passed, error out - if (that._config.offline) { - throw createError('No cached version for ' + resolver.getSource() + '#' + resolver.getTarget(), 'ENOCACHE', { - resolver: resolver - }); - } - - // Otherwise, we have to resolve it - logger.info('not-cached', resolver.getSource() + (resolver.getTarget() ? '#' + resolver.getTarget() : '')); - logger.action('resolve', resolver.getSource() + '#' + resolver.getTarget()); - - return that._resolve(resolver, logger); - } - - info.canonicalDir = canonicalDir; - info.pkgMeta = pkgMeta; - - logger.info('cached', resolver.getSource() + (pkgMeta._release ? '#' + pkgMeta._release : '')); - - // If offline flag is used, use directly the cached one - if (that._config.offline) { - return [canonicalDir, pkgMeta, isTargetable]; - } + return ( + this._getResolver(decEndpoint, logger) + // Decide if we retrieve from the cache or not + // Also decide if we validate the cached entry or not + .then(function(resolver) { + info.resolver = resolver; + isTargetable = resolver.constructor.isTargetable; - // Otherwise check for new contents - logger.action('validate', (pkgMeta._release ? pkgMeta._release + ' against ' : '') + - resolver.getSource() + (resolver.getTarget() ? '#' + resolver.getTarget() : '')); + if (!resolver.isCacheable()) { + return that._resolve(resolver, logger); + } - return resolver.hasNew(pkgMeta) - .then(function (hasNew) { - // If there are no new contents, resolve to - // the cached one - if (!hasNew) { - return [canonicalDir, pkgMeta, isTargetable]; + // If force flag is used, bypass cache, but write to cache anyway + if (that._config.force) { + logger.action( + 'resolve', + resolver.getSource() + '#' + resolver.getTarget() + ); + return that._resolve(resolver, logger); } - // Otherwise resolve to the newest one - logger.info('new', 'version for ' + resolver.getSource() + '#' + resolver.getTarget()); - logger.action('resolve', resolver.getSource() + '#' + resolver.getTarget()); - - return that._resolve(resolver, logger); - }); - }); - }) - // If something went wrong, also extend the error - .fail(function (err) { - that._extendLog(err, info); - throw err; - }); + // Note that we use the resolver methods to query the + // cache because transformations/normalisations can occur + return ( + that._resolveCache + .retrieve(resolver.getSource(), resolver.getTarget()) + // Decide if we can use the one from the resolve cache + .spread(function(canonicalDir, pkgMeta) { + // If there's no package in the cache + if (!canonicalDir) { + // And the offline flag is passed, error out + if (that._config.offline) { + throw createError( + 'No cached version for ' + + resolver.getSource() + + '#' + + resolver.getTarget(), + 'ENOCACHE', + { + resolver: resolver + } + ); + } + + // Otherwise, we have to resolve it + logger.info( + 'not-cached', + resolver.getSource() + + (resolver.getTarget() + ? '#' + resolver.getTarget() + : '') + ); + logger.action( + 'resolve', + resolver.getSource() + + '#' + + resolver.getTarget() + ); + + return that._resolve(resolver, logger); + } + + info.canonicalDir = canonicalDir; + info.pkgMeta = pkgMeta; + + logger.info( + 'cached', + resolver.getSource() + + (pkgMeta._release + ? '#' + pkgMeta._release + : '') + ); + + // If offline flag is used, use directly the cached one + if (that._config.offline) { + return [canonicalDir, pkgMeta, isTargetable]; + } + + // Otherwise check for new contents + logger.action( + 'validate', + (pkgMeta._release + ? pkgMeta._release + ' against ' + : '') + + resolver.getSource() + + (resolver.getTarget() + ? '#' + resolver.getTarget() + : '') + ); + + return resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + // If there are no new contents, resolve to + // the cached one + if (!hasNew) { + return [ + canonicalDir, + pkgMeta, + isTargetable + ]; + } + + // Otherwise resolve to the newest one + logger.info( + 'new', + 'version for ' + + resolver.getSource() + + '#' + + resolver.getTarget() + ); + logger.action( + 'resolve', + resolver.getSource() + + '#' + + resolver.getTarget() + ); + + return that._resolve(resolver, logger); + }); + }) + ); + }) + // If something went wrong, also extend the error + .fail(function(err) { + that._extendLog(err, info); + throw err; + }) + ); }; -PackageRepository.prototype.versions = function (source) { +PackageRepository.prototype.versions = function(source) { // Resolve the source using the factory because the // source can actually be a registry name - return this._getResolver({ source: source }) - .then(function (resolver) { - // If offline, resolve using the cached versions - if (this._config.offline) { - return this._resolveCache.versions(resolver.getSource()); - } - - // Otherwise, fetch remotely - return resolver.constructor.versions(resolver.getSource()); - }.bind(this)); + return this._getResolver({ source: source }).then( + function(resolver) { + // If offline, resolve using the cached versions + if (this._config.offline) { + return this._resolveCache.versions(resolver.getSource()); + } + + // Otherwise, fetch remotely + return resolver.constructor.versions(resolver.getSource()); + }.bind(this) + ); }; -PackageRepository.prototype.eliminate = function (pkgMeta) { +PackageRepository.prototype.eliminate = function(pkgMeta) { return Q.all([ this._resolveCache.eliminate(pkgMeta), - Q.nfcall(this._registryClient.clearCache.bind(this._registryClient), pkgMeta.name) + Q.nfcall( + this._registryClient.clearCache.bind(this._registryClient), + pkgMeta.name + ) ]); }; -PackageRepository.prototype.clear = function () { +PackageRepository.prototype.clear = function() { return Q.all([ this._resolveCache.clear(), Q.nfcall(this._registryClient.clearCache.bind(this._registryClient)) ]); }; -PackageRepository.prototype.reset = function () { +PackageRepository.prototype.reset = function() { this._resolveCache.reset(); this._registryClient.resetCache(); }; -PackageRepository.prototype.list = function () { +PackageRepository.prototype.list = function() { return this._resolveCache.list(); }; -PackageRepository.prototype.getRegistryClient = function () { +PackageRepository.prototype.getRegistryClient = function() { return this._registryClient; }; -PackageRepository.prototype.getResolveCache = function () { +PackageRepository.prototype.getResolveCache = function() { return this._resolveCache; }; -PackageRepository.clearRuntimeCache = function () { +PackageRepository.clearRuntimeCache = function() { ResolveCache.clearRuntimeCache(); RegistryClient.clearRuntimeCache(); resolverFactory.clearRuntimeCache(); @@ -169,41 +228,59 @@ PackageRepository.clearRuntimeCache = function () { // --------------------- -PackageRepository.prototype._getResolver = function (decEndpoint, logger) { +PackageRepository.prototype._getResolver = function(decEndpoint, logger) { logger = logger || this._logger; // Get the appropriate resolver - return resolverFactory(decEndpoint, { config: this._config, logger: logger }, this._registryClient); + return resolverFactory( + decEndpoint, + { config: this._config, logger: logger }, + this._registryClient + ); }; -PackageRepository.prototype._resolve = function (resolver, logger) { +PackageRepository.prototype._resolve = function(resolver, logger) { var that = this; // Resolve the resolver - return resolver.resolve() - // Store in the cache - .then(function (canonicalDir) { - if (!resolver.isCacheable()) { - return canonicalDir; - } - - return that._resolveCache.store(canonicalDir, resolver.getPkgMeta()); - }) - // Resolve promise with canonical dir and package meta - .then(function (dir) { - var pkgMeta = resolver.getPkgMeta(); - - logger.info('resolved', resolver.getSource() + (pkgMeta._release ? '#' + pkgMeta._release : '')); - return [dir, pkgMeta, resolver.constructor.isTargetable()]; - }); + return ( + resolver + .resolve() + // Store in the cache + .then(function(canonicalDir) { + if (!resolver.isCacheable()) { + return canonicalDir; + } + + return that._resolveCache.store( + canonicalDir, + resolver.getPkgMeta() + ); + }) + // Resolve promise with canonical dir and package meta + .then(function(dir) { + var pkgMeta = resolver.getPkgMeta(); + + logger.info( + 'resolved', + resolver.getSource() + + (pkgMeta._release ? '#' + pkgMeta._release : '') + ); + return [dir, pkgMeta, resolver.constructor.isTargetable()]; + }) + ); }; -PackageRepository.prototype._extendLog = function (log, info) { +PackageRepository.prototype._extendLog = function(log, info) { log.data = log.data || {}; // Store endpoint info in each log if (info.decEndpoint) { - log.data.endpoint = mout.object.pick(info.decEndpoint, ['name', 'source', 'target']); + log.data.endpoint = mout.object.pick(info.decEndpoint, [ + 'name', + 'source', + 'target' + ]); } // Store the resolver info in each log diff --git a/lib/core/Project.js b/lib/core/Project.js index 62f649b74..72c3c12f8 100644 --- a/lib/core/Project.js +++ b/lib/core/Project.js @@ -25,7 +25,7 @@ function Project(config, logger) { // ----------------- -Project.prototype.install = function (decEndpoints, options, config) { +Project.prototype.install = function(decEndpoints, options, config) { var that = this; var targets = []; var resolved = {}; @@ -42,84 +42,107 @@ Project.prototype.install = function (decEndpoints, options, config) { // Analyse the project return this._analyse() - .spread(function (json, tree) { - // It shows an error when issuing `bower install` - // and no bower.json is present in current directory - if (!that._jsonFile && decEndpoints.length === 0 ) { - throw createError('No bower.json present', 'ENOENT'); - } - - // Recover tree - that.walkTree(tree, function (node, name) { - if (node.incompatible) { - incompatibles.push(node); - } else if (node.missing || node.different || that._config.force) { - targets.push(node); - } else { - resolved[name] = node; + .spread(function(json, tree) { + // It shows an error when issuing `bower install` + // and no bower.json is present in current directory + if (!that._jsonFile && decEndpoints.length === 0) { + throw createError('No bower.json present', 'ENOENT'); } - }, true); - - // Add decomposed endpoints as targets - decEndpoints = decEndpoints || []; - decEndpoints.forEach(function (decEndpoint) { - // Mark as new so that a conflict for this target - // always require a choice - // Also allows for the target to be converted in case - // of being * - decEndpoint.newly = true; - targets.push(decEndpoint); - }); - // Bootstrap the process - return that._bootstrap(targets, resolved, incompatibles); - }) - .then(function () { - return that._manager.preinstall(that._json); - }) - .then(function () { - return that._manager.install(that._json); - }) - .then(function (installed) { - // Handle save and saveDev options - if (that._options.save || that._options.saveDev || that._options.saveExact || that._config.save || that._config.saveExact) { - // Cycle through the specified endpoints - decEndpoints.forEach(function (decEndpoint) { - var jsonEndpoint; - - jsonEndpoint = endpointParser.decomposed2json(decEndpoint); - - if (that._options.saveExact || that._config.saveExact) { - if (decEndpoint.name !== decEndpoint.source) { - jsonEndpoint[decEndpoint.name] = decEndpoint.source + '#' + decEndpoint.pkgMeta.version; + // Recover tree + that.walkTree( + tree, + function(node, name) { + if (node.incompatible) { + incompatibles.push(node); + } else if ( + node.missing || + node.different || + that._config.force + ) { + targets.push(node); } else { - jsonEndpoint[decEndpoint.name] = decEndpoint.pkgMeta.version; + resolved[name] = node; } - } - - if (that._options.saveDev) { - that._json.devDependencies = mout.object.mixIn(that._json.devDependencies || {}, jsonEndpoint); - } else { - that._json.dependencies = mout.object.mixIn(that._json.dependencies || {}, jsonEndpoint); - } + }, + true + ); + + // Add decomposed endpoints as targets + decEndpoints = decEndpoints || []; + decEndpoints.forEach(function(decEndpoint) { + // Mark as new so that a conflict for this target + // always require a choice + // Also allows for the target to be converted in case + // of being * + decEndpoint.newly = true; + targets.push(decEndpoint); }); - } - // Save JSON, might contain changes to dependencies and resolutions - return that.saveJson() - .then(function () { - return that._manager.postinstall(that._json).then(function () { - return installed; + // Bootstrap the process + return that._bootstrap(targets, resolved, incompatibles); + }) + .then(function() { + return that._manager.preinstall(that._json); + }) + .then(function() { + return that._manager.install(that._json); + }) + .then(function(installed) { + // Handle save and saveDev options + if ( + that._options.save || + that._options.saveDev || + that._options.saveExact || + that._config.save || + that._config.saveExact + ) { + // Cycle through the specified endpoints + decEndpoints.forEach(function(decEndpoint) { + var jsonEndpoint; + + jsonEndpoint = endpointParser.decomposed2json(decEndpoint); + + if (that._options.saveExact || that._config.saveExact) { + if (decEndpoint.name !== decEndpoint.source) { + jsonEndpoint[decEndpoint.name] = + decEndpoint.source + + '#' + + decEndpoint.pkgMeta.version; + } else { + jsonEndpoint[decEndpoint.name] = + decEndpoint.pkgMeta.version; + } + } + + if (that._options.saveDev) { + that._json.devDependencies = mout.object.mixIn( + that._json.devDependencies || {}, + jsonEndpoint + ); + } else { + that._json.dependencies = mout.object.mixIn( + that._json.dependencies || {}, + jsonEndpoint + ); + } + }); + } + + // Save JSON, might contain changes to dependencies and resolutions + return that.saveJson().then(function() { + return that._manager.postinstall(that._json).then(function() { + return installed; + }); }); + }) + .fin(function() { + that._installed = null; + that._working = false; }); - }) - .fin(function () { - that._installed = null; - that._working = false; - }); }; -Project.prototype.update = function (names, options) { +Project.prototype.update = function(names, options) { var that = this; var targets = []; var resolved = {}; @@ -135,99 +158,124 @@ Project.prototype.update = function (names, options) { // Analyse the project return this._analyse() - .spread(function (json, tree, flattened) { - // If no names were specified, update every package - if (!names) { - // Mark each root dependency as targets - that.walkTree(tree, function (node) { - // We don't know the real source of linked packages - // Instead we read its dependencies - if (node.linked) { - targets.push.apply(targets, mout.object.values(node.dependencies)); - } else { - targets.push(node); - } - - return false; - }, true); - // Otherwise, selectively update the specified ones - } else { - // Error out if some of the specified names - // are not installed - names.forEach(function (name) { - if (!flattened[name]) { - throw createError('Package ' + name + ' is not installed', 'ENOTINS', { - name: name - }); - } - }); - - // Add packages whose names are specified to be updated - that.walkTree(tree, function (node, name) { - if (names.indexOf(name) !== -1) { - // We don't know the real source of linked packages - // Instead we read its dependencies - if (node.linked) { - targets.push.apply(targets, mout.object.values(node.dependencies)); - } else { - targets.push(node); + .spread(function(json, tree, flattened) { + // If no names were specified, update every package + if (!names) { + // Mark each root dependency as targets + that.walkTree( + tree, + function(node) { + // We don't know the real source of linked packages + // Instead we read its dependencies + if (node.linked) { + targets.push.apply( + targets, + mout.object.values(node.dependencies) + ); + } else { + targets.push(node); + } + + return false; + }, + true + ); + // Otherwise, selectively update the specified ones + } else { + // Error out if some of the specified names + // are not installed + names.forEach(function(name) { + if (!flattened[name]) { + throw createError( + 'Package ' + name + ' is not installed', + 'ENOTINS', + { + name: name + } + ); } + }); - return false; - } - }, true); - - // Recover tree - that.walkTree(tree, function (node, name) { - if (node.missing || node.different) { - targets.push(node); - } else if (node.incompatible) { - incompatibles.push(node); - } else { - resolved[name] = node; - } - }, true); - } + // Add packages whose names are specified to be updated + that.walkTree( + tree, + function(node, name) { + if (names.indexOf(name) !== -1) { + // We don't know the real source of linked packages + // Instead we read its dependencies + if (node.linked) { + targets.push.apply( + targets, + mout.object.values(node.dependencies) + ); + } else { + targets.push(node); + } + + return false; + } + }, + true + ); + + // Recover tree + that.walkTree( + tree, + function(node, name) { + if (node.missing || node.different) { + targets.push(node); + } else if (node.incompatible) { + incompatibles.push(node); + } else { + resolved[name] = node; + } + }, + true + ); + } - // Bootstrap the process - return that._bootstrap(targets, resolved, incompatibles) - .then(function () { - return that._manager.preinstall(that._json); - }) - .then(function () { - return that._manager.install(that._json); - }) - .then(function (installed) { - // Save JSON, might contain changes to resolutions - return that.saveJson() - .then(function () { - return that._manager.postinstall(that._json).then(function () { - return installed; + // Bootstrap the process + return that + ._bootstrap(targets, resolved, incompatibles) + .then(function() { + return that._manager.preinstall(that._json); + }) + .then(function() { + return that._manager.install(that._json); + }) + .then(function(installed) { + // Save JSON, might contain changes to resolutions + return that.saveJson().then(function() { + return that._manager + .postinstall(that._json) + .then(function() { + return installed; + }); + }); }); - }); + }) + .fin(function() { + that._installed = null; + that._working = false; }); - }) - .fin(function () { - that._installed = null; - that._working = false; - }); }; -function resolveUrlNames(names, flattened) -{ +function resolveUrlNames(names, flattened) { for (var i = 0; i < names.length; i++) - if (! flattened[names[i]]) - { + if (!flattened[names[i]]) { var url = names[i].trim().replace(/\/$/, ''); var packName; for (packName in flattened) - if (! ( !flattened[packName].source)) - if (url == flattened[packName].source.trim().replace(/\/$/, '')) + if (!!flattened[packName].source) + if ( + url == + flattened[packName].source.trim().replace(/\/$/, '') + ) names[i] = packName; } } -Project.prototype.uninstall = function (names, options) { +Project.prototype.uninstall = function(names, options) { var that = this; var packages = {}; @@ -240,150 +288,192 @@ Project.prototype.uninstall = function (names, options) { this._working = true; // Analyse the project - return this._analyse() - // Fill in the packages to be uninstalled - .spread(function (json, tree, flattened) { - var promise = Q.resolve(); - resolveUrlNames(names, flattened); - - names.forEach(function (name) { - var decEndpoint = flattened[name]; - - // Check if it is not installed - if (!decEndpoint || decEndpoint.missing) { - packages[name] = null; - return; - } - - promise = promise - .then(function () { - var message; - var data; - var dependantsNames; - var dependants = []; - - // Walk the down the tree, gathering dependants of the package - that.walkTree(tree, function (node, nodeName) { - if (name === nodeName) { - dependants.push.apply(dependants, mout.object.values(node.dependants)); + return ( + this._analyse() + // Fill in the packages to be uninstalled + .spread(function(json, tree, flattened) { + var promise = Q.resolve(); + resolveUrlNames(names, flattened); + + names.forEach(function(name) { + var decEndpoint = flattened[name]; + + // Check if it is not installed + if (!decEndpoint || decEndpoint.missing) { + packages[name] = null; + return; } - }, true); - - // Remove duplicates - dependants = mout.array.unique(dependants); - - // Note that the root is filtered from the dependants - // as well as other dependants marked to be uninstalled - dependants = dependants.filter(function (dependant) { - return !dependant.root && names.indexOf(dependant.name) === -1; - }); - - // If the package has no dependants or the force config is enabled, - // mark it to be removed - if (!dependants.length || that._config.force) { - packages[name] = decEndpoint.canonicalDir; - return; - } - // Otherwise we need to figure it out if the user really wants to remove it, - // even with dependants - // As such we need to prompt the user with a meaningful message - dependantsNames = dependants.map(function (dep) { return dep.name; }); - dependantsNames.sort(function (name1, name2) { return name1.localeCompare(name2); }); - dependantsNames = mout.array.unique(dependantsNames); - dependants = dependants.map(function (dependant) { return that._manager.toData(dependant); }); - message = dependantsNames.join(', ') + ' depends on ' + decEndpoint.name; - data = { - name: decEndpoint.name, - dependants: dependants - }; + promise = promise.then(function() { + var message; + var data; + var dependantsNames; + var dependants = []; + + // Walk the down the tree, gathering dependants of the package + that.walkTree( + tree, + function(node, nodeName) { + if (name === nodeName) { + dependants.push.apply( + dependants, + mout.object.values(node.dependants) + ); + } + }, + true + ); + + // Remove duplicates + dependants = mout.array.unique(dependants); + + // Note that the root is filtered from the dependants + // as well as other dependants marked to be uninstalled + dependants = dependants.filter(function(dependant) { + return ( + !dependant.root && + names.indexOf(dependant.name) === -1 + ); + }); - // If interactive is disabled, error out - if (!that._config.interactive) { - throw createError(message, 'ECONFLICT', { - data: data + // If the package has no dependants or the force config is enabled, + // mark it to be removed + if (!dependants.length || that._config.force) { + packages[name] = decEndpoint.canonicalDir; + return; + } + + // Otherwise we need to figure it out if the user really wants to remove it, + // even with dependants + // As such we need to prompt the user with a meaningful message + dependantsNames = dependants.map(function(dep) { + return dep.name; + }); + dependantsNames.sort(function(name1, name2) { + return name1.localeCompare(name2); + }); + dependantsNames = mout.array.unique(dependantsNames); + dependants = dependants.map(function(dependant) { + return that._manager.toData(dependant); + }); + message = + dependantsNames.join(', ') + + ' depends on ' + + decEndpoint.name; + data = { + name: decEndpoint.name, + dependants: dependants + }; + + // If interactive is disabled, error out + if (!that._config.interactive) { + throw createError(message, 'ECONFLICT', { + data: data + }); + } + + that._logger.conflict('mutual', message, data); + + // Prompt the user + return Q.nfcall( + that._logger.prompt.bind(that._logger), + { + type: 'confirm', + message: 'Continue anyway?', + default: true + } + ).then(function(confirmed) { + // If the user decided to skip it, remove from the array so that it won't + // influence subsequent dependants + if (!confirmed) { + mout.array.remove(names, name); + } else { + packages[name] = decEndpoint.canonicalDir; + } + }); }); - } - - that._logger.conflict('mutual', message, data); - - // Prompt the user - return Q.nfcall(that._logger.prompt.bind(that._logger), { - type: 'confirm', - message: 'Continue anyway?', - default: true - }) - .then(function (confirmed) { - // If the user decided to skip it, remove from the array so that it won't - // influence subsequent dependants - if (!confirmed) { - mout.array.remove(names, name); - } else { - packages[name] = decEndpoint.canonicalDir; - } }); - }); - }); - return promise; - }) - // Remove packages - .then(function () { - return that._removePackages(packages); - }) - .fin(function () { - that._installed = null; - that._working = false; - }); + return promise; + }) + // Remove packages + .then(function() { + return that._removePackages(packages); + }) + .fin(function() { + that._installed = null; + that._working = false; + }) + ); }; -Project.prototype.getTree = function (options) { +Project.prototype.getTree = function(options) { this._options = options || {}; - return this._analyse() - .spread(function (json, tree, flattened) { - var extraneous = []; - var additionalKeys = ['missing', 'extraneous', 'different', 'linked']; - - // Convert tree - tree = this._manager.toData(tree, additionalKeys); - - // Mark incompatibles - this.walkTree(tree, function (node) { - var version; - var target = node.endpoint.target; - - if (node.pkgMeta && semver.validRange(target)) { - version = node.pkgMeta.version; - - // Ignore if target is '*' and resolved to a non-semver release - if (!version && target === '*') { - return; - } - - if (!version || !semver.satisfies(version, target)) { - node.incompatible = true; - } - } - }, true); - - // Convert extraneous - mout.object.forOwn(flattened, function (pkg) { - if (pkg.extraneous) { - extraneous.push(this._manager.toData(pkg, additionalKeys)); - } - }, this); - - // Convert flattened - flattened = mout.object.map(flattened, function (node) { - return this._manager.toData(node, additionalKeys); - }, this); - - return [tree, flattened, extraneous]; - }.bind(this)); + return this._analyse().spread( + function(json, tree, flattened) { + var extraneous = []; + var additionalKeys = [ + 'missing', + 'extraneous', + 'different', + 'linked' + ]; + + // Convert tree + tree = this._manager.toData(tree, additionalKeys); + + // Mark incompatibles + this.walkTree( + tree, + function(node) { + var version; + var target = node.endpoint.target; + + if (node.pkgMeta && semver.validRange(target)) { + version = node.pkgMeta.version; + + // Ignore if target is '*' and resolved to a non-semver release + if (!version && target === '*') { + return; + } + + if (!version || !semver.satisfies(version, target)) { + node.incompatible = true; + } + } + }, + true + ); + + // Convert extraneous + mout.object.forOwn( + flattened, + function(pkg) { + if (pkg.extraneous) { + extraneous.push( + this._manager.toData(pkg, additionalKeys) + ); + } + }, + this + ); + + // Convert flattened + flattened = mout.object.map( + flattened, + function(node) { + return this._manager.toData(node, additionalKeys); + }, + this + ); + + return [tree, flattened, extraneous]; + }.bind(this) + ); }; -Project.prototype.walkTree = function (node, fn, onlyOnce) { +Project.prototype.walkTree = function(node, fn, onlyOnce) { var result; var dependencies; var queue = mout.object.values(node.dependencies); @@ -406,15 +496,20 @@ Project.prototype.walkTree = function (node, fn, onlyOnce) { // If onlyOnce was true, do not add if already traversed if (onlyOnce) { - dependencies = dependencies.filter(function (dependency) { - return !mout.array.find(onlyOnce, function (stacked) { + dependencies = dependencies.filter(function(dependency) { + return !mout.array.find(onlyOnce, function(stacked) { if (dependency.endpoint) { - return mout.object.equals(dependency.endpoint, stacked.endpoint); + return mout.object.equals( + dependency.endpoint, + stacked.endpoint + ); } - return dependency.name === stacked.name && - dependency.source === stacked.source && - dependency.target === stacked.target; + return ( + dependency.name === stacked.name && + dependency.source === stacked.source && + dependency.target === stacked.target + ); }); }); @@ -425,7 +520,7 @@ Project.prototype.walkTree = function (node, fn, onlyOnce) { } }; -Project.prototype.saveJson = function (forceCreate) { +Project.prototype.saveJson = function(forceCreate) { var file; var jsonStr = JSON.stringify(this._json, null, ' ') + '\n'; var jsonHash = md5(jsonStr); @@ -438,109 +533,127 @@ Project.prototype.saveJson = function (forceCreate) { // Error out if the json file does not exist, unless force create // is true if (!this._jsonFile && !forceCreate) { - this._logger.warn('no-json', 'No bower.json file to save to, use bower init to create one'); + this._logger.warn( + 'no-json', + 'No bower.json file to save to, use bower init to create one' + ); return Q.resolve(); } file = this._jsonFile || path.join(this._config.cwd, 'bower.json'); - return Q.nfcall(fs.writeFile, file, jsonStr) - .then(function () { - this._jsonHash = jsonHash; - this._jsonFile = file; - return this._json; - }.bind(this)); + return Q.nfcall(fs.writeFile, file, jsonStr).then( + function() { + this._jsonHash = jsonHash; + this._jsonFile = file; + return this._json; + }.bind(this) + ); }; -Project.prototype.hasJson = function () { - return this._readJson() - .then(function (json) { - return json ? this._jsonFile : false; - }.bind(this)); +Project.prototype.hasJson = function() { + return this._readJson().then( + function(json) { + return json ? this._jsonFile : false; + }.bind(this) + ); }; -Project.prototype.getJson = function () { +Project.prototype.getJson = function() { return this._readJson(); }; -Project.prototype.getManager = function () { +Project.prototype.getManager = function() { return this._manager; }; -Project.prototype.getPackageRepository = function () { +Project.prototype.getPackageRepository = function() { return this._manager.getPackageRepository(); }; // ----------------- -Project.prototype._analyse = function () { +Project.prototype._analyse = function() { return Q.all([ this._readJson(), this._readInstalled(), this._readLinks() - ]) - .spread(function (json, installed, links) { - var root; - var jsonCopy = mout.lang.deepClone(json); - - root = { - name: json.name, - source: this._config.cwd, - target: json.version || '*', - pkgMeta: jsonCopy, - canonicalDir: this._config.cwd, - root: true - }; - - mout.object.mixIn(installed, links); - - // Mix direct extraneous as dependencies - // (dependencies installed without --save/--save-dev) - jsonCopy.dependencies = jsonCopy.dependencies || {}; - jsonCopy.devDependencies = jsonCopy.devDependencies || {}; - mout.object.forOwn(installed, function (decEndpoint, key) { - var pkgMeta = decEndpoint.pkgMeta; - var isSaved = jsonCopy.dependencies[key] || jsonCopy.devDependencies[key]; - - // The _direct propery is saved by the manager when .newly is specified - // It may happen pkgMeta is undefined if package is uninstalled - if (!isSaved && pkgMeta && pkgMeta._direct) { - decEndpoint.extraneous = true; - - if (decEndpoint.linked) { - jsonCopy.dependencies[key] = pkgMeta.version || '*'; - } else { - jsonCopy.dependencies[key] = (pkgMeta._originalSource || pkgMeta._source) + '#' + pkgMeta._target; + ]).spread( + function(json, installed, links) { + var root; + var jsonCopy = mout.lang.deepClone(json); + + root = { + name: json.name, + source: this._config.cwd, + target: json.version || '*', + pkgMeta: jsonCopy, + canonicalDir: this._config.cwd, + root: true + }; + + mout.object.mixIn(installed, links); + + // Mix direct extraneous as dependencies + // (dependencies installed without --save/--save-dev) + jsonCopy.dependencies = jsonCopy.dependencies || {}; + jsonCopy.devDependencies = jsonCopy.devDependencies || {}; + mout.object.forOwn(installed, function(decEndpoint, key) { + var pkgMeta = decEndpoint.pkgMeta; + var isSaved = + jsonCopy.dependencies[key] || jsonCopy.devDependencies[key]; + + // The _direct propery is saved by the manager when .newly is specified + // It may happen pkgMeta is undefined if package is uninstalled + if (!isSaved && pkgMeta && pkgMeta._direct) { + decEndpoint.extraneous = true; + + if (decEndpoint.linked) { + jsonCopy.dependencies[key] = pkgMeta.version || '*'; + } else { + jsonCopy.dependencies[key] = + (pkgMeta._originalSource || pkgMeta._source) + + '#' + + pkgMeta._target; + } } - } - }); - - // Restore the original dependencies cross-references, - // that is, the parent-child relationships - this._restoreNode(root, installed, 'dependencies'); - // Do the same for the dev dependencies - if (!this._options.production) { - this._restoreNode(root, installed, 'devDependencies'); - } + }); - // Restore the rest of the extraneous (not installed directly) - mout.object.forOwn(installed, function (decEndpoint, name) { - if (!decEndpoint.dependants) { - decEndpoint.extraneous = true; - this._restoreNode(decEndpoint, installed, 'dependencies'); - // Note that it has no dependants, just dependencies! - root.dependencies[name] = decEndpoint; + // Restore the original dependencies cross-references, + // that is, the parent-child relationships + this._restoreNode(root, installed, 'dependencies'); + // Do the same for the dev dependencies + if (!this._options.production) { + this._restoreNode(root, installed, 'devDependencies'); } - }, this); - // Remove root from the flattened tree - delete installed[json.name]; + // Restore the rest of the extraneous (not installed directly) + mout.object.forOwn( + installed, + function(decEndpoint, name) { + if (!decEndpoint.dependants) { + decEndpoint.extraneous = true; + this._restoreNode( + decEndpoint, + installed, + 'dependencies' + ); + // Note that it has no dependants, just dependencies! + root.dependencies[name] = decEndpoint; + } + }, + this + ); + + // Remove root from the flattened tree + delete installed[json.name]; - return [json, root, installed]; - }.bind(this)); + return [json, root, installed]; + }.bind(this) + ); }; -Project.prototype._bootstrap = function (targets, resolved, incompatibles) { - var installed = mout.object.map(this._installed, function (decEndpoint) { +Project.prototype._bootstrap = function(targets, resolved, incompatibles) { + var installed = mout.object.map(this._installed, function(decEndpoint) { return decEndpoint.pkgMeta; }); @@ -548,72 +661,85 @@ Project.prototype._bootstrap = function (targets, resolved, incompatibles) { // Configure the manager and kick in the resolve process return this._manager - .configure({ - targets: targets, - resolved: resolved, - incompatibles: incompatibles, - resolutions: this._json.resolutions, - installed: installed, - forceLatest: this._options.forceLatest - }) - .resolve() - .then(function () { - // If the resolutions is empty, delete key - if (!mout.object.size(this._json.resolutions)) { - delete this._json.resolutions; - } - }.bind(this)); + .configure({ + targets: targets, + resolved: resolved, + incompatibles: incompatibles, + resolutions: this._json.resolutions, + installed: installed, + forceLatest: this._options.forceLatest + }) + .resolve() + .then( + function() { + // If the resolutions is empty, delete key + if (!mout.object.size(this._json.resolutions)) { + delete this._json.resolutions; + } + }.bind(this) + ); }; -Project.prototype._readJson = function () { +Project.prototype._readJson = function() { var that = this; if (this._json) { return Q.resolve(this._json); } - return Q.fcall(function () { + return Q.fcall(function() { // This will throw if package.json does not exist return fs.readFileSync(path.join(that._config.cwd, 'package.json')); }) - .then(function (buffer) { - // If package.json exists, use it's values as defaults - var defaults = {}, npm = JSON.parse(buffer.toString()); - - defaults.name = npm.name || path.basename(that._config.cwd) || 'root'; - defaults.description = npm.description; - defaults.main = npm.main; - defaults.authors = npm.contributors || npm.author; - defaults.license = npm.license; - defaults.keywords = npm.keywords; - - return defaults; - }) - .catch(function (err) { - // Most likely no package.json so just set default name - return { name: path.basename(that._config.cwd) || 'root' }; - }) - .then(function (defaults) { - return that._json = readJson(that._config.cwd, { assume: defaults, logger: that._logger }); - }) - .spread(function (json, deprecated, assumed) { - var jsonStr; - - if (deprecated) { - that._logger.warn('deprecated', 'You are using the deprecated ' + deprecated + ' file'); - } + .then(function(buffer) { + // If package.json exists, use it's values as defaults + var defaults = {}, + npm = JSON.parse(buffer.toString()); + + defaults.name = + npm.name || path.basename(that._config.cwd) || 'root'; + defaults.description = npm.description; + defaults.main = npm.main; + defaults.authors = npm.contributors || npm.author; + defaults.license = npm.license; + defaults.keywords = npm.keywords; + + return defaults; + }) + .catch(function(err) { + // Most likely no package.json so just set default name + return { name: path.basename(that._config.cwd) || 'root' }; + }) + .then(function(defaults) { + return (that._json = readJson(that._config.cwd, { + assume: defaults, + logger: that._logger + })); + }) + .spread(function(json, deprecated, assumed) { + var jsonStr; + + if (deprecated) { + that._logger.warn( + 'deprecated', + 'You are using the deprecated ' + deprecated + ' file' + ); + } - if (!assumed) { - that._jsonFile = path.join(that._config.cwd, deprecated ? deprecated : 'bower.json'); - } + if (!assumed) { + that._jsonFile = path.join( + that._config.cwd, + deprecated ? deprecated : 'bower.json' + ); + } - jsonStr = JSON.stringify(json, null, ' ') + '\n'; - that._jsonHash = md5(jsonStr); - return that._json = json; - }); + jsonStr = JSON.stringify(json, null, ' ') + '\n'; + that._jsonHash = md5(jsonStr); + return (that._json = json); + }); }; -Project.prototype._readInstalled = function () { +Project.prototype._readInstalled = function() { var componentsDir; var that = this; @@ -624,22 +750,20 @@ Project.prototype._readInstalled = function () { // Gather all folders that are actual packages by // looking for the package metadata file componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory); - return this._installed = Q.nfcall(glob, '*/.bower.json', { + return (this._installed = Q.nfcall(glob, '*/.bower.json', { cwd: componentsDir, dot: true - }) - .then(function (filenames) { + }).then(function(filenames) { var promises; var decEndpoints = {}; // Foreach bower.json found - promises = filenames.map(function (filename) { + promises = filenames.map(function(filename) { var name = path.dirname(filename); var metaFile = path.join(componentsDir, filename); // Read package metadata - return readJson(metaFile) - .spread(function (pkgMeta) { + return readJson(metaFile).spread(function(pkgMeta) { decEndpoints[name] = { name: name, source: pkgMeta._originalSource || pkgMeta._source, @@ -652,145 +776,176 @@ Project.prototype._readInstalled = function () { // Wait until all files have been read // and resolve with the decomposed endpoints - return Q.all(promises) - .then(function () { - return that._installed = decEndpoints; + return Q.all(promises).then(function() { + return (that._installed = decEndpoints); }); - }); + })); }; -Project.prototype._readLinks = function () { +Project.prototype._readLinks = function() { var componentsDir; var that = this; // Read directory, looking for links componentsDir = relativeToBaseDir(this._config.cwd)(this._config.directory); - return Q.nfcall(fs.readdir, componentsDir) - .then(function (filenames) { - var promises; - var decEndpoints = {}; - - promises = filenames.map(function (filename) { - var dir = path.join(componentsDir, filename); - - // Filter only those that are valid links - return validLink(dir) - .spread(function (valid, err) { - var name; - - if (!valid) { - if (err) { - that._logger.debug('read-link', 'Link ' + dir + ' is invalid', { - filename: dir, - error: err - }); + return Q.nfcall(fs.readdir, componentsDir).then( + function(filenames) { + var promises; + var decEndpoints = {}; + + promises = filenames.map(function(filename) { + var dir = path.join(componentsDir, filename); + + // Filter only those that are valid links + return validLink(dir).spread(function(valid, err) { + var name; + + if (!valid) { + if (err) { + that._logger.debug( + 'read-link', + 'Link ' + dir + ' is invalid', + { + filename: dir, + error: err + } + ); + } + return; } - return; - } - // Skip links to files (see #783) - if (!valid.isDirectory()) { - return; - } - - name = path.basename(dir); - return readJson(dir, { - assume: { name: name } - }) - .spread(function (json, deprecated) { - if (deprecated) { - that._logger.warn('deprecated', 'Package ' + name + ' is using the deprecated ' + deprecated); + // Skip links to files (see #783) + if (!valid.isDirectory()) { + return; } - json._direct = true; // Mark as a direct dep of root - decEndpoints[name] = { - name: name, - source: dir, - target: '*', - canonicalDir: dir, - pkgMeta: json, - linked: true - }; + name = path.basename(dir); + return readJson(dir, { + assume: { name: name } + }).spread(function(json, deprecated) { + if (deprecated) { + that._logger.warn( + 'deprecated', + 'Package ' + + name + + ' is using the deprecated ' + + deprecated + ); + } + + json._direct = true; // Mark as a direct dep of root + decEndpoints[name] = { + name: name, + source: dir, + target: '*', + canonicalDir: dir, + pkgMeta: json, + linked: true + }; + }); }); }); - }); - // Wait until all links have been read - // and resolve with the decomposed endpoints - return Q.all(promises) - .then(function () { - return decEndpoints; - }); - // Ignore if folder does not exist - }, function (err) { - if (err.code !== 'ENOENT') { - throw err; - } + // Wait until all links have been read + // and resolve with the decomposed endpoints + return Q.all(promises).then(function() { + return decEndpoints; + }); + // Ignore if folder does not exist + }, + function(err) { + if (err.code !== 'ENOENT') { + throw err; + } - return {}; - }); + return {}; + } + ); }; -Project.prototype._removePackages = function (packages) { +Project.prototype._removePackages = function(packages) { var that = this; var promises = []; - return scripts.preuninstall(that._config, that._logger, packages, that._installed, that._json) - .then(function () { + return ( + scripts + .preuninstall( + that._config, + that._logger, + packages, + that._installed, + that._json + ) + .then(function() { + mout.object.forOwn(packages, function(dir, name) { + var promise; + + // Delete directory + if (!dir) { + promise = Q.resolve(); + that._logger.warn( + 'not-installed', + "'" + + name + + "'" + + ' cannot be uninstalled as it is not currently installed', + { + name: name + } + ); + } else { + promise = Q.nfcall(rimraf, dir); + that._logger.action('uninstall', name, { + name: name, + dir: dir + }); + } - mout.object.forOwn(packages, function (dir, name) { - var promise; + // Remove from json only if successfully deleted + if ( + (that._options.save || that._config.save) && + that._json.dependencies + ) { + promise = promise.then(function() { + delete that._json.dependencies[name]; + }); + } - // Delete directory - if (!dir) { - promise = Q.resolve(); - that._logger.warn('not-installed', '\'' + name + '\'' + ' cannot be uninstalled as it is not currently installed', { - name: name - }); - } else { - promise = Q.nfcall(rimraf, dir); - that._logger.action('uninstall', name, { - name: name, - dir: dir - }); - } + if (that._options.saveDev && that._json.devDependencies) { + promise = promise.then(function() { + delete that._json.devDependencies[name]; + }); + } - // Remove from json only if successfully deleted - if ((that._options.save || that._config.save) && that._json.dependencies) { - promise = promise - .then(function () { - delete that._json.dependencies[name]; + promises.push(promise); }); - } - if (that._options.saveDev && that._json.devDependencies) { - promise = promise - .then(function () { - delete that._json.devDependencies[name]; + return Q.all(promises); + }) + .then(function() { + return that.saveJson(); + }) + // Run post-uninstall hook before resolving with removed packages. + .then( + scripts.postuninstall.bind( + null, + that._config, + that._logger, + packages, + that._installed, + that._json + ) + ) + // Resolve with removed packages + .then(function() { + return mout.object.filter(packages, function(dir) { + return !!dir; }); - } - - promises.push(promise); - }); - - return Q.all(promises); - - }) - .then(function () { - return that.saveJson(); - }) - // Run post-uninstall hook before resolving with removed packages. - .then(scripts.postuninstall.bind( - null, that._config, that._logger, packages, that._installed, that._json)) - // Resolve with removed packages - .then(function () { - return mout.object.filter(packages, function (dir) { - return !!dir; - }); - }); + }) + ); }; -Project.prototype._restoreNode = function (node, flattened, jsonKey, processed) { +Project.prototype._restoreNode = function(node, flattened, jsonKey, processed) { var deps; // Do not restore if the node is missing @@ -803,67 +958,76 @@ Project.prototype._restoreNode = function (node, flattened, jsonKey, processed) processed = processed || {}; // Only process deps that are not yet processed - deps = mout.object.filter(node.pkgMeta[jsonKey], function (value, key) { + deps = mout.object.filter(node.pkgMeta[jsonKey], function(value, key) { return !processed[node.name + ':' + key]; }); - mout.object.forOwn(deps, function (value, key) { - var local = flattened[key]; - var json = endpointParser.json2decomposed(key, value); - var restored; - var compatible; - var originalSource; - - // Check if the dependency is not installed - if (!local) { - flattened[key] = restored = json; - restored.missing = true; - // Even if it is installed, check if it's compatible - // Note that linked packages are interpreted as compatible - // This might change in the future: #673 - } else { - compatible = local.linked || (!local.missing && json.target === local.pkgMeta._target); - - if (!compatible) { - restored = json; - - if (!local.missing) { - restored.pkgMeta = local.pkgMeta; - restored.canonicalDir = local.canonicalDir; - restored.incompatible = true; + mout.object.forOwn( + deps, + function(value, key) { + var local = flattened[key]; + var json = endpointParser.json2decomposed(key, value); + var restored; + var compatible; + var originalSource; + + // Check if the dependency is not installed + if (!local) { + flattened[key] = restored = json; + restored.missing = true; + // Even if it is installed, check if it's compatible + // Note that linked packages are interpreted as compatible + // This might change in the future: #673 + } else { + compatible = + local.linked || + (!local.missing && json.target === local.pkgMeta._target); + + if (!compatible) { + restored = json; + + if (!local.missing) { + restored.pkgMeta = local.pkgMeta; + restored.canonicalDir = local.canonicalDir; + restored.incompatible = true; + } else { + restored.missing = true; + } } else { - restored.missing = true; + restored = local; + mout.object.mixIn(local, json); } - } else { - restored = local; - mout.object.mixIn(local, json); - } - // Check if source changed, marking as different if it did - // We only do this for direct root dependencies that are compatible - if (node.root && compatible) { - originalSource = mout.object.get(local, 'pkgMeta._originalSource'); - if (originalSource && originalSource !== json.source) { - restored.different = true; + // Check if source changed, marking as different if it did + // We only do this for direct root dependencies that are compatible + if (node.root && compatible) { + originalSource = mout.object.get( + local, + 'pkgMeta._originalSource' + ); + if (originalSource && originalSource !== json.source) { + restored.different = true; + } } } - } - // Cross reference - node.dependencies[key] = restored; - processed[node.name + ':' + key] = true; + // Cross reference + node.dependencies[key] = restored; + processed[node.name + ':' + key] = true; - restored.dependants = restored.dependants || {}; - restored.dependants[node.name] = mout.object.mixIn({}, node); // We need to clone due to shared objects in the manager! + restored.dependants = restored.dependants || {}; + restored.dependants[node.name] = mout.object.mixIn({}, node); // We need to clone due to shared objects in the manager! - // Call restore for this dependency - this._restoreNode(restored, flattened, 'dependencies', processed); + // Call restore for this dependency + this._restoreNode(restored, flattened, 'dependencies', processed); - // Do the same for the incompatible local package - if (local && restored !== local) { - this._restoreNode(local, flattened, 'dependencies', processed); - } - }, this); + // Do the same for the incompatible local package + if (local && restored !== local) { + this._restoreNode(local, flattened, 'dependencies', processed); + } + }, + this + ); }; module.exports = Project; diff --git a/lib/core/ResolveCache.js b/lib/core/ResolveCache.js index d1242d7c9..2784dc3d1 100644 --- a/lib/core/ResolveCache.js +++ b/lib/core/ResolveCache.js @@ -29,7 +29,7 @@ function ResolveCache(config) { if (!this._cache) { this._cache = new LRU({ max: 100, - maxAge: 60 * 5 * 1000 // 5 minutes + maxAge: 60 * 5 * 1000 // 5 minutes }); this.constructor._cache.set(this._dir, this._cache); } @@ -40,7 +40,7 @@ function ResolveCache(config) { // ----------------- -ResolveCache.prototype.retrieve = function (source, target) { +ResolveCache.prototype.retrieve = function(source, target) { var sourceId = md5(source); var dir = path.join(this._dir, sourceId); var that = this; @@ -48,56 +48,57 @@ ResolveCache.prototype.retrieve = function (source, target) { target = target || '*'; return this._getVersions(sourceId) - .spread(function (versions) { - var suitable; + .spread(function(versions) { + var suitable; - // If target is a semver, find a suitable version - if (semver.validRange(target)) { - suitable = semver.maxSatisfying(versions, target, true); + // If target is a semver, find a suitable version + if (semver.validRange(target)) { + suitable = semver.maxSatisfying(versions, target, true); - if (suitable) { - return suitable; + if (suitable) { + return suitable; + } } - } - // If target is '*' check if there's a cached '_wildcard' - if (target === '*') { - return mout.array.find(versions, function (version) { - return version === '_wildcard'; - }); - } + // If target is '*' check if there's a cached '_wildcard' + if (target === '*') { + return mout.array.find(versions, function(version) { + return version === '_wildcard'; + }); + } - // Otherwise check if there's an exact match - return mout.array.find(versions, function (version) { - return version === target; - }); - }) - .then(function (version) { - var canonicalDir; + // Otherwise check if there's an exact match + return mout.array.find(versions, function(version) { + return version === target; + }); + }) + .then(function(version) { + var canonicalDir; - if (!version) { - return []; - } + if (!version) { + return []; + } - // Resolve with canonical dir and package meta - canonicalDir = path.join(dir, encodeURIComponent(version)); - return that._readPkgMeta(canonicalDir) - .then(function (pkgMeta) { - return [canonicalDir, pkgMeta]; - }, function () { - // If there was an error, invalidate the in-memory cache, - // delete the cached package and try again - that._cache.del(sourceId); + // Resolve with canonical dir and package meta + canonicalDir = path.join(dir, encodeURIComponent(version)); + return that._readPkgMeta(canonicalDir).then( + function(pkgMeta) { + return [canonicalDir, pkgMeta]; + }, + function() { + // If there was an error, invalidate the in-memory cache, + // delete the cached package and try again + that._cache.del(sourceId); - return Q.nfcall(rimraf, canonicalDir) - .then(function () { - return that.retrieve(source, target); - }); + return Q.nfcall(rimraf, canonicalDir).then(function() { + return that.retrieve(source, target); + }); + } + ); }); - }); }; -ResolveCache.prototype.store = function (canonicalDir, pkgMeta) { +ResolveCache.prototype.store = function(canonicalDir, pkgMeta) { var sourceId; var release; var dir; @@ -108,70 +109,82 @@ ResolveCache.prototype.store = function (canonicalDir, pkgMeta) { promise = pkgMeta ? Q.resolve(pkgMeta) : this._readPkgMeta(canonicalDir); return promise - .then(function (pkgMeta) { - sourceId = md5(pkgMeta._source); - release = that._getPkgRelease(pkgMeta); - dir = path.join(that._dir, sourceId, release); - pkgLock = path.join(that._lockDir, sourceId + '-' + release + '.lock'); - - // Check if destination directory exists to prevent issuing lock at all times - return Q.nfcall(fs.stat, dir) - .fail(function (err) { - var lockParams = { wait: 250, retries: 25, stale: 60000 }; - return Q.nfcall(lockFile.lock, pkgLock, lockParams).then(function () { - // Ensure other process didn't start copying files before lock was created - return Q.nfcall(fs.stat, dir) - .fail(function (err) { - // If stat fails, it is expected to return ENOENT - if (err.code !== 'ENOENT') { - throw err; - } - - // Create missing directory and copy files there - return Q.nfcall(mkdirp, path.dirname(dir)).then(function () { - return Q.nfcall(fs.rename, canonicalDir, dir) - .fail(function (err) { - // If error is EXDEV it means that we are trying to rename - // across different drives, so we copy and remove it instead - if (err.code !== 'EXDEV') { - throw err; - } - - return copy.copyDir(canonicalDir, dir); + .then(function(pkgMeta) { + sourceId = md5(pkgMeta._source); + release = that._getPkgRelease(pkgMeta); + dir = path.join(that._dir, sourceId, release); + pkgLock = path.join( + that._lockDir, + sourceId + '-' + release + '.lock' + ); + + // Check if destination directory exists to prevent issuing lock at all times + return Q.nfcall(fs.stat, dir) + .fail(function(err) { + var lockParams = { wait: 250, retries: 25, stale: 60000 }; + return Q.nfcall(lockFile.lock, pkgLock, lockParams) + .then(function() { + // Ensure other process didn't start copying files before lock was created + return Q.nfcall(fs.stat, dir).fail(function(err) { + // If stat fails, it is expected to return ENOENT + if (err.code !== 'ENOENT') { + throw err; + } + + // Create missing directory and copy files there + return Q.nfcall(mkdirp, path.dirname(dir)).then( + function() { + return Q.nfcall( + fs.rename, + canonicalDir, + dir + ).fail(function(err) { + // If error is EXDEV it means that we are trying to rename + // across different drives, so we copy and remove it instead + if (err.code !== 'EXDEV') { + throw err; + } + + return copy.copyDir( + canonicalDir, + dir + ); + }); + } + ); + }); + }) + .finally(function() { + lockFile.unlockSync(pkgLock); }); - }); + }) + .finally(function() { + // Ensure no tmp dir is left on disk. + return Q.nfcall(rimraf, canonicalDir); }); - }).finally(function () { - lockFile.unlockSync(pkgLock); - }); - }).finally(function () { - // Ensure no tmp dir is left on disk. - return Q.nfcall(rimraf, canonicalDir); - }); - }) - .then(function () { - var versions = that._cache.get(sourceId); - - // Add it to the in memory cache - // and sort the versions afterwards - if (versions && versions.indexOf(release) === -1) { - versions.push(release); - that._sortVersions(versions); - } + }) + .then(function() { + var versions = that._cache.get(sourceId); + + // Add it to the in memory cache + // and sort the versions afterwards + if (versions && versions.indexOf(release) === -1) { + versions.push(release); + that._sortVersions(versions); + } - // Resolve with the final location - return dir; - }); + // Resolve with the final location + return dir; + }); }; -ResolveCache.prototype.eliminate = function (pkgMeta) { +ResolveCache.prototype.eliminate = function(pkgMeta) { var sourceId = md5(pkgMeta._source); var release = this._getPkgRelease(pkgMeta); var dir = path.join(this._dir, sourceId, release); var that = this; - return Q.nfcall(rimraf, dir) - .then(function () { + return Q.nfcall(rimraf, dir).then(function() { var versions = that._cache.get(sourceId) || []; mout.array.remove(versions, release); @@ -182,8 +195,7 @@ ResolveCache.prototype.eliminate = function (pkgMeta) { if (!versions.length) { that._cache.del(sourceId); - return that._getVersions(sourceId) - .spread(function (versions) { + return that._getVersions(sourceId).spread(function(versions) { if (!versions.length) { // Do not keep in-memory cache if it's completely // empty @@ -196,125 +208,144 @@ ResolveCache.prototype.eliminate = function (pkgMeta) { }); }; -ResolveCache.prototype.clear = function () { +ResolveCache.prototype.clear = function() { return Q.nfcall(rimraf, this._dir) - .then(function () { - return Q.nfcall(fs.mkdir, this._dir); - }.bind(this)) - .then(function () { - this._cache.reset(); - }.bind(this)); + .then( + function() { + return Q.nfcall(fs.mkdir, this._dir); + }.bind(this) + ) + .then( + function() { + this._cache.reset(); + }.bind(this) + ); }; -ResolveCache.prototype.reset = function () { +ResolveCache.prototype.reset = function() { this._cache.reset(); return this; }; -ResolveCache.prototype.versions = function (source) { +ResolveCache.prototype.versions = function(source) { var sourceId = md5(source); - return this._getVersions(sourceId) - .spread(function (versions) { - return versions.filter(function (version) { + return this._getVersions(sourceId).spread(function(versions) { + return versions.filter(function(version) { return semver.valid(version); }); }); }; -ResolveCache.prototype.list = function () { +ResolveCache.prototype.list = function() { var promises; var dirs = []; var that = this; // Get the list of directories - return Q.nfcall(fs.readdir, this._dir) - .then(function (sourceIds) { - promises = sourceIds.map(function (sourceId) { - return Q.nfcall(fs.readdir, path.join(that._dir, sourceId)) - .then(function (versions) { - versions.forEach(function (version) { - var dir = path.join(that._dir, sourceId, version); - dirs.push(dir); - }); - }, function (err) { - // Ignore lurking files, e.g.: .DS_Store if the user - // has navigated throughout the cache - if (err.code === 'ENOTDIR' && err.path) { - return Q.nfcall(rimraf, err.path); - } + return ( + Q.nfcall(fs.readdir, this._dir) + .then(function(sourceIds) { + promises = sourceIds.map(function(sourceId) { + return Q.nfcall( + fs.readdir, + path.join(that._dir, sourceId) + ).then( + function(versions) { + versions.forEach(function(version) { + var dir = path.join( + that._dir, + sourceId, + version + ); + dirs.push(dir); + }); + }, + function(err) { + // Ignore lurking files, e.g.: .DS_Store if the user + // has navigated throughout the cache + if (err.code === 'ENOTDIR' && err.path) { + return Q.nfcall(rimraf, err.path); + } - throw err; - }); - }); + throw err; + } + ); + }); - return Q.all(promises); - }) - // Read every package meta - .then(function () { - promises = dirs.map(function (dir) { - return that._readPkgMeta(dir) - .then(function (pkgMeta) { - return { - canonicalDir: dir, - pkgMeta: pkgMeta - }; - }, function () { - // If it fails to read, invalidate the in memory - // cache for the source and delete the entry directory - var sourceId = path.basename(path.dirname(dir)); - that._cache.del(sourceId); - - return Q.nfcall(rimraf, dir); - }); - }); + return Q.all(promises); + }) + // Read every package meta + .then(function() { + promises = dirs.map(function(dir) { + return that._readPkgMeta(dir).then( + function(pkgMeta) { + return { + canonicalDir: dir, + pkgMeta: pkgMeta + }; + }, + function() { + // If it fails to read, invalidate the in memory + // cache for the source and delete the entry directory + var sourceId = path.basename(path.dirname(dir)); + that._cache.del(sourceId); + + return Q.nfcall(rimraf, dir); + } + ); + }); - return Q.all(promises); - }) - // Sort by name ASC & release ASC - .then(function (entries) { - // Ignore falsy entries due to errors reading - // package metas - entries = entries.filter(function (entry) { - return !!entry; - }); + return Q.all(promises); + }) + // Sort by name ASC & release ASC + .then(function(entries) { + // Ignore falsy entries due to errors reading + // package metas + entries = entries.filter(function(entry) { + return !!entry; + }); - return entries.sort(function (entry1, entry2) { - var pkgMeta1 = entry1.pkgMeta; - var pkgMeta2 = entry2.pkgMeta; - var comp = pkgMeta1.name.localeCompare(pkgMeta2.name); + return entries.sort(function(entry1, entry2) { + var pkgMeta1 = entry1.pkgMeta; + var pkgMeta2 = entry2.pkgMeta; + var comp = pkgMeta1.name.localeCompare(pkgMeta2.name); - // Sort by name - if (comp) { - return comp; - } + // Sort by name + if (comp) { + return comp; + } - // Sort by version - if (pkgMeta1.version && pkgMeta2.version) { - return semver.compare(pkgMeta1.version, pkgMeta2.version); - } - if (pkgMeta1.version) { - return -1; - } - if (pkgMeta2.version) { - return 1; - } + // Sort by version + if (pkgMeta1.version && pkgMeta2.version) { + return semver.compare( + pkgMeta1.version, + pkgMeta2.version + ); + } + if (pkgMeta1.version) { + return -1; + } + if (pkgMeta2.version) { + return 1; + } - // Sort by target - return pkgMeta1._target.localeCompare(pkgMeta2._target); - }); - }); + // Sort by target + return pkgMeta1._target.localeCompare(pkgMeta2._target); + }); + }) + ); }; // ------------------------ -ResolveCache.clearRuntimeCache = function () { +ResolveCache.clearRuntimeCache = function() { // Note that _cache refers to the static _cache variable // that holds other caches per dir! // Do not confuse it with the instance cache // Clear cache of each directory - this._cache.forEach(function (cache) { + this._cache.forEach(function(cache) { cache.reset(); }); @@ -324,8 +355,10 @@ ResolveCache.clearRuntimeCache = function () { // ------------------------ -ResolveCache.prototype._getPkgRelease = function (pkgMeta) { - var release = pkgMeta.version || (pkgMeta._target === '*' ? '_wildcard' : pkgMeta._target); +ResolveCache.prototype._getPkgRelease = function(pkgMeta) { + var release = + pkgMeta.version || + (pkgMeta._target === '*' ? '_wildcard' : pkgMeta._target); // Encode some dangerous chars such as / and \ release = encodeURIComponent(release); @@ -333,16 +366,15 @@ ResolveCache.prototype._getPkgRelease = function (pkgMeta) { return release; }; -ResolveCache.prototype._readPkgMeta = function (dir) { +ResolveCache.prototype._readPkgMeta = function(dir) { var filename = path.join(dir, '.bower.json'); - return readJson(filename) - .spread(function (json) { + return readJson(filename).spread(function(json) { return json; }); }; -ResolveCache.prototype._getVersions = function (sourceId) { +ResolveCache.prototype._getVersions = function(sourceId) { var dir; var versions = this._cache.get(sourceId); var that = this; @@ -352,29 +384,31 @@ ResolveCache.prototype._getVersions = function (sourceId) { } dir = path.join(this._dir, sourceId); - return Q.nfcall(fs.readdir, dir) - .then(function (versions) { - // Sort and cache in memory - that._sortVersions(versions); - versions = versions.map(decodeURIComponent); - that._cache.set(sourceId, versions); - return [versions, false]; - }, function (err) { - // If the directory does not exists, resolve - // as an empty array - if (err.code === 'ENOENT') { - versions = []; + return Q.nfcall(fs.readdir, dir).then( + function(versions) { + // Sort and cache in memory + that._sortVersions(versions); + versions = versions.map(decodeURIComponent); that._cache.set(sourceId, versions); return [versions, false]; - } + }, + function(err) { + // If the directory does not exists, resolve + // as an empty array + if (err.code === 'ENOENT') { + versions = []; + that._cache.set(sourceId, versions); + return [versions, false]; + } - throw err; - }); + throw err; + } + ); }; -ResolveCache.prototype._sortVersions = function (versions) { +ResolveCache.prototype._sortVersions = function(versions) { // Sort DESC - versions.sort(function (version1, version2) { + versions.sort(function(version1, version2) { var validSemver1 = semver.valid(version1); var validSemver2 = semver.valid(version2); @@ -400,7 +434,7 @@ ResolveCache.prototype._sortVersions = function (versions) { ResolveCache._cache = new LRU({ max: 5, - maxAge: 60 * 30 * 1000 // 30 minutes + maxAge: 60 * 30 * 1000 // 30 minutes }); module.exports = ResolveCache; diff --git a/lib/core/resolverFactory.js b/lib/core/resolverFactory.js index f015fb485..8ca7507d2 100644 --- a/lib/core/resolverFactory.js +++ b/lib/core/resolverFactory.js @@ -13,9 +13,15 @@ function createInstance(decEndpoint, options, registryClient) { options.version = require('../version'); - return getConstructor(decEndpoint, options, registryClient) - .spread(function (ConcreteResolver, decEndpoint) { - return new ConcreteResolver(decEndpoint, options.config, options.logger); + return getConstructor(decEndpoint, options, registryClient).spread(function( + ConcreteResolver, + decEndpoint + ) { + return new ConcreteResolver( + decEndpoint, + options.config, + options.logger + ); }); } @@ -29,8 +35,8 @@ function getConstructor(decEndpoint, options, registryClient) { var promise = Q.resolve(); - var addResolver = function (resolverFactory) { - promise = promise.then(function (result) { + var addResolver = function(resolverFactory) { + promise = promise.then(function(result) { if (result === undefined) { return resolverFactory(decEndpoint, options); } else { @@ -43,7 +49,7 @@ function getConstructor(decEndpoint, options, registryClient) { // // It requires each resolver defined in config.resolvers and calls // its "match" to check if given resolves supports given decEndpoint - addResolver(function () { + addResolver(function() { var selectedResolver; var resolverNames; @@ -55,28 +61,32 @@ function getConstructor(decEndpoint, options, registryClient) { resolverNames = []; } - var resolverPromises = resolverNames.map(function (resolverName) { - - + var resolverPromises = resolverNames.map(function(resolverName) { var resolver = resolvers[resolverName]; if (resolver === undefined) { var resolverPath = resolve(resolverName, { cwd: config.cwd }); if (resolverPath === undefined) { - throw createError('Bower resolver not found: ' + resolverName, 'ENORESOLVER') + throw createError( + 'Bower resolver not found: ' + resolverName, + 'ENORESOLVER' + ); } - resolver = pluginResolverFactory(require(resolverPath), options); + resolver = pluginResolverFactory( + require(resolverPath), + options + ); } - return function () { + return function() { if (selectedResolver === undefined) { var match = resolver.match.bind(resolver); - return Q.fcall(match, source).then(function (result) { + return Q.fcall(match, source).then(function(result) { if (result) { - return selectedResolver = resolver; + return (selectedResolver = resolver); } }); } else { @@ -85,26 +95,39 @@ function getConstructor(decEndpoint, options, registryClient) { }; }); - return resolverPromises.reduce(Q.when, new Q(undefined)).then(function (resolver) { - if (resolver) { - return Q.fcall(resolver.locate.bind(resolver), decEndpoint.source).then(function (result) { - if (result && result !== decEndpoint.source) { - decEndpoint.source = result; - decEndpoint.registry = true; - return getConstructor(decEndpoint, options, registryClient); - } else { - return [resolver, decEndpoint]; - } - }); - } - }); + return resolverPromises + .reduce(Q.when, new Q(undefined)) + .then(function(resolver) { + if (resolver) { + return Q.fcall( + resolver.locate.bind(resolver), + decEndpoint.source + ).then(function(result) { + if (result && result !== decEndpoint.source) { + decEndpoint.source = result; + decEndpoint.registry = true; + return getConstructor( + decEndpoint, + options, + registryClient + ); + } else { + return [resolver, decEndpoint]; + } + }); + } + }); }); // Git case: git git+ssh, git+http, git+https // .git at the end (probably ssh shorthand) // git@ at the start - addResolver(function () { - if (/^git(\+(ssh|https?))?:\/\//i.test(source) || /\.git\/?$/i.test(source) || /^git@/i.test(source)) { + addResolver(function() { + if ( + /^git(\+(ssh|https?))?:\/\//i.test(source) || + /\.git\/?$/i.test(source) || + /^git@/i.test(source) + ) { decEndpoint.source = source.replace(/^git\+/, ''); // If it's a GitHub repository, return the specialized resolver @@ -117,66 +140,69 @@ function getConstructor(decEndpoint, options, registryClient) { }); // SVN case: svn, svn+ssh, svn+http, svn+https, svn+file - addResolver(function () { + addResolver(function() { if (/^svn(\+(ssh|https?|file))?:\/\//i.test(source)) { return [resolvers.Svn, decEndpoint]; } }); // URL case - addResolver(function () { + addResolver(function() { if (/^https?:\/\//i.exec(source)) { return [resolvers.Url, decEndpoint]; } }); - // If source is ./ or ../ or an absolute path - addResolver(function () { + addResolver(function() { var absolutePath = path.resolve(config.cwd, source); - if (/^\.\.?[\/\\]/.test(source) || /^~\//.test(source) || + if ( + /^\.\.?[\/\\]/.test(source) || + /^~\//.test(source) || path.normalize(source).replace(/[\/\\]+$/, '') === absolutePath ) { - return Q.nfcall(fs.stat, path.join(absolutePath, '.git')) - .then(function (stats) { - decEndpoint.source = absolutePath; + return ( + Q.nfcall(fs.stat, path.join(absolutePath, '.git')) + .then(function(stats) { + decEndpoint.source = absolutePath; - if (stats.isDirectory()) { - return Q.resolve([resolvers.GitFs, decEndpoint]); - } + if (stats.isDirectory()) { + return Q.resolve([resolvers.GitFs, decEndpoint]); + } - throw new Error('Not a Git repository'); - }) - // If not, check if source is a valid Subversion repository - .fail(function () { - return Q.nfcall(fs.stat, path.join(absolutePath, '.svn')) - .then(function (stats) { - decEndpoint.source = absolutePath; - - if (stats.isDirectory()) { - return Q.resolve([resolvers.Svn, decEndpoint]); - } - - throw new Error('Not a Subversion repository'); - }); - }) - // If not, check if source is a valid file/folder - .fail(function () { - return Q.nfcall(fs.stat, absolutePath) - .then(function () { - decEndpoint.source = absolutePath; - - return Q.resolve([resolvers.Fs, decEndpoint]); - }); - }); + throw new Error('Not a Git repository'); + }) + // If not, check if source is a valid Subversion repository + .fail(function() { + return Q.nfcall( + fs.stat, + path.join(absolutePath, '.svn') + ).then(function(stats) { + decEndpoint.source = absolutePath; + + if (stats.isDirectory()) { + return Q.resolve([resolvers.Svn, decEndpoint]); + } + + throw new Error('Not a Subversion repository'); + }); + }) + // If not, check if source is a valid file/folder + .fail(function() { + return Q.nfcall(fs.stat, absolutePath).then(function() { + decEndpoint.source = absolutePath; + + return Q.resolve([resolvers.Fs, decEndpoint]); + }); + }) + ); } }); // Check if is a shorthand and expand it - addResolver(function () { - + addResolver(function() { // Check if the shorthandResolver is falsy if (!config.shorthandResolver) { return; @@ -190,26 +216,34 @@ function getConstructor(decEndpoint, options, registryClient) { // Ensure exactly only one "/" var parts = source.split('/'); if (parts.length === 2) { - decEndpoint.source = mout.string.interpolate(config.shorthandResolver, { - shorthand: source, - owner: parts[0], - package: parts[1] - }); + decEndpoint.source = mout.string.interpolate( + config.shorthandResolver, + { + shorthand: source, + owner: parts[0], + package: parts[1] + } + ); return getConstructor(decEndpoint, options, registryClient); } }); // As last resort, we try the registry - addResolver(function () { + addResolver(function() { if (!registryClient) { return; } - return Q.nfcall(registryClient.lookup.bind(registryClient), source) - .then(function (entry) { + return Q.nfcall( + registryClient.lookup.bind(registryClient), + source + ).then(function(entry) { if (!entry) { - throw createError('Package ' + source + ' not found', 'ENOTFOUND'); + throw createError( + 'Package ' + source + ' not found', + 'ENOTFOUND' + ); } decEndpoint.registry = true; @@ -224,15 +258,18 @@ function getConstructor(decEndpoint, options, registryClient) { }); }); - addResolver(function () { - throw createError('Could not find appropriate resolver for ' + source, 'ENORESOLVER'); + addResolver(function() { + throw createError( + 'Could not find appropriate resolver for ' + source, + 'ENORESOLVER' + ); }); return promise; } function clearRuntimeCache() { - mout.object.values(resolvers).forEach(function (ConcreteResolver) { + mout.object.values(resolvers).forEach(function(ConcreteResolver) { ConcreteResolver.clearRuntimeCache(); }); } diff --git a/lib/core/resolvers/FsResolver.js b/lib/core/resolvers/FsResolver.js index e133a4428..be8cfb668 100644 --- a/lib/core/resolvers/FsResolver.js +++ b/lib/core/resolvers/FsResolver.js @@ -17,13 +17,19 @@ function FsResolver(decEndpoint, config, logger) { // If target was specified, simply reject the promise if (this._target !== '*') { - throw createError('File system sources can\'t resolve targets', 'ENORESTARGET'); + throw createError( + "File system sources can't resolve targets", + 'ENORESTARGET' + ); } // If the name was guessed if (this._guessedName) { // Remove extension - this._name = this._name.substr(0, this._name.length - path.extname(this._name).length); + this._name = this._name.substr( + 0, + this._name.length - path.extname(this._name).length + ); } } @@ -32,7 +38,7 @@ mout.object.mixIn(FsResolver, Resolver); // ----------------- -FsResolver.isTargetable = function () { +FsResolver.isTargetable = function() { return false; }; @@ -42,19 +48,18 @@ FsResolver.isTargetable = function () { // TODO: There's room for improvement by using streams if the source // is an archive file, by piping read stream to the zip extractor // This will likely increase the complexity of code but might worth it -FsResolver.prototype._resolve = function () { +FsResolver.prototype._resolve = function() { return this._copy() - .then(this._extract.bind(this)) - .then(this._rename.bind(this)); + .then(this._extract.bind(this)) + .then(this._rename.bind(this)); }; // ----------------- -FsResolver.prototype._copy = function () { +FsResolver.prototype._copy = function() { var that = this; - return Q.nfcall(fs.stat, this._source) - .then(function (stat) { + return Q.nfcall(fs.stat, this._source).then(function(stat) { var dst; var copyOpts; var promise; @@ -68,22 +73,24 @@ FsResolver.prototype._copy = function () { // Read the bower.json inside the folder, so that we // copy only the necessary files if it has ignore specified - promise = that._readJson(that._source) - .then(function (json) { - copyOpts.ignore = json.ignore; - return copy.copyDir(that._source, dst, copyOpts); - }) - .then(function () { - // Resolve to null because it's a dir - return; - }); - // Else it's a file + promise = that + ._readJson(that._source) + .then(function(json) { + copyOpts.ignore = json.ignore; + return copy.copyDir(that._source, dst, copyOpts); + }) + .then(function() { + // Resolve to null because it's a dir + return; + }); + // Else it's a file } else { dst = path.join(that._tempDir, path.basename(that._source)); - promise = copy.copyFile(that._source, dst, copyOpts) - .then(function () { - return dst; - }); + promise = copy + .copyFile(that._source, dst, copyOpts) + .then(function() { + return dst; + }); } that._logger.action('copy', that._source, { @@ -95,7 +102,7 @@ FsResolver.prototype._copy = function () { }); }; -FsResolver.prototype._extract = function (file) { +FsResolver.prototype._extract = function(file) { if (!file || !extract.canExtract(file)) { return Q.resolve(); } @@ -108,30 +115,34 @@ FsResolver.prototype._extract = function (file) { return extract(file, this._tempDir); }; -FsResolver.prototype._rename = function () { - return Q.nfcall(fs.readdir, this._tempDir) - .then(function (files) { - var file; - var oldPath; - var newPath; - - // Remove any OS specific files from the files array - // before checking its length - files = files.filter(junk.isnt); - - // Only rename if there's only one file and it's not the json - if (files.length === 1 && !/^(bower|component)\.json$/.test(files[0])) { - file = files[0]; - this._singleFile = 'index' + path.extname(file); - oldPath = path.join(this._tempDir, file); - newPath = path.join(this._tempDir, this._singleFile); - - return Q.nfcall(fs.rename, oldPath, newPath); - } - }.bind(this)); +FsResolver.prototype._rename = function() { + return Q.nfcall(fs.readdir, this._tempDir).then( + function(files) { + var file; + var oldPath; + var newPath; + + // Remove any OS specific files from the files array + // before checking its length + files = files.filter(junk.isnt); + + // Only rename if there's only one file and it's not the json + if ( + files.length === 1 && + !/^(bower|component)\.json$/.test(files[0]) + ) { + file = files[0]; + this._singleFile = 'index' + path.extname(file); + oldPath = path.join(this._tempDir, file); + newPath = path.join(this._tempDir, this._singleFile); + + return Q.nfcall(fs.rename, oldPath, newPath); + } + }.bind(this) + ); }; -FsResolver.prototype._savePkgMeta = function (meta) { +FsResolver.prototype._savePkgMeta = function(meta) { // Store main if is a single file if (this._singleFile) { meta.main = this._singleFile; diff --git a/lib/core/resolvers/GitFsResolver.js b/lib/core/resolvers/GitFsResolver.js index 3f3e9438d..91227c478 100644 --- a/lib/core/resolvers/GitFsResolver.js +++ b/lib/core/resolvers/GitFsResolver.js @@ -19,31 +19,52 @@ mout.object.mixIn(GitFsResolver, GitResolver); // ----------------- // Override the checkout function to work with the local copy -GitFsResolver.prototype._checkout = function () { +GitFsResolver.prototype._checkout = function() { var resolution = this._resolution; // The checkout process could be similar to the GitRemoteResolver by prepending file:// to the source // But from my performance measures, it's faster to copy the folder and just checkout in there - this._logger.action('checkout', resolution.tag || resolution.branch || resolution.commit, { - resolution: resolution, - to: this._tempDir - }); + this._logger.action( + 'checkout', + resolution.tag || resolution.branch || resolution.commit, + { + resolution: resolution, + to: this._tempDir + } + ); // Copy files to the temporary directory first - return this._copy() - .then(cmd.bind(cmd, 'git', ['checkout', '-f', resolution.tag || resolution.branch || resolution.commit], { cwd: this._tempDir })) - // Cleanup unstaged files - .then(cmd.bind(cmd, 'git', ['clean', '-f', '-d'], { cwd: this._tempDir })); + return ( + this._copy() + .then( + cmd.bind( + cmd, + 'git', + [ + 'checkout', + '-f', + resolution.tag || resolution.branch || resolution.commit + ], + { cwd: this._tempDir } + ) + ) + // Cleanup unstaged files + .then( + cmd.bind(cmd, 'git', ['clean', '-f', '-d'], { + cwd: this._tempDir + }) + ) + ); }; -GitFsResolver.prototype._copy = function () { +GitFsResolver.prototype._copy = function() { return copy.copyDir(this._source, this._tempDir); }; // ----------------- // Grab refs locally -GitFsResolver.refs = function (source) { +GitFsResolver.refs = function(source) { var value; // TODO: Normalize source because of the various available protocols? @@ -52,20 +73,24 @@ GitFsResolver.refs = function (source) { return Q.resolve(value); } - value = cmd('git', ['show-ref', '--tags', '--heads'], { cwd : source }) - .spread(function (stdout) { - var refs; + value = cmd('git', ['show-ref', '--tags', '--heads'], { + cwd: source + }).spread( + function(stdout) { + var refs; - refs = stdout.toString() - .trim() // Trim trailing and leading spaces - .replace(/[\t ]+/g, ' ') // Standardize spaces (some git versions make tabs, other spaces) - .split(/[\r\n]+/); // Split lines into an array + refs = stdout + .toString() + .trim() // Trim trailing and leading spaces + .replace(/[\t ]+/g, ' ') // Standardize spaces (some git versions make tabs, other spaces) + .split(/[\r\n]+/); // Split lines into an array - // Update the refs with the actual refs - this._cache.refs.set(source, refs); + // Update the refs with the actual refs + this._cache.refs.set(source, refs); - return refs; - }.bind(this)); + return refs; + }.bind(this) + ); // Store the promise to be reused until it resolves // to a specific value diff --git a/lib/core/resolvers/GitHubResolver.js b/lib/core/resolvers/GitHubResolver.js index b9bb61ebd..7b4507e11 100644 --- a/lib/core/resolvers/GitHubResolver.js +++ b/lib/core/resolvers/GitHubResolver.js @@ -35,7 +35,7 @@ function GitHubResolver(decEndpoint, config, logger) { } // Enable shallow clones for GitHub repos - this._shallowClone = function () { + this._shallowClone = function() { return Q.resolve(true); }; } @@ -45,10 +45,20 @@ mout.object.mixIn(GitHubResolver, GitRemoteResolver); // ----------------- -GitHubResolver.prototype._checkout = function () { +GitHubResolver.prototype._checkout = function() { var msg; - var name = this._resolution.tag || this._resolution.branch || this._resolution.commit; - var tarballUrl = 'https://github.com/' + this._org + '/' + this._repo + '/archive/' + name + '.tar.gz'; + var name = + this._resolution.tag || + this._resolution.branch || + this._resolution.commit; + var tarballUrl = + 'https://github.com/' + + this._org + + '/' + + this._repo + + '/archive/' + + name + + '.tar.gz'; var file = path.join(this._tempDir, 'archive.tar.gz'); var reqHeaders = {}; @@ -70,54 +80,88 @@ GitHubResolver.prototype._checkout = function () { timeout: this._config.timeout, headers: reqHeaders }) - .progress(function (state) { - // Retry? - if (state.retry) { - msg = 'Download of ' + tarballUrl + ' failed with ' + state.error.code + ', '; - msg += 'retrying in ' + (state.delay / 1000).toFixed(1) + 's'; - that._logger.debug('error', state.error.message, { error: state.error }); - return that._logger.warn('retry', msg); - } - - // Progress - msg = 'received ' + (state.received / 1024 / 1024).toFixed(1) + 'MB'; - if (state.total) { - msg += ' of ' + (state.total / 1024 / 1024).toFixed(1) + 'MB downloaded, '; - msg += state.percent + '%'; - } - that._logger.info('progress', msg); - }) - .then(function () { - // Extract archive - that._logger.action('extract', path.basename(file), { - archive: file, - to: that._tempDir - }); - - return extract(file, that._tempDir) - // Fallback to standard git clone if extraction failed - .fail(function (err) { - msg = 'Decompression of ' + path.basename(file) + ' failed' + (err.code ? ' with ' + err.code : '') + ', '; - msg += 'trying with git..'; - that._logger.debug('error', err.message, { error: err }); - that._logger.warn('retry', msg); - - return that._cleanTempDir() - .then(GitRemoteResolver.prototype._checkout.bind(that)); - }); - // Fallback to standard git clone if download failed - }, function (err) { - msg = 'Download of ' + tarballUrl + ' failed' + (err.code ? ' with ' + err.code : '') + ', '; - msg += 'trying with git..'; - that._logger.debug('error', err.message, { error: err }); - that._logger.warn('retry', msg); - - return that._cleanTempDir() - .then(GitRemoteResolver.prototype._checkout.bind(that)); - }); + .progress(function(state) { + // Retry? + if (state.retry) { + msg = + 'Download of ' + + tarballUrl + + ' failed with ' + + state.error.code + + ', '; + msg += 'retrying in ' + (state.delay / 1000).toFixed(1) + 's'; + that._logger.debug('error', state.error.message, { + error: state.error + }); + return that._logger.warn('retry', msg); + } + + // Progress + msg = + 'received ' + (state.received / 1024 / 1024).toFixed(1) + 'MB'; + if (state.total) { + msg += + ' of ' + + (state.total / 1024 / 1024).toFixed(1) + + 'MB downloaded, '; + msg += state.percent + '%'; + } + that._logger.info('progress', msg); + }) + .then( + function() { + // Extract archive + that._logger.action('extract', path.basename(file), { + archive: file, + to: that._tempDir + }); + + return ( + extract(file, that._tempDir) + // Fallback to standard git clone if extraction failed + .fail(function(err) { + msg = + 'Decompression of ' + + path.basename(file) + + ' failed' + + (err.code ? ' with ' + err.code : '') + + ', '; + msg += 'trying with git..'; + that._logger.debug('error', err.message, { + error: err + }); + that._logger.warn('retry', msg); + + return that + ._cleanTempDir() + .then( + GitRemoteResolver.prototype._checkout.bind( + that + ) + ); + }) + ); + // Fallback to standard git clone if download failed + }, + function(err) { + msg = + 'Download of ' + + tarballUrl + + ' failed' + + (err.code ? ' with ' + err.code : '') + + ', '; + msg += 'trying with git..'; + that._logger.debug('error', err.message, { error: err }); + that._logger.warn('retry', msg); + + return that + ._cleanTempDir() + .then(GitRemoteResolver.prototype._checkout.bind(that)); + } + ); }; -GitHubResolver.prototype._savePkgMeta = function (meta) { +GitHubResolver.prototype._savePkgMeta = function(meta) { // Set homepage if not defined if (!meta.homepage) { meta.homepage = 'https://github.com/' + this._org + '/' + this._repo; @@ -128,10 +172,12 @@ GitHubResolver.prototype._savePkgMeta = function (meta) { // ---------------- -GitHubResolver.getOrgRepoPair = function (url) { +GitHubResolver.getOrgRepoPair = function(url) { var match; - match = url.match(/(?:@|:\/\/)github.com[:\/]([^\/\s]+?)\/([^\/\s]+?)(?:\.git)?\/?$/i); + match = url.match( + /(?:@|:\/\/)github.com[:\/]([^\/\s]+?)\/([^\/\s]+?)(?:\.git)?\/?$/i + ); if (!match) { return null; } diff --git a/lib/core/resolvers/GitRemoteResolver.js b/lib/core/resolvers/GitRemoteResolver.js index b8f32f8be..dec9ebda8 100644 --- a/lib/core/resolvers/GitRemoteResolver.js +++ b/lib/core/resolvers/GitRemoteResolver.js @@ -25,7 +25,7 @@ function GitRemoteResolver(decEndpoint, config, logger) { } else { this._remote = url.parse(this._source); } - + this._host = this._remote.host; // Verify whether the server supports shallow cloning @@ -37,33 +37,37 @@ mout.object.mixIn(GitRemoteResolver, GitResolver); // ----------------- -GitRemoteResolver.prototype._checkout = function () { +GitRemoteResolver.prototype._checkout = function() { var promise; var timer; var reporter; var that = this; var resolution = this._resolution; - this._logger.action('checkout', resolution.tag || resolution.branch || resolution.commit, { - resolution: resolution, - to: this._tempDir - }); + this._logger.action( + 'checkout', + resolution.tag || resolution.branch || resolution.commit, + { + resolution: resolution, + to: this._tempDir + } + ); // If resolution is a commit, we need to clone the entire repo and check it out // Because a commit is not a named ref, there's no better solution if (resolution.type === 'commit') { promise = this._slowClone(resolution); - // Otherwise we are checking out a named ref so we can optimize it + // Otherwise we are checking out a named ref so we can optimize it } else { promise = this._fastClone(resolution); } // Throttle the progress reporter to 1 time each sec - reporter = mout.fn.throttle(function (data) { + reporter = mout.fn.throttle(function(data) { var lines; lines = data.split(/[\r\n]+/); - lines.forEach(function (line) { + lines.forEach(function(line) { if (/\d{1,3}\%/.test(line)) { // TODO: There are some strange chars that appear once in a while (\u001b[K) // Trim also those? @@ -73,94 +77,125 @@ GitRemoteResolver.prototype._checkout = function () { }, 1000); // Start reporting progress after a few seconds - timer = setTimeout(function () { + timer = setTimeout(function() { promise.progress(reporter); }, 8000); - return promise - // Add additional proxy information to the error if necessary - .fail(function (err) { - that._suggestProxyWorkaround(err); - throw err; - }) - // Clear timer at the end - .fin(function () { - clearTimeout(timer); - reporter.cancel(); - }); + return ( + promise + // Add additional proxy information to the error if necessary + .fail(function(err) { + that._suggestProxyWorkaround(err); + throw err; + }) + // Clear timer at the end + .fin(function() { + clearTimeout(timer); + reporter.cancel(); + }) + ); }; -GitRemoteResolver.prototype._findResolution = function (target) { +GitRemoteResolver.prototype._findResolution = function(target) { var that = this; // Override this function to include a meaningful message related to proxies // if necessary - return GitResolver.prototype._findResolution.call(this, target) - .fail(function (err) { - that._suggestProxyWorkaround(err); - throw err; - }); + return GitResolver.prototype._findResolution + .call(this, target) + .fail(function(err) { + that._suggestProxyWorkaround(err); + throw err; + }); }; // ------------------------------ -GitRemoteResolver.prototype._slowClone = function (resolution) { - return cmd('git', ['clone', this._source, this._tempDir, '--progress']) - .then(cmd.bind(cmd, 'git', ['checkout', resolution.commit], { cwd: this._tempDir })); +GitRemoteResolver.prototype._slowClone = function(resolution) { + return cmd('git', [ + 'clone', + this._source, + this._tempDir, + '--progress' + ]).then( + cmd.bind(cmd, 'git', ['checkout', resolution.commit], { + cwd: this._tempDir + }) + ); }; -GitRemoteResolver.prototype._fastClone = function (resolution) { +GitRemoteResolver.prototype._fastClone = function(resolution) { var branch, args, that = this; branch = resolution.tag || resolution.branch; - args = ['clone', this._source, '-b', branch, '--progress', '.']; + args = ['clone', this._source, '-b', branch, '--progress', '.']; - return this._shallowClone().then(function (shallowCloningSupported) { + return this._shallowClone().then(function(shallowCloningSupported) { // If the host does not support shallow clones, we don't use --depth=1 - if (shallowCloningSupported && !GitRemoteResolver._noShallow.get(that._host)) { + if ( + shallowCloningSupported && + !GitRemoteResolver._noShallow.get(that._host) + ) { args.push('--depth', 1); } - return cmd('git', args, { cwd: that._tempDir }) - .spread(function (stdout, stderr) { - // Only after 1.7.10 --branch accepts tags - // Detect those cases and inform the user to update git otherwise it's - // a lot slower than newer versions - if (!/branch .+? not found/i.test(stderr)) { - return; - } - - that._logger.warn('old-git', 'It seems you are using an old version of git, it will be slower and propitious to errors!'); - return cmd('git', ['checkout', resolution.commit], { cwd: that._tempDir }); - }, function (err) { - // Some git servers do not support shallow clones - // When that happens, we mark this host and try again - if (!GitRemoteResolver._noShallow.has(that._source) && - err.details && - /(rpc failed|shallow|--depth)/i.test(err.details) + return cmd('git', args, { cwd: that._tempDir }).spread( + function(stdout, stderr) { + // Only after 1.7.10 --branch accepts tags + // Detect those cases and inform the user to update git otherwise it's + // a lot slower than newer versions + if (!/branch .+? not found/i.test(stderr)) { + return; + } + + that._logger.warn( + 'old-git', + 'It seems you are using an old version of git, it will be slower and propitious to errors!' + ); + return cmd('git', ['checkout', resolution.commit], { + cwd: that._tempDir + }); + }, + function(err) { + // Some git servers do not support shallow clones + // When that happens, we mark this host and try again + if ( + !GitRemoteResolver._noShallow.has(that._source) && + err.details && + /(rpc failed|shallow|--depth)/i.test(err.details) ) { - GitRemoteResolver._noShallow.set(that._host, true); - return that._fastClone(resolution); - } + GitRemoteResolver._noShallow.set(that._host, true); + return that._fastClone(resolution); + } - throw err; - }); + throw err; + } + ); }); }; -GitRemoteResolver.prototype._suggestProxyWorkaround = function (err) { - if ((this._config.proxy || this._config.httpsProxy) && +GitRemoteResolver.prototype._suggestProxyWorkaround = function(err) { + if ( + (this._config.proxy || this._config.httpsProxy) && mout.string.startsWith(this._source, 'git://') && - err.code === 'ECMDERR' && err.details + err.code === 'ECMDERR' && + err.details ) { err.details = err.details.trim(); - err.details += '\n\nWhen under a proxy, you must configure git to use https:// instead of git://.'; - err.details += '\nYou can configure it for every endpoint or for this specific host as follows:'; + err.details += + '\n\nWhen under a proxy, you must configure git to use https:// instead of git://.'; + err.details += + '\nYou can configure it for every endpoint or for this specific host as follows:'; err.details += '\ngit config --global url."https://".insteadOf git://'; - err.details += '\ngit config --global url."https://' + this._host + '".insteadOf git://' + this._host; - err.details += 'Ignore this suggestion if you already have this configured.'; + err.details += + '\ngit config --global url."https://' + + this._host + + '".insteadOf git://' + + this._host; + err.details += + 'Ignore this suggestion if you already have this configured.'; } }; @@ -182,7 +217,7 @@ GitRemoteResolver.prototype._suggestProxyWorkaround = function (err) { // negotiation that needs to take place. // // The above should cover most cases, including BitBucket. -GitRemoteResolver.prototype._supportsShallowCloning = function () { +GitRemoteResolver.prototype._supportsShallowCloning = function() { var value = true; // Verify that the remote could be parsed and that a protocol is set @@ -191,8 +226,11 @@ GitRemoteResolver.prototype._supportsShallowCloning = function () { return Q.resolve(false); } - - if (!this._host || !this._config.shallowCloneHosts || this._config.shallowCloneHosts.indexOf(this._host) === -1) { + if ( + !this._host || + !this._config.shallowCloneHosts || + this._config.shallowCloneHosts.indexOf(this._host) === -1 + ) { return Q.resolve(false); } @@ -200,34 +238,43 @@ GitRemoteResolver.prototype._supportsShallowCloning = function () { // HTTP or HTTPS, not for Git or SSH. // Also check for hosts that have been checked in a previous request and have been found to support // shallow cloning. - if (mout.string.startsWith(this._remote.protocol, 'http') - && !GitRemoteResolver._canShallow.get(this._host)) { + if ( + mout.string.startsWith(this._remote.protocol, 'http') && + !GitRemoteResolver._canShallow.get(this._host) + ) { // Provide GIT_CURL_VERBOSE=2 environment variable to capture curl output. // Calling ls-remote includes a call to the git-upload-pack service, which returns the content type in the response. - var processEnv = mout.object.merge(process.env, { 'GIT_CURL_VERBOSE': '2' }); + var processEnv = mout.object.merge(process.env, { + GIT_CURL_VERBOSE: '2' + }); value = cmd('git', ['ls-remote', '--heads', this._source], { env: processEnv - }) - .spread(function (stdout, stderr) { - // Check stderr for content-type, ignore stdout - var isSmartServer; - - // If the content type is 'x-git', then the server supports shallow cloning - isSmartServer = mout.string.contains(stderr, - 'Content-Type: application/x-git-upload-pack-advertisement'); - - this._logger.debug('detect-smart-git', 'Smart Git host detected: ' + isSmartServer); - - if (isSmartServer) { - // Cache this host - GitRemoteResolver._canShallow.set(this._host, true); - } - - return isSmartServer; - }.bind(this)); - } - else { + }).spread( + function(stdout, stderr) { + // Check stderr for content-type, ignore stdout + var isSmartServer; + + // If the content type is 'x-git', then the server supports shallow cloning + isSmartServer = mout.string.contains( + stderr, + 'Content-Type: application/x-git-upload-pack-advertisement' + ); + + this._logger.debug( + 'detect-smart-git', + 'Smart Git host detected: ' + isSmartServer + ); + + if (isSmartServer) { + // Cache this host + GitRemoteResolver._canShallow.set(this._host, true); + } + + return isSmartServer; + }.bind(this) + ); + } else { // One of the following cases: // * A non-HTTP/HTTPS protocol // * A host that has been checked before and that supports shallow cloning @@ -240,7 +287,7 @@ GitRemoteResolver.prototype._supportsShallowCloning = function () { // ------------------------------ // Grab refs remotely -GitRemoteResolver.refs = function (source) { +GitRemoteResolver.refs = function(source) { var value; // TODO: Normalize source because of the various available protocols? @@ -250,20 +297,22 @@ GitRemoteResolver.refs = function (source) { } // Store the promise in the refs object - value = cmd('git', ['ls-remote', '--tags', '--heads', source]) - .spread(function (stdout) { - var refs; - - refs = stdout.toString() - .trim() // Trim trailing and leading spaces - .replace(/[\t ]+/g, ' ') // Standardize spaces (some git versions make tabs, other spaces) - .split(/[\r\n]+/); // Split lines into an array - - // Update the refs with the actual refs - this._cache.refs.set(source, refs); - - return refs; - }.bind(this)); + value = cmd('git', ['ls-remote', '--tags', '--heads', source]).spread( + function(stdout) { + var refs; + + refs = stdout + .toString() + .trim() // Trim trailing and leading spaces + .replace(/[\t ]+/g, ' ') // Standardize spaces (some git versions make tabs, other spaces) + .split(/[\r\n]+/); // Split lines into an array + + // Update the refs with the actual refs + this._cache.refs.set(source, refs); + + return refs; + }.bind(this) + ); // Store the promise to be reused until it resolves // to a specific value diff --git a/lib/core/resolvers/GitResolver.js b/lib/core/resolvers/GitResolver.js index 90d58c03a..fefa75cb1 100644 --- a/lib/core/resolvers/GitResolver.js +++ b/lib/core/resolvers/GitResolver.js @@ -51,18 +51,20 @@ mout.object.mixIn(GitResolver, Resolver); // ----------------- -GitResolver.prototype._hasNew = function (pkgMeta) { +GitResolver.prototype._hasNew = function(pkgMeta) { var oldResolution = pkgMeta._resolution || {}; - return this._findResolution() - .then(function (resolution) { + return this._findResolution().then(function(resolution) { // Check if resolution types are different if (oldResolution.type !== resolution.type) { return true; } // If resolved to a version, there is new content if the tags are not equal - if (resolution.type === 'version' && semver.neq(resolution.tag, oldResolution.tag)) { + if ( + resolution.type === 'version' && + semver.neq(resolution.tag, oldResolution.tag) + ) { return true; } @@ -71,35 +73,37 @@ GitResolver.prototype._hasNew = function (pkgMeta) { }); }; -GitResolver.prototype._resolve = function () { +GitResolver.prototype._resolve = function() { var that = this; - return this._findResolution() - .then(function () { - return that._checkout() - // Always run cleanup after checkout to ensure that .git is removed! - // If it's not removed, problems might arise when the "tmp" module attempts - // to delete the temporary folder - .fin(function () { - return that._cleanup(); - }); + return this._findResolution().then(function() { + return ( + that + ._checkout() + // Always run cleanup after checkout to ensure that .git is removed! + // If it's not removed, problems might arise when the "tmp" module attempts + // to delete the temporary folder + .fin(function() { + return that._cleanup(); + }) + ); }); }; // ----------------- // Abstract functions that should be implemented by concrete git resolvers -GitResolver.prototype._checkout = function () { +GitResolver.prototype._checkout = function() { throw new Error('_checkout not implemented'); }; -GitResolver.refs = function (source) { +GitResolver.refs = function(source) { throw new Error('refs not implemented'); }; // ----------------- -GitResolver.prototype._findResolution = function (target) { +GitResolver.prototype._findResolution = function(target) { var err; var self = this.constructor; var that = this; @@ -108,18 +112,15 @@ GitResolver.prototype._findResolution = function (target) { // Target is a commit, so it's a stale target (not a moving target) // There's nothing to do in this case - if ((/^[a-f0-9]{40}$/).test(target)) { + if (/^[a-f0-9]{40}$/.test(target)) { this._resolution = { type: 'commit', commit: target }; return Q.resolve(this._resolution); } // Target is a range/version if (semver.validRange(target)) { - return self.versions(this._source, true) - .then(function (versions) { - var versionsArr, - version, - index; + return self.versions(this._source, true).then(function(versions) { + var versionsArr, version, index; // If there are no tags and target is *, // fallback to the latest commit on master @@ -127,98 +128,143 @@ GitResolver.prototype._findResolution = function (target) { return that._findResolution('master'); } - versionsArr = versions.map(function (obj) { return obj.version; }); + versionsArr = versions.map(function(obj) { + return obj.version; + }); // Find a satisfying version, enabling strict match so that pre-releases // have lower priority over normal ones when target is * index = semver.maxSatisfyingIndex(versionsArr, target, true); if (index !== -1) { version = versions[index]; - return that._resolution = { type: 'version', tag: version.tag, commit: version.commit }; + return (that._resolution = { + type: 'version', + tag: version.tag, + commit: version.commit + }); } // Check if there's an exact branch/tag with this name as last resort return Q.all([ self.branches(that._source), self.tags(that._source) - ]) - .spread(function (branches, tags) { + ]).spread(function(branches, tags) { // Use hasOwn because a branch/tag could have a name like "hasOwnProperty" if (mout.object.hasOwn(tags, target)) { - return that._resolution = { type: 'tag', tag: target, commit: tags[target] }; + return (that._resolution = { + type: 'tag', + tag: target, + commit: tags[target] + }); } if (mout.object.hasOwn(branches, target)) { - return that._resolution = { type: 'branch', branch: target, commit: branches[target] }; + return (that._resolution = { + type: 'branch', + branch: target, + commit: branches[target] + }); } - throw createError('No tag found that was able to satisfy ' + target, 'ENORESTARGET', { - details: !versions.length ? - 'No versions found in ' + that._source : - 'Available versions in ' + that._source + ': ' + versions.map(function (version) { return version.version; }).join(', ') - }); + throw createError( + 'No tag found that was able to satisfy ' + target, + 'ENORESTARGET', + { + details: !versions.length + ? 'No versions found in ' + that._source + : 'Available versions in ' + + that._source + + ': ' + + versions + .map(function(version) { + return version.version; + }) + .join(', ') + } + ); }); }); } // Otherwise, target is either a tag or a branch - return Q.all([ - self.branches(that._source), - self.tags(that._source) - ]) - .spread(function (branches, tags) { - // Use hasOwn because a branch/tag could have a name like "hasOwnProperty" - if (mout.object.hasOwn(tags, target)) { - return that._resolution = { type: 'tag', tag: target, commit: tags[target] }; - } - if (mout.object.hasOwn(branches, target)) { - return that._resolution = { type: 'branch', branch: target, commit: branches[target] }; - } - - if ((/^[a-f0-9]{4,40}$/).test(target)) { - if (target.length < 12) { - that._logger.warn( - 'short-sha', - 'Consider using longer commit SHA to avoid conflicts' - ); + return Q.all([self.branches(that._source), self.tags(that._source)]).spread( + function(branches, tags) { + // Use hasOwn because a branch/tag could have a name like "hasOwnProperty" + if (mout.object.hasOwn(tags, target)) { + return (that._resolution = { + type: 'tag', + tag: target, + commit: tags[target] + }); + } + if (mout.object.hasOwn(branches, target)) { + return (that._resolution = { + type: 'branch', + branch: target, + commit: branches[target] + }); } - that._resolution = { type: 'commit', commit: target }; - return that._resolution; - } - - branches = Object.keys(branches); - tags = Object.keys(tags); + if (/^[a-f0-9]{4,40}$/.test(target)) { + if (target.length < 12) { + that._logger.warn( + 'short-sha', + 'Consider using longer commit SHA to avoid conflicts' + ); + } - err = createError('Tag/branch ' + target + ' does not exist', 'ENORESTARGET'); - err.details = !tags.length ? - 'No tags found in ' + that._source : - 'Available tags: ' + tags.join(', '); - err.details += '\n'; - err.details += !branches.length ? - 'No branches found in ' + that._source : - 'Available branches: ' + branches.join(', '); + that._resolution = { type: 'commit', commit: target }; + return that._resolution; + } - throw err; - }); + branches = Object.keys(branches); + tags = Object.keys(tags); + + err = createError( + 'Tag/branch ' + target + ' does not exist', + 'ENORESTARGET' + ); + err.details = !tags.length + ? 'No tags found in ' + that._source + : 'Available tags: ' + tags.join(', '); + err.details += '\n'; + err.details += !branches.length + ? 'No branches found in ' + that._source + : 'Available branches: ' + branches.join(', '); + + throw err; + } + ); }; -GitResolver.prototype._cleanup = function () { +GitResolver.prototype._cleanup = function() { var gitFolder = path.join(this._tempDir, '.git'); return Q.nfcall(rimraf, gitFolder); }; -GitResolver.prototype._savePkgMeta = function (meta) { +GitResolver.prototype._savePkgMeta = function(meta) { var version; if (this._resolution.type === 'version') { version = semver.clean(this._resolution.tag); // Warn if the package meta version is different than the resolved one - if (typeof meta.version === 'string' && semver.valid(meta.version) && semver.neq(meta.version, version)) { - this._logger.warn('mismatch', 'Version declared in the json (' + meta.version + ') is different than the resolved one (' + version + ')', { - resolution: this._resolution, - pkgMeta: meta - }); + if ( + typeof meta.version === 'string' && + semver.valid(meta.version) && + semver.neq(meta.version, version) + ) { + this._logger.warn( + 'mismatch', + 'Version declared in the json (' + + meta.version + + ') is different than the resolved one (' + + version + + ')', + { + resolution: this._resolution, + pkgMeta: meta + } + ); } // Ensure package meta version is the same as the resolution @@ -232,9 +278,10 @@ GitResolver.prototype._savePkgMeta = function (meta) { // Save version/tag/commit in the release // Note that we can't store branches because _release is supposed to be // an unique id of this ref. - meta._release = version || - this._resolution.tag || - this._resolution.commit.substr(0, 10); + meta._release = + version || + this._resolution.tag || + this._resolution.commit.substr(0, 10); // Save resolution to be used in hasNew later meta._resolution = this._resolution; @@ -244,51 +291,56 @@ GitResolver.prototype._savePkgMeta = function (meta) { // ------------------------------ -GitResolver.versions = function (source, extra) { +GitResolver.versions = function(source, extra) { var value = this._cache.versions.get(source); if (value) { - return Q.resolve(value) - .then(function () { - var versions = this._cache.versions.get(source); - - // If no extra information was requested, - // resolve simply with the versions - if (!extra) { - versions = versions.map(function (version) { - return version.version; - }); - } + return Q.resolve(value).then( + function() { + var versions = this._cache.versions.get(source); + + // If no extra information was requested, + // resolve simply with the versions + if (!extra) { + versions = versions.map(function(version) { + return version.version; + }); + } - return versions; - }.bind(this)); + return versions; + }.bind(this) + ); } - value = this.tags(source) - .then(function (tags) { - var tag; - var version; - var versions = []; - - // For each tag - for (tag in tags) { - version = semver.clean(tag); - if (version) { - versions.push({ version: version, tag: tag, commit: tags[tag] }); + value = this.tags(source).then( + function(tags) { + var tag; + var version; + var versions = []; + + // For each tag + for (tag in tags) { + version = semver.clean(tag); + if (version) { + versions.push({ + version: version, + tag: tag, + commit: tags[tag] + }); + } } - } - - // Sort them by DESC order - versions.sort(function (a, b) { - return semver.rcompare(a.version, b.version); - }); - this._cache.versions.set(source, versions); + // Sort them by DESC order + versions.sort(function(a, b) { + return semver.rcompare(a.version, b.version); + }); - // Call the function again to keep it DRY - return this.versions(source, extra); - }.bind(this)); + this._cache.versions.set(source, versions); + // Call the function again to keep it DRY + return this.versions(source, extra); + }.bind(this) + ); // Store the promise to be reused until it resolves // to a specific value @@ -297,30 +349,31 @@ GitResolver.versions = function (source, extra) { return value; }; -GitResolver.tags = function (source) { +GitResolver.tags = function(source) { var value = this._cache.tags.get(source); if (value) { return Q.resolve(value); } - value = this.refs(source) - .then(function (refs) { - var tags = {}; + value = this.refs(source).then( + function(refs) { + var tags = {}; - // For each line in the refs, match only the tags - refs.forEach(function (line) { - var match = line.match(/^([a-f0-9]{40})\s+refs\/tags\/(\S+)/); + // For each line in the refs, match only the tags + refs.forEach(function(line) { + var match = line.match(/^([a-f0-9]{40})\s+refs\/tags\/(\S+)/); - if (match && !mout.string.endsWith(match[2], '^{}')) { - tags[match[2]] = match[1]; - } - }); + if (match && !mout.string.endsWith(match[2], '^{}')) { + tags[match[2]] = match[1]; + } + }); - this._cache.tags.set(source, tags); + this._cache.tags.set(source, tags); - return tags; - }.bind(this)); + return tags; + }.bind(this) + ); // Store the promise to be reused until it resolves // to a specific value @@ -329,32 +382,33 @@ GitResolver.tags = function (source) { return value; }; -GitResolver.branches = function (source) { +GitResolver.branches = function(source) { var value = this._cache.branches.get(source); if (value) { return Q.resolve(value); } - value = this.refs(source) - .then(function (refs) { - var branches = {}; + value = this.refs(source).then( + function(refs) { + var branches = {}; - // For each line in the refs, extract only the heads - // Organize them in an object where keys are branches and values - // the commit hashes - refs.forEach(function (line) { - var match = line.match(/^([a-f0-9]{40})\s+refs\/heads\/(\S+)/); + // For each line in the refs, extract only the heads + // Organize them in an object where keys are branches and values + // the commit hashes + refs.forEach(function(line) { + var match = line.match(/^([a-f0-9]{40})\s+refs\/heads\/(\S+)/); - if (match) { - branches[match[2]] = match[1]; - } - }); + if (match) { + branches[match[2]] = match[1]; + } + }); - this._cache.branches.set(source, branches); + this._cache.branches.set(source, branches); - return branches; - }.bind(this)); + return branches; + }.bind(this) + ); // Store the promise to be reused until it resolves // to a specific value @@ -363,9 +417,9 @@ GitResolver.branches = function (source) { return value; }; -GitResolver.clearRuntimeCache = function () { +GitResolver.clearRuntimeCache = function() { // Reset cache for branches, tags, etc - mout.object.forOwn(GitResolver._cache, function (lru) { + mout.object.forOwn(GitResolver._cache, function(lru) { lru.reset(); }); }; diff --git a/lib/core/resolvers/Resolver.js b/lib/core/resolvers/Resolver.js index 6b587dc73..93a0613e1 100644 --- a/lib/core/resolvers/Resolver.js +++ b/lib/core/resolvers/Resolver.js @@ -24,27 +24,27 @@ function Resolver(decEndpoint, config, logger) { // ----------------- -Resolver.prototype.getSource = function () { +Resolver.prototype.getSource = function() { return this._source; }; -Resolver.prototype.getName = function () { +Resolver.prototype.getName = function() { return this._name; }; -Resolver.prototype.getTarget = function () { +Resolver.prototype.getTarget = function() { return this._target; }; -Resolver.prototype.getTempDir = function () { +Resolver.prototype.getTempDir = function() { return this._tempDir; }; -Resolver.prototype.getPkgMeta = function () { +Resolver.prototype.getPkgMeta = function() { return this._pkgMeta; }; -Resolver.prototype.hasNew = function (pkgMeta) { +Resolver.prototype.hasNew = function(pkgMeta) { var promise; var that = this; @@ -58,12 +58,12 @@ Resolver.prototype.hasNew = function (pkgMeta) { // Avoid reading the package meta if already given promise = this._hasNew(pkgMeta); - return promise.fin(function () { + return promise.fin(function() { that._working = false; }); }; -Resolver.prototype.resolve = function () { +Resolver.prototype.resolve = function() { var that = this; // If already working, error out @@ -74,89 +74,104 @@ Resolver.prototype.resolve = function () { this._working = true; // Create temporary dir - return this._createTempDir() - // Resolve self - .then(this._resolve.bind(this)) - // Read json, generating the package meta - .then(this._readJson.bind(this, null)) - // Apply and save package meta - .then(function (meta) { - return that._applyPkgMeta(meta) - .then(that._savePkgMeta.bind(that, meta)); - }) - .then(function () { - // Resolve with the folder - return that._tempDir; - }, function (err) { - // If something went wrong, unset the temporary dir - that._tempDir = null; - throw err; - }) - .fin(function () { - that._working = false; - }); -}; - -Resolver.prototype.isCacheable = function () { + return ( + this._createTempDir() + // Resolve self + .then(this._resolve.bind(this)) + // Read json, generating the package meta + .then(this._readJson.bind(this, null)) + // Apply and save package meta + .then(function(meta) { + return that + ._applyPkgMeta(meta) + .then(that._savePkgMeta.bind(that, meta)); + }) + .then( + function() { + // Resolve with the folder + return that._tempDir; + }, + function(err) { + // If something went wrong, unset the temporary dir + that._tempDir = null; + throw err; + } + ) + .fin(function() { + that._working = false; + }) + ); +}; + +Resolver.prototype.isCacheable = function() { // Bypass cache for local dependencies - if (this._source && + if ( + this._source && /^(?:file:[\/\\]{2}|[A-Z]:)?\.?\.?[\/\\]/.test(this._source) ) { return false; } // We don't want to cache moving targets like branches - if (this._pkgMeta && + if ( + this._pkgMeta && this._pkgMeta._resolution && - this._pkgMeta._resolution.type === 'branch') { + this._pkgMeta._resolution.type === 'branch' + ) { return false; } return true; }; - // ----------------- // Abstract functions that must be implemented by concrete resolvers -Resolver.prototype._resolve = function () { +Resolver.prototype._resolve = function() { throw new Error('_resolve not implemented'); }; // Abstract functions that can be re-implemented by concrete resolvers // as necessary -Resolver.prototype._hasNew = function (pkgMeta) { +Resolver.prototype._hasNew = function(pkgMeta) { return Q.resolve(true); }; -Resolver.isTargetable = function () { +Resolver.isTargetable = function() { return true; }; -Resolver.versions = function (source) { +Resolver.versions = function(source) { return Q.resolve([]); }; -Resolver.clearRuntimeCache = function () {}; +Resolver.clearRuntimeCache = function() {}; // ----------------- -Resolver.prototype._createTempDir = function () { +Resolver.prototype._createTempDir = function() { return Q.nfcall(mkdirp, this._config.tmp) - .then(function () { - return Q.nfcall(tmp.dir, { - template: path.join(this._config.tmp, md5(this._name) + '-' + process.pid + '-XXXXXX'), - mode: 0777 & ~process.umask(), - unsafeCleanup: true - }); - }.bind(this)) - .then(function (dir) { - // nfcall may return multiple callback arguments as an array - return this._tempDir = Array.isArray(dir) ? dir[0] : dir; - }.bind(this)); -}; - -Resolver.prototype._cleanTempDir = function () { + .then( + function() { + return Q.nfcall(tmp.dir, { + template: path.join( + this._config.tmp, + md5(this._name) + '-' + process.pid + '-XXXXXX' + ), + mode: 0777 & ~process.umask(), + unsafeCleanup: true + }); + }.bind(this) + ) + .then( + function(dir) { + // nfcall may return multiple callback arguments as an array + return (this._tempDir = Array.isArray(dir) ? dir[0] : dir); + }.bind(this) + ); +}; + +Resolver.prototype._cleanTempDir = function() { var tempDir = this._tempDir; if (!tempDir) { @@ -165,32 +180,37 @@ Resolver.prototype._cleanTempDir = function () { // Delete and create folder return Q.nfcall(rimraf, tempDir) - .then(function () { - return Q.nfcall(mkdirp, tempDir, 0777 & ~process.umask()); - }) - .then(function () { - return tempDir; - }); + .then(function() { + return Q.nfcall(mkdirp, tempDir, 0777 & ~process.umask()); + }) + .then(function() { + return tempDir; + }); }; -Resolver.prototype._readJson = function (dir) { +Resolver.prototype._readJson = function(dir) { var that = this; dir = dir || this._tempDir; return readJson(dir, { assume: { name: this._name }, logger: that._logger - }) - .spread(function (json, deprecated) { + }).spread(function(json, deprecated) { if (deprecated) { - that._logger.warn('deprecated', 'Package ' + that._name + ' is using the deprecated ' + deprecated); + that._logger.warn( + 'deprecated', + 'Package ' + + that._name + + ' is using the deprecated ' + + deprecated + ); } return json; }); }; -Resolver.prototype._applyPkgMeta = function (meta) { +Resolver.prototype._applyPkgMeta = function(meta) { // Check if name defined in the json is different // If so and if the name was "guessed", assume the json name if (meta.name !== this._name && this._guessedName) { @@ -204,13 +224,12 @@ Resolver.prototype._applyPkgMeta = function (meta) { } // Otherwise remove them from the temp dir - return removeIgnores(this._tempDir, meta) - .then(function () { + return removeIgnores(this._tempDir, meta).then(function() { return meta; }); }; -Resolver.prototype._savePkgMeta = function (meta) { +Resolver.prototype._savePkgMeta = function(meta) { var that = this; var contents; @@ -221,9 +240,12 @@ Resolver.prototype._savePkgMeta = function (meta) { // Stringify contents contents = JSON.stringify(meta, null, 2); - return Q.nfcall(fs.writeFile, path.join(this._tempDir, '.bower.json'), contents) - .then(function () { - return that._pkgMeta = meta; + return Q.nfcall( + fs.writeFile, + path.join(this._tempDir, '.bower.json'), + contents + ).then(function() { + return (that._pkgMeta = meta); }); }; diff --git a/lib/core/resolvers/SvnResolver.js b/lib/core/resolvers/SvnResolver.js index 17da23744..5534f6286 100644 --- a/lib/core/resolvers/SvnResolver.js +++ b/lib/core/resolvers/SvnResolver.js @@ -31,27 +31,29 @@ mout.object.mixIn(SvnResolver, Resolver); // ----------------- -SvnResolver.getSource = function (source) { +SvnResolver.getSource = function(source) { var uri = this._source || source; return uri - .replace(/^svn\+(https?|file):\/\//i, '$1://') // Change svn+http or svn+https or svn+file to http(s), file respectively - .replace('svn://', 'http://') // Change svn to http - .replace(/\/+$/, ''); // Remove trailing slashes + .replace(/^svn\+(https?|file):\/\//i, '$1://') // Change svn+http or svn+https or svn+file to http(s), file respectively + .replace('svn://', 'http://') // Change svn to http + .replace(/\/+$/, ''); // Remove trailing slashes }; -SvnResolver.prototype._hasNew = function (pkgMeta) { +SvnResolver.prototype._hasNew = function(pkgMeta) { var oldResolution = pkgMeta._resolution || {}; - return this._findResolution() - .then(function (resolution) { + return this._findResolution().then(function(resolution) { // Check if resolution types are different if (oldResolution.type !== resolution.type) { return true; } // If resolved to a version, there is new content if the tags are not equal - if (resolution.type === 'version' && semver.neq(resolution.tag, oldResolution.tag)) { + if ( + resolution.type === 'version' && + semver.neq(resolution.tag, oldResolution.tag) + ) { return true; } @@ -60,18 +62,17 @@ SvnResolver.prototype._hasNew = function (pkgMeta) { }); }; -SvnResolver.prototype._resolve = function () { +SvnResolver.prototype._resolve = function() { var that = this; - return this._findResolution() - .then(function () { + return this._findResolution().then(function() { return that._export(); }); }; // ----------------- -SvnResolver.prototype._export = function () { +SvnResolver.prototype._export = function() { var promise; var timer; var reporter; @@ -80,27 +81,56 @@ SvnResolver.prototype._export = function () { this.source = SvnResolver.getSource(this._source); - this._logger.action('export', resolution.tag || resolution.branch || resolution.commit, { - resolution: resolution, - to: this._tempDir - }); + this._logger.action( + 'export', + resolution.tag || resolution.branch || resolution.commit, + { + resolution: resolution, + to: this._tempDir + } + ); if (resolution.type === 'commit') { - promise = cmd('svn', ['export', '--force', '--non-interactive', this._source + '/trunk', '-r' + resolution.commit, this._tempDir]); + promise = cmd('svn', [ + 'export', + '--force', + '--non-interactive', + this._source + '/trunk', + '-r' + resolution.commit, + this._tempDir + ]); } else if (resolution.type === 'branch' && resolution.branch === 'trunk') { - promise = cmd('svn', ['export', '--force', '--non-interactive', this._source + '/trunk', this._tempDir]); + promise = cmd('svn', [ + 'export', + '--force', + '--non-interactive', + this._source + '/trunk', + this._tempDir + ]); } else if (resolution.type === 'branch') { - promise = cmd('svn', ['export', '--force', '--non-interactive', this._source + '/branches/' + resolution.branch, this._tempDir]); + promise = cmd('svn', [ + 'export', + '--force', + '--non-interactive', + this._source + '/branches/' + resolution.branch, + this._tempDir + ]); } else { - promise = cmd('svn', ['export', '--force', '--non-interactive', this._source + '/tags/' + resolution.tag, this._tempDir]); + promise = cmd('svn', [ + 'export', + '--force', + '--non-interactive', + this._source + '/tags/' + resolution.tag, + this._tempDir + ]); } // Throttle the progress reporter to 1 time each sec - reporter = mout.fn.throttle(function (data) { + reporter = mout.fn.throttle(function(data) { var lines; lines = data.split(/[\r\n]+/); - lines.forEach(function (line) { + lines.forEach(function(line) { if (/\d{1,3}\%/.test(line)) { // TODO: There are some strange chars that appear once in a while (\u001b[K) // Trim also those? @@ -110,25 +140,27 @@ SvnResolver.prototype._export = function () { }, 1000); // Start reporting progress after a few seconds - timer = setTimeout(function () { + timer = setTimeout(function() { promise.progress(reporter); }, 8000); - return promise - // Add additional proxy information to the error if necessary - .fail(function (err) { - throw err; - }) - // Clear timer at the end - .fin(function () { - clearTimeout(timer); - reporter.cancel(); - }); + return ( + promise + // Add additional proxy information to the error if necessary + .fail(function(err) { + throw err; + }) + // Clear timer at the end + .fin(function() { + clearTimeout(timer); + reporter.cancel(); + }) + ); }; // ----------------- -SvnResolver.prototype._findResolution = function (target) { +SvnResolver.prototype._findResolution = function(target) { var err; var self = this.constructor; var that = this; @@ -139,7 +171,7 @@ SvnResolver.prototype._findResolution = function (target) { // Target is a revision, so it's a stale target (not a moving target) // There's nothing to do in this case - if ((/^r\d+/).test(target)) { + if (/^r\d+/.test(target)) { target = target.split('r'); this._resolution = { type: 'commit', commit: target[1] }; @@ -148,13 +180,12 @@ SvnResolver.prototype._findResolution = function (target) { // Target is a range/version if (semver.validRange(target)) { - return self.versions(this._source, true) - .then(function (versions) { - var versionsArr, - version, - index; + return self.versions(this._source, true).then(function(versions) { + var versionsArr, version, index; - versionsArr = versions.map(function (obj) { return obj.version; }); + versionsArr = versions.map(function(obj) { + return obj.version; + }); // If there are no tags and target is *, // fallback to the latest commit on trunk @@ -162,80 +193,124 @@ SvnResolver.prototype._findResolution = function (target) { return that._findResolution('trunk'); } - versionsArr = versions.map(function (obj) { return obj.version; }); + versionsArr = versions.map(function(obj) { + return obj.version; + }); // Find a satisfying version, enabling strict match so that pre-releases // have lower priority over normal ones when target is * index = semver.maxSatisfyingIndex(versionsArr, target, true); if (index !== -1) { version = versions[index]; - return that._resolution = { type: 'version', tag: version.tag, commit: version.commit }; + return (that._resolution = { + type: 'version', + tag: version.tag, + commit: version.commit + }); } // Check if there's an exact branch/tag with this name as last resort return Q.all([ self.branches(that._source), self.tags(that._source) - ]) - .spread(function (branches, tags) { + ]).spread(function(branches, tags) { // Use hasOwn because a branch/tag could have a name like "hasOwnProperty" if (mout.object.hasOwn(tags, target)) { - return that._resolution = { type: 'tag', tag: target, commit: tags[target] }; + return (that._resolution = { + type: 'tag', + tag: target, + commit: tags[target] + }); } if (mout.object.hasOwn(branches, target)) { - return that._resolution = { type: 'branch', branch: target, commit: branches[target] }; + return (that._resolution = { + type: 'branch', + branch: target, + commit: branches[target] + }); } - throw createError('No tag found that was able to satisfy ' + target, 'ENORESTARGET', { - details: !versions.length ? - 'No versions found in ' + that._source : - 'Available versions in ' + that._source + ': ' + versions.map(function (version) { return version.version; }).join(', ') - }); + throw createError( + 'No tag found that was able to satisfy ' + target, + 'ENORESTARGET', + { + details: !versions.length + ? 'No versions found in ' + that._source + : 'Available versions in ' + + that._source + + ': ' + + versions + .map(function(version) { + return version.version; + }) + .join(', ') + } + ); }); }); } // Otherwise, target is either a tag or a branch - return Q.all([ - self.branches(that._source), - self.tags(that._source) - ]) - .spread(function (branches, tags) { - // Use hasOwn because a branch/tag could have a name like "hasOwnProperty" - if (mout.object.hasOwn(tags, target)) { - return that._resolution = { type: 'tag', tag: target, commit: tags[target] }; - } - if (mout.object.hasOwn(branches, target)) { - return that._resolution = { type: 'branch', branch: target, commit: branches[target] }; - } - - branches = Object.keys(branches); - tags = Object.keys(tags); - - err = createError('target ' + target + ' does not exist', 'ENORESTARGET'); - err.details = !tags.length ? - 'No tags found in ' + that._source : - 'Available tags: ' + tags.join(', '); - err.details += '\n'; - err.details += !branches.length ? - 'No branches found in ' + that._source : - 'Available branches: ' + branches.join(', '); + return Q.all([self.branches(that._source), self.tags(that._source)]).spread( + function(branches, tags) { + // Use hasOwn because a branch/tag could have a name like "hasOwnProperty" + if (mout.object.hasOwn(tags, target)) { + return (that._resolution = { + type: 'tag', + tag: target, + commit: tags[target] + }); + } + if (mout.object.hasOwn(branches, target)) { + return (that._resolution = { + type: 'branch', + branch: target, + commit: branches[target] + }); + } - throw err; - }); + branches = Object.keys(branches); + tags = Object.keys(tags); + + err = createError( + 'target ' + target + ' does not exist', + 'ENORESTARGET' + ); + err.details = !tags.length + ? 'No tags found in ' + that._source + : 'Available tags: ' + tags.join(', '); + err.details += '\n'; + err.details += !branches.length + ? 'No branches found in ' + that._source + : 'Available branches: ' + branches.join(', '); + + throw err; + } + ); }; -SvnResolver.prototype._savePkgMeta = function (meta) { +SvnResolver.prototype._savePkgMeta = function(meta) { var version; if (this._resolution.type === 'version') { version = semver.clean(this._resolution.tag); // Warn if the package meta version is different than the resolved one - if (typeof meta.version === 'string' && semver.neq(meta.version, version)) { - this._logger.warn('mismatch', 'Version declared in the json (' + meta.version + ') is different than the resolved one (' + version + ')', { - resolution: this._resolution, - pkgMeta: meta - }); + if ( + typeof meta.version === 'string' && + semver.neq(meta.version, version) + ) { + this._logger.warn( + 'mismatch', + 'Version declared in the json (' + + meta.version + + ') is different than the resolved one (' + + version + + ')', + { + resolution: this._resolution, + pkgMeta: meta + } + ); } // Ensure package meta version is the same as the resolution @@ -249,9 +324,7 @@ SvnResolver.prototype._savePkgMeta = function (meta) { // Save version/tag/commit in the release // Note that we can't store branches because _release is supposed to be // an unique id of this ref. - meta._release = version || - this._resolution.tag || - this._resolution.commit; + meta._release = version || this._resolution.tag || this._resolution.commit; // Save resolution to be used in hasNew later meta._resolution = this._resolution; @@ -261,52 +334,58 @@ SvnResolver.prototype._savePkgMeta = function (meta) { // ------------------------------ -SvnResolver.versions = function (source, extra) { +SvnResolver.versions = function(source, extra) { source = SvnResolver.getSource(source); var value = this._cache.versions.get(source); if (value) { - return Q.resolve(value) - .then(function () { - var versions = this._cache.versions.get(source); - - // If no extra information was requested, - // resolve simply with the versions - if (!extra) { - versions = versions.map(function (version) { - return version.version; - }); - } + return Q.resolve(value).then( + function() { + var versions = this._cache.versions.get(source); + + // If no extra information was requested, + // resolve simply with the versions + if (!extra) { + versions = versions.map(function(version) { + return version.version; + }); + } - return versions; - }.bind(this)); + return versions; + }.bind(this) + ); } - value = this.tags(source) - .then(function (tags) { - var tag; - var version; - var versions = []; - - // For each tag - for (tag in tags) { - version = semver.clean(tag); - if (version) { - versions.push({ version: version, tag: tag, commit: tags[tag] }); + value = this.tags(source).then( + function(tags) { + var tag; + var version; + var versions = []; + + // For each tag + for (tag in tags) { + version = semver.clean(tag); + if (version) { + versions.push({ + version: version, + tag: tag, + commit: tags[tag] + }); + } } - } - // Sort them by DESC order - versions.sort(function (a, b) { - return semver.rcompare(a.version, b.version); - }); + // Sort them by DESC order + versions.sort(function(a, b) { + return semver.rcompare(a.version, b.version); + }); - this._cache.versions.set(source, versions); + this._cache.versions.set(source, versions); - // Call the function again to keep it DRY - return this.versions(source, extra); - }.bind(this)); + // Call the function again to keep it DRY + return this.versions(source, extra); + }.bind(this) + ); // Store the promise to be reused until it resolves // to a specific value @@ -315,7 +394,7 @@ SvnResolver.versions = function (source, extra) { return value; }; -SvnResolver.tags = function (source) { +SvnResolver.tags = function(source) { source = SvnResolver.getSource(source); var value = this._cache.tags.get(source); @@ -324,14 +403,19 @@ SvnResolver.tags = function (source) { return Q.resolve(value); } - value = cmd('svn', ['list', source + '/tags', '--verbose', '--non-interactive']) - .spread(function (stout) { - var tags = SvnResolver.parseSubversionListOutput(stout.toString()); + value = cmd('svn', [ + 'list', + source + '/tags', + '--verbose', + '--non-interactive' + ]).spread( + function(stout) { + var tags = SvnResolver.parseSubversionListOutput(stout.toString()); - this._cache.tags.set(source, tags); - return tags; - - }.bind(this)); + this._cache.tags.set(source, tags); + return tags; + }.bind(this) + ); // Store the promise to be reused until it resolves // to a specific value @@ -340,7 +424,7 @@ SvnResolver.tags = function (source) { return value; }; -SvnResolver.branches = function (source) { +SvnResolver.branches = function(source) { source = SvnResolver.getSource(source); var value = this._cache.branches.get(source); @@ -349,17 +433,24 @@ SvnResolver.branches = function (source) { return Q.resolve(value); } - value = cmd('svn', ['list', source + '/branches', '--verbose', '--non-interactive']) - .spread(function (stout) { - var branches = SvnResolver.parseSubversionListOutput(stout.toString()); - - // trunk is a branch! - branches.trunk = '*'; - - this._cache.branches.set(source, branches); - return branches; - - }.bind(this)); + value = cmd('svn', [ + 'list', + source + '/branches', + '--verbose', + '--non-interactive' + ]).spread( + function(stout) { + var branches = SvnResolver.parseSubversionListOutput( + stout.toString() + ); + + // trunk is a branch! + branches.trunk = '*'; + + this._cache.branches.set(source, branches); + return branches; + }.bind(this) + ); // Store the promise to be reused until it resolves // to a specific value @@ -368,15 +459,12 @@ SvnResolver.branches = function (source) { return value; }; -SvnResolver.parseSubversionListOutput = function (stout) { - +SvnResolver.parseSubversionListOutput = function(stout) { var entries = {}; - var lines = stout - .trim() - .split(/[\r\n]+/); + var lines = stout.trim().split(/[\r\n]+/); // For each line in the refs, match only the branches - lines.forEach(function (line) { + lines.forEach(function(line) { var match = line.match(/\s+([0-9]+)\s.+\s([\w.$-]+)\//i); if (match && match[2] !== '.') { @@ -387,9 +475,9 @@ SvnResolver.parseSubversionListOutput = function (stout) { return entries; }; -SvnResolver.clearRuntimeCache = function () { +SvnResolver.clearRuntimeCache = function() { // Reset cache for branches, tags, etc - mout.object.forOwn(SvnResolver._cache, function (lru) { + mout.object.forOwn(SvnResolver._cache, function(lru) { lru.reset(); }); }; diff --git a/lib/core/resolvers/UrlResolver.js b/lib/core/resolvers/UrlResolver.js index 48be0ba01..1c3decbcf 100644 --- a/lib/core/resolvers/UrlResolver.js +++ b/lib/core/resolvers/UrlResolver.js @@ -16,7 +16,7 @@ function UrlResolver(decEndpoint, config, logger) { // If target was specified, error out if (this._target !== '*') { - throw createError('URL sources can\'t resolve targets', 'ENORESTARGET'); + throw createError("URL sources can't resolve targets", 'ENORESTARGET'); } // If the name was guessed @@ -24,7 +24,10 @@ function UrlResolver(decEndpoint, config, logger) { // Remove the ?xxx part this._name = this._name.replace(/\?.*$/, ''); // Remove extension - this._name = this._name.substr(0, this._name.length - path.extname(this._name).length); + this._name = this._name.substr( + 0, + this._name.length - path.extname(this._name).length + ); } this._remote = url.parse(this._source); @@ -35,11 +38,11 @@ mout.object.mixIn(UrlResolver, Resolver); // ----------------- -UrlResolver.isTargetable = function () { +UrlResolver.isTargetable = function() { return false; }; -UrlResolver.prototype._hasNew = function (pkgMeta) { +UrlResolver.prototype._hasNew = function(pkgMeta) { var oldCacheHeaders = pkgMeta._cacheHeaders || {}; var reqHeaders = {}; @@ -54,61 +57,71 @@ UrlResolver.prototype._hasNew = function (pkgMeta) { } // Make an HEAD request to the source - return Q.nfcall(request.head, this._source, { - ca: this._config.ca.default, - strictSSL: this._config.strictSsl, - timeout: this._config.timeout, - headers: reqHeaders - }) - // Compare new headers with the old ones - .spread(function (response) { - var cacheHeaders; - - // If the server responded with 303 then the resource - // still has the same ETag - if (response.statusCode === 304) { - return false; - } - - // If status code is not in the 2xx range, - // then just resolve to true - if (response.statusCode < 200 || response.statusCode >= 300) { - return true; - } - - // Fallback to comparing cache headers - cacheHeaders = this._collectCacheHeaders(response); - return !mout.object.equals(oldCacheHeaders, cacheHeaders); - }.bind(this), function () { - // Assume new contents if the request failed - // Note that we do not retry the request using the "request-replay" module - // because it would take too long - return true; - }); + return ( + Q.nfcall(request.head, this._source, { + ca: this._config.ca.default, + strictSSL: this._config.strictSsl, + timeout: this._config.timeout, + headers: reqHeaders + }) + // Compare new headers with the old ones + .spread( + function(response) { + var cacheHeaders; + + // If the server responded with 303 then the resource + // still has the same ETag + if (response.statusCode === 304) { + return false; + } + + // If status code is not in the 2xx range, + // then just resolve to true + if ( + response.statusCode < 200 || + response.statusCode >= 300 + ) { + return true; + } + + // Fallback to comparing cache headers + cacheHeaders = this._collectCacheHeaders(response); + return !mout.object.equals(oldCacheHeaders, cacheHeaders); + }.bind(this), + function() { + // Assume new contents if the request failed + // Note that we do not retry the request using the "request-replay" module + // because it would take too long + return true; + } + ) + ); }; // TODO: There's room for improvement by using streams if the URL // is an archive file, by piping read stream to the zip extractor // This will likely increase the complexity of code but might worth it -UrlResolver.prototype._resolve = function () { +UrlResolver.prototype._resolve = function() { // Download - return this._download() - // Parse headers - .spread(this._parseHeaders.bind(this)) - // Extract file - .spread(this._extract.bind(this)) - // Rename file to index - .then(this._rename.bind(this)); + return ( + this._download() + // Parse headers + .spread(this._parseHeaders.bind(this)) + // Extract file + .spread(this._extract.bind(this)) + // Rename file to index + .then(this._rename.bind(this)) + ); }; // ----------------- -UrlResolver.prototype._parseSourceURL = function (_url) { +UrlResolver.prototype._parseSourceURL = function(_url) { return url.parse(path.basename(_url)).pathname; }; -UrlResolver.prototype._download = function () { +UrlResolver.prototype._download = function() { var fileName = this._parseSourceURL(this._source); if (!fileName) { @@ -136,32 +149,43 @@ UrlResolver.prototype._download = function () { timeout: this._config.timeout, headers: reqHeaders }) - .progress(function (state) { - var msg; - - // Retry? - if (state.retry) { - msg = 'Download of ' + that._source + ' failed' + (state.error.code ? ' with ' + state.error.code : '') + ', '; - msg += 'retrying in ' + (state.delay / 1000).toFixed(1) + 's'; - that._logger.debug('error', state.error.message, { error: state.error }); - return that._logger.warn('retry', msg); - } - - // Progress - msg = 'received ' + (state.received / 1024 / 1024).toFixed(1) + 'MB'; - if (state.total) { - msg += ' of ' + (state.total / 1024 / 1024).toFixed(1) + 'MB downloaded, '; - msg += state.percent + '%'; - } - that._logger.info('progress', msg); - }) - .then(function (response) { - that._response = response; - return [file, response]; - }); + .progress(function(state) { + var msg; + + // Retry? + if (state.retry) { + msg = + 'Download of ' + + that._source + + ' failed' + + (state.error.code ? ' with ' + state.error.code : '') + + ', '; + msg += 'retrying in ' + (state.delay / 1000).toFixed(1) + 's'; + that._logger.debug('error', state.error.message, { + error: state.error + }); + return that._logger.warn('retry', msg); + } + + // Progress + msg = + 'received ' + (state.received / 1024 / 1024).toFixed(1) + 'MB'; + if (state.total) { + msg += + ' of ' + + (state.total / 1024 / 1024).toFixed(1) + + 'MB downloaded, '; + msg += state.percent + '%'; + } + that._logger.info('progress', msg); + }) + .then(function(response) { + that._response = response; + return [file, response]; + }); }; -UrlResolver.prototype._parseHeaders = function (file, response) { +UrlResolver.prototype._parseHeaders = function(file, response) { var disposition; var newFile; var match; @@ -196,20 +220,19 @@ UrlResolver.prototype._parseHeaders = function (file, response) { newFile = path.join(this._tempDir, newFile); - return Q.nfcall(fs.rename, file, newFile) - .then(function () { + return Q.nfcall(fs.rename, file, newFile).then(function() { return [newFile, response]; }); }; -UrlResolver.prototype._extract = function (file, response) { +UrlResolver.prototype._extract = function(file, response) { var mimeType = response.headers['content-type']; if (mimeType) { // Clean everything after ; and trim the end result mimeType = mimeType.split(';')[0].trim(); // Some servers add quotes around the content-type, so we trim that also - mimeType = mout.string.trim(mimeType, ['"', '\'']); + mimeType = mout.string.trim(mimeType, ['"', "'"]); } if (!extract.canExtract(file, mimeType)) { @@ -226,36 +249,42 @@ UrlResolver.prototype._extract = function (file, response) { }); }; -UrlResolver.prototype._rename = function () { - return Q.nfcall(fs.readdir, this._tempDir) - .then(function (files) { - var file; - var oldPath; - var newPath; - - // Remove any OS specific files from the files array - // before checking its length - files = files.filter(junk.isnt); - - // Only rename if there's only one file and it's not the json - if (files.length === 1 && !/^(component|bower)\.json$/.test(files[0])) { - file = files[0]; - this._singleFile = 'index' + path.extname(file); - oldPath = path.join(this._tempDir, file); - newPath = path.join(this._tempDir, this._singleFile); - - return Q.nfcall(fs.rename, oldPath, newPath); - } - }.bind(this)); +UrlResolver.prototype._rename = function() { + return Q.nfcall(fs.readdir, this._tempDir).then( + function(files) { + var file; + var oldPath; + var newPath; + + // Remove any OS specific files from the files array + // before checking its length + files = files.filter(junk.isnt); + + // Only rename if there's only one file and it's not the json + if ( + files.length === 1 && + !/^(component|bower)\.json$/.test(files[0]) + ) { + file = files[0]; + this._singleFile = 'index' + path.extname(file); + oldPath = path.join(this._tempDir, file); + newPath = path.join(this._tempDir, this._singleFile); + + return Q.nfcall(fs.rename, oldPath, newPath); + } + }.bind(this) + ); }; -UrlResolver.prototype._savePkgMeta = function (meta) { +UrlResolver.prototype._savePkgMeta = function(meta) { // Store collected headers in the package meta meta._cacheHeaders = this._collectCacheHeaders(this._response); // Store ETAG under _release if (meta._cacheHeaders.ETag) { - meta._release = 'e-tag:' + mout.string.trim(meta._cacheHeaders.ETag.substr(0, 10), '"'); + meta._release = + 'e-tag:' + + mout.string.trim(meta._cacheHeaders.ETag.substr(0, 10), '"'); } // Store main if is a single file @@ -266,11 +295,11 @@ UrlResolver.prototype._savePkgMeta = function (meta) { return Resolver.prototype._savePkgMeta.call(this, meta); }; -UrlResolver.prototype._collectCacheHeaders = function (res) { +UrlResolver.prototype._collectCacheHeaders = function(res) { var headers = {}; // Collect cache headers - this.constructor._cacheHeaders.forEach(function (name) { + this.constructor._cacheHeaders.forEach(function(name) { var value = res.headers[name.toLowerCase()]; if (value != null) { diff --git a/lib/core/resolvers/pluginResolverFactory.js b/lib/core/resolvers/pluginResolverFactory.js index d751d1f51..4d9c93582 100644 --- a/lib/core/resolvers/pluginResolverFactory.js +++ b/lib/core/resolvers/pluginResolverFactory.js @@ -12,7 +12,12 @@ function pluginResolverFactory(resolverFactory, bower) { bower = bower || {}; if (typeof resolverFactory !== 'function') { - throw createError('Resolver has "' + typeof resolverFactory + '" type instead of "function" type.', 'ERESOLERAPI'); + throw createError( + 'Resolver has "' + + typeof resolverFactory + + '" type instead of "function" type.', + 'ERESOLERAPI' + ); } var resolver = resolverFactory(bower); @@ -20,7 +25,9 @@ function pluginResolverFactory(resolverFactory, bower) { function maxSatisfyingVersion(versions, target) { var versionsArr, index; - versionsArr = versions.map(function (obj) { return obj.version; }); + versionsArr = versions.map(function(obj) { + return obj.version; + }); // Find a satisfying version, enabling strict match so that pre-releases // have lower priority over normal ones when target is * @@ -36,7 +43,7 @@ function pluginResolverFactory(resolverFactory, bower) { } // @private - PluginResolver.prototype.getEndpoint = function () { + PluginResolver.prototype.getEndpoint = function() { return object.merge(this._decEndpoint, { name: this.getName(), source: this.getSource(), @@ -44,15 +51,15 @@ function pluginResolverFactory(resolverFactory, bower) { }); }; - PluginResolver.prototype.getSource = function () { + PluginResolver.prototype.getSource = function() { return this._decEndpoint.source; }; - PluginResolver.prototype.getTarget = function () { + PluginResolver.prototype.getTarget = function() { return this._decEndpoint.target || '*'; }; - PluginResolver.prototype.getName = function () { + PluginResolver.prototype.getName = function() { if (!this._decEndpoint.name && typeof resolver.getName === 'function') { return resolver.getName.call(resolver, this.getSource()); } else if (!this._decEndpoint.name) { @@ -62,7 +69,7 @@ function pluginResolverFactory(resolverFactory, bower) { } }; - PluginResolver.prototype.getPkgMeta = function () { + PluginResolver.prototype.getPkgMeta = function() { return this._pkgMeta; }; @@ -70,32 +77,32 @@ function pluginResolverFactory(resolverFactory, bower) { // Plugin Resolver is always considered potentially cacheable // The "resolve" method decides whether to use cached or fetch new version. - PluginResolver.prototype.isCacheable = function () { + PluginResolver.prototype.isCacheable = function() { return true; }; // Not only it's always potentially cacheable, but also always potenially new. // The "resolve" handles logic of re-downloading target if needed. - PluginResolver.prototype.hasNew = function (pkgMeta) { + PluginResolver.prototype.hasNew = function(pkgMeta) { if (this.hasNewPromise) { return this.hasNewPromise; } this._pkgMeta = pkgMeta; - return this.hasNewPromise = this.resolve().then(function (result) { + return (this.hasNewPromise = this.resolve().then(function(result) { return result !== undefined; - }); + })); }; - PluginResolver.prototype.resolve = function () { + PluginResolver.prototype.resolve = function() { if (this.resolvePromise) { return this.resolvePromise; } var that = this; - return this.resolvePromise = Q.fcall(function () { + return (this.resolvePromise = Q.fcall(function() { var target = that.getTarget(); // It means that we can accept ranges as targets @@ -103,15 +110,19 @@ function pluginResolverFactory(resolverFactory, bower) { that._release = target; if (semver.validRange(target)) { - return Q.fcall(resolver.releases.bind(resolver), that.getSource()) - .then(function (result) { + return Q.fcall( + resolver.releases.bind(resolver), + that.getSource() + ).then(function(result) { if (!result) { - throw createError('Resolver did not provide releases of package.'); + throw createError( + 'Resolver did not provide releases of package.' + ); } - var releases = that._releases = result; + var releases = (that._releases = result); - var versions = releases.filter(function (target) { + var versions = releases.filter(function(target) { return semver.clean(target.version); }); @@ -119,91 +130,122 @@ function pluginResolverFactory(resolverFactory, bower) { if (maxRelease) { that._version = maxRelease.version; - that._release = that._decEndpoint.target = maxRelease.target; + that._release = that._decEndpoint.target = + maxRelease.target; } else { - throw createError('No version found that was able to satisfy ' + target, 'ENORESTARGET', { - details: !versions.length ? - 'No versions found in ' + that.getSource() : - 'Available versions: ' + versions.map(function (version) { return version.version; }).join(', ') - }); + throw createError( + 'No version found that was able to satisfy ' + + target, + 'ENORESTARGET', + { + details: !versions.length + ? 'No versions found in ' + + that.getSource() + : 'Available versions: ' + + versions + .map(function(version) { + return version.version; + }) + .join(', ') + } + ); } }); } } else { if (semver.validRange(target) && target !== '*') { - return Q.reject(createError('Resolver does not accept version ranges (' + target + ')')); + return Q.reject( + createError( + 'Resolver does not accept version ranges (' + + target + + ')' + ) + ); } } }) - .then(function () { - - // We pass old _resolution (if hasNew has been called before contents). - // So resolver can decide wheter use cached version of contents new one. - if (typeof resolver.fetch !== 'function') { - throw createError('Resolver does not implement the "fetch" method.'); - } - - var cached = {}; + .then(function() { + // We pass old _resolution (if hasNew has been called before contents). + // So resolver can decide wheter use cached version of contents new one. + if (typeof resolver.fetch !== 'function') { + throw createError( + 'Resolver does not implement the "fetch" method.' + ); + } - if (that._releases) { - cached.releases = that._releases; - } + var cached = {}; - if (that._pkgMeta) { - cached.endpoint = { - name: that._pkgMeta.name, - source: that._pkgMeta._source, - target: that._pkgMeta._target - }; + if (that._releases) { + cached.releases = that._releases; + } - cached.release = that._pkgMeta._release; + if (that._pkgMeta) { + cached.endpoint = { + name: that._pkgMeta.name, + source: that._pkgMeta._source, + target: that._pkgMeta._target + }; - cached.version = that._pkgMeta.version; + cached.release = that._pkgMeta._release; - cached.resolution = that._pkgMeta._resolution || {}; - } + cached.version = that._pkgMeta.version; - return Q.fcall(resolver.fetch.bind(resolver), that.getEndpoint(), cached); - }) - .then(function (result) { - // Empty result means to re-use existing resolution - if (!result) { - return; - } else { - if (!result.tempPath) { - throw createError('Resolver did not provide path to extracted contents of package.'); + cached.resolution = that._pkgMeta._resolution || {}; } - that._tempDir = result.tempPath; - - return that._readJson(that._tempDir).then(function (meta) { - return that._applyPkgMeta(meta, result) - .then(that._savePkgMeta.bind(that, meta, result)) - .then(function () { - return that._tempDir; + return Q.fcall( + resolver.fetch.bind(resolver), + that.getEndpoint(), + cached + ); + }) + .then(function(result) { + // Empty result means to re-use existing resolution + if (!result) { + return; + } else { + if (!result.tempPath) { + throw createError( + 'Resolver did not provide path to extracted contents of package.' + ); + } + + that._tempDir = result.tempPath; + + return that._readJson(that._tempDir).then(function(meta) { + return that + ._applyPkgMeta(meta, result) + .then(that._savePkgMeta.bind(that, meta, result)) + .then(function() { + return that._tempDir; + }); }); - }); - } - }); + } + })); }; - PluginResolver.prototype._readJson = function (dir) { + PluginResolver.prototype._readJson = function(dir) { var that = this; return readJson(dir, { assume: { name: that.getName() }, logger: bower.logger - }) - .spread(function (json, deprecated) { + }).spread(function(json, deprecated) { if (deprecated) { - bower.logger.warn('deprecated', 'Package ' + that.getName() + ' is using the deprecated ' + deprecated); + bower.logger.warn( + 'deprecated', + 'Package ' + + that.getName() + + ' is using the deprecated ' + + deprecated + ); } return json; }); }; - PluginResolver.prototype._applyPkgMeta = function (meta, result) { + PluginResolver.prototype._applyPkgMeta = function(meta, result) { // Check if name defined in the json is different // If so and if the name was "guessed", assume the json name if (meta.name !== this._name) { @@ -212,17 +254,21 @@ function pluginResolverFactory(resolverFactory, bower) { // Handle ignore property, deleting all files from the temporary directory // If no ignores were specified, simply resolve - if (result.removeIgnores === false || !meta.ignore || !meta.ignore.length) { + if ( + result.removeIgnores === false || + !meta.ignore || + !meta.ignore.length + ) { return Q.resolve(meta); } // Otherwise remove them from the temp dir - return removeIgnores(this._tempDir, meta).then(function () { + return removeIgnores(this._tempDir, meta).then(function() { return meta; }); }; - PluginResolver.prototype._savePkgMeta = function (meta, result) { + PluginResolver.prototype._savePkgMeta = function(meta, result) { var that = this; meta._source = that.getSource(); @@ -245,30 +291,37 @@ function pluginResolverFactory(resolverFactory, bower) { // Stringify contents var contents = JSON.stringify(meta, null, 2); - return Q.nfcall(fs.writeFile, path.join(this._tempDir, '.bower.json'), contents) - .then(function () { - return that._pkgMeta = meta; + return Q.nfcall( + fs.writeFile, + path.join(this._tempDir, '.bower.json'), + contents + ).then(function() { + return (that._pkgMeta = meta); }); }; // It is used only by "bower info". It returns all semver versions. - PluginResolver.versions = function (source) { - return Q.fcall(resolver.releases.bind(resolver), source).then(function (result) { + PluginResolver.versions = function(source) { + return Q.fcall(resolver.releases.bind(resolver), source).then(function( + result + ) { if (!result) { - throw createError('Resolver did not provide releases of package.'); + throw createError( + 'Resolver did not provide releases of package.' + ); } - var releases = this._releases = result; + var releases = (this._releases = result); - var versions = releases.map(function (version) { + var versions = releases.map(function(version) { return semver.clean(version.version); }); - versions = versions.filter(function (version) { + versions = versions.filter(function(version) { return version; }); - versions.sort(function (a, b) { + versions.sort(function(a, b) { return semver.rcompare(a, b); }); @@ -276,39 +329,50 @@ function pluginResolverFactory(resolverFactory, bower) { }); }; - PluginResolver.isTargetable = function () { + PluginResolver.isTargetable = function() { // If resolver doesn't define versions function, it's not targetable.. return typeof resolver.releases === 'function'; }; - PluginResolver.clearRuntimeCache = function () { + PluginResolver.clearRuntimeCache = function() { resolver = resolverFactory(bower); }; - PluginResolver.match = function (source) { + PluginResolver.match = function(source) { if (typeof resolver.match !== 'function') { - throw createError('Resolver is missing "match" method.', 'ERESOLVERAPI'); + throw createError( + 'Resolver is missing "match" method.', + 'ERESOLVERAPI' + ); } var match = resolver.match.bind(resolver); - return Q.fcall(match, source).then(function (result) { + return Q.fcall(match, source).then(function(result) { if (typeof result !== 'boolean') { - throw createError('Resolver\'s "match" method should return a boolean', 'ERESOLVERAPI'); + throw createError( + 'Resolver\'s "match" method should return a boolean', + 'ERESOLVERAPI' + ); } return result; }); }; - PluginResolver.locate = function (source) { + PluginResolver.locate = function(source) { if (typeof resolver.locate !== 'function') { return source; } - return Q.fcall(resolver.locate.bind(resolver), source).then(function (result) { + return Q.fcall(resolver.locate.bind(resolver), source).then(function( + result + ) { if (typeof result !== 'string') { - throw createError('Resolver\'s "locate" method should return a string', 'ERESOLVERAPI'); + throw createError( + 'Resolver\'s "locate" method should return a string', + 'ERESOLVERAPI' + ); } return result; @@ -318,6 +382,4 @@ function pluginResolverFactory(resolverFactory, bower) { return PluginResolver; } - module.exports = pluginResolverFactory; - diff --git a/lib/core/scripts.js b/lib/core/scripts.js index d0e7d42a0..3c0f70db5 100644 --- a/lib/core/scripts.js +++ b/lib/core/scripts.js @@ -3,28 +3,36 @@ var cmd = require('../util/cmd'); var Q = require('q'); var shellquote = require('shell-quote'); -var orderByDependencies = function (packages, installed, json) { +var orderByDependencies = function(packages, installed, json) { var ordered = []; installed = mout.object.keys(installed); - var depsSatisfied = function (packageName) { - return mout.array.difference(mout.object.keys(packages[packageName].dependencies), installed, ordered).length === 0; + var depsSatisfied = function(packageName) { + return ( + mout.array.difference( + mout.object.keys(packages[packageName].dependencies), + installed, + ordered + ).length === 0 + ); }; - var depsFromBowerJson = json && json.dependencies ? mout.object.keys(json.dependencies) : []; + var depsFromBowerJson = + json && json.dependencies ? mout.object.keys(json.dependencies) : []; var packageNames = mout.object.keys(packages); //get the list of the packages that are specified in bower.json in that order //its nice to maintain that order for users var desiredOrder = mout.array.intersection(depsFromBowerJson, packageNames); //then add to the end any remaining packages that werent in bower.json - desiredOrder = desiredOrder.concat(mout.array.difference(packageNames, desiredOrder)); + desiredOrder = desiredOrder.concat( + mout.array.difference(packageNames, desiredOrder) + ); //the desired order isn't necessarily a correct dependency specific order //so we ensure that below var resolvedOne = true; while (resolvedOne) { - resolvedOne = false; for (var i = 0; i < desiredOrder.length; i++) { @@ -43,17 +51,16 @@ var orderByDependencies = function (packages, installed, json) { //so lets just jam those names on the end ordered = ordered.concat(desiredOrder); } - } return ordered; }; -var run = function (cmdString, action, logger, config) { +var run = function(cmdString, action, logger, config) { logger.action(action, cmdString); //pass env + BOWER_PID so callees can identify a preinstall+postinstall from the same bower instance - var env = mout.object.mixIn({ 'BOWER_PID': process.pid }, process.env); + var env = mout.object.mixIn({ BOWER_PID: process.pid }, process.env); var args = shellquote.parse(cmdString, env); var cmdName = args[0]; mout.array.remove(args, cmdName); //no rest() in mout @@ -65,8 +72,8 @@ var run = function (cmdString, action, logger, config) { var promise = cmd(cmdName, args, options); - promise.progress(function (progress) { - progress.split('\n').forEach(function (line) { + promise.progress(function(progress) { + progress.split('\n').forEach(function(line) { if (line) { logger.action(action, line); } @@ -76,14 +83,32 @@ var run = function (cmdString, action, logger, config) { return promise; }; -var hook = function (action, ordered, config, logger, packages, installed, json) { - if (mout.object.keys(packages).length === 0 || !config.scripts || !config.scripts[action]) { +var hook = function( + action, + ordered, + config, + logger, + packages, + installed, + json +) { + if ( + mout.object.keys(packages).length === 0 || + !config.scripts || + !config.scripts[action] + ) { return Q(); } - var orderedPackages = ordered ? orderByDependencies(packages, installed, json) : mout.object.keys(packages); + var orderedPackages = ordered + ? orderByDependencies(packages, installed, json) + : mout.object.keys(packages); var placeholder = new RegExp('%', 'g'); - var cmdString = mout.string.replace(config.scripts[action], placeholder, orderedPackages.join(' ')); + var cmdString = mout.string.replace( + config.scripts[action], + placeholder, + orderedPackages.join(' ') + ); return run(cmdString, action, logger, config); }; diff --git a/lib/renderers/JsonRenderer.js b/lib/renderers/JsonRenderer.js index 460ff9eb1..aa036192d 100644 --- a/lib/renderers/JsonRenderer.js +++ b/lib/renderers/JsonRenderer.js @@ -7,7 +7,7 @@ function JsonRenderer() { this._nrLogs = 0; } -JsonRenderer.prototype.end = function (data) { +JsonRenderer.prototype.end = function(data) { if (this._nrLogs) { process.stderr.write(']\n'); } @@ -17,7 +17,7 @@ JsonRenderer.prototype.end = function (data) { } }; -JsonRenderer.prototype.error = function (err) { +JsonRenderer.prototype.error = function(err) { var message = err.message; var stack; @@ -32,13 +32,13 @@ JsonRenderer.prototype.error = function (err) { // Stack stack = err.fstream_stack || err.stack || 'N/A'; - err.stacktrace = (Array.isArray(stack) ? stack.join('\n') : stack); + err.stacktrace = Array.isArray(stack) ? stack.join('\n') : stack; this.log(err); this.end(); }; -JsonRenderer.prototype.log = function (log) { +JsonRenderer.prototype.log = function(log) { if (!this._nrLogs) { process.stderr.write('['); } else { @@ -49,12 +49,12 @@ JsonRenderer.prototype.log = function (log) { this._nrLogs++; }; -JsonRenderer.prototype.prompt = function (prompts) { +JsonRenderer.prototype.prompt = function(prompts) { var promise = Q.resolve(); var answers = {}; var that = this; - prompts.forEach(function (prompt) { + prompts.forEach(function(prompt) { var opts; var funcName; @@ -63,18 +63,20 @@ JsonRenderer.prototype.prompt = function (prompts) { // Prompt opts = { - silent: true, // To not mess with JSON output - trim: false, // To allow " " to not assume the default value - default: prompt.default == null ? '' : prompt.default, // If default is null, make it '' so that it does not retry - validator: !prompt.validate ? null : function (value) { - var ret = prompt.validate(value); - - if (typeof ret === 'string') { - throw ret; + silent: true, // To not mess with JSON output + trim: false, // To allow " " to not assume the default value + default: prompt.default == null ? '' : prompt.default, // If default is null, make it '' so that it does not retry + validator: !prompt.validate + ? null + : function(value) { + var ret = prompt.validate(value); + + if (typeof ret === 'string') { + throw ret; + } + + return value; } - - return value; - }, }; // For now only "input", "confirm" and "password" are supported @@ -90,38 +92,39 @@ JsonRenderer.prototype.prompt = function (prompts) { funcName = 'prompt'; break; default: - promise = promise.then(function () { + promise = promise.then(function() { throw createError('Unknown prompt type', 'ENOTSUP'); }); return; } - promise = promise.then(function () { + promise = promise.then(function() { // Log prompt.level = 'prompt'; that.log(prompt); - return Q.nfcall(promptly[funcName], '', opts) - .then(function (answer) { + return Q.nfcall(promptly[funcName], '', opts).then(function( + answer + ) { answers[prompt.name] = answer; }); }); if (prompt.type === 'checkbox') { - promise = promise.then(function () { + promise = promise.then(function() { answers[prompt.name] = answers[prompt.name].split(','); }); } }); - return promise.then(function () { + return promise.then(function() { return answers; }); }; // ------------------------- -JsonRenderer.prototype._stringify = function (log) { +JsonRenderer.prototype._stringify = function(log) { // To json var str = JSON.stringify(log, null, ' '); // Remove colors in case some log has colors.. diff --git a/lib/renderers/StandardRenderer.js b/lib/renderers/StandardRenderer.js index 71c4c65be..8641806b8 100644 --- a/lib/renderers/StandardRenderer.js +++ b/lib/renderers/StandardRenderer.js @@ -11,9 +11,9 @@ var template = require('../util/template'); function StandardRenderer(command, config) { this._sizes = { - id: 13, // Id max chars + id: 13, // Id max chars label: 20, // Label max chars - sumup: 5 // Amount to sum when the label exceeds + sumup: 5 // Amount to sum when the label exceeds }; this._colors = { warn: chalk.yellow, @@ -32,7 +32,7 @@ function StandardRenderer(command, config) { this._compact = process.stdout.columns < 120; } - var exitOnPipeError = function (err) { + var exitOnPipeError = function(err) { if (err.code === 'EPIPE') { process.exit(0); } @@ -43,7 +43,7 @@ function StandardRenderer(command, config) { process.stderr.on('error', exitOnPipeError); } -StandardRenderer.prototype.end = function (data) { +StandardRenderer.prototype.end = function(data) { var method = '_' + mout.string.camelCase(this._command); if (this[method]) { @@ -51,7 +51,7 @@ StandardRenderer.prototype.end = function (data) { } }; -StandardRenderer.prototype.error = function (err) { +StandardRenderer.prototype.error = function(err) { var str; var stack; @@ -60,12 +60,19 @@ StandardRenderer.prototype.error = function (err) { err.id = err.code || 'error'; err.level = 'error'; - str = this._prefix(err) + ' ' + err.message.replace(/\r?\n/g, ' ').trim() + '\n'; + str = + this._prefix(err) + + ' ' + + err.message.replace(/\r?\n/g, ' ').trim() + + '\n'; this._write(process.stderr, 'bower ' + str); // Check if additional details were provided if (err.details) { - str = chalk.yellow('\nAdditional error details:\n') + err.details.trim() + '\n'; + str = + chalk.yellow('\nAdditional error details:\n') + + err.details.trim() + + '\n'; this._write(process.stderr, str); } @@ -83,12 +90,18 @@ StandardRenderer.prototype.error = function (err) { // Print bower version, node version and system info. this._write(process.stderr, chalk.yellow('\nSystem info:\n')); this._write(process.stderr, 'Bower version: ' + version + '\n'); - this._write(process.stderr, 'Node version: ' + process.versions.node + '\n'); - this._write(process.stderr, 'OS: ' + os.type() + ' ' + os.release() + ' ' + os.arch() + '\n'); + this._write( + process.stderr, + 'Node version: ' + process.versions.node + '\n' + ); + this._write( + process.stderr, + 'OS: ' + os.type() + ' ' + os.release() + ' ' + os.arch() + '\n' + ); } }; -StandardRenderer.prototype.log = function (log) { +StandardRenderer.prototype.log = function(log) { var method = '_' + mout.string.camelCase(log.id) + 'Log'; this._guessOrigin(log); @@ -101,12 +114,12 @@ StandardRenderer.prototype.log = function (log) { } }; -StandardRenderer.prototype.prompt = function (prompts) { +StandardRenderer.prototype.prompt = function(prompts) { var deferred; // Strip colors from the prompt if color is disabled if (!this._config.color) { - prompts.forEach(function (prompt) { + prompts.forEach(function(prompt) { prompt.message = chalk.stripColor(prompt.message); }); } @@ -121,7 +134,7 @@ StandardRenderer.prototype.prompt = function (prompts) { // ------------------------- -StandardRenderer.prototype._help = function (data) { +StandardRenderer.prototype._help = function(data) { var str; var that = this; var specific; @@ -136,60 +149,68 @@ StandardRenderer.prototype._help = function (data) { if (template.exists(specific)) { str = template.render(specific, data); } else { - str = template.render('std/help-generic.std', data); + str = template.render('std/help-generic.std', data); } that._write(process.stdout, str); } }; -StandardRenderer.prototype._install = function (packages) { +StandardRenderer.prototype._install = function(packages) { var str = ''; - mout.object.forOwn(packages, function (pkg) { - var cliTree; + mout.object.forOwn( + packages, + function(pkg) { + var cliTree; - // List only 1 level deep dependencies - mout.object.forOwn(pkg.dependencies, function (dependency) { - dependency.dependencies = {}; - }); - // Make canonical dir relative - pkg.canonicalDir = path.relative(this._config.cwd, pkg.canonicalDir); - // Signal as root - pkg.root = true; - - cliTree = this._tree2archy(pkg); - str += '\n' + archy(cliTree); - }, this); + // List only 1 level deep dependencies + mout.object.forOwn(pkg.dependencies, function(dependency) { + dependency.dependencies = {}; + }); + // Make canonical dir relative + pkg.canonicalDir = path.relative( + this._config.cwd, + pkg.canonicalDir + ); + // Signal as root + pkg.root = true; + + cliTree = this._tree2archy(pkg); + str += '\n' + archy(cliTree); + }, + this + ); if (str) { this._write(process.stdout, str); } }; -StandardRenderer.prototype._update = function (packages) { +StandardRenderer.prototype._update = function(packages) { this._install(packages); }; -StandardRenderer.prototype._list = function (tree) { +StandardRenderer.prototype._list = function(tree) { var cliTree; if (tree.pkgMeta) { tree.root = true; cliTree = archy(this._tree2archy(tree)); } else { - cliTree = stringifyObject(tree, { indent: ' ' }).replace(/[{}]/g, '') + '\n'; + cliTree = + stringifyObject(tree, { indent: ' ' }).replace(/[{}]/g, '') + '\n'; } this._write(process.stdout, cliTree); }; -StandardRenderer.prototype._search = function (results) { +StandardRenderer.prototype._search = function(results) { var str = template.render('std/search-results.std', results); this._write(process.stdout, str); }; -StandardRenderer.prototype._info = function (data) { +StandardRenderer.prototype._info = function(data) { var str = ''; var pkgMeta = data; var includeVersions = false; @@ -212,7 +233,7 @@ StandardRenderer.prototype._info = function (data) { data.numPreReleases = 0; // If output isn't verbose, hide prereleases if (!this._config.verbose) { - data.versions = mout.array.filter(data.versions, function (version) { + data.versions = mout.array.filter(data.versions, function(version) { version = semverUtils.parse(version); if (!version.release && !version.build) { return true; @@ -227,13 +248,13 @@ StandardRenderer.prototype._info = function (data) { this._write(process.stdout, str); }; -StandardRenderer.prototype._lookup = function (data) { +StandardRenderer.prototype._lookup = function(data) { var str = template.render('std/lookup.std', data); this._write(process.stdout, str); }; -StandardRenderer.prototype._link = function (data) { +StandardRenderer.prototype._link = function(data) { this._sizes.id = 4; this.log({ @@ -248,7 +269,7 @@ StandardRenderer.prototype._link = function (data) { } }; -StandardRenderer.prototype._register = function (data) { +StandardRenderer.prototype._register = function(data) { var str; // If no data passed, it means the user aborted @@ -260,17 +281,20 @@ StandardRenderer.prototype._register = function (data) { this._write(process.stdout, str); }; -StandardRenderer.prototype._cacheList = function (entries) { - entries.forEach(function (entry) { +StandardRenderer.prototype._cacheList = function(entries) { + entries.forEach(function(entry) { var pkgMeta = entry.pkgMeta; var version = pkgMeta.version || pkgMeta._target; - this._write(process.stdout, pkgMeta.name + '=' + pkgMeta._source + '#' + version + '\n'); + this._write( + process.stdout, + pkgMeta.name + '=' + pkgMeta._source + '#' + version + '\n' + ); }, this); }; // ------------------------- -StandardRenderer.prototype._genericLog = function (log) { +StandardRenderer.prototype._genericLog = function(log) { var stream; var str; @@ -284,7 +308,7 @@ StandardRenderer.prototype._genericLog = function (log) { this._write(stream, 'bower ' + str); }; -StandardRenderer.prototype._checkoutLog = function (log) { +StandardRenderer.prototype._checkoutLog = function(log) { if (this._compact) { log.message = log.origin.split('#')[0] + '#' + log.message; } @@ -292,7 +316,7 @@ StandardRenderer.prototype._checkoutLog = function (log) { this._genericLog(log); }; -StandardRenderer.prototype._progressLog = function (log) { +StandardRenderer.prototype._progressLog = function(log) { if (this._compact) { log.message = log.origin + ' ' + log.message; } @@ -300,7 +324,7 @@ StandardRenderer.prototype._progressLog = function (log) { this._genericLog(log); }; -StandardRenderer.prototype._extractLog = function (log) { +StandardRenderer.prototype._extractLog = function(log) { if (this._compact) { log.message = log.origin + ' ' + log.message; } @@ -308,19 +332,23 @@ StandardRenderer.prototype._extractLog = function (log) { this._genericLog(log); }; -StandardRenderer.prototype._incompatibleLog = function (log) { +StandardRenderer.prototype._incompatibleLog = function(log) { var str; var templatePath; // Generate dependants string for each pick - log.data.picks.forEach(function (pick) { - pick.dependants = pick.dependants.map(function (dependant) { - var release = dependant.pkgMeta._release; - return dependant.endpoint.name + (release ? '#' + release : ''); - }).join(', '); + log.data.picks.forEach(function(pick) { + pick.dependants = pick.dependants + .map(function(dependant) { + var release = dependant.pkgMeta._release; + return dependant.endpoint.name + (release ? '#' + release : ''); + }) + .join(', '); }); - templatePath = log.data.suitable ? 'std/conflict-resolved.std' : 'std/conflict.std'; + templatePath = log.data.suitable + ? 'std/conflict-resolved.std' + : 'std/conflict.std'; str = template.render(templatePath, log.data); this._write(process.stdout, '\n'); @@ -328,15 +356,18 @@ StandardRenderer.prototype._incompatibleLog = function (log) { this._write(process.stdout, '\n'); }; -StandardRenderer.prototype._solvedLog = function (log) { +StandardRenderer.prototype._solvedLog = function(log) { this._incompatibleLog(log); }; -StandardRenderer.prototype._jsonLog = function (log) { - this._write(process.stdout, '\n' + this._highlightJson(log.data.json) + '\n\n'); +StandardRenderer.prototype._jsonLog = function(log) { + this._write( + process.stdout, + '\n' + this._highlightJson(log.data.json) + '\n\n' + ); }; -StandardRenderer.prototype._cachedEntryLog = function (log) { +StandardRenderer.prototype._cachedEntryLog = function(log) { if (this._compact) { log.message = log.origin; } @@ -346,7 +377,7 @@ StandardRenderer.prototype._cachedEntryLog = function (log) { // ------------------------- -StandardRenderer.prototype._guessOrigin = function (log) { +StandardRenderer.prototype._guessOrigin = function(log) { var data = log.data; if (!data) { @@ -354,7 +385,8 @@ StandardRenderer.prototype._guessOrigin = function (log) { } if (data.endpoint) { - log.origin = data.endpoint.name || (data.registry && data.endpoint.source); + log.origin = + data.endpoint.name || (data.registry && data.endpoint.source); // Resort to using the resolver name for unnamed endpoints if (!log.origin && data.resolver) { @@ -373,7 +405,7 @@ StandardRenderer.prototype._guessOrigin = function (log) { } }; -StandardRenderer.prototype._prefix = function (log) { +StandardRenderer.prototype._prefix = function(log) { var label; var length; var nrSpaces; @@ -405,7 +437,7 @@ StandardRenderer.prototype._prefix = function (log) { return chalk.green(label) + mout.string.repeat(' ', nrSpaces) + idColor(id); }; -StandardRenderer.prototype._write = function (stream, str) { +StandardRenderer.prototype._write = function(stream, str) { if (!this._config.color) { str = chalk.stripColor(str); } @@ -413,18 +445,18 @@ StandardRenderer.prototype._write = function (stream, str) { stream.write(str); }; -StandardRenderer.prototype._highlightJson = function (json) { +StandardRenderer.prototype._highlightJson = function(json) { var cardinal = require('cardinal'); return cardinal.highlight(stringifyObject(json, { indent: ' ' }), { theme: { String: { - _default: function (str) { + _default: function(str) { return chalk.cyan(str); } }, Identifier: { - _default: function (str) { + _default: function(str) { return chalk.green(str); } } @@ -433,9 +465,11 @@ StandardRenderer.prototype._highlightJson = function (json) { }); }; -StandardRenderer.prototype._tree2archy = function (node) { +StandardRenderer.prototype._tree2archy = function(node) { var dependencies = mout.object.values(node.dependencies); - var version = !node.missing ? node.pkgMeta._release || node.pkgMeta.version : null; + var version = !node.missing + ? node.pkgMeta._release || node.pkgMeta.version + : null; var label = node.endpoint.name + (version ? '#' + version : ''); var update; @@ -458,7 +492,8 @@ StandardRenderer.prototype._tree2archy = function (node) { } if (node.incompatible) { - label += chalk.yellow(' incompatible') + ' with ' + node.endpoint.target; + label += + chalk.yellow(' incompatible') + ' with ' + node.endpoint.target; } else if (node.extraneous) { label += chalk.green(' extraneous'); } @@ -472,7 +507,7 @@ StandardRenderer.prototype._tree2archy = function (node) { } if (node.update.latest !== node.update.target) { - update += (update ? ', ' : ''); + update += update ? ', ' : ''; update += 'latest is ' + node.update.latest; } @@ -500,7 +535,7 @@ StandardRenderer._wideCommands = [ 'register' ]; StandardRenderer._idMappings = { - 'mutual': 'conflict', + mutual: 'conflict', 'cached-entry': 'cached' }; diff --git a/lib/templates/helpers/colors.js b/lib/templates/helpers/colors.js index f9727b433..d197a3824 100644 --- a/lib/templates/helpers/colors.js +++ b/lib/templates/helpers/colors.js @@ -1,17 +1,10 @@ var chalk = require('chalk'); -var templateColors = [ - 'yellow', - 'green', - 'cyan', - 'red', - 'white', - 'magenta' -]; +var templateColors = ['yellow', 'green', 'cyan', 'red', 'white', 'magenta']; function colors(Handlebars) { - templateColors.forEach(function (color) { - Handlebars.registerHelper(color, function (context) { + templateColors.forEach(function(color) { + Handlebars.registerHelper(color, function(context) { return chalk[color](context.fn(this)); }); }); diff --git a/lib/templates/helpers/condense.js b/lib/templates/helpers/condense.js index 3b8d366f1..f37695494 100644 --- a/lib/templates/helpers/condense.js +++ b/lib/templates/helpers/condense.js @@ -1,9 +1,9 @@ var mout = require('mout'); var leadLinesRegExp = /^\r?\n/; -var multipleLinesRegExp = /\r?\n(\r?\n)+/mg; +var multipleLinesRegExp = /\r?\n(\r?\n)+/gm; function condense(Handlebars) { - Handlebars.registerHelper('condense', function (context) { + Handlebars.registerHelper('condense', function(context) { var str = context.fn(this); // Remove multiple lines diff --git a/lib/templates/helpers/indent.js b/lib/templates/helpers/indent.js index 7738f624e..7f42be2d9 100644 --- a/lib/templates/helpers/indent.js +++ b/lib/templates/helpers/indent.js @@ -1,7 +1,7 @@ var mout = require('mout'); function indent(Handlebars) { - Handlebars.registerHelper('indent', function (context) { + Handlebars.registerHelper('indent', function(context) { var hash = context.hash; var indentStr = mout.string.repeat(' ', parseInt(hash.level, 10)); diff --git a/lib/templates/helpers/rpad.js b/lib/templates/helpers/rpad.js index f1aba4f91..86671ba1b 100644 --- a/lib/templates/helpers/rpad.js +++ b/lib/templates/helpers/rpad.js @@ -1,7 +1,7 @@ var mout = require('mout'); function rpad(Handlebars) { - Handlebars.registerHelper('rpad', function (context) { + Handlebars.registerHelper('rpad', function(context) { var hash = context.hash; var minLength = parseInt(hash.minLength, 10); var chr = hash.char; diff --git a/lib/templates/helpers/sum.js b/lib/templates/helpers/sum.js index 62e0b3ce9..5ef6ae306 100644 --- a/lib/templates/helpers/sum.js +++ b/lib/templates/helpers/sum.js @@ -1,5 +1,5 @@ function sum(Handlebars) { - Handlebars.registerHelper('sum', function (val1, val2) { + Handlebars.registerHelper('sum', function(val1, val2) { return val1 + val2; }); } diff --git a/lib/util/abbreviations.js b/lib/util/abbreviations.js index a0b5a938f..fd0304762 100644 --- a/lib/util/abbreviations.js +++ b/lib/util/abbreviations.js @@ -5,7 +5,7 @@ function expandNames(obj, prefix, stack) { prefix = prefix || ''; stack = stack || []; - mout.object.forOwn(obj, function (value, name) { + mout.object.forOwn(obj, function(value, name) { name = prefix + name; stack.push(name); @@ -18,7 +18,7 @@ function expandNames(obj, prefix, stack) { return stack; } -module.exports = function (commands) { +module.exports = function(commands) { var abbreviations = abbrev(expandNames(commands)); abbreviations.i = 'install'; diff --git a/lib/util/cli.js b/lib/util/cli.js index a537c75c7..d9fa57d49 100644 --- a/lib/util/cli.js +++ b/lib/util/cli.js @@ -15,10 +15,10 @@ function readOptions(options, argv) { options = options || {}; } - types = mout.object.map(options, function (option) { + types = mout.object.map(options, function(option) { return option.type; }); - mout.object.forOwn(options, function (option, name) { + mout.object.forOwn(options, function(option, name) { shorthands[option.shorthand] = '--' + name; }); @@ -26,7 +26,7 @@ function readOptions(options, argv) { // Filter only the specified options because nopt parses every -- // Also make them camel case - mout.object.forOwn(noptOptions, function (value, key) { + mout.object.forOwn(noptOptions, function(value, key) { if (options[key]) { parsedOptions[mout.string.camelCase(key)] = value; } diff --git a/lib/util/cmd.js b/lib/util/cmd.js index f2894999e..4dfb929c2 100644 --- a/lib/util/cmd.js +++ b/lib/util/cmd.js @@ -37,17 +37,17 @@ function getWindowsCommand(command) { try { fullCommand = which.sync(command); } catch (err) { - return winWhichCache[command] = command; + return (winWhichCache[command] = command); } extension = path.extname(fullCommand).toLowerCase(); // Does it need to be converted? if (winBatchExtensions.indexOf(extension) === -1) { - return winWhichCache[command] = command; + return (winWhichCache[command] = command); } - return winWhichCache[command] = fullCommand; + return (winWhichCache[command] = fullCommand); } // Executes a shell command, buffering the stdout and stderr @@ -67,25 +67,25 @@ function executeCmd(command, args, options) { // Buffer output, reporting progress process = cp.spawn(command, args, options); - process.stdout.on('data', function (data) { + process.stdout.on('data', function(data) { data = data.toString(); deferred.notify(data); stdout += data; }); - process.stderr.on('data', function (data) { + process.stderr.on('data', function(data) { data = data.toString(); deferred.notify(data); stderr += data; }); // If there is an error spawning the command, reject the promise - process.on('error', function (error) { + process.on('error', function(error) { return deferred.reject(error); }); // Listen to the close event instead of exit // They are similar but close ensures that streams are flushed - process.on('close', function (code) { + process.on('close', function(code) { var fullCommand; var error; @@ -99,10 +99,19 @@ function executeCmd(command, args, options) { fullCommand += args.length ? ' ' + args.join(' ') : ''; // Build the error instance - error = createError('Failed to execute "' + fullCommand + '", exit code of #' + code + '\n' + stderr, 'ECMDERR', { - details: stderr, - exitCode: code - }); + error = createError( + 'Failed to execute "' + + fullCommand + + '", exit code of #' + + code + + '\n' + + stderr, + 'ECMDERR', + { + details: stderr, + exitCode: code + } + ); return deferred.reject(error); } diff --git a/lib/util/copy.js b/lib/util/copy.js index 26a3f3ff5..137151dee 100644 --- a/lib/util/copy.js +++ b/lib/util/copy.js @@ -26,18 +26,17 @@ function copy(reader, writer) { deferred = Q.defer(); reader - .on('error', deferred.reject) - // Pipe to writer - .pipe(fstream.Writer(writer)) - .on('error', deferred.reject) - .on('close', deferred.resolve); + .on('error', deferred.reject) + // Pipe to writer + .pipe(fstream.Writer(writer)) + .on('error', deferred.reject) + .on('close', deferred.resolve); return deferred.promise; } function copyMode(src, dst) { - return Q.nfcall(fs.stat, src) - .then(function (stat) { + return Q.nfcall(fs.stat, src).then(function(stat) { return Q.nfcall(fs.chmod, dst, stat.mode); }); } @@ -68,14 +67,17 @@ function copyFile(src, dst, opts) { opts = parseOptions(opts); - promise = copy({ - path: src, - type: 'File' - }, { - path: dst, - mode: opts.mode, - type: 'File' - }); + promise = copy( + { + path: src, + type: 'File' + }, + { + path: dst, + mode: opts.mode, + type: 'File' + } + ); if (opts.copyMode) { promise = promise.then(copyMode.bind(copyMode, src, dst)); @@ -93,15 +95,18 @@ function copyDir(src, dst, opts) { opts = parseOptions(opts); - promise = copy({ - path: src, - type: 'Directory', - ignore: opts.ignore - }, { - path: dst, - mode: opts.mode, - type: 'Directory' - }); + promise = copy( + { + path: src, + type: 'Directory', + ignore: opts.ignore + }, + { + path: dst, + mode: opts.mode, + type: 'Directory' + } + ); if (opts.copyMode) { promise = promise.then(copyMode.bind(copyMode, src, dst)); diff --git a/lib/util/createLink.js b/lib/util/createLink.js index 838927928..d64f29a35 100644 --- a/lib/util/createLink.js +++ b/lib/util/createLink.js @@ -10,41 +10,55 @@ function createLink(src, dst, type) { var dstDir = path.dirname(dst); // Create directory - return Q.nfcall(mkdirp, dstDir) - // Check if source exists - .then(function () { - return Q.nfcall(fs.stat, src) - .fail(function (error) { - if (error.code === 'ENOENT') { - throw createError('Failed to create link to ' + path.basename(src), 'ENOENT', { - details: src + ' does not exist or points to a non-existent file' - }); - } + return ( + Q.nfcall(mkdirp, dstDir) + // Check if source exists + .then(function() { + return Q.nfcall(fs.stat, src).fail(function(error) { + if (error.code === 'ENOENT') { + throw createError( + 'Failed to create link to ' + path.basename(src), + 'ENOENT', + { + details: + src + + ' does not exist or points to a non-existent file' + } + ); + } - throw error; - }); - }) - // Create symlink - .then(function (stat) { - type = type || (stat.isDirectory() ? 'dir' : 'file'); + throw error; + }); + }) + // Create symlink + .then(function(stat) { + type = type || (stat.isDirectory() ? 'dir' : 'file'); - return Q.nfcall(fs.symlink, src, dst, type) - .fail(function (err) { - if (!isWin || err.code !== 'EPERM') { - throw err; - } + return Q.nfcall(fs.symlink, src, dst, type).fail(function(err) { + if (!isWin || err.code !== 'EPERM') { + throw err; + } - // Try with type "junction" on Windows - // Junctions behave equally to true symlinks and can be created in - // non elevated terminal (well, not always..) - return Q.nfcall(fs.symlink, src, dst, 'junction') - .fail(function (err) { - throw createError('Unable to create link to ' + path.basename(src), err.code, { - details: err.message.trim() + '\n\nTry running this command in an elevated terminal (run as root/administrator).' + // Try with type "junction" on Windows + // Junctions behave equally to true symlinks and can be created in + // non elevated terminal (well, not always..) + return Q.nfcall(fs.symlink, src, dst, 'junction').fail( + function(err) { + throw createError( + 'Unable to create link to ' + + path.basename(src), + err.code, + { + details: + err.message.trim() + + '\n\nTry running this command in an elevated terminal (run as root/administrator).' + } + ); + } + ); }); - }); - }); - }); + }) + ); } module.exports = createLink; diff --git a/lib/util/download.js b/lib/util/download.js index 4b451e892..62172636c 100644 --- a/lib/util/download.js +++ b/lib/util/download.js @@ -20,50 +20,53 @@ function download(url, file, options) { var deferred = Q.defer(); var progressDelay = 8000; - options = mout.object.mixIn({ - retries: 5, - factor: 2, - minTimeout: 1000, - maxTimeout: 35000, - randomize: true, - progressDelay: progressDelay, - gzip: true - }, options || {}); + options = mout.object.mixIn( + { + retries: 5, + factor: 2, + minTimeout: 1000, + maxTimeout: 35000, + randomize: true, + progressDelay: progressDelay, + gzip: true + }, + options || {} + ); // Retry on network errors operation = retry.operation(options); - operation.attempt(function () { + operation.attempt(function() { Q.fcall(fetch, url, file, options) - .then(function (response) { - deferred.resolve(response); - }) - .progress(function (status) { - deferred.notify(status); - }) - .fail(function (error) { - // Save timeout before retrying to report - var timeout = operation._timeouts[0]; - - // Reject if error is not a network error - if (errorCodes.indexOf(error.code) === -1) { - return deferred.reject(error); - } - - // Next attempt will start reporting download progress immediately - progressDelay = 0; - - // This will schedule next retry or return false - if (operation.retry(error)) { - deferred.notify({ - retry: true, - delay: timeout, - error: error - }); - } else { - deferred.reject(error); - } - }); + .then(function(response) { + deferred.resolve(response); + }) + .progress(function(status) { + deferred.notify(status); + }) + .fail(function(error) { + // Save timeout before retrying to report + var timeout = operation._timeouts[0]; + + // Reject if error is not a network error + if (errorCodes.indexOf(error.code) === -1) { + return deferred.reject(error); + } + + // Next attempt will start reporting download progress immediately + progressDelay = 0; + + // This will schedule next retry or return false + if (operation.retry(error)) { + deferred.notify({ + retry: true, + delay: timeout, + error: error + }); + } else { + deferred.reject(error); + } + }); }); return deferred.promise; @@ -75,68 +78,75 @@ function fetch(url, file, options) { var contentLength; var bytesDownloaded = 0; - var reject = function (error) { + var reject = function(error) { deferred.reject(error); }; var req = progress(request(url, options), { delay: options.progressDelay }) - .on('response', function (response) { - contentLength = Number(response.headers['content-length']); - - var status = response.statusCode; - - if (status < 200 || status >= 300) { - return deferred.reject(createError('Status code of ' + status, 'EHTTP')); - } - - var writeStream = createWriteStream(file); - var errored = false; - - // Change error listener so it cleans up writeStream before exiting - req.removeListener('error', reject); - req.on('error', function (error) { - errored = true; - destroy(req); - destroy(writeStream); - - // Wait for writeStream to cleanup after itself... - // TODO: Maybe there's a better way? - setTimeout(function () { - deferred.reject(error); - }, 50); - }); + .on('response', function(response) { + contentLength = Number(response.headers['content-length']); + + var status = response.statusCode; + + if (status < 200 || status >= 300) { + return deferred.reject( + createError('Status code of ' + status, 'EHTTP') + ); + } + + var writeStream = createWriteStream(file); + var errored = false; - writeStream.on('finish', function () { - if (!errored) { + // Change error listener so it cleans up writeStream before exiting + req.removeListener('error', reject); + req.on('error', function(error) { + errored = true; destroy(req); - deferred.resolve(response); + destroy(writeStream); + + // Wait for writeStream to cleanup after itself... + // TODO: Maybe there's a better way? + setTimeout(function() { + deferred.reject(error); + }, 50); + }); + + writeStream.on('finish', function() { + if (!errored) { + destroy(req); + deferred.resolve(response); + } + }); + + req.pipe(writeStream); + }) + .on('data', function(data) { + bytesDownloaded += data.length; + }) + .on('progress', function(state) { + deferred.notify(state); + }) + .on('error', reject) + .on('end', function() { + // Check if the whole file was downloaded + // In some unstable connections the ACK/FIN packet might be sent in the + // middle of the download + // See: https://github.com/joyent/node/issues/6143 + if (contentLength && bytesDownloaded < contentLength) { + req.emit( + 'error', + createError( + 'Transfer closed with ' + + (contentLength - bytesDownloaded) + + ' bytes remaining to read', + 'EINCOMPLETE' + ) + ); } }); - req.pipe(writeStream); - }) - .on('data', function (data) { - bytesDownloaded += data.length; - }) - .on('progress', function (state) { - deferred.notify(state); - }) - .on('error', reject) - .on('end', function () { - // Check if the whole file was downloaded - // In some unstable connections the ACK/FIN packet might be sent in the - // middle of the download - // See: https://github.com/joyent/node/issues/6143 - if (contentLength && bytesDownloaded < contentLength) { - req.emit('error', createError( - 'Transfer closed with ' + (contentLength - bytesDownloaded) + ' bytes remaining to read', - 'EINCOMPLETE' - )); - } - }); - return deferred.promise; } diff --git a/lib/util/extract.js b/lib/util/extract.js index 0c7851b95..7ba285c14 100644 --- a/lib/util/extract.js +++ b/lib/util/extract.js @@ -38,13 +38,13 @@ function extractZip(archive, dst) { var deferred = Q.defer(); new DecompressZip(archive) - .on('error', deferred.reject) - .on('extract', deferred.resolve.bind(deferred, dst)) - .extract({ - path: dst, - follow: false, // Do not follow symlinks (#699) - filter: filterSymlinks // Filter symlink files - }); + .on('error', deferred.reject) + .on('extract', deferred.resolve.bind(deferred, dst)) + .extract({ + path: dst, + follow: false, // Do not follow symlinks (#699) + filter: filterSymlinks // Filter symlink files + }); return deferred.promise; } @@ -54,22 +54,25 @@ function extractTar(archive, dst) { var stream = fs.createReadStream(archive); - var reject = function (error) { + var reject = function(error) { destroy(stream); deferred.reject(error); }; - stream.on('error', reject) - .pipe(tar.extract(dst, { - ignore: isSymlink, // Filter symlink files - dmode: 0555, // Ensure dirs are readable - fmode: 0444 // Ensure files are readable - })) - .on('error', reject) - .on('finish', function (result) { - destroy(stream); - deferred.resolve(dst); - }); + stream + .on('error', reject) + .pipe( + tar.extract(dst, { + ignore: isSymlink, // Filter symlink files + dmode: 0555, // Ensure dirs are readable + fmode: 0444 // Ensure files are readable + }) + ) + .on('error', reject) + .on('finish', function(result) { + destroy(stream); + deferred.resolve(dst); + }); return deferred.promise; } @@ -79,24 +82,27 @@ function extractTarGz(archive, dst) { var stream = fs.createReadStream(archive); - var reject = function (error) { + var reject = function(error) { destroy(stream); deferred.reject(error); }; - stream.on('error', reject) - .pipe(zlib.createGunzip()) - .on('error', reject) - .pipe(tar.extract(dst, { - ignore: isSymlink, // Filter symlink files - dmode: 0555, // Ensure dirs are readable - fmode: 0444 // Ensure files are readable - })) - .on('error', reject) - .on('finish', function (result) { - destroy(stream); - deferred.resolve(dst); - }); + stream + .on('error', reject) + .pipe(zlib.createGunzip()) + .on('error', reject) + .pipe( + tar.extract(dst, { + ignore: isSymlink, // Filter symlink files + dmode: 0555, // Ensure dirs are readable + fmode: 0444 // Ensure files are readable + }) + ) + .on('error', reject) + .on('finish', function(result) { + destroy(stream); + deferred.resolve(dst); + }); return deferred.promise; } @@ -106,19 +112,20 @@ function extractGz(archive, dst) { var stream = fs.createReadStream(archive); - var reject = function (error) { + var reject = function(error) { destroy(stream); deferred.reject(error); }; - stream.on('error', reject) - .pipe(zlib.createGunzip()) - .on('error', reject) - .pipe(createWriteStream(dst)) - .on('error', reject) - .on('finish', function (result) { - destroy(stream); - deferred.resolve(dst); - }); + stream + .on('error', reject) + .pipe(zlib.createGunzip()) + .on('error', reject) + .pipe(createWriteStream(dst)) + .on('error', reject) + .on('finish', function(result) { + destroy(stream); + deferred.resolve(dst); + }); return deferred.promise; } @@ -136,7 +143,7 @@ function getExtractor(archive) { // This ensures that upper-cased extensions work archive = archive.toLowerCase(); - var type = mout.array.find(extractorTypes, function (type) { + var type = mout.array.find(extractorTypes, function(type) { return mout.string.endsWith(archive, type); }); @@ -144,8 +151,7 @@ function getExtractor(archive) { } function isSingleDir(dir) { - return Q.nfcall(fs.readdir, dir) - .then(function (files) { + return Q.nfcall(fs.readdir, dir).then(function(files) { var singleDir; // Remove any OS specific files from the files array @@ -158,8 +164,7 @@ function isSingleDir(dir) { singleDir = path.join(dir, files[0]); - return Q.nfcall(fs.stat, singleDir) - .then(function (stat) { + return Q.nfcall(fs.stat, singleDir).then(function(stat) { return stat.isDirectory() ? singleDir : false; }); }); @@ -167,19 +172,19 @@ function isSingleDir(dir) { function moveDirectory(srcDir, destDir) { return Q.nfcall(fs.readdir, srcDir) - .then(function (files) { - var promises = files.map(function (file) { - var src = path.join(srcDir, file); - var dst = path.join(destDir, file); + .then(function(files) { + var promises = files.map(function(file) { + var src = path.join(srcDir, file); + var dst = path.join(destDir, file); - return Q.nfcall(fs.rename, src, dst); - }); + return Q.nfcall(fs.rename, src, dst); + }); - return Q.all(promises); - }) - .then(function () { - return Q.nfcall(fs.rmdir, srcDir); - }); + return Q.all(promises); + }) + .then(function() { + return Q.nfcall(fs.rmdir, srcDir); + }); } // ----------------------------- @@ -209,57 +214,64 @@ function extract(src, dst, opts) { // If extractor is null, then the archive type is unknown if (!extractor) { - return Q.reject(createError('File ' + src + ' is not a known archive', 'ENOTARCHIVE')); + return Q.reject( + createError( + 'File ' + src + ' is not a known archive', + 'ENOTARCHIVE' + ) + ); } // Extract to a temporary directory in case of file name clashes return Q.nfcall(tmp.dir, { template: dst + '-XXXXXX', mode: 0777 & ~process.umask() - }).then(function (tempDir) { - // nfcall may return multiple callback arguments as an array - return Array.isArray(tempDir) ? tempDir[0] : tempDir; - }).then(function (tempDir) { - - // Check archive file size - promise = Q.nfcall(fs.stat, src) - .then(function (stat) { - if (stat.size <= 8) { - throw createError('File ' + src + ' is an invalid archive', 'ENOTARCHIVE'); - } - - // Extract archive - return extractor(src, tempDir); - }); - - // Remove archive - if (!opts.keepArchive) { - promise = promise - .then(function () { - return Q.nfcall(fs.unlink, src); + }) + .then(function(tempDir) { + // nfcall may return multiple callback arguments as an array + return Array.isArray(tempDir) ? tempDir[0] : tempDir; + }) + .then(function(tempDir) { + // Check archive file size + promise = Q.nfcall(fs.stat, src).then(function(stat) { + if (stat.size <= 8) { + throw createError( + 'File ' + src + ' is an invalid archive', + 'ENOTARCHIVE' + ); + } + + // Extract archive + return extractor(src, tempDir); }); - } - // Move contents from the temporary directory - // If the contents are a single directory (and we're not preserving structure), - // move its contents directly instead. - promise = promise - .then(function () { - return isSingleDir(tempDir); - }) - .then(function (singleDir) { - if (singleDir && !opts.keepStructure) { - return moveDirectory(singleDir, dst); - } else { - return moveDirectory(tempDir, dst); + // Remove archive + if (!opts.keepArchive) { + promise = promise.then(function() { + return Q.nfcall(fs.unlink, src); + }); } - }); - // Resolve promise to the dst dir - return promise.then(function () { - return dst; + // Move contents from the temporary directory + // If the contents are a single directory (and we're not preserving structure), + // move its contents directly instead. + promise = promise + .then(function() { + return isSingleDir(tempDir); + }) + .then(function(singleDir) { + if (singleDir && !opts.keepStructure) { + return moveDirectory(singleDir, dst); + } else { + return moveDirectory(tempDir, dst); + } + }); + + // Resolve promise to the dst dir + return promise.then(function() { + return dst; + }); }); - }); } module.exports = extract; diff --git a/lib/util/fs.js b/lib/util/fs.js index 5fd35177a..1d98f420c 100644 --- a/lib/util/fs.js +++ b/lib/util/fs.js @@ -5,14 +5,14 @@ var readdirSync = fs.readdirSync.bind(fs); module.exports = fs; -module.exports.readdir = function (dir, callback) { - fs.stat(dir, function (err, stats) { +module.exports.readdir = function(dir, callback) { + fs.stat(dir, function(err, stats) { if (err) return callback(err); if (stats.isDirectory()) { return readdir(dir, callback); } else { - var error = new Error('ENOTDIR, not a directory \'' + dir + '\''); + var error = new Error("ENOTDIR, not a directory '" + dir + "'"); error.code = 'ENOTDIR'; error.path = dir; error.errono = -20; @@ -21,7 +21,7 @@ module.exports.readdir = function (dir, callback) { }); }; -module.exports.readdirSync = function (dir) { +module.exports.readdirSync = function(dir) { var stats = fs.statSync(dir); if (stats.isDirectory()) { diff --git a/lib/util/readJson.js b/lib/util/readJson.js index 4b3d51fb8..82876e193 100644 --- a/lib/util/readJson.js +++ b/lib/util/readJson.js @@ -13,41 +13,43 @@ function readJson(file, options) { options = options || {}; // Read - return Q.nfcall(bowerJson.read, file, options) - .spread(function (json, jsonFile) { - var deprecated; - - if (options.logger) { - var issues = bowerJson.getIssues(json); - if (issues.warnings.length > 0) { - options.logger.warn('invalid-meta', 'for:' + jsonFile); + return Q.nfcall(bowerJson.read, file, options).spread( + function(json, jsonFile) { + var deprecated; + + if (options.logger) { + var issues = bowerJson.getIssues(json); + if (issues.warnings.length > 0) { + options.logger.warn('invalid-meta', 'for:' + jsonFile); + } + issues.warnings.forEach(function(warning) { + options.logger.warn('invalid-meta', warning); + }); } - issues.warnings.forEach(function (warning) { - options.logger.warn('invalid-meta', warning); - }); - } - jsonFile = path.basename(jsonFile); - deprecated = jsonFile === 'component.json' ? jsonFile : false; + jsonFile = path.basename(jsonFile); + deprecated = jsonFile === 'component.json' ? jsonFile : false; - return [json, deprecated, false]; - }, function (err) { - // No json file was found, assume one - if (err.code === 'ENOENT' && options.assume) { - return [bowerJson.parse(options.assume, options), false, true]; - } + return [json, deprecated, false]; + }, + function(err) { + // No json file was found, assume one + if (err.code === 'ENOENT' && options.assume) { + return [bowerJson.parse(options.assume, options), false, true]; + } - err.details = err.message; + err.details = err.message; - if (err.file) { - err.message = 'Failed to read ' + err.file; - err.data = { filename: err.file }; - } else { - err.message = 'Failed to read json from ' + file; - } + if (err.file) { + err.message = 'Failed to read ' + err.file; + err.data = { filename: err.file }; + } else { + err.message = 'Failed to read json from ' + file; + } - throw err; - }); + throw err; + } + ); } module.exports = readJson; diff --git a/lib/util/relativeToBaseDir.js b/lib/util/relativeToBaseDir.js index 450c2e32d..f3deffd37 100644 --- a/lib/util/relativeToBaseDir.js +++ b/lib/util/relativeToBaseDir.js @@ -2,7 +2,7 @@ var path = require('path'); var isPathAbsolute = require('./isPathAbsolute'); function relativeToBaseDir(baseDir) { - return function (filePath) { + return function(filePath) { if (isPathAbsolute(filePath)) { return path.resolve(filePath); } else { diff --git a/lib/util/removeIgnores.js b/lib/util/removeIgnores.js index eaa5b80f0..42bcf25fc 100644 --- a/lib/util/removeIgnores.js +++ b/lib/util/removeIgnores.js @@ -14,7 +14,7 @@ function removeIgnores(dir, meta) { // Don't ignore main files nonIgnored = nonIgnored.concat(meta.main || []); - nonIgnored = nonIgnored.map(function (file) { + nonIgnored = nonIgnored.map(function(file) { return path.join(dir, file); }); @@ -27,7 +27,7 @@ function removeIgnores(dir, meta) { // Monkey patch applyIgnores such that we get hold of all ignored files applyIgnores = reader.applyIgnores; - reader.applyIgnores = function (entry) { + reader.applyIgnores = function(entry) { var ret = applyIgnores.apply(this, arguments); if (!ret) { @@ -38,27 +38,26 @@ function removeIgnores(dir, meta) { }; reader - .on('child', function (entry) { - nonIgnored.push(entry.path); - }) - .on('error', deferred.reject) - .on('end', function () { - var promises; + .on('child', function(entry) { + nonIgnored.push(entry.path); + }) + .on('error', deferred.reject) + .on('end', function() { + var promises; - // Ensure that we are not ignoring files that should not be ignored! - ignored = mout.array.unique(ignored); - ignored = ignored.filter(function (file) { - return nonIgnored.indexOf(file) === -1; - }); + // Ensure that we are not ignoring files that should not be ignored! + ignored = mout.array.unique(ignored); + ignored = ignored.filter(function(file) { + return nonIgnored.indexOf(file) === -1; + }); - // Delete all the ignored files - promises = ignored.map(function (file) { - return Q.nfcall(rimraf, file); - }); + // Delete all the ignored files + promises = ignored.map(function(file) { + return Q.nfcall(rimraf, file); + }); - return Q.all(promises) - .then(deferred.resolve, deferred.reject); - }); + return Q.all(promises).then(deferred.resolve, deferred.reject); + }); return deferred.promise; } diff --git a/lib/util/resolve.js b/lib/util/resolve.js index 5924d85d7..78431936c 100644 --- a/lib/util/resolve.js +++ b/lib/util/resolve.js @@ -4,9 +4,9 @@ var resolve = require('resolve'); function startsWith(string, searchString, position) { position = position || 0; return string.substr(position, searchString.length) === searchString; -}; +} -module.exports = function (id, options) { +module.exports = function(id, options) { var resolvedPath; var cwd = (options || {}).cwd || process.cwd(); @@ -19,4 +19,4 @@ module.exports = function (id, options) { } return resolvedPath; -} +}; diff --git a/lib/util/rimraf.js b/lib/util/rimraf.js index 6fa8e8687..d79fdab1b 100644 --- a/lib/util/rimraf.js +++ b/lib/util/rimraf.js @@ -2,15 +2,15 @@ var rimraf = require('rimraf'); var chmodr = require('chmodr'); var fs = require('./fs'); -module.exports = function (dir, callback) { - var checkAndRetry = function (e) { - fs.lstat(dir, function (err, stats) { +module.exports = function(dir, callback) { + var checkAndRetry = function(e) { + fs.lstat(dir, function(err, stats) { if (err) { if (err.code === 'ENOENT') return callback(); return callback(e); } - chmodr(dir, 0777, function (err) { + chmodr(dir, 0777, function(err) { if (err) return callback(e); rimraf(dir, callback); }); @@ -24,8 +24,8 @@ module.exports = function (dir, callback) { } }; -module.exports.sync = function (dir) { - var checkAndRetry = function () { +module.exports.sync = function(dir) { + var checkAndRetry = function() { try { fs.lstatSync(dir); chmodr.sync(dir, 0777); diff --git a/lib/util/rootCheck.js b/lib/util/rootCheck.js index b391ea965..fd10f7c8b 100644 --- a/lib/util/rootCheck.js +++ b/lib/util/rootCheck.js @@ -1,4 +1,3 @@ -'use strict'; var isRoot = require('is-root'); var createError = require('./createError'); @@ -12,7 +11,8 @@ function rootCheck(options, config) { return; } - errorMsg = 'Since bower is a user command, there is no need to execute it with \ + errorMsg = + 'Since bower is a user command, there is no need to execute it with \ superuser permissions.\nIf you\'re having permission errors when using bower without \ sudo, please spend a few minutes learning more about how your system should work and \ make any necessary repairs.\n\n\ @@ -23,7 +23,11 @@ You can however run a command with sudo using "--allow-root" option'; if (isRoot()) { var cli = require('./cli'); renderer = cli.getRenderer('', false, config); - renderer.error(createError('Cannot be run with sudo', 'ESUDO', { details : errorMsg })); + renderer.error( + createError('Cannot be run with sudo', 'ESUDO', { + details: errorMsg + }) + ); process.exit(1); } } diff --git a/lib/util/semver.js b/lib/util/semver.js index d0a195357..39970805e 100644 --- a/lib/util/semver.js +++ b/lib/util/semver.js @@ -6,13 +6,13 @@ function maxSatisfying(versions, range, strictMatch) { var filteredVersions; // Filter only valid versions, since semver.maxSatisfying() throws an error - versions = versions.filter(function (version) { + versions = versions.filter(function(version) { return semver.valid(version); }); // Exact version & range match if (semver.valid(range)) { - version = mout.array.find(versions, function (version) { + version = mout.array.find(versions, function(version) { return version === range; }); if (version) { @@ -25,7 +25,7 @@ function maxSatisfying(versions, range, strictMatch) { // When strict match is enabled give priority to non-pre-releases // We do this by filtering every pre-release version if (strictMatch) { - filteredVersions = versions.map(function (version) { + filteredVersions = versions.map(function(version) { return !isPreRelease(version) ? version : null; }); @@ -57,7 +57,10 @@ function clean(version) { } // Keep builds! - return parsed.version + (parsed.build.length ? '+' + parsed.build.join('.') : ''); + return ( + parsed.version + + (parsed.build.length ? '+' + parsed.build.join('.') : '') + ); } function isPreRelease(version) { diff --git a/lib/util/template.js b/lib/util/template.js index 23fe1310c..a163667dc 100644 --- a/lib/util/template.js +++ b/lib/util/template.js @@ -8,7 +8,7 @@ var templatesDir = path.resolve(__dirname, '../templates'); var cache = {}; // Register helpers -mout.object.forOwn(helpers, function (register) { +mout.object.forOwn(helpers, function(register) { register(Handlebars); }); diff --git a/lib/util/userAgent.js b/lib/util/userAgent.js index 3400b5bab..9cf47edb7 100644 --- a/lib/util/userAgent.js +++ b/lib/util/userAgent.js @@ -1,3 +1,12 @@ var version = require('../version'); -module.exports = 'node/' + process.version + ' ' + process.platform + ' ' + process.arch + ' ' + ';Bower ' + version; +module.exports = + 'node/' + + process.version + + ' ' + + process.platform + + ' ' + + process.arch + + ' ' + + ';Bower ' + + version; diff --git a/lib/util/validLink.js b/lib/util/validLink.js index b367a3c05..07dc1dcda 100644 --- a/lib/util/validLink.js +++ b/lib/util/validLink.js @@ -5,20 +5,18 @@ function validLink(file) { // Ensures that a file is a symlink that points // to a valid file return Q.nfcall(fs.lstat, file) - .then(function (lstat) { - if (!lstat.isSymbolicLink()) { - return [false]; - } + .then(function(lstat) { + if (!lstat.isSymbolicLink()) { + return [false]; + } - return Q.nfcall(fs.stat, file) - .then(function (stat) { - return [stat]; + return Q.nfcall(fs.stat, file).then(function(stat) { + return [stat]; + }); + }) + .fail(function(err) { + return [false, err]; }); - }) - .fail(function (err) { - return [false, err]; - }); } module.exports = validLink; - diff --git a/package.json b/package.json index 7284231fb..984c33bdd 100644 --- a/package.json +++ b/package.json @@ -76,13 +76,16 @@ "grunt-eslint": "^18.1.0", "grunt-exec": "^0.4.7", "grunt-simple-mocha": "^0.4.1", + "husky": "^0.14.3", "in-publish": "^2.0.0", "istanbul": "^0.4.3", + "lint-staged": "^7.0.0", "load-grunt-tasks": "^3.5.0", "mocha": "^2.5.3", "multiline": "^1.0.2", "nock": "^9.2.3", "node-uuid": "^1.4.7", + "prettier": "^1.11.1", "proxyquire": "^1.7.9", "spawn-sync": "1.0.15", "wrench": "^1.5.8" @@ -91,7 +94,15 @@ "test": "grunt test", "ci": "grunt travis", "coveralls": "coveralls", - "prepublish": "in-publish && echo 'You need to use \"grunt publish\" to publish bower' && false || not-in-publish" + "prepublish": "in-publish && echo 'You need to use \"grunt publish\" to publish bower' && false || not-in-publish", + "format": "prettier --write --single-quote --tab-width 4 '**/*.js'", + "precommit": "lint-staged && npm test" + }, + "lint-staged": { + "*.js": [ + "prettier --single-quote --tab-width 4", + "git add" + ] }, "files": [ "bin", diff --git a/packages/bower-config/Gruntfile.js b/packages/bower-config/Gruntfile.js index 018ecd5d0..a8a94305a 100644 --- a/packages/bower-config/Gruntfile.js +++ b/packages/bower-config/Gruntfile.js @@ -1,5 +1,4 @@ -'use strict'; -module.exports = function (grunt) { +module.exports = function(grunt) { require('load-grunt-tasks')(grunt); grunt.initConfig({ @@ -34,10 +33,12 @@ module.exports = function (grunt) { }, exec: { cover: { - command: 'STRICT_REQUIRE=1 node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' + command: + 'STRICT_REQUIRE=1 node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' }, coveralls: { - command: 'node node_modules/.bin/coveralls < test/reports/lcov.info' + command: + 'node node_modules/.bin/coveralls < test/reports/lcov.info' } }, watch: { diff --git a/packages/bower-config/lib/Config.js b/packages/bower-config/lib/Config.js index 470ddfd4b..dbb013b66 100644 --- a/packages/bower-config/lib/Config.js +++ b/packages/bower-config/lib/Config.js @@ -12,12 +12,12 @@ function Config(cwd) { this._config = {}; } -Config.prototype.load = function (overwrites) { +Config.prototype.load = function(overwrites) { this._config = rc('bower', this._cwd); this._config = object.merge( - expand(this._config || {}), - expand(overwrites || {}) + expand(this._config || {}), + expand(overwrites || {}) ); this._config = normalise(this._config); @@ -27,8 +27,8 @@ Config.prototype.load = function (overwrites) { return this; }; -Config.prototype.restore = function () { - this._proxy.restore(); +Config.prototype.restore = function() { + this._proxy.restore(); }; function readCertFile(path) { @@ -44,10 +44,14 @@ function readCertFile(path) { certificates = path; } - return certificates. - split(sep). - filter(function(s) { return !s.match(/^\s*$/); }). - map(function(s) { return s + sep; }); + return certificates + .split(sep) + .filter(function(s) { + return !s.match(/^\s*$/); + }) + .map(function(s) { + return s + sep; + }); } function loadCAs(caConfig) { @@ -68,15 +72,15 @@ function loadCAs(caConfig) { } } -Config.prototype.toObject = function () { +Config.prototype.toObject = function() { return lang.deepClone(this._config); }; -Config.create = function (cwd) { +Config.create = function(cwd) { return new Config(cwd); }; -Config.read = function (cwd, overrides) { +Config.read = function(cwd, overrides) { var config = Config.create(cwd); return config.load(overrides).toObject(); }; @@ -86,13 +90,13 @@ function normalise(config) { // Some backwards compatible things.. if (config.shorthandResolver) { - config.shorthandResolver = config.shorthandResolver - .replace(/\{\{\{/g, '{{') - .replace(/\}\}\}/g, '}}'); + config.shorthandResolver = config.shorthandResolver + .replace(/\{\{\{/g, '{{') + .replace(/\}\}\}/g, '}}'); } // Ensure that every registry endpoint does not end with / - config.registry.search = config.registry.search.map(function (url) { + config.registry.search = config.registry.search.map(function(url) { return url.replace(/\/+$/, ''); }); config.registry.register = config.registry.register.replace(/\/+$/, ''); diff --git a/packages/bower-config/lib/util/defaults.js b/packages/bower-config/lib/util/defaults.js index 3d58502d4..ae3c88ade 100644 --- a/packages/bower-config/lib/util/defaults.js +++ b/packages/bower-config/lib/util/defaults.js @@ -2,43 +2,44 @@ var path = require('path'); var paths = require('./paths'); // Guess proxy defined in the env -var proxy = process.env.HTTP_PROXY - || process.env.http_proxy - || null; +var proxy = process.env.HTTP_PROXY || process.env.http_proxy || null; -var httpsProxy = process.env.HTTPS_PROXY - || process.env.https_proxy - || proxy; +var httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy || proxy; -var noProxy = process.env.NO_PROXY - || process.env.no_proxy; +var noProxy = process.env.NO_PROXY || process.env.no_proxy; // Use a well known user agent (in this case, curl) when using a proxy, // to avoid potential filtering on many corporate proxies with blank or unknown agents -var userAgent = !proxy && !httpsProxy - ? 'node/' + process.version + ' ' + process.platform + ' ' + process.arch - : 'curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5'; +var userAgent = + !proxy && !httpsProxy + ? 'node/' + + process.version + + ' ' + + process.platform + + ' ' + + process.arch + : 'curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5'; var defaults = { - 'directory': 'bower_components', - 'registry': 'https://registry.bower.io', + directory: 'bower_components', + registry: 'https://registry.bower.io', 'shorthand-resolver': 'https://github.com/{{owner}}/{{package}}.git', - 'tmp': paths.tmp, - 'proxy': proxy, + tmp: paths.tmp, + proxy: proxy, 'https-proxy': httpsProxy, 'no-proxy': noProxy, - 'timeout': 30000, - 'ca': { search: [] }, + timeout: 30000, + ca: { search: [] }, 'strict-ssl': true, 'user-agent': userAgent, - 'color': true, - 'interactive': null, - 'storage': { + color: true, + interactive: null, + storage: { packages: path.join(paths.cache, 'packages'), links: path.join(paths.data, 'links'), completion: path.join(paths.data, 'completion'), registry: path.join(paths.cache, 'registry'), - empty: path.join(paths.data, 'empty') // Empty dir, used in GIT_TEMPLATE_DIR among others + empty: path.join(paths.data, 'empty') // Empty dir, used in GIT_TEMPLATE_DIR among others } }; diff --git a/packages/bower-config/lib/util/expand.js b/packages/bower-config/lib/util/expand.js index 303fadef2..a4e50baba 100644 --- a/packages/bower-config/lib/util/expand.js +++ b/packages/bower-config/lib/util/expand.js @@ -6,7 +6,7 @@ function camelCase(config) { var camelCased = {}; // Camel case - object.forOwn(config, function (value, key) { + object.forOwn(config, function(value, key) { // Ignore null values if (value == null) { return; @@ -22,33 +22,33 @@ function camelCase(config) { // Function to replace ${VAR} - style variables // with values set in the environment // This function expects to be passed a string -function doEnvReplaceStr (f) { - - // Un-tildify - var untildify = require('untildify'); - f = untildify(f); - - // replace any ${ENV} values with the appropriate environ. - var envExpr = /(\\*)\$\{([^}]+)\}/g; - return f.replace(envExpr, function (orig, esc, name) { - esc = esc.length && esc.length % 2; - if (esc) return orig; - if (undefined === process.env[name]) { - throw new Error('Environment variable used in .bowerrc is not defined: ' + orig); - } +function doEnvReplaceStr(f) { + // Un-tildify + var untildify = require('untildify'); + f = untildify(f); + + // replace any ${ENV} values with the appropriate environ. + var envExpr = /(\\*)\$\{([^}]+)\}/g; + return f.replace(envExpr, function(orig, esc, name) { + esc = esc.length && esc.length % 2; + if (esc) return orig; + if (undefined === process.env[name]) { + throw new Error( + 'Environment variable used in .bowerrc is not defined: ' + orig + ); + } - return process.env[name]; -}); + return process.env[name]; + }); } function envReplace(config) { var envReplaced = {}; - if ( lang.isArray(config) ) { + if (lang.isArray(config)) { envReplaced = []; } - object.forOwn(config, function (value, key) { - + object.forOwn(config, function(value, key) { // Ignore null values if (value == null) { return; @@ -57,22 +57,19 @@ function envReplace(config) { // Ignore 'scripts' // These hooks run within the shell // environment variable expansion is not required - if ( key === 'scripts' && lang.isPlainObject(value) ){ + if (key === 'scripts' && lang.isPlainObject(value)) { envReplaced[key] = value; return; } // Perform variable replacements based on var type - if ( lang.isPlainObject(value) ) { + if (lang.isPlainObject(value)) { envReplaced[key] = envReplace(value); - } - else if ( lang.isArray(value) ) { + } else if (lang.isArray(value)) { envReplaced[key] = envReplace(value); - } - else if ( lang.isString(value) ) { + } else if (lang.isString(value)) { envReplaced[key] = doEnvReplaceStr(value); - } - else { + } else { envReplaced[key] = value; } }); @@ -92,7 +89,8 @@ function expand(config) { publish: config.registry }; } else if (typeof config.registry === 'object') { - config.registry.default = config.registry.default || 'https://registry.bower.io'; + config.registry.default = + config.registry.default || 'https://registry.bower.io'; config.registry = { default: config.registry.default, diff --git a/packages/bower-config/lib/util/paths.js b/packages/bower-config/lib/util/paths.js index d1eddf080..f8b78b0f8 100644 --- a/packages/bower-config/lib/util/paths.js +++ b/packages/bower-config/lib/util/paths.js @@ -4,8 +4,16 @@ var osenv = require('osenv'); var crypto = require('crypto'); function generateFakeUser() { - var uid = process.pid + '-' + Date.now() + '-' + Math.floor(Math.random() * 1000000); - return crypto.createHash('md5').update(uid).digest('hex'); + var uid = + process.pid + + '-' + + Date.now() + + '-' + + Math.floor(Math.random() * 1000000); + return crypto + .createHash('md5') + .update(uid) + .digest('hex'); } // Assume XDG defaults @@ -30,7 +38,7 @@ if (process.platform === 'win32') { paths.config = paths.config || path.join(base, 'config'); paths.data = paths.data || path.join(base, 'data'); paths.cache = paths.cache || path.join(base, 'cache'); -// Fallbacks for other operating systems + // Fallbacks for other operating systems } else { base = path.resolve(home || tmp); diff --git a/packages/bower-config/lib/util/proxy.js b/packages/bower-config/lib/util/proxy.js index 1dcdc4e2a..e65449cf4 100644 --- a/packages/bower-config/lib/util/proxy.js +++ b/packages/bower-config/lib/util/proxy.js @@ -2,78 +2,78 @@ // process.env uppercase proxy variables to them with the ability // to restore the original values later var EnvProxy = function() { - this.restoreFrom = {}; + this.restoreFrom = {}; }; -EnvProxy.prototype.set = function (config) { - this.config = config; +EnvProxy.prototype.set = function(config) { + this.config = config; - // Override environment defaults if proxy config options are set - // This will make requests.js follow the proxies in config - if (Object.prototype.hasOwnProperty.call(config, 'noProxy')) { - this.restoreFrom.NO_PROXY = process.env.NO_PROXY; - this.restoreFrom.no_proxy = process.env.no_proxy; - delete process.env.no_proxy; - process.env.NO_PROXY = config.noProxy; - } + // Override environment defaults if proxy config options are set + // This will make requests.js follow the proxies in config + if (Object.prototype.hasOwnProperty.call(config, 'noProxy')) { + this.restoreFrom.NO_PROXY = process.env.NO_PROXY; + this.restoreFrom.no_proxy = process.env.no_proxy; + delete process.env.no_proxy; + process.env.NO_PROXY = config.noProxy; + } - if (Object.prototype.hasOwnProperty.call(config, 'proxy')) { - this.restoreFrom.HTTP_PROXY = process.env.HTTP_PROXY; - this.restoreFrom.http_proxy = process.env.http_proxy; - delete process.env.http_proxy; - process.env.HTTP_PROXY = config.proxy; - } + if (Object.prototype.hasOwnProperty.call(config, 'proxy')) { + this.restoreFrom.HTTP_PROXY = process.env.HTTP_PROXY; + this.restoreFrom.http_proxy = process.env.http_proxy; + delete process.env.http_proxy; + process.env.HTTP_PROXY = config.proxy; + } - if (Object.prototype.hasOwnProperty.call(config, 'httpsProxy')) { - this.restoreFrom.HTTPS_PROXY = process.env.HTTPS_PROXY; - this.restoreFrom.https_proxy = process.env.https_proxy; - delete process.env.https_proxy; - process.env.HTTPS_PROXY = config.httpsProxy; - } + if (Object.prototype.hasOwnProperty.call(config, 'httpsProxy')) { + this.restoreFrom.HTTPS_PROXY = process.env.HTTPS_PROXY; + this.restoreFrom.https_proxy = process.env.https_proxy; + delete process.env.https_proxy; + process.env.HTTPS_PROXY = config.httpsProxy; + } }; -EnvProxy.prototype.restore = function () { - if (Object.prototype.hasOwnProperty.call(this.config, 'noProxy')) { - if (this.restoreFrom.NO_PROXY !== undefined) { - process.env.NO_PROXY = this.restoreFrom.NO_PROXY; - } else { - delete process.env.NO_PROXY; - } +EnvProxy.prototype.restore = function() { + if (Object.prototype.hasOwnProperty.call(this.config, 'noProxy')) { + if (this.restoreFrom.NO_PROXY !== undefined) { + process.env.NO_PROXY = this.restoreFrom.NO_PROXY; + } else { + delete process.env.NO_PROXY; + } - if (this.restoreFrom.no_proxy !== undefined) { - process.env.no_proxy = this.restoreFrom.no_proxy; - } else { - delete process.env.no_proxy; + if (this.restoreFrom.no_proxy !== undefined) { + process.env.no_proxy = this.restoreFrom.no_proxy; + } else { + delete process.env.no_proxy; + } } - } - if (Object.prototype.hasOwnProperty.call(this.config, 'proxy')) { - if (this.restoreFrom.HTTP_PROXY !== undefined) { - process.env.HTTP_PROXY = this.restoreFrom.HTTP_PROXY; - } else { - delete process.env.HTTP_PROXY; - } + if (Object.prototype.hasOwnProperty.call(this.config, 'proxy')) { + if (this.restoreFrom.HTTP_PROXY !== undefined) { + process.env.HTTP_PROXY = this.restoreFrom.HTTP_PROXY; + } else { + delete process.env.HTTP_PROXY; + } - if (this.restoreFrom.http_proxy !== undefined) { - process.env.http_proxy = this.restoreFrom.http_proxy; - } else { - delete process.env.http_proxy; + if (this.restoreFrom.http_proxy !== undefined) { + process.env.http_proxy = this.restoreFrom.http_proxy; + } else { + delete process.env.http_proxy; + } } - } - if (Object.prototype.hasOwnProperty.call(this.config, 'httpsProxy')) { - if (this.restoreFrom.HTTPS_PROXY !== undefined) { - process.env.HTTPS_PROXY = this.restoreFrom.HTTPS_PROXY; - } else { - delete process.env.HTTPS_PROXY; - } + if (Object.prototype.hasOwnProperty.call(this.config, 'httpsProxy')) { + if (this.restoreFrom.HTTPS_PROXY !== undefined) { + process.env.HTTPS_PROXY = this.restoreFrom.HTTPS_PROXY; + } else { + delete process.env.HTTPS_PROXY; + } - if (this.restoreFrom.https_proxy !== undefined) { - process.env.https_proxy = this.restoreFrom.https_proxy; - } else { - delete process.env.https_proxy; + if (this.restoreFrom.https_proxy !== undefined) { + process.env.https_proxy = this.restoreFrom.https_proxy; + } else { + delete process.env.https_proxy; + } } - } }; module.exports = EnvProxy; diff --git a/packages/bower-config/lib/util/rc.js b/packages/bower-config/lib/util/rc.js index ddfa6f672..76a2ce628 100644 --- a/packages/bower-config/lib/util/rc.js +++ b/packages/bower-config/lib/util/rc.js @@ -16,7 +16,7 @@ function rc(name, cwd, argv) { argv = argv || optimist.argv; // Parse --config.foo=false - argvConfig = object.map(argv.config || {}, function (value) { + argvConfig = object.map(argv.config || {}, function(value) { return value === 'false' ? false : value; }); @@ -106,14 +106,14 @@ function env(prefix) { prefix = prefix.toLowerCase(); - object.forOwn(process.env, function (value, key) { + object.forOwn(process.env, function(value, key) { key = key.toLowerCase(); if (string.startsWith(key, prefix)) { var parsedKey = key - .substr(prefixLength) - .replace(/__/g, '.') // __ is used for nesting - .replace(/_/g, '-'); // _ is used as a - separator + .substr(prefixLength) + .replace(/__/g, '.') // __ is used for nesting + .replace(/_/g, '-'); // _ is used as a - separator //use a convention patern to accept array from process.env //e.g. export bower_registry__search='["http://abc.com","http://def.com"]' @@ -122,10 +122,9 @@ function env(prefix) { if (!match || match.length === 0) { targetValue = value; } else { - targetValue = match[1].split(',') - .map(function(m) { - return m.trim(); - }); + targetValue = match[1].split(',').map(function(m) { + return m.trim(); + }); } object.set(obj, parsedKey, targetValue); } @@ -137,7 +136,7 @@ function env(prefix) { function find(filename, dir) { var files = []; - var walk = function (filename, dir) { + var walk = function(filename, dir) { var file = path.join(dir, filename); var parent = path.dirname(dir); diff --git a/packages/bower-config/test/helpers.js b/packages/bower-config/test/helpers.js index 8722dad41..51d546059 100644 --- a/packages/bower-config/test/helpers.js +++ b/packages/bower-config/test/helpers.js @@ -17,17 +17,17 @@ var tmpLocation = path.join( uuid.v4().slice(0, 8) ); -after(function () { +after(function() { rimraf.sync(tmpLocation); }); exports.TempDir = (function() { - function TempDir (defaults) { + function TempDir(defaults) { this.path = path.join(tmpLocation, uuid.v4()); this.defaults = defaults; } - TempDir.prototype.create = function (files, defaults) { + TempDir.prototype.create = function(files, defaults) { var that = this; defaults = defaults || this.defaults || {}; @@ -42,7 +42,7 @@ exports.TempDir = (function() { }; if (files) { - object.forOwn(files, function (contents, filepath) { + object.forOwn(files, function(contents, filepath) { if (typeof contents === 'object') { contents = JSON.stringify(contents, null, ' ') + '\n'; } @@ -56,7 +56,7 @@ exports.TempDir = (function() { return this; }; - TempDir.prototype.prepare = function (files) { + TempDir.prototype.prepare = function(files) { rimraf.sync(this.path); mkdirp.sync(this.path); this.create(files); @@ -65,7 +65,7 @@ exports.TempDir = (function() { }; // TODO: Rewrite to synchronous form - TempDir.prototype.prepareGit = function (revisions) { + TempDir.prototype.prepareGit = function(revisions) { var that = this; revisions = object.merge(revisions || {}, this.defaults); @@ -76,51 +76,56 @@ exports.TempDir = (function() { var promise = new Q(); - object.forOwn(revisions, function (files, tag) { - promise = promise.then(function () { - return that.git('init'); - }).then(function () { - that.glob('./!(.git)').map(function (removePath) { - var fullPath = path.join(that.path, removePath); - - rimraf.sync(fullPath); + object.forOwn(revisions, function(files, tag) { + promise = promise + .then(function() { + return that.git('init'); + }) + .then(function() { + that.glob('./!(.git)').map(function(removePath) { + var fullPath = path.join(that.path, removePath); + + rimraf.sync(fullPath); + }); + + that.create(files, {}); + }) + .then(function() { + return that.git('add', '-A'); + }) + .then(function() { + return that.git('commit', '-m"commit"'); + }) + .then(function() { + return that.git('tag', tag); }); - - that.create(files, {}); - }).then(function () { - return that.git('add', '-A'); - }).then(function () { - return that.git('commit', '-m"commit"'); - }).then(function () { - return that.git('tag', tag); - }); }); return promise; }; - TempDir.prototype.glob = function (pattern) { + TempDir.prototype.glob = function(pattern) { return glob.sync(pattern, { cwd: this.path, dot: true }); }; - TempDir.prototype.getPath = function (name) { + TempDir.prototype.getPath = function(name) { return path.join(this.path, name); }; - TempDir.prototype.read = function (name) { + TempDir.prototype.read = function(name) { return fs.readFileSync(this.getPath(name), 'utf8'); }; - TempDir.prototype.readJson = function (name) { + TempDir.prototype.readJson = function(name) { return JSON.parse(this.read(name)); }; - TempDir.prototype.exists = function (name) { + TempDir.prototype.exists = function(name) { return fs.existsSync(path.join(this.path, name)); }; return TempDir; -})(); \ No newline at end of file +})(); diff --git a/packages/bower-config/test/test.js b/packages/bower-config/test/test.js index d9a810e28..c5aeaaeeb 100644 --- a/packages/bower-config/test/test.js +++ b/packages/bower-config/test/test.js @@ -1,66 +1,64 @@ var assert = require('assert'); var path = require('path'); -describe('NPM Config on package.json', function () { - beforeEach(function () { +describe('NPM Config on package.json', function() { + beforeEach(function() { delete process.env.npm_package_config_bower_directory; delete process.env.npm_package_config_bower_colors; delete process.env.npm_package_config_bower_resolvers; }); - it('defaults registry entries to default registry', function () { + it('defaults registry entries to default registry', function() { var config = require('../lib/Config').read(null, {}); assert.deepEqual(config.registry, { - 'default': 'https://registry.bower.io', - 'search': [ - 'https://registry.bower.io' - ], - 'register': 'https://registry.bower.io', - 'publish': 'https://registry.bower.io' + default: 'https://registry.bower.io', + search: ['https://registry.bower.io'], + register: 'https://registry.bower.io', + publish: 'https://registry.bower.io' }); }); - it('can change default registry', function () { - var config = require('../lib/Config').read(null, { registry: 'https://foobar' }); + it('can change default registry', function() { + var config = require('../lib/Config').read(null, { + registry: 'https://foobar' + }); assert.deepEqual(config.registry, { - 'default': 'https://foobar', - 'search': [ - 'https://foobar', - ], - 'register': 'https://foobar', - 'publish': 'https://foobar' + default: 'https://foobar', + search: ['https://foobar'], + register: 'https://foobar', + publish: 'https://foobar' }); }); - it('can override single entries in registry configuration', function () { - var config = require('../lib/Config').read(null, { registry: { search: 'https://foobar' } }); + it('can override single entries in registry configuration', function() { + var config = require('../lib/Config').read(null, { + registry: { search: 'https://foobar' } + }); assert.deepEqual(config.registry, { - 'default': 'https://registry.bower.io', - 'search': [ - 'https://foobar', - ], - 'register': 'https://registry.bower.io', - 'publish': 'https://registry.bower.io' + default: 'https://registry.bower.io', + search: ['https://foobar'], + register: 'https://registry.bower.io', + publish: 'https://registry.bower.io' }); }); - it('can override single entries in registry configuration and defaults', function () { - var config = require('../lib/Config').read(null, { registry: { default: 'https://fizfuz', search: 'https://foobar' } }); + it('can override single entries in registry configuration and defaults', function() { + var config = require('../lib/Config').read(null, { + registry: { default: 'https://fizfuz', search: 'https://foobar' } + }); assert.deepEqual(config.registry, { - 'default': 'https://fizfuz', - 'search': [ - 'https://foobar', - ], - 'register': 'https://fizfuz', - 'publish': 'https://fizfuz' + default: 'https://fizfuz', + search: ['https://foobar'], + register: 'https://fizfuz', + publish: 'https://fizfuz' }); }); - it('allows for not providing cwd', function () { + it('allows for not providing cwd', function() { var config = require('../lib/Config').read(); config.tmp = '/foo/bar'; @@ -68,24 +66,22 @@ describe('NPM Config on package.json', function () { delete config.storage; assert.deepEqual(config, { - 'directory': 'bower_components', - 'registry': { - 'default': 'https://registry.bower.io', - 'search': [ - 'https://registry.bower.io' - ], - 'register': 'https://registry.bower.io', - 'publish': 'https://registry.bower.io' - }, - 'shorthandResolver': 'https://github.com/{{owner}}/{{package}}.git', - 'tmp': '/foo/bar', - 'timeout': 30000, - 'ca': { - 'search': [] - }, - 'strictSsl': true, - 'userAgent': 'firefox', - 'color': true + directory: 'bower_components', + registry: { + default: 'https://registry.bower.io', + search: ['https://registry.bower.io'], + register: 'https://registry.bower.io', + publish: 'https://registry.bower.io' + }, + shorthandResolver: 'https://github.com/{{owner}}/{{package}}.git', + tmp: '/foo/bar', + timeout: 30000, + ca: { + search: [] + }, + strictSsl: true, + userAgent: 'firefox', + color: true }); }); @@ -96,41 +92,49 @@ describe('NPM Config on package.json', function () { assert(Array.isArray(caData), name + ' should be an array'); assert.equal(2, caData.length); caData.forEach(function(c, i) { - assert(c.match(r), - name + '[' + i + '] should contain a certificate. Given: ' + JSON.stringify(c)); + assert( + c.match(r), + name + + '[' + + i + + '] should contain a certificate. Given: ' + + JSON.stringify(c) + ); }); } - describe('Setting process.env.npm_package_config', function () { + describe('Setting process.env.npm_package_config', function() { process.env.npm_package_config_bower_directory = 'npm-path'; process.env.npm_package_config_bower_colors = 'false'; process.env.npm_package_config_bower_resolvers = '[foo,bar,baz]'; var config = require('../lib/Config').read(); - it('should return "npm-path" for "bower_directory"', function () { + it('should return "npm-path" for "bower_directory"', function() { assert.equal('npm-path', config.directory); }); - it('should return "false" for "bower_colors"', function () { + it('should return "false" for "bower_colors"', function() { assert.equal('false', config.colors); }); - it('should expand array "false" for "bower_resolvers"', function () { + it('should expand array "false" for "bower_resolvers"', function() { assert.deepEqual(['foo', 'bar', 'baz'], config.resolvers); }); }); describe('Specifying custom CA', function() { - it('should read the CA file', function() { - var config = require('../lib/Config') - .read(path.resolve('test/assets/custom-ca')); + var config = require('../lib/Config').read( + path.resolve('test/assets/custom-ca') + ); - ['register', 'publish', 'default'].forEach(function (p) { + ['register', 'publish', 'default'].forEach(function(p) { assertCAContents(config.ca[p], 'config.ca.' + p); }); - assert(Array.isArray(config.ca.search), - 'ca property search should be an array'); + assert( + Array.isArray(config.ca.search), + 'ca property search should be an array' + ); config.ca.search.forEach(function(c, i) { assertCAContents(c, 'config.ca.search[' + i + ']'); @@ -138,23 +142,26 @@ describe('NPM Config on package.json', function () { }); it('should backward-support certificate inside .bowerrc', function() { - var config = require('../lib/Config') - .read(path.resolve('test/assets/custom-ca-embed')); + var config = require('../lib/Config').read( + path.resolve('test/assets/custom-ca-embed') + ); - ['register', 'publish', 'default'].forEach(function (p) { + ['register', 'publish', 'default'].forEach(function(p) { assertCAContents(config.ca[p], 'config.ca.' + p); }); - assert(Array.isArray(config.ca.search), - 'ca property search should be an array'); + assert( + Array.isArray(config.ca.search), + 'ca property search should be an array' + ); config.ca.search.forEach(function(c, i) { assertCAContents(c, 'config.ca.search[' + i + ']'); }); }); }); - describe('setting ENV variables', function () { - beforeEach(function () { + describe('setting ENV variables', function() { + beforeEach(function() { delete process.env.no_proxy; delete process.env.http_proxy; delete process.env.https_proxy; @@ -163,7 +170,7 @@ describe('NPM Config on package.json', function () { delete process.env.HTTPS_PROXY; }); - it('sets env variables', function () { + it('sets env variables', function() { require('../lib/Config').read('test/assets/env-variables'); assert.equal(process.env.HTTP_PROXY, 'http://HTTP_PROXY'); @@ -175,7 +182,7 @@ describe('NPM Config on package.json', function () { assert.equal(process.env.no_proxy, undefined); }); - it('restores env variables', function () { + it('restores env variables', function() { process.env.HTTP_PROXY = 'a'; process.env.HTTPS_PROXY = 'b'; process.env.NO_PROXY = 'c'; @@ -183,7 +190,9 @@ describe('NPM Config on package.json', function () { process.env.https_proxy = 'e'; process.env.no_proxy = 'f'; - var config = require('../lib/Config').create('test/assets/env-variables').load(); + var config = require('../lib/Config') + .create('test/assets/env-variables') + .load(); config.restore(); assert.equal(process.env.HTTP_PROXY, 'a'); @@ -195,8 +204,10 @@ describe('NPM Config on package.json', function () { assert.equal(process.env.no_proxy, 'f'); }); - it('restores env variables if they are undefined', function () { - var config = require('../lib/Config').create('test/assets/env-variables').load(); + it('restores env variables if they are undefined', function() { + var config = require('../lib/Config') + .create('test/assets/env-variables') + .load(); config.restore(); assert.equal(process.env.HTTP_PROXY, undefined); @@ -208,7 +219,7 @@ describe('NPM Config on package.json', function () { assert.equal(process.env.no_proxy, undefined); }); - it('allows for overriding options', function () { + it('allows for overriding options', function() { require('../lib/Config').read('test/assets/env-variables', { httpsProxy: 'http://other-proxy.local' }); @@ -220,14 +231,15 @@ describe('NPM Config on package.json', function () { }); describe('Allow ${ENV} variables in .bowerrc', function() { - it('sets values from process.env', function() { process.env._BOWERRC_MY_PACKAGES = 'a'; process.env._BOWERRC_MY_TMP = '/tmp/b'; process.env._BOWERRC_MY_USER = 'username'; process.env._BOWERRC_MY_PASS = 'password'; - var config = require('../lib/Config').read('test/assets/env-variables-values'); + var config = require('../lib/Config').read( + 'test/assets/env-variables-values' + ); assert.equal('a', config.storage.packages); assert.equal('/tmp/b', config.tmp); assert.equal('username:password', config.storage.registry.search[0]); @@ -236,12 +248,16 @@ describe('Allow ${ENV} variables in .bowerrc', function() { }); describe('untildify paths in .bowerrc', function() { - it('resolve ~/ in .bowerrc', function() { - var config = require('../lib/Config').read('test/assets/env-variables-values'); + var config = require('../lib/Config').read( + 'test/assets/env-variables-values' + ); var untildify = require('untildify'); - assert.equal(untildify('~/.bower-test/registry') , config.storage.registry.register); + assert.equal( + untildify('~/.bower-test/registry'), + config.storage.registry.register + ); }); }); diff --git a/packages/bower-config/test/util/index.js b/packages/bower-config/test/util/index.js index 2a2d25259..239318c84 100644 --- a/packages/bower-config/test/util/index.js +++ b/packages/bower-config/test/util/index.js @@ -1,3 +1,3 @@ -describe('util', function () { +describe('util', function() { require('./rc'); -}); \ No newline at end of file +}); diff --git a/packages/bower-config/test/util/rc.js b/packages/bower-config/test/util/rc.js index bc4f2fad9..9b234895d 100644 --- a/packages/bower-config/test/util/rc.js +++ b/packages/bower-config/test/util/rc.js @@ -29,7 +29,6 @@ describe('rc', function() { '.bowerrc/foo': { key: 'bar' } - }); it('correctly reads .bowerrc files', function() { @@ -60,22 +59,21 @@ describe('rc', function() { expect(config.key2).to.eql(undefined); }); - it('loads the .bowerrc file from the cwd specified on the command line', function(){ + it('loads the .bowerrc file from the cwd specified on the command line', function() { var argv = { - 'config': { - 'cwd': tempDir.path + '/other_dir/' + config: { + cwd: tempDir.path + '/other_dir/' } }; var config = rc('bower', tempDir.path, argv); expect(config.key).to.eql('othervalue'); - }); it('throws an easy to understand error if .bowerrc is a dir', function() { // Gotta wrap this to catch the error - var config = function () { + var config = function() { rc('bower', tempDirBowerrc.path); }; diff --git a/packages/bower-endpoint-parser/index.js b/packages/bower-endpoint-parser/index.js index 05523941d..eac54adad 100644 --- a/packages/bower-endpoint-parser/index.js +++ b/packages/bower-endpoint-parser/index.js @@ -59,10 +59,10 @@ function json2decomposed(key, value) { // If # was found, the source was specified if (split.length > 1) { endpoint += (split[0] || key) + '#' + split[1]; - // Check if value looks like a source + // Check if value looks like a source } else if (isSource(value)) { endpoint += value + '#*'; - // Otherwise use the key as the source + // Otherwise use the key as the source } else { endpoint += key + '#' + split[0]; } @@ -85,7 +85,7 @@ function decomposed2json(decEndpoint) { } // Add source only if different than the name - if (source !== name) { + if (source !== name) { value += source; } @@ -100,7 +100,7 @@ function decomposed2json(decEndpoint) { value += target; } } - // Otherwise append only if not a wildcard or source does not look like a source + // Otherwise append only if not a wildcard or source does not look like a source } else if (!isWildcard(target) || !isSource(source)) { value += '#' + (target || '*'); } @@ -119,7 +119,7 @@ function isWildcard(target) { } function isSource(value) { - return (/[\/\\@]/).test(value); + return /[\/\\@]/.test(value); } module.exports.decompose = decompose; diff --git a/packages/bower-endpoint-parser/test/test.js b/packages/bower-endpoint-parser/test/test.js index 084c410d2..fcaf0efb4 100644 --- a/packages/bower-endpoint-parser/test/test.js +++ b/packages/bower-endpoint-parser/test/test.js @@ -3,29 +3,68 @@ var lang = require('mout/lang'); var object = require('mout/object'); var endpointParser = require('../'); -describe('endpoint-parser', function () { - describe('.decompose', function () { - it('should decompose endpoints correctly', function () { +describe('endpoint-parser', function() { + describe('.decompose', function() { + it('should decompose endpoints correctly', function() { var suite = { - 'jquery#~2.0.0': { name: '', source: 'jquery', target: '~2.0.0' }, + 'jquery#~2.0.0': { + name: '', + source: 'jquery', + target: '~2.0.0' + }, 'jquery#*': { name: '', source: 'jquery', target: '*' }, 'jquery#latest': { name: '', source: 'jquery', target: '*' }, - 'jquery#3dc50c62fe2d2d01afc58e7ad42236a35acff4d8': { name: '', source: 'jquery', target: '3dc50c62fe2d2d01afc58e7ad42236a35acff4d8' }, - 'jquery#master': { name: '', source: 'jquery', target: 'master' }, - 'backbone=backbone-amd#~1.0.0': { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }, - 'backbone=backbone-amd#latest': { name: 'backbone', source: 'backbone-amd', target: '*' }, - 'backbone=backbone-amd#*': { name: 'backbone', source: 'backbone-amd', target: '*' }, - 'http://twitter.github.io/bootstrap/assets/bootstrap.zip': { name: '', source: 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', target: '*' }, - 'bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip': { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', target: '*' }, - 'bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip#latest': { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', target: '*' } + 'jquery#3dc50c62fe2d2d01afc58e7ad42236a35acff4d8': { + name: '', + source: 'jquery', + target: '3dc50c62fe2d2d01afc58e7ad42236a35acff4d8' + }, + 'jquery#master': { + name: '', + source: 'jquery', + target: 'master' + }, + 'backbone=backbone-amd#~1.0.0': { + name: 'backbone', + source: 'backbone-amd', + target: '~1.0.0' + }, + 'backbone=backbone-amd#latest': { + name: 'backbone', + source: 'backbone-amd', + target: '*' + }, + 'backbone=backbone-amd#*': { + name: 'backbone', + source: 'backbone-amd', + target: '*' + }, + 'http://twitter.github.io/bootstrap/assets/bootstrap.zip': { + name: '', + source: + 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', + target: '*' + }, + 'bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip': { + name: 'bootstrap', + source: + 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', + target: '*' + }, + 'bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip#latest': { + name: 'bootstrap', + source: + 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', + target: '*' + } }; - object.forOwn(suite, function (decEndpoint, endpoint) { + object.forOwn(suite, function(decEndpoint, endpoint) { expect(endpointParser.decompose(endpoint)).to.eql(decEndpoint); }); }); - it('should trim sources and targets', function () { + it('should trim sources and targets', function() { var decEndpoint = endpointParser.decompose('foo= source # ~1.0.2 '); expect(decEndpoint.source).to.equal('source'); expect(decEndpoint.target).to.equal('~1.0.2'); @@ -40,77 +79,135 @@ describe('endpoint-parser', function () { }); }); - describe('.compose', function () { - it('should compose endpoints correctly', function () { + describe('.compose', function() { + it('should compose endpoints correctly', function() { var suite = { - 'jquery#~2.0.0': { name: '', source: 'jquery', target: '~2.0.0' }, - 'jquery': [{ name: '', source: 'jquery', target: '*' }, { name: '', source: 'jquery', target: 'latest' }, { name: '', source: 'jquery', target: '' }], - 'jquery#3dc50c62fe2d2d01afc58e7ad42236a35acff4d8': { name: '', source: 'jquery', target: '3dc50c62fe2d2d01afc58e7ad42236a35acff4d8' }, - 'jquery#master': { name: '', source: 'jquery', target: 'master' }, - 'backbone=backbone-amd#~1.0.0': { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }, - 'backbone=backbone-amd': [{ name: 'backbone', source: 'backbone-amd', target: '*' }, { name: 'backbone', source: 'backbone-amd', target: '*' }, { name: 'backbone', source: 'backbone-amd', target: '' }], - 'http://twitter.github.io/bootstrap/assets/bootstrap.zip': { name: '', source: 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', target: '*' }, - 'bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip': { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', target: '*' } + 'jquery#~2.0.0': { + name: '', + source: 'jquery', + target: '~2.0.0' + }, + jquery: [ + { name: '', source: 'jquery', target: '*' }, + { name: '', source: 'jquery', target: 'latest' }, + { name: '', source: 'jquery', target: '' } + ], + 'jquery#3dc50c62fe2d2d01afc58e7ad42236a35acff4d8': { + name: '', + source: 'jquery', + target: '3dc50c62fe2d2d01afc58e7ad42236a35acff4d8' + }, + 'jquery#master': { + name: '', + source: 'jquery', + target: 'master' + }, + 'backbone=backbone-amd#~1.0.0': { + name: 'backbone', + source: 'backbone-amd', + target: '~1.0.0' + }, + 'backbone=backbone-amd': [ + { name: 'backbone', source: 'backbone-amd', target: '*' }, + { name: 'backbone', source: 'backbone-amd', target: '*' }, + { name: 'backbone', source: 'backbone-amd', target: '' } + ], + 'http://twitter.github.io/bootstrap/assets/bootstrap.zip': { + name: '', + source: + 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', + target: '*' + }, + 'bootstrap=http://twitter.github.io/bootstrap/assets/bootstrap.zip': { + name: 'bootstrap', + source: + 'http://twitter.github.io/bootstrap/assets/bootstrap.zip', + target: '*' + } }; - object.forOwn(suite, function (decEndpoints, endpoint) { + object.forOwn(suite, function(decEndpoints, endpoint) { decEndpoints = lang.toArray(decEndpoints); - decEndpoints.forEach(function (decEndpoint) { - expect(endpointParser.compose(decEndpoint)).to.equal(endpoint); + decEndpoints.forEach(function(decEndpoint) { + expect(endpointParser.compose(decEndpoint)).to.equal( + endpoint + ); }); }); }); - it('should trim values', function () { - expect(endpointParser.compose({ - name: ' foo ', - source: ' bar ', - target: ' ~1.0.2 ' - })).to.equal('foo=bar#~1.0.2'); + it('should trim values', function() { + expect( + endpointParser.compose({ + name: ' foo ', + source: ' bar ', + target: ' ~1.0.2 ' + }) + ).to.equal('foo=bar#~1.0.2'); - expect(endpointParser.compose({ - name: ' foo ', - source: ' foo ', - target: ' ~1.0.2 ' - })).to.equal('foo=foo#~1.0.2'); + expect( + endpointParser.compose({ + name: ' foo ', + source: ' foo ', + target: ' ~1.0.2 ' + }) + ).to.equal('foo=foo#~1.0.2'); - expect(endpointParser.compose({ - name: ' foo ', - source: ' foo ', - target: ' * ' - })).to.equal('foo=foo'); + expect( + endpointParser.compose({ + name: ' foo ', + source: ' foo ', + target: ' * ' + }) + ).to.equal('foo=foo'); - expect(endpointParser.compose({ - name: ' foo ', - source: ' foo ', - target: ' * ' - })).to.equal('foo=foo'); + expect( + endpointParser.compose({ + name: ' foo ', + source: ' foo ', + target: ' * ' + }) + ).to.equal('foo=foo'); - expect(endpointParser.compose({ - name: ' ', - source: ' foo ', - target: '' - })).to.equal('foo'); + expect( + endpointParser.compose({ + name: ' ', + source: ' foo ', + target: '' + }) + ).to.equal('foo'); }); }); - describe('.json2decomposed', function () { + describe('.json2decomposed', function() { var expected = [ { name: 'jquery', source: 'jquery', target: '~1.9.1' }, { name: 'foo', source: 'foo', target: '*' }, { name: 'bar', source: 'bar', target: '*' }, { name: 'baz', source: 'baz', target: '~0.2.0' }, { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }, - { name: 'backbone2', source: 'backbone=backbone-amd', target: '~1.0.0' }, - { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }, - { name: 'bootstrap2', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }, + { + name: 'backbone2', + source: 'backbone=backbone-amd', + target: '~1.0.0' + }, + { + name: 'bootstrap', + source: 'http://twitter.github.io/bootstrap/assets/bootstrap', + target: '*' + }, + { + name: 'bootstrap2', + source: 'http://twitter.github.io/bootstrap/assets/bootstrap', + target: '*' + }, { name: 'ssh', source: 'git@example.com', target: '*' }, { name: 'git', source: 'git://example.com', target: '*' }, { name: 'path', source: '/foo', target: '*' }, { name: 'winpath', source: 'c:\\foo', target: '*' } ]; - it('should decompose json endpoints correctly', function () { + it('should decompose json endpoints correctly', function() { var dependencies = { jquery: '~1.9.1', foo: 'latest', @@ -118,8 +215,10 @@ describe('endpoint-parser', function () { baz: '#~0.2.0', backbone: 'backbone-amd#~1.0.0', backbone2: 'backbone=backbone-amd#~1.0.0', - bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap', - bootstrap2: 'http://twitter.github.io/bootstrap/assets/bootstrap#*', + bootstrap: + 'http://twitter.github.io/bootstrap/assets/bootstrap', + bootstrap2: + 'http://twitter.github.io/bootstrap/assets/bootstrap#*', ssh: 'git@example.com', git: 'git://example.com', path: '/foo', @@ -127,13 +226,15 @@ describe('endpoint-parser', function () { }; var x = 0; - object.forOwn(dependencies, function (value, key) { - expect(endpointParser.json2decomposed(key, value)).to.eql(expected[x]); + object.forOwn(dependencies, function(value, key) { + expect(endpointParser.json2decomposed(key, value)).to.eql( + expected[x] + ); x += 1; }); }); - it('should trim values', function () { + it('should trim values', function() { var dependencies = { ' jquery ': ' ~1.9.1 ', ' foo ': ' latest ', @@ -141,8 +242,10 @@ describe('endpoint-parser', function () { ' baz ': '# ~0.2.0 ', ' backbone ': ' backbone-amd#~1.0.0 ', ' backbone2 ': ' backbone=backbone-amd # ~1.0.0 ', - ' bootstrap ': ' http://twitter.github.io/bootstrap/assets/bootstrap', - ' bootstrap2 ': ' http://twitter.github.io/bootstrap/assets/bootstrap # *', + ' bootstrap ': + ' http://twitter.github.io/bootstrap/assets/bootstrap', + ' bootstrap2 ': + ' http://twitter.github.io/bootstrap/assets/bootstrap # *', ' ssh ': ' git@example.com ', ' git ': ' git://example.com ', ' path ': ' /foo ', @@ -150,13 +253,15 @@ describe('endpoint-parser', function () { }; var x = 0; - object.forOwn(dependencies, function (value, key) { - expect(endpointParser.json2decomposed(key, value)).to.eql(expected[x]); + object.forOwn(dependencies, function(value, key) { + expect(endpointParser.json2decomposed(key, value)).to.eql( + expected[x] + ); x += 1; }); }); - it('should error out if key is not specified', function () { + it('should error out if key is not specified', function() { try { endpointParser.json2decomposed(null); throw new Error('Should have failed'); @@ -175,7 +280,7 @@ describe('endpoint-parser', function () { }); }); - describe('.decomposed2json', function () { + describe('.decomposed2json', function() { var expected = [ { jquery: '~1.9.1' }, { foo: '*' }, @@ -185,15 +290,19 @@ describe('endpoint-parser', function () { { jqueryy: 'jquery-x#*' }, { jqueryy: 'jquery-x#*' }, { backbone: 'backbone-amd#~1.0.0' }, - { backbone : 'backbone=backbone-amd#~1.0.0' }, - { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' }, - { bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' }, + { backbone: 'backbone=backbone-amd#~1.0.0' }, + { + bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' + }, + { + bootstrap: 'http://twitter.github.io/bootstrap/assets/bootstrap' + }, { ssh: 'git@example.com' }, { git: 'git://example.com' }, { ckeditor: '#full/4.3.3' } ]; - it('should compose endpoints to json correctly', function () { + it('should compose endpoints to json correctly', function() { var decEndpoints = [ { name: 'jquery', source: 'jquery', target: '~1.9.1' }, { name: 'foo', source: 'foo', target: 'latest' }, @@ -203,22 +312,38 @@ describe('endpoint-parser', function () { { name: 'jqueryy', source: 'jquery-x', target: '' }, { name: 'jqueryy', source: 'jquery-x', target: '*' }, { name: 'backbone', source: 'backbone-amd', target: '~1.0.0' }, - { name: 'backbone', source: 'backbone=backbone-amd', target: '~1.0.0' }, - { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '' }, - { name: 'bootstrap', source: 'http://twitter.github.io/bootstrap/assets/bootstrap', target: '*' }, + { + name: 'backbone', + source: 'backbone=backbone-amd', + target: '~1.0.0' + }, + { + name: 'bootstrap', + source: + 'http://twitter.github.io/bootstrap/assets/bootstrap', + target: '' + }, + { + name: 'bootstrap', + source: + 'http://twitter.github.io/bootstrap/assets/bootstrap', + target: '*' + }, { name: 'ssh', source: 'git@example.com', target: '*' }, { name: 'git', source: 'git://example.com', target: '*' }, { name: 'ckeditor', source: 'ckeditor', target: 'full/4.3.3' } ]; var x = 0; - decEndpoints.forEach(function (decEndpoint) { - expect(endpointParser.decomposed2json(decEndpoint)).to.eql(expected[x]); + decEndpoints.forEach(function(decEndpoint) { + expect(endpointParser.decomposed2json(decEndpoint)).to.eql( + expected[x] + ); x += 1; }); }); - it('should trim values', function () { + it('should trim values', function() { var decEndpoints = [ { name: ' jquery ', source: ' jquery ', target: ' ~1.9.1 ' }, { name: 'foo', source: ' foo', target: ' latest ' }, @@ -227,24 +352,48 @@ describe('endpoint-parser', function () { { name: ' jqueryx ', source: ' jquery ', target: ' ~1.9.1 ' }, { name: ' jqueryy ', source: ' jquery-x ', target: ' ' }, { name: ' jqueryy ', source: ' jquery-x ', target: ' * ' }, - { name: ' backbone ', source: ' backbone-amd ', target: ' ~1.0.0 ' }, - { name: ' backbone ', source: ' backbone=backbone-amd ', target: ' ~1.0.0 ' }, - { name: ' bootstrap ', source: ' http://twitter.github.io/bootstrap/assets/bootstrap ', target: ' ' }, - { name: ' bootstrap ', source: ' http://twitter.github.io/bootstrap/assets/bootstrap ', target: ' * ' }, + { + name: ' backbone ', + source: ' backbone-amd ', + target: ' ~1.0.0 ' + }, + { + name: ' backbone ', + source: ' backbone=backbone-amd ', + target: ' ~1.0.0 ' + }, + { + name: ' bootstrap ', + source: + ' http://twitter.github.io/bootstrap/assets/bootstrap ', + target: ' ' + }, + { + name: ' bootstrap ', + source: + ' http://twitter.github.io/bootstrap/assets/bootstrap ', + target: ' * ' + }, { name: ' ssh ', source: ' git@example.com ', target: ' * ' }, { name: ' git ', source: ' git://example.com ', target: ' * ' } ]; var x = 0; - decEndpoints.forEach(function (decEndpoint) { - expect(endpointParser.decomposed2json(decEndpoint)).to.eql(expected[x]); + decEndpoints.forEach(function(decEndpoint) { + expect(endpointParser.decomposed2json(decEndpoint)).to.eql( + expected[x] + ); x += 1; }); }); - it('should throw an error if name is empty', function () { + it('should throw an error if name is empty', function() { try { - endpointParser.decomposed2json({ name: '', source: 'jquery', target: '*' }); + endpointParser.decomposed2json({ + name: '', + source: 'jquery', + target: '*' + }); throw new Error('Should have failed'); } catch (e) { expect(e.code).to.equal('EINVEND'); @@ -252,7 +401,11 @@ describe('endpoint-parser', function () { } try { - endpointParser.decomposed2json({ name: ' ', source: 'jquery', target: '*' }); + endpointParser.decomposed2json({ + name: ' ', + source: 'jquery', + target: '*' + }); throw new Error('Should have failed'); } catch (e) { expect(e.code).to.equal('EINVEND'); diff --git a/packages/bower-json/Gruntfile.js b/packages/bower-json/Gruntfile.js index 2d34d078b..2080356f0 100644 --- a/packages/bower-json/Gruntfile.js +++ b/packages/bower-json/Gruntfile.js @@ -1,10 +1,7 @@ -'use strict'; - -module.exports = function (grunt) { +module.exports = function(grunt) { require('load-grunt-tasks')(grunt); // Project configuration. grunt.initConfig({ - jshint: { files: [ 'Gruntfile.js', @@ -38,19 +35,19 @@ module.exports = function (grunt) { exec: { cover: { - command: 'STRICT_REQUIRE=1 node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' + command: + 'STRICT_REQUIRE=1 node node_modules/istanbul/lib/cli.js cover --dir ./test/reports node_modules/mocha/bin/_mocha -- --timeout 30000 -R dot test/test.js' }, coveralls: { - command: 'node node_modules/.bin/coveralls < test/reports/lcov.info' + command: + 'node node_modules/.bin/coveralls < test/reports/lcov.info' } }, - watch: { files: ['<%= jshint.files %>'], tasks: ['jshint', 'simplemocha:short'] } - }); // Default task. diff --git a/packages/bower-json/lib/json.js b/packages/bower-json/lib/json.js index 46b12788f..00a15adee 100644 --- a/packages/bower-json/lib/json.js +++ b/packages/bower-json/lib/json.js @@ -14,14 +14,14 @@ function read(file, options, callback) { } // Check if file is a directory - fs.stat(file, function (err, stat) { + fs.stat(file, function(err, stat) { if (err) { return callback(err); } // It's a directory, so we find the json inside it if (stat.isDirectory()) { - return find(file, function (err, file) { + return find(file, function(err, file) { if (err) { return callback(err); } @@ -31,7 +31,7 @@ function read(file, options, callback) { } // Otherwise read it - fs.readFile(file, function (err, contents) { + fs.readFile(file, function(err, contents) { var json; if (err) { @@ -99,11 +99,14 @@ function readSync(file, options) { } function parse(json, options) { - options = deepExtend({ - normalize: false, - validate: true, - clone: false - }, options || {}); + options = deepExtend( + { + normalize: false, + validate: true, + clone: false + }, + options || {} + ); // Clone if (options.clone) { @@ -137,7 +140,9 @@ function getIssues(json) { errors.push('No "name" property set'); } else { if (!/^[a-zA-Z0-9_@][a-zA-Z0-9_@\.\- \/]*$/.test(json.name)) { - errors.push('Name must be lowercase, can contain digits, dots, dashes, "@" or spaces'); + errors.push( + 'Name must be lowercase, can contain digits, dots, dashes, "@" or spaces' + ); } if (json.name.length > 50) { @@ -145,7 +150,9 @@ function getIssues(json) { } if (!/^[a-z0-9_][a-z0-9_\.\-]*$/.test(json.name)) { - warnings.push('The "name" is recommended to be lowercase, can contain digits, dots, dashes'); + warnings.push( + 'The "name" is recommended to be lowercase, can contain digits, dots, dashes' + ); } if (/^[\.-]/.test(json.name)) { @@ -158,7 +165,9 @@ function getIssues(json) { } if (json.description && json.description.length > 140) { - warnings.push('The "description" is too long, the limit is 140 characters'); + warnings.push( + 'The "description" is too long, the limit is 140 characters' + ); } if (json.main !== undefined) { @@ -167,21 +176,29 @@ function getIssues(json) { main = [main]; } if (!(main instanceof Array)) { - errors.push('The "main" field has to be either an Array or a String'); + errors.push( + 'The "main" field has to be either an Array or a String' + ); } else { var ext2files = {}; - main.forEach(function (filename) { + main.forEach(function(filename) { if (typeof filename !== 'string') { errors.push('The "main" Array has to contain only Strings'); } if (/[*]/.test(filename)) { - warnings.push('The "main" field cannot contain globs (example: "*.js")'); + warnings.push( + 'The "main" field cannot contain globs (example: "*.js")' + ); } if (/[.]min[.][^/]+$/.test(filename)) { - warnings.push('The "main" field cannot contain minified files'); + warnings.push( + 'The "main" field cannot contain minified files' + ); } if (isAsset(filename)) { - warnings.push('The "main" field cannot contain font, image, audio, or video files'); + warnings.push( + 'The "main" field cannot contain font, image, audio, or video files' + ); } var ext = path.extname(filename); if (ext.length >= 2) { @@ -192,10 +209,15 @@ function getIssues(json) { files.push(filename); } }); - Object.keys(ext2files).forEach(function (ext) { + Object.keys(ext2files).forEach(function(ext) { var files = ext2files[ext]; if (files.length > 1) { - warnings.push('The "main" field has to contain only 1 file per filetype; found multiple ' + ext + ' files: ' + JSON.stringify(files)); + warnings.push( + 'The "main" field has to contain only 1 file per filetype; found multiple ' + + ext + + ' files: ' + + JSON.stringify(files) + ); } }); } @@ -234,12 +256,15 @@ function find(folder, files, callback) { } if (!files.length) { - err = createError('None of ' + possibleJsons.join(', ') + ' were found in ' + folder, 'ENOENT'); + err = createError( + 'None of ' + possibleJsons.join(', ') + ' were found in ' + folder, + 'ENOENT' + ); return callback(err); } file = path.resolve(path.join(folder, files[0])); - fs.exists(file, function (exists) { + fs.exists(file, function(exists) { if (!exists) { return find(folder, files.slice(1), callback); } @@ -250,7 +275,7 @@ function find(folder, files, callback) { // If the file is component.json, check it it's a component(1) file // If it is, we ignore it and keep searching - isComponent(file, function (is) { + isComponent(file, function(is) { if (is) { return find(folder, files.slice(1), callback); } @@ -269,14 +294,16 @@ function findSync(folder, files) { } if (!files.length) { - return createError('None of ' + possibleJsons.join(', ') + ' were found in ' + folder, 'ENOENT'); + return createError( + 'None of ' + possibleJsons.join(', ') + ' were found in ' + folder, + 'ENOENT' + ); } file = path.resolve(path.join(folder, files[0])); - try{ + try { exists = fs.statSync(file); - } - catch (err) { + } catch (err) { exists = false; } if (exists && exists.isFile()) { diff --git a/packages/bower-json/lib/util/isAsset.js b/packages/bower-json/lib/util/isAsset.js index e373cb1d5..0f08530d2 100644 --- a/packages/bower-json/lib/util/isAsset.js +++ b/packages/bower-json/lib/util/isAsset.js @@ -2,10 +2,14 @@ var extName = require('ext-name'); function isAsset(filename) { var info = extName(filename); - - return info && info.mime && ( - /^((image)|(audio)|(video)|(font))\//.test(info.mime) || - /application\/((x[-]font[-])|(font[-]woff(\d?))|(vnd[.]ms[-]fontobject))/.test(info.mime) + + return ( + info && + info.mime && + (/^((image)|(audio)|(video)|(font))\//.test(info.mime) || + /application\/((x[-]font[-])|(font[-]woff(\d?))|(vnd[.]ms[-]fontobject))/.test( + info.mime + )) ); } diff --git a/packages/bower-json/lib/util/isComponent.js b/packages/bower-json/lib/util/isComponent.js index 021120658..a17ba96c1 100644 --- a/packages/bower-json/lib/util/isComponent.js +++ b/packages/bower-json/lib/util/isComponent.js @@ -3,7 +3,7 @@ var intersect = require('intersect'); // Function to check if a file is a component(1) file function isComponent(file, callback) { - fs.readFile(file, function (err, contents) { + fs.readFile(file, function(err, contents) { var json; var keys; var common; diff --git a/packages/bower-json/test/test.js b/packages/bower-json/test/test.js index 9f7cce31d..43bd2f322 100644 --- a/packages/bower-json/test/test.js +++ b/packages/bower-json/test/test.js @@ -4,114 +4,142 @@ var _s = require('underscore.string'); var bowerJson = require('../lib/json'); var request = require('request'); -describe('.find', function () { - it('should find the bower.json file', function (done) { - bowerJson.find(__dirname + '/pkg-bower-json', function (err, file) { +describe('.find', function() { + it('should find the bower.json file', function(done) { + bowerJson.find(__dirname + '/pkg-bower-json', function(err, file) { if (err) { return done(err); } - expect(file).to.equal(path.resolve(__dirname + '/pkg-bower-json/bower.json')); + expect(file).to.equal( + path.resolve(__dirname + '/pkg-bower-json/bower.json') + ); done(); }); }); - it('should fallback to the component.json file', function (done) { - bowerJson.find(__dirname + '/pkg-component-json', function (err, file) { + it('should fallback to the component.json file', function(done) { + bowerJson.find(__dirname + '/pkg-component-json', function(err, file) { if (err) { return done(err); } - expect(file).to.equal(path.resolve(__dirname + '/pkg-component-json/component.json')); + expect(file).to.equal( + path.resolve(__dirname + '/pkg-component-json/component.json') + ); done(); }); }); - it('should not fallback to the component.json file if it\'s a component(1) file', function (done) { - bowerJson.find(__dirname + '/pkg-component(1)-json', function (err) { + it("should not fallback to the component.json file if it's a component(1) file", function(done) { + bowerJson.find(__dirname + '/pkg-component(1)-json', function(err) { expect(err).to.be.an(Error); expect(err.code).to.equal('ENOENT'); - expect(err.message).to.equal('None of bower.json, component.json, .bower.json were found in ' + __dirname + '/pkg-component(1)-json'); + expect(err.message).to.equal( + 'None of bower.json, component.json, .bower.json were found in ' + + __dirname + + '/pkg-component(1)-json' + ); done(); }); }); - it('should fallback to the .bower.json file', function (done) { - bowerJson.find(__dirname + '/pkg-dot-bower-json', function (err, file) { + it('should fallback to the .bower.json file', function(done) { + bowerJson.find(__dirname + '/pkg-dot-bower-json', function(err, file) { if (err) { return done(err); } - expect(file).to.equal(path.resolve(__dirname + '/pkg-dot-bower-json/.bower.json')); + expect(file).to.equal( + path.resolve(__dirname + '/pkg-dot-bower-json/.bower.json') + ); done(); }); }); - it('should error if no component.json / bower.json / .bower.json is found', function (done) { - bowerJson.find(__dirname, function (err) { + it('should error if no component.json / bower.json / .bower.json is found', function(done) { + bowerJson.find(__dirname, function(err) { expect(err).to.be.an(Error); expect(err.code).to.equal('ENOENT'); - expect(err.message).to.equal('None of bower.json, component.json, .bower.json were found in ' + __dirname); + expect(err.message).to.equal( + 'None of bower.json, component.json, .bower.json were found in ' + + __dirname + ); done(); }); }); }); -describe('.findSync', function () { - - it('should find the bower.json file', function (done) { +describe('.findSync', function() { + it('should find the bower.json file', function(done) { var file = bowerJson.findSync(__dirname + '/pkg-bower-json'); - expect(file).to.equal(path.resolve(__dirname + '/pkg-bower-json/bower.json')); + expect(file).to.equal( + path.resolve(__dirname + '/pkg-bower-json/bower.json') + ); done(); }); - it('should fallback to the component.json file', function (done) { + it('should fallback to the component.json file', function(done) { var file = bowerJson.findSync(__dirname + '/pkg-component-json'); - expect(file).to.equal(path.resolve(__dirname + '/pkg-component-json/component.json')); + expect(file).to.equal( + path.resolve(__dirname + '/pkg-component-json/component.json') + ); done(); }); - it('should fallback to the .bower.json file', function (done) { + it('should fallback to the .bower.json file', function(done) { var file = bowerJson.findSync(__dirname + '/pkg-dot-bower-json'); - expect(file).to.equal(path.resolve(__dirname + '/pkg-dot-bower-json/.bower.json')); + expect(file).to.equal( + path.resolve(__dirname + '/pkg-dot-bower-json/.bower.json') + ); done(); }); - it('should error if no component.json / bower.json / .bower.json is found', function (done) { + it('should error if no component.json / bower.json / .bower.json is found', function(done) { var err = bowerJson.findSync(__dirname); expect(err).to.be.an(Error); expect(err.code).to.equal('ENOENT'); - expect(err.message).to.equal('None of bower.json, component.json, .bower.json were found in ' + __dirname); + expect(err.message).to.equal( + 'None of bower.json, component.json, .bower.json were found in ' + + __dirname + ); done(); }); - - - }); -describe('.read', function () { - it('should give error if file does not exists', function (done) { - bowerJson.read(__dirname + '/willneverexist', function (err) { +describe('.read', function() { + it('should give error if file does not exists', function(done) { + bowerJson.read(__dirname + '/willneverexist', function(err) { expect(err).to.be.an(Error); expect(err.code).to.equal('ENOENT'); done(); }); }); - it('should give error if when reading an invalid json', function (done) { - bowerJson.read(__dirname + '/pkg-bower-json-malformed/bower.json', function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.equal('EMALFORMED'); - expect(err.file).to.equal(path.resolve(__dirname + '/pkg-bower-json-malformed/bower.json')); - done(); - }); + it('should give error if when reading an invalid json', function(done) { + bowerJson.read( + __dirname + '/pkg-bower-json-malformed/bower.json', + function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.equal('EMALFORMED'); + expect(err.file).to.equal( + path.resolve( + __dirname + '/pkg-bower-json-malformed/bower.json' + ) + ); + done(); + } + ); }); - it('should read the file and give an object', function (done) { - bowerJson.read(__dirname + '/pkg-bower-json/bower.json', function (err, json) { + it('should read the file and give an object', function(done) { + bowerJson.read(__dirname + '/pkg-bower-json/bower.json', function( + err, + json + ) { if (err) { return done(err); } @@ -124,20 +152,27 @@ describe('.read', function () { }); }); - it('should give the json file that was read', function (done) { - bowerJson.read(__dirname + '/pkg-bower-json', function (err, json, file) { + it('should give the json file that was read', function(done) { + bowerJson.read(__dirname + '/pkg-bower-json', function( + err, + json, + file + ) { if (err) { return done(err); } - expect(file).to.equal(__dirname + '/pkg-bower-json/bower.json'); done(); }); }); - it('should find for a json file if a directory is given', function (done) { - bowerJson.read(__dirname + '/pkg-component-json', function (err, json, file) { + it('should find for a json file if a directory is given', function(done) { + bowerJson.read(__dirname + '/pkg-component-json', function( + err, + json, + file + ) { if (err) { return done(err); } @@ -145,60 +180,84 @@ describe('.read', function () { expect(json).to.be.an('object'); expect(json.name).to.equal('some-pkg'); expect(json.version).to.equal('0.0.0'); - expect(file).to.equal(path.resolve(__dirname + '/pkg-component-json/component.json')); + expect(file).to.equal( + path.resolve(__dirname + '/pkg-component-json/component.json') + ); done(); }); }); - it('should validate the returned object unless validate is false', function (done) { - bowerJson.read(__dirname + '/pkg-bower-json-invalid/bower.json', function (err) { - expect(err).to.be.an(Error); - expect(err.message).to.contain('name'); - expect(err.file).to.equal(path.resolve(__dirname + '/pkg-bower-json-invalid/bower.json')); - - bowerJson.read(__dirname + '/pkg-bower-json-invalid/bower.json', { validate: false }, function (err) { - done(err); - }); - }); + it('should validate the returned object unless validate is false', function(done) { + bowerJson.read( + __dirname + '/pkg-bower-json-invalid/bower.json', + function(err) { + expect(err).to.be.an(Error); + expect(err.message).to.contain('name'); + expect(err.file).to.equal( + path.resolve( + __dirname + '/pkg-bower-json-invalid/bower.json' + ) + ); + + bowerJson.read( + __dirname + '/pkg-bower-json-invalid/bower.json', + { validate: false }, + function(err) { + done(err); + } + ); + } + ); }); - it('should normalize the returned object if normalize is true', function (done) { - bowerJson.read(__dirname + '/pkg-bower-json/bower.json', function (err, json) { + it('should normalize the returned object if normalize is true', function(done) { + bowerJson.read(__dirname + '/pkg-bower-json/bower.json', function( + err, + json + ) { if (err) { return done(err); } expect(json.main).to.equal('foo.js'); - bowerJson.read(__dirname + '/pkg-bower-json/bower.json', { normalize: true }, function (err, json) { - if (err) { - return done(err); - } + bowerJson.read( + __dirname + '/pkg-bower-json/bower.json', + { normalize: true }, + function(err, json) { + if (err) { + return done(err); + } - expect(json.main).to.eql(['foo.js']); - done(); - }); + expect(json.main).to.eql(['foo.js']); + done(); + } + ); }); }); }); -describe('.readSync', function () { - it('should give error if file does not exists', function (done) { +describe('.readSync', function() { + it('should give error if file does not exists', function(done) { var err = bowerJson.readSync(__dirname + '/willneverexist'); expect(err).to.be.an(Error); expect(err.code).to.equal('ENOENT'); done(); }); - it('should give error if when reading an invalid json', function (done) { - var err = bowerJson.readSync(__dirname + '/pkg-bower-json-malformed/bower.json'); + it('should give error if when reading an invalid json', function(done) { + var err = bowerJson.readSync( + __dirname + '/pkg-bower-json-malformed/bower.json' + ); expect(err).to.be.an(Error); expect(err.code).to.equal('EMALFORMED'); - expect(err.file).to.equal(path.resolve(__dirname + '/pkg-bower-json-malformed/bower.json')); + expect(err.file).to.equal( + path.resolve(__dirname + '/pkg-bower-json-malformed/bower.json') + ); done(); }); - it('should read the file and give an object', function (done) { + it('should read the file and give an object', function(done) { var json = bowerJson.readSync(__dirname + '/pkg-bower-json/bower.json'); expect(json).to.be.an('object'); @@ -208,7 +267,7 @@ describe('.readSync', function () { done(); }); - it('should find for a json file if a directory is given', function (done) { + it('should find for a json file if a directory is given', function(done) { var json = bowerJson.readSync(__dirname + '/pkg-component-json'); expect(json).to.be.an('object'); @@ -217,32 +276,39 @@ describe('.readSync', function () { done(); }); - it('should validate the returned object unless validate is false', function (done) { - var err = bowerJson.readSync(__dirname + '/pkg-bower-json-invalid/bower.json'); + it('should validate the returned object unless validate is false', function(done) { + var err = bowerJson.readSync( + __dirname + '/pkg-bower-json-invalid/bower.json' + ); expect(err).to.be.an(Error); expect(err.message).to.contain('name'); - expect(err.file).to.equal(path.resolve(__dirname + '/pkg-bower-json-invalid/bower.json')); + expect(err.file).to.equal( + path.resolve(__dirname + '/pkg-bower-json-invalid/bower.json') + ); - err = bowerJson.readSync(__dirname + '/pkg-bower-json-invalid/bower.json', { validate: false }); + err = bowerJson.readSync( + __dirname + '/pkg-bower-json-invalid/bower.json', + { validate: false } + ); expect(err).to.not.be.an(Error); done(); }); - it('should normalize the returned object if normalize is true', function (done) { - var json = bowerJson.readSync(__dirname + '/pkg-bower-json/bower.json'); + it('should normalize the returned object if normalize is true', function(done) { + var json = bowerJson.readSync(__dirname + '/pkg-bower-json/bower.json'); expect(json.main).to.equal('foo.js'); - json = bowerJson.readSync(__dirname + '/pkg-bower-json/bower.json', { normalize: true }); + json = bowerJson.readSync(__dirname + '/pkg-bower-json/bower.json', { + normalize: true + }); expect(json.main).to.eql(['foo.js']); done(); }); - - }); -describe('.parse', function () { - it('should return the same object, unless clone is true', function () { +describe('.parse', function() { + it('should return the same object, unless clone is true', function() { var json = { name: 'foo' }; expect(bowerJson.parse(json)).to.equal(json); @@ -250,17 +316,17 @@ describe('.parse', function () { expect(bowerJson.parse(json, { clone: true })).to.eql(json); }); - it('should validate the passed object, unless validate is false', function () { - expect(function () { + it('should validate the passed object, unless validate is false', function() { + expect(function() { bowerJson.parse({}); }).to.throwException(/name/); - expect(function () { + expect(function() { bowerJson.parse({}, { validate: false }); }).to.not.throwException(); }); - it('should not normalize the passed object unless normalize is true', function () { + it('should not normalize the passed object unless normalize is true', function() { var json = { name: 'foo', main: 'foo.js' }; bowerJson.parse(json); @@ -271,22 +337,24 @@ describe('.parse', function () { }); }); -describe('.getIssues', function () { - it('should print no errors even for weird package names', function () { +describe('.getIssues', function() { + it('should print no errors even for weird package names', function() { var json = { name: '@gruNt/my dependency' }; expect(bowerJson.getIssues(json).errors).to.be.empty(); }); - it('should validate the name length', function () { - var json = { name: 'a_123456789_123456789_123456789_123456789_123456789_z' }; + it('should validate the name length', function() { + var json = { + name: 'a_123456789_123456789_123456789_123456789_123456789_z' + }; expect(bowerJson.getIssues(json).warnings).to.contain( 'The "name" is too long, the limit is 50 characters' ); }); - it('should validate the name is lowercase', function () { + it('should validate the name is lowercase', function() { var json = { name: 'gruNt' }; expect(bowerJson.getIssues(json).warnings).to.contain( @@ -294,7 +362,7 @@ describe('.getIssues', function () { ); }); - it('should validate the name starts with lowercase', function () { + it('should validate the name starts with lowercase', function() { var json = { name: '-runt' }; expect(bowerJson.getIssues(json).warnings).to.contain( @@ -302,7 +370,7 @@ describe('.getIssues', function () { ); }); - it('should validate the name starts with lowercase', function () { + it('should validate the name starts with lowercase', function() { var json = { name: '.grunt' }; expect(bowerJson.getIssues(json).warnings).to.contain( @@ -310,7 +378,7 @@ describe('.getIssues', function () { ); }); - it('should validate the name ends with lowercase', function () { + it('should validate the name ends with lowercase', function() { var json = { name: 'grun-' }; expect(bowerJson.getIssues(json).warnings).to.contain( @@ -318,7 +386,7 @@ describe('.getIssues', function () { ); }); - it('should validate the name ends with lowercase', function () { + it('should validate the name ends with lowercase', function() { var json = { name: 'grun.' }; expect(bowerJson.getIssues(json).warnings).to.contain( @@ -326,13 +394,13 @@ describe('.getIssues', function () { ); }); - it('should validate the name is valid', function () { + it('should validate the name is valid', function() { var json = { name: 'gru.n-t' }; expect(bowerJson.getIssues(json).warnings).to.eql([]); }); - it('should validate the description length', function () { + it('should validate the description length', function() { var json = { name: 'foo', description: _s.repeat('æ', 141) @@ -343,7 +411,7 @@ describe('.getIssues', function () { ); }); - it('should validate the description is valid', function () { + it('should validate the description is valid', function() { var json = { name: 'foo', description: _s.repeat('æ', 140) @@ -352,7 +420,7 @@ describe('.getIssues', function () { expect(bowerJson.getIssues(json).warnings).to.eql([]); }); - it('should validate that main does not contain globs', function () { + it('should validate that main does not contain globs', function() { var json = { name: 'foo', main: ['js/*.js'] @@ -363,7 +431,7 @@ describe('.getIssues', function () { ); }); - it('should validate that main does not contain minified files', function () { + it('should validate that main does not contain minified files', function() { var json = { name: 'foo', main: ['foo.min.css'] @@ -374,7 +442,7 @@ describe('.getIssues', function () { ); }); - it('should validate that main does not contain fonts', function () { + it('should validate that main does not contain fonts', function() { var json = { name: 'foo', main: ['foo.woff'] @@ -385,7 +453,7 @@ describe('.getIssues', function () { ); }); - it('should validate that main does not contain images', function () { + it('should validate that main does not contain images', function() { var json = { name: 'foo', main: ['foo.png'] @@ -396,7 +464,7 @@ describe('.getIssues', function () { ); }); - it('should validate that main does not contain multiple files of the same filetype', function () { + it('should validate that main does not contain multiple files of the same filetype', function() { var json = { name: 'foo', main: ['foo.js', 'bar.js'] @@ -408,35 +476,35 @@ describe('.getIssues', function () { }); }); -describe('.validate', function () { - it('should validate the name property', function () { - expect(function () { +describe('.validate', function() { + it('should validate the name property', function() { + expect(function() { bowerJson.validate({}); }).to.throwException(/name/); }); - it('should validate the type of main', function () { + it('should validate the type of main', function() { var json = { name: 'foo', main: {} }; - expect(function () { + expect(function() { bowerJson.validate(json); }).to.throwException(); }); - it('should validate the type of items of an Array main', function () { + it('should validate the type of items of an Array main', function() { var json = { name: 'foo', main: [{}] }; - expect(function () { + expect(function() { bowerJson.validate(json); }).to.throwException(); }); }); -describe('.normalize', function () { - it('should normalize the main property', function () { +describe('.normalize', function() { + it('should normalize the main property', function() { var json = { name: 'foo', main: 'foo.js' }; bowerJson.normalize(json); @@ -444,34 +512,35 @@ describe('.normalize', function () { }); }); -describe('packages from bower registry', function () { - +describe('packages from bower registry', function() { var packageList, packageListUrl = 'http://registry.bower.io/packages'; this.timeout(60000); - it('can be downloaded from online source ' + packageListUrl, function(done) { - request({ - url: packageListUrl, - json: true - }, function(error, response, body) { - - if(error) { - throw error; - } - - expect(body).to.be.an('array'); - expect(body).to.not.be.empty(); - packageList = body; + it('can be downloaded from online source ' + packageListUrl, function( + done + ) { + request( + { + url: packageListUrl, + json: true + }, + function(error, response, body) { + if (error) { + throw error; + } - done(); + expect(body).to.be.an('array'); + expect(body).to.not.be.empty(); + packageList = body; - }); + done(); + } + ); }); - it('should validate each listed package', function (done) { - + it('should validate each listed package', function(done) { expect(packageList).to.be.an('array'); var invalidPackageCount = 0; @@ -479,19 +548,23 @@ describe('packages from bower registry', function () { packageList.forEach(function(package) { try { bowerJson.validate(package); - } catch(e) { + } catch (e) { invalidPackageCount++; - console.error('validation of "' + package.name + '" failed: ' + e.message); + console.error( + 'validation of "' + package.name + '" failed: ' + e.message + ); } - }); - if(invalidPackageCount) { - throw new Error(invalidPackageCount + '/' + packageList.length + ' package names do not validate'); + if (invalidPackageCount) { + throw new Error( + invalidPackageCount + + '/' + + packageList.length + + ' package names do not validate' + ); } done(); - }); }); - diff --git a/packages/bower-logger/lib/Logger.js b/packages/bower-logger/lib/Logger.js index 7c4dff10a..7ab40642e 100644 --- a/packages/bower-logger/lib/Logger.js +++ b/packages/bower-logger/lib/Logger.js @@ -10,18 +10,18 @@ function Logger() { util.inherits(Logger, EventEmitter); -Logger.prototype.intercept = function (fn) { +Logger.prototype.intercept = function(fn) { this._interceptors.push(fn); return this; }; -Logger.prototype.emit = function () { +Logger.prototype.emit = function() { var ret; var args = slice.call(arguments); // Run interceptors before if (args[0] === 'log') { - this._interceptors.forEach(function (interceptor) { + this._interceptors.forEach(function(interceptor) { interceptor.apply(this, args.slice(1)); }); } @@ -29,27 +29,27 @@ Logger.prototype.emit = function () { ret = EventEmitter.prototype.emit.apply(this, args); // Pipe - this._piped.forEach(function (emitter) { + this._piped.forEach(function(emitter) { emitter.emit.apply(emitter, args); }); return ret; }; -Logger.prototype.pipe = function (emitter) { +Logger.prototype.pipe = function(emitter) { this._piped.push(emitter); return emitter; }; -Logger.prototype.geminate = function () { +Logger.prototype.geminate = function() { var logger = new Logger(); logger.pipe(this); return logger; }; -Logger.prototype.log = function (level, id, message, data) { +Logger.prototype.log = function(level, id, message, data) { var log = { level: level, id: id, @@ -63,7 +63,7 @@ Logger.prototype.log = function (level, id, message, data) { return this; }; -Logger.prototype.prompt = function (prompts, callback) { +Logger.prototype.prompt = function(prompts, callback) { var fn; var one; var invalid; @@ -78,7 +78,7 @@ Logger.prototype.prompt = function (prompts, callback) { } // Validate prompt types - invalid = prompts.some(function (prompt) { + invalid = prompts.some(function(prompt) { return validPrompts.indexOf(prompt.type) === -1; }); @@ -88,20 +88,20 @@ Logger.prototype.prompt = function (prompts, callback) { return callback(error); } - fn = function (answers) { + fn = function(answers) { // Run callback only once if (runned) { return; } // Trim answers automatically - Object.keys(answers).forEach(function (key) { + Object.keys(answers).forEach(function(key) { var value = answers[key]; if (typeof value === 'string') { answers[key] = value.trim(); } else if (Array.isArray(value)) { - answers[key] = value.map(function (item) { + answers[key] = value.map(function(item) { if (typeof item === 'string') { return item.trim(); } @@ -124,25 +124,20 @@ Logger.prototype.prompt = function (prompts, callback) { // ------------------ -Logger._validPrompts = [ - 'input', - 'confirm', - 'password', - 'checkbox' -]; +Logger._validPrompts = ['input', 'confirm', 'password', 'checkbox']; Logger.LEVELS = { - 'error': 5, - 'conflict': 4, - 'warn': 3, - 'action': 2, - 'info': 1, - 'debug': 0 + error: 5, + conflict: 4, + warn: 3, + action: 2, + info: 1, + debug: 0 }; // Add helpful log methods -Object.keys(Logger.LEVELS).forEach(function (level) { - Logger.prototype[level] = function (id, message, data) { +Object.keys(Logger.LEVELS).forEach(function(level) { + Logger.prototype[level] = function(id, message, data) { this.log(level, id, message, data); }; }); diff --git a/packages/bower-logger/test/test.js b/packages/bower-logger/test/test.js index 54f394fab..8b69bf77d 100644 --- a/packages/bower-logger/test/test.js +++ b/packages/bower-logger/test/test.js @@ -2,57 +2,55 @@ var expect = require('expect.js'); var EventEmitter = require('events').EventEmitter; var Logger = require('../'); -describe('Logger', function () { +describe('Logger', function() { var logger; - beforeEach(function () { + beforeEach(function() { logger = new Logger(); }); - describe('.constructor', function () { - it('should provide an instance of Logger', function () { + describe('.constructor', function() { + it('should provide an instance of Logger', function() { expect(logger instanceof Logger).to.be(true); }); - it('should provide an instance of EventEmitter', function () { + it('should provide an instance of EventEmitter', function() { expect(logger instanceof EventEmitter).to.be(true); }); - it('should have prototype methods', function () { - var methods = [ - 'intercept', 'pipe', 'geminate', 'log' - ]; + it('should have prototype methods', function() { + var methods = ['intercept', 'pipe', 'geminate', 'log']; - methods.forEach(function (method) { + methods.forEach(function(method) { expect(logger).to.have.property(method); }); }); }); - describe('events', function () { + describe('events', function() { var logData = { foo: 'bar', baz: 'string' }; - it('should pass through {}', function (next) { - logger.on('log', function (log) { + it('should pass through {}', function(next) { + logger.on('log', function(log) { expect(log.data).to.eql({}); next(); }); logger.info(); }); - it('should pass through logData', function (next) { - logger.on('log', function (log) { + it('should pass through logData', function(next) { + logger.on('log', function(log) { expect(log.data).to.eql(logData); next(); }); logger.info('foo', 'message', logData); }); - it('should emit error event', function (next) { - logger.on('log', function (log) { + it('should emit error event', function(next) { + logger.on('log', function(log) { expect(log.level).to.eql('error'); expect(log.id).to.eql('foo'); expect(log.message).to.eql('error message'); @@ -62,8 +60,8 @@ describe('Logger', function () { logger.error('foo', 'error message'); }); - it('should emit conflict event', function (next) { - logger.on('log', function (log) { + it('should emit conflict event', function(next) { + logger.on('log', function(log) { expect(log.level).to.eql('conflict'); expect(log.id).to.eql('foo'); expect(log.message).to.eql('conflict message'); @@ -73,8 +71,8 @@ describe('Logger', function () { logger.conflict('foo', 'conflict message'); }); - it('should emit warn event', function (next) { - logger.on('log', function (log) { + it('should emit warn event', function(next) { + logger.on('log', function(log) { expect(log.level).to.eql('warn'); expect(log.id).to.eql('foo'); expect(log.message).to.eql('warn message'); @@ -84,8 +82,8 @@ describe('Logger', function () { logger.warn('foo', 'warn message'); }); - it('should emit action event', function (next) { - logger.on('log', function (log) { + it('should emit action event', function(next) { + logger.on('log', function(log) { expect(log.level).to.eql('action'); expect(log.id).to.eql('foo'); expect(log.message).to.eql('action message'); @@ -95,8 +93,8 @@ describe('Logger', function () { logger.action('foo', 'action message'); }); - it('should emit info event', function (next) { - logger.on('log', function (log) { + it('should emit info event', function(next) { + logger.on('log', function(log) { expect(log.level).to.eql('info'); expect(log.id).to.eql('foo'); expect(log.message).to.eql('info message'); @@ -106,8 +104,8 @@ describe('Logger', function () { logger.info('foo', 'info message'); }); - it('should emit debug event', function (next) { - logger.on('log', function (log) { + it('should emit debug event', function(next) { + logger.on('log', function(log) { expect(log.level).to.eql('debug'); expect(log.id).to.eql('foo'); expect(log.message).to.eql('debug message'); @@ -118,14 +116,14 @@ describe('Logger', function () { }); }); - describe('.intercept', function () { - it('should add the function and call it when a log occurs', function (next) { + describe('.intercept', function() { + it('should add the function and call it when a log occurs', function(next) { var called; var data = { - 'some': 'thing' + some: 'thing' }; - logger.intercept(function (log) { + logger.intercept(function(log) { called = true; expect(log).to.eql({ @@ -143,13 +141,13 @@ describe('Logger', function () { next(); }); - it('should call the interceptors by order before emitting the event', function (next) { + it('should call the interceptors by order before emitting the event', function(next) { var called = []; - logger.intercept(function () { + logger.intercept(function() { called.push(1); }); - logger.intercept(function () { + logger.intercept(function() { called.push(2); }); @@ -159,21 +157,21 @@ describe('Logger', function () { next(); }); - it('should call the interceptors along the chain', function (next) { + it('should call the interceptors along the chain', function(next) { var called = []; var childLogger = logger.geminate(); - childLogger.intercept(function () { + childLogger.intercept(function() { called.push(1); }); - logger.intercept(function () { + logger.intercept(function() { called.push(3); }); - childLogger.on('log', function () { + childLogger.on('log', function() { called.push(2); }); - logger.on('log', function () { + logger.on('log', function() { called.push(4); }); @@ -184,22 +182,22 @@ describe('Logger', function () { }); }); - describe('.pipe', function () { - it('should return the passed emitter', function () { + describe('.pipe', function() { + it('should return the passed emitter', function() { var otherEmitter = new EventEmitter(); expect(logger.pipe(otherEmitter)).to.equal(otherEmitter); }); - it('should pipe log events to another emitter', function (next) { + it('should pipe log events to another emitter', function(next) { var otherEmitter = new EventEmitter(); var data = { - 'some': 'thing' + some: 'thing' }; var piped; logger.pipe(otherEmitter); - otherEmitter.on('log', function (log) { + otherEmitter.on('log', function(log) { piped = true; expect(log).to.eql({ level: 'warn', @@ -216,8 +214,8 @@ describe('Logger', function () { }); }); - describe('.geminate', function () { - it('should return a new logger instance', function () { + describe('.geminate', function() { + it('should return a new logger instance', function() { var newLogger = logger.geminate(); expect(newLogger).to.be.an(Logger); @@ -225,14 +223,14 @@ describe('Logger', function () { expect(newLogger).to.not.be.equal(logger); }); - it('should pipe the new logger events to the original logger', function (next) { + it('should pipe the new logger events to the original logger', function(next) { var piped = []; var childLogger = logger.geminate(); var data = { - 'some': 'thing' + some: 'thing' }; - childLogger.on('log', function (log) { + childLogger.on('log', function(log) { piped.push(1); expect(log).to.eql({ level: 'warn', @@ -243,7 +241,7 @@ describe('Logger', function () { expect(log.data).to.equal(data); }); - logger.on('log', function (log) { + logger.on('log', function(log) { piped.push(2); expect(log).to.eql({ level: 'warn', @@ -260,130 +258,150 @@ describe('Logger', function () { }); }); - describe('.prompt', function () { - it('should only allow calling the callback once', function () { + describe('.prompt', function() { + it('should only allow calling the callback once', function() { var calls = 0; logger - .once('prompt', function (prompts, callback) { - callback({ prompt: 'bar' }); - callback({ prompt: 'foo' }); - }) - .prompt({ - type: 'input', - message: 'foo' - }, function () { - calls += 1; - }); + .once('prompt', function(prompts, callback) { + callback({ prompt: 'bar' }); + callback({ prompt: 'foo' }); + }) + .prompt( + { + type: 'input', + message: 'foo' + }, + function() { + calls += 1; + } + ); expect(calls).to.equal(1); }); - it('should accept a prompt', function (next) { + it('should accept a prompt', function(next) { logger - .once('prompt', function (prompts, callback) { - callback({ - prompt: 'bar' - }); - }) - .prompt({ - type: 'input', - message: 'foo' - }, function (err, answer) { - expect(err).to.not.be.ok(); - expect(answer).to.equal('bar'); - next(); - }); + .once('prompt', function(prompts, callback) { + callback({ + prompt: 'bar' + }); + }) + .prompt( + { + type: 'input', + message: 'foo' + }, + function(err, answer) { + expect(err).to.not.be.ok(); + expect(answer).to.equal('bar'); + next(); + } + ); }); - it('should accept several prompts', function (next) { + it('should accept several prompts', function(next) { logger - .once('prompt', function (prompts, callback) { - callback({ - foo: 'bar', - foz: 'baz' - }); - }) - .prompt([ + .once('prompt', function(prompts, callback) { + callback({ + foo: 'bar', + foz: 'baz' + }); + }) + .prompt( + [ + { + name: 'foo', + type: 'input', + message: 'foo' + }, + { + name: 'foz', + type: 'confirm', + message: 'foz' + } + ], + function(err, answer) { + expect(err).to.not.be.ok(); + expect(answer.foo).to.equal('bar'); + expect(answer.foz).to.equal('baz'); + + logger + .once('prompt', function(prompts, callback) { + callback({ + foo: 'bar' + }); + }) + .prompt( + [ + { + name: 'foo', + type: 'input', + message: 'foo' + } + ], + function(err, answer) { + expect(err).to.not.be.ok(); + expect(answer.foo).to.equal('bar'); + next(); + } + ); + } + ); + }); + + it('should error on invalid prompt type', function(next) { + logger.prompt( { - name: 'foo', - type: 'input', + type: 'xxx', message: 'foo' }, - { - name: 'foz', - type: 'confirm', - message: 'foz' + function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.be('ENOTSUP'); + next(); } - ], function (err, answer) { - expect(err).to.not.be.ok(); - expect(answer.foo).to.equal('bar'); - expect(answer.foz).to.equal('baz'); + ); + }); - logger - .once('prompt', function (prompts, callback) { + it('should trim the answers', function(next) { + logger + .once('prompt', function(prompts, callback) { callback({ - foo: 'bar' + prompt: ' bar ' }); }) - .prompt([ + .prompt( { - name: 'foo', type: 'input', message: 'foo' + }, + function(err, answer) { + expect(err).to.not.be.ok(); + expect(answer).to.equal('bar'); + next(); } - ], function (err, answer) { - expect(err).to.not.be.ok(); - expect(answer.foo).to.equal('bar'); - next(); - }); - }); + ); }); - it('should error on invalid prompt type', function (next) { - logger.prompt({ - type: 'xxx', - message: 'foo' - }, function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.be('ENOTSUP'); - next(); - }); - }); - - it('should trim the answers', function (next) { + it('should trim multiple response answers', function(next) { logger - .once('prompt', function (prompts, callback) { - callback({ - prompt: ' bar ' - }); - }) - .prompt({ - type: 'input', - message: 'foo' - }, function (err, answer) { - expect(err).to.not.be.ok(); - expect(answer).to.equal('bar'); - next(); - }); - }); - - it('should trim multiple response answers', function (next) { - logger - .once('prompt', function (prompts, callback) { - callback({ - prompt: [' bar ', ' foo', 'baz '] - }); - }) - .prompt({ - type: 'checkbox', - message: 'foo' - }, function (err, answer) { - expect(err).to.not.be.ok(); - expect(answer).to.eql(['bar', 'foo', 'baz']); - next(); - }); + .once('prompt', function(prompts, callback) { + callback({ + prompt: [' bar ', ' foo', 'baz '] + }); + }) + .prompt( + { + type: 'checkbox', + message: 'foo' + }, + function(err, answer) { + expect(err).to.not.be.ok(); + expect(answer).to.eql(['bar', 'foo', 'baz']); + next(); + } + ); }); - }); }); diff --git a/packages/bower-registry-client/Client.js b/packages/bower-registry-client/Client.js index 2714c3a5f..2beb7d4ee 100644 --- a/packages/bower-registry-client/Client.js +++ b/packages/bower-registry-client/Client.js @@ -7,12 +7,16 @@ function RegistryClient(config, logger) { this._config = config; if (!this._config.registry) { - throw new Error("You need to pass config as read by bower-config module. Registry field is missing."); + throw new Error( + 'You need to pass config as read by bower-config module. Registry field is missing.' + ); } // Cache defaults to storage registry if (!Object.prototype.hasOwnProperty.call(this._config, 'cache')) { - this._config.cache = this._config.storage ? this._config.storage.registry : null; + this._config.cache = this._config.storage + ? this._config.storage.registry + : null; } // Init the cache @@ -26,20 +30,23 @@ RegistryClient.prototype.list = methods.list; RegistryClient.prototype.register = methods.register; RegistryClient.prototype.unregister = methods.unregister; -RegistryClient.prototype.clearCache = function (name, callback) { +RegistryClient.prototype.clearCache = function(name, callback) { if (typeof name === 'function') { callback = name; name = null; } - async.parallel([ - this.lookup.clearCache.bind(this, name), - this.search.clearCache.bind(this, name), - this.list.clearCache.bind(this) - ], callback); + async.parallel( + [ + this.lookup.clearCache.bind(this, name), + this.search.clearCache.bind(this, name), + this.list.clearCache.bind(this) + ], + callback + ); }; -RegistryClient.prototype.resetCache = function (name) { +RegistryClient.prototype.resetCache = function(name) { this.lookup.resetCache.call(this, name); this.search.resetCache.call(this, name); this.list.resetCache.call(this); @@ -47,13 +54,13 @@ RegistryClient.prototype.resetCache = function (name) { return this; }; -RegistryClient.clearRuntimeCache = function () { +RegistryClient.clearRuntimeCache = function() { Cache.clearRuntimeCache(); }; // ----------------------------- -RegistryClient.prototype._initCache = function () { +RegistryClient.prototype._initCache = function() { var cache; var dir = this._config.cache; diff --git a/packages/bower-registry-client/Gruntfile.js b/packages/bower-registry-client/Gruntfile.js index d7e9d440c..0d8489729 100644 --- a/packages/bower-registry-client/Gruntfile.js +++ b/packages/bower-registry-client/Gruntfile.js @@ -1,16 +1,11 @@ -'use strict'; -module.exports = function (grunt) { +module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-simple-mocha'); grunt.initConfig({ jshint: { - files: [ - 'Gruntfile.js', - 'lib/**/*.js', - 'test/**/*.js' - ], + files: ['Gruntfile.js', 'lib/**/*.js', 'test/**/*.js'], options: { jshintrc: '.jshintrc' } diff --git a/packages/bower-registry-client/lib/list.js b/packages/bower-registry-client/lib/list.js index 4ad13566f..b7d0c40dd 100644 --- a/packages/bower-registry-client/lib/list.js +++ b/packages/bower-registry-client/lib/list.js @@ -20,59 +20,63 @@ function list(callback) { } // List packages in series in each registry - async.doUntil(function (next) { - var remote = url.parse(registry[index]); - var listCache = that._listCache[remote.host]; + async.doUntil( + function(next) { + var remote = url.parse(registry[index]); + var listCache = that._listCache[remote.host]; + + // If offline flag is passed, only query the cache + if (that._config.offline) { + return listCache.get('list', function(err, results) { + if (err || !results) { + return next(err); + } + + // Add each result + results.forEach(function(result) { + addResult.call(that, data, result); + }); + + next(); + }); + } - // If offline flag is passed, only query the cache - if (that._config.offline) { - return listCache.get('list', function (err, results) { + // Otherwise make a request to always obtain fresh data + doRequest.call(that, index, function(err, results) { if (err || !results) { return next(err); } // Add each result - results.forEach(function (result) { - addResult.call(that, data, result); + results.forEach(function(result) { + addResult(data, result); }); - next(); + // Store in cache for future offline usage + listCache.set('list', results, getMaxAge(), next); }); - } - - // Otherwise make a request to always obtain fresh data - doRequest.call(that, index, function (err, results) { - if (err || !results) { - return next(err); + }, + function() { + // Until there's still registries to test + return ++index === total; + }, + function(err) { + // Clear runtime cache, keeping the persistent data + // in files for future offline usage + resetCache(); + + // If some of the registry entries failed, error out + if (err) { + return callback(err); } - // Add each result - results.forEach(function (result) { - addResult(data, result); - }); - - // Store in cache for future offline usage - listCache.set('list', results, getMaxAge(), next); - }); - }, function () { - // Until there's still registries to test - return ++index === total; - }, function (err) { - // Clear runtime cache, keeping the persistent data - // in files for future offline usage - resetCache(); - - // If some of the registry entries failed, error out - if (err) { - return callback(err); + callback(null, data); } - - callback(null, data); - }); + ); } function addResult(accumulated, result) { - var exists = accumulated.some(function (current) { + var exists = accumulated.some(function(current) { return current.name === result.name; }); @@ -93,35 +97,69 @@ function doRequest(index, callback) { headers['User-Agent'] = this._config.userAgent; } - req = replay(request.get(requestUrl, { - ca: this._config.ca.search[index], - headers: headers, - strictSSL: this._config.strictSsl, - timeout: this._config.timeout, - json: true - }, function (err, response, body) { - // If there was an internal error (e.g. timeout) - if (err) { - return callback(createError('Request to ' + requestUrl + ' failed: ' + err.message, err.code)); - } + req = replay( + request.get( + requestUrl, + { + ca: this._config.ca.search[index], + headers: headers, + strictSSL: this._config.strictSsl, + timeout: this._config.timeout, + json: true + }, + function(err, response, body) { + // If there was an internal error (e.g. timeout) + if (err) { + return callback( + createError( + 'Request to ' + + requestUrl + + ' failed: ' + + err.message, + err.code + ) + ); + } - // Abort if there was an error (range different than 2xx) - if (response.statusCode < 200 || response.statusCode > 299) { - return callback(createError('Request to ' + requestUrl + ' failed with ' + response.statusCode, 'EINVRES')); - } + // Abort if there was an error (range different than 2xx) + if (response.statusCode < 200 || response.statusCode > 299) { + return callback( + createError( + 'Request to ' + + requestUrl + + ' failed with ' + + response.statusCode, + 'EINVRES' + ) + ); + } - // Validate response body, since we are expecting a JSON object - // If the server returns an invalid JSON, it's still a string - if (typeof body !== 'object') { - return callback(createError('Response of request to ' + requestUrl + ' is not a valid json', 'EINVRES')); - } + // Validate response body, since we are expecting a JSON object + // If the server returns an invalid JSON, it's still a string + if (typeof body !== 'object') { + return callback( + createError( + 'Response of request to ' + + requestUrl + + ' is not a valid json', + 'EINVRES' + ) + ); + } - callback(null, body); - })); + callback(null, body); + } + ) + ); if (this._logger) { - req.on('replay', function (replay) { - msg = 'Request to ' + requestUrl + ' failed with ' + replay.error.code + ', '; + req.on('replay', function(replay) { + msg = + 'Request to ' + + requestUrl + + ' failed with ' + + replay.error.code + + ', '; msg += 'retrying in ' + (replay.delay / 1000).toFixed(1) + 's'; that._logger.warn('retry', msg); }); @@ -137,7 +175,7 @@ function initCache() { this._listCache = this._cache.list || {}; // Generate a cache instance for each registry endpoint - this._config.registry.search.forEach(function (registry) { + this._config.registry.search.forEach(function(registry) { var cacheDir; var host = url.parse(registry).host; @@ -147,7 +185,11 @@ function initCache() { } if (this._config.cache) { - cacheDir = path.join(this._config.cache, encodeURIComponent(host), 'list'); + cacheDir = path.join( + this._config.cache, + encodeURIComponent(host), + 'list' + ); } this._listCache[host] = new Cache(cacheDir, { @@ -164,9 +206,13 @@ function clearCache(callback) { // There's only one key, which is 'list'.. // But we clear everything anyway - async.forEach(remotes, function (remote, next) { - listCache[remote].clear(next); - }, callback); + async.forEach( + remotes, + function(remote, next) { + listCache[remote].clear(next); + }, + callback + ); } function resetCache() { diff --git a/packages/bower-registry-client/lib/lookup.js b/packages/bower-registry-client/lib/lookup.js index 7164bce5c..638af93e9 100644 --- a/packages/bower-registry-client/lib/lookup.js +++ b/packages/bower-registry-client/lib/lookup.js @@ -20,22 +20,37 @@ function lookup(name, callback) { // Lookup package in series in each registry // endpoint until we got the data - async.doUntil(function (next) { - var remote = url.parse(registry[index]); - var lookupCache = that._lookupCache[remote.host]; - - // If force flag is disabled we check the cache - if (!that._config.force) { - lookupCache.get(name, function (err, value) { - data = value; - - // Don't proceed with making a request if we got an error, - // a value from the cache or if the offline flag is enabled - if (err || data || that._config.offline) { - return next(err); - } + async.doUntil( + function(next) { + var remote = url.parse(registry[index]); + var lookupCache = that._lookupCache[remote.host]; + + // If force flag is disabled we check the cache + if (!that._config.force) { + lookupCache.get(name, function(err, value) { + data = value; + + // Don't proceed with making a request if we got an error, + // a value from the cache or if the offline flag is enabled + if (err || data || that._config.offline) { + return next(err); + } - doRequest.call(that, name, index, function (err, entry) { + doRequest.call(that, name, index, function(err, entry) { + if (err || !entry) { + return next(err); + } + + data = entry; + + // Store in cache + lookupCache.set(name, entry, getMaxAge(entry), next); + }); + }); + // Otherwise, we totally bypass the cache and + // make only the request + } else { + doRequest.call(that, name, index, function(err, entry) { if (err || !entry) { return next(err); } @@ -45,38 +60,30 @@ function lookup(name, callback) { // Store in cache lookupCache.set(name, entry, getMaxAge(entry), next); }); - }); - // Otherwise, we totally bypass the cache and - // make only the request - } else { - doRequest.call(that, name, index, function (err, entry) { - if (err || !entry) { - return next(err); - } - - data = entry; - - // Store in cache - lookupCache.set(name, entry, getMaxAge(entry), next); - }); + } + }, + function() { + // Until the data is unknown or there's still registries to test + return !!data || ++index === total; + }, + function(err) { + // If some of the registry entries failed, error out + if (err) { + return callback(err); + } + + callback(null, data); } - }, function () { - // Until the data is unknown or there's still registries to test - return !!data || ++index === total; - }, function (err) { - // If some of the registry entries failed, error out - if (err) { - return callback(err); - } - - callback(null, data); - }); + ); } function doRequest(name, index, callback) { var req; var msg; - var requestUrl = this._config.registry.search[index] + '/packages/' + encodeURIComponent(name); + var requestUrl = + this._config.registry.search[index] + + '/packages/' + + encodeURIComponent(name); var remote = url.parse(requestUrl); var headers = {}; var that = this; @@ -85,47 +92,81 @@ function doRequest(name, index, callback) { headers['User-Agent'] = this._config.userAgent; } - req = replay(request.get(requestUrl, { - headers: headers, - ca: this._config.ca.search[index], - strictSSL: this._config.strictSsl, - timeout: this._config.timeout, - json: true - }, function (err, response, body) { - // If there was an internal error (e.g. timeout) - if (err) { - return callback(createError('Request to ' + requestUrl + ' failed: ' + err.message, err.code)); - } + req = replay( + request.get( + requestUrl, + { + headers: headers, + ca: this._config.ca.search[index], + strictSSL: this._config.strictSsl, + timeout: this._config.timeout, + json: true + }, + function(err, response, body) { + // If there was an internal error (e.g. timeout) + if (err) { + return callback( + createError( + 'Request to ' + + requestUrl + + ' failed: ' + + err.message, + err.code + ) + ); + } - // If not found, try next - if (response.statusCode === 404) { - return callback(); - } + // If not found, try next + if (response.statusCode === 404) { + return callback(); + } - // Abort if there was an error (range different than 2xx) - if (response.statusCode < 200 || response.statusCode > 299) { - return callback(createError('Request to ' + requestUrl + ' failed with ' + response.statusCode, 'EINVRES')); - } + // Abort if there was an error (range different than 2xx) + if (response.statusCode < 200 || response.statusCode > 299) { + return callback( + createError( + 'Request to ' + + requestUrl + + ' failed with ' + + response.statusCode, + 'EINVRES' + ) + ); + } - // Validate response body, since we are expecting a JSON object - // If the server returns an invalid JSON, it's still a string - if (typeof body !== 'object') { - return callback(createError('Response of request to ' + requestUrl + ' is not a valid json', 'EINVRES')); - } + // Validate response body, since we are expecting a JSON object + // If the server returns an invalid JSON, it's still a string + if (typeof body !== 'object') { + return callback( + createError( + 'Response of request to ' + + requestUrl + + ' is not a valid json', + 'EINVRES' + ) + ); + } - var data; - if (body.url) { - data = { - type: 'alias', - url: body.url - }; - } - callback(null, data); - })); + var data; + if (body.url) { + data = { + type: 'alias', + url: body.url + }; + } + callback(null, data); + } + ) + ); if (this._logger) { - req.on('replay', function (replay) { - msg = 'Request to ' + requestUrl + ' failed with ' + replay.error.code + ', '; + req.on('replay', function(replay) { + msg = + 'Request to ' + + requestUrl + + ' failed with ' + + replay.error.code + + ', '; msg += 'retrying in ' + (replay.delay / 1000).toFixed(1) + 's'; that._logger.warn('retry', msg); }); @@ -146,7 +187,7 @@ function initCache() { this._lookupCache = this._cache.lookup || {}; // Generate a cache instance for each registry endpoint - this._config.registry.search.forEach(function (registry) { + this._config.registry.search.forEach(function(registry) { var cacheDir; var host = url.parse(registry).host; @@ -156,7 +197,11 @@ function initCache() { } if (this._config.cache) { - cacheDir = path.join(this._config.cache, encodeURIComponent(host), 'lookup'); + cacheDir = path.join( + this._config.cache, + encodeURIComponent(host), + 'lookup' + ); } this._lookupCache[host] = new Cache(cacheDir, { @@ -177,13 +222,21 @@ function clearCache(name, callback) { } if (name) { - async.forEach(remotes, function (remote, next) { - lookupCache[remote].del(name, next); - }, callback); + async.forEach( + remotes, + function(remote, next) { + lookupCache[remote].del(name, next); + }, + callback + ); } else { - async.forEach(remotes, function (remote, next) { - lookupCache[remote].clear(next); - }, callback); + async.forEach( + remotes, + function(remote, next) { + lookupCache[remote].clear(next); + }, + callback + ); } } diff --git a/packages/bower-registry-client/lib/register.js b/packages/bower-registry-client/lib/register.js index b6929ff0c..6e5762fca 100644 --- a/packages/bower-registry-client/lib/register.js +++ b/packages/bower-registry-client/lib/register.js @@ -16,43 +16,61 @@ function register(name, url, callback) { requestUrl += '?access_token=' + config.accessToken; } - request.post({ - url: requestUrl, - headers: headers, - ca: config.ca.register, - strictSSL: config.strictSsl, - timeout: config.timeout, - json: true, - form: { - name: name, - url: url - } - }, function (err, response) { - // If there was an internal error (e.g. timeout) - if (err) { - return callback(createError('Request to ' + requestUrl + ' failed: ' + err.message, err.code)); - } + request.post( + { + url: requestUrl, + headers: headers, + ca: config.ca.register, + strictSSL: config.strictSsl, + timeout: config.timeout, + json: true, + form: { + name: name, + url: url + } + }, + function(err, response) { + // If there was an internal error (e.g. timeout) + if (err) { + return callback( + createError( + 'Request to ' + requestUrl + ' failed: ' + err.message, + err.code + ) + ); + } - // Duplicate - if (response.statusCode === 403) { - return callback(createError('Duplicate package', 'EDUPLICATE')); - } + // Duplicate + if (response.statusCode === 403) { + return callback(createError('Duplicate package', 'EDUPLICATE')); + } - // Invalid format - if (response.statusCode === 400) { - return callback(createError('Invalid URL format', 'EINVFORMAT')); - } + // Invalid format + if (response.statusCode === 400) { + return callback( + createError('Invalid URL format', 'EINVFORMAT') + ); + } - // Everything other than 201 is unknown - if (response.statusCode !== 201) { - return callback(createError('Unknown error: ' + response.statusCode + ' - ' + response.body, 'EUNKNOWN')); - } + // Everything other than 201 is unknown + if (response.statusCode !== 201) { + return callback( + createError( + 'Unknown error: ' + + response.statusCode + + ' - ' + + response.body, + 'EUNKNOWN' + ) + ); + } - callback(null, { - name: name, - url: url - }); - }); + callback(null, { + name: name, + url: url + }); + } + ); } module.exports = register; diff --git a/packages/bower-registry-client/lib/search.js b/packages/bower-registry-client/lib/search.js index c994c68f7..e0fc07cc3 100644 --- a/packages/bower-registry-client/lib/search.js +++ b/packages/bower-registry-client/lib/search.js @@ -28,59 +28,63 @@ function search(name, callback) { // Search package in series in each registry, // merging results together - async.doUntil(function (next) { - var remote = url.parse(registry[index]); - var searchCache = that._searchCache[remote.host]; + async.doUntil( + function(next) { + var remote = url.parse(registry[index]); + var searchCache = that._searchCache[remote.host]; + + // If offline flag is passed, only query the cache + if (that._config.offline) { + return searchCache.get(name, function(err, results) { + if (err || !results || !results.length) { + return next(err); + } + + // Add each result + results.forEach(function(result) { + addResult.call(that, data, result); + }); + + next(); + }); + } - // If offline flag is passed, only query the cache - if (that._config.offline) { - return searchCache.get(name, function (err, results) { + // Otherwise make a request to always obtain fresh data + doRequest.call(that, name, index, function(err, results) { if (err || !results || !results.length) { return next(err); } // Add each result - results.forEach(function (result) { + results.forEach(function(result) { addResult.call(that, data, result); }); - next(); + // Store in cache for future offline usage + searchCache.set(name, results, getMaxAge(), next); }); - } - - // Otherwise make a request to always obtain fresh data - doRequest.call(that, name, index, function (err, results) { - if (err || !results || !results.length) { - return next(err); + }, + function() { + // Until the data is unknown or there's still registries to test + return ++index === total; + }, + function(err) { + // Clear runtime cache, keeping the persistent data + // in files for future offline usage + resetCache(); + + // If some of the registry entries failed, error out + if (err) { + return callback(err); } - // Add each result - results.forEach(function (result) { - addResult.call(that, data, result); - }); - - // Store in cache for future offline usage - searchCache.set(name, results, getMaxAge(), next); - }); - }, function () { - // Until the data is unknown or there's still registries to test - return ++index === total; - }, function (err) { - // Clear runtime cache, keeping the persistent data - // in files for future offline usage - resetCache(); - - // If some of the registry entries failed, error out - if (err) { - return callback(err); + callback(null, data); } - - callback(null, data); - }); + ); } function addResult(accumulated, result) { - var exists = accumulated.some(function (current) { + var exists = accumulated.some(function(current) { return current.name === result.name; }); @@ -92,7 +96,10 @@ function addResult(accumulated, result) { function doRequest(name, index, callback) { var req; var msg; - var requestUrl = this._config.registry.search[index] + '/packages/search/' + encodeURIComponent(name); + var requestUrl = + this._config.registry.search[index] + + '/packages/search/' + + encodeURIComponent(name); var remote = url.parse(requestUrl); var headers = {}; var that = this; @@ -101,35 +108,69 @@ function doRequest(name, index, callback) { headers['User-Agent'] = this._config.userAgent; } - req = replay(request.get(requestUrl, { - headers: headers, - ca: this._config.ca.search[index], - strictSSL: this._config.strictSsl, - timeout: this._config.timeout, - json: true - }, function (err, response, body) { - // If there was an internal error (e.g. timeout) - if (err) { - return callback(createError('Request to ' + requestUrl + ' failed: ' + err.message, err.code)); - } + req = replay( + request.get( + requestUrl, + { + headers: headers, + ca: this._config.ca.search[index], + strictSSL: this._config.strictSsl, + timeout: this._config.timeout, + json: true + }, + function(err, response, body) { + // If there was an internal error (e.g. timeout) + if (err) { + return callback( + createError( + 'Request to ' + + requestUrl + + ' failed: ' + + err.message, + err.code + ) + ); + } - // Abort if there was an error (range different than 2xx) - if (response.statusCode < 200 || response.statusCode > 299) { - return callback(createError('Request to ' + requestUrl + ' failed with ' + response.statusCode, 'EINVRES')); - } + // Abort if there was an error (range different than 2xx) + if (response.statusCode < 200 || response.statusCode > 299) { + return callback( + createError( + 'Request to ' + + requestUrl + + ' failed with ' + + response.statusCode, + 'EINVRES' + ) + ); + } - // Validate response body, since we are expecting a JSON object - // If the server returns an invalid JSON, it's still a string - if (typeof body !== 'object') { - return callback(createError('Response of request to ' + requestUrl + ' is not a valid json', 'EINVRES')); - } + // Validate response body, since we are expecting a JSON object + // If the server returns an invalid JSON, it's still a string + if (typeof body !== 'object') { + return callback( + createError( + 'Response of request to ' + + requestUrl + + ' is not a valid json', + 'EINVRES' + ) + ); + } - callback(null, body); - })); + callback(null, body); + } + ) + ); if (this._logger) { - req.on('replay', function (replay) { - msg = 'Request to ' + requestUrl + ' failed with ' + replay.error.code + ', '; + req.on('replay', function(replay) { + msg = + 'Request to ' + + requestUrl + + ' failed with ' + + replay.error.code + + ', '; msg += 'retrying in ' + (replay.delay / 1000).toFixed(1) + 's'; that._logger.warn('retry', msg); }); @@ -145,7 +186,7 @@ function initCache() { this._searchCache = this._cache.search || {}; // Generate a cache instance for each registry endpoint - this._config.registry.search.forEach(function (registry) { + this._config.registry.search.forEach(function(registry) { var cacheDir; var host = url.parse(registry).host; @@ -155,7 +196,11 @@ function initCache() { } if (this._config.cache) { - cacheDir = path.join(this._config.cache, encodeURIComponent(host), 'search'); + cacheDir = path.join( + this._config.cache, + encodeURIComponent(host), + 'search' + ); } this._searchCache[host] = new Cache(cacheDir, { @@ -180,9 +225,13 @@ function clearCache(name, callback) { // One possible solution would be to read every entry from the cache and // delete if the package is contained in the search results // But this is too expensive - async.forEach(remotes, function (remote, next) { - searchCache[remote].clear(next); - }, callback); + async.forEach( + remotes, + function(remote, next) { + searchCache[remote].clear(next); + }, + callback + ); } function resetCache() { diff --git a/packages/bower-registry-client/lib/unregister.js b/packages/bower-registry-client/lib/unregister.js index d4378c687..6350b6a5f 100644 --- a/packages/bower-registry-client/lib/unregister.js +++ b/packages/bower-registry-client/lib/unregister.js @@ -16,32 +16,40 @@ function unregister(name, callback) { requestUrl += '?access_token=' + config.accessToken; } - request.del({ - url: requestUrl, - headers: headers, - ca: config.ca.register, - strictSSL: config.strictSsl, - timeout: config.timeout - }, function (err, response) { - // If there was an internal error (e.g. timeout) - if (err) { - return callback(createError('Request to ' + requestUrl + ' failed: ' + err.message, err.code)); + request.del( + { + url: requestUrl, + headers: headers, + ca: config.ca.register, + strictSSL: config.strictSsl, + timeout: config.timeout + }, + function(err, response) { + // If there was an internal error (e.g. timeout) + if (err) { + return callback( + createError( + 'Request to ' + requestUrl + ' failed: ' + err.message, + err.code + ) + ); + } + + // Forbidden + if (response.statusCode === 403) { + return callback(createError(response.body, 'EFORBIDDEN')); + } + + // Everything other than 204 is unknown + if (response.statusCode !== 204) { + return callback(createError(response.body, 'EUNKNOWN')); + } + + callback(null, { + name: name + }); } - - // Forbidden - if (response.statusCode === 403) { - return callback(createError(response.body, 'EFORBIDDEN')); - } - - // Everything other than 204 is unknown - if (response.statusCode !== 204) { - return callback(createError(response.body, 'EUNKNOWN')); - } - - callback(null, { - name: name - }); - }); + ); } module.exports = unregister; diff --git a/packages/bower-registry-client/lib/util/Cache.js b/packages/bower-registry-client/lib/util/Cache.js index c490b9182..73f863dbe 100644 --- a/packages/bower-registry-client/lib/util/Cache.js +++ b/packages/bower-registry-client/lib/util/Cache.js @@ -22,7 +22,7 @@ function Cache(dir, options) { } } -Cache.prototype.get = function (key, callback) { +Cache.prototype.get = function(key, callback) { var file; var json = this._cache.get(key); @@ -43,35 +43,38 @@ Cache.prototype.get = function (key, callback) { } file = this._getFile(key); - fs.readFile(file, function (err, contents) { - var json; - - // Check if there was an error reading - // Note that if the file does not exist then - // we don't have its value - if (err) { - return callback(err.code === 'ENOENT' ? null : err); - } - - // If there was an error reading the file as json - // simply assume it doesn't exist - try { - json = JSON.parse(contents.toString()); - } catch (e) { - return this.del(key, callback); // If so, delete it - } - - // Check if it has expired - if (this._hasExpired(json)) { - return this.del(key, callback); - } - - this._cache.set(key, json); - callback(null, json.value); - }.bind(this)); + fs.readFile( + file, + function(err, contents) { + var json; + + // Check if there was an error reading + // Note that if the file does not exist then + // we don't have its value + if (err) { + return callback(err.code === 'ENOENT' ? null : err); + } + + // If there was an error reading the file as json + // simply assume it doesn't exist + try { + json = JSON.parse(contents.toString()); + } catch (e) { + return this.del(key, callback); // If so, delete it + } + + // Check if it has expired + if (this._hasExpired(json)) { + return this.del(key, callback); + } + + this._cache.set(key, json); + callback(null, json.value); + }.bind(this) + ); }; -Cache.prototype.set = function (key, value, maxAge, callback) { +Cache.prototype.set = function(key, value, maxAge, callback) { var file; var entry; var str; @@ -102,7 +105,7 @@ Cache.prototype.set = function (key, value, maxAge, callback) { fs.writeFile(file, str, callback); }; -Cache.prototype.del = function (key, callback) { +Cache.prototype.del = function(key, callback) { // Delete from memory this._cache.del(key); @@ -111,7 +114,7 @@ Cache.prototype.del = function (key, callback) { return callback(null); } - fs.unlink(this._getFile(key), function (err) { + fs.unlink(this._getFile(key), function(err) { if (err && err.code !== 'ENOENT') { return callback(err); } @@ -120,7 +123,7 @@ Cache.prototype.del = function (key, callback) { }); }; -Cache.prototype.clear = function (callback) { +Cache.prototype.clear = function(callback) { var dir = this._dir; // Clear in memory cache @@ -131,35 +134,39 @@ Cache.prototype.clear = function (callback) { return callback(null); } - fs.readdir(dir, function (err, files) { + fs.readdir(dir, function(err, files) { if (err) { return callback(err); } // Delete every file in parallel - async.forEach(files, function (file, next) { - fs.unlink(path.join(dir, file), function (err) { - if (err && err.code !== 'ENOENT') { - return next(err); - } - - next(); - }); - }, callback); + async.forEach( + files, + function(file, next) { + fs.unlink(path.join(dir, file), function(err) { + if (err && err.code !== 'ENOENT') { + return next(err); + } + + next(); + }); + }, + callback + ); }); }; -Cache.prototype.reset = function () { +Cache.prototype.reset = function() { this._cache.reset(); }; -Cache.clearRuntimeCache = function () { +Cache.clearRuntimeCache = function() { // Note that _cache refers to the static _cache variable // that holds other caches per dir! // Do not confuse it with the instance cache // Clear cache of each directory - this._cache.forEach(function (cache) { + this._cache.forEach(function(cache) { cache.reset(); }); @@ -169,7 +176,7 @@ Cache.clearRuntimeCache = function () { //------------------------------- -Cache.prototype._hasExpired = function (json) { +Cache.prototype._hasExpired = function(json) { var expires = json.expires; if (!expires || this._options.useStale) { @@ -180,16 +187,19 @@ Cache.prototype._hasExpired = function (json) { return Date.now() > expires; }; -Cache.prototype._getFile = function (key) { +Cache.prototype._getFile = function(key) { // Append a truncated md5 to the end of the file to solve case issues // on case insensitive file systems // See: https://github.com/bower/bower/issues/859 - return path.join(this._dir, encodeURIComponent(key) + '_' + md5(key).substr(0, 5)); + return path.join( + this._dir, + encodeURIComponent(key) + '_' + md5(key).substr(0, 5) + ); }; Cache._cache = new LRU({ max: 5, - maxAge: 60 * 30 * 1000 // 30 minutes + maxAge: 60 * 30 * 1000 // 30 minutes }); module.exports = Cache; diff --git a/packages/bower-registry-client/lib/util/md5.js b/packages/bower-registry-client/lib/util/md5.js index dbc920b04..a54b03adb 100644 --- a/packages/bower-registry-client/lib/util/md5.js +++ b/packages/bower-registry-client/lib/util/md5.js @@ -1,7 +1,10 @@ var crypto = require('crypto'); function md5(contents) { - return crypto.createHash('md5').update(contents).digest('hex'); + return crypto + .createHash('md5') + .update(contents) + .digest('hex'); } module.exports = md5; diff --git a/packages/bower-registry-client/test/Client.js b/packages/bower-registry-client/test/Client.js index a25b6435f..570e6f349 100644 --- a/packages/bower-registry-client/test/Client.js +++ b/packages/bower-registry-client/test/Client.js @@ -6,14 +6,16 @@ var nock = require('nock'); var http = require('http'); var Config = require('bower-config'); -describe('RegistryClient', function () { - beforeEach(function () { +describe('RegistryClient', function() { + beforeEach(function() { this.uri = 'https://registry.bower.io'; this.timeoutVal = 5000; - this.registry = new RegistryClient(Config.read(process.cwd(), { - strictSsl: false, - timeout: this.timeoutVal - })); + this.registry = new RegistryClient( + Config.read(process.cwd(), { + strictSsl: false, + timeout: this.timeoutVal + }) + ); this.conf = { default: this.uri, @@ -23,133 +25,150 @@ describe('RegistryClient', function () { }; }); - describe('Constructor', function () { - describe('instantiating a client', function () { - it('should provide an instance of RegistryClient', function () { + describe('Constructor', function() { + describe('instantiating a client', function() { + it('should provide an instance of RegistryClient', function() { expect(this.registry instanceof RegistryClient).to.be.ok; }); - it('should set default registry config', function () { + it('should set default registry config', function() { expect(this.registry._config.registry).to.eql(this.conf); }); - it('should set default search config', function () { - expect(this.registry._config.registry.search[0]).to.eql(this.uri); + it('should set default search config', function() { + expect(this.registry._config.registry.search[0]).to.eql( + this.uri + ); }); - it('should set default register config', function () { - expect(this.registry._config.registry.register).to.eql(this.uri); + it('should set default register config', function() { + expect(this.registry._config.registry.register).to.eql( + this.uri + ); }); - it('should set default publish config', function () { + it('should set default publish config', function() { expect(this.registry._config.registry.publish).to.eql(this.uri); }); - it('should set default cache path config', function () { - expect(typeof this.registry._config.cache === 'string').to.be.ok; + it('should set default cache path config', function() { + expect(typeof this.registry._config.cache === 'string').to.be + .ok; }); - it('should set default timeout config', function () { + it('should set default timeout config', function() { expect(this.registry._config.timeout).to.eql(this.timeoutVal); }); - it('should set default strictSsl config', function () { + it('should set default strictSsl config', function() { expect(this.registry._config.strictSsl).to.be(false); }); }); - it('should have a lookup prototype method', function () { + it('should have a lookup prototype method', function() { expect(RegistryClient.prototype).to.have.property('lookup'); }); - it('should have a search prototype method', function () { + it('should have a search prototype method', function() { expect(RegistryClient.prototype).to.have.property('search'); }); - it('should have a list prototype method', function () { + it('should have a list prototype method', function() { expect(RegistryClient.prototype).to.have.property('list'); }); - it('should have a register prototype method', function () { + it('should have a register prototype method', function() { expect(RegistryClient.prototype).to.have.property('register'); }); - it('should have a clearCache prototype method', function () { + it('should have a clearCache prototype method', function() { expect(RegistryClient.prototype).to.have.property('clearCache'); }); - it('should have a resetCache prototype method', function () { + it('should have a resetCache prototype method', function() { expect(RegistryClient.prototype).to.have.property('resetCache'); }); - it('should have a clearRuntimeCache static method', function () { + it('should have a clearRuntimeCache static method', function() { expect(RegistryClient).to.have.property('clearRuntimeCache'); }); }); - describe('instantiating a client with custom options', function () { - describe('offline', function () { - it('should not return search results if cache is empty', function (next) { + describe('instantiating a client with custom options', function() { + describe('offline', function() { + it('should not return search results if cache is empty', function(next) { // TODO: this test should be made individually for search, list and lookup - this.registry.clearCache(function () { - this.registry._config.offline = true; - this.registry.search('jquery', function (err, results) { - expect(err).to.be(null); - expect(results.length).to.eql(0); - next(); - }); - }.bind(this)); + this.registry.clearCache( + function() { + this.registry._config.offline = true; + this.registry.search('jquery', function(err, results) { + expect(err).to.be(null); + expect(results.length).to.eql(0); + next(); + }); + }.bind(this) + ); }); }); - describe('cache', function () { - beforeEach(function () { + describe('cache', function() { + beforeEach(function() { nock('https://registry.bower.io:443') - .get('/packages/search/jquery') - .replyWithFile(200, __dirname + '/fixtures/search.json'); + .get('/packages/search/jquery') + .replyWithFile(200, __dirname + '/fixtures/search.json'); - this.client = new RegistryClient(Config.read(process.cwd(), { - cache: __dirname + '/cache', - strictSsl: false - })); + this.client = new RegistryClient( + Config.read(process.cwd(), { + cache: __dirname + '/cache', + strictSsl: false + }) + ); this.cacheDir = this.client._config.cache; this.host = 'registry.bower.io'; this.method = 'search'; this.pkg = 'jquery'; - this.path = this.cacheDir + '/' + this.host + '/' + this.method + '/' + this.pkg + '_' + md5(this.pkg).substr(0, 5); + this.path = + this.cacheDir + + '/' + + this.host + + '/' + + this.method + + '/' + + this.pkg + + '_' + + md5(this.pkg).substr(0, 5); }); - afterEach(function (next) { + afterEach(function(next) { this.client.clearCache(next); }); - it('should fill cache', function (next) { + it('should fill cache', function(next) { var self = this; // fill cache - self.client.search(self.pkg, function (err, results) { + self.client.search(self.pkg, function(err, results) { expect(err).to.be(null); expect(results.length).to.eql(334); // check for cache existence - fs.exists(self.path, function (exists) { + fs.exists(self.path, function(exists) { expect(exists).to.be(true); next(); }); }); - }); - it('should read results from cache', function (next) { + it('should read results from cache', function(next) { var self = this; - self.client.search(self.pkg, function (err, results) { + self.client.search(self.pkg, function(err, results) { expect(err).to.be(null); expect(results.length).to.eql(334); - fs.exists(self.path, function (exists) { + fs.exists(self.path, function(exists) { expect(exists).to.be(true); next(); }); @@ -158,50 +177,51 @@ describe('RegistryClient', function () { }); }); - // // lookup // - describe('calling the lookup instance method with argument', function () { - beforeEach(function () { + describe('calling the lookup instance method with argument', function() { + beforeEach(function() { nock('https://registry.bower.io:443') - .get('/packages/jquery') - .reply(200, { - name: 'jquery', - url: 'git://github.com/components/jquery.git' - }); + .get('/packages/jquery') + .reply(200, { + name: 'jquery', + url: 'git://github.com/components/jquery.git' + }); this.registry._config.force = true; }); - it('should not return an error', function (next) { - this.registry.lookup('jquery', function (err) { + it('should not return an error', function(next) { + this.registry.lookup('jquery', function(err) { expect(err).to.be(null); next(); }); }); - it('should return entry type', function (next) { - this.registry.lookup('jquery', function (err, entry) { + it('should return entry type', function(next) { + this.registry.lookup('jquery', function(err, entry) { expect(err).to.be(null); expect(entry.type).to.eql('alias'); next(); }); }); - it('should return entry url ', function (next) { - this.registry.lookup('jquery', function (err, entry) { + it('should return entry url ', function(next) { + this.registry.lookup('jquery', function(err, entry) { expect(err).to.be(null); - expect(entry.url).to.eql('git://github.com/components/jquery.git'); + expect(entry.url).to.eql( + 'git://github.com/components/jquery.git' + ); }); next(); }); }); - describe('calling the lookup instance method without argument', function () { - it('should return no result', function (next) { + describe('calling the lookup instance method without argument', function() { + it('should return no result', function(next) { this.timeout(10000); - this.registry.lookup('', function (err, entry) { + this.registry.lookup('', function(err, entry) { expect(err).to.not.be.ok(); expect(entry).to.not.be.ok(); next(); @@ -209,38 +229,40 @@ describe('RegistryClient', function () { }); }); - describe('calling the lookup instance method with two registries, and the first missing.', function () { - beforeEach(function () { + describe('calling the lookup instance method with two registries, and the first missing.', function() { + beforeEach(function() { nock('http://custom-registry.com') - .get('/packages/jquery') - .reply(200, { - 'error': { - 'message': 'missing', - 'stack': 'Error: missing' - } - }); + .get('/packages/jquery') + .reply(200, { + error: { + message: 'missing', + stack: 'Error: missing' + } + }); nock('http://custom-registry2.com') - .get('/packages/jquery') - .reply(200, { - name: 'jquery', - url: 'git://github.com/foo/baz' - }); - - this.registry = new RegistryClient(Config.read(process.cwd(), { - strictSsl: false, - force: true, - registry: { - search: [ - 'http://custom-registry.com', - 'http://custom-registry2.com' - ] - } - })); - }); + .get('/packages/jquery') + .reply(200, { + name: 'jquery', + url: 'git://github.com/foo/baz' + }); - it('should return entry type', function (next) { - this.registry.lookup('jquery', function (err, entry) { + this.registry = new RegistryClient( + Config.read(process.cwd(), { + strictSsl: false, + force: true, + registry: { + search: [ + 'http://custom-registry.com', + 'http://custom-registry2.com' + ] + } + }) + ); + }); + + it('should return entry type', function(next) { + this.registry.lookup('jquery', function(err, entry) { expect(err).to.be(null); expect(entry).to.be.an('object'); expect(entry.type).to.eql('alias'); @@ -248,8 +270,8 @@ describe('RegistryClient', function () { }); }); - it('should return entry url ', function (next) { - this.registry.lookup('jquery', function (err, entry) { + it('should return entry url ', function(next) { + this.registry.lookup('jquery', function(err, entry) { expect(err).to.be(null); expect(entry).to.be.an('object'); expect(entry.url).to.eql('git://github.com/foo/baz'); @@ -258,41 +280,43 @@ describe('RegistryClient', function () { }); }); - describe('calling the lookup instance method with three registries', function () { - beforeEach(function () { + describe('calling the lookup instance method with three registries', function() { + beforeEach(function() { nock('https://registry.bower.io:443') - .get('/packages/jquery') - .reply(404); + .get('/packages/jquery') + .reply(404); nock('http://custom-registry.com') - .get('/packages/jquery') - .reply(200, { - name: 'jquery', - url: 'git://github.com/foo/bar' - }); + .get('/packages/jquery') + .reply(200, { + name: 'jquery', + url: 'git://github.com/foo/bar' + }); nock('http://custom-registry2.com') - .get('/packages/jquery') - .reply(200, { - name: 'jquery', - url: 'git://github.com/foo/baz' - }); - - this.registry = new RegistryClient(Config.read(process.cwd(), { - strictSsl: false, - force: true, - registry: { - search: [ - 'https://registry.bower.io', - 'http://custom-registry.com', - 'http://custom-registry2.com' - ] - } - })); - }); + .get('/packages/jquery') + .reply(200, { + name: 'jquery', + url: 'git://github.com/foo/baz' + }); - it('should return entry type', function (next) { - this.registry.lookup('jquery', function (err, entry) { + this.registry = new RegistryClient( + Config.read(process.cwd(), { + strictSsl: false, + force: true, + registry: { + search: [ + 'https://registry.bower.io', + 'http://custom-registry.com', + 'http://custom-registry2.com' + ] + } + }) + ); + }); + + it('should return entry type', function(next) { + this.registry.lookup('jquery', function(err, entry) { expect(err).to.be(null); expect(entry).to.be.an('object'); expect(entry.type).to.eql('alias'); @@ -300,8 +324,8 @@ describe('RegistryClient', function () { }); }); - it('should return entry url ', function (next) { - this.registry.lookup('jquery', function (err, entry) { + it('should return entry url ', function(next) { + this.registry.lookup('jquery', function(err, entry) { expect(err).to.be(null); expect(entry).to.be.an('object'); expect(entry.url).to.eql('git://github.com/foo/bar'); @@ -309,14 +333,14 @@ describe('RegistryClient', function () { }); }); - it('should respect order', function (next) { + it('should respect order', function(next) { this.registry._config.registry.search = [ 'https://registry.bower.io', 'http://custom-registry2.com', 'http://custom-registry.com' ]; - this.registry.lookup('jquery', function (err, entry) { + this.registry.lookup('jquery', function(err, entry) { expect(err).to.be(null); expect(entry).to.be.an('object'); expect(entry.url).to.eql('git://github.com/foo/baz'); @@ -328,37 +352,40 @@ describe('RegistryClient', function () { // // register // - describe('calling the register instance method with argument', function () { - beforeEach(function () { + describe('calling the register instance method with argument', function() { + beforeEach(function() { nock('https://registry.bower.io:443') - .post('/packages', 'name=test-ba&url=git%3A%2F%2Fgithub.com%2Ftest-ba%2Ftest-ba.git') - .reply(201); + .post( + '/packages', + 'name=test-ba&url=git%3A%2F%2Fgithub.com%2Ftest-ba%2Ftest-ba.git' + ) + .reply(201); this.pkg = 'test-ba'; this.pkgUrl = 'git://github.com/test-ba/test-ba.git'; }); - it('should not return an error', function (next) { - this.registry.register(this.pkg, this.pkgUrl, function (err) { + it('should not return an error', function(next) { + this.registry.register(this.pkg, this.pkgUrl, function(err) { expect(err).to.be(null); next(); }); }); - it('should return entry name', function (next) { + it('should return entry name', function(next) { var self = this; - this.registry.register(this.pkg, this.pkgUrl, function (err, entry) { + this.registry.register(this.pkg, this.pkgUrl, function(err, entry) { expect(err).to.be(null); expect(entry.name).to.eql(self.pkg); next(); }); }); - it('should return entry url', function (next) { + it('should return entry url', function(next) { var self = this; - this.registry.register(this.pkg, this.pkgUrl, function (err, entry) { + this.registry.register(this.pkg, this.pkgUrl, function(err, entry) { expect(err).to.be(null); expect(entry.url).to.eql(self.pkgUrl); next(); @@ -366,15 +393,15 @@ describe('RegistryClient', function () { }); }); - describe('calling the register instance method without arguments', function () { - beforeEach(function () { + describe('calling the register instance method without arguments', function() { + beforeEach(function() { nock('https://registry.bower.io:443') - .post('/packages', 'name=&url=') - .reply(400); + .post('/packages', 'name=&url=') + .reply(400); }); - it('should return an error and no result', function (next) { - this.registry.register('', '', function (err, entry) { + it('should return an error and no result', function(next) { + this.registry.register('', '', function(err, entry) { expect(err).to.be.an(Error); expect(entry).to.be(undefined); next(); @@ -382,32 +409,36 @@ describe('RegistryClient', function () { }); }); - // // unregister // - describe('calling the unregister instance method with argument', function () { - beforeEach(function () { + describe('calling the unregister instance method with argument', function() { + beforeEach(function() { this.pkg = 'testfoo'; this.accessToken = '12345678'; this.registry._config.accessToken = this.accessToken; nock('https://registry.bower.io:443') - .delete('/packages/' + this.pkg + '?access_token=' + this.accessToken) - .reply(204); + .delete( + '/packages/' + + this.pkg + + '?access_token=' + + this.accessToken + ) + .reply(204); }); - it('should not return an error when valid', function (next) { - this.registry.unregister(this.pkg, function (err) { + it('should not return an error when valid', function(next) { + this.registry.unregister(this.pkg, function(err) { expect(err).to.be(null); next(); }); }); - it('should return entry name', function (next) { + it('should return entry name', function(next) { var self = this; - this.registry.unregister(this.pkg, function (err, entry) { + this.registry.unregister(this.pkg, function(err, entry) { expect(err).to.be(null); expect(entry.name).to.eql(self.pkg); next(); @@ -415,18 +446,18 @@ describe('RegistryClient', function () { }); }); - describe('calling the unregister instance method with invalid token', function () { - beforeEach(function () { + describe('calling the unregister instance method with invalid token', function() { + beforeEach(function() { this.pkg = 'testfoo'; this.registry._config.accessToken = ''; nock('https://registry.bower.io:443') - .delete('/packages/' + this.pkg) - .reply(403); + .delete('/packages/' + this.pkg) + .reply(403); }); - it('should return an error', function (next) { - this.registry.unregister(this.pkg, function (err, entry) { + it('should return an error', function(next) { + this.registry.unregister(this.pkg, function(err, entry) { expect(err).to.be.an(Error); expect(entry).to.be(undefined); next(); @@ -434,19 +465,24 @@ describe('RegistryClient', function () { }); }); - describe('calling the unregister instance method with invalid package', function () { - beforeEach(function () { + describe('calling the unregister instance method with invalid package', function() { + beforeEach(function() { this.notpkg = 'testbar'; this.accessToken = '12345678'; this.registry._config.accessToken = this.accessToken; nock('https://registry.bower.io:443') - .delete('/packages/' + this.notpkg + '?access_token=' + this.accessToken) - .reply(404); + .delete( + '/packages/' + + this.notpkg + + '?access_token=' + + this.accessToken + ) + .reply(404); }); - it('should return an error', function (next) { - this.registry.unregister(this.notpkg, function (err, entry) { + it('should return an error', function(next) { + this.registry.unregister(this.notpkg, function(err, entry) { expect(err).to.be.an(Error); expect(entry).to.be(undefined); next(); @@ -457,11 +493,11 @@ describe('RegistryClient', function () { // // search // - describe('calling the search instance method with argument', function () { - beforeEach(function () { + describe('calling the search instance method with argument', function() { + beforeEach(function() { nock('https://registry.bower.io:443') - .get('/packages/search/jquery') - .replyWithFile(200, __dirname + '/fixtures/search.json'); + .get('/packages/search/jquery') + .replyWithFile(200, __dirname + '/fixtures/search.json'); this.pkg = 'jquery'; this.pkgUrl = 'git://github.com/components/jquery.git'; @@ -469,18 +505,18 @@ describe('RegistryClient', function () { this.registry._config.force = true; }); - it('should not return an error', function (next) { - this.registry.search(this.pkg, function (err) { + it('should not return an error', function(next) { + this.registry.search(this.pkg, function(err) { expect(err).to.be(null); next(); }); }); - it('should return entry name', function (next) { + it('should return entry name', function(next) { var self = this; - this.registry.search(this.pkg, function (err, results) { - var found = results.some(function (entry) { + this.registry.search(this.pkg, function(err, results) { + var found = results.some(function(entry) { return entry.name === self.pkg; }); @@ -489,11 +525,11 @@ describe('RegistryClient', function () { }); }); - it('should return entry url', function (next) { + it('should return entry url', function(next) { var self = this; - this.registry.search(this.pkg, function (err, results) { - var found = results.some(function (entry) { + this.registry.search(this.pkg, function(err, results) { + var found = results.some(function(entry) { return entry.url === self.pkgUrl; }); @@ -503,41 +539,43 @@ describe('RegistryClient', function () { }); }); - describe('calling the search instance method with two registries', function () { - beforeEach(function () { + describe('calling the search instance method with two registries', function() { + beforeEach(function() { nock('https://registry.bower.io:443') - .get('/packages/search/jquery') - .reply(200, []); + .get('/packages/search/jquery') + .reply(200, []); nock('http://custom-registry.com') - .get('/packages/search/jquery') - .reply(200, [ - { - name: 'jquery', - url: 'git://github.com/bar/foo.git' - } - ]); + .get('/packages/search/jquery') + .reply(200, [ + { + name: 'jquery', + url: 'git://github.com/bar/foo.git' + } + ]); this.pkg = 'jquery'; this.pkgUrl = 'git://github.com/bar/foo.git'; - this.registry = new RegistryClient(Config.read(process.cwd(), { - strictSsl: false, - force: true, - registry: { - search: [ - 'https://registry.bower.io', - 'http://custom-registry.com' - ] - } - })); - }); - - it('should return entry name', function (next) { + this.registry = new RegistryClient( + Config.read(process.cwd(), { + strictSsl: false, + force: true, + registry: { + search: [ + 'https://registry.bower.io', + 'http://custom-registry.com' + ] + } + }) + ); + }); + + it('should return entry name', function(next) { var self = this; - this.registry.search(this.pkg, function (err, results) { - var found = results.some(function (entry) { + this.registry.search(this.pkg, function(err, results) { + var found = results.some(function(entry) { return entry.name === self.pkg; }); @@ -546,15 +584,15 @@ describe('RegistryClient', function () { }); }); - it('should return entry url', function (next) { + it('should return entry url', function(next) { var self = this; - this.registry.search(this.pkg, function (err, results) { - if (! results.length) { + this.registry.search(this.pkg, function(err, results) { + if (!results.length) { return next(new Error('Result expected')); } - var found = results.some(function (entry) { + var found = results.some(function(entry) { return entry.url === self.pkgUrl; }); @@ -564,15 +602,15 @@ describe('RegistryClient', function () { }); }); - describe('calling the search instance method without argument', function () { - beforeEach(function () { + describe('calling the search instance method without argument', function() { + beforeEach(function() { nock('https://registry.bower.io:443') - .get('/packages/search/') - .reply(404); + .get('/packages/search/') + .reply(404); }); - it('should return an error and no results', function (next) { - this.registry.search('', function (err, results) { + it('should return an error and no results', function(next) { + this.registry.search('', function(err, results) { expect(err).to.be.an(Error); expect(results).to.be(undefined); next(); @@ -583,63 +621,64 @@ describe('RegistryClient', function () { // // list // - describe('calling the list instance method', function () { - beforeEach(function () { + describe('calling the list instance method', function() { + beforeEach(function() { nock('https://registry.bower.io:443') - .get('/packages') - .reply(200, [], {}); + .get('/packages') + .reply(200, [], {}); this.registry._config.force = true; }); - it('should not return an error', function (next) { - this.registry.list(function (err) { + it('should not return an error', function(next) { + this.registry.list(function(err) { expect(err).to.be(null); next(); }); }); - it('should return results array', function (next) { - this.registry.list(function (err, results) { + it('should return results array', function(next) { + this.registry.list(function(err, results) { expect(results).to.be.an('array'); next(); }); }); - }); - describe('calling the list instance method with two registries', function () { - beforeEach(function () { + describe('calling the list instance method with two registries', function() { + beforeEach(function() { nock('https://registry.bower.io:443') - .get('/packages') - .reply(200, []); + .get('/packages') + .reply(200, []); nock('http://custom-registry.com') - .get('/packages') - .reply(200, [ - { - name: 'jquery', - url: 'git://github.com/bar/foo.git' - } - ]); - - this.registry = new RegistryClient(Config.read(process.cwd(), { - strictSsl: false, - force: true, - registry: { - search: [ - 'https://registry.bower.io', - 'http://custom-registry.com' - ] - } - })); - }); - - it('should return entry name', function (next) { + .get('/packages') + .reply(200, [ + { + name: 'jquery', + url: 'git://github.com/bar/foo.git' + } + ]); + + this.registry = new RegistryClient( + Config.read(process.cwd(), { + strictSsl: false, + force: true, + registry: { + search: [ + 'https://registry.bower.io', + 'http://custom-registry.com' + ] + } + }) + ); + }); + + it('should return entry name', function(next) { var self = this; - this.registry.list(function (err, results) { - var found = results.some(function (entry) { + this.registry.list(function(err, results) { + var found = results.some(function(entry) { return entry.name === self.pkg; }); @@ -648,15 +687,15 @@ describe('RegistryClient', function () { }); }); - it('should return entry url', function (next) { + it('should return entry url', function(next) { var self = this; - this.registry.list(function (err, results) { - if (! results.length) { + this.registry.list(function(err, results) { + if (!results.length) { return next(new Error('Result expected')); } - var found = results.some(function (entry) { + var found = results.some(function(entry) { return entry.url === self.pkgUrl; }); @@ -666,16 +705,15 @@ describe('RegistryClient', function () { }); }); - describe('calling the list instance method', function () { - - beforeEach(function () { + describe('calling the list instance method', function() { + beforeEach(function() { nock('https://registry.bower.io:443') - .get('/packages') - .reply(200, [], {}); + .get('/packages') + .reply(200, [], {}); }); - it('should return an error and no results', function (next) { - this.registry.list(function (err) { + it('should return an error and no results', function(next) { + this.registry.list(function(err) { expect(err).to.be(null); next(); }); @@ -685,22 +723,22 @@ describe('RegistryClient', function () { // // clearCache // - describe('called the clearCache instance method with argument', function () { - beforeEach(function () { + describe('called the clearCache instance method with argument', function() { + beforeEach(function() { this.pkg = 'jquery'; }); - it('should not return an error', function (next) { - this.registry.clearCache(this.pkg, function (err) { + it('should not return an error', function(next) { + this.registry.clearCache(this.pkg, function(err) { expect(err).to.be(null); next(); }); }); }); - describe('called the clearCache instance method without argument', function () { - it('should not return any errors and remove all cache items', function (next) { - this.registry.clearCache(function (err) { + describe('called the clearCache instance method without argument', function() { + it('should not return any errors and remove all cache items', function(next) { + this.registry.clearCache(function(err) { expect(err).to.be(null); next(); }); @@ -710,25 +748,29 @@ describe('RegistryClient', function () { // // test userAgent // - describe('add a custom userAgent with argument', function () { + describe('add a custom userAgent with argument', function() { this.timeout(5000); - it('should send custom userAgent to the server', function (next) { + it('should send custom userAgent to the server', function(next) { var self = this; this.ua = ''; - this.server = http.createServer(function (req, res) { + this.server = http.createServer(function(req, res) { self.ua = req.headers['user-agent']; res.writeHeader(200, { 'Content-Type': 'application/json' }); - res.end('{"name":"jquery","url":"git://github.com/components/jquery.git"}'); + res.end( + '{"name":"jquery","url":"git://github.com/components/jquery.git"}' + ); self.server.close(); }); this.server.listen('7777', '127.0.0.1'); - this.registry = new RegistryClient(Config.read(process.cwd(), { - userAgent: 'test agent', - registry: 'http://127.0.0.1:7777' - })); - this.registry.search('jquery', function (err, result) { + this.registry = new RegistryClient( + Config.read(process.cwd(), { + userAgent: 'test agent', + registry: 'http://127.0.0.1:7777' + }) + ); + this.registry.search('jquery', function(err, result) { expect(self.ua).to.be('test agent'); next(); }); diff --git a/packages/bower-registry-client/test/core/index.js b/packages/bower-registry-client/test/core/index.js index 1536a5140..731d02707 100644 --- a/packages/bower-registry-client/test/core/index.js +++ b/packages/bower-registry-client/test/core/index.js @@ -1,21 +1,21 @@ var index = require('../../lib/index'); var expect = require('expect.js'); -describe('index module', function () { - describe('requiring the index module', function () { - it('should expose a lookup method', function () { +describe('index module', function() { + describe('requiring the index module', function() { + it('should expose a lookup method', function() { expect(index.lookup).to.be.ok; }); - it('should expose a list method', function () { + it('should expose a list method', function() { expect(index.list).to.be.ok; }); - it('should expose a register method', function () { + it('should expose a register method', function() { expect(index.register).to.be.ok; }); - it('should expose a search method', function () { + it('should expose a search method', function() { expect(index.search).to.be.ok; }); }); diff --git a/packages/bower-registry-client/test/core/list.js b/packages/bower-registry-client/test/core/list.js index 39f92e047..1719e4a86 100644 --- a/packages/bower-registry-client/test/core/list.js +++ b/packages/bower-registry-client/test/core/list.js @@ -1,23 +1,23 @@ var list = require('../../lib/list'); var expect = require('expect.js'); -describe('list module', function () { - describe('requiring the list module', function () { - it('should expose a list method', function () { +describe('list module', function() { + describe('requiring the list module', function() { + it('should expose a list method', function() { expect(typeof list === 'function').to.be.ok; }); - it('should expose a initCache method', function () { + it('should expose a initCache method', function() { expect(list.initCache).to.be.ok; expect(typeof list.initCache === 'function').to.be.ok; }); - it('should expose a clearCache method', function () { + it('should expose a clearCache method', function() { expect(list.clearCache).to.be.ok; expect(typeof list.clearCache === 'function').to.be.ok; }); - it('should expose a resetCache method', function () { + it('should expose a resetCache method', function() { expect(list.resetCache).to.be.ok; expect(typeof list.resetCache === 'function').to.be.ok; }); diff --git a/packages/bower-registry-client/test/core/lookup.js b/packages/bower-registry-client/test/core/lookup.js index e730698ab..4f4380740 100644 --- a/packages/bower-registry-client/test/core/lookup.js +++ b/packages/bower-registry-client/test/core/lookup.js @@ -1,23 +1,23 @@ var lookup = require('../../lib/lookup'); var expect = require('expect.js'); -describe('lookup module', function () { - describe('requiring the lookup module', function () { - it('should expose a lookup method', function () { +describe('lookup module', function() { + describe('requiring the lookup module', function() { + it('should expose a lookup method', function() { expect(typeof lookup === 'function').to.be.ok; }); - it('should expose a initCache method', function () { + it('should expose a initCache method', function() { expect(lookup.initCache).to.be.ok; expect(typeof lookup.initCache === 'function').to.be.ok; }); - it('should expose a clearCache method', function () { + it('should expose a clearCache method', function() { expect(lookup.clearCache).to.be.ok; expect(typeof lookup.clearCache === 'function').to.be.ok; }); - it('should expose a resetCache method', function () { + it('should expose a resetCache method', function() { expect(lookup.resetCache).to.be.ok; expect(typeof lookup.resetCache === 'function').to.be.ok; }); diff --git a/packages/bower-registry-client/test/core/register.js b/packages/bower-registry-client/test/core/register.js index 1180b8afb..46d4bd019 100644 --- a/packages/bower-registry-client/test/core/register.js +++ b/packages/bower-registry-client/test/core/register.js @@ -1,9 +1,9 @@ var register = require('../../lib/register'); var expect = require('expect.js'); -describe('register module', function () { - describe('requiring the register module', function () { - it('should expose a register method', function () { +describe('register module', function() { + describe('requiring the register module', function() { + it('should expose a register method', function() { expect(typeof register === 'function').to.be.ok; }); }); diff --git a/packages/bower-registry-client/test/core/search.js b/packages/bower-registry-client/test/core/search.js index 8a6285d47..d52b71e75 100644 --- a/packages/bower-registry-client/test/core/search.js +++ b/packages/bower-registry-client/test/core/search.js @@ -1,23 +1,23 @@ var search = require('../../lib/search'); var expect = require('expect.js'); -describe('search module', function () { - describe('requiring the search module', function () { - it('should expose a search method', function () { +describe('search module', function() { + describe('requiring the search module', function() { + it('should expose a search method', function() { expect(typeof search === 'function').to.be.ok; }); - it('should expose a initCache method', function () { + it('should expose a initCache method', function() { expect(search.initCache).to.be.ok; expect(typeof search.initCache === 'function').to.be.ok; }); - it('should expose a clearCache method', function () { + it('should expose a clearCache method', function() { expect(search.clearCache).to.be.ok; expect(typeof search.clearCache === 'function').to.be.ok; }); - it('should expose a resetCache method', function () { + it('should expose a resetCache method', function() { expect(search.resetCache).to.be.ok; expect(typeof search.resetCache === 'function').to.be.ok; }); diff --git a/packages/bower-registry-client/test/core/util/Cache.js b/packages/bower-registry-client/test/core/util/Cache.js index 702957f65..de82fbd9c 100644 --- a/packages/bower-registry-client/test/core/util/Cache.js +++ b/packages/bower-registry-client/test/core/util/Cache.js @@ -1,48 +1,60 @@ var Cache = require('../../../lib/util/Cache'); var expect = require('expect.js'); -describe('Cache', function () { - beforeEach(function () { +describe('Cache', function() { + beforeEach(function() { this.cache = new Cache(); }); - describe('Constructor', function () { - describe('instantiating cache', function () { - it('should provide an instance of RegistryClient', function () { + describe('Constructor', function() { + describe('instantiating cache', function() { + it('should provide an instance of RegistryClient', function() { expect(this.cache instanceof Cache).to.be.ok; }); - it('should inherit LRU cache methods', function () { + it('should inherit LRU cache methods', function() { var self = this, lruMethods = [ - 'max', 'lengthCalculator', 'length', 'itemCount', 'forEach', - 'keys', 'values', 'reset', 'dump', 'dumpLru', 'set', 'has', - 'get', 'peek', 'del' - ]; - - lruMethods.forEach(function (method) { + 'max', + 'lengthCalculator', + 'length', + 'itemCount', + 'forEach', + 'keys', + 'values', + 'reset', + 'dump', + 'dumpLru', + 'set', + 'has', + 'get', + 'peek', + 'del' + ]; + + lruMethods.forEach(function(method) { expect(self.cache._cache).to.have.property(method); }); }); }); - it('should have a get prototype method', function () { + it('should have a get prototype method', function() { expect(Cache.prototype).to.have.property('get'); }); - it('should have a set prototype method', function () { + it('should have a set prototype method', function() { expect(Cache.prototype).to.have.property('set'); }); - it('should have a del prototype method', function () { + it('should have a del prototype method', function() { expect(Cache.prototype).to.have.property('del'); }); - it('should have a clear prototype method', function () { + it('should have a clear prototype method', function() { expect(Cache.prototype).to.have.property('clear'); }); - it('should have a reset prototype method', function () { + it('should have a reset prototype method', function() { expect(Cache.prototype).to.have.property('reset'); }); }); diff --git a/packages/bower-registry-client/test/core/util/createError.js b/packages/bower-registry-client/test/core/util/createError.js index a01031daa..c1d624306 100644 --- a/packages/bower-registry-client/test/core/util/createError.js +++ b/packages/bower-registry-client/test/core/util/createError.js @@ -1,35 +1,28 @@ var createError = require('../../../lib/util/createError'); var expect = require('expect.js'); -describe('createError', function () { - - beforeEach(function () { +describe('createError', function() { + beforeEach(function() { this.err = createError('message', 500); }); - describe('requiring the createError module', function () { - - it('should expose a createError method', function () { + describe('requiring the createError module', function() { + it('should expose a createError method', function() { expect(typeof createError === 'function').to.be.ok; }); - }); - describe('invoking createError', function () { - - it('should return a new Error Object', function () { + describe('invoking createError', function() { + it('should return a new Error Object', function() { expect(typeof createError() === 'object').to.be.ok; }); - it('should return an Error with message', function () { + it('should return an Error with message', function() { expect(this.err.message).to.eql('message'); }); - it('should return an Error with code', function () { + it('should return an Error with code', function() { expect(this.err.code).to.eql(500); }); - }); - - }); diff --git a/test/commands/bower.js b/test/commands/bower.js index c169ebf34..2df4993b7 100644 --- a/test/commands/bower.js +++ b/test/commands/bower.js @@ -1,10 +1,10 @@ var expect = require('expect.js'); var runBin = require('../helpers').runBin; -describe('bower', function () { +describe('bower', function() { process.env.CI = '1'; - it('runs bower installation', function () { + it('runs bower installation', function() { var result = runBin(); var text = result.stdout.toString(); @@ -13,8 +13,8 @@ describe('bower', function () { }); }); -describe('abbreviations', function () { - it('Returns same value than the full command', function () { +describe('abbreviations', function() { + it('Returns same value than the full command', function() { var abbr = runBin(['install']); var full = runBin(['i']); diff --git a/test/commands/cache/clean.js b/test/commands/cache/clean.js index 3a8e0b73b..c32cd5786 100644 --- a/test/commands/cache/clean.js +++ b/test/commands/cache/clean.js @@ -5,22 +5,24 @@ var helpers = require('../../helpers'); var cacheClean = helpers.command('cache/clean'); var object = require('mout/object'); -describe('bower cache clean', function () { - +describe('bower cache clean', function() { // Because directory names are required to be md5 of _source - var cacheFilesFactory = function (spec) { + var cacheFilesFactory = function(spec) { var files = {}; - object.map(spec, function (bowerJson) { + object.map(spec, function(bowerJson) { bowerJson._source = bowerJson.name + '/' + bowerJson.version; - var path = md5(bowerJson._source) + '/' + bowerJson.version + '/.bower.json'; + var path = + md5(bowerJson._source) + + '/' + + bowerJson.version + + '/.bower.json'; files[path] = bowerJson; }); return files; }; - var cacheFiles = cacheFilesFactory([ { name: 'angular', @@ -38,52 +40,72 @@ describe('bower cache clean', function () { var cacheDir = new helpers.TempDir(cacheFiles); - it('correctly reads arguments', function () { - expect(cacheClean.readOptions(['jquery', 'angular'])) - .to.eql([['jquery', 'angular'], {}]); + it('correctly reads arguments', function() { + expect(cacheClean.readOptions(['jquery', 'angular'])).to.eql([ + ['jquery', 'angular'], + {} + ]); }); - it('removes all cache', function () { + it('removes all cache', function() { cacheDir.prepare(); - return helpers.run(cacheClean, [undefined, {}, { - storage: { - packages: cacheDir.path - } - }]).spread(function (result) { - object.map(cacheFiles, function (_, cacheFile) { - expect(cacheDir.exists(cacheFile)).to.be(false); + return helpers + .run(cacheClean, [ + undefined, + {}, + { + storage: { + packages: cacheDir.path + } + } + ]) + .spread(function(result) { + object.map(cacheFiles, function(_, cacheFile) { + expect(cacheDir.exists(cacheFile)).to.be(false); + }); }); - }); }); - it('removes single package', function () { + it('removes single package', function() { cacheDir.prepare(); - return helpers.run(cacheClean, [['angular'], {}, { - storage: { - packages: cacheDir.path - } - }]).spread(function (result) { - var paths = Object.keys(cacheFiles); - expect(cacheDir.exists(paths[0])).to.be(false); - expect(cacheDir.exists(paths[1])).to.be(false); - expect(cacheDir.exists(paths[2])).to.be(true); - }); + return helpers + .run(cacheClean, [ + ['angular'], + {}, + { + storage: { + packages: cacheDir.path + } + } + ]) + .spread(function(result) { + var paths = Object.keys(cacheFiles); + expect(cacheDir.exists(paths[0])).to.be(false); + expect(cacheDir.exists(paths[1])).to.be(false); + expect(cacheDir.exists(paths[2])).to.be(true); + }); }); - it('removes single package package version', function () { + it('removes single package package version', function() { cacheDir.prepare(); - return helpers.run(cacheClean, [['angular#1.3.8'], {}, { - storage: { - packages: cacheDir.path - } - }]).spread(function (result) { - var paths = Object.keys(cacheFiles); - expect(cacheDir.exists(paths[0])).to.be(false); - expect(cacheDir.exists(paths[1])).to.be(true); - expect(cacheDir.exists(paths[2])).to.be(true); - }); + return helpers + .run(cacheClean, [ + ['angular#1.3.8'], + {}, + { + storage: { + packages: cacheDir.path + } + } + ]) + .spread(function(result) { + var paths = Object.keys(cacheFiles); + expect(cacheDir.exists(paths[0])).to.be(false); + expect(cacheDir.exists(paths[1])).to.be(true); + expect(cacheDir.exists(paths[2])).to.be(true); + }); }); }); diff --git a/test/commands/cache/list.js b/test/commands/cache/list.js index 89d598a4d..e05577edb 100644 --- a/test/commands/cache/list.js +++ b/test/commands/cache/list.js @@ -3,8 +3,7 @@ var helpers = require('../../helpers'); var cacheList = helpers.command('cache/list'); -describe('bower cache list', function () { - +describe('bower cache list', function() { var cacheDir = new helpers.TempDir({ '87323d6d4e48be291a9616a033d4cc6c/1.3.8/.bower.json': { name: 'angular', @@ -20,41 +19,55 @@ describe('bower cache list', function () { } }); - it('correctly reads arguments', function () { - expect(cacheList.readOptions(['jquery', 'angular'])) - .to.eql([['jquery', 'angular'], {}]); + it('correctly reads arguments', function() { + expect(cacheList.readOptions(['jquery', 'angular'])).to.eql([ + ['jquery', 'angular'], + {} + ]); }); - it('lists packages from cache', function () { + it('lists packages from cache', function() { cacheDir.prepare(); - return helpers.run(cacheList, [undefined, {}, { - storage: { - packages: cacheDir.path - } - }]).spread(function (result) { - expect(result[0].canonicalDir) - .to.be(cacheDir.getPath('87323d6d4e48be291a9616a033d4cc6c/1.3.8')); - expect(result[0].pkgMeta.version).to.be('1.3.8'); - expect(result[1].pkgMeta.version).to.be('1.3.9'); - expect(result[2].pkgMeta.version).to.be('1.0.0'); - }); - + return helpers + .run(cacheList, [ + undefined, + {}, + { + storage: { + packages: cacheDir.path + } + } + ]) + .spread(function(result) { + expect(result[0].canonicalDir).to.be( + cacheDir.getPath('87323d6d4e48be291a9616a033d4cc6c/1.3.8') + ); + expect(result[0].pkgMeta.version).to.be('1.3.8'); + expect(result[1].pkgMeta.version).to.be('1.3.9'); + expect(result[2].pkgMeta.version).to.be('1.0.0'); + }); }); - it('lists selected package names', function () { + it('lists selected package names', function() { cacheDir.prepare(); - return helpers.run(cacheList, [['angular'], {}, { - storage: { - packages: cacheDir.path - } - }]).spread(function (result) { - expect(result[0].canonicalDir) - .to.be(cacheDir.getPath('87323d6d4e48be291a9616a033d4cc6c/1.3.8')); - expect(result[0].pkgMeta.version).to.be('1.3.8'); - expect(result[1].pkgMeta.version).to.be('1.3.9'); - }); - + return helpers + .run(cacheList, [ + ['angular'], + {}, + { + storage: { + packages: cacheDir.path + } + } + ]) + .spread(function(result) { + expect(result[0].canonicalDir).to.be( + cacheDir.getPath('87323d6d4e48be291a9616a033d4cc6c/1.3.8') + ); + expect(result[0].pkgMeta.version).to.be('1.3.8'); + expect(result[1].pkgMeta.version).to.be('1.3.9'); + }); }); }); diff --git a/test/commands/help.js b/test/commands/help.js index d719fc490..c1a47b294 100644 --- a/test/commands/help.js +++ b/test/commands/help.js @@ -2,14 +2,13 @@ var expect = require('expect.js'); var helpers = require('../helpers'); var help = helpers.command('help'); -describe('bower help', function () { - - it('correctly reads arguments', function () { +describe('bower help', function() { + it('correctly reads arguments', function() { expect(help.readOptions(['foo'])).to.eql(['foo']); }); - it('shows general help', function () { - return helpers.run(help).spread(function (result) { + it('shows general help', function() { + return helpers.run(help).spread(function(result) { expect(result.usage[0]).to.be.a('string'); expect(result.commands).to.be.a('object'); expect(result.options).to.be.a('object'); @@ -17,15 +16,26 @@ describe('bower help', function () { }); var commands = [ - 'home', 'info', 'init', 'install', - 'link', 'list', 'lookup', 'prune', 'register', - 'search', 'update', 'uninstall', 'version', - 'cache list', 'cache clean' + 'home', + 'info', + 'init', + 'install', + 'link', + 'list', + 'lookup', + 'prune', + 'register', + 'search', + 'update', + 'uninstall', + 'version', + 'cache list', + 'cache clean' ]; - commands.forEach(function (command) { - it('shows help for ' + command + ' command', function () { - return helpers.run(help, [command]).spread(function (result) { + commands.forEach(function(command) { + it('shows help for ' + command + ' command', function() { + return helpers.run(help, [command]).spread(function(result) { expect(result.command).to.be(command); expect(result.description).to.be.a('string'); expect(result.usage[0]).to.be.a('string'); @@ -33,8 +43,8 @@ describe('bower help', function () { }); }); - it('displays error for non-existing command', function () { - return helpers.run(help, ['fuu']).fail(function (e) { + it('displays error for non-existing command', function() { + return helpers.run(help, ['fuu']).fail(function(e) { expect(e.message).to.be('Unknown command: fuu'); expect(e.command).to.be('fuu'); expect(e.code).to.be('EUNKNOWNCMD'); diff --git a/test/commands/home.js b/test/commands/home.js index 99f3cf1e6..4257a9394 100644 --- a/test/commands/home.js +++ b/test/commands/home.js @@ -4,9 +4,8 @@ var helpers = require('../helpers'); var home = helpers.command('home'); -describe('bower home', function () { - - it('correctly reads arguments', function () { +describe('bower home', function() { + it('correctly reads arguments', function() { expect(home.readOptions(['foo'])).to.eql(['foo']); }); @@ -23,35 +22,35 @@ describe('bower home', function () { } }); - it('opens repository home page in web browser', function () { + it('opens repository home page in web browser', function() { mainPackage.prepare(); - return Q.Promise(function (resolve) { + return Q.Promise(function(resolve) { var home = helpers.command('home', { opn: resolve }); helpers.run(home, [mainPackage.path]); - }).then(function (url) { + }).then(function(url) { expect(url).to.be('http://bower.io'); }); }); - it('opens home page of current repository', function () { + it('opens home page of current repository', function() { mainPackage.prepare(); - return Q.Promise(function (resolve) { + return Q.Promise(function(resolve) { var home = helpers.command('home', { opn: resolve }); helpers.run(home, [undefined, { cwd: mainPackage.path }]); - }).then(function (url) { + }).then(function(url) { expect(url).to.be('http://bower.io'); }); }); - it('errors if no homepage is set', function () { + it('errors if no homepage is set', function() { wrongPackage.prepare(); - return Q.Promise(function (resolve) { + return Q.Promise(function(resolve) { var home = helpers.command('home', { opn: resolve }); helpers.run(home, [wrongPackage.path]).fail(resolve); - }).then(function (reason) { + }).then(function(reason) { expect(reason.message).to.be('No homepage set for package'); expect(reason.code).to.be('ENOHOME'); }); diff --git a/test/commands/index.js b/test/commands/index.js index 916bbc292..81330223f 100644 --- a/test/commands/index.js +++ b/test/commands/index.js @@ -1,4 +1,4 @@ -describe('integration tests', function () { +describe('integration tests', function() { require('./cache/list'); require('./cache/clean'); require('./help'); diff --git a/test/commands/info.js b/test/commands/info.js index 60e39135c..d2da3b90b 100644 --- a/test/commands/info.js +++ b/test/commands/info.js @@ -3,11 +3,12 @@ var expect = require('expect.js'); var helpers = require('../helpers'); var info = helpers.command('info'); -describe('bower info', function () { - - it('correctly reads arguments', function () { - expect(info.readOptions(['pkg', 'property'])) - .to.eql(['pkg', 'property']); +describe('bower info', function() { + it('correctly reads arguments', function() { + expect(info.readOptions(['pkg', 'property'])).to.eql([ + 'pkg', + 'property' + ]); }); var meta = { @@ -29,37 +30,33 @@ describe('bower info', function () { '0.1.3': { 'bower.json': meta2 } }); - it('just returns if not package is specified', function () { - return helpers.run(info).spread(function (results) { + it('just returns if not package is specified', function() { + return helpers.run(info).spread(function(results) { expect(results).to.be(undefined); }); }); - it('shows info about given package', function () { + it('shows info about given package', function() { mainPackage.prepareGit({}); - return helpers.run(info, [mainPackage.path]).spread(function (results) { + return helpers.run(info, [mainPackage.path]).spread(function(results) { expect(results).to.eql({ - 'latest': meta2, - 'name': mainPackage.path, - 'versions': [ - '0.1.3', - '0.1.2' - ] + latest: meta2, + name: mainPackage.path, + versions: ['0.1.3', '0.1.2'] }); }); }); - it('should handle @ as a divider', function () { - return helpers.run(info, [mainPackage.path + '@0.1.3']).spread(function (results) { - expect(results).to.eql( - { + it('should handle @ as a divider', function() { + return helpers + .run(info, [mainPackage.path + '@0.1.3']) + .spread(function(results) { + expect(results).to.eql({ name: 'package', version: '0.1.3', homepage: 'http://bower.io', description: 'Hello world! Hello!' - } - ); - }); - + }); + }); }); }); diff --git a/test/commands/init.js b/test/commands/init.js index 795c964f9..9f3870786 100644 --- a/test/commands/init.js +++ b/test/commands/init.js @@ -3,16 +3,14 @@ var helpers = require('../helpers'); var init = helpers.command('init'); -describe('bower init', function () { - +describe('bower init', function() { var mainPackage = new helpers.TempDir(); - it('correctly reads arguments', function () { - expect(init.readOptions([])) - .to.eql([]); + it('correctly reads arguments', function() { + expect(init.readOptions([])).to.eql([]); }); - it('generates bower.json file', function () { + it('generates bower.json file', function() { mainPackage.prepare(); var logger = init({ @@ -20,50 +18,55 @@ describe('bower init', function () { interactive: true }); - return helpers.expectEvent(logger, 'prompt') - .spread(function (prompt, answer) { - answer({ - name: 'test-name', - description: 'test-description', - keywords: 'test-keyword', - authors: 'test-author', - license: 'test-license', - homepage: 'test-homepage', - private: true - }); - - return helpers.expectEvent(logger, 'prompt'); - }) - .spread(function (prompt, answer) { - answer({ prompt: true }); - return helpers.expectEvent(logger, 'end'); - }) - .then(function () { - expect(mainPackage.readJson('bower.json')).to.eql({ - name: 'test-name', - homepage: 'test-homepage', - authors: [ 'test-author' ], - description: 'test-description', - keywords: [ 'test-keyword' ], - license: 'test-license', - private: true + return helpers + .expectEvent(logger, 'prompt') + .spread(function(prompt, answer) { + answer({ + name: 'test-name', + description: 'test-description', + keywords: 'test-keyword', + authors: 'test-author', + license: 'test-license', + homepage: 'test-homepage', + private: true + }); + + return helpers.expectEvent(logger, 'prompt'); + }) + .spread(function(prompt, answer) { + answer({ prompt: true }); + return helpers.expectEvent(logger, 'end'); + }) + .then(function() { + expect(mainPackage.readJson('bower.json')).to.eql({ + name: 'test-name', + homepage: 'test-homepage', + authors: ['test-author'], + description: 'test-description', + keywords: ['test-keyword'], + license: 'test-license', + private: true + }); }); - }); }); - it('errors on non-interactive mode', function () { + it('errors on non-interactive mode', function() { mainPackage.prepare(); return helpers.run(init, { cwd: mainPackage.path }).then( - function () { throw 'should fail'; }, - function (reason) { - expect(reason.message).to.be('Register requires an interactive shell'); + function() { + throw 'should fail'; + }, + function(reason) { + expect(reason.message).to.be( + 'Register requires an interactive shell' + ); expect(reason.code).to.be('ENOINT'); } ); }); - it('warns about existing bower.json', function () { + it('warns about existing bower.json', function() { mainPackage.prepare({ 'bower.json': { name: 'foobar' @@ -72,7 +75,7 @@ describe('bower init', function () { var logger = init({ cwd: mainPackage.path, interactive: true }); - return helpers.expectEvent(logger, 'log').spread(function (event) { + return helpers.expectEvent(logger, 'log').spread(function(event) { expect(event.level).to.be('warn'); expect(event.message).to.be( 'The existing bower.json file will be used and filled in' @@ -80,18 +83,15 @@ describe('bower init', function () { }); }); - it('gets defaults from package.json', function () { + it('gets defaults from package.json', function() { mainPackage.prepare({ 'package.json': { - 'name': 'name-from-npm', - 'description': 'description from npm', - 'main': 'index.js', - 'keywords': [ - 'foo', - 'bar' - ], - 'author': 'JD Isaacks', - 'license': 'ISC' + name: 'name-from-npm', + description: 'description from npm', + main: 'index.js', + keywords: ['foo', 'bar'], + author: 'JD Isaacks', + license: 'ISC' } }); @@ -100,54 +100,51 @@ describe('bower init', function () { interactive: true }); - return helpers.expectEvent(logger, 'prompt') - .spread(function (prompt, answer) { - - // Get defaults from prompt - var defaults = prompt.reduce(function (memo, obj) { - memo[obj.name] = obj['default']; - return memo; - }, {}); - - // Answer with defaults - answer({ - name: defaults.name, - description: defaults.description, - main: defaults.main, - keywords: defaults.keywords, - authors: defaults.authors, - license: defaults.license, - homepage: 'test-homepage', - private: true + return helpers + .expectEvent(logger, 'prompt') + .spread(function(prompt, answer) { + // Get defaults from prompt + var defaults = prompt.reduce(function(memo, obj) { + memo[obj.name] = obj['default']; + return memo; + }, {}); + + // Answer with defaults + answer({ + name: defaults.name, + description: defaults.description, + main: defaults.main, + keywords: defaults.keywords, + authors: defaults.authors, + license: defaults.license, + homepage: 'test-homepage', + private: true + }); + + return helpers.expectEvent(logger, 'prompt'); + }) + .spread(function(prompt, answer) { + answer({ prompt: true }); + return helpers.expectEvent(logger, 'end'); + }) + .then(function() { + expect(mainPackage.readJson('bower.json')).to.eql({ + name: 'name-from-npm', + description: 'description from npm', + main: 'index.js', + keywords: ['foo', 'bar'], + authors: ['JD Isaacks'], + license: 'ISC', + private: true, + homepage: 'test-homepage' + }); }); - - return helpers.expectEvent(logger, 'prompt'); - }) - .spread(function (prompt, answer) { - answer({ prompt: true }); - return helpers.expectEvent(logger, 'end'); - }) - .then(function () { - expect(mainPackage.readJson('bower.json')).to.eql({ - 'name': 'name-from-npm', - 'description': 'description from npm', - 'main': 'index.js', - 'keywords': [ - 'foo', - 'bar' - ], - 'authors': ['JD Isaacks'], - 'license': 'ISC', - 'private': true, - 'homepage': 'test-homepage' - }); - }); }); - it('can handle strange characters', function () { + it('can handle strange characters', function() { mainPackage.prepare({ 'package.json': { - 'name': 'name/from npm' + name: 'name/from npm' } }); diff --git a/test/commands/install.js b/test/commands/install.js index c35b66744..59f51084b 100644 --- a/test/commands/install.js +++ b/test/commands/install.js @@ -8,33 +8,50 @@ var tar = require('tar-fs'); var destroy = require('destroy'); var Q = require('q'); -describe('bower install', function () { - +describe('bower install', function() { var tempDir = new helpers.TempDir(); var install = helpers.command('install', { cwd: tempDir.path }); - it('correctly reads arguments', function () { - expect(install.readOptions(['jquery', 'angular', '-F', '-p', '-S', '-D', '-E'])) - .to.eql([ - ['jquery', 'angular'], { - forceLatest: true, - production: true, - save: true, - saveDev: true, - saveExact: true - } - ]); + it('correctly reads arguments', function() { + expect( + install.readOptions([ + 'jquery', + 'angular', + '-F', + '-p', + '-S', + '-D', + '-E' + ]) + ).to.eql([ + ['jquery', 'angular'], + { + forceLatest: true, + production: true, + save: true, + saveDev: true, + saveExact: true + } + ]); }); - it('correctly reads long arguments', function () { - expect(install.readOptions([ - 'jquery', 'angular', - '--force-latest', '--production', '--save', '--save-dev', '--save-exact' - ])).to.eql([ - ['jquery', 'angular'], { + it('correctly reads long arguments', function() { + expect( + install.readOptions([ + 'jquery', + 'angular', + '--force-latest', + '--production', + '--save', + '--save-dev', + '--save-exact' + ]) + ).to.eql([ + ['jquery', 'angular'], + { forceLatest: true, production: true, save: true, @@ -67,7 +84,7 @@ describe('bower install', function () { } }); - it('writes to bower.json if --save flag is used', function () { + it('writes to bower.json if --save flag is used', function() { mainPackage.prepare(); tempDir.prepare({ @@ -76,16 +93,19 @@ describe('bower install', function () { } }); - return helpers.run(install, [ - [mainPackage.path], { - save: true - } - ]).then(function () { - expect(tempDir.read('bower.json')).to.contain('dependencies'); - }); + return helpers + .run(install, [ + [mainPackage.path], + { + save: true + } + ]) + .then(function() { + expect(tempDir.read('bower.json')).to.contain('dependencies'); + }); }); - it('does not write to bower.json if no --save flag is used', function () { + it('does not write to bower.json if no --save flag is used', function() { mainPackage.prepare(); tempDir.prepare({ @@ -94,15 +114,12 @@ describe('bower install', function () { } }); - return helpers.run(install, [ - [mainPackage.path], { - } - ]).then(function () { + return helpers.run(install, [[mainPackage.path], {}]).then(function() { expect(tempDir.read('bower.json')).to.not.contain('dependencies'); }); }); - it('writes to bower.json if save config setting is set to true', function () { + it('writes to bower.json if save config setting is set to true', function() { mainPackage.prepare(); tempDir.prepare({ @@ -111,16 +128,20 @@ describe('bower install', function () { } }); - return helpers.run(install, [ - [mainPackage.path], {}, { - save: true - } - ]).then(function () { - expect(tempDir.read('bower.json')).to.contain('dependencies'); - }); + return helpers + .run(install, [ + [mainPackage.path], + {}, + { + save: true + } + ]) + .then(function() { + expect(tempDir.read('bower.json')).to.contain('dependencies'); + }); }); - it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function () { + it('writes an exact version number to dependencies in bower.json if --save --save-exact flags are used', function() { mainPackage.prepare({ 'bower.json': { name: 'package', @@ -134,17 +155,22 @@ describe('bower install', function () { } }); - return helpers.run(install, [ - [mainPackage.path], { - saveExact: true, - save: true - } - ]).then(function () { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(mainPackage.path + '#1.2.3'); - }); + return helpers + .run(install, [ + [mainPackage.path], + { + saveExact: true, + save: true + } + ]) + .then(function() { + expect( + tempDir.readJson('bower.json').dependencies.package + ).to.equal(mainPackage.path + '#1.2.3'); + }); }); - it('writes an exact version number to dependencies in bower.json if save and save-exact config settings are set to true', function () { + it('writes an exact version number to dependencies in bower.json if save and save-exact config settings are set to true', function() { mainPackage.prepare({ 'bower.json': { name: 'package', @@ -158,17 +184,23 @@ describe('bower install', function () { } }); - return helpers.run(install, [ - [mainPackage.path], {}, { - saveExact: true, - save: true - } - ]).then(function () { - expect(tempDir.readJson('bower.json').dependencies.package).to.equal(mainPackage.path + '#1.2.3'); - }); + return helpers + .run(install, [ + [mainPackage.path], + {}, + { + saveExact: true, + save: true + } + ]) + .then(function() { + expect( + tempDir.readJson('bower.json').dependencies.package + ).to.equal(mainPackage.path + '#1.2.3'); + }); }); - it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function () { + it('writes an exact version number to devDependencies in bower.json if --save-dev --save-exact flags are used', function() { mainPackage.prepare({ 'bower.json': { name: 'package', @@ -182,17 +214,22 @@ describe('bower install', function () { } }); - return helpers.run(install, [ - [mainPackage.path], { - saveExact: true, - saveDev: true - } - ]).then(function () { - expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(mainPackage.path + '#0.1.0'); - }); + return helpers + .run(install, [ + [mainPackage.path], + { + saveExact: true, + saveDev: true + } + ]) + .then(function() { + expect( + tempDir.readJson('bower.json').devDependencies.package + ).to.equal(mainPackage.path + '#0.1.0'); + }); }); - it('writes an exact version number to devDependencies in bower.json if save-exact config setting is true and --save-dev flag is used', function () { + it('writes an exact version number to devDependencies in bower.json if save-exact config setting is true and --save-dev flag is used', function() { mainPackage.prepare({ 'bower.json': { name: 'package', @@ -206,18 +243,24 @@ describe('bower install', function () { } }); - return helpers.run(install, [ - [mainPackage.path], { - saveDev: true - }, { - saveExact: true - } - ]).then(function () { - expect(tempDir.readJson('bower.json').devDependencies.package).to.equal(mainPackage.path + '#0.1.0'); - }); + return helpers + .run(install, [ + [mainPackage.path], + { + saveDev: true + }, + { + saveExact: true + } + ]) + .then(function() { + expect( + tempDir.readJson('bower.json').devDependencies.package + ).to.equal(mainPackage.path + '#0.1.0'); + }); }); - it('reads .bowerrc from cwd', function () { + it('reads .bowerrc from cwd', function() { mainPackage.prepare({ foo: 'bar' }); @@ -234,12 +277,12 @@ describe('bower install', function () { } }); - return helpers.run(install).then(function () { + return helpers.run(install).then(function() { expect(tempDir.read('assets/package/foo')).to.be('bar'); }); }); - it('.bowerrc directory can be an absolute path', function () { + it('.bowerrc directory can be an absolute path', function() { mainPackage.prepare({ foo: 'bar' }); @@ -256,10 +299,17 @@ describe('bower install', function () { } }); - return helpers.run(install).then(function () { - expect(require('fs').readFileSync('/tmp/bower-absolute-destination-directory/package/foo', 'utf8').toString()).to.be('bar'); + return helpers.run(install).then(function() { + expect( + require('fs') + .readFileSync( + '/tmp/bower-absolute-destination-directory/package/foo', + 'utf8' + ) + .toString() + ).to.be('bar'); var deferred = Q.defer(); - rimraf('/tmp/bower-absolute-destination-directory', function (err) { + rimraf('/tmp/bower-absolute-destination-directory', function(err) { if (err) { deferred.reject(err); } else { @@ -270,7 +320,7 @@ describe('bower install', function () { }); }); - it('runs preinstall hook', function () { + it('runs preinstall hook', function() { mainPackage.prepare(); tempDir.prepare({ @@ -282,17 +332,18 @@ describe('bower install', function () { }, '.bowerrc': { scripts: { - preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' + preinstall: + 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' } } }); - return helpers.run(install).then(function () { + return helpers.run(install).then(function() { expect(tempDir.read('preinstall.txt')).to.be('package'); }); }); - it('runs postinstall hook', function () { + it('runs postinstall hook', function() { mainPackage.prepare(); tempDir.prepare({ @@ -304,36 +355,39 @@ describe('bower install', function () { }, '.bowerrc': { scripts: { - postinstall: 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' + postinstall: + 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' } } }); - return helpers.run(install).then(function () { + return helpers.run(install).then(function() { expect(tempDir.read('postinstall.txt')).to.be('package'); }); }); // To be discussed, but that's the implementation now - it('does not run hooks if nothing is installed', function () { + it('does not run hooks if nothing is installed', function() { tempDir.prepare({ 'bower.json': { name: 'test' }, '.bowerrc': { scripts: { - postinstall: 'node -e \'require("fs").writeFileSync("hooks.txt", "%")\'', - preinstall: 'node -e \'require("fs").writeFileSync("hooks.txt", "%")\'' + postinstall: + 'node -e \'require("fs").writeFileSync("hooks.txt", "%")\'', + preinstall: + 'node -e \'require("fs").writeFileSync("hooks.txt", "%")\'' } } }); - return helpers.run(install).then(function () { + return helpers.run(install).then(function() { expect(tempDir.exists('hooks.txt')).to.be(false); }); }); - it('runs postinstall after bower.json is written', function () { + it('runs postinstall after bower.json is written', function() { mainPackage.prepare(); tempDir.prepare({ @@ -342,21 +396,25 @@ describe('bower install', function () { }, '.bowerrc': { scripts: { - postinstall: 'node -e \'var fs = require("fs"); fs.writeFileSync("hook.txt", fs.readFileSync("bower.json"));\'' + postinstall: + 'node -e \'var fs = require("fs"); fs.writeFileSync("hook.txt", fs.readFileSync("bower.json"));\'' } } }); - return helpers.run(install, [ - [mainPackage.path], { - save: true - } - ]).then(function () { - expect(tempDir.read('hook.txt')).to.contain('dependencies'); - }); + return helpers + .run(install, [ + [mainPackage.path], + { + save: true + } + ]) + .then(function() { + expect(tempDir.read('hook.txt')).to.contain('dependencies'); + }); }); - it('display the output of hook scripts', function (next) { + it('display the output of hook scripts', function(next) { mainPackage.prepare(); tempDir.prepare({ @@ -374,17 +432,20 @@ describe('bower install', function () { }); var lastAction = null; - helpers.run(install).logger.intercept(function (log) { - if (log.level === 'action') { - lastAction = log; - } - }).on('end', function () { - expect(lastAction.message).to.be('foobar'); - next(); - }); + helpers + .run(install) + .logger.intercept(function(log) { + if (log.level === 'action') { + lastAction = log; + } + }) + .on('end', function() { + expect(lastAction.message).to.be('foobar'); + next(); + }); }); - it('skips components not installed by bower', function () { + it('skips components not installed by bower', function() { mainPackage.prepare({ '.git': {} //Make a dummy file instead of using slower gitPrepare() }); @@ -398,14 +459,14 @@ describe('bower install', function () { } }); - return helpers.run(install).then(function () { + return helpers.run(install).then(function() { var packageFiles = fs.readdirSync(mainPackage.path); //presence of .git file implies folder was not overwritten expect(packageFiles).to.contain('.git'); }); }); - it('works for git repositories', function () { + it('works for git repositories', function() { gitPackage.prepareGit({ '1.0.0': { 'bower.json': { @@ -430,12 +491,14 @@ describe('bower install', function () { } }); - return helpers.run(install).then(function () { - expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); + return helpers.run(install).then(function() { + expect( + tempDir.read('bower_components/package/version.txt') + ).to.contain('1.0.0'); }); }); - it('works for dependencies that point to tar files', function () { + it('works for dependencies that point to tar files', function() { var packageDir = path.join(__dirname, '../assets/package-tar.tar'); tempDir.prepare({ 'bower.json': { @@ -446,16 +509,18 @@ describe('bower install', function () { } }); - return helpers.run(install).then(function () { - expect(tempDir.read('bower_components/package/index.txt')).to.contain('1.0.0'); + return helpers.run(install).then(function() { + expect( + tempDir.read('bower_components/package/index.txt') + ).to.contain('1.0.0'); }); }); - it('does not install ignored dependencies', function () { + it('does not install ignored dependencies', function() { mainPackage.prepare(); var package2 = new helpers.TempDir({ 'bower.json': { - name: 'package2', + name: 'package2' } }).prepare(); @@ -464,7 +529,7 @@ describe('bower install', function () { name: 'package3', dependencies: { package2: package2.path, - package: mainPackage.path, + package: mainPackage.path } } }).prepare(); @@ -481,17 +546,17 @@ describe('bower install', function () { } }); - return helpers.run(install).then(function () { + return helpers.run(install).then(function() { expect(tempDir.exists('bower_components/package')).to.be(false); expect(tempDir.exists('bower_components/package2')).to.be(true); }); }); - it('does not install ignored dependencies if run multiple times', function () { + it('does not install ignored dependencies if run multiple times', function() { mainPackage.prepare(); var package2 = new helpers.TempDir({ 'bower.json': { - name: 'package2', + name: 'package2' } }).prepare(); @@ -500,7 +565,7 @@ describe('bower install', function () { name: 'package3', dependencies: { package2: package2.path, - package: mainPackage.path, + package: mainPackage.path } } }).prepare(); @@ -516,20 +581,20 @@ describe('bower install', function () { ignoredDependencies: ['package'] } }); - return helpers.run(install).then(function () { - return helpers.run(install).then(function () { + return helpers.run(install).then(function() { + return helpers.run(install).then(function() { expect(tempDir.exists('bower_components/package')).to.be(false); expect(tempDir.exists('bower_components/package2')).to.be(true); }); }); }); - it('works if packages reference each other locally', function () { + it('works if packages reference each other locally', function() { mainPackage.prepare(); var package2 = new helpers.TempDir({ 'bower.json': { name: 'package2', - dependencies : { + dependencies: { package: mainPackage.path } } @@ -552,18 +617,24 @@ describe('bower install', function () { var installPackage3 = helpers.command('install', { cwd: package3.path }); - return helpers.run(installPackage).then(function () { - return helpers.run(installPackage2).then(function () { - return helpers.run(installPackage3).then(function () { - expect(package2.exists('bower_components/package')).to.be(true); - expect(package3.exists('bower_components/package2')).to.be(true); - expect(package3.exists('bower_components/package')).to.be(true); + return helpers.run(installPackage).then(function() { + return helpers.run(installPackage2).then(function() { + return helpers.run(installPackage3).then(function() { + expect(package2.exists('bower_components/package')).to.be( + true + ); + expect(package3.exists('bower_components/package2')).to.be( + true + ); + expect(package3.exists('bower_components/package')).to.be( + true + ); }); }); }); }); - it('works if packages are nested and reference each other locally', function () { + it('works if packages are nested and reference each other locally', function() { // root directory for nested components var rootDir = new helpers.TempDir().prepare(); @@ -577,7 +648,7 @@ describe('bower install', function () { var package2 = new helpers.TempDir({ 'bower.json': { name: 'package2', - dependencies : { + dependencies: { package: package.path } } @@ -604,18 +675,24 @@ describe('bower install', function () { var installPackage3 = helpers.command('install', { cwd: package3.path }); - return helpers.run(installPackage).then(function () { - return helpers.run(installPackage2).then(function () { - return helpers.run(installPackage3).then(function () { - expect(package2.exists('bower_components/package')).to.be(true); - expect(package3.exists('bower_components/package2')).to.be(true); - expect(package3.exists('bower_components/package')).to.be(true); + return helpers.run(installPackage).then(function() { + return helpers.run(installPackage2).then(function() { + return helpers.run(installPackage3).then(function() { + expect(package2.exists('bower_components/package')).to.be( + true + ); + expect(package3.exists('bower_components/package2')).to.be( + true + ); + expect(package3.exists('bower_components/package')).to.be( + true + ); }); }); }); }); - it('recognizes proxy option in config', function (done) { + it('recognizes proxy option in config', function(done) { this.timeout(10000); tempDir.prepare({ @@ -635,30 +712,31 @@ describe('bower install', function () { .get('http://github.com/yahoo/pure/archive/v0.6.0.tar.gz') .reply(500); - return helpers.run(install, [ - undefined, - undefined, - { proxy: 'http://dummy.local/' } - ]) - .fail(function (error) { - expect(error.message).to.equal('Status code of 500'); - done(); - }); + return helpers + .run(install, [ + undefined, + undefined, + { proxy: 'http://dummy.local/' } + ]) + .fail(function(error) { + expect(error.message).to.equal('Status code of 500'); + done(); + }); }); - it('errors if the components directory is not a directory', function () { + it('errors if the components directory is not a directory', function() { tempDir.prepare({ '.bowerrc': { directory: '.bowerrc' } }); - return helpers.run(install).fail(function (error) { + return helpers.run(install).fail(function(error) { expect(error.code).to.equal('ENOTDIR'); }); }); - it('works if the package is a compressed single directory containing another directory with the same name', function () { + it('works if the package is a compressed single directory containing another directory with the same name', function() { var mainPackageBaseName = path.basename(mainPackage.path); var parentDir = path.dirname(mainPackage.path); @@ -673,7 +751,7 @@ describe('bower install', function () { var stream = tar.pack(parentDir, { entries: [mainPackageBaseName] }); stream .pipe(fs.createWriteStream(archivePath)) - .on('finish', function (result) { + .on('finish', function(result) { destroy(stream); archiveDeferred.resolve(result); }); @@ -686,15 +764,24 @@ describe('bower install', function () { }); return archiveDeferred.promise - .then(function () { - return helpers.run(install, [[archivePath]]); - }) - .then(function () { - expect(tempDir.read(path.join('bower_components', 'package', mainPackageBaseName, 'test.js'))).to.contain('test'); - }); + .then(function() { + return helpers.run(install, [[archivePath]]); + }) + .then(function() { + expect( + tempDir.read( + path.join( + 'bower_components', + 'package', + mainPackageBaseName, + 'test.js' + ) + ) + ).to.contain('test'); + }); }); - it('works if the package is an archive containing a file with an identical name', function () { + it('works if the package is an archive containing a file with an identical name', function() { var parentDir = path.dirname(mainPackage.path); mainPackage.prepare({ @@ -706,12 +793,11 @@ describe('bower install', function () { var stream = tar.pack(mainPackage.path); stream .pipe(fs.createWriteStream(archivePath)) - .on('finish', function (result) { + .on('finish', function(result) { destroy(stream); archiveDeferred.resolve(result); }); - tempDir.prepare({ 'bower.json': { name: 'test' @@ -719,20 +805,29 @@ describe('bower install', function () { }); return archiveDeferred.promise - .then(function () { - return helpers.run(install, [[archivePath]]); - }) - .then(function () { - expect(tempDir.read(path.join('bower_components', 'package', 'package.tar'))).to.contain('test'); - }); + .then(function() { + return helpers.run(install, [[archivePath]]); + }) + .then(function() { + expect( + tempDir.read( + path.join('bower_components', 'package', 'package.tar') + ) + ).to.contain('test'); + }); }); - it('should handle @ as a divider', function () { - return helpers.run(install, [ - ['empty@1.0.1'], { - save: true - } - ]).then(function () { - expect(tempDir.readJson('bower.json').dependencies).to.eql({empty: '1.0.1'}); - }); + it('should handle @ as a divider', function() { + return helpers + .run(install, [ + ['empty@1.0.1'], + { + save: true + } + ]) + .then(function() { + expect(tempDir.readJson('bower.json').dependencies).to.eql({ + empty: '1.0.1' + }); + }); }); }); diff --git a/test/commands/link.js b/test/commands/link.js index 9378f5f66..04ccd7c23 100644 --- a/test/commands/link.js +++ b/test/commands/link.js @@ -4,157 +4,202 @@ var helpers = require('../helpers'); var link = helpers.command('link'); -describe('bower link', function () { - +describe('bower link', function() { var mainPackage = new helpers.TempDir({ 'bower.json': { - name: 'package', + name: 'package' }, 'index.js': 'Hello World!' }); var otherPackage = new helpers.TempDir({ 'bower.json': { - name: 'package2', + name: 'package2' }, 'index.js': 'Welcome World!' }); var linksDir = new helpers.TempDir(); - beforeEach(function () { + beforeEach(function() { mainPackage.prepare(); otherPackage.prepare(); linksDir.prepare(); }); - it('correctly reads arguments', function () { - expect(link.readOptions(['jquery', 'angular'])) - .to.eql(['jquery', 'angular']); + it('correctly reads arguments', function() { + expect(link.readOptions(['jquery', 'angular'])).to.eql([ + 'jquery', + 'angular' + ]); }); - it('creates self link', function () { - return helpers.run(link, [undefined, undefined, - { - cwd: mainPackage.path, - storage: { - links: linksDir.path + it('creates self link', function() { + return helpers + .run(link, [ + undefined, + undefined, + { + cwd: mainPackage.path, + storage: { + links: linksDir.path + } } - } - ]).then(function () { - expect(linksDir.read('package/index.js')) - .to.be('Hello World!'); - }); + ]) + .then(function() { + expect(linksDir.read('package/index.js')).to.be('Hello World!'); + }); }); - it('creates inter-link', function () { - return helpers.run(link, [undefined, undefined, - { - cwd: mainPackage.path, - storage: { - links: linksDir.path - } - } - ]).then(function () { - return helpers.run(link, ['package', undefined, + it('creates inter-link', function() { + return helpers + .run(link, [ + undefined, + undefined, { - cwd: otherPackage.path, + cwd: mainPackage.path, storage: { links: linksDir.path } } - ]); - }).then(function () { - expect(otherPackage.read('bower_components/package/index.js')) - .to.be('Hello World!'); - }); + ]) + .then(function() { + return helpers.run(link, [ + 'package', + undefined, + { + cwd: otherPackage.path, + storage: { + links: linksDir.path + } + } + ]); + }) + .then(function() { + expect( + otherPackage.read('bower_components/package/index.js') + ).to.be('Hello World!'); + }); }); - it('creates inter-link to relative config.directory', function () { - return helpers.run(link, [undefined, undefined, - { - cwd: mainPackage.path, - storage: { - links: linksDir.path - } - } - ]).then(function () { - return helpers.run(link, ['package', undefined, + it('creates inter-link to relative config.directory', function() { + return helpers + .run(link, [ + undefined, + undefined, { - cwd: otherPackage.path, - directory: 'valid-extend', + cwd: mainPackage.path, storage: { links: linksDir.path } } - ]); - }).then(function () { - expect(otherPackage.read('valid-extend/package/index.js')) - .to.be('Hello World!'); - }); + ]) + .then(function() { + return helpers.run(link, [ + 'package', + undefined, + { + cwd: otherPackage.path, + directory: 'valid-extend', + storage: { + links: linksDir.path + } + } + ]); + }) + .then(function() { + expect( + otherPackage.read('valid-extend/package/index.js') + ).to.be('Hello World!'); + }); }); - - it('creates inter-link to absolute config.directory', function () { - return helpers.run(link, [undefined, undefined, - { - cwd: mainPackage.path, - storage: { - links: linksDir.path - } - } - ]).then(function () { - return helpers.run(link, ['package', undefined, + it('creates inter-link to absolute config.directory', function() { + return helpers + .run(link, [ + undefined, + undefined, { - cwd: path.join(otherPackage.path, 'invalid'), - directory: path.join(otherPackage.path, 'valid-override'), + cwd: mainPackage.path, storage: { links: linksDir.path } } - ]); - }).then(function () { - expect(otherPackage.read('valid-override/package/index.js')) - .to.be('Hello World!'); - }); + ]) + .then(function() { + return helpers.run(link, [ + 'package', + undefined, + { + cwd: path.join(otherPackage.path, 'invalid'), + directory: path.join( + otherPackage.path, + 'valid-override' + ), + storage: { + links: linksDir.path + } + } + ]); + }) + .then(function() { + expect( + otherPackage.read('valid-override/package/index.js') + ).to.be('Hello World!'); + }); }); - it('creates inter-link with custom local name', function () { - return helpers.run(link, [undefined, undefined, - { - cwd: mainPackage.path, - storage: { - links: linksDir.path - } - } - ]).then(function () { - return helpers.run(link, ['package', 'local', + it('creates inter-link with custom local name', function() { + return helpers + .run(link, [ + undefined, + undefined, { - cwd: otherPackage.path, + cwd: mainPackage.path, storage: { links: linksDir.path } } - ]); - }).then(function () { - expect(otherPackage.read('bower_components/local/index.js')) - .to.be('Hello World!'); - }); + ]) + .then(function() { + return helpers.run(link, [ + 'package', + 'local', + { + cwd: otherPackage.path, + storage: { + links: linksDir.path + } + } + ]); + }) + .then(function() { + expect( + otherPackage.read('bower_components/local/index.js') + ).to.be('Hello World!'); + }); }); - it('errors on unexising package', function () { - return helpers.run(link, ['package', 'local', - { - cwd: otherPackage.path, - storage: { - links: linksDir.path + it('errors on unexising package', function() { + return helpers + .run(link, [ + 'package', + 'local', + { + cwd: otherPackage.path, + storage: { + links: linksDir.path + } } - } - ]).then(function () { - throw 'Should fail creating a link!'; - }).fail(function (reason) { - expect(reason.code).to.be('ENOENT'); - expect(reason.message).to.be('Failed to create link to package'); - }); + ]) + .then(function() { + throw 'Should fail creating a link!'; + }) + .fail(function(reason) { + expect(reason.code).to.be('ENOENT'); + expect(reason.message).to.be( + 'Failed to create link to package' + ); + }); }); }); diff --git a/test/commands/list.js b/test/commands/list.js index 8385ab380..115121bde 100644 --- a/test/commands/list.js +++ b/test/commands/list.js @@ -9,13 +9,12 @@ var commands = { list: helpers.command('list') }; -describe('bower list', function () { - +describe('bower list', function() { var tempDir = new helpers.TempDir(); var gitPackage = new helpers.TempDir(); - var install = function (packages, options, config) { + var install = function(packages, options, config) { config = object.merge(config || {}, { cwd: tempDir.path }); @@ -23,7 +22,7 @@ describe('bower list', function () { return helpers.run(commands.install, [packages, options, config]); }; - var list = function (options, config) { + var list = function(options, config) { config = object.merge(config || {}, { cwd: tempDir.path }); @@ -31,26 +30,28 @@ describe('bower list', function () { return helpers.run(commands.list, [options, config]); }; - it('correctly reads arguments', function () { - expect(commands.list.readOptions(['-p', '-r'])) - .to.eql([{ - paths: true, - relative: true - }]); + it('correctly reads arguments', function() { + expect(commands.list.readOptions(['-p', '-r'])).to.eql([ + { + paths: true, + relative: true + } + ]); }); - it('correctly reads long arguments', function () { - expect(commands.list.readOptions(['--paths', '--relative'])) - .to.eql([{ - paths: true, - relative: true - }]); + it('correctly reads long arguments', function() { + expect(commands.list.readOptions(['--paths', '--relative'])).to.eql([ + { + paths: true, + relative: true + } + ]); }); - it('lists no packages when nothing installed', function () { + it('lists no packages when nothing installed', function() { tempDir.prepare(); - return list().spread(function (results) { + return list().spread(function(results) { expect(results).to.be.an(Object); expect(results.canonicalDir).to.equal(tempDir.path); expect(results.pkgMeta.dependencies).to.eql({}); @@ -61,8 +62,7 @@ describe('bower list', function () { }); }); - it('lists 1 dependency when 1 local package installed', function () { - + it('lists 1 dependency when 1 local package installed', function() { var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package', @@ -71,8 +71,8 @@ describe('bower list', function () { }).prepare(); mainPackage.prepare(); - return install([mainPackage.path]).then(function () { - return list().spread(function (results) { + return install([mainPackage.path]).then(function() { + return list().spread(function(results) { expect(results).to.be.an(Object); expect(results.canonicalDir).to.equal(tempDir.path); expect(results.pkgMeta.dependencies).to.eql({ @@ -81,7 +81,9 @@ describe('bower list', function () { expect(results.pkgMeta.devDependencies).to.eql({}); expect(results.dependencies.package).to.be.an(Object); expect(results.dependencies.package.pkgMeta).to.be.an(Object); - expect(results.dependencies.package.pkgMeta.main).to.equal('test.txt'); + expect(results.dependencies.package.pkgMeta.main).to.equal( + 'test.txt' + ); expect(results.dependencies.package.canonicalDir).to.equal( path.join(tempDir.path, 'bower_components/package') ); @@ -94,8 +96,7 @@ describe('bower list', function () { }); }); - it('lists 1 dependency with relative paths when 1 local package installed', function () { - + it('lists 1 dependency with relative paths when 1 local package installed', function() { var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package', @@ -104,14 +105,16 @@ describe('bower list', function () { }).prepare(); mainPackage.prepare(); - return install([mainPackage.path]).then(function () { - return list({relative: true}).spread(function (results) { + return install([mainPackage.path]).then(function() { + return list({ relative: true }).spread(function(results) { expect(results).to.be.an(Object); expect(results.canonicalDir).to.equal(tempDir.path); expect(results.dependencies).to.be.an(Object); expect(results.dependencies.package).to.be.an(Object); expect(results.dependencies.package.pkgMeta).to.be.an(Object); - expect(results.dependencies.package.pkgMeta.main).to.equal('test.txt'); + expect(results.dependencies.package.pkgMeta.main).to.equal( + 'test.txt' + ); expect(results.pkgMeta.dependencies).to.eql({ package: mainPackage.path + '#*' }); @@ -122,8 +125,7 @@ describe('bower list', function () { }); }); - it('lists 1 dependency with 1 source relative source mapping when 1 local package installed', function () { - + it('lists 1 dependency with 1 source relative source mapping when 1 local package installed', function() { var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package', @@ -132,8 +134,8 @@ describe('bower list', function () { }).prepare(); mainPackage.prepare(); - return install([mainPackage.path]).then(function () { - return list({paths: true}).spread(function (results) { + return install([mainPackage.path]).then(function() { + return list({ paths: true }).spread(function(results) { expect(results).to.be.an(Object); expect(results.package).to.equal( 'bower_components/package/test.txt' @@ -142,8 +144,7 @@ describe('bower list', function () { }); }); - it('lists 1 dependency with 2 source relative source mapping when 1 local package installed', function () { - + it('lists 1 dependency with 2 source relative source mapping when 1 local package installed', function() { var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package', @@ -152,8 +153,8 @@ describe('bower list', function () { }).prepare(); mainPackage.prepare(); - return install([mainPackage.path]).then(function () { - return list({paths: true}).spread(function (results) { + return install([mainPackage.path]).then(function() { + return list({ paths: true }).spread(function(results) { expect(results).to.be.an(Object); expect(results.package).to.be.an(Object); expect(results.package).to.eql([ @@ -164,7 +165,7 @@ describe('bower list', function () { }); }); - it('lists 1 dependency when 1 git package installed', function () { + it('lists 1 dependency when 1 git package installed', function() { gitPackage.prepareGit({ '1.0.0': { 'bower.json': { @@ -191,8 +192,8 @@ describe('bower list', function () { } }); - return install().then(function () { - return list().spread(function (results) { + return install().then(function() { + return list().spread(function(results) { expect(results).to.be.an(Object); expect(results.canonicalDir).to.equal(tempDir.path); expect(results.pkgMeta.dependencies).to.eql({ @@ -201,20 +202,25 @@ describe('bower list', function () { expect(results.pkgMeta.devDependencies).to.eql({}); expect(results.dependencies.package).to.be.an(Object); expect(results.dependencies.package.pkgMeta).to.be.an(Object); - expect(results.dependencies.package.pkgMeta.main).to.equal('test.txt'); + expect(results.dependencies.package.pkgMeta.main).to.equal( + 'test.txt' + ); expect(results.dependencies.package.canonicalDir).to.equal( path.join(tempDir.path, 'bower_components/package') ); expect(results.dependencies.package.dependencies).to.eql({}); expect(results.dependencies.package.nrDependants).to.equal(1); - expect(results.dependencies.package.versions).to.eql(['1.0.1', '1.0.0']); + expect(results.dependencies.package.versions).to.eql([ + '1.0.1', + '1.0.0' + ]); expect(results.nrDependants).to.equal(0); expect(results.versions).to.eql([]); }); }); }); - it('lists 1 dependency with relative paths when 1 git package installed', function () { + it('lists 1 dependency with relative paths when 1 git package installed', function() { gitPackage.prepareGit({ '1.0.0': { 'bower.json': { @@ -241,8 +247,8 @@ describe('bower list', function () { } }); - return install().then(function () { - return list({relative: true}).spread(function (results) { + return install().then(function() { + return list({ relative: true }).spread(function(results) { expect(results.canonicalDir).to.equal(tempDir.path); expect(results.pkgMeta.dependencies).to.eql({ package: gitPackage.path + '#1.0.0' diff --git a/test/commands/login.js b/test/commands/login.js index bff23734f..a867cba2a 100644 --- a/test/commands/login.js +++ b/test/commands/login.js @@ -1,24 +1,31 @@ var expect = require('expect.js'); var helpers = require('../helpers'); -var fakeGitHub = function (authenticate) { - function FakeGitHub() { } +var fakeGitHub = function(authenticate) { + function FakeGitHub() {} var _creds; - FakeGitHub.prototype.authenticate = function (creds) { + FakeGitHub.prototype.authenticate = function(creds) { _creds = creds; }; FakeGitHub.prototype.authorization = { - create: function (options, cb) { + create: function(options, cb) { if (_creds.password === 'validpassword') { cb(null, { token: 'faketoken' }); } else if (_creds.password === 'withtwofactor') { - if (options.headers && options.headers['X-GitHub-OTP'] === '123456') { + if ( + options.headers && + options.headers['X-GitHub-OTP'] === '123456' + ) { cb(null, { token: 'faketwoauthtoken' }); } else { - cb({ code: 401, message: '{ "message": "Must specify two-factor authentication OTP code." }' }); + cb({ + code: 401, + message: + '{ "message": "Must specify two-factor authentication OTP code." }' + }); } } else { cb({ code: 401, message: 'Bad credentials' }); @@ -29,8 +36,8 @@ var fakeGitHub = function (authenticate) { return FakeGitHub; }; -var fakeConfigstore = function (set, get) { - function FakeConfigstore() { } +var fakeConfigstore = function(set, get) { + function FakeConfigstore() {} FakeConfigstore.prototype.set = set; FakeConfigstore.prototype.get = get; @@ -40,59 +47,64 @@ var fakeConfigstore = function (set, get) { var login = helpers.command('login'); -var loginFactory = function (options) { +var loginFactory = function(options) { return helpers.command('login', { - 'github': fakeGitHub(), - 'configstore': fakeConfigstore( - options.set || function () { return true; }, - options.get || function () { return true; } + github: fakeGitHub(), + configstore: fakeConfigstore( + options.set || + function() { + return true; + }, + options.get || + function() { + return true; + } ) }); }; -describe('bower login', function () { - - it('correctly reads arguments', function () { - expect(login.readOptions(['--token', 'foobar'])) - .to.eql([{ token: 'foobar' }]); +describe('bower login', function() { + it('correctly reads arguments', function() { + expect(login.readOptions(['--token', 'foobar'])).to.eql([ + { token: 'foobar' } + ]); }); - it('fails if run in non-interactive shell without token passed', function () { - return helpers.run(login, []).fail(function (reason) { + it('fails if run in non-interactive shell without token passed', function() { + return helpers.run(login, []).fail(function(reason) { expect(reason.message).to.be('Login requires an interactive shell'); expect(reason.code).to.be('ENOINT'); }); }); - it('succeeds if run in non-interactive shell with token passed', function () { + it('succeeds if run in non-interactive shell with token passed', function() { return helpers.run(login, [{ token: 'foobar' }]); }); - it('succeeds if provided password is valid', function () { + it('succeeds if provided password is valid', function() { var login = loginFactory({}); var logger = login({}, { interactive: true }); - logger.once('prompt', function (prompt, answer) { + logger.once('prompt', function(prompt, answer) { answer({ username: 'user', password: 'validpassword' }); }); - return helpers.expectEvent(logger, 'end') - .spread(function (options) { + return helpers.expectEvent(logger, 'end').spread(function(options) { expect(options.token).to.be('faketoken'); }); }); - it('supports two-factor authorization', function () { + it('supports two-factor authorization', function() { var login = loginFactory({}); var logger = login({}, { interactive: true }); - logger.once('prompt', function (prompt, answer) { - logger.once('prompt', function (prompt, answer) { + logger.once('prompt', function(prompt, answer) { + logger.once('prompt', function(prompt, answer) { answer({ otpcode: '123456' }); @@ -104,33 +116,32 @@ describe('bower login', function () { }); }); - return helpers.expectEvent(logger, 'end') - .spread(function (options) { + return helpers.expectEvent(logger, 'end').spread(function(options) { expect(options.token).to.be('faketwoauthtoken'); }); }); - it('fails if provided password is invalid', function () { + it('fails if provided password is invalid', function() { var login = loginFactory({}); var logger = login({}, { interactive: true }); - logger.once('prompt', function (prompt, answer) { + logger.once('prompt', function(prompt, answer) { answer({ username: 'user', password: 'invalidpassword' }); }); - return helpers.expectEvent(logger, 'error').spread(function (error) { + return helpers.expectEvent(logger, 'error').spread(function(error) { expect(error.code).to.be('EAUTH'); expect(error.message).to.be('Authorization failed'); }); }); - it('uses username stored in config as default username', function () { + it('uses username stored in config as default username', function() { var login = loginFactory({ - get: function (key) { + get: function(key) { if (key === 'username') { return 'savedusername'; } @@ -139,15 +150,16 @@ describe('bower login', function () { var logger = login({}, { interactive: true }); - return helpers.expectEvent(logger, 'prompt') - .spread(function (prompt, answer) { - expect(prompt[0].default).to.be('savedusername'); - }); + return helpers + .expectEvent(logger, 'prompt') + .spread(function(prompt, answer) { + expect(prompt[0].default).to.be('savedusername'); + }); }); - it('saves username in config', function (done) { + it('saves username in config', function(done) { var login = loginFactory({ - set: function (key, value) { + set: function(key, value) { if (key === 'username') { expect(value).to.be('user'); done(); @@ -157,7 +169,7 @@ describe('bower login', function () { var logger = login({}, { interactive: true }); - logger.once('prompt', function (prompt, answer) { + logger.once('prompt', function(prompt, answer) { answer({ username: 'user', password: 'validpassword' @@ -165,9 +177,9 @@ describe('bower login', function () { }); }); - it('saves received token in accessToken config', function (done) { + it('saves received token in accessToken config', function(done) { var login = loginFactory({ - set: function (key, value) { + set: function(key, value) { if (key === 'accessToken') { expect(value).to.be('faketoken'); done(); @@ -177,7 +189,7 @@ describe('bower login', function () { var logger = login({}, { interactive: true }); - logger.once('prompt', function (prompt, answer) { + logger.once('prompt', function(prompt, answer) { answer({ username: 'user', password: 'validpassword' diff --git a/test/commands/lookup.js b/test/commands/lookup.js index 684582a2e..d82b029f0 100644 --- a/test/commands/lookup.js +++ b/test/commands/lookup.js @@ -3,15 +3,14 @@ var helpers = require('../helpers'); var lookup = helpers.command('lookup'); -describe('bower lookup', function () { - - var lookupWithResult = function (response) { +describe('bower lookup', function() { + var lookupWithResult = function(response) { return helpers.command('lookup', { - '../core/PackageRepository': function () { + '../core/PackageRepository': function() { return { - getRegistryClient: function () { + getRegistryClient: function() { return { - lookup: function (query, callback) { + lookup: function(query, callback) { if (query in response) { callback(null, response[query]); } else { @@ -20,20 +19,19 @@ describe('bower lookup', function () { } }; } - } + }; } }); }; - it('correctly reads arguments', function () { - expect(lookup.readOptions(['jquery'])) - .to.eql(['jquery']); + it('correctly reads arguments', function() { + expect(lookup.readOptions(['jquery'])).to.eql(['jquery']); }); - it('lookups package by name', function () { + it('lookups package by name', function() { var lookup = lookupWithResult({ jquery: { url: 'http://jquery.org' } }); - return helpers.run(lookup, ['jquery']).spread(function (result) { + return helpers.run(lookup, ['jquery']).spread(function(result) { expect(result).to.eql({ name: 'jquery', url: 'http://jquery.org' @@ -41,18 +39,18 @@ describe('bower lookup', function () { }); }); - it('returns null if no package is found', function () { + it('returns null if no package is found', function() { var lookup = lookupWithResult({ jquery: { url: 'http://jquery.org' } }); - return helpers.run(lookup, ['foobar']).spread(function (result) { + return helpers.run(lookup, ['foobar']).spread(function(result) { expect(result).to.eql(null); }); }); - it('returns null if called without argument', function () { + it('returns null if called without argument', function() { var lookup = lookupWithResult({ jquery: { url: 'http://jquery.org' } }); - return helpers.run(lookup, []).spread(function (result) { + return helpers.run(lookup, []).spread(function(result) { expect(result).to.eql(null); }); }); diff --git a/test/commands/prune.js b/test/commands/prune.js index e9092d767..b1ca44ee7 100644 --- a/test/commands/prune.js +++ b/test/commands/prune.js @@ -3,8 +3,7 @@ var helpers = require('../helpers'); var prune = helpers.command('prune'); -describe('bower home', function () { - +describe('bower home', function() { var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package', @@ -15,40 +14,46 @@ describe('bower home', function () { 'bower_components/jquery/jquery.js': 'jquery source' }); - it('correctly reads arguments', function () { - expect(prune.readOptions(['-p'])) - .to.eql([{ production: true }]); + it('correctly reads arguments', function() { + expect(prune.readOptions(['-p'])).to.eql([{ production: true }]); }); - it('correctly reads long arguments', function () { - expect(prune.readOptions(['--production'])) - .to.eql([{ production: true }]); + it('correctly reads long arguments', function() { + expect(prune.readOptions(['--production'])).to.eql([ + { production: true } + ]); }); - it('removes extraneous packages', function () { + it('removes extraneous packages', function() { mainPackage.prepare({ 'bower_components/angular/angular.js': 'angular source', 'bower_components/angular/.bower.json': { name: 'angular' } }); - return helpers.run(prune, [{}, { cwd: mainPackage.path }]).then(function () { - expect(mainPackage.exists('bower_components/angular/angular.js')) - .to.be(false); - }); + return helpers + .run(prune, [{}, { cwd: mainPackage.path }]) + .then(function() { + expect( + mainPackage.exists('bower_components/angular/angular.js') + ).to.be(false); + }); }); - it('leaves non-bower packages', function () { + it('leaves non-bower packages', function() { mainPackage.prepare({ 'bower_components/angular/angular.js': 'angular source' }); - return helpers.run(prune, [{}, { cwd: mainPackage.path }]).then(function () { - expect(mainPackage.exists('bower_components/angular/angular.js')) - .to.be(true); - }); + return helpers + .run(prune, [{}, { cwd: mainPackage.path }]) + .then(function() { + expect( + mainPackage.exists('bower_components/angular/angular.js') + ).to.be(true); + }); }); - it('deals with custom directory', function () { + it('deals with custom directory', function() { mainPackage.prepare({ '.bowerrc': { directory: 'components' }, 'bower_components/angular/.bower.json': { name: 'angular' }, @@ -57,9 +62,15 @@ describe('bower home', function () { 'components/angular/angular.js': 'angular source' }); - return helpers.run(prune, [{}, { cwd: mainPackage.path }]).then(function () { - expect(mainPackage.exists('components/angular/angular.js')).to.be(false); - expect(mainPackage.exists('bower_components/angular/angular.js')).to.be(true); - }); + return helpers + .run(prune, [{}, { cwd: mainPackage.path }]) + .then(function() { + expect( + mainPackage.exists('components/angular/angular.js') + ).to.be(false); + expect( + mainPackage.exists('bower_components/angular/angular.js') + ).to.be(true); + }); }); }); diff --git a/test/commands/register.js b/test/commands/register.js index afb43321a..845bd1554 100644 --- a/test/commands/register.js +++ b/test/commands/register.js @@ -4,18 +4,18 @@ var helpers = require('../helpers'); var register = helpers.command('register'); -var fakeRepositoryFactory = function (canonicalDir, pkgMeta) { - function FakeRepository() { } +var fakeRepositoryFactory = function(canonicalDir, pkgMeta) { + function FakeRepository() {} - FakeRepository.prototype.fetch = function () { - return Q.fcall(function () { + FakeRepository.prototype.fetch = function() { + return Q.fcall(function() { return [canonicalDir, pkgMeta]; }); }; - FakeRepository.prototype.getRegistryClient = function () { + FakeRepository.prototype.getRegistryClient = function() { return { - register: function (name, url, cb) { + register: function(name, url, cb) { cb(null, { name: name, url: url }); } }; @@ -26,118 +26,133 @@ var fakeRepositoryFactory = function (canonicalDir, pkgMeta) { var register = helpers.command('register'); -var registerFactory = function (canonicalDir, pkgMeta) { +var registerFactory = function(canonicalDir, pkgMeta) { return helpers.command('register', { '../core/PackageRepository': fakeRepositoryFactory( - canonicalDir, pkgMeta + canonicalDir, + pkgMeta ) }); }; -describe('bower register', function () { - +describe('bower register', function() { var mainPackage = new helpers.TempDir({ 'bower.json': { name: 'package' } }); - it('correctly reads arguments', function () { - expect(register.readOptions(['jquery', 'url'])) - .to.eql(['jquery', 'url']); + it('correctly reads arguments', function() { + expect(register.readOptions(['jquery', 'url'])).to.eql([ + 'jquery', + 'url' + ]); }); - it('errors if name is not provided', function () { - return helpers.run(register).fail(function (reason) { + it('errors if name is not provided', function() { + return helpers.run(register).fail(function(reason) { expect(reason.message).to.be('Usage: bower register '); expect(reason.code).to.be('EINVFORMAT'); }); }); - it('errors if url is not provided', function () { - return helpers.run(register, ['some-name']) - .fail(function (reason) { + it('errors if url is not provided', function() { + return helpers.run(register, ['some-name']).fail(function(reason) { expect(reason.message).to.be('Usage: bower register '); expect(reason.code).to.be('EINVFORMAT'); }); }); - it('errors if trying to register private package', function () { + it('errors if trying to register private package', function() { mainPackage.prepare({ 'bower.json': { private: true } }); var register = registerFactory(mainPackage.path, mainPackage.meta()); - return helpers.run(register, ['some-name', 'git://fake-url.git']) - .fail(function (reason) { - expect(reason.message).to.be('The package you are trying to register is marked as private'); - expect(reason.code).to.be('EPRIV'); - }); + return helpers + .run(register, ['some-name', 'git://fake-url.git']) + .fail(function(reason) { + expect(reason.message).to.be( + 'The package you are trying to register is marked as private' + ); + expect(reason.code).to.be('EPRIV'); + }); }); - it('should call registry client with name and url', function () { + it('should call registry client with name and url', function() { mainPackage.prepare(); var register = registerFactory(mainPackage.path, mainPackage.meta()); - return helpers.run(register, ['some-name', 'git://fake-url.git']) - .spread(function (result) { - expect(result).to.eql({ - // Result from register action on stub - name: 'some-name', url: 'git://fake-url.git' + return helpers + .run(register, ['some-name', 'git://fake-url.git']) + .spread(function(result) { + expect(result).to.eql({ + // Result from register action on stub + name: 'some-name', + url: 'git://fake-url.git' + }); }); - }); }); - it('should call registry client with name and github source', function () { + it('should call registry client with name and github source', function() { mainPackage.prepare(); var register = registerFactory(mainPackage.path, mainPackage.meta()); - return helpers.run(register, ['some-name', 'some-name/repo']) - .spread(function (result) { - expect(result).to.eql({ - // Result from register action on stub - name: 'some-name', url: 'git@github.com:some-name/repo.git' + return helpers + .run(register, ['some-name', 'some-name/repo']) + .spread(function(result) { + expect(result).to.eql({ + // Result from register action on stub + name: 'some-name', + url: 'git@github.com:some-name/repo.git' + }); }); - }); }); - it('should support single-char github names', function () { + it('should support single-char github names', function() { mainPackage.prepare(); var register = registerFactory(mainPackage.path, mainPackage.meta()); - return helpers.run(register, ['some-name', 'a/b']) - .spread(function (result) { - expect(result).to.eql({ - // Result from register action on stub - name: 'some-name', url: 'git@github.com:a/b.git' + return helpers + .run(register, ['some-name', 'a/b']) + .spread(function(result) { + expect(result).to.eql({ + // Result from register action on stub + name: 'some-name', + url: 'git@github.com:a/b.git' + }); }); - }); }); - it('should confirm in interactive mode', function () { + it('should confirm in interactive mode', function() { mainPackage.prepare(); var register = registerFactory(mainPackage.path, mainPackage.meta()); - var promise = helpers.run(register, - ['some-name', 'git://fake-url.git', { interactive: true }] - ); - - return helpers.expectEvent(promise.logger, 'confirm') - .spread(function (e) { - expect(e.type).to.be('confirm'); - expect(e.message).to.be('Registering a package will make it installable via the registry (https://registry.bower.io), continue?'); - expect(e.default).to.be(true); - }); + var promise = helpers.run(register, [ + 'some-name', + 'git://fake-url.git', + { interactive: true } + ]); + + return helpers + .expectEvent(promise.logger, 'confirm') + .spread(function(e) { + expect(e.type).to.be('confirm'); + expect(e.message).to.be( + 'Registering a package will make it installable via the registry (https://registry.bower.io), continue?' + ); + expect(e.default).to.be(true); + }); }); - it('should skip confirming when forcing', function () { + it('should skip confirming when forcing', function() { mainPackage.prepare(); var register = registerFactory(mainPackage.path, mainPackage.meta()); - return helpers.run(register, - ['some-name', 'git://fake-url.git', - { interactive: true, force: true } - ] - ); + return helpers.run(register, [ + 'some-name', + 'git://fake-url.git', + { interactive: true, force: true } + ]); }); }); diff --git a/test/commands/search.js b/test/commands/search.js index 8f6a01c92..bc2785c49 100644 --- a/test/commands/search.js +++ b/test/commands/search.js @@ -4,46 +4,44 @@ var helpers = require('../helpers'); var search = helpers.command('search'); -describe('bower search', function () { - - it('correctly reads arguments', function () { - expect(search.readOptions(['jquery'])) - .to.eql(['jquery']); +describe('bower search', function() { + it('correctly reads arguments', function() { + expect(search.readOptions(['jquery'])).to.eql(['jquery']); }); - it('searches for single repository', function () { - return Q.Promise(function (resolve) { + it('searches for single repository', function() { + return Q.Promise(function(resolve) { var search = helpers.command('search', { - '../core/PackageRepository': function () { + '../core/PackageRepository': function() { return { - getRegistryClient: function () { + getRegistryClient: function() { return { search: resolve }; } - } + }; } }); helpers.run(search, ['jquery'], {}); - }).then(function (query) { + }).then(function(query) { expect(query).to.be('jquery'); }); }); - it('lists all repositories when no query given in non-interactive mode', function () { + it('lists all repositories when no query given in non-interactive mode', function() { var nonInteractiveConfig = { interactive: false }; - return Q.Promise(function (resolve) { + return Q.Promise(function(resolve) { var search = helpers.command('search', { - '../core/PackageRepository': function () { + '../core/PackageRepository': function() { return { - getRegistryClient: function () { + getRegistryClient: function() { return { list: resolve }; } - } + }; } }); @@ -51,49 +49,57 @@ describe('bower search', function () { }); }); - it('lists all repositories when no query given and config.json is enabled in interactive mode', function () { + it('lists all repositories when no query given and config.json is enabled in interactive mode', function() { var interactiveConfig = { interactive: true, json: true }; var search = helpers.command('search', { - '../core/PackageRepository': function () { + '../core/PackageRepository': function() { return { - getRegistryClient: function () { + getRegistryClient: function() { return { - list: function (cb) { return cb(null, 'foobar'); } + list: function(cb) { + return cb(null, 'foobar'); + } }; } - } + }; } }); - return helpers.run(search, [null, interactiveConfig]) - .spread(function (result) { - expect(result).to.be('foobar'); - }); + return helpers + .run(search, [null, interactiveConfig]) + .spread(function(result) { + expect(result).to.be('foobar'); + }); }); - it('does not list any repositories in interactive mode if no query given and config.json is disabled', function () { + it('does not list any repositories in interactive mode if no query given and config.json is disabled', function() { var interactiveConfig = { interactive: true }; var search = helpers.command('search', { - '../core/PackageRepository': function () { + '../core/PackageRepository': function() { return { - getRegistryClient: function () { + getRegistryClient: function() { return { - list: function () { throw 'list called'; }, - search: function () { throw 'search called'; } + list: function() { + throw 'list called'; + }, + search: function() { + throw 'search called'; + } }; } - } + }; } }); - return helpers.run(search, [null, interactiveConfig]) - .then(function (commandResult) { - expect().fail('should fail'); - }) - .catch(function (e) { - expect(e.code).to.be('EREADOPTIONS'); - }); + return helpers + .run(search, [null, interactiveConfig]) + .then(function(commandResult) { + expect().fail('should fail'); + }) + .catch(function(e) { + expect(e.code).to.be('EREADOPTIONS'); + }); }); }); diff --git a/test/commands/uninstall.js b/test/commands/uninstall.js index db3ecbb51..a856392cb 100644 --- a/test/commands/uninstall.js +++ b/test/commands/uninstall.js @@ -6,18 +6,17 @@ var fs = require('../../lib/util/fs'); var helpers = require('../helpers'); var uninstall = helpers.command('uninstall'); -describe('bower uninstall', function () { - +describe('bower uninstall', function() { var tempDir = new helpers.TempDir({ 'bower.json': { name: 'hello-world', dependencies: { - 'underscore': '*' + underscore: '*' } } }); - beforeEach(function () { + beforeEach(function() { tempDir.prepare(); }); @@ -32,88 +31,129 @@ describe('bower uninstall', function () { interactive: true }; - it('correctly reads arguments', function () { - expect(uninstall.readOptions(['jquery', '-S', '-D'])) - .to.eql([['jquery'], { save: true, saveDev: true }]); + it('correctly reads arguments', function() { + expect(uninstall.readOptions(['jquery', '-S', '-D'])).to.eql([ + ['jquery'], + { save: true, saveDev: true } + ]); }); - it('correctly reads long arguments', function () { - expect(uninstall.readOptions(['jquery', '--save', '--save-dev'])) - .to.eql([['jquery'], { save: true, saveDev: true }]); + it('correctly reads long arguments', function() { + expect( + uninstall.readOptions(['jquery', '--save', '--save-dev']) + ).to.eql([['jquery'], { save: true, saveDev: true }]); }); - it('does not remove anything from dependencies by default', function () { - return helpers.run(uninstall, [['underscore'], undefined, config]).then(function () { - expect(bowerJson().dependencies).to.eql({ 'underscore': '*' }); - }); + it('does not remove anything from dependencies by default', function() { + return helpers + .run(uninstall, [['underscore'], undefined, config]) + .then(function() { + expect(bowerJson().dependencies).to.eql({ underscore: '*' }); + }); }); - it('removes dependency from bower.json if --save flag is used', function () { - return helpers.run(uninstall, [['underscore'], {save: true}, config]).then(function () { - expect(bowerJson().dependencies).to.eql({}); - }); + it('removes dependency from bower.json if --save flag is used', function() { + return helpers + .run(uninstall, [['underscore'], { save: true }, config]) + .then(function() { + expect(bowerJson().dependencies).to.eql({}); + }); }); - it('removes dependency from bower.json if save config setting is true', function () { + it('removes dependency from bower.json if save config setting is true', function() { var configWithSave = { cwd: tempDir.path, interactive: true, save: true }; - return helpers.run(uninstall, [['underscore'], {}, configWithSave]).then(function () { - expect(bowerJson().dependencies).to.eql({}); - }); + return helpers + .run(uninstall, [['underscore'], {}, configWithSave]) + .then(function() { + expect(bowerJson().dependencies).to.eql({}); + }); }); - it('removes dependency from relative config.directory', function () { - var targetPath = path.resolve(tempDir.path, 'other_directory/underscore'); + it('removes dependency from relative config.directory', function() { + var targetPath = path.resolve( + tempDir.path, + 'other_directory/underscore' + ); mkdirp.sync(targetPath); - fs.writeFileSync(path.join(targetPath, '.bower.json'), '{ "name": "underscore" }'); - - return helpers.run(uninstall, [['underscore'], undefined, { - cwd: tempDir.path, - directory: 'other_directory', - interactive: true - }]) - .then(function () { - expect(function () { - fs.statSync(targetPath); - }).to.throwException(/no such file or directory/); - }); + fs.writeFileSync( + path.join(targetPath, '.bower.json'), + '{ "name": "underscore" }' + ); + + return helpers + .run(uninstall, [ + ['underscore'], + undefined, + { + cwd: tempDir.path, + directory: 'other_directory', + interactive: true + } + ]) + .then(function() { + expect(function() { + fs.statSync(targetPath); + }).to.throwException(/no such file or directory/); + }); }); - it('removes dependency from absolute config.directory', function () { - var targetPath = path.resolve(tempDir.path, 'other_directory/underscore'); + it('removes dependency from absolute config.directory', function() { + var targetPath = path.resolve( + tempDir.path, + 'other_directory/underscore' + ); mkdirp.sync(targetPath); - fs.writeFileSync(path.join(targetPath, '.bower.json'), '{ "name": "underscore" }'); - - return helpers.run(uninstall, [['underscore'], undefined, { - cwd: tempDir.path, - directory: path.resolve(tempDir.path, 'other_directory'), - interactive: true - }]) - .then(function () { - expect(function () { - fs.statSync(targetPath); - }).to.throwException(/no such file or directory/); - }); + fs.writeFileSync( + path.join(targetPath, '.bower.json'), + '{ "name": "underscore" }' + ); + + return helpers + .run(uninstall, [ + ['underscore'], + undefined, + { + cwd: tempDir.path, + directory: path.resolve(tempDir.path, 'other_directory'), + interactive: true + } + ]) + .then(function() { + expect(function() { + fs.statSync(targetPath); + }).to.throwException(/no such file or directory/); + }); }); - it('removes a project with url from absolute path', function () { - var targetPath = path.resolve(tempDir.path, 'other_directory/underscore'); + it('removes a project with url from absolute path', function() { + var targetPath = path.resolve( + tempDir.path, + 'other_directory/underscore' + ); mkdirp.sync(targetPath); - fs.writeFileSync(path.join(targetPath, '.bower.json'), '{ "name": "underscore", "_source": "git://github.com/user/repo.git" }'); - - return helpers.run(uninstall, [['git://github.com/user/repo.git'], undefined, { - cwd: tempDir.path, - directory: path.resolve(tempDir.path, 'other_directory'), - interactive: true - }]) - .then(function () { - expect(function () { + fs.writeFileSync( + path.join(targetPath, '.bower.json'), + '{ "name": "underscore", "_source": "git://github.com/user/repo.git" }' + ); + + return helpers + .run(uninstall, [ + ['git://github.com/user/repo.git'], + undefined, + { + cwd: tempDir.path, + directory: path.resolve(tempDir.path, 'other_directory'), + interactive: true + } + ]) + .then(function() { + expect(function() { fs.statSync(targetPath); }).to.throwException(/no such file or directory/); }); }); - }); diff --git a/test/commands/unregister.js b/test/commands/unregister.js index 2cfdef97c..99ca1f578 100644 --- a/test/commands/unregister.js +++ b/test/commands/unregister.js @@ -1,12 +1,12 @@ var expect = require('expect.js'); var helpers = require('../helpers'); -var fakeRepositoryFactory = function () { - function FakeRepository() { } +var fakeRepositoryFactory = function() { + function FakeRepository() {} - FakeRepository.prototype.getRegistryClient = function () { + FakeRepository.prototype.getRegistryClient = function() { return { - unregister: function (name, cb) { + unregister: function(name, cb) { cb(null, { name: name }); } }; @@ -17,31 +17,30 @@ var fakeRepositoryFactory = function () { var unregister = helpers.command('unregister'); -var unregisterFactory = function () { +var unregisterFactory = function() { return helpers.command('unregister', { '../core/PackageRepository': fakeRepositoryFactory() }); }; -describe('bower unregister', function () { - - it('correctly reads arguments', function () { - expect(unregister.readOptions(['jquery'])) - .to.eql(['jquery']); +describe('bower unregister', function() { + it('correctly reads arguments', function() { + expect(unregister.readOptions(['jquery'])).to.eql(['jquery']); }); - it('errors if name is not provided', function () { - return helpers.run(unregister).fail(function (reason) { - expect(reason.message).to.be('Usage: bower unregister '); + it('errors if name is not provided', function() { + return helpers.run(unregister).fail(function(reason) { + expect(reason.message).to.be( + 'Usage: bower unregister ' + ); expect(reason.code).to.be('EINVFORMAT'); }); }); - it('should call registry client with name', function () { + it('should call registry client with name', function() { var unregister = unregisterFactory(); - return helpers.run(unregister, ['some-name']) - .spread(function (result) { + return helpers.run(unregister, ['some-name']).spread(function(result) { expect(result).to.eql({ // Result from register action on stub name: 'some-name' @@ -49,31 +48,34 @@ describe('bower unregister', function () { }); }); - it('should confirm in interactive mode', function () { + it('should confirm in interactive mode', function() { var register = unregisterFactory(); - var promise = helpers.run(register, - ['some-name', { + var promise = helpers.run(register, [ + 'some-name', + { interactive: true, registry: { register: 'http://localhost' } - }] - ); + } + ]); - return helpers.expectEvent(promise.logger, 'confirm') - .spread(function (e) { - expect(e.type).to.be('confirm'); - expect(e.message).to.be('You are about to remove component "some-name" from the bower registry (http://localhost). It is generally considered bad behavior to remove versions of a library that others are depending on. Are you really sure?'); - expect(e.default).to.be(false); - }); + return helpers + .expectEvent(promise.logger, 'confirm') + .spread(function(e) { + expect(e.type).to.be('confirm'); + expect(e.message).to.be( + 'You are about to remove component "some-name" from the bower registry (http://localhost). It is generally considered bad behavior to remove versions of a library that others are depending on. Are you really sure?' + ); + expect(e.default).to.be(false); + }); }); - it('should skip confirming when forcing', function () { + it('should skip confirming when forcing', function() { var register = unregisterFactory(); - return helpers.run(register, - ['some-name', - { interactive: true, force: true } - ] - ); + return helpers.run(register, [ + 'some-name', + { interactive: true, force: true } + ]); }); }); diff --git a/test/commands/update.js b/test/commands/update.js index d5e31a037..dcc8f1999 100644 --- a/test/commands/update.js +++ b/test/commands/update.js @@ -5,7 +5,7 @@ var helpers = require('../helpers'); var updateCmd = helpers.command('update'); var commands = helpers.require('lib/index').commands; -describe('bower update', function () { +describe('bower update', function() { this.timeout(10000); var tempDir = new helpers.TempDir(); @@ -42,7 +42,7 @@ describe('bower update', function () { } }).prepare(); - var updateLogger = function (packages, options, config) { + var updateLogger = function(packages, options, config) { config = object.merge(config || {}, { cwd: tempDir.path }); @@ -50,30 +50,30 @@ describe('bower update', function () { return commands.update(packages, options, config); }; - var update = function (packages, options, config) { + var update = function(packages, options, config) { var logger = updateLogger(packages, options, config); return helpers.expectEvent(logger, 'end'); }; - var install = function (packages, options, config) { + var install = function(packages, options, config) { config = object.merge(config || {}, { cwd: tempDir.path }); - var logger = commands.install( - packages, options, config - ); + var logger = commands.install(packages, options, config); return helpers.expectEvent(logger, 'end'); }; - it('correctly reads arguments', function () { - expect(updateCmd.readOptions(['jquery', '-F', '-p'])) - .to.eql([['jquery'], { forceLatest: true, production: true }]); + it('correctly reads arguments', function() { + expect(updateCmd.readOptions(['jquery', '-F', '-p'])).to.eql([ + ['jquery'], + { forceLatest: true, production: true } + ]); }); - it('install missing packages', function () { + it('install missing packages', function() { mainPackage.prepare(); tempDir.prepare({ @@ -85,13 +85,17 @@ describe('bower update', function () { } }); - return update().then(function () { - expect(tempDir.exists('bower_components/package/bower.json')).to.equal(true); - expect(tempDir.read('bower_components/package/bower.json')).to.contain('"name": "package"'); + return update().then(function() { + expect( + tempDir.exists('bower_components/package/bower.json') + ).to.equal(true); + expect( + tempDir.read('bower_components/package/bower.json') + ).to.contain('"name": "package"'); }); }); - it('does not install ignored dependencies', function () { + it('does not install ignored dependencies', function() { var package3 = new helpers.TempDir({ 'bower.json': { name: 'package3' @@ -119,13 +123,15 @@ describe('bower update', function () { } }); - return update().then(function () { - expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); + return update().then(function() { + expect( + tempDir.exists('bower_components/package2/bower.json') + ).to.equal(true); expect(tempDir.exists('bower_components/package3')).to.equal(false); }); }); - it('does not install ignored dependencies if run multiple times', function () { + it('does not install ignored dependencies if run multiple times', function() { var package3 = new helpers.TempDir({ 'bower.json': { name: 'package3' @@ -153,16 +159,19 @@ describe('bower update', function () { } }); - return update().then(function () { - return update().then(function () { - expect(tempDir.exists('bower_components/package2/bower.json')).to.equal(true); - expect(tempDir.exists('bower_components/package3')).to.equal(false); + return update().then(function() { + return update().then(function() { + expect( + tempDir.exists('bower_components/package2/bower.json') + ).to.equal(true); + expect(tempDir.exists('bower_components/package3')).to.equal( + false + ); }); }); - }); - it('runs preinstall hook when installing missing package', function () { + it('runs preinstall hook when installing missing package', function() { mainPackage.prepare(); tempDir.prepare({ @@ -174,17 +183,18 @@ describe('bower update', function () { }, '.bowerrc': { scripts: { - preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' + preinstall: + 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' } } }); - return update().then(function () { + return update().then(function() { expect(tempDir.read('preinstall.txt')).to.be('package'); }); }); - it('runs postinstall hook when installing missing package', function () { + it('runs postinstall hook when installing missing package', function() { mainPackage.prepare(); tempDir.prepare({ @@ -196,17 +206,18 @@ describe('bower update', function () { }, '.bowerrc': { scripts: { - postinstall: 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' + postinstall: + 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' } } }); - return update().then(function () { + return update().then(function() { expect(tempDir.read('postinstall.txt')).to.be('package'); }); }); - it('doesn\'t runs postinstall when no package is update', function () { + it("doesn't runs postinstall when no package is update", function() { mainPackage.prepare(); tempDir.prepare({ @@ -218,21 +229,22 @@ describe('bower update', function () { }, '.bowerrc': { scripts: { - postinstall: 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' + postinstall: + 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' } } }); - return install().then(function () { + return install().then(function() { tempDir.prepare(); - return update().then(function () { + return update().then(function() { expect(tempDir.exists('postinstall.txt')).to.be(false); }); }); }); - it('updates a package', function () { + it('updates a package', function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -242,9 +254,10 @@ describe('bower update', function () { } }); - return install().then(function () { - - expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.0'); + return install().then(function() { + expect( + tempDir.read('bower_components/package/version.txt') + ).to.contain('1.0.0'); tempDir.prepare({ 'bower.json': { @@ -255,13 +268,15 @@ describe('bower update', function () { } }); - return update().then(function () { - expect(tempDir.read('bower_components/package/version.txt')).to.contain('1.0.1'); + return update().then(function() { + expect( + tempDir.read('bower_components/package/version.txt') + ).to.contain('1.0.1'); }); }); }); - it('does not install ignored dependencies when updating a package', function () { + it('does not install ignored dependencies when updating a package', function() { this.timeout(15000); var package3 = new helpers.TempDir({ @@ -303,9 +318,10 @@ describe('bower update', function () { } }); - return install().then(function () { - - expect(tempDir.readJson('bower_components/package2/bower.json').version).to.equal('1.0.0'); + return install().then(function() { + expect( + tempDir.readJson('bower_components/package2/bower.json').version + ).to.equal('1.0.0'); expect(tempDir.exists('bower_components/package3')).to.equal(false); tempDir.prepare({ @@ -320,14 +336,19 @@ describe('bower update', function () { } }); - return update().then(function () { - expect(tempDir.readJson('bower_components/package2/bower.json').version).to.equal('1.0.1'); - expect(tempDir.exists('bower_components/package3')).to.equal(false); + return update().then(function() { + expect( + tempDir.readJson('bower_components/package2/bower.json') + .version + ).to.equal('1.0.1'); + expect(tempDir.exists('bower_components/package3')).to.equal( + false + ); }); }); }); - it('runs preinstall hook when updating a package', function () { + it('runs preinstall hook when updating a package', function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -337,7 +358,7 @@ describe('bower update', function () { } }); - return install().then(function () { + return install().then(function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -347,19 +368,22 @@ describe('bower update', function () { }, '.bowerrc': { scripts: { - preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' + preinstall: + 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'' } } }); expect(tempDir.exists('preinstall.txt')).to.be(false); - return update().then(function () { - expect(tempDir.read('preinstall.txt')).to.be('subPackage package'); + return update().then(function() { + expect(tempDir.read('preinstall.txt')).to.be( + 'subPackage package' + ); }); }); }); - it('runs postinstall hook when updating a package', function () { + it('runs postinstall hook when updating a package', function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -369,7 +393,7 @@ describe('bower update', function () { } }); - return install().then(function () { + return install().then(function() { tempDir.prepare({ 'bower.json': { name: 'test', @@ -379,15 +403,19 @@ describe('bower update', function () { }, '.bowerrc': { scripts: { - preinstall: 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'', - postinstall: 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' + preinstall: + 'node -e \'require("fs").writeFileSync("preinstall.txt", "%")\'', + postinstall: + 'node -e \'require("fs").writeFileSync("postinstall.txt", "%")\'' } } }); expect(tempDir.exists('postinstall.txt')).to.be(false); - return update().then(function () { - expect(tempDir.read('postinstall.txt')).to.be('subPackage package'); + return update().then(function() { + expect(tempDir.read('postinstall.txt')).to.be( + 'subPackage package' + ); }); }); }); diff --git a/test/commands/version.js b/test/commands/version.js index f666a5688..cad36863c 100644 --- a/test/commands/version.js +++ b/test/commands/version.js @@ -3,109 +3,140 @@ var expect = require('expect.js'); var helpers = require('../helpers'); var version = helpers.require('lib/commands').version; -describe('bower version', function () { - +describe('bower version', function() { var mainPackage = new helpers.TempDir({ 'v0.0.0': { 'bower.json': { - name: 'foobar', + name: 'foobar' } } }); - it('bumps patch version', function () { + it('bumps patch version', function() { mainPackage.prepareGit(); - return helpers.run(version, ['patch', {}, { cwd: mainPackage.path }]).then(function () { - expect(mainPackage.latestGitTag()).to.be('0.0.1'); - }); + return helpers + .run(version, ['patch', {}, { cwd: mainPackage.path }]) + .then(function() { + expect(mainPackage.latestGitTag()).to.be('0.0.1'); + }); }); - it('bumps minor version', function () { + it('bumps minor version', function() { mainPackage.prepareGit(); - return helpers.run(version, ['minor', {}, { cwd: mainPackage.path }]).then(function () { - expect(mainPackage.latestGitTag()).to.be('0.1.0'); - }); + return helpers + .run(version, ['minor', {}, { cwd: mainPackage.path }]) + .then(function() { + expect(mainPackage.latestGitTag()).to.be('0.1.0'); + }); }); - it('bumps major version', function () { + it('bumps major version', function() { mainPackage.prepareGit(); - return helpers.run(version, ['major', {}, { cwd: mainPackage.path }]).then(function () { - expect(mainPackage.latestGitTag()).to.be('1.0.0'); - }); + return helpers + .run(version, ['major', {}, { cwd: mainPackage.path }]) + .then(function() { + expect(mainPackage.latestGitTag()).to.be('1.0.0'); + }); }); - it('changes version', function () { + it('changes version', function() { mainPackage.prepareGit(); - return helpers.run(version, ['1.2.3', {}, { cwd: mainPackage.path }]).then(function () { - expect(mainPackage.latestGitTag()).to.be('1.2.3'); - }); + return helpers + .run(version, ['1.2.3', {}, { cwd: mainPackage.path }]) + .then(function() { + expect(mainPackage.latestGitTag()).to.be('1.2.3'); + }); }); - it('returns the new version', function () { + it('returns the new version', function() { mainPackage.prepareGit(); - return helpers.run(version, ['major', {}, { cwd: mainPackage.path }]).then(function (results) { - expect(results[0]).to.be('v1.0.0'); - }); + return helpers + .run(version, ['major', {}, { cwd: mainPackage.path }]) + .then(function(results) { + expect(results[0]).to.be('v1.0.0'); + }); }); - it('fails on a dirty git repository', function () { + it('fails on a dirty git repository', function() { mainPackage.prepareGit(); mainPackage.create({ 'dirty.txt': 'This file has not been committed' }); - return helpers.run(version, ['patch', {}, { cwd: mainPackage.path }]).then(null, function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.be('ENOTGITREPOSITORY'); - }); + return helpers + .run(version, ['patch', {}, { cwd: mainPackage.path }]) + .then(null, function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.be('ENOTGITREPOSITORY'); + }); }); - it('fails when the version already exists', function () { + it('fails when the version already exists', function() { mainPackage.prepareGit(); - return helpers.run(version, ['0.0.0', {}, { cwd: mainPackage.path }]).then(null, function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.be('EVERSIONEXISTS'); - }); + return helpers + .run(version, ['0.0.0', {}, { cwd: mainPackage.path }]) + .then(null, function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.be('EVERSIONEXISTS'); + }); }); - it('fails with an invalid argument', function () { + it('fails with an invalid argument', function() { mainPackage.prepareGit(); - return helpers.run(version, ['lol', {}, { cwd: mainPackage.path }]).then(null, function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.be('EINVALIDVERSION'); - }); + return helpers + .run(version, ['lol', {}, { cwd: mainPackage.path }]) + .then(null, function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.be('EINVALIDVERSION'); + }); }); - it('bumps with custom commit message', function () { + it('bumps with custom commit message', function() { mainPackage.prepareGit(); - return helpers.run(version, ['patch', { message: 'Bumping %s, because what'}, { cwd: mainPackage.path }]).then(function () { - var tags = mainPackage.git('tag'); - expect(tags).to.be('v0.0.0\nv0.0.1\n'); - var message = mainPackage.git('log', '--pretty=format:%s', '-n1'); - expect(message).to.be('Bumping v0.0.1, because what'); - }); + return helpers + .run(version, [ + 'patch', + { message: 'Bumping %s, because what' }, + { cwd: mainPackage.path } + ]) + .then(function() { + var tags = mainPackage.git('tag'); + expect(tags).to.be('v0.0.0\nv0.0.1\n'); + var message = mainPackage.git( + 'log', + '--pretty=format:%s', + '-n1' + ); + expect(message).to.be('Bumping v0.0.1, because what'); + }); }); - it('creates commit and tags', function () { + it('creates commit and tags', function() { mainPackage.prepareGit(); - return helpers.run(version, ['patch', {}, { cwd: mainPackage.path }]).then(function () { - var tags = mainPackage.git('tag'); - expect(tags).to.be('v0.0.0\nv0.0.1\n'); - var message = mainPackage.git('log', '--pretty=format:%s', '-n1'); - expect(message).to.be('v0.0.1'); - }); + return helpers + .run(version, ['patch', {}, { cwd: mainPackage.path }]) + .then(function() { + var tags = mainPackage.git('tag'); + expect(tags).to.be('v0.0.0\nv0.0.1\n'); + var message = mainPackage.git( + 'log', + '--pretty=format:%s', + '-n1' + ); + expect(message).to.be('v0.0.1'); + }); }); - it('assumes v0.0.0 when no tags exist', function () { + it('assumes v0.0.0 when no tags exist', function() { var packageWithoutTags = new helpers.TempDir({}); packageWithoutTags.prepareGit(); @@ -115,8 +146,10 @@ describe('bower version', function () { packageWithoutTags.git('add', '-A'); packageWithoutTags.git('commit', '-m"commit"'); - return helpers.run(version, ['major', {}, { cwd: packageWithoutTags.path }]).then(function () { - expect(packageWithoutTags.latestGitTag()).to.be('1.0.0'); - }); + return helpers + .run(version, ['major', {}, { cwd: packageWithoutTags.path }]) + .then(function() { + expect(packageWithoutTags.latestGitTag()).to.be('1.0.0'); + }); }); }); diff --git a/test/core/Manager.js b/test/core/Manager.js index f47ec20c7..66bd4baba 100644 --- a/test/core/Manager.js +++ b/test/core/Manager.js @@ -5,21 +5,22 @@ var Logger = require('bower-logger'); var Manager = require('../../lib/core/Manager'); var defaultConfig = require('../../lib/config'); -describe('Manager', function () { +describe('Manager', function() { var manager; - var packagesCacheDir = - path.join(__dirname, '../assets/temp-resolve-cache'); + var packagesCacheDir = path.join(__dirname, '../assets/temp-resolve-cache'); - var registryCacheDir = - path.join(__dirname, '../assets/temp-registry-cache'); + var registryCacheDir = path.join( + __dirname, + '../assets/temp-registry-cache' + ); - after(function () { + after(function() { rimraf.sync(registryCacheDir); rimraf.sync(packagesCacheDir); }); - beforeEach(function (next) { + beforeEach(function(next) { var logger = new Logger(); var config = defaultConfig({ @@ -34,8 +35,8 @@ describe('Manager', function () { next(); }); - describe('resolve', function () { - it('prefers exact versions over ranges', function () { + describe('resolve', function() { + it('prefers exact versions over ranges', function() { manager._resolved = { ember: [ { @@ -49,7 +50,7 @@ describe('Manager', function () { ] }; - return manager.resolve().then(function () { + return manager.resolve().then(function() { expect(manager._dissected).to.eql({ ember: { target: '2.7.0', @@ -60,74 +61,91 @@ describe('Manager', function () { }); }); - describe('_areCompatible', function () { - describe('resolved is being fetched', function () { - - it('accepts endpoints with same targets', function () { - expect(manager._areCompatible( - { name: 'foo', target: 'xxx' }, - { name: 'bar', target: 'xxx' } - )).to.be(true); + describe('_areCompatible', function() { + describe('resolved is being fetched', function() { + it('accepts endpoints with same targets', function() { + expect( + manager._areCompatible( + { name: 'foo', target: 'xxx' }, + { name: 'bar', target: 'xxx' } + ) + ).to.be(true); }); - it('rejects endpoints with different targets', function () { - expect(manager._areCompatible( - { name: 'foo', target: 'xxx' }, - { name: 'bar', target: 'yyy' } - )).to.be(false); + it('rejects endpoints with different targets', function() { + expect( + manager._areCompatible( + { name: 'foo', target: 'xxx' }, + { name: 'bar', target: 'yyy' } + ) + ).to.be(false); }); - it('accepts with version and matching range', function () { - expect(manager._areCompatible( - { name: 'foo', target: '0.1.2' }, - { name: 'bar', target: '~0.1.0' } - )).to.be(true); + it('accepts with version and matching range', function() { + expect( + manager._areCompatible( + { name: 'foo', target: '0.1.2' }, + { name: 'bar', target: '~0.1.0' } + ) + ).to.be(true); }); - it('rejects with version and non-matching range', function () { - expect(manager._areCompatible( - { name: 'foo', target: '0.1.2' }, - { name: 'bar', target: '~0.1.3' } - )).to.be(false); + it('rejects with version and non-matching range', function() { + expect( + manager._areCompatible( + { name: 'foo', target: '0.1.2' }, + { name: 'bar', target: '~0.1.3' } + ) + ).to.be(false); }); - it('accepts with matching range and version', function () { - expect(manager._areCompatible( - { name: 'foo', target: '~0.1.0' }, - { name: 'bar', target: '0.1.2' } - )).to.be(true); + it('accepts with matching range and version', function() { + expect( + manager._areCompatible( + { name: 'foo', target: '~0.1.0' }, + { name: 'bar', target: '0.1.2' } + ) + ).to.be(true); }); - it('accepts with non-matching range and version', function () { - expect(manager._areCompatible( - { name: 'foo', target: '~0.1.3' }, - { name: 'bar', target: '0.1.2' } - )).to.be(false); + it('accepts with non-matching range and version', function() { + expect( + manager._areCompatible( + { name: 'foo', target: '~0.1.3' }, + { name: 'bar', target: '0.1.2' } + ) + ).to.be(false); }); - it('accepts with matching ranges', function () { - expect(manager._areCompatible( - { name: 'foo', target: '~0.1.0' }, - { name: 'bar', target: '~0.1.3' } - )).to.be(true); + it('accepts with matching ranges', function() { + expect( + manager._areCompatible( + { name: 'foo', target: '~0.1.0' }, + { name: 'bar', target: '~0.1.3' } + ) + ).to.be(true); }); - it('rejects with non-matching ranges', function () { - expect(manager._areCompatible( - { name: 'foo', target: '~0.1.0' }, - { name: 'bar', target: '~0.2.3' } - )).to.be(false); + it('rejects with non-matching ranges', function() { + expect( + manager._areCompatible( + { name: 'foo', target: '~0.1.0' }, + { name: 'bar', target: '~0.2.3' } + ) + ).to.be(false); }); - it('rejects with non-matching ranges', function () { - expect(manager._areCompatible( - { name: 'foo', target: '~0.1.0' }, - { name: 'bar', target: 'xxx' } - )).to.be(false); + it('rejects with non-matching ranges', function() { + expect( + manager._areCompatible( + { name: 'foo', target: '~0.1.0' }, + { name: 'bar', target: 'xxx' } + ) + ).to.be(false); }); }); - describe('resolved is already fetched', function () { + describe('resolved is already fetched', function() { var resolved = { name: 'foo', target: '~1.2.1', @@ -136,38 +154,46 @@ describe('Manager', function () { } }; - it('accepts if the same version as resolved', function () { - expect(manager._areCompatible( - { name: 'foo', target: '1.2.3' }, - resolved - )).to.be(true); + it('accepts if the same version as resolved', function() { + expect( + manager._areCompatible( + { name: 'foo', target: '1.2.3' }, + resolved + ) + ).to.be(true); }); - it('rejects if different version than resolved', function () { - expect(manager._areCompatible( - { name: 'foo', target: '1.2.4' }, - resolved - )).to.be(false); + it('rejects if different version than resolved', function() { + expect( + manager._areCompatible( + { name: 'foo', target: '1.2.4' }, + resolved + ) + ).to.be(false); }); - it('accepts if range matches resolved version', function () { - expect(manager._areCompatible( - { name: 'foo', target: '~1.2.1' }, - resolved - )).to.be(true); + it('accepts if range matches resolved version', function() { + expect( + manager._areCompatible( + { name: 'foo', target: '~1.2.1' }, + resolved + ) + ).to.be(true); }); - it('rejects if range does not match', function () { - expect(manager._areCompatible( - { name: 'foo', target: '~1.2.4' }, - resolved - )).to.be(false); + it('rejects if range does not match', function() { + expect( + manager._areCompatible( + { name: 'foo', target: '~1.2.4' }, + resolved + ) + ).to.be(false); }); }); }); - describe('_getCap', function () { - it('finds highest bound', function () { + describe('_getCap', function() { + it('finds highest bound', function() { var highest = manager._getCap( [['2.1.1-0', '<2.2.0-0'], '<3.2.0'], 'highest' @@ -179,7 +205,7 @@ describe('Manager', function () { }); }); - it('finds lowest bound', function () { + it('finds lowest bound', function() { var highest = manager._getCap( [['2.1.1-0', '<2.2.0-0'], '<3.2.0'], 'lowest' @@ -191,10 +217,8 @@ describe('Manager', function () { }); }); - it('defaults to highest bound', function () { - var highest = manager._getCap( - ['1.0.0', '2.0.0'] - ); + it('defaults to highest bound', function() { + var highest = manager._getCap(['1.0.0', '2.0.0']); expect(highest).to.eql({ version: '2.0.0', @@ -202,11 +226,8 @@ describe('Manager', function () { }); }); - - it('ignores non-semver elements', function () { - var highest = manager._getCap( - ['0.9', '>1.0.1', ['<1.0.0', 'lol']] - ); + it('ignores non-semver elements', function() { + var highest = manager._getCap(['0.9', '>1.0.1', ['<1.0.0', 'lol']]); expect(highest).to.eql({ version: '1.0.1', @@ -214,7 +235,7 @@ describe('Manager', function () { }); }); - it('returns empty object if cap is not found', function () { + it('returns empty object if cap is not found', function() { var highest = manager._getCap( ['0.9'] // Not a semver ); @@ -223,41 +244,34 @@ describe('Manager', function () { }); }); - describe('_uniquify', function () { - - it('leaves last unique element', function () { + describe('_uniquify', function() { + it('leaves last unique element', function() { var unique = manager._uniquify([ { name: 'foo', id: 1 }, { name: 'foo', id: 2 } ]); - expect(unique).to.eql([ - { name: 'foo', id: 2 } - ]); + expect(unique).to.eql([{ name: 'foo', id: 2 }]); }); - it('compares by name first', function () { + it('compares by name first', function() { var unique = manager._uniquify([ { name: 'foo', source: 'google.com' }, { name: 'foo', source: 'facebook.com' } ]); - expect(unique).to.eql([ - { name: 'foo', source: 'facebook.com' } - ]); + expect(unique).to.eql([{ name: 'foo', source: 'facebook.com' }]); }); - it('compares by source if name is not available', function () { + it('compares by source if name is not available', function() { var unique = manager._uniquify([ { source: 'facebook.com' }, { source: 'facebook.com' } ]); - expect(unique).to.eql([ - { source: 'facebook.com' } - ]); + expect(unique).to.eql([{ source: 'facebook.com' }]); }); - it('leaves different targets intact', function () { + it('leaves different targets intact', function() { var unique = manager._uniquify([ { source: 'facebook.com', target: 'a1b2c3' }, { source: 'facebook.com', target: 'ffffff' } @@ -269,7 +283,7 @@ describe('Manager', function () { ]); }); - it('removes if same targets', function () { + it('removes if same targets', function() { var unique = manager._uniquify([ { source: 'facebook.com', target: 'ffffff' }, { source: 'facebook.com', target: 'ffffff' } @@ -280,16 +294,13 @@ describe('Manager', function () { ]); }); - it('ignores other fields', function () { + it('ignores other fields', function() { var unique = manager._uniquify([ { source: 'facebook.com', foo: 12 }, { source: 'facebook.com', bar: 13 } ]); - expect(unique).to.eql([ - { source: 'facebook.com', bar: 13 } - ]); + expect(unique).to.eql([{ source: 'facebook.com', bar: 13 }]); }); }); - }); diff --git a/test/core/packageRepository.js b/test/core/packageRepository.js index 9bb453069..52db905d4 100644 --- a/test/core/packageRepository.js +++ b/test/core/packageRepository.js @@ -13,7 +13,7 @@ var resolvers = require('../../lib/core/resolvers'); var copy = require('../../lib/util/copy'); var helpers = require('../helpers'); -describe('PackageRepository', function () { +describe('PackageRepository', function() { var packageRepository; var resolver; var resolverFactoryHook; @@ -26,12 +26,12 @@ describe('PackageRepository', function () { var forceCaching = true; - after(function () { + after(function() { rimraf.sync(registryCacheDir); rimraf.sync(packagesCacheDir); }); - beforeEach(function (next) { + beforeEach(function(next) { var PackageRepository; var config; var logger = new Logger(); @@ -60,7 +60,7 @@ describe('PackageRepository', function () { if (forceCaching) { // Force to use cache even for local resources - resolver.isCacheable = function () { + resolver.isCacheable = function() { return true; }; } @@ -69,12 +69,15 @@ describe('PackageRepository', function () { return Q.resolve(resolver); } - resolverFactory.getConstructor = function () { - return Q.resolve([resolvers.GitRemote, { - source: helpers.localSource(testPackage) - }]); + resolverFactory.getConstructor = function() { + return Q.resolve([ + resolvers.GitRemote, + { + source: helpers.localSource(testPackage) + } + ]); }; - resolverFactory.clearRuntimeCache = function () { + resolverFactory.clearRuntimeCache = function() { resolverFactoryClearHook(); }; @@ -84,398 +87,434 @@ describe('PackageRepository', function () { packageRepository = new PackageRepository(config, logger); // Reset hooks - resolverFactoryHook = resolverFactoryClearHook = function () {}; + resolverFactoryHook = resolverFactoryClearHook = function() {}; // Remove temp package rimraf.sync(tempPackage); // Clear the repository - packageRepository.clear() - .then(next.bind(next, null), next); + packageRepository.clear().then(next.bind(next, null), next); }); - describe('.constructor', function () { - it('should pass the config correctly to the registry client, including its cache folder', function () { - expect(packageRepository._registryClient._config.cache).to.equal(registryCacheDir); + describe('.constructor', function() { + it('should pass the config correctly to the registry client, including its cache folder', function() { + expect(packageRepository._registryClient._config.cache).to.equal( + registryCacheDir + ); }); }); - describe('.fetch', function () { - it('should call the resolver factory to get the appropriate resolver', function (next) { + describe('.fetch', function() { + it('should call the resolver factory to get the appropriate resolver', function(next) { var called; - resolverFactoryHook = function () { + resolverFactoryHook = function() { called = true; }; - packageRepository.fetch({ name: '', source: 'foo', target: '~0.1.0' }) - .spread(function (canonicalDir, pkgMeta) { - expect(called).to.be(true); - expect(fs.existsSync(canonicalDir)).to.be(true); - expect(pkgMeta).to.be.an('object'); - expect(pkgMeta.name).to.be('package-a'); - expect(pkgMeta.version).to.be('0.1.1'); - next(); - }) - .done(); + packageRepository + .fetch({ name: '', source: 'foo', target: '~0.1.0' }) + .spread(function(canonicalDir, pkgMeta) { + expect(called).to.be(true); + expect(fs.existsSync(canonicalDir)).to.be(true); + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta.name).to.be('package-a'); + expect(pkgMeta.version).to.be('0.1.1'); + next(); + }) + .done(); }); - it('should just call the resolver resolve method if force was specified', function (next) { + it('should just call the resolver resolve method if force was specified', function(next) { var called = []; - resolverFactoryHook = function (resolver) { + resolverFactoryHook = function(resolver) { var originalResolve = resolver.resolve; - resolver.resolve = function () { + resolver.resolve = function() { called.push('resolve'); return originalResolve.apply(this, arguments); }; - resolver.hasNew = function () { + resolver.hasNew = function() { called.push('hasNew'); return Q.resolve(false); }; }; - packageRepository._resolveCache.retrieve = function () { + packageRepository._resolveCache.retrieve = function() { called.push('retrieve'); return Q.resolve([]); }; packageRepository._config.force = true; - packageRepository.fetch({ name: '', source: 'foo', target: ' ~0.1.0' }) - .spread(function (canonicalDir, pkgMeta) { - expect(called).to.eql(['resolve']); - expect(fs.existsSync(canonicalDir)).to.be(true); - expect(pkgMeta).to.be.an('object'); - expect(pkgMeta.name).to.be('package-a'); - expect(pkgMeta.version).to.be('0.1.1'); - next(); - }) - .done(); + packageRepository + .fetch({ name: '', source: 'foo', target: ' ~0.1.0' }) + .spread(function(canonicalDir, pkgMeta) { + expect(called).to.eql(['resolve']); + expect(fs.existsSync(canonicalDir)).to.be(true); + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta.name).to.be('package-a'); + expect(pkgMeta.version).to.be('0.1.1'); + next(); + }) + .done(); }); - it('should attempt to retrieve a resolved package from the resolve package', function (next) { + it('should attempt to retrieve a resolved package from the resolve package', function(next) { var called = false; var originalRetrieve = packageRepository._resolveCache.retrieve; - packageRepository._resolveCache.retrieve = function (source) { + packageRepository._resolveCache.retrieve = function(source) { called = true; expect(source).to.be(mockSource); return originalRetrieve.apply(this, arguments); }; - packageRepository.fetch({ name: '', source: 'foo', target: '~0.1.0' }) - .spread(function (canonicalDir, pkgMeta) { - expect(called).to.be(true); - expect(fs.existsSync(canonicalDir)).to.be(true); - expect(pkgMeta).to.be.an('object'); - expect(pkgMeta.name).to.be('package-a'); - expect(pkgMeta.version).to.be('0.1.1'); - next(); - }) - .done(); + packageRepository + .fetch({ name: '', source: 'foo', target: '~0.1.0' }) + .spread(function(canonicalDir, pkgMeta) { + expect(called).to.be(true); + expect(fs.existsSync(canonicalDir)).to.be(true); + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta.name).to.be('package-a'); + expect(pkgMeta.version).to.be('0.1.1'); + next(); + }) + .done(); }); - it('should avoid using cache for local resources', function (next) { + it('should avoid using cache for local resources', function(next) { forceCaching = false; var called = false; var originalRetrieve = packageRepository._resolveCache.retrieve; - packageRepository._resolveCache.retrieve = function (source) { + packageRepository._resolveCache.retrieve = function(source) { called = true; expect(source).to.be(mockSource); return originalRetrieve.apply(this, arguments); }; - packageRepository.fetch({ name: '', source: helpers.localSource(testPackage), target: '~0.1.0' }) - .spread(function (canonicalDir, pkgMeta) { - expect(called).to.be(false); - expect(fs.existsSync(canonicalDir)).to.be(true); - expect(pkgMeta).to.be.an('object'); - expect(pkgMeta.name).to.be('package-a'); - expect(pkgMeta.version).to.be('0.1.1'); - forceCaching = true; - next(); - }) - .done(); + packageRepository + .fetch({ + name: '', + source: helpers.localSource(testPackage), + target: '~0.1.0' + }) + .spread(function(canonicalDir, pkgMeta) { + expect(called).to.be(false); + expect(fs.existsSync(canonicalDir)).to.be(true); + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta.name).to.be('package-a'); + expect(pkgMeta.version).to.be('0.1.1'); + forceCaching = true; + next(); + }) + .done(); }); - it('should just call the resolver resolve method if no appropriate package was found in the resolve cache', function (next) { + it('should just call the resolver resolve method if no appropriate package was found in the resolve cache', function(next) { var called = []; - resolverFactoryHook = function (resolver) { + resolverFactoryHook = function(resolver) { var originalResolve = resolver.resolve; - resolver.resolve = function () { + resolver.resolve = function() { called.push('resolve'); return originalResolve.apply(this, arguments); }; - resolver.hasNew = function () { + resolver.hasNew = function() { called.push('hasNew'); }; }; - packageRepository._resolveCache.retrieve = function () { + packageRepository._resolveCache.retrieve = function() { return Q.resolve([]); }; - packageRepository.fetch({ name: '', source: 'foo', target: ' ~0.1.0' }) - .spread(function (canonicalDir, pkgMeta) { - expect(called).to.eql(['resolve']); - expect(fs.existsSync(canonicalDir)).to.be(true); - expect(pkgMeta).to.be.an('object'); - expect(pkgMeta.name).to.be('package-a'); - expect(pkgMeta.version).to.be('0.1.1'); - next(); - }) - .done(); + packageRepository + .fetch({ name: '', source: 'foo', target: ' ~0.1.0' }) + .spread(function(canonicalDir, pkgMeta) { + expect(called).to.eql(['resolve']); + expect(fs.existsSync(canonicalDir)).to.be(true); + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta.name).to.be('package-a'); + expect(pkgMeta.version).to.be('0.1.1'); + next(); + }) + .done(); }); - it('should call the resolver hasNew method if an appropriate package was found in the resolve cache', function (next) { + it('should call the resolver hasNew method if an appropriate package was found in the resolve cache', function(next) { var json = { name: 'a', version: '0.2.1' }; var called; - resolverFactoryHook = function (resolver) { + resolverFactoryHook = function(resolver) { var originalHasNew = resolver.hasNew; - resolver.hasNew = function (pkgMeta) { + resolver.hasNew = function(pkgMeta) { expect(pkgMeta).to.eql(json); called = true; return originalHasNew.apply(this, arguments); }; }; - packageRepository._resolveCache.retrieve = function () { + packageRepository._resolveCache.retrieve = function() { return Q.resolve([tempPackage, json]); }; - copy.copyDir(testPackage, tempPackage, { ignore: ['.git'] }) - .then(function () { - fs.writeFileSync(path.join(tempPackage, '.bower.json'), JSON.stringify(json)); - - return packageRepository.fetch({ name: '', source: 'foo', target: '~0.1.0' }) - .spread(function (canonicalDir, pkgMeta) { - expect(called).to.be(true); - expect(fs.existsSync(canonicalDir)).to.be(true); - expect(pkgMeta).to.be.an('object'); - expect(pkgMeta.name).to.be('package-a'); - expect(pkgMeta.version).to.be('0.1.1'); - next(); - }); - }) - .done(); + copy + .copyDir(testPackage, tempPackage, { ignore: ['.git'] }) + .then(function() { + fs.writeFileSync( + path.join(tempPackage, '.bower.json'), + JSON.stringify(json) + ); + + return packageRepository + .fetch({ name: '', source: 'foo', target: '~0.1.0' }) + .spread(function(canonicalDir, pkgMeta) { + expect(called).to.be(true); + expect(fs.existsSync(canonicalDir)).to.be(true); + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta.name).to.be('package-a'); + expect(pkgMeta.version).to.be('0.1.1'); + next(); + }); + }) + .done(); }); - it('should call the resolver resolve method if hasNew resolved to true', function (next) { + it('should call the resolver resolve method if hasNew resolved to true', function(next) { var json = { name: 'a', version: '0.2.0' }; var called = []; - resolverFactoryHook = function (resolver) { + resolverFactoryHook = function(resolver) { var originalResolve = resolver.resolve; - resolver.resolve = function () { + resolver.resolve = function() { called.push('resolve'); return originalResolve.apply(this, arguments); }; - resolver.hasNew = function (pkgMeta) { + resolver.hasNew = function(pkgMeta) { expect(pkgMeta).to.eql(json); called.push('hasNew'); return Q.resolve(true); }; }; - packageRepository._resolveCache.retrieve = function () { + packageRepository._resolveCache.retrieve = function() { return Q.resolve([tempPackage, json]); }; - copy.copyDir(testPackage, tempPackage, { ignore: ['.git'] }) - .then(function () { - fs.writeFileSync(path.join(tempPackage, '.bower.json'), JSON.stringify(json)); - - return packageRepository.fetch({ name: '', source: 'foo', target: '~0.2.0' }) - .spread(function (canonicalDir, pkgMeta) { - expect(called).to.eql(['hasNew', 'resolve']); - expect(fs.existsSync(canonicalDir)).to.be(true); - expect(pkgMeta).to.be.an('object'); - expect(pkgMeta.name).to.be('a'); - expect(pkgMeta.version).to.be('0.2.2'); - next(); - }); - }) - .done(); + copy + .copyDir(testPackage, tempPackage, { ignore: ['.git'] }) + .then(function() { + fs.writeFileSync( + path.join(tempPackage, '.bower.json'), + JSON.stringify(json) + ); + + return packageRepository + .fetch({ name: '', source: 'foo', target: '~0.2.0' }) + .spread(function(canonicalDir, pkgMeta) { + expect(called).to.eql(['hasNew', 'resolve']); + expect(fs.existsSync(canonicalDir)).to.be(true); + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta.name).to.be('a'); + expect(pkgMeta.version).to.be('0.2.2'); + next(); + }); + }) + .done(); }); - it('should resolve to the cached package if hasNew resolve to false', function (next) { + it('should resolve to the cached package if hasNew resolve to false', function(next) { var json = { name: 'a', version: '0.2.0' }; var called = []; - resolverFactoryHook = function (resolver) { + resolverFactoryHook = function(resolver) { var originalResolve = resolver.resolve; - resolver.resolve = function () { + resolver.resolve = function() { called.push('resolve'); return originalResolve.apply(this, arguments); }; - resolver.hasNew = function (pkgMeta) { + resolver.hasNew = function(pkgMeta) { expect(pkgMeta).to.eql(json); called.push('hasNew'); return Q.resolve(false); }; }; - packageRepository._resolveCache.retrieve = function () { + packageRepository._resolveCache.retrieve = function() { return Q.resolve([tempPackage, json]); }; - copy.copyDir(testPackage, tempPackage, { ignore: ['.git'] }) - .then(function () { - fs.writeFileSync(path.join(tempPackage, '.bower.json'), JSON.stringify(json)); - - return packageRepository.fetch({ name: '', source: 'foo', target: '~0.2.0' }) - .spread(function (canonicalDir, pkgMeta) { - expect(called).to.eql(['hasNew']); - expect(canonicalDir).to.equal(tempPackage); - expect(pkgMeta).to.eql(json); - next(); - }); - }) - .done(); + copy + .copyDir(testPackage, tempPackage, { ignore: ['.git'] }) + .then(function() { + fs.writeFileSync( + path.join(tempPackage, '.bower.json'), + JSON.stringify(json) + ); + + return packageRepository + .fetch({ name: '', source: 'foo', target: '~0.2.0' }) + .spread(function(canonicalDir, pkgMeta) { + expect(called).to.eql(['hasNew']); + expect(canonicalDir).to.equal(tempPackage); + expect(pkgMeta).to.eql(json); + next(); + }); + }) + .done(); }); - it('should just use the cached package if offline was specified', function (next) { + it('should just use the cached package if offline was specified', function(next) { var json = { name: 'a', version: '0.2.0' }; var called = []; - resolverFactoryHook = function (resolver) { + resolverFactoryHook = function(resolver) { var originalResolve = resolver.resolve; - resolver.hasNew = function (pkgMeta) { + resolver.hasNew = function(pkgMeta) { expect(pkgMeta).to.eql(json); called.push('resolve'); return originalResolve.apply(this, arguments); }; - resolver.hasNew = function () { + resolver.hasNew = function() { called.push('hasNew'); return Q.resolve(false); }; }; - packageRepository._resolveCache.retrieve = function () { + packageRepository._resolveCache.retrieve = function() { return Q.resolve([tempPackage, json]); }; - copy.copyDir(testPackage, tempPackage, { ignore: ['.git'] }) - .then(function () { - fs.writeFileSync(path.join(tempPackage, '.bower.json'), JSON.stringify(json)); - - packageRepository._config.offline = true; - return packageRepository.fetch({ name: '', source: 'foo', target: '~0.2.0' }) - .spread(function (canonicalDir, pkgMeta) { - expect(called.length).to.be(0); - expect(canonicalDir).to.equal(tempPackage); - expect(pkgMeta).to.eql(json); - next(); - }); - }) - .done(); + copy + .copyDir(testPackage, tempPackage, { ignore: ['.git'] }) + .then(function() { + fs.writeFileSync( + path.join(tempPackage, '.bower.json'), + JSON.stringify(json) + ); + + packageRepository._config.offline = true; + return packageRepository + .fetch({ name: '', source: 'foo', target: '~0.2.0' }) + .spread(function(canonicalDir, pkgMeta) { + expect(called.length).to.be(0); + expect(canonicalDir).to.equal(tempPackage); + expect(pkgMeta).to.eql(json); + next(); + }); + }) + .done(); }); - it('should error out if there is no appropriate package in the resolve cache and offline was specified', function (next) { + it('should error out if there is no appropriate package in the resolve cache and offline was specified', function(next) { packageRepository._config.offline = true; - packageRepository.fetch({ name: '', source: 'foo', target: '~0.2.0' }) - .then(function () { - throw new Error('Should have failed'); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.equal('ENOCACHE'); - - next(); - }) - .done(); + packageRepository + .fetch({ name: '', source: 'foo', target: '~0.2.0' }) + .then( + function() { + throw new Error('Should have failed'); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.equal('ENOCACHE'); + + next(); + } + ) + .done(); }); }); - describe('.versions', function () { - it('should call the versions method on the concrete resolver', function (next) { + describe('.versions', function() { + it('should call the versions method on the concrete resolver', function(next) { var called = []; var originalVersions = resolvers.GitRemote.versions; - resolvers.GitRemote.versions = function (source) { + resolvers.GitRemote.versions = function(source) { expect(source).to.equal(mockSource); called.push('resolver'); return Q.resolve([]); }; - packageRepository._resolveCache.versions = function () { + packageRepository._resolveCache.versions = function() { called.push('resolve-cache'); return Q.resolve([]); }; - packageRepository.versions('foo') - .then(function (versions) { - expect(called).to.eql(['resolver']); - expect(versions).to.be.an('array'); - expect(versions.length).to.be(0); + packageRepository + .versions('foo') + .then(function(versions) { + expect(called).to.eql(['resolver']); + expect(versions).to.be.an('array'); + expect(versions.length).to.be(0); - next(); - }) - .fin(function () { - resolvers.GitRemote.versions = originalVersions; - }) - .done(); + next(); + }) + .fin(function() { + resolvers.GitRemote.versions = originalVersions; + }) + .done(); }); - it('should call the versions method on the resolve cache if offline was specified', function (next) { + it('should call the versions method on the resolve cache if offline was specified', function(next) { var called = []; var originalVersions = resolvers.GitRemote.versions; - resolvers.GitRemote.versions = function () { + resolvers.GitRemote.versions = function() { called.push('resolver'); return Q.resolve([]); }; - packageRepository._resolveCache.versions = function (source) { + packageRepository._resolveCache.versions = function(source) { expect(source).to.equal(mockSource); called.push('resolve-cache'); return Q.resolve([]); }; packageRepository._config.offline = true; - packageRepository.versions('foo') - .then(function (versions) { - expect(called).to.eql(['resolve-cache']); - expect(versions).to.be.an('array'); - expect(versions.length).to.be(0); - - next(); - }) - .fin(function () { - resolvers.GitRemote.versions = originalVersions; - }) - .done(); + packageRepository + .versions('foo') + .then(function(versions) { + expect(called).to.eql(['resolve-cache']); + expect(versions).to.be.an('array'); + expect(versions.length).to.be(0); + + next(); + }) + .fin(function() { + resolvers.GitRemote.versions = originalVersions; + }) + .done(); }); }); - describe('.eliminate', function () { - it('should call the eliminate method from the resolve cache', function (next) { + describe('.eliminate', function() { + it('should call the eliminate method from the resolve cache', function(next) { var called; var json = { name: 'a', @@ -483,21 +522,22 @@ describe('PackageRepository', function () { _source: 'foo' }; - packageRepository._resolveCache.eliminate = function (pkgMeta) { + packageRepository._resolveCache.eliminate = function(pkgMeta) { expect(pkgMeta).to.eql(json); called = true; return Q.resolve(); }; - packageRepository.eliminate(json) - .then(function () { - expect(called).to.be(true); - next(); - }) - .done(); + packageRepository + .eliminate(json) + .then(function() { + expect(called).to.be(true); + next(); + }) + .done(); }); - it('should call the clearCache method with the name from the registry client', function (next) { + it('should call the clearCache method with the name from the registry client', function(next) { var called; var json = { name: 'a', @@ -505,80 +545,87 @@ describe('PackageRepository', function () { _source: 'foo' }; - packageRepository._registryClient.clearCache = function (name, callback) { + packageRepository._registryClient.clearCache = function( + name, + callback + ) { expect(name).to.eql(json.name); called = true; callback(); }; - packageRepository.eliminate(json) - .then(function () { - expect(called).to.be(true); - next(); - }) - .done(); + packageRepository + .eliminate(json) + .then(function() { + expect(called).to.be(true); + next(); + }) + .done(); }); }); - describe('.list', function () { - it('should proxy to the resolve cache list method', function (next) { + describe('.list', function() { + it('should proxy to the resolve cache list method', function(next) { var called; var originalList = packageRepository._resolveCache.list; - packageRepository._resolveCache.list = function () { + packageRepository._resolveCache.list = function() { called = true; return originalList.apply(this, arguments); }; - packageRepository.list() - .then(function (entries) { - expect(called).to.be(true); - expect(entries).to.be.an('array'); - next(); - }) - .done(); + packageRepository + .list() + .then(function(entries) { + expect(called).to.be(true); + expect(entries).to.be.an('array'); + next(); + }) + .done(); }); }); - describe('.clear', function () { - it('should call the clear method from the resolve cache', function (next) { + describe('.clear', function() { + it('should call the clear method from the resolve cache', function(next) { var called; - packageRepository._resolveCache.clear = function () { + packageRepository._resolveCache.clear = function() { called = true; return Q.resolve(); }; - packageRepository.clear() - .then(function () { - expect(called).to.be(true); - next(); - }) - .done(); + packageRepository + .clear() + .then(function() { + expect(called).to.be(true); + next(); + }) + .done(); }); - it('should call the clearCache method without name from the registry client', function (next) { + it('should call the clearCache method without name from the registry client', function(next) { var called; - packageRepository._registryClient.clearCache = function (callback) { + packageRepository._registryClient.clearCache = function(callback) { called = true; callback(); }; - packageRepository.clear() - .then(function () { - expect(called).to.be(true); - next(); - }) - .done(); + packageRepository + .clear() + .then(function() { + expect(called).to.be(true); + next(); + }) + .done(); }); }); - describe('.reset', function () { - it('should call the reset method from the resolve cache', function () { + describe('.reset', function() { + it('should call the reset method from the resolve cache', function() { var called; - packageRepository._resolveCache.reset = function () { + packageRepository._resolveCache.reset = function() { called = true; return packageRepository._resolveCache; }; @@ -587,10 +634,10 @@ describe('PackageRepository', function () { expect(called).to.be(true); }); - it('should call the resetCache method without name from the registry client', function () { + it('should call the resetCache method without name from the registry client', function() { var called; - packageRepository._registryClient.resetCache = function () { + packageRepository._registryClient.resetCache = function() { called = true; return packageRepository._registryClient; }; @@ -600,26 +647,28 @@ describe('PackageRepository', function () { }); }); - describe('.getRegistryClient', function () { - it('should return the underlying registry client', function () { - expect(packageRepository.getRegistryClient()).to.be.an(RegistryClient); + describe('.getRegistryClient', function() { + it('should return the underlying registry client', function() { + expect(packageRepository.getRegistryClient()).to.be.an( + RegistryClient + ); }); }); - describe('.getResolveCache', function () { - it('should return the underlying resolve cache', function () { + describe('.getResolveCache', function() { + it('should return the underlying resolve cache', function() { expect(packageRepository.getResolveCache()).to.be.an(ResolveCache); }); }); - describe('#clearRuntimeCache', function () { - it('should clear the resolve cache runtime cache', function () { + describe('#clearRuntimeCache', function() { + it('should clear the resolve cache runtime cache', function() { var called; var originalClearRuntimeCache = ResolveCache.clearRuntimeCache; // No need to restore the original method since the constructor // gets re-assigned every time in beforeEach - ResolveCache.clearRuntimeCache = function () { + ResolveCache.clearRuntimeCache = function() { called = true; return originalClearRuntimeCache.apply(ResolveCache, arguments); }; @@ -628,10 +677,10 @@ describe('PackageRepository', function () { expect(called).to.be(true); }); - it('should clear the resolver factory runtime cache', function () { + it('should clear the resolver factory runtime cache', function() { var called; - resolverFactoryClearHook = function () { + resolverFactoryClearHook = function() { called = true; }; @@ -639,15 +688,18 @@ describe('PackageRepository', function () { expect(called).to.be(true); }); - it('should clear the registry runtime cache', function () { + it('should clear the registry runtime cache', function() { var called; var originalClearRuntimeCache = RegistryClient.clearRuntimeCache; // No need to restore the original method since the constructor // gets re-assigned every time in beforeEach - RegistryClient.clearRuntimeCache = function () { + RegistryClient.clearRuntimeCache = function() { called = true; - return originalClearRuntimeCache.apply(RegistryClient, arguments); + return originalClearRuntimeCache.apply( + RegistryClient, + arguments + ); }; packageRepository.constructor.clearRuntimeCache(); diff --git a/test/core/resolveCache.js b/test/core/resolveCache.js index 80da557c7..f933ba9b5 100644 --- a/test/core/resolveCache.js +++ b/test/core/resolveCache.js @@ -11,283 +11,332 @@ var defaultConfig = require('../../lib/config'); var cmd = require('../../lib/util/cmd'); var copy = require('../../lib/util/copy'); -describe('ResolveCache', function () { +describe('ResolveCache', function() { var resolveCache; var testPackage = path.resolve(__dirname, '../assets/package-a'); var tempPackage = path.resolve(__dirname, '../tmp/temp-package'); var tempPackage2 = path.resolve(__dirname, '../tmp/temp2-package'); var cacheDir = path.join(__dirname, '../tmp/temp-resolve-cache'); - before(function (next) { + before(function(next) { // Delete cache folder rimraf.sync(cacheDir); // Instantiate resolver cache - resolveCache = new ResolveCache(defaultConfig({ - storage: { - packages: cacheDir - } - })); + resolveCache = new ResolveCache( + defaultConfig({ + storage: { + packages: cacheDir + } + }) + ); // Checkout test package version 0.2.0 - cmd('git', ['checkout', '0.2.0'], { cwd: testPackage }) - .then(next.bind(next, null), next); + cmd('git', ['checkout', '0.2.0'], { cwd: testPackage }).then( + next.bind(next, null), + next + ); }); - beforeEach(function () { + beforeEach(function() { // Reset in memory cache for each test resolveCache.reset(); }); - after(function () { + after(function() { // Remove cache folder afterwards rimraf.sync(cacheDir); }); - describe('.constructor', function () { - beforeEach(function () { + describe('.constructor', function() { + beforeEach(function() { // Delete temp folder rimraf.sync(tempPackage); }); - after(function () { + after(function() { // Delete temp folder rimraf.sync(tempPackage); }); function initialize(cacheDir) { - return new ResolveCache(defaultConfig({ - storage: { - packages: cacheDir - } - })); + return new ResolveCache( + defaultConfig({ + storage: { + packages: cacheDir + } + }) + ); } - it('should create the cache folder if it doesn\'t exists', function () { + it("should create the cache folder if it doesn't exists", function() { initialize(tempPackage); expect(fs.existsSync(tempPackage)).to.be(true); }); - it('should not error out if the cache folder already exists', function () { + it('should not error out if the cache folder already exists', function() { mkdirp.sync(tempPackage); initialize(tempPackage); }); }); - describe('.store', function () { + describe('.store', function() { var oldFsRename = fs.rename; - beforeEach(function (next) { + beforeEach(function(next) { // Restore oldFsRename fs.rename = oldFsRename; // Create a fresh copy of the test package into temp rimraf.sync(tempPackage); - copy.copyDir(testPackage, tempPackage, { ignore: ['.git'] }) - .then(next.bind(next, null), next); + copy + .copyDir(testPackage, tempPackage, { ignore: ['.git'] }) + .then(next.bind(next, null), next); }); - it('should move the canonical dir to source-md5/version/ folder if package meta has a version', function (next) { - resolveCache.store(tempPackage, { - name: 'foo', - version: '1.0.0', - _source: 'foo', - _target: '*' - }) - .then(function (dir) { - expect(dir).to.equal(path.join(cacheDir, md5('foo'), '1.0.0')); - expect(fs.existsSync(dir)).to.be(true); - expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); - expect(fs.existsSync(tempPackage)).to.be(false); + it('should move the canonical dir to source-md5/version/ folder if package meta has a version', function(next) { + resolveCache + .store(tempPackage, { + name: 'foo', + version: '1.0.0', + _source: 'foo', + _target: '*' + }) + .then(function(dir) { + expect(dir).to.equal( + path.join(cacheDir, md5('foo'), '1.0.0') + ); + expect(fs.existsSync(dir)).to.be(true); + expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); + expect(fs.existsSync(tempPackage)).to.be(false); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should move the canonical dir to source-md5/target/ folder if package meta has no version', function (next) { - resolveCache.store(tempPackage, { - name: 'foo', - _source: 'foo', - _target: 'some-branch' - }) - .then(function (dir) { - expect(dir).to.equal(path.join(cacheDir, md5('foo'), 'some-branch')); - expect(fs.existsSync(dir)).to.be(true); - expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); - expect(fs.existsSync(tempPackage)).to.be(false); + it('should move the canonical dir to source-md5/target/ folder if package meta has no version', function(next) { + resolveCache + .store(tempPackage, { + name: 'foo', + _source: 'foo', + _target: 'some-branch' + }) + .then(function(dir) { + expect(dir).to.equal( + path.join(cacheDir, md5('foo'), 'some-branch') + ); + expect(fs.existsSync(dir)).to.be(true); + expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); + expect(fs.existsSync(tempPackage)).to.be(false); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should move the canonical dir to source-md5/_wildcard/ folder if package meta has no version and target is *', function (next) { - resolveCache.store(tempPackage, { - name: 'foo', - _source: 'foo', - _target: '*' - }) - .then(function (dir) { - expect(dir).to.equal(path.join(cacheDir, md5('foo'), '_wildcard')); - expect(fs.existsSync(dir)).to.be(true); - expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); - expect(fs.existsSync(tempPackage)).to.be(false); + it('should move the canonical dir to source-md5/_wildcard/ folder if package meta has no version and target is *', function(next) { + resolveCache + .store(tempPackage, { + name: 'foo', + _source: 'foo', + _target: '*' + }) + .then(function(dir) { + expect(dir).to.equal( + path.join(cacheDir, md5('foo'), '_wildcard') + ); + expect(fs.existsSync(dir)).to.be(true); + expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); + expect(fs.existsSync(tempPackage)).to.be(false); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should read the package meta if not present', function (next) { + it('should read the package meta if not present', function(next) { var pkgMeta = path.join(tempPackage, '.bower.json'); // Copy bower.json to .bower.json and add some props - copy.copyFile(path.join(tempPackage, 'component.json'), pkgMeta) - .then(function () { - return Q.nfcall(fs.readFile, pkgMeta) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - - json._target = '~0.2.0'; - json._source = 'git://github.com/bower/test-package.git'; - - return Q.nfcall(fs.writeFile, pkgMeta, JSON.stringify(json, null, ' ')); - }); - }) - // Store as usual - .then(function () { - return resolveCache.store(tempPackage); - }) - .then(function (dir) { - expect(dir).to.equal(path.join(cacheDir, md5('git://github.com/bower/test-package.git'), '0.2.0')); - expect(fs.existsSync(dir)).to.be(true); - expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); - expect(fs.existsSync(tempPackage)).to.be(false); + copy + .copyFile(path.join(tempPackage, 'component.json'), pkgMeta) + .then(function() { + return Q.nfcall(fs.readFile, pkgMeta).then(function( + contents + ) { + var json = JSON.parse(contents.toString()); + + json._target = '~0.2.0'; + json._source = + 'git://github.com/bower/test-package.git'; + + return Q.nfcall( + fs.writeFile, + pkgMeta, + JSON.stringify(json, null, ' ') + ); + }); + }) + // Store as usual + .then(function() { + return resolveCache.store(tempPackage); + }) + .then(function(dir) { + expect(dir).to.equal( + path.join( + cacheDir, + md5('git://github.com/bower/test-package.git'), + '0.2.0' + ) + ); + expect(fs.existsSync(dir)).to.be(true); + expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); + expect(fs.existsSync(tempPackage)).to.be(false); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should error out when reading the package meta if the file does not exist', function (next) { - resolveCache.store(tempPackage) - .then(function () { - next(new Error('Should have failed')); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.equal('ENOENT'); - expect(err.message).to.contain(path.join(tempPackage, '.bower.json')); - - next(); - }) - .done(); + it('should error out when reading the package meta if the file does not exist', function(next) { + resolveCache + .store(tempPackage) + .then( + function() { + next(new Error('Should have failed')); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.equal('ENOENT'); + expect(err.message).to.contain( + path.join(tempPackage, '.bower.json') + ); + + next(); + } + ) + .done(); }); - it('should error out when reading an invalid package meta', function (next) { + it('should error out when reading an invalid package meta', function(next) { var pkgMeta = path.join(tempPackage, '.bower.json'); return Q.nfcall(fs.writeFile, pkgMeta, 'w00t') - .then(function () { - return resolveCache.store(tempPackage) - .then(function () { - next(new Error('Should have failed')); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.equal('EMALFORMED'); - expect(err.message).to.contain(path.join(tempPackage, '.bower.json')); - - next(); - }); - }) - .done(); + .then(function() { + return resolveCache.store(tempPackage).then( + function() { + next(new Error('Should have failed')); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.equal('EMALFORMED'); + expect(err.message).to.contain( + path.join(tempPackage, '.bower.json') + ); + + next(); + } + ); + }) + .done(); }); - it('should move the canonical dir, even if it is in a different drive', function (next) { + it('should move the canonical dir, even if it is in a different drive', function(next) { var hittedMock = false; - fs.rename = function (src, dest, cb) { + fs.rename = function(src, dest, cb) { hittedMock = true; - setTimeout(function () { + setTimeout(function() { var err = new Error(); err.code = 'EXDEV'; cb(err); }, 10); }; - resolveCache.store(tempPackage, { - name: 'foo', - _source: 'foobar', - _target: 'some-branch' - }) - .then(function (dir) { - // Ensure mock was called - expect(hittedMock).to.be(true); + resolveCache + .store(tempPackage, { + name: 'foo', + _source: 'foobar', + _target: 'some-branch' + }) + .then(function(dir) { + // Ensure mock was called + expect(hittedMock).to.be(true); - expect(dir).to.equal(path.join(cacheDir, md5('foobar'), 'some-branch')); - expect(fs.existsSync(dir)).to.be(true); - expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); - expect(fs.existsSync(tempPackage)).to.be(false); + expect(dir).to.equal( + path.join(cacheDir, md5('foobar'), 'some-branch') + ); + expect(fs.existsSync(dir)).to.be(true); + expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); + expect(fs.existsSync(tempPackage)).to.be(false); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should update the in-memory cache', function (next) { + it('should update the in-memory cache', function(next) { // Feed the cache - resolveCache.versions('test-in-memory') - // Copy temp package to temp package 2 - .then(function () { - return copy.copyDir(tempPackage, tempPackage2, { ignore: ['.git'] }); - }) - // Store the two packages - .then(function () { - return resolveCache.store(tempPackage, { - name: 'foo', - version: '1.0.0', - _source: 'test-in-memory', - _target: '*' - }); - }) - .then(function () { - return resolveCache.store(tempPackage2, { - name: 'foo', - version: '1.0.1', - _source: 'test-in-memory', - _target: '*' - }); - }) - // Cache should have been updated - .then(function () { - return resolveCache.versions('test-in-memory') - .then(function (versions) { - expect(versions).to.eql(['1.0.1', '1.0.0']); - - next(); - }); - }) - .done(); + resolveCache + .versions('test-in-memory') + // Copy temp package to temp package 2 + .then(function() { + return copy.copyDir(tempPackage, tempPackage2, { + ignore: ['.git'] + }); + }) + // Store the two packages + .then(function() { + return resolveCache.store(tempPackage, { + name: 'foo', + version: '1.0.0', + _source: 'test-in-memory', + _target: '*' + }); + }) + .then(function() { + return resolveCache.store(tempPackage2, { + name: 'foo', + version: '1.0.1', + _source: 'test-in-memory', + _target: '*' + }); + }) + // Cache should have been updated + .then(function() { + return resolveCache + .versions('test-in-memory') + .then(function(versions) { + expect(versions).to.eql(['1.0.1', '1.0.0']); + + next(); + }); + }) + .done(); }); - it('should url encode target when storing to the fs', function (next) { - resolveCache.store(tempPackage, { - name: 'foo', - _source: 'foo', - _target: 'foo/bar' - }) - .then(function (dir) { - expect(dir).to.equal(path.join(cacheDir, md5('foo'), 'foo%2Fbar')); - expect(fs.existsSync(dir)).to.be(true); - expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); - expect(fs.existsSync(tempPackage)).to.be(false); + it('should url encode target when storing to the fs', function(next) { + resolveCache + .store(tempPackage, { + name: 'foo', + _source: 'foo', + _target: 'foo/bar' + }) + .then(function(dir) { + expect(dir).to.equal( + path.join(cacheDir, md5('foo'), 'foo%2Fbar') + ); + expect(fs.existsSync(dir)).to.be(true); + expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); + expect(fs.existsSync(tempPackage)).to.be(false); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should be possible to store two package at same time', function (next) { + it('should be possible to store two package at same time', function(next) { var store = resolveCache.store.bind(resolveCache, tempPackage, { name: 'foo', _source: 'foo', @@ -299,30 +348,35 @@ describe('ResolveCache', function () { _target: 'foo/bar' }); - Q.all([store(), store2()]).then(function (dirs) { - var dir = dirs[0]; - expect(dir).to.equal(path.join(cacheDir, md5('foo'), 'foo%2Fbar')); - expect(fs.existsSync(dir)).to.be(true); - expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); - expect(fs.existsSync(tempPackage)).to.be(false); - expect(fs.existsSync(tempPackage2)).to.be(false); + Q.all([store(), store2()]) + .then(function(dirs) { + var dir = dirs[0]; + expect(dir).to.equal( + path.join(cacheDir, md5('foo'), 'foo%2Fbar') + ); + expect(fs.existsSync(dir)).to.be(true); + expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); + expect(fs.existsSync(tempPackage)).to.be(false); + expect(fs.existsSync(tempPackage2)).to.be(false); - next(); - }).done(); + next(); + }) + .done(); }); }); - describe('.versions', function () { - it('should resolve to an array', function (next) { - resolveCache.versions(String(Math.random())) - .then(function (versions) { - expect(versions).to.be.an('array'); - next(); - }) - .done(); + describe('.versions', function() { + it('should resolve to an array', function(next) { + resolveCache + .versions(String(Math.random())) + .then(function(versions) { + expect(versions).to.be.an('array'); + next(); + }) + .done(); }); - it('should ignore non-semver folders of the source', function (next) { + it('should ignore non-semver folders of the source', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -333,17 +387,18 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir, '0.1.0')); fs.mkdirSync(path.join(sourceDir, 'foo')); - resolveCache.versions(source) - .then(function (versions) { - expect(versions).to.not.contain('foo'); - expect(versions).to.contain('0.0.1'); - expect(versions).to.contain('0.1.0'); - next(); - }) - .done(); + resolveCache + .versions(source) + .then(function(versions) { + expect(versions).to.not.contain('foo'); + expect(versions).to.contain('0.0.1'); + expect(versions).to.contain('0.1.0'); + next(); + }) + .done(); }); - it('should order the versions', function (next) { + it('should order the versions', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -354,15 +409,16 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir, '0.1.0')); fs.mkdirSync(path.join(sourceDir, '0.1.0-rc.1')); - resolveCache.versions(source) - .then(function (versions) { - expect(versions).to.eql(['0.1.0', '0.1.0-rc.1', '0.0.1']); - next(); - }) - .done(); + resolveCache + .versions(source) + .then(function(versions) { + expect(versions).to.eql(['0.1.0', '0.1.0-rc.1', '0.0.1']); + next(); + }) + .done(); }); - it('should cache versions to speed-up subsequent calls', function (next) { + it('should cache versions to speed-up subsequent calls', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -371,32 +427,34 @@ describe('ResolveCache', function () { fs.mkdirSync(sourceDir); fs.mkdirSync(path.join(sourceDir, '0.0.1')); - resolveCache.versions(source) - .then(function () { - // Remove folder - rimraf.sync(sourceDir); + resolveCache + .versions(source) + .then(function() { + // Remove folder + rimraf.sync(sourceDir); - return resolveCache.versions(source); - }) - .then(function (versions) { - expect(versions).to.eql(['0.0.1']); - next(); - }) - .done(); + return resolveCache.versions(source); + }) + .then(function(versions) { + expect(versions).to.eql(['0.0.1']); + next(); + }) + .done(); }); }); - describe('.retrieve', function () { - it('should resolve to empty if there are no packages for the requested source', function (next) { - resolveCache.retrieve(String(Math.random())) - .spread(function () { - expect(arguments.length).to.equal(0); - next(); - }) - .done(); + describe('.retrieve', function() { + it('should resolve to empty if there are no packages for the requested source', function(next) { + resolveCache + .retrieve(String(Math.random())) + .spread(function() { + expect(arguments.length).to.equal(0); + next(); + }) + .done(); }); - it('should resolve to empty if there are no suitable packages for the requested target', function (next) { + it('should resolve to empty if there are no suitable packages for the requested target', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -408,21 +466,22 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir, '0.1.9')); fs.mkdirSync(path.join(sourceDir, '0.2.0')); - resolveCache.retrieve(source, '~0.3.0') - .spread(function () { - expect(arguments.length).to.equal(0); + resolveCache + .retrieve(source, '~0.3.0') + .spread(function() { + expect(arguments.length).to.equal(0); - return resolveCache.retrieve(source, 'some-branch'); - }) - .spread(function () { - expect(arguments.length).to.equal(0); + return resolveCache.retrieve(source, 'some-branch'); + }) + .spread(function() { + expect(arguments.length).to.equal(0); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should remove invalid packages from the cache if their package meta is missing or invalid', function (next) { + it('should remove invalid packages from the cache if their package meta is missing or invalid', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -435,21 +494,25 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir, '0.2.0')); // Create an invalid package meta - fs.writeFileSync(path.join(sourceDir, '0.2.0', '.bower.json'), 'w00t'); - - resolveCache.retrieve(source, '~0.1.0') - .spread(function () { - var dirs = fs.readdirSync(sourceDir); - - expect(arguments.length).to.equal(0); - expect(dirs).to.contain('0.0.1'); - expect(dirs).to.contain('0.2.0'); - next(); - }) - .done(); + fs.writeFileSync( + path.join(sourceDir, '0.2.0', '.bower.json'), + 'w00t' + ); + + resolveCache + .retrieve(source, '~0.1.0') + .spread(function() { + var dirs = fs.readdirSync(sourceDir); + + expect(arguments.length).to.equal(0); + expect(dirs).to.contain('0.0.1'); + expect(dirs).to.contain('0.2.0'); + next(); + }) + .done(); }); - it('should resolve to the highest package that matches a range target, ignoring pre-releases', function (next) { + it('should resolve to the highest package that matches a range target, ignoring pre-releases', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -460,43 +523,63 @@ describe('ResolveCache', function () { json.version = '0.0.1'; fs.mkdirSync(path.join(sourceDir, '0.0.1')); - fs.writeFileSync(path.join(sourceDir, '0.0.1', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, '0.0.1', '.bower.json'), + JSON.stringify(json, null, ' ') + ); json.version = '0.1.0'; fs.mkdirSync(path.join(sourceDir, '0.1.0')); - fs.writeFileSync(path.join(sourceDir, '0.1.0', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, '0.1.0', '.bower.json'), + JSON.stringify(json, null, ' ') + ); json.version = '0.1.0-rc.1'; fs.mkdirSync(path.join(sourceDir, '0.1.0-rc.1')); - fs.writeFileSync(path.join(sourceDir, '0.1.0-rc.1', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, '0.1.0-rc.1', '.bower.json'), + JSON.stringify(json, null, ' ') + ); json.version = '0.1.9'; fs.mkdirSync(path.join(sourceDir, '0.1.9')); - fs.writeFileSync(path.join(sourceDir, '0.1.9', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, '0.1.9', '.bower.json'), + JSON.stringify(json, null, ' ') + ); json.version = '0.2.0'; fs.mkdirSync(path.join(sourceDir, '0.2.0')); - fs.writeFileSync(path.join(sourceDir, '0.2.0', '.bower.json'), JSON.stringify(json, null, ' ')); - - resolveCache.retrieve(source, '~0.1.0') - .spread(function (canonicalDir, pkgMeta) { - expect(pkgMeta).to.be.an('object'); - expect(pkgMeta.version).to.equal('0.1.9'); - expect(canonicalDir).to.equal(path.join(sourceDir, '0.1.9')); - - return resolveCache.retrieve(source, '*'); - }) - .spread(function (canonicalDir, pkgMeta) { - expect(pkgMeta).to.be.an('object'); - expect(pkgMeta.version).to.equal('0.2.0'); - expect(canonicalDir).to.equal(path.join(sourceDir, '0.2.0')); + fs.writeFileSync( + path.join(sourceDir, '0.2.0', '.bower.json'), + JSON.stringify(json, null, ' ') + ); + + resolveCache + .retrieve(source, '~0.1.0') + .spread(function(canonicalDir, pkgMeta) { + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta.version).to.equal('0.1.9'); + expect(canonicalDir).to.equal( + path.join(sourceDir, '0.1.9') + ); + + return resolveCache.retrieve(source, '*'); + }) + .spread(function(canonicalDir, pkgMeta) { + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta.version).to.equal('0.2.0'); + expect(canonicalDir).to.equal( + path.join(sourceDir, '0.2.0') + ); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should resolve to the highest package that matches a range target, not ignoring pre-releases if they are the only versions', function (next) { + it('should resolve to the highest package that matches a range target, not ignoring pre-releases if they are the only versions', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -507,24 +590,33 @@ describe('ResolveCache', function () { json.version = '0.1.0-rc.1'; fs.mkdirSync(path.join(sourceDir, '0.1.0-rc.1')); - fs.writeFileSync(path.join(sourceDir, '0.1.0-rc.1', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, '0.1.0-rc.1', '.bower.json'), + JSON.stringify(json, null, ' ') + ); json.version = '0.1.0-rc.2'; fs.mkdirSync(path.join(sourceDir, '0.1.0-rc.2')); - fs.writeFileSync(path.join(sourceDir, '0.1.0-rc.2', '.bower.json'), JSON.stringify(json, null, ' ')); - - resolveCache.retrieve(source, '~0.1.0') - .spread(function (canonicalDir, pkgMeta) { - expect(pkgMeta).to.be.an('object'); - expect(pkgMeta.version).to.equal('0.1.0-rc.2'); - expect(canonicalDir).to.equal(path.join(sourceDir, '0.1.0-rc.2')); + fs.writeFileSync( + path.join(sourceDir, '0.1.0-rc.2', '.bower.json'), + JSON.stringify(json, null, ' ') + ); + + resolveCache + .retrieve(source, '~0.1.0') + .spread(function(canonicalDir, pkgMeta) { + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta.version).to.equal('0.1.0-rc.2'); + expect(canonicalDir).to.equal( + path.join(sourceDir, '0.1.0-rc.2') + ); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should resolve to exact match (including build metadata) if available', function (next) { + it('should resolve to exact match (including build metadata) if available', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -536,35 +628,53 @@ describe('ResolveCache', function () { json.version = '0.1.0'; fs.mkdirSync(path.join(sourceDir, '0.1.0')); - fs.writeFileSync(path.join(sourceDir, '0.1.0', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, '0.1.0', '.bower.json'), + JSON.stringify(json, null, ' ') + ); json.version = '0.1.0+build.4'; encoded = encodeURIComponent('0.1.0+build.4'); fs.mkdirSync(path.join(sourceDir, encoded)); - fs.writeFileSync(path.join(sourceDir, encoded, '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, encoded, '.bower.json'), + JSON.stringify(json, null, ' ') + ); json.version = '0.1.0+build.5'; encoded = encodeURIComponent('0.1.0+build.5'); fs.mkdirSync(path.join(sourceDir, encoded)); - fs.writeFileSync(path.join(sourceDir, encoded, '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, encoded, '.bower.json'), + JSON.stringify(json, null, ' ') + ); json.version = '0.1.0+build.6'; encoded = encodeURIComponent('0.1.0+build.6'); fs.mkdirSync(path.join(sourceDir, encoded)); - fs.writeFileSync(path.join(sourceDir, encoded, '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, encoded, '.bower.json'), + JSON.stringify(json, null, ' ') + ); + + resolveCache + .retrieve(source, '0.1.0+build.5') + .spread(function(canonicalDir, pkgMeta) { + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta.version).to.equal('0.1.0+build.5'); + expect(canonicalDir).to.equal( + path.join( + sourceDir, + encodeURIComponent('0.1.0+build.5') + ) + ); - resolveCache.retrieve(source, '0.1.0+build.5') - .spread(function (canonicalDir, pkgMeta) { - expect(pkgMeta).to.be.an('object'); - expect(pkgMeta.version).to.equal('0.1.0+build.5'); - expect(canonicalDir).to.equal(path.join(sourceDir, encodeURIComponent('0.1.0+build.5'))); - - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should resolve to the _wildcard package if target is * and there are no semver versions', function (next) { + it('should resolve to the _wildcard package if target is * and there are no semver versions', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -574,19 +684,25 @@ describe('ResolveCache', function () { fs.mkdirSync(sourceDir); fs.mkdirSync(path.join(sourceDir, '_wildcard')); - fs.writeFileSync(path.join(sourceDir, '_wildcard', '.bower.json'), JSON.stringify(json, null, ' ')); - - resolveCache.retrieve(source, '*') - .spread(function (canonicalDir, pkgMeta) { - expect(pkgMeta).to.be.an('object'); - expect(canonicalDir).to.equal(path.join(sourceDir, '_wildcard')); + fs.writeFileSync( + path.join(sourceDir, '_wildcard', '.bower.json'), + JSON.stringify(json, null, ' ') + ); + + resolveCache + .retrieve(source, '*') + .spread(function(canonicalDir, pkgMeta) { + expect(pkgMeta).to.be.an('object'); + expect(canonicalDir).to.equal( + path.join(sourceDir, '_wildcard') + ); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should resolve to the exact target it\'s not a semver range', function (next) { + it("should resolve to the exact target it's not a semver range", function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -596,28 +712,35 @@ describe('ResolveCache', function () { fs.mkdirSync(sourceDir); fs.mkdirSync(path.join(sourceDir, 'some-branch')); - fs.writeFileSync(path.join(sourceDir, 'some-branch', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, 'some-branch', '.bower.json'), + JSON.stringify(json, null, ' ') + ); fs.mkdirSync(path.join(sourceDir, 'other-branch')); - fs.writeFileSync(path.join(sourceDir, 'other-branch', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, 'other-branch', '.bower.json'), + JSON.stringify(json, null, ' ') + ); - resolveCache.retrieve(source, 'some-branch') - .spread(function (canonicalDir, pkgMeta) { - expect(pkgMeta).to.be.an('object'); - expect(pkgMeta).to.not.have.property('version'); + resolveCache + .retrieve(source, 'some-branch') + .spread(function(canonicalDir, pkgMeta) { + expect(pkgMeta).to.be.an('object'); + expect(pkgMeta).to.not.have.property('version'); - next(); - }) - .done(); + next(); + }) + .done(); }); }); - describe('.eliminate', function () { - beforeEach(function () { + describe('.eliminate', function() { + beforeEach(function() { mkdirp.sync(cacheDir); }); - it('should delete the source-md5/version folder', function (next) { + it('should delete the source-md5/version folder', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -627,22 +750,27 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir, '0.0.1')); fs.mkdirSync(path.join(sourceDir, '0.1.0')); - resolveCache.eliminate({ - name: 'foo', - version: '0.0.1', - _source: source, - _target: '*' - }) - .then(function () { - expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be(false); - expect(fs.existsSync(path.join(sourceDir, '0.1.0'))).to.be(true); + resolveCache + .eliminate({ + name: 'foo', + version: '0.0.1', + _source: source, + _target: '*' + }) + .then(function() { + expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be( + false + ); + expect(fs.existsSync(path.join(sourceDir, '0.1.0'))).to.be( + true + ); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should delete the source-md5/target folder', function (next) { + it('should delete the source-md5/target folder', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -652,21 +780,26 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir, '0.0.1')); fs.mkdirSync(path.join(sourceDir, 'some-branch')); - resolveCache.eliminate({ - name: 'foo', - _source: source, - _target: 'some-branch' - }) - .then(function () { - expect(fs.existsSync(path.join(sourceDir, 'some-branch'))).to.be(false); - expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be(true); + resolveCache + .eliminate({ + name: 'foo', + _source: source, + _target: 'some-branch' + }) + .then(function() { + expect( + fs.existsSync(path.join(sourceDir, 'some-branch')) + ).to.be(false); + expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be( + true + ); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should delete the source-md5/_wildcard folder', function (next) { + it('should delete the source-md5/_wildcard folder', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -676,21 +809,26 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir, '0.0.1')); fs.mkdirSync(path.join(sourceDir, '_wildcard')); - resolveCache.eliminate({ - name: 'foo', - _source: source, - _target: '*' - }) - .then(function () { - expect(fs.existsSync(path.join(sourceDir, '_wildcard'))).to.be(false); - expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be(true); + resolveCache + .eliminate({ + name: 'foo', + _source: source, + _target: '*' + }) + .then(function() { + expect( + fs.existsSync(path.join(sourceDir, '_wildcard')) + ).to.be(false); + expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be( + true + ); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should delete the source-md5 folder if empty', function (next) { + it('should delete the source-md5 folder if empty', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -699,22 +837,25 @@ describe('ResolveCache', function () { fs.mkdirSync(sourceDir); fs.mkdirSync(path.join(sourceDir, '0.0.1')); - resolveCache.eliminate({ - name: 'foo', - version: '0.0.1', - _source: source, - _target: '*' - }) - .then(function () { - expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be(false); - expect(fs.existsSync(path.join(sourceDir))).to.be(false); + resolveCache + .eliminate({ + name: 'foo', + version: '0.0.1', + _source: source, + _target: '*' + }) + .then(function() { + expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be( + false + ); + expect(fs.existsSync(path.join(sourceDir))).to.be(false); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should remove entry from in memory cache if the source-md5 folder was deleted', function (next) { + it('should remove entry from in memory cache if the source-md5 folder was deleted', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -724,54 +865,55 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir, '0.0.1')); // Feed up the cache - resolveCache.versions(source) - // Eliminate - .then(function () { - return resolveCache.eliminate({ - name: 'foo', - version: '0.0.1', - _source: source, - _target: '*' - }); - }) - .then(function () { - // At this point the parent folder should be deleted - // To test against the in-memory cache, we create a folder - // manually and request the versions - mkdirp.sync(path.join(sourceDir, '0.0.2')); - - resolveCache.versions(source) - .then(function (versions) { - expect(versions).to.eql(['0.0.2']); + resolveCache + .versions(source) + // Eliminate + .then(function() { + return resolveCache.eliminate({ + name: 'foo', + version: '0.0.1', + _source: source, + _target: '*' + }); + }) + .then(function() { + // At this point the parent folder should be deleted + // To test against the in-memory cache, we create a folder + // manually and request the versions + mkdirp.sync(path.join(sourceDir, '0.0.2')); - next(); - }); - }) - .done(); + resolveCache.versions(source).then(function(versions) { + expect(versions).to.eql(['0.0.2']); + + next(); + }); + }) + .done(); }); }); - describe('.clear', function () { - beforeEach(function () { + describe('.clear', function() { + beforeEach(function() { mkdirp.sync(cacheDir); }); - it('should empty the whole cache folder', function (next) { - resolveCache.clear() - .then(function () { - var files; + it('should empty the whole cache folder', function(next) { + resolveCache + .clear() + .then(function() { + var files; - expect(fs.existsSync(cacheDir)).to.be(true); + expect(fs.existsSync(cacheDir)).to.be(true); - files = fs.readdirSync(cacheDir); - expect(files.length).to.be(0); + files = fs.readdirSync(cacheDir); + expect(files.length).to.be(0); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should erase the in-memory cache', function (next) { + it('should erase the in-memory cache', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -781,29 +923,29 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir, '0.0.1')); // Feed the in-memory cache - resolveCache.versions(source) - // Clear - .then(function () { - return resolveCache.clear(); - }) - .then(function () { - // To test against the in-memory cache, we create a folder - // manually and request the versions - mkdirp.sync(path.join(sourceDir, '0.0.2')); + resolveCache + .versions(source) + // Clear + .then(function() { + return resolveCache.clear(); + }) + .then(function() { + // To test against the in-memory cache, we create a folder + // manually and request the versions + mkdirp.sync(path.join(sourceDir, '0.0.2')); - resolveCache.versions(source) - .then(function (versions) { - expect(versions).to.eql(['0.0.2']); + resolveCache.versions(source).then(function(versions) { + expect(versions).to.eql(['0.0.2']); - next(); - }); - }) - .done(); + next(); + }); + }) + .done(); }); }); - describe('.reset', function () { - it('should erase the in-memory cache', function (next) { + describe('.reset', function() { + it('should erase the in-memory cache', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -813,45 +955,47 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir, '0.0.1')); // Feed the in-memory cache - resolveCache.versions(source) - .then(function () { - // Delete 0.0.1 and create 0.0.2 - fs.rmdirSync(path.join(sourceDir, '0.0.1')); - fs.mkdirSync(path.join(sourceDir, '0.0.2')); - - // Reset cache - resolveCache.reset(); - - // Get versions - return resolveCache.versions(source); - }) - .then(function (versions) { - expect(versions).to.eql(['0.0.2']); + resolveCache + .versions(source) + .then(function() { + // Delete 0.0.1 and create 0.0.2 + fs.rmdirSync(path.join(sourceDir, '0.0.1')); + fs.mkdirSync(path.join(sourceDir, '0.0.2')); + + // Reset cache + resolveCache.reset(); + + // Get versions + return resolveCache.versions(source); + }) + .then(function(versions) { + expect(versions).to.eql(['0.0.2']); - next(); - }) - .done(); + next(); + }) + .done(); }); }); - describe('.list', function () { - beforeEach(function () { + describe('.list', function() { + beforeEach(function() { rimraf.sync(cacheDir); mkdirp.sync(cacheDir); }); - it('should resolve to an empty array if the cache is empty', function (next) { - resolveCache.list() - .then(function (entries) { - expect(entries).to.be.an('array'); - expect(entries.length).to.be(0); + it('should resolve to an empty array if the cache is empty', function(next) { + resolveCache + .list() + .then(function(entries) { + expect(entries).to.be.an('array'); + expect(entries.length).to.be(0); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should resolve to an ordered array of entries (name ASC, release ASC)', function (next) { + it('should resolve to an ordered array of entries (name ASC, release ASC)', function(next) { var source = 'list-package-1'; var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -868,62 +1012,94 @@ describe('ResolveCache', function () { fs.mkdirSync(sourceDir); fs.mkdirSync(path.join(sourceDir, '0.0.1')); json.version = '0.0.1'; - fs.writeFileSync(path.join(sourceDir, '0.0.1', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, '0.0.1', '.bower.json'), + JSON.stringify(json, null, ' ') + ); fs.mkdirSync(path.join(sourceDir, '0.1.0')); json.version = '0.1.0'; - fs.writeFileSync(path.join(sourceDir, '0.1.0', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, '0.1.0', '.bower.json'), + JSON.stringify(json, null, ' ') + ); delete json.version; fs.mkdirSync(path.join(sourceDir, 'foo')); json._target = 'foo'; - fs.writeFileSync(path.join(sourceDir, 'foo', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, 'foo', '.bower.json'), + JSON.stringify(json, null, ' ') + ); fs.mkdirSync(path.join(sourceDir, 'bar')); json._target = 'bar'; - fs.writeFileSync(path.join(sourceDir, 'bar', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, 'bar', '.bower.json'), + JSON.stringify(json, null, ' ') + ); fs.mkdirSync(path.join(sourceDir, 'aa')); json._target = 'aa'; - fs.writeFileSync(path.join(sourceDir, 'aa', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, 'aa', '.bower.json'), + JSON.stringify(json, null, ' ') + ); delete json._target; fs.mkdirSync(sourceDir2); fs.mkdirSync(path.join(sourceDir2, '0.2.1')); json.version = '0.2.1'; - fs.writeFileSync(path.join(sourceDir2, '0.2.1', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir2, '0.2.1', '.bower.json'), + JSON.stringify(json, null, ' ') + ); fs.mkdirSync(path.join(sourceDir2, '0.2.0')); json.name = 'abc'; json.version = '0.2.0'; - fs.writeFileSync(path.join(sourceDir2, '0.2.0', '.bower.json'), JSON.stringify(json, null, ' ')); - - resolveCache.list() - .then(function (entries) { - var expectedJson; - var bowerDir = path.join(__dirname, '../..'); - - expect(entries).to.be.an('array'); - - expectedJson = fs.readFileSync(path.join(__dirname, '../assets/resolve-cache/list-json-1.json')); + fs.writeFileSync( + path.join(sourceDir2, '0.2.0', '.bower.json'), + JSON.stringify(json, null, ' ') + ); + + resolveCache + .list() + .then(function(entries) { + var expectedJson; + var bowerDir = path.join(__dirname, '../..'); + + expect(entries).to.be.an('array'); + + expectedJson = fs.readFileSync( + path.join( + __dirname, + '../assets/resolve-cache/list-json-1.json' + ) + ); + + mout.object.forOwn(entries, function(entry) { + // Trim absolute bower path from json + entry.canonicalDir = entry.canonicalDir.substr( + bowerDir.length + ); + // Convert windows \ paths to / + entry.canonicalDir = entry.canonicalDir.replace( + /\\/g, + '/' + ); + }); + + expect(entries).to.eql(JSON.parse(expectedJson)); - mout.object.forOwn(entries, function (entry) { - // Trim absolute bower path from json - entry.canonicalDir = entry.canonicalDir.substr(bowerDir.length); - // Convert windows \ paths to / - entry.canonicalDir = entry.canonicalDir.replace(/\\/g, '/'); - }); - - expect(entries).to.eql(JSON.parse(expectedJson)); - - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should ignore lurking files where dirs are expected', function (next) { + it('should ignore lurking files where dirs are expected', function(next) { var source = 'list-package-1'; var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -935,7 +1111,10 @@ describe('ResolveCache', function () { fs.mkdirSync(sourceDir); fs.mkdirSync(path.join(sourceDir, '0.0.1')); json.version = '0.0.1'; - fs.writeFileSync(path.join(sourceDir, '0.0.1', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, '0.0.1', '.bower.json'), + JSON.stringify(json, null, ' ') + ); // Create lurking files fs.writeFileSync(path.join(cacheDir, 'foo'), 'w00t'); @@ -944,25 +1123,33 @@ describe('ResolveCache', function () { fs.writeFileSync(path.join(sourceDir, '.DS_Store'), ''); // It should not error out - resolveCache.list() - .then(function (entries) { - expect(entries).to.be.an('array'); - expect(entries.length).to.be(1); - expect(entries[0].pkgMeta).to.eql(json); - - // Lurking file should have been removed - expect(fs.existsSync(path.join(cacheDir, 'foo'))).to.be(false); - expect(fs.existsSync(path.join(cacheDir, '.DS_Store'))).to.be(false); - expect(fs.existsSync(path.join(sourceDir, 'foo'))).to.be(false); - expect(fs.existsSync(path.join(sourceDir, '.DS_Store'))).to.be(false); - - next(); - }) - .done(); + resolveCache + .list() + .then(function(entries) { + expect(entries).to.be.an('array'); + expect(entries.length).to.be(1); + expect(entries[0].pkgMeta).to.eql(json); + + // Lurking file should have been removed + expect(fs.existsSync(path.join(cacheDir, 'foo'))).to.be( + false + ); + expect( + fs.existsSync(path.join(cacheDir, '.DS_Store')) + ).to.be(false); + expect(fs.existsSync(path.join(sourceDir, 'foo'))).to.be( + false + ); + expect( + fs.existsSync(path.join(sourceDir, '.DS_Store')) + ).to.be(false); + next(); + }) + .done(); }); - it('should delete entries if failed to read package meta', function (next) { + it('should delete entries if failed to read package meta', function(next) { var source = 'list-package-1'; var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -975,32 +1162,43 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir, '0.0.1')); fs.mkdirSync(path.join(sourceDir, '0.0.2')); - fs.writeFileSync(path.join(sourceDir, '0.0.2', '.bower.json'), 'w00t'); + fs.writeFileSync( + path.join(sourceDir, '0.0.2', '.bower.json'), + 'w00t' + ); // Create valid version fs.mkdirSync(path.join(sourceDir, '0.0.3')); json.version = '0.0.3'; - fs.writeFileSync(path.join(sourceDir, '0.0.3', '.bower.json'), JSON.stringify(json, null, ' ')); + fs.writeFileSync( + path.join(sourceDir, '0.0.3', '.bower.json'), + JSON.stringify(json, null, ' ') + ); // It should not error out - resolveCache.list() - .then(function (entries) { - expect(entries).to.be.an('array'); - expect(entries.length).to.be(1); - expect(entries[0].pkgMeta).to.eql(json); - - // Packages with invalid metas should have been removed - expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be(false); - expect(fs.existsSync(path.join(sourceDir, '0.0.2'))).to.be(false); + resolveCache + .list() + .then(function(entries) { + expect(entries).to.be.an('array'); + expect(entries.length).to.be(1); + expect(entries[0].pkgMeta).to.eql(json); + + // Packages with invalid metas should have been removed + expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be( + false + ); + expect(fs.existsSync(path.join(sourceDir, '0.0.2'))).to.be( + false + ); - next(); - }) - .done(); + next(); + }) + .done(); }); }); - describe('#clearRuntimeCache', function () { - it('should clear the in-memory cache for all sources', function (next) { + describe('#clearRuntimeCache', function() { + it('should clear the in-memory cache for all sources', function(next) { var source = String(Math.random()); var sourceId = md5(source); var sourceDir = path.join(cacheDir, sourceId); @@ -1016,32 +1214,34 @@ describe('ResolveCache', function () { fs.mkdirSync(path.join(sourceDir2, '0.0.2')); // Feed the cache - resolveCache.versions(source) - .then(function () { - return resolveCache.versions(source2); - }) - .then(function () { - // Create some more - fs.mkdirSync(path.join(sourceDir, '0.0.3')); - fs.mkdirSync(path.join(sourceDir2, '0.0.4')); - - // Reset cache - ResolveCache.clearRuntimeCache(); - }) - .then(function () { - return resolveCache.versions(source) - .then(function (versions) { - expect(versions).to.eql(['0.0.3', '0.0.1']); - + resolveCache + .versions(source) + .then(function() { return resolveCache.versions(source2); }) - .then(function (versions) { - expect(versions).to.eql(['0.0.4', '0.0.2']); + .then(function() { + // Create some more + fs.mkdirSync(path.join(sourceDir, '0.0.3')); + fs.mkdirSync(path.join(sourceDir2, '0.0.4')); - next(); - }); - }) - .done(); + // Reset cache + ResolveCache.clearRuntimeCache(); + }) + .then(function() { + return resolveCache + .versions(source) + .then(function(versions) { + expect(versions).to.eql(['0.0.3', '0.0.1']); + + return resolveCache.versions(source2); + }) + .then(function(versions) { + expect(versions).to.eql(['0.0.4', '0.0.2']); + + next(); + }); + }) + .done(); }); }); }); diff --git a/test/core/resolverFactory.js b/test/core/resolverFactory.js index 96ff56f4b..d455fd3c8 100644 --- a/test/core/resolverFactory.js +++ b/test/core/resolverFactory.js @@ -12,14 +12,16 @@ var resolvers = require('../../lib/core/resolvers'); var defaultConfig = require('../../lib/config'); var helpers = require('../helpers'); -describe('resolverFactory', function () { +describe('resolverFactory', function() { var tempSource; var logger = new Logger(); - var registryClient = new RegistryClient(defaultConfig({ - cache: defaultConfig()._registry - })); + var registryClient = new RegistryClient( + defaultConfig({ + cache: defaultConfig()._registry + }) + ); - afterEach(function (next) { + afterEach(function(next) { logger.removeAllListeners(); if (tempSource) { @@ -30,189 +32,278 @@ describe('resolverFactory', function () { } }); - after(function (next) { + after(function(next) { rimraf('pure', next); }); function callFactory(decEndpoint, config, skipRegistry) { - return resolverFactory(decEndpoint, { config: defaultConfig(config), logger: logger }, skipRegistry ? undefined : registryClient); + return resolverFactory( + decEndpoint, + { config: defaultConfig(config), logger: logger }, + skipRegistry ? undefined : registryClient + ); } - it('should recognize git remote endpoints correctly', function (next) { + it('should recognize git remote endpoints correctly', function(next) { var promise = Q.resolve(); var endpoints; endpoints = { // git: - 'git://hostname.com/user/project': 'git://hostname.com/user/project', - 'git://hostname.com/user/project/': 'git://hostname.com/user/project', - 'git://hostname.com/user/project.git': 'git://hostname.com/user/project.git', - 'git://hostname.com/user/project.git/': 'git://hostname.com/user/project.git', + 'git://hostname.com/user/project': + 'git://hostname.com/user/project', + 'git://hostname.com/user/project/': + 'git://hostname.com/user/project', + 'git://hostname.com/user/project.git': + 'git://hostname.com/user/project.git', + 'git://hostname.com/user/project.git/': + 'git://hostname.com/user/project.git', // git@: 'git@hostname.com:user/project': 'git@hostname.com:user/project', 'git@hostname.com:user/project/': 'git@hostname.com:user/project', - 'git@hostname.com:user/project.git': 'git@hostname.com:user/project.git', - 'git@hostname.com:user/project.git/': 'git@hostname.com:user/project.git', + 'git@hostname.com:user/project.git': + 'git@hostname.com:user/project.git', + 'git@hostname.com:user/project.git/': + 'git@hostname.com:user/project.git', // git+ssh: - 'git+ssh://user@hostname.com:project': 'ssh://user@hostname.com:project', - 'git+ssh://user@hostname.com:project/': 'ssh://user@hostname.com:project', - 'git+ssh://user@hostname.com:project.git': 'ssh://user@hostname.com:project.git', - 'git+ssh://user@hostname.com:project.git/': 'ssh://user@hostname.com:project.git', - 'git+ssh://user@hostname.com/project': 'ssh://user@hostname.com/project', - 'git+ssh://user@hostname.com/project/': 'ssh://user@hostname.com/project', - 'git+ssh://user@hostname.com/project.git': 'ssh://user@hostname.com/project.git', - 'git+ssh://user@hostname.com/project.git/': 'ssh://user@hostname.com/project.git', + 'git+ssh://user@hostname.com:project': + 'ssh://user@hostname.com:project', + 'git+ssh://user@hostname.com:project/': + 'ssh://user@hostname.com:project', + 'git+ssh://user@hostname.com:project.git': + 'ssh://user@hostname.com:project.git', + 'git+ssh://user@hostname.com:project.git/': + 'ssh://user@hostname.com:project.git', + 'git+ssh://user@hostname.com/project': + 'ssh://user@hostname.com/project', + 'git+ssh://user@hostname.com/project/': + 'ssh://user@hostname.com/project', + 'git+ssh://user@hostname.com/project.git': + 'ssh://user@hostname.com/project.git', + 'git+ssh://user@hostname.com/project.git/': + 'ssh://user@hostname.com/project.git', // git+http - 'git+http://hostname.com/project/blah': 'http://hostname.com/project/blah', - 'git+http://hostname.com/project/blah/': 'http://hostname.com/project/blah', - 'git+http://hostname.com/project/blah.git': 'http://hostname.com/project/blah.git', - 'git+http://hostname.com/project/blah.git/': 'http://hostname.com/project/blah.git', - 'git+http://user@hostname.com/project/blah': 'http://user@hostname.com/project/blah', - 'git+http://user@hostname.com/project/blah/': 'http://user@hostname.com/project/blah', - 'git+http://user@hostname.com/project/blah.git': 'http://user@hostname.com/project/blah.git', - 'git+http://user@hostname.com/project/blah.git/': 'http://user@hostname.com/project/blah.git', + 'git+http://hostname.com/project/blah': + 'http://hostname.com/project/blah', + 'git+http://hostname.com/project/blah/': + 'http://hostname.com/project/blah', + 'git+http://hostname.com/project/blah.git': + 'http://hostname.com/project/blah.git', + 'git+http://hostname.com/project/blah.git/': + 'http://hostname.com/project/blah.git', + 'git+http://user@hostname.com/project/blah': + 'http://user@hostname.com/project/blah', + 'git+http://user@hostname.com/project/blah/': + 'http://user@hostname.com/project/blah', + 'git+http://user@hostname.com/project/blah.git': + 'http://user@hostname.com/project/blah.git', + 'git+http://user@hostname.com/project/blah.git/': + 'http://user@hostname.com/project/blah.git', // git+https - 'git+https://hostname.com/project/blah': 'https://hostname.com/project/blah', - 'git+https://hostname.com/project/blah/': 'https://hostname.com/project/blah', - 'git+https://hostname.com/project/blah.git': 'https://hostname.com/project/blah.git', - 'git+https://hostname.com/project/blah.git/': 'https://hostname.com/project/blah.git', - 'git+https://user@hostname.com/project/blah': 'https://user@hostname.com/project/blah', - 'git+https://user@hostname.com/project/blah/': 'https://user@hostname.com/project/blah', - 'git+https://user@hostname.com/project/blah.git': 'https://user@hostname.com/project/blah.git', - 'git+https://user@hostname.com/project/blah.git/': 'https://user@hostname.com/project/blah.git', + 'git+https://hostname.com/project/blah': + 'https://hostname.com/project/blah', + 'git+https://hostname.com/project/blah/': + 'https://hostname.com/project/blah', + 'git+https://hostname.com/project/blah.git': + 'https://hostname.com/project/blah.git', + 'git+https://hostname.com/project/blah.git/': + 'https://hostname.com/project/blah.git', + 'git+https://user@hostname.com/project/blah': + 'https://user@hostname.com/project/blah', + 'git+https://user@hostname.com/project/blah/': + 'https://user@hostname.com/project/blah', + 'git+https://user@hostname.com/project/blah.git': + 'https://user@hostname.com/project/blah.git', + 'git+https://user@hostname.com/project/blah.git/': + 'https://user@hostname.com/project/blah.git', // ssh .git$ - 'ssh://user@hostname.com:project.git': 'ssh://user@hostname.com:project.git', - 'ssh://user@hostname.com:project.git/': 'ssh://user@hostname.com:project.git', - 'ssh://user@hostname.com/project.git': 'ssh://user@hostname.com/project.git', - 'ssh://user@hostname.com/project.git/': 'ssh://user@hostname.com/project.git', + 'ssh://user@hostname.com:project.git': + 'ssh://user@hostname.com:project.git', + 'ssh://user@hostname.com:project.git/': + 'ssh://user@hostname.com:project.git', + 'ssh://user@hostname.com/project.git': + 'ssh://user@hostname.com/project.git', + 'ssh://user@hostname.com/project.git/': + 'ssh://user@hostname.com/project.git', // http .git$ - 'http://hostname.com/project.git': 'http://hostname.com/project.git', - 'http://hostname.com/project.git/': 'http://hostname.com/project.git', - 'http://user@hostname.com/project.git': 'http://user@hostname.com/project.git', - 'http://user@hostname.com/project.git/': 'http://user@hostname.com/project.git', + 'http://hostname.com/project.git': + 'http://hostname.com/project.git', + 'http://hostname.com/project.git/': + 'http://hostname.com/project.git', + 'http://user@hostname.com/project.git': + 'http://user@hostname.com/project.git', + 'http://user@hostname.com/project.git/': + 'http://user@hostname.com/project.git', // https .git$ - 'https://hostname.com/project.git': 'https://hostname.com/project.git', - 'https://hostname.com/project.git/': 'https://hostname.com/project.git', - 'https://user@hostname.com/project.git': 'https://user@hostname.com/project.git', - 'https://user@hostname.com/project.git/': 'https://user@hostname.com/project.git', + 'https://hostname.com/project.git': + 'https://hostname.com/project.git', + 'https://hostname.com/project.git/': + 'https://hostname.com/project.git', + 'https://user@hostname.com/project.git': + 'https://user@hostname.com/project.git', + 'https://user@hostname.com/project.git/': + 'https://user@hostname.com/project.git', // shorthand 'bower/bower': 'https://github.com/bower/bower.git' }; - mout.object.forOwn(endpoints, function (value, key) { + mout.object.forOwn(endpoints, function(value, key) { // Test without name and target - promise = promise.then(function () { - return callFactory({ source: key }); - }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.GitRemote); - expect(resolver).to.not.be(resolvers.GitHub); - expect(resolver.getSource()).to.equal(value); - expect(resolver.getTarget()).to.equal('*'); - }); + promise = promise + .then(function() { + return callFactory({ source: key }); + }) + .then(function(resolver) { + expect(resolver).to.be.a(resolvers.GitRemote); + expect(resolver).to.not.be(resolvers.GitHub); + expect(resolver.getSource()).to.equal(value); + expect(resolver.getTarget()).to.equal('*'); + }); // Test with target - promise = promise.then(function () { - return callFactory({ source: key, target: 'commit-ish' }); - }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.GitRemote); - expect(resolver).to.not.be(resolvers.GitHub); - expect(resolver.getSource()).to.equal(value); - expect(resolver.getTarget()).to.equal('commit-ish'); - }); + promise = promise + .then(function() { + return callFactory({ source: key, target: 'commit-ish' }); + }) + .then(function(resolver) { + expect(resolver).to.be.a(resolvers.GitRemote); + expect(resolver).to.not.be(resolvers.GitHub); + expect(resolver.getSource()).to.equal(value); + expect(resolver.getTarget()).to.equal('commit-ish'); + }); // Test with name - promise = promise.then(function () { - return callFactory({ name: 'foo', source: key }); - }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.GitRemote); - expect(resolver).to.not.be(resolvers.GitHub); - expect(resolver.getSource()).to.equal(value); - expect(resolver.getName()).to.equal('foo'); - expect(resolver.getTarget()).to.equal('*'); - }); + promise = promise + .then(function() { + return callFactory({ name: 'foo', source: key }); + }) + .then(function(resolver) { + expect(resolver).to.be.a(resolvers.GitRemote); + expect(resolver).to.not.be(resolvers.GitHub); + expect(resolver.getSource()).to.equal(value); + expect(resolver.getName()).to.equal('foo'); + expect(resolver.getTarget()).to.equal('*'); + }); }); - promise - .then(next.bind(next, null)) - .done(); + promise.then(next.bind(next, null)).done(); }); - it('should recognize GitHub endpoints correctly', function (next) { + it('should recognize GitHub endpoints correctly', function(next) { var promise = Q.resolve(); var gitHub; var nonGitHub; gitHub = { // git: - 'git://github.com/user/project': 'git://github.com/user/project.git', - 'git://github.com/user/project/': 'git://github.com/user/project.git', - 'git://github.com/user/project.git': 'git://github.com/user/project.git', - 'git://github.com/user/project.git/': 'git://github.com/user/project.git', + 'git://github.com/user/project': + 'git://github.com/user/project.git', + 'git://github.com/user/project/': + 'git://github.com/user/project.git', + 'git://github.com/user/project.git': + 'git://github.com/user/project.git', + 'git://github.com/user/project.git/': + 'git://github.com/user/project.git', // git@: 'git@github.com:user/project': 'git@github.com:user/project.git', 'git@github.com:user/project/': 'git@github.com:user/project.git', - 'git@github.com:user/project.git': 'git@github.com:user/project.git', - 'git@github.com:user/project.git/': 'git@github.com:user/project.git', + 'git@github.com:user/project.git': + 'git@github.com:user/project.git', + 'git@github.com:user/project.git/': + 'git@github.com:user/project.git', // git+ssh: - 'git+ssh://git@github.com:project/blah': 'ssh://git@github.com:project/blah.git', - 'git+ssh://git@github.com:project/blah/': 'ssh://git@github.com:project/blah.git', - 'git+ssh://git@github.com:project/blah.git': 'ssh://git@github.com:project/blah.git', - 'git+ssh://git@github.com:project/blah.git/': 'ssh://git@github.com:project/blah.git', - 'git+ssh://git@github.com/project/blah': 'ssh://git@github.com/project/blah.git', - 'git+ssh://git@github.com/project/blah/': 'ssh://git@github.com/project/blah.git', - 'git+ssh://git@github.com/project/blah.git': 'ssh://git@github.com/project/blah.git', - 'git+ssh://git@github.com/project/blah.git/': 'ssh://git@github.com/project/blah.git', + 'git+ssh://git@github.com:project/blah': + 'ssh://git@github.com:project/blah.git', + 'git+ssh://git@github.com:project/blah/': + 'ssh://git@github.com:project/blah.git', + 'git+ssh://git@github.com:project/blah.git': + 'ssh://git@github.com:project/blah.git', + 'git+ssh://git@github.com:project/blah.git/': + 'ssh://git@github.com:project/blah.git', + 'git+ssh://git@github.com/project/blah': + 'ssh://git@github.com/project/blah.git', + 'git+ssh://git@github.com/project/blah/': + 'ssh://git@github.com/project/blah.git', + 'git+ssh://git@github.com/project/blah.git': + 'ssh://git@github.com/project/blah.git', + 'git+ssh://git@github.com/project/blah.git/': + 'ssh://git@github.com/project/blah.git', // git+http - 'git+http://github.com/project/blah': 'http://github.com/project/blah.git', - 'git+http://github.com/project/blah/': 'http://github.com/project/blah.git', - 'git+http://github.com/project/blah.git': 'http://github.com/project/blah.git', - 'git+http://github.com/project/blah.git/': 'http://github.com/project/blah.git', - 'git+http://user@github.com/project/blah': 'http://user@github.com/project/blah.git', - 'git+http://user@github.com/project/blah/': 'http://user@github.com/project/blah.git', - 'git+http://user@github.com/project/blah.git': 'http://user@github.com/project/blah.git', - 'git+http://user@github.com/project/blah.git/': 'http://user@github.com/project/blah.git', + 'git+http://github.com/project/blah': + 'http://github.com/project/blah.git', + 'git+http://github.com/project/blah/': + 'http://github.com/project/blah.git', + 'git+http://github.com/project/blah.git': + 'http://github.com/project/blah.git', + 'git+http://github.com/project/blah.git/': + 'http://github.com/project/blah.git', + 'git+http://user@github.com/project/blah': + 'http://user@github.com/project/blah.git', + 'git+http://user@github.com/project/blah/': + 'http://user@github.com/project/blah.git', + 'git+http://user@github.com/project/blah.git': + 'http://user@github.com/project/blah.git', + 'git+http://user@github.com/project/blah.git/': + 'http://user@github.com/project/blah.git', // git+https - 'git+https://github.com/project/blah': 'https://github.com/project/blah.git', - 'git+https://github.com/project/blah/': 'https://github.com/project/blah.git', - 'git+https://github.com/project/blah.git': 'https://github.com/project/blah.git', - 'git+https://github.com/project/blah.git/': 'https://github.com/project/blah.git', - 'git+https://user@github.com/project/blah': 'https://user@github.com/project/blah.git', - 'git+https://user@github.com/project/blah/': 'https://user@github.com/project/blah.git', - 'git+https://user@github.com/project/blah.git': 'https://user@github.com/project/blah.git', - 'git+https://user@github.com/project/blah.git/': 'https://user@github.com/project/blah.git', + 'git+https://github.com/project/blah': + 'https://github.com/project/blah.git', + 'git+https://github.com/project/blah/': + 'https://github.com/project/blah.git', + 'git+https://github.com/project/blah.git': + 'https://github.com/project/blah.git', + 'git+https://github.com/project/blah.git/': + 'https://github.com/project/blah.git', + 'git+https://user@github.com/project/blah': + 'https://user@github.com/project/blah.git', + 'git+https://user@github.com/project/blah/': + 'https://user@github.com/project/blah.git', + 'git+https://user@github.com/project/blah.git': + 'https://user@github.com/project/blah.git', + 'git+https://user@github.com/project/blah.git/': + 'https://user@github.com/project/blah.git', // ssh .git$ - 'ssh://git@github.com:project/blah.git': 'ssh://git@github.com:project/blah.git', - 'ssh://git@github.com:project/blah.git/': 'ssh://git@github.com:project/blah.git', - 'ssh://git@github.com/project/blah.git': 'ssh://git@github.com/project/blah.git', - 'ssh://git@github.com/project/blah.git/': 'ssh://git@github.com/project/blah.git', + 'ssh://git@github.com:project/blah.git': + 'ssh://git@github.com:project/blah.git', + 'ssh://git@github.com:project/blah.git/': + 'ssh://git@github.com:project/blah.git', + 'ssh://git@github.com/project/blah.git': + 'ssh://git@github.com/project/blah.git', + 'ssh://git@github.com/project/blah.git/': + 'ssh://git@github.com/project/blah.git', // http .git$ - 'http://github.com/project/blah.git': 'http://github.com/project/blah.git', - 'http://github.com/project/blah.git/': 'http://github.com/project/blah.git', - 'http://user@github.com/project/blah.git': 'http://user@github.com/project/blah.git', - 'http://user@github.com/project/blah.git/': 'http://user@github.com/project/blah.git', + 'http://github.com/project/blah.git': + 'http://github.com/project/blah.git', + 'http://github.com/project/blah.git/': + 'http://github.com/project/blah.git', + 'http://user@github.com/project/blah.git': + 'http://user@github.com/project/blah.git', + 'http://user@github.com/project/blah.git/': + 'http://user@github.com/project/blah.git', // https - 'https://github.com/project/blah.git': 'https://github.com/project/blah.git', - 'https://github.com/project/blah.git/': 'https://github.com/project/blah.git', - 'https://user@github.com/project/blah.git': 'https://user@github.com/project/blah.git', - 'https://user@github.com/project/blah.git/': 'https://user@github.com/project/blah.git', + 'https://github.com/project/blah.git': + 'https://github.com/project/blah.git', + 'https://github.com/project/blah.git/': + 'https://github.com/project/blah.git', + 'https://user@github.com/project/blah.git': + 'https://user@github.com/project/blah.git', + 'https://user@github.com/project/blah.git/': + 'https://user@github.com/project/blah.git', // shorthand 'bower/bower': 'https://github.com/bower/bower.git' @@ -236,64 +327,66 @@ describe('resolverFactory', function () { ]; // Test GitHub ones - mout.object.forOwn(gitHub, function (value, key) { + mout.object.forOwn(gitHub, function(value, key) { // Test without name and target - promise = promise.then(function () { - return callFactory({ source: key }); - }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.GitHub); - expect(resolver.getSource()).to.equal(value); - expect(resolver.getTarget()).to.equal('*'); - }); - - // Test with target - promise = promise.then(function () { - return callFactory({ source: key, target: 'commit-ish' }); - }) - .then(function (resolver) { - if (value) { + promise = promise + .then(function() { + return callFactory({ source: key }); + }) + .then(function(resolver) { expect(resolver).to.be.a(resolvers.GitHub); expect(resolver.getSource()).to.equal(value); - expect(resolver.getTarget()).to.equal('commit-ish'); - } else { - expect(resolver).to.not.be.a(resolvers.GitHub); - } - }); + expect(resolver.getTarget()).to.equal('*'); + }); + + // Test with target + promise = promise + .then(function() { + return callFactory({ source: key, target: 'commit-ish' }); + }) + .then(function(resolver) { + if (value) { + expect(resolver).to.be.a(resolvers.GitHub); + expect(resolver.getSource()).to.equal(value); + expect(resolver.getTarget()).to.equal('commit-ish'); + } else { + expect(resolver).to.not.be.a(resolvers.GitHub); + } + }); // Test with name - promise = promise.then(function () { - return callFactory({ name: 'foo', source: key }); - }) - .then(function (resolver) { - if (value) { - expect(resolver).to.be.a(resolvers.GitHub); - expect(resolver.getSource()).to.equal(value); - expect(resolver.getName()).to.equal('foo'); - expect(resolver.getTarget()).to.equal('*'); - } else { - expect(resolver).to.not.be.a(resolvers.GitHub); - } - }); + promise = promise + .then(function() { + return callFactory({ name: 'foo', source: key }); + }) + .then(function(resolver) { + if (value) { + expect(resolver).to.be.a(resolvers.GitHub); + expect(resolver.getSource()).to.equal(value); + expect(resolver.getName()).to.equal('foo'); + expect(resolver.getTarget()).to.equal('*'); + } else { + expect(resolver).to.not.be.a(resolvers.GitHub); + } + }); }); // Test similar to GitHub but not real GitHub - nonGitHub.forEach(function (value) { - promise = promise.then(function () { - return callFactory({ source: value }); - }) - .then(function (resolver) { - expect(resolver).to.not.be.a(resolvers.GitHub); - expect(resolver).to.be.a(resolvers.GitRemote); - }); + nonGitHub.forEach(function(value) { + promise = promise + .then(function() { + return callFactory({ source: value }); + }) + .then(function(resolver) { + expect(resolver).to.not.be.a(resolvers.GitHub); + expect(resolver).to.be.a(resolvers.GitRemote); + }); }); - promise - .then(next.bind(next, null)) - .done(); + promise.then(next.bind(next, null)).done(); }); - it('should recognize local fs git endpoints correctly', function (next) { + it('should recognize local fs git endpoints correctly', function(next) { var promise = Q.resolve(); var endpoints; var temp; @@ -314,112 +407,139 @@ describe('resolverFactory', function () { // TODO: test with backslashes on windows and ~/ on unix - mout.object.forOwn(endpoints, function (value, key) { + mout.object.forOwn(endpoints, function(value, key) { // Test without name - promise = promise.then(function () { - return callFactory({ source: key }); - }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.GitFs); - expect(resolver.getTarget()).to.equal('*'); - }); + promise = promise + .then(function() { + return callFactory({ source: key }); + }) + .then(function(resolver) { + expect(resolver).to.be.a(resolvers.GitFs); + expect(resolver.getTarget()).to.equal('*'); + }); // Test with name - promise = promise.then(function () { - return callFactory({ name: 'foo', source: key }); - }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.GitFs); - expect(resolver.getName()).to.equal('foo'); - expect(resolver.getTarget()).to.equal('*'); - }); + promise = promise + .then(function() { + return callFactory({ name: 'foo', source: key }); + }) + .then(function(resolver) { + expect(resolver).to.be.a(resolvers.GitFs); + expect(resolver.getName()).to.equal('foo'); + expect(resolver.getTarget()).to.equal('*'); + }); }); - promise - .then(next.bind(next, null)) - .done(); + promise.then(next.bind(next, null)).done(); }); if (!helpers.hasSvn()) - describe.skip('should recognize svn remote endpoints correctly', function () {}); - else it('should recognize svn remote endpoints correctly', function (next) { - var promise = Q.resolve(); - var endpoints; - - endpoints = { - // svn: - 'svn://hostname.com/user/project': 'http://hostname.com/user/project', - 'svn://hostname.com/user/project/': 'http://hostname.com/user/project', - - // svn@: - 'svn://svn@hostname.com:user/project': 'http://svn@hostname.com:user/project', - 'svn://svn@hostname.com:user/project/': 'http://svn@hostname.com:user/project', - - // svn+http - 'svn+http://hostname.com/project/blah': 'http://hostname.com/project/blah', - 'svn+http://hostname.com/project/blah/': 'http://hostname.com/project/blah', - 'svn+http://user@hostname.com/project/blah': 'http://user@hostname.com/project/blah', - 'svn+http://user@hostname.com/project/blah/': 'http://user@hostname.com/project/blah', - - // svn+https - 'svn+https://hostname.com/project/blah': 'https://hostname.com/project/blah', - 'svn+https://hostname.com/project/blah/': 'https://hostname.com/project/blah', - 'svn+https://user@hostname.com/project/blah': 'https://user@hostname.com/project/blah', - 'svn+https://user@hostname.com/project/blah/': 'https://user@hostname.com/project/blah', - - // svn+ssh - 'svn+ssh://hostname.com/project/blah': 'svn+ssh://hostname.com/project/blah', - 'svn+ssh://hostname.com/project/blah/': 'svn+ssh://hostname.com/project/blah', - 'svn+ssh://user@hostname.com/project/blah': 'svn+ssh://user@hostname.com/project/blah', - 'svn+ssh://user@hostname.com/project/blah/': 'svn+ssh://user@hostname.com/project/blah', - - // svn+file - 'svn+file:///project/blah': 'file:///project/blah', - 'svn+file:///project/blah/': 'file:///project/blah' - }; - - mout.object.forOwn(endpoints, function (value, key) { - // Test without name and target - promise = promise.then(function () { - return callFactory({ source: key }); - }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.Svn); - expect(resolver).to.not.be(resolvers.GitHub); - expect(resolvers.Svn.getSource(resolver.getSource())).to.equal(value); - expect(resolver.getTarget()).to.equal('*'); - }); + describe.skip('should recognize svn remote endpoints correctly', function() {}); + else + it('should recognize svn remote endpoints correctly', function(next) { + var promise = Q.resolve(); + var endpoints; + + endpoints = { + // svn: + 'svn://hostname.com/user/project': + 'http://hostname.com/user/project', + 'svn://hostname.com/user/project/': + 'http://hostname.com/user/project', + + // svn@: + 'svn://svn@hostname.com:user/project': + 'http://svn@hostname.com:user/project', + 'svn://svn@hostname.com:user/project/': + 'http://svn@hostname.com:user/project', + + // svn+http + 'svn+http://hostname.com/project/blah': + 'http://hostname.com/project/blah', + 'svn+http://hostname.com/project/blah/': + 'http://hostname.com/project/blah', + 'svn+http://user@hostname.com/project/blah': + 'http://user@hostname.com/project/blah', + 'svn+http://user@hostname.com/project/blah/': + 'http://user@hostname.com/project/blah', + + // svn+https + 'svn+https://hostname.com/project/blah': + 'https://hostname.com/project/blah', + 'svn+https://hostname.com/project/blah/': + 'https://hostname.com/project/blah', + 'svn+https://user@hostname.com/project/blah': + 'https://user@hostname.com/project/blah', + 'svn+https://user@hostname.com/project/blah/': + 'https://user@hostname.com/project/blah', + + // svn+ssh + 'svn+ssh://hostname.com/project/blah': + 'svn+ssh://hostname.com/project/blah', + 'svn+ssh://hostname.com/project/blah/': + 'svn+ssh://hostname.com/project/blah', + 'svn+ssh://user@hostname.com/project/blah': + 'svn+ssh://user@hostname.com/project/blah', + 'svn+ssh://user@hostname.com/project/blah/': + 'svn+ssh://user@hostname.com/project/blah', + + // svn+file + 'svn+file:///project/blah': 'file:///project/blah', + 'svn+file:///project/blah/': 'file:///project/blah' + }; - // Test with target - promise = promise.then(function () { - return callFactory({ source: key, target: 'commit-ish' }); - }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.Svn); - expect(resolver).to.not.be(resolvers.GitHub); - expect(resolvers.Svn.getSource(resolver.getSource())).to.equal(value); - expect(resolver.getTarget()).to.equal('commit-ish'); + mout.object.forOwn(endpoints, function(value, key) { + // Test without name and target + promise = promise + .then(function() { + return callFactory({ source: key }); + }) + .then(function(resolver) { + expect(resolver).to.be.a(resolvers.Svn); + expect(resolver).to.not.be(resolvers.GitHub); + expect( + resolvers.Svn.getSource(resolver.getSource()) + ).to.equal(value); + expect(resolver.getTarget()).to.equal('*'); + }); + + // Test with target + promise = promise + .then(function() { + return callFactory({ + source: key, + target: 'commit-ish' + }); + }) + .then(function(resolver) { + expect(resolver).to.be.a(resolvers.Svn); + expect(resolver).to.not.be(resolvers.GitHub); + expect( + resolvers.Svn.getSource(resolver.getSource()) + ).to.equal(value); + expect(resolver.getTarget()).to.equal('commit-ish'); + }); + + // Test with name + promise = promise + .then(function() { + return callFactory({ name: 'foo', source: key }); + }) + .then(function(resolver) { + expect(resolver).to.be.a(resolvers.Svn); + expect(resolver).to.not.be(resolvers.GitHub); + expect( + resolvers.Svn.getSource(resolver.getSource()) + ).to.equal(value); + expect(resolver.getName()).to.equal('foo'); + expect(resolver.getTarget()).to.equal('*'); + }); }); - // Test with name - promise = promise.then(function () { - return callFactory({ name: 'foo', source: key }); - }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.Svn); - expect(resolver).to.not.be(resolvers.GitHub); - expect(resolvers.Svn.getSource(resolver.getSource())).to.equal(value); - expect(resolver.getName()).to.equal('foo'); - expect(resolver.getTarget()).to.equal('*'); - }); + promise.then(next.bind(next, null)).done(); }); - promise - .then(next.bind(next, null)) - .done(); - }); - - it('should recognize local fs files/folder endpoints correctly', function (next) { + it('should recognize local fs files/folder endpoints correctly', function(next) { var promise = Q.resolve(); var endpoints; var temp; @@ -427,7 +547,10 @@ describe('resolverFactory', function () { tempSource = path.resolve(__dirname, '../tmp/tmp'); mkdirp.sync(tempSource); fs.writeFileSync(path.join(tempSource, '.git'), 'foo'); - fs.writeFileSync(path.join(tempSource, 'file.with.multiple.dots'), 'foo'); + fs.writeFileSync( + path.join(tempSource, 'file.with.multiple.dots'), + 'foo' + ); endpoints = {}; @@ -462,150 +585,154 @@ describe('resolverFactory', function () { temp = path.join(tempSource, 'file.with.multiple.dots'); endpoints[temp] = temp; - mout.object.forOwn(endpoints, function (value, key) { + mout.object.forOwn(endpoints, function(value, key) { // Test without name - promise = promise.then(function () { - return callFactory({ source: key }); - }) - .then(function (resolver) { - expect(resolver.getSource()).to.equal(value); - expect(resolver).to.be.a(resolvers.Fs); - expect(resolver.getTarget()).to.equal('*'); - }); + promise = promise + .then(function() { + return callFactory({ source: key }); + }) + .then(function(resolver) { + expect(resolver.getSource()).to.equal(value); + expect(resolver).to.be.a(resolvers.Fs); + expect(resolver.getTarget()).to.equal('*'); + }); // Test with name - promise = promise.then(function () { - return callFactory({ name: 'foo', source: key }); - }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.Fs); - expect(resolver.getName()).to.equal('foo'); - expect(resolver.getTarget()).to.equal('*'); - expect(resolver.getSource()).to.equal(value); - }); + promise = promise + .then(function() { + return callFactory({ name: 'foo', source: key }); + }) + .then(function(resolver) { + expect(resolver).to.be.a(resolvers.Fs); + expect(resolver.getName()).to.equal('foo'); + expect(resolver.getTarget()).to.equal('*'); + expect(resolver.getSource()).to.equal(value); + }); }); - - promise - .then(next.bind(next, null)) - .done(); + promise.then(next.bind(next, null)).done(); }); - it('should recognize URL endpoints correctly', function (next) { + it('should recognize URL endpoints correctly', function(next) { var promise = Q.resolve(); var endpoints; - endpoints = [ - 'http://bower.io/foo.js', - 'https://bower.io/foo.js' - ]; + endpoints = ['http://bower.io/foo.js', 'https://bower.io/foo.js']; - endpoints.forEach(function (source) { + endpoints.forEach(function(source) { // Test without name - promise = promise.then(function () { - return callFactory({ source: source }); - }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.Url); - expect(resolver.getSource()).to.equal(source); - }); + promise = promise + .then(function() { + return callFactory({ source: source }); + }) + .then(function(resolver) { + expect(resolver).to.be.a(resolvers.Url); + expect(resolver.getSource()).to.equal(source); + }); // Test with name - promise = promise.then(function () { - return callFactory({ name: 'foo', source: source }); - }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.Url); - expect(resolver.getName()).to.equal('foo'); - expect(resolver.getSource()).to.equal(source); - }); + promise = promise + .then(function() { + return callFactory({ name: 'foo', source: source }); + }) + .then(function(resolver) { + expect(resolver).to.be.a(resolvers.Url); + expect(resolver.getName()).to.equal('foo'); + expect(resolver.getSource()).to.equal(source); + }); }); - promise - .then(next.bind(next, null)) - .done(); + promise.then(next.bind(next, null)).done(); }); - it('should recognize URL endpoints correctly', function (next) { + it('should recognize URL endpoints correctly', function(next) { var promise = Q.resolve(); var endpoints; - endpoints = [ - 'http://bower.io/foo.js', - 'https://bower.io/foo.js' - ]; + endpoints = ['http://bower.io/foo.js', 'https://bower.io/foo.js']; - endpoints.forEach(function (source) { + endpoints.forEach(function(source) { // Test without name - promise = promise.then(function () { - return callFactory({ source: source }); - }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.Url); - expect(resolver.getSource()).to.equal(source); - }); + promise = promise + .then(function() { + return callFactory({ source: source }); + }) + .then(function(resolver) { + expect(resolver).to.be.a(resolvers.Url); + expect(resolver.getSource()).to.equal(source); + }); // Test with name - promise = promise.then(function () { - return callFactory({ name: 'foo', source: source }); - }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.Url); - expect(resolver.getName()).to.equal('foo'); - expect(resolver.getSource()).to.equal(source); - }); + promise = promise + .then(function() { + return callFactory({ name: 'foo', source: source }); + }) + .then(function(resolver) { + expect(resolver).to.be.a(resolvers.Url); + expect(resolver.getName()).to.equal('foo'); + expect(resolver.getSource()).to.equal(source); + }); }); - promise - .then(next.bind(next, null)) - .done(); + promise.then(next.bind(next, null)).done(); }); - it('should recognize registry endpoints correctly', function (next) { + it('should recognize registry endpoints correctly', function(next) { // Create a 'pure' file at the root to prevent regressions of #666 fs.writeFileSync('pure', 'foo'); callFactory({ source: 'pure' }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.GitRemote); - expect(resolver.getSource()).to.equal('https://github.com/yui/pure-release.git'); - expect(resolver.getTarget()).to.equal('*'); - }) - .then(function () { - // Test with name - return callFactory({ source: 'pure', name: 'foo' }) - .then(function (resolver) { + .then(function(resolver) { expect(resolver).to.be.a(resolvers.GitRemote); - expect(resolver.getSource()).to.equal('https://github.com/yui/pure-release.git'); - expect(resolver.getName()).to.equal('foo'); + expect(resolver.getSource()).to.equal( + 'https://github.com/yui/pure-release.git' + ); expect(resolver.getTarget()).to.equal('*'); - }); - }) - .then(function () { - // Test with target - return callFactory({ source: 'pure', target: '~0.4.0' }) - .then(function (resolver) { - expect(resolver).to.be.a(resolvers.GitRemote); - expect(resolver.getTarget()).to.equal('~0.4.0'); - - next(); - }); - }) - .done(); + }) + .then(function() { + // Test with name + return callFactory({ source: 'pure', name: 'foo' }).then( + function(resolver) { + expect(resolver).to.be.a(resolvers.GitRemote); + expect(resolver.getSource()).to.equal( + 'https://github.com/yui/pure-release.git' + ); + expect(resolver.getName()).to.equal('foo'); + expect(resolver.getTarget()).to.equal('*'); + } + ); + }) + .then(function() { + // Test with target + return callFactory({ source: 'pure', target: '~0.4.0' }).then( + function(resolver) { + expect(resolver).to.be.a(resolvers.GitRemote); + expect(resolver.getTarget()).to.equal('~0.4.0'); + + next(); + } + ); + }) + .done(); }); - it('should error out if the package was not found in the registry', function (next) { + it('should error out if the package was not found in the registry', function(next) { callFactory({ source: 'some-package-that-will-never-exist' }) - .then(function () { - throw new Error('Should have failed'); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.equal('ENOTFOUND'); - expect(err.message).to.contain('some-package-that-will-never-exist'); - - next(); - }) - .done(); + .then( + function() { + throw new Error('Should have failed'); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.equal('ENOTFOUND'); + expect(err.message).to.contain( + 'some-package-that-will-never-exist' + ); + + next(); + } + ) + .done(); }); // it('should set registry to true on the decomposed endpoint if fetched from the registry', function (next) { @@ -618,54 +745,68 @@ describe('resolverFactory', function () { // .done(); // }); - it('should use the configured shorthand resolver', function (next) { + it('should use the configured shorthand resolver', function(next) { callFactory({ source: 'bower/bower' }) - .then(function (resolver) { - var config = { - shorthandResolver: 'https://bower.io/{{owner}}/{{package}}/{{shorthand}}' - }; + .then(function(resolver) { + var config = { + shorthandResolver: + 'https://bower.io/{{owner}}/{{package}}/{{shorthand}}' + }; - expect(resolver.getSource()).to.equal('https://github.com/bower/bower.git'); + expect(resolver.getSource()).to.equal( + 'https://github.com/bower/bower.git' + ); - return callFactory({ source: 'IndigoUnited/promptly' }, config); - }) - .then(function (resolver) { - expect(resolver.getSource()).to.equal('https://bower.io/IndigoUnited/promptly/IndigoUnited/promptly'); - next(); - }) - .done(); + return callFactory({ source: 'IndigoUnited/promptly' }, config); + }) + .then(function(resolver) { + expect(resolver.getSource()).to.equal( + 'https://bower.io/IndigoUnited/promptly/IndigoUnited/promptly' + ); + next(); + }) + .done(); }); - it('should not expand using the shorthand resolver if it looks like a SSH URL', function (next) { + it('should not expand using the shorthand resolver if it looks like a SSH URL', function(next) { callFactory({ source: 'bleh@xxx.com:foo/bar' }) - .then(function (resolver) { - throw new Error('Should have failed'); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.equal('ENOTFOUND'); - expect(err.message).to.contain('bleh@xxx.com:foo/bar'); - next(); - }) - .done(); + .then( + function(resolver) { + throw new Error('Should have failed'); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.equal('ENOTFOUND'); + expect(err.message).to.contain('bleh@xxx.com:foo/bar'); + next(); + } + ) + .done(); }); - - it('should error out if there\'s no suitable resolver for a given source', function (next) { - callFactory({ source: 'some-package-that-will-never-exist' }, undefined, true) - .then(function () { - throw new Error('Should have failed'); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.be('ENORESOLVER'); - expect(err.message).to.contain('appropriate resolver'); - next(); - }) - .done(); + it("should error out if there's no suitable resolver for a given source", function(next) { + callFactory( + { source: 'some-package-that-will-never-exist' }, + undefined, + true + ) + .then( + function() { + throw new Error('Should have failed'); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.be('ENORESOLVER'); + expect(err.message).to.contain('appropriate resolver'); + next(); + } + ) + .done(); }); it.skip('should use config.cwd when resolving relative paths'); - it('should not swallow constructor errors when instantiating resolvers', function (next) { + it('should not swallow constructor errors when instantiating resolvers', function(next) { var promise = Q.resolve(); var endpoints; @@ -675,33 +816,35 @@ describe('resolverFactory', function () { path.resolve(__dirname, '../assets/test-temp-dir') ]; - endpoints.forEach(function (source) { - promise = promise.then(function () { - return callFactory({ source: source, target: 'bleh' }); - }) - .then(function () { - throw new Error('Should have failed'); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.message).to.match(/can't resolve targets/i); - expect(err.code).to.equal('ENORESTARGET'); - }); + endpoints.forEach(function(source) { + promise = promise + .then(function() { + return callFactory({ source: source, target: 'bleh' }); + }) + .then( + function() { + throw new Error('Should have failed'); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.message).to.match(/can't resolve targets/i); + expect(err.code).to.equal('ENORESTARGET'); + } + ); }); - promise - .then(next.bind(next, null)) - .done(); + promise.then(next.bind(next, null)).done(); }); - describe('.clearRuntimeCache', function () { - it('should call every resolver static method that clears the runtime cache', function () { + describe('.clearRuntimeCache', function() { + it('should call every resolver static method that clears the runtime cache', function() { var originalMethods = {}; var called = []; var error; - mout.object.forOwn(resolvers, function (ConcreteResolver, key) { + mout.object.forOwn(resolvers, function(ConcreteResolver, key) { originalMethods[key] = ConcreteResolver.clearRuntimeCache; - ConcreteResolver.clearRuntimeCache = function () { + ConcreteResolver.clearRuntimeCache = function() { called.push(key); return originalMethods[key].apply(this, arguments); }; @@ -712,7 +855,7 @@ describe('resolverFactory', function () { } catch (e) { error = e; } finally { - mout.object.forOwn(resolvers, function (ConcreteResolver, key) { + mout.object.forOwn(resolvers, function(ConcreteResolver, key) { ConcreteResolver.clearRuntimeCache = originalMethods[key]; }); } diff --git a/test/core/resolvers/fsResolver.js b/test/core/resolvers/fsResolver.js index 40ae32f4e..6485e8955 100644 --- a/test/core/resolvers/fsResolver.js +++ b/test/core/resolvers/fsResolver.js @@ -11,20 +11,22 @@ var copy = require('../../../lib/util/copy'); var FsResolver = require('../../../lib/core/resolvers/FsResolver'); var defaultConfig = require('../../../lib/config'); -describe('FsResolver', function () { +describe('FsResolver', function() { var tempSource; var logger; var testPackage = path.resolve(__dirname, '../../assets/package-a'); - before(function (next) { + before(function(next) { logger = new Logger(); // Checkout test package version 0.2.1 which has a bower.json // with ignores - cmd('git', ['checkout', '0.2.1'], { cwd: testPackage }) - .then(next.bind(next, null), next); + cmd('git', ['checkout', '0.2.1'], { cwd: testPackage }).then( + next.bind(next, null), + next + ); }); - afterEach(function (next) { + afterEach(function(next) { logger.removeAllListeners(); if (tempSource) { @@ -43,14 +45,14 @@ describe('FsResolver', function () { return new FsResolver(decEndpoint, defaultConfig(), logger); } - describe('.constructor', function () { - it('should guess the name from the path', function () { + describe('.constructor', function() { + it('should guess the name from the path', function() { var resolver = create(path.resolve('../../assets/package-zip.zip')); expect(resolver.getName()).to.equal('package-zip'); }); - it('should make paths absolute and normalized', function () { + it('should make paths absolute and normalized', function() { var resolver; resolver = create(path.relative(process.cwd(), testPackage)); @@ -62,7 +64,7 @@ describe('FsResolver', function () { it.skip('should use config.cwd for resolving relative paths'); - it('should error out if a target was specified', function (next) { + it('should error out if a target was specified', function(next) { var resolver; try { @@ -78,20 +80,21 @@ describe('FsResolver', function () { }); }); - describe('.hasNew', function () { - it('should resolve always to true (for now..)', function (next) { + describe('.hasNew', function() { + it('should resolve always to true (for now..)', function(next) { var resolver = create(testPackage); var pkgMeta = { name: 'test' }; - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(true); - next(); - }) - .done(); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); }); //it.skip('should be false if the file mtime hasn\'t changed'); @@ -101,62 +104,74 @@ describe('FsResolver', function () { //it.skip('should ignore files specified to be ignored'); }); - describe('.resolve', function () { + describe('.resolve', function() { // Function to assert that the main property of the // package meta of a canonical dir is set to the // expected value function assertMain(dir, singleFile) { - return Q.nfcall(fs.readFile, path.join(dir, '.bower.json')) - .then(function (contents) { - var pkgMeta = JSON.parse(contents.toString()); + return Q.nfcall(fs.readFile, path.join(dir, '.bower.json')).then( + function(contents) { + var pkgMeta = JSON.parse(contents.toString()); - expect(pkgMeta.main).to.equal(singleFile); + expect(pkgMeta.main).to.equal(singleFile); - return pkgMeta; - }); + return pkgMeta; + } + ); } - it('should copy the source directory contents', function (next) { + it('should copy the source directory contents', function(next) { var resolver = create(testPackage); - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'README.md'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'more'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'more', 'more-foo'))).to.be(true); - next(); - }) - .done(); + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'README.md'))).to.be( + true + ); + expect(fs.existsSync(path.join(dir, 'more'))).to.be(true); + expect( + fs.existsSync(path.join(dir, 'more', 'more-foo')) + ).to.be(true); + next(); + }) + .done(); }); - it('should copy the source file, renaming it to index', function (next) { + it('should copy the source file, renaming it to index', function(next) { var resolver = create(path.join(testPackage, 'foo')); - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'index'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'foo'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'bar'))).to.be(false); - }) - .then(function () { - // Test with extension - var resolver = create(path.join(testPackage, 'README.md')); - return resolver.resolve(); - }) - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'index.md'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'README.md'))).to.be(false); - - return assertMain(dir, 'index.md') - .then(next.bind(next, null)); - }) - .done(); + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'index'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'foo'))).to.be(false); + expect(fs.existsSync(path.join(dir, 'bar'))).to.be(false); + }) + .then(function() { + // Test with extension + var resolver = create(path.join(testPackage, 'README.md')); + return resolver.resolve(); + }) + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'index.md'))).to.be( + true + ); + expect(fs.existsSync(path.join(dir, 'README.md'))).to.be( + false + ); + + return assertMain(dir, 'index.md').then( + next.bind(next, null) + ); + }) + .done(); }); - it('should rename to index if source is a folder with just one file in it', function (next) { + it('should rename to index if source is a folder with just one file in it', function(next) { var resolver; tempSource = path.resolve(__dirname, '../../tmp/tmp'); @@ -164,19 +179,22 @@ describe('FsResolver', function () { mkdirp.sync(tempSource); resolver = create(tempSource); - copy.copyFile(path.join(testPackage, 'foo'), path.join(tempSource, 'foo')) - .then(resolver.resolve.bind(resolver)) - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'index'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'foo'))).to.be(false); - - return assertMain(dir, 'index') - .then(next.bind(next, null)); - }) - .done(); + copy + .copyFile( + path.join(testPackage, 'foo'), + path.join(tempSource, 'foo') + ) + .then(resolver.resolve.bind(resolver)) + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'index'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'foo'))).to.be(false); + + return assertMain(dir, 'index').then(next.bind(next, null)); + }) + .done(); }); - it('should not rename to index if source is a folder with just bower.json/component.json file in it', function (next) { + it('should not rename to index if source is a folder with just bower.json/component.json file in it', function(next) { var resolver; tempSource = path.resolve(__dirname, '../../tmp/tmp'); @@ -184,156 +202,222 @@ describe('FsResolver', function () { mkdirp.sync(tempSource); resolver = create(tempSource); - copy.copyFile(path.join(testPackage, 'bower.json'), path.join(tempSource, 'bower.json')) - .then(resolver.resolve.bind(resolver)) - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'bower.json'))).to.be(true); - - rimraf.sync(tempSource); - mkdirp.sync(tempSource); - - resolver = create(tempSource); - }) - .then(copy.copyFile.bind(copy, path.join(testPackage, 'bower.json'), path.join(tempSource, 'component.json'))) - .then(function () { - return resolver.resolve(); - }) - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'component.json'))).to.be(true); - next(); - }) - .done(); + copy + .copyFile( + path.join(testPackage, 'bower.json'), + path.join(tempSource, 'bower.json') + ) + .then(resolver.resolve.bind(resolver)) + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'bower.json'))).to.be( + true + ); + + rimraf.sync(tempSource); + mkdirp.sync(tempSource); + + resolver = create(tempSource); + }) + .then( + copy.copyFile.bind( + copy, + path.join(testPackage, 'bower.json'), + path.join(tempSource, 'component.json') + ) + ) + .then(function() { + return resolver.resolve(); + }) + .then(function(dir) { + expect( + fs.existsSync(path.join(dir, 'component.json')) + ).to.be(true); + next(); + }) + .done(); }); - it('should copy the source directory permissions', function (next) { + it('should copy the source directory permissions', function(next) { var mode0777; var resolver; tempSource = path.resolve(__dirname, '../../assets/package-a-copy'); resolver = create(tempSource); - copy.copyDir(testPackage, tempSource) - .then(function () { - // Change tempSource dir to 0777 - fs.chmodSync(tempSource, 0777); - // Get the mode to a variable - mode0777 = fs.statSync(tempSource).mode; - }) - .then(resolver.resolve.bind(resolver)) - .then(function (dir) { - // Check if temporary dir is 0777 instead of default 0777 & ~process.umask() - var stat = fs.statSync(dir); - expect(stat.mode).to.equal(mode0777); - next(); - }) - .done(); + copy + .copyDir(testPackage, tempSource) + .then(function() { + // Change tempSource dir to 0777 + fs.chmodSync(tempSource, 0777); + // Get the mode to a variable + mode0777 = fs.statSync(tempSource).mode; + }) + .then(resolver.resolve.bind(resolver)) + .then(function(dir) { + // Check if temporary dir is 0777 instead of default 0777 & ~process.umask() + var stat = fs.statSync(dir); + expect(stat.mode).to.equal(mode0777); + next(); + }) + .done(); }); - it('should copy the source file permissions', function (next) { + it('should copy the source file permissions', function(next) { var mode0777; var resolver; tempSource = path.resolve(__dirname, '../../tmp/temp-source'); resolver = create(tempSource); - copy.copyFile(path.join(testPackage, 'foo'), tempSource) - .then(function () { - // Change tempSource dir to 0777 - fs.chmodSync(tempSource, 0777); - // Get the mode to a variable - mode0777 = fs.statSync(tempSource).mode; - }) - .then(resolver.resolve.bind(resolver)) - .then(function (dir) { - // Check if file is 0777 - var stat = fs.statSync(path.join(dir, 'index')); - expect(stat.mode).to.equal(mode0777); - next(); - }) - .done(); + copy + .copyFile(path.join(testPackage, 'foo'), tempSource) + .then(function() { + // Change tempSource dir to 0777 + fs.chmodSync(tempSource, 0777); + // Get the mode to a variable + mode0777 = fs.statSync(tempSource).mode; + }) + .then(resolver.resolve.bind(resolver)) + .then(function(dir) { + // Check if file is 0777 + var stat = fs.statSync(path.join(dir, 'index')); + expect(stat.mode).to.equal(mode0777); + next(); + }) + .done(); }); - it('should not copy ignored paths (to speed up copying)', function (next) { + it('should not copy ignored paths (to speed up copying)', function(next) { var resolver = create(testPackage); // Override the _applyPkgMeta function to prevent it from deleting ignored files - resolver._applyPkgMeta = function () { + resolver._applyPkgMeta = function() { return Q.resolve(); }; - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'test'))).to.be(false); - next(); - }) - .done(); + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'test'))).to.be(false); + next(); + }) + .done(); }); - it('should extract if source is an archive', function (next) { - var resolver = create(path.resolve(__dirname, '../../assets/package-zip.zip')); - - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip.zip'))).to.be(false); - next(); - }) - .done(); + it('should extract if source is an archive', function(next) { + var resolver = create( + path.resolve(__dirname, '../../assets/package-zip.zip') + ); + + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect( + fs.existsSync(path.join(dir, 'package-zip.zip')) + ).to.be(false); + next(); + }) + .done(); }); - it('should copy extracted folder contents if archive contains only a folder inside', function (next) { - var resolver = create(path.resolve(__dirname, '../../assets/package-zip-folder.zip')); - - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip-folder'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip-folder.zip'))).to.be(false); - next(); - }) - .done(); + it('should copy extracted folder contents if archive contains only a folder inside', function(next) { + var resolver = create( + path.resolve(__dirname, '../../assets/package-zip-folder.zip') + ); + + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be( + false + ); + expect( + fs.existsSync(path.join(dir, 'package-zip-folder')) + ).to.be(false); + expect( + fs.existsSync(path.join(dir, 'package-zip-folder.zip')) + ).to.be(false); + next(); + }) + .done(); }); - - it('should extract if source is an archive and rename to index if it\'s only one file inside', function (next) { - var resolver = create(path.resolve(__dirname, '../../assets/package-zip-single-file.zip')); - - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'index.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip-single-file'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip-single-file.zip'))).to.be(false); - - return assertMain(dir, 'index.js') - .then(next.bind(next, null)); - }) - .done(); + it("should extract if source is an archive and rename to index if it's only one file inside", function(next) { + var resolver = create( + path.resolve( + __dirname, + '../../assets/package-zip-single-file.zip' + ) + ); + + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'index.js'))).to.be( + true + ); + expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be( + false + ); + expect( + fs.existsSync(path.join(dir, 'package-zip-single-file')) + ).to.be(false); + expect( + fs.existsSync( + path.join(dir, 'package-zip-single-file.zip') + ) + ).to.be(false); + + return assertMain(dir, 'index.js').then( + next.bind(next, null) + ); + }) + .done(); }); - it('should rename single file from a single folder to index when source is an archive', function (next) { - var resolver = create(path.resolve(__dirname, '../../assets/package-zip-folder-single-file.zip')); - - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'index.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip-folder-single-file'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip-folder-single-file.zip'))).to.be(false); - - return assertMain(dir, 'index.js') - .then(next.bind(next, null)); - }) - .done(); + it('should rename single file from a single folder to index when source is an archive', function(next) { + var resolver = create( + path.resolve( + __dirname, + '../../assets/package-zip-folder-single-file.zip' + ) + ); + + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'index.js'))).to.be( + true + ); + expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be( + false + ); + expect( + fs.existsSync( + path.join(dir, 'package-zip-folder-single-file') + ) + ).to.be(false); + expect( + fs.existsSync( + path.join(dir, 'package-zip-folder-single-file.zip') + ) + ).to.be(false); + + return assertMain(dir, 'index.js').then( + next.bind(next, null) + ); + }) + .done(); }); }); - describe('#isTargetable', function () { - it('should return false', function () { + describe('#isTargetable', function() { + it('should return false', function() { expect(FsResolver.isTargetable()).to.be(false); }); }); diff --git a/test/core/resolvers/gitFsResolver.js b/test/core/resolvers/gitFsResolver.js index d116aecaf..57bfaa68b 100644 --- a/test/core/resolvers/gitFsResolver.js +++ b/test/core/resolvers/gitFsResolver.js @@ -9,16 +9,16 @@ var copy = require('../../../lib/util/copy'); var GitFsResolver = require('../../../lib/core/resolvers/GitFsResolver'); var defaultConfig = require('../../../lib/config'); -describe('GitFsResolver', function () { +describe('GitFsResolver', function() { var tempSource; var testPackage = path.resolve(__dirname, '../../assets/package-a'); var logger; - before(function () { + before(function() { logger = new Logger(); }); - afterEach(function (next) { + afterEach(function(next) { logger.removeAllListeners(); if (tempSource) { @@ -41,20 +41,20 @@ describe('GitFsResolver', function () { return new GitFsResolver(decEndpoint, defaultConfig(), logger); } - describe('.constructor', function () { - it('should guess the name from the path', function () { + describe('.constructor', function() { + it('should guess the name from the path', function() { var resolver = create(testPackage); expect(resolver.getName()).to.equal('package-a'); }); - it('should not guess the name from the path if the name was specified', function () { + it('should not guess the name from the path if the name was specified', function() { var resolver = create({ source: testPackage, name: 'foo' }); expect(resolver.getName()).to.equal('foo'); }); - it('should make paths absolute and normalized', function () { + it('should make paths absolute and normalized', function() { var resolver; resolver = create(path.relative(process.cwd(), testPackage)); @@ -67,67 +67,81 @@ describe('GitFsResolver', function () { it.skip('should use config.cwd for resolving relative paths'); }); - describe('.resolve', function () { - it('should checkout correctly if resolution is a branch', function (next) { - var resolver = create({ source: testPackage, target: 'some-branch' }); + describe('.resolve', function() { + it('should checkout correctly if resolution is a branch', function(next) { + var resolver = create({ + source: testPackage, + target: 'some-branch' + }); - resolver.resolve() - .then(function (dir) { - expect(dir).to.be.a('string'); + resolver + .resolve() + .then(function(dir) { + expect(dir).to.be.a('string'); - var files = fs.readdirSync(dir); - var fooContents; + var files = fs.readdirSync(dir); + var fooContents; - expect(files).to.contain('foo'); - expect(files).to.contain('baz'); - expect(files).to.contain('baz'); + expect(files).to.contain('foo'); + expect(files).to.contain('baz'); + expect(files).to.contain('baz'); - fooContents = fs.readFileSync(path.join(dir, 'foo')).toString(); - expect(fooContents).to.equal('foo foo'); + fooContents = fs + .readFileSync(path.join(dir, 'foo')) + .toString(); + expect(fooContents).to.equal('foo foo'); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should checkout correctly if resolution is a tag', function (next) { + it('should checkout correctly if resolution is a tag', function(next) { var resolver = create({ source: testPackage, target: '~0.0.1' }); - resolver.resolve() - .then(function (dir) { - expect(dir).to.be.a('string'); + resolver + .resolve() + .then(function(dir) { + expect(dir).to.be.a('string'); - var files = fs.readdirSync(dir); + var files = fs.readdirSync(dir); - expect(files).to.contain('foo'); - expect(files).to.contain('bar'); - expect(files).to.not.contain('baz'); + expect(files).to.contain('foo'); + expect(files).to.contain('bar'); + expect(files).to.not.contain('baz'); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should checkout correctly if resolution is a commit', function (next) { - var resolver = create({ source: testPackage, target: 'bdf51ece75e20cf404e49286727b7e92d33e9ad0' }); + it('should checkout correctly if resolution is a commit', function(next) { + var resolver = create({ + source: testPackage, + target: 'bdf51ece75e20cf404e49286727b7e92d33e9ad0' + }); - resolver.resolve() - .then(function (dir) { - expect(dir).to.be.a('string'); + resolver + .resolve() + .then(function(dir) { + expect(dir).to.be.a('string'); - var files = fs.readdirSync(dir); + var files = fs.readdirSync(dir); - expect(files).to.not.contain('foo'); - expect(files).to.not.contain('bar'); - expect(files).to.not.contain('baz'); - expect(files).to.contain('.master'); - next(); - }) - .done(); + expect(files).to.not.contain('foo'); + expect(files).to.not.contain('bar'); + expect(files).to.not.contain('baz'); + expect(files).to.contain('.master'); + next(); + }) + .done(); }); - it('should remove any untracked files and directories', function (next) { - var resolver = create({ source: testPackage, target: 'bdf51ece75e20cf404e49286727b7e92d33e9ad0' }); + it('should remove any untracked files and directories', function(next) { + var resolver = create({ + source: testPackage, + target: 'bdf51ece75e20cf404e49286727b7e92d33e9ad0' + }); var file = path.join(testPackage, 'new-file'); var dir = path.join(testPackage, 'new-dir'); @@ -143,122 +157,129 @@ describe('GitFsResolver', function () { } } - resolver.resolve() - .then(function (dir) { - expect(dir).to.be.a('string'); + resolver + .resolve() + .then(function(dir) { + expect(dir).to.be.a('string'); - var files = fs.readdirSync(dir); + var files = fs.readdirSync(dir); - expect(files).to.not.contain('new-file'); - expect(files).to.not.contain('new-dir'); + expect(files).to.not.contain('new-file'); + expect(files).to.not.contain('new-dir'); - cleanup(); - next(); - }) - .fail(cleanup) - .done(); + cleanup(); + next(); + }) + .fail(cleanup) + .done(); }); - it('should leave the original repository untouched', function (next) { + it('should leave the original repository untouched', function(next) { // Switch to master cmd('git', ['checkout', 'master'], { cwd: testPackage }) - // Resolve to some-branch - .then(function () { - var resolver = create({ source: testPackage, target: 'some-branch' }); - return resolver.resolve(); - }) - // Check if the original branch is still the master one - .then(function () { - return cmd('git', ['branch', '--color=never'], { cwd: testPackage }) - .spread(function (stdout) { - expect(stdout).to.contain('* master'); - }); - }) - // Check if git status is empty - .then(function () { - return cmd('git', ['status', '--porcelain'], { cwd: testPackage }) - .spread(function (stdout) { - stdout = stdout.trim(); - expect(stdout).to.equal(''); - next(); - }); - }) - .done(); + // Resolve to some-branch + .then(function() { + var resolver = create({ + source: testPackage, + target: 'some-branch' + }); + return resolver.resolve(); + }) + // Check if the original branch is still the master one + .then(function() { + return cmd('git', ['branch', '--color=never'], { + cwd: testPackage + }).spread(function(stdout) { + expect(stdout).to.contain('* master'); + }); + }) + // Check if git status is empty + .then(function() { + return cmd('git', ['status', '--porcelain'], { + cwd: testPackage + }).spread(function(stdout) { + stdout = stdout.trim(); + expect(stdout).to.equal(''); + next(); + }); + }) + .done(); }); - it('should copy source folder permissions', function (next) { + it('should copy source folder permissions', function(next) { var mode0777; var resolver; tempSource = path.resolve(__dirname, '../../assets/package-a-copy'); resolver = create({ source: tempSource, target: 'some-branch' }); - copy.copyDir(testPackage, tempSource) - .then(function () { - // Change tempSource dir to 0777 - fs.chmodSync(tempSource, 0777); - // Get the mode to a variable - mode0777 = fs.statSync(tempSource).mode; - }) - .then(resolver.resolve.bind(resolver)) - .then(function (dir) { - // Check if temporary dir is 0777 instead of default 0777 & ~process.umask() - var stat = fs.statSync(dir); - expect(stat.mode).to.equal(mode0777); - next(); - }) - .done(); + copy + .copyDir(testPackage, tempSource) + .then(function() { + // Change tempSource dir to 0777 + fs.chmodSync(tempSource, 0777); + // Get the mode to a variable + mode0777 = fs.statSync(tempSource).mode; + }) + .then(resolver.resolve.bind(resolver)) + .then(function(dir) { + // Check if temporary dir is 0777 instead of default 0777 & ~process.umask() + var stat = fs.statSync(dir); + expect(stat.mode).to.equal(mode0777); + next(); + }) + .done(); }); }); - describe('#refs', function () { + describe('#refs', function() { afterEach(clearResolverRuntimeCache); - it('should resolve to the references of the local repository', function (next) { + it('should resolve to the references of the local repository', function(next) { GitFsResolver.refs(testPackage) - .then(function (refs) { - // Remove master and test only for the first 7 refs - refs = refs.slice(1, 8); - - expect(refs).to.eql([ - 'e4655d250f2a3f64ef2d712f25dafa60652bb93e refs/heads/some-branch', - '0a7daf646d4fd743b6ef701d63bdbe20eee422de refs/tags/0.0.1', - '0791865e6f4b88f69fc35167a09a6f0626627765 refs/tags/0.0.2', - '2af02ac6ddeaac1c2f4bead8d6287ce54269c039 refs/tags/0.1.0', - '6ab264f1ba5bafa80fb0198183493e4d5b20804a refs/tags/0.1.1', - 'c91ed7facbb695510e3e1ab86bac8b5ac159f4f3 refs/tags/0.2.0', - '8556e55c65722a351ca5fdce4f1ebe83ec3f2365 refs/tags/0.2.1' - ]); - next(); - }) - .done(); + .then(function(refs) { + // Remove master and test only for the first 7 refs + refs = refs.slice(1, 8); + + expect(refs).to.eql([ + 'e4655d250f2a3f64ef2d712f25dafa60652bb93e refs/heads/some-branch', + '0a7daf646d4fd743b6ef701d63bdbe20eee422de refs/tags/0.0.1', + '0791865e6f4b88f69fc35167a09a6f0626627765 refs/tags/0.0.2', + '2af02ac6ddeaac1c2f4bead8d6287ce54269c039 refs/tags/0.1.0', + '6ab264f1ba5bafa80fb0198183493e4d5b20804a refs/tags/0.1.1', + 'c91ed7facbb695510e3e1ab86bac8b5ac159f4f3 refs/tags/0.2.0', + '8556e55c65722a351ca5fdce4f1ebe83ec3f2365 refs/tags/0.2.1' + ]); + next(); + }) + .done(); }); - it('should cache the results', function (next) { + it('should cache the results', function(next) { GitFsResolver.refs(testPackage) - .then(function () { - // Manipulate the cache and check if it resolves for the cached ones - GitFsResolver._cache.refs.get(testPackage).splice(0, 1); - - // Check if it resolver to the same array - return GitFsResolver.refs(testPackage); - }) - .then(function (refs) { - // Test only for the first 6 refs - refs = refs.slice(0, 7); - - expect(refs).to.eql([ - 'e4655d250f2a3f64ef2d712f25dafa60652bb93e refs/heads/some-branch', - '0a7daf646d4fd743b6ef701d63bdbe20eee422de refs/tags/0.0.1', - '0791865e6f4b88f69fc35167a09a6f0626627765 refs/tags/0.0.2', - '2af02ac6ddeaac1c2f4bead8d6287ce54269c039 refs/tags/0.1.0', - '6ab264f1ba5bafa80fb0198183493e4d5b20804a refs/tags/0.1.1', - 'c91ed7facbb695510e3e1ab86bac8b5ac159f4f3 refs/tags/0.2.0', - '8556e55c65722a351ca5fdce4f1ebe83ec3f2365 refs/tags/0.2.1' - ]); - next(); - }) - .done(); + .then(function() { + // Manipulate the cache and check if it resolves for the cached ones + GitFsResolver._cache.refs.get(testPackage).splice(0, 1); + + // Check if it resolver to the same array + return GitFsResolver.refs(testPackage); + }) + .then(function(refs) { + // Test only for the first 6 refs + refs = refs.slice(0, 7); + + expect(refs).to.eql([ + 'e4655d250f2a3f64ef2d712f25dafa60652bb93e refs/heads/some-branch', + '0a7daf646d4fd743b6ef701d63bdbe20eee422de refs/tags/0.0.1', + '0791865e6f4b88f69fc35167a09a6f0626627765 refs/tags/0.0.2', + '2af02ac6ddeaac1c2f4bead8d6287ce54269c039 refs/tags/0.1.0', + '6ab264f1ba5bafa80fb0198183493e4d5b20804a refs/tags/0.1.1', + 'c91ed7facbb695510e3e1ab86bac8b5ac159f4f3 refs/tags/0.2.0', + '8556e55c65722a351ca5fdce4f1ebe83ec3f2365 refs/tags/0.2.1' + ]); + next(); + }) + .done(); }); }); }); diff --git a/test/core/resolvers/gitHubResolver.js b/test/core/resolvers/gitHubResolver.js index 5485befee..3b63ab58b 100644 --- a/test/core/resolvers/gitHubResolver.js +++ b/test/core/resolvers/gitHubResolver.js @@ -3,19 +3,19 @@ var nock = require('nock'); var fs = require('../../../lib/util/fs'); var expect = require('expect.js'); var Logger = require('bower-logger'); -var GitRemoteResolver = require('../../../lib/core/resolvers/GitRemoteResolver'); +var GitRemoteResolver = require('../../../lib/core/resolvers/GitRemoteResolver'); var GitHubResolver = require('../../../lib/core/resolvers/GitHubResolver'); var defaultConfig = require('../../../lib/config'); -describe('GitHub', function () { +describe('GitHub', function() { var logger; var testPackage = path.resolve(__dirname, '../../assets/package-a'); - before(function () { + before(function() { logger = new Logger(); }); - afterEach(function () { + afterEach(function() { logger.removeAllListeners(); }); @@ -24,118 +24,152 @@ describe('GitHub', function () { decEndpoint = { source: decEndpoint }; } - return new GitHubResolver(decEndpoint, defaultConfig({ strictSsl: false }), logger); + return new GitHubResolver( + decEndpoint, + defaultConfig({ strictSsl: false }), + logger + ); } - describe('.constructor', function () { + describe('.constructor', function() { it.skip('should throw an error on invalid GitHub URLs'); - it('should ensure .git in the source', function () { + it('should ensure .git in the source', function() { var resolver; resolver = create('git://github.com/twitter/bower'); - expect(resolver.getSource()).to.equal('git://github.com/twitter/bower.git'); + expect(resolver.getSource()).to.equal( + 'git://github.com/twitter/bower.git' + ); resolver = create('git://github.com/twitter/bower.git'); - expect(resolver.getSource()).to.equal('git://github.com/twitter/bower.git'); + expect(resolver.getSource()).to.equal( + 'git://github.com/twitter/bower.git' + ); resolver = create('git://github.com/twitter/bower.git/'); - expect(resolver.getSource()).to.equal('git://github.com/twitter/bower.git'); + expect(resolver.getSource()).to.equal( + 'git://github.com/twitter/bower.git' + ); }); }); - describe('.resolve', function () { - it('should download and extract the .tar.gz archive from GitHub.com', function (next) { + describe('.resolve', function() { + it('should download and extract the .tar.gz archive from GitHub.com', function(next) { var resolver; nock('https://github.com') - .get('/IndigoUnited/js-events-emitter/archive/0.1.0.tar.gz') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-tar.tar.gz')); - - resolver = create({ source: 'git://github.com/IndigoUnited/js-events-emitter.git', target: '0.1.0' }); - - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, '.bower.json'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-tar.tar.gz'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-tar.tar'))).to.be(false); - next(); - }) - .done(); + .get('/IndigoUnited/js-events-emitter/archive/0.1.0.tar.gz') + .replyWithFile( + 200, + path.resolve(__dirname, '../../assets/package-tar.tar.gz') + ); + + resolver = create({ + source: 'git://github.com/IndigoUnited/js-events-emitter.git', + target: '0.1.0' + }); + + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, '.bower.json'))).to.be( + true + ); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect( + fs.existsSync(path.join(dir, 'package-tar.tar.gz')) + ).to.be(false); + expect( + fs.existsSync(path.join(dir, 'package-tar.tar')) + ).to.be(false); + next(); + }) + .done(); }); - it('should retry using the GitRemoteResolver mechanism if download failed', function (next) { + it('should retry using the GitRemoteResolver mechanism if download failed', function(next) { this.timeout(20000); var resolver; var retried; nock('https://github.com') - .get('/IndigoUnited/js-events-emitter/archive/0.1.0.tar.gz') - .reply(200, 'this is not a valid tar'); + .get('/IndigoUnited/js-events-emitter/archive/0.1.0.tar.gz') + .reply(200, 'this is not a valid tar'); - logger.on('log', function (entry) { + logger.on('log', function(entry) { if (entry.level === 'warn' && entry.id === 'retry') { retried = true; } }); - resolver = create({ source: 'git://github.com/IndigoUnited/js-events-emitter.git', target: '0.1.0' }); + resolver = create({ + source: 'git://github.com/IndigoUnited/js-events-emitter.git', + target: '0.1.0' + }); // Monkey patch source to file:// resolver._source = 'file://' + testPackage; - resolver.resolve() - .then(function (dir) { - expect(retried).to.be(true); - expect(fs.existsSync(path.join(dir, 'foo'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); - next(); - }) - .done(); + resolver + .resolve() + .then(function(dir) { + expect(retried).to.be(true); + expect(fs.existsSync(path.join(dir, 'foo'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); + next(); + }) + .done(); }); - it('should retry using the GitRemoteResolver mechanism if extraction failed', function (next) { + it('should retry using the GitRemoteResolver mechanism if extraction failed', function(next) { this.timeout(20000); var resolver; var retried; nock('https://github.com') - .get('/IndigoUnited/js-events-emitter/archive/0.1.0.tar.gz') - .reply(500); + .get('/IndigoUnited/js-events-emitter/archive/0.1.0.tar.gz') + .reply(500); - logger.on('log', function (entry) { + logger.on('log', function(entry) { if (entry.level === 'warn' && entry.id === 'retry') { retried = true; } }); - resolver = create({ source: 'git://github.com/IndigoUnited/js-events-emitter.git', target: '0.1.0' }); + resolver = create({ + source: 'git://github.com/IndigoUnited/js-events-emitter.git', + target: '0.1.0' + }); // Monkey patch source to file:// resolver._source = 'file://' + testPackage; - resolver.resolve() - .then(function (dir) { - expect(retried).to.be(true); - expect(fs.existsSync(path.join(dir, 'foo'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); - next(); - }) - .done(); + resolver + .resolve() + .then(function(dir) { + expect(retried).to.be(true); + expect(fs.existsSync(path.join(dir, 'foo'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); + next(); + }) + .done(); }); - it('should fallback to the GitRemoteResolver mechanism if resolution is not a tag', function (next) { - var resolver = create({ source: 'git://github.com/foo/bar.git', target: '2af02ac6ddeaac1c2f4bead8d6287ce54269c039' }); + it('should fallback to the GitRemoteResolver mechanism if resolution is not a tag', function(next) { + var resolver = create({ + source: 'git://github.com/foo/bar.git', + target: '2af02ac6ddeaac1c2f4bead8d6287ce54269c039' + }); var originalCheckout = GitRemoteResolver.prototype._checkout; var called; - GitRemoteResolver.prototype._checkout = function () { + GitRemoteResolver.prototype._checkout = function() { called = true; return originalCheckout.apply(this, arguments); }; @@ -143,18 +177,19 @@ describe('GitHub', function () { // Monkey patch source to file:// resolver._source = 'file://' + testPackage; - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); - expect(called).to.be(true); - next(); - }) - .fin(function () { - GitRemoteResolver.prototype._checkout = originalCheckout; - }) - .done(); + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true); + expect(called).to.be(true); + next(); + }) + .fin(function() { + GitRemoteResolver.prototype._checkout = originalCheckout; + }) + .done(); }); it.skip('it should error out if the status code is not within 200-299'); @@ -162,7 +197,7 @@ describe('GitHub', function () { it.skip('should report progress if it takes too long to download'); }); - describe('._savePkgMeta', function () { + describe('._savePkgMeta', function() { it.skip('should guess the homepage if not already set'); }); }); diff --git a/test/core/resolvers/gitRemoteResolver.js b/test/core/resolvers/gitRemoteResolver.js index 30c7a0bd6..08095e770 100644 --- a/test/core/resolvers/gitRemoteResolver.js +++ b/test/core/resolvers/gitRemoteResolver.js @@ -9,15 +9,15 @@ var multiline = require('multiline').stripIndent; var GitRemoteResolver = require('../../../lib/core/resolvers/GitRemoteResolver'); var defaultConfig = require('../../../lib/config'); -describe('GitRemoteResolver', function () { +describe('GitRemoteResolver', function() { var testPackage = path.resolve(__dirname, '../../assets/package-a'); var logger; - before(function () { + before(function() { logger = new Logger(); }); - afterEach(function () { + afterEach(function() { logger.removeAllListeners(); }); @@ -33,8 +33,8 @@ describe('GitRemoteResolver', function () { return new GitRemoteResolver(decEndpoint, defaultConfig(), logger); } - describe('.constructor', function () { - it('should guess the name from the path', function () { + describe('.constructor', function() { + it('should guess the name from the path', function() { var resolver; resolver = create('file://' + testPackage); @@ -51,94 +51,132 @@ describe('GitRemoteResolver', function () { }); }); - describe('.resolve', function () { - it('should checkout correctly if resolution is a branch', function (next) { - var resolver = create({ source: 'file://' + testPackage, target: 'some-branch' }); + describe('.resolve', function() { + it('should checkout correctly if resolution is a branch', function(next) { + var resolver = create({ + source: 'file://' + testPackage, + target: 'some-branch' + }); - resolver.resolve() - .then(function (dir) { - expect(dir).to.be.a('string'); + resolver + .resolve() + .then(function(dir) { + expect(dir).to.be.a('string'); - var files = fs.readdirSync(dir); - var fooContents; + var files = fs.readdirSync(dir); + var fooContents; - expect(files).to.contain('foo'); - expect(files).to.contain('baz'); - expect(files).to.contain('baz'); + expect(files).to.contain('foo'); + expect(files).to.contain('baz'); + expect(files).to.contain('baz'); - fooContents = fs.readFileSync(path.join(dir, 'foo')).toString(); - expect(fooContents).to.equal('foo foo'); + fooContents = fs + .readFileSync(path.join(dir, 'foo')) + .toString(); + expect(fooContents).to.equal('foo foo'); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should checkout correctly if resolution is a tag', function (next) { - var resolver = create({ source: 'file://' + testPackage, target: '~0.0.1' }); + it('should checkout correctly if resolution is a tag', function(next) { + var resolver = create({ + source: 'file://' + testPackage, + target: '~0.0.1' + }); - resolver.resolve() - .then(function (dir) { - expect(dir).to.be.a('string'); + resolver + .resolve() + .then(function(dir) { + expect(dir).to.be.a('string'); - var files = fs.readdirSync(dir); + var files = fs.readdirSync(dir); - expect(files).to.contain('foo'); - expect(files).to.contain('bar'); - expect(files).to.not.contain('baz'); + expect(files).to.contain('foo'); + expect(files).to.contain('bar'); + expect(files).to.not.contain('baz'); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should checkout correctly if resolution is a commit', function (next) { - var resolver = create({ source: 'file://' + testPackage, target: 'bdf51ece75e20cf404e49286727b7e92d33e9ad0' }); + it('should checkout correctly if resolution is a commit', function(next) { + var resolver = create({ + source: 'file://' + testPackage, + target: 'bdf51ece75e20cf404e49286727b7e92d33e9ad0' + }); - resolver.resolve() - .then(function (dir) { - expect(dir).to.be.a('string'); + resolver + .resolve() + .then(function(dir) { + expect(dir).to.be.a('string'); - var files = fs.readdirSync(dir); + var files = fs.readdirSync(dir); - expect(files).to.not.contain('foo'); - expect(files).to.not.contain('bar'); - expect(files).to.not.contain('baz'); - expect(files).to.contain('.master'); - next(); - }) - .done(); + expect(files).to.not.contain('foo'); + expect(files).to.not.contain('bar'); + expect(files).to.not.contain('baz'); + expect(files).to.contain('.master'); + next(); + }) + .done(); }); - describe('shallow cloning', function () { + describe('shallow cloning', function() { var gitRemoteResolverFactory; - beforeEach(function () { - gitRemoteResolverFactory = function (handler) { - return helpers.require('lib/core/resolvers/GitRemoteResolver', { - '../../util/cmd': handler - }); + beforeEach(function() { + gitRemoteResolverFactory = function(handler) { + return helpers.require( + 'lib/core/resolvers/GitRemoteResolver', + { + '../../util/cmd': handler + } + ); }; }); - it('should add --depth=1 when shallow cloning is supported', function (next) { + it('should add --depth=1 when shallow cloning is supported', function(next) { var testSource = 'http://foo/bar.git'; - var MyGitRemoteResolver = gitRemoteResolverFactory(function (cmd, args) { + var MyGitRemoteResolver = gitRemoteResolverFactory(function( + cmd, + args + ) { // The first git call fetches the tags for the provided source - if (mout.array.equals(args, ['ls-remote', '--tags', '--heads', testSource])) { + if ( + mout.array.equals(args, [ + 'ls-remote', + '--tags', + '--heads', + testSource + ]) + ) { // Return list of commits, including one tag. // The tag will be used for the clone call. - return Q.all([multiline(function () {/* + return Q.all([ + multiline(function() { + /* e4655d250f2a3f64ef2d712f25dafa60652bb93e refs/heads/some-branch 0a7daf646d4fd743b6ef701d63bdbe20eee422de refs/tags/0.0.1 */ - })]); - } - else if (args[0] === 'clone') { + }) + ]); + } else if (args[0] === 'clone') { // Verify parameters of the clone call. // In this case, the arguments need to contain "--depth 1". - expect(args).to.eql(['clone', 'http://foo/bar.git', '-b', '0.0.1', '--progress', '.', '--depth', 1]); + expect(args).to.eql([ + 'clone', + 'http://foo/bar.git', + '-b', + '0.0.1', + '--progress', + '.', + '--depth', + 1 + ]); // In this case, only the stderr content is evaluated. Everything's fine as long as it // does not contain any error description. @@ -147,35 +185,58 @@ describe('GitRemoteResolver', function () { }); // Mock the call, return true for this test. - MyGitRemoteResolver.prototype._supportsShallowCloning = function () { + MyGitRemoteResolver.prototype._supportsShallowCloning = function() { return Q.resolve(true); }; - var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + var resolver = new MyGitRemoteResolver( + { source: testSource }, + defaultConfig(), + logger + ); - resolver.resolve().then(function () { + resolver.resolve().then(function() { next(); }); }); - it('should not add --depth=1 when shallow cloning is not supported', function (next) { + it('should not add --depth=1 when shallow cloning is not supported', function(next) { var testSource = 'http://foo/bar.git'; - var MyGitRemoteResolver = gitRemoteResolverFactory(function (cmd, args) { + var MyGitRemoteResolver = gitRemoteResolverFactory(function( + cmd, + args + ) { // The first git call fetches the tags for the provided source - if (mout.array.equals(args, ['ls-remote', '--tags', '--heads', testSource])) { + if ( + mout.array.equals(args, [ + 'ls-remote', + '--tags', + '--heads', + testSource + ]) + ) { // Return list of commits, including one tag. // The tag will be used for the clone call. - return Q.all([multiline(function () {/* + return Q.all([ + multiline(function() { + /* e4655d250f2a3f64ef2d712f25dafa60652bb93e refs/heads/some-branch 0a7daf646d4fd743b6ef701d63bdbe20eee422de refs/tags/0.0.1 */ - })]); - } - else if (args[0] === 'clone') { + }) + ]); + } else if (args[0] === 'clone') { // Verify parameters of the clone call. // In this case, the arguments should not contain "--depth 1". - expect(args).to.eql(['clone', 'http://foo/bar.git', '-b', '0.0.1', '--progress', '.']); + expect(args).to.eql([ + 'clone', + 'http://foo/bar.git', + '-b', + '0.0.1', + '--progress', + '.' + ]); // In this case, only the stderr content is evaluated. Everything's fine as long as it // does not contain any error description. @@ -184,80 +245,86 @@ describe('GitRemoteResolver', function () { }); // Mock the call, return false for this test. - MyGitRemoteResolver.prototype._supportsShallowCloning = function () { + MyGitRemoteResolver.prototype._supportsShallowCloning = function() { return Q.resolve(false); }; - var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + var resolver = new MyGitRemoteResolver( + { source: testSource }, + defaultConfig(), + logger + ); - resolver.resolve().then(function () { + resolver.resolve().then(function() { next(); }); }); }); - it.skip('should handle gracefully servers that do not support --depth=1'); + it.skip( + 'should handle gracefully servers that do not support --depth=1' + ); it.skip('should report progress when it takes too long to clone'); }); - describe('#refs', function () { + describe('#refs', function() { afterEach(clearResolverRuntimeCache); - it('should resolve to the references of the remote repository', function (next) { + it('should resolve to the references of the remote repository', function(next) { GitRemoteResolver.refs('file://' + testPackage) - .then(function (refs) { - // Remove master and test only for the first 7 refs - refs = refs.slice(1, 8); - - expect(refs).to.eql([ - 'e4655d250f2a3f64ef2d712f25dafa60652bb93e refs/heads/some-branch', - '0a7daf646d4fd743b6ef701d63bdbe20eee422de refs/tags/0.0.1', - '0791865e6f4b88f69fc35167a09a6f0626627765 refs/tags/0.0.2', - '2af02ac6ddeaac1c2f4bead8d6287ce54269c039 refs/tags/0.1.0', - '6ab264f1ba5bafa80fb0198183493e4d5b20804a refs/tags/0.1.1', - 'c91ed7facbb695510e3e1ab86bac8b5ac159f4f3 refs/tags/0.2.0', - '8556e55c65722a351ca5fdce4f1ebe83ec3f2365 refs/tags/0.2.1' - ]); - next(); - }) - .done(); + .then(function(refs) { + // Remove master and test only for the first 7 refs + refs = refs.slice(1, 8); + + expect(refs).to.eql([ + 'e4655d250f2a3f64ef2d712f25dafa60652bb93e refs/heads/some-branch', + '0a7daf646d4fd743b6ef701d63bdbe20eee422de refs/tags/0.0.1', + '0791865e6f4b88f69fc35167a09a6f0626627765 refs/tags/0.0.2', + '2af02ac6ddeaac1c2f4bead8d6287ce54269c039 refs/tags/0.1.0', + '6ab264f1ba5bafa80fb0198183493e4d5b20804a refs/tags/0.1.1', + 'c91ed7facbb695510e3e1ab86bac8b5ac159f4f3 refs/tags/0.2.0', + '8556e55c65722a351ca5fdce4f1ebe83ec3f2365 refs/tags/0.2.1' + ]); + next(); + }) + .done(); }); - it('should cache the results', function (next) { + it('should cache the results', function(next) { var source = 'file://' + testPackage; GitRemoteResolver.refs(source) - .then(function () { - // Manipulate the cache and check if it resolves for the cached ones - GitRemoteResolver._cache.refs.get(source).splice(0, 1); - - // Check if it resolver to the same array - return GitRemoteResolver.refs('file://' + testPackage); - }) - .then(function (refs) { - // Test only for the first 7 refs - refs = refs.slice(0, 7); - - expect(refs).to.eql([ - 'e4655d250f2a3f64ef2d712f25dafa60652bb93e refs/heads/some-branch', - '0a7daf646d4fd743b6ef701d63bdbe20eee422de refs/tags/0.0.1', - '0791865e6f4b88f69fc35167a09a6f0626627765 refs/tags/0.0.2', - '2af02ac6ddeaac1c2f4bead8d6287ce54269c039 refs/tags/0.1.0', - '6ab264f1ba5bafa80fb0198183493e4d5b20804a refs/tags/0.1.1', - 'c91ed7facbb695510e3e1ab86bac8b5ac159f4f3 refs/tags/0.2.0', - '8556e55c65722a351ca5fdce4f1ebe83ec3f2365 refs/tags/0.2.1' - ]); - next(); - }) - .done(); + .then(function() { + // Manipulate the cache and check if it resolves for the cached ones + GitRemoteResolver._cache.refs.get(source).splice(0, 1); + + // Check if it resolver to the same array + return GitRemoteResolver.refs('file://' + testPackage); + }) + .then(function(refs) { + // Test only for the first 7 refs + refs = refs.slice(0, 7); + + expect(refs).to.eql([ + 'e4655d250f2a3f64ef2d712f25dafa60652bb93e refs/heads/some-branch', + '0a7daf646d4fd743b6ef701d63bdbe20eee422de refs/tags/0.0.1', + '0791865e6f4b88f69fc35167a09a6f0626627765 refs/tags/0.0.2', + '2af02ac6ddeaac1c2f4bead8d6287ce54269c039 refs/tags/0.1.0', + '6ab264f1ba5bafa80fb0198183493e4d5b20804a refs/tags/0.1.1', + 'c91ed7facbb695510e3e1ab86bac8b5ac159f4f3 refs/tags/0.2.0', + '8556e55c65722a351ca5fdce4f1ebe83ec3f2365 refs/tags/0.2.1' + ]); + next(); + }) + .done(); }); }); - describe('#_supportsShallowCloning', function () { + describe('#_supportsShallowCloning', function() { var gitRemoteResolverFactory; - beforeEach(function () { - gitRemoteResolverFactory = function (handler) { + beforeEach(function() { + gitRemoteResolverFactory = function(handler) { return helpers.require('lib/core/resolvers/GitRemoteResolver', { '../../util/cmd': handler }); @@ -265,257 +332,359 @@ describe('GitRemoteResolver', function () { }); function createCmdHandlerFn(testSource, stderr) { - return function (cmd, args, options) { + return function(cmd, args, options) { expect(cmd).to.be('git'); - expect(args).to.eql([ 'ls-remote', '--heads', testSource ]); + expect(args).to.eql(['ls-remote', '--heads', testSource]); expect(options.env.GIT_CURL_VERBOSE).to.be('2'); return Q.all(['stdout', stderr]); }; } - it('should call ls-remote when using http protocol', function (next) { + it('should call ls-remote when using http protocol', function(next) { var testSource = 'http://foo/bar.git'; var MyGitRemoteResolver = gitRemoteResolverFactory( - createCmdHandlerFn(testSource, multiline(function () {/* + createCmdHandlerFn( + testSource, + multiline(function() { + /* foo: bar Content-Type: none 1234: 5678 - */})) + */ + }) + ) ); - var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); + var resolver = new MyGitRemoteResolver( + { source: testSource }, + defaultConfig({ shallowCloneHosts: ['foo'] }), + logger + ); - resolver._shallowClone().then(function (shallowCloningSupported) { + resolver._shallowClone().then(function(shallowCloningSupported) { expect(shallowCloningSupported).to.be(false); next(); }); }); - it('should call ls-remote when using https protocol', function (next) { + it('should call ls-remote when using https protocol', function(next) { var testSource = 'https://foo/bar.git'; var MyGitRemoteResolver = gitRemoteResolverFactory( - createCmdHandlerFn(testSource, multiline(function () {/* + createCmdHandlerFn( + testSource, + multiline(function() { + /* foo: bar Content-Type: none 1234: 5678 - */})) + */ + }) + ) ); - var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); + var resolver = new MyGitRemoteResolver( + { source: testSource }, + defaultConfig({ shallowCloneHosts: ['foo'] }), + logger + ); - resolver._shallowClone().then(function (shallowCloningSupported) { + resolver._shallowClone().then(function(shallowCloningSupported) { expect(shallowCloningSupported).to.be(false); next(); }); }); - it('should evaluate to false when the URL can not be parsed', function (next) { + it('should evaluate to false when the URL can not be parsed', function(next) { var testSource = 'grmblfjx///:::.git'; var MyGitRemoteResolver = gitRemoteResolverFactory( - createCmdHandlerFn(testSource, multiline(function () {/* + createCmdHandlerFn( + testSource, + multiline(function() { + /* foo: bar Content-Type: none 1234: 5678 - */})) + */ + }) + ) ); - var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig(), logger); + var resolver = new MyGitRemoteResolver( + { source: testSource }, + defaultConfig(), + logger + ); - resolver._shallowClone().then(function (shallowCloningSupported) { - expect(shallowCloningSupported).to.be(false); + resolver._shallowClone().then( + function(shallowCloningSupported) { + expect(shallowCloningSupported).to.be(false); - next(); - }, function (err) { - next(err); - }); + next(); + }, + function(err) { + next(err); + } + ); }); - it('should evaluate to true when the smart content type is returned', function (next) { + it('should evaluate to true when the smart content type is returned', function(next) { var testSource = 'https://foo/bar.git'; var MyGitRemoteResolver = gitRemoteResolverFactory( - createCmdHandlerFn(testSource, multiline(function () {/* + createCmdHandlerFn( + testSource, + multiline(function() { + /* foo: bar Content-Type: application/x-git-upload-pack-advertisement 1234: 5678 - */})) + */ + }) + ) ); - var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); + var resolver = new MyGitRemoteResolver( + { source: testSource }, + defaultConfig({ shallowCloneHosts: ['foo'] }), + logger + ); - resolver._shallowClone().then(function (shallowCloningSupported) { + resolver._shallowClone().then(function(shallowCloningSupported) { expect(shallowCloningSupported).to.be(true); next(); }); }); - it('should evaluate to true when source is a ssh protocol and host is defined to support shallow cloning', function (next) { + it('should evaluate to true when source is a ssh protocol and host is defined to support shallow cloning', function(next) { var testSource = 'git@foo:bar.git'; var MyGitRemoteResolver = gitRemoteResolverFactory( - createCmdHandlerFn(testSource, multiline(function () {/* + createCmdHandlerFn( + testSource, + multiline(function() { + /* foo: bar Content-Type: application/x-git-upload-pack-advertisement 1234: 5678 - */})) + */ + }) + ) ); - var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); + var resolver = new MyGitRemoteResolver( + { source: testSource }, + defaultConfig({ shallowCloneHosts: ['foo'] }), + logger + ); - resolver._shallowClone().then(function (shallowCloningSupported) { + resolver._shallowClone().then(function(shallowCloningSupported) { expect(shallowCloningSupported).to.be(true); next(); }); }); - it('should cache hosts that support shallow cloning', function (next) { + it('should cache hosts that support shallow cloning', function(next) { var testSource = 'https://foo/bar.git'; var counter = 0; - var MyGitRemoteResolver = gitRemoteResolverFactory( - function (cmd, args, options) { - counter++; - - if (counter === 1) { - expect(cmd).to.be('git'); - expect(args).to.eql([ 'ls-remote', '--heads', testSource ]); - expect(options.env.GIT_CURL_VERBOSE).to.be('2'); - - return Q.all(['stdout', multiline(function () {/* + var MyGitRemoteResolver = gitRemoteResolverFactory(function( + cmd, + args, + options + ) { + counter++; + + if (counter === 1) { + expect(cmd).to.be('git'); + expect(args).to.eql(['ls-remote', '--heads', testSource]); + expect(options.env.GIT_CURL_VERBOSE).to.be('2'); + + return Q.all([ + 'stdout', + multiline(function() { + /* foo: bar Content-Type: application/x-git-upload-pack-advertisement 1234: 5678 */ - })]); - } - else { - return Q.reject(new Error('More calls than expected')); - } + }) + ]); + } else { + return Q.reject(new Error('More calls than expected')); } - ); + }); - var resolver = new MyGitRemoteResolver({ source: testSource }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); + var resolver = new MyGitRemoteResolver( + { source: testSource }, + defaultConfig({ shallowCloneHosts: ['foo'] }), + logger + ); - resolver._shallowClone().then(function (shallowCloningSupported) { + resolver._shallowClone().then(function(shallowCloningSupported) { expect(shallowCloningSupported).to.be(true); - var resolver2 = new MyGitRemoteResolver({ source: testSource }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); + var resolver2 = new MyGitRemoteResolver( + { source: testSource }, + defaultConfig({ shallowCloneHosts: ['foo'] }), + logger + ); - resolver2._shallowClone().then(function (shallowCloningSupported) { - expect(shallowCloningSupported).to.be(true); + resolver2._shallowClone().then( + function(shallowCloningSupported) { + expect(shallowCloningSupported).to.be(true); - next(); - }, function (err) { - next(err); - }); + next(); + }, + function(err) { + next(err); + } + ); }); }); - it('should cache hosts that support shallow cloning across multiple repos', function (next) { + it('should cache hosts that support shallow cloning across multiple repos', function(next) { var testSource1 = 'https://foo/bar.git'; var testSource2 = 'https://foo/barbaz.git'; var counter = 0; - var MyGitRemoteResolver = gitRemoteResolverFactory( - function (cmd, args, options) { - counter++; - - if (counter === 1) { - expect(cmd).to.be('git'); - expect(args).to.eql([ 'ls-remote', '--heads', testSource1 ]); - expect(options.env.GIT_CURL_VERBOSE).to.be('2'); - - return Q.all(['stdout', multiline(function () {/* + var MyGitRemoteResolver = gitRemoteResolverFactory(function( + cmd, + args, + options + ) { + counter++; + + if (counter === 1) { + expect(cmd).to.be('git'); + expect(args).to.eql(['ls-remote', '--heads', testSource1]); + expect(options.env.GIT_CURL_VERBOSE).to.be('2'); + + return Q.all([ + 'stdout', + multiline(function() { + /* foo: bar Content-Type: application/x-git-upload-pack-advertisement 1234: 5678 */ - })]); - } - else { - return Q.reject(new Error('More calls than expected')); - } + }) + ]); + } else { + return Q.reject(new Error('More calls than expected')); } - ); + }); - var resolver = new MyGitRemoteResolver({ source: testSource1 }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); + var resolver = new MyGitRemoteResolver( + { source: testSource1 }, + defaultConfig({ shallowCloneHosts: ['foo'] }), + logger + ); - resolver._shallowClone().then(function (shallowCloningSupported) { + resolver._shallowClone().then(function(shallowCloningSupported) { expect(shallowCloningSupported).to.be(true); - var resolver2 = new MyGitRemoteResolver({ source: testSource2 }, defaultConfig({ shallowCloneHosts: ['foo'] }), logger); + var resolver2 = new MyGitRemoteResolver( + { source: testSource2 }, + defaultConfig({ shallowCloneHosts: ['foo'] }), + logger + ); - resolver2._shallowClone().then(function (shallowCloningSupported) { - expect(shallowCloningSupported).to.be(true); + resolver2._shallowClone().then( + function(shallowCloningSupported) { + expect(shallowCloningSupported).to.be(true); - next(); - }, function (err) { - next(err); - }); + next(); + }, + function(err) { + next(err); + } + ); }); }); - it('should run separate checks for separate hosts ', function (next) { + it('should run separate checks for separate hosts ', function(next) { var testSource1 = 'https://foo/bar.git'; var testSource2 = 'https://foo.bar.baz/barbaz.git'; var counter = 0; - var MyGitRemoteResolver = gitRemoteResolverFactory( - function (cmd, args, options) { - counter++; - - if (counter === 1) { - expect(cmd).to.be('git'); - expect(args).to.eql([ 'ls-remote', '--heads', testSource1 ]); - expect(options.env.GIT_CURL_VERBOSE).to.be('2'); - - return Q.all(['stdout', multiline(function () {/* + var MyGitRemoteResolver = gitRemoteResolverFactory(function( + cmd, + args, + options + ) { + counter++; + + if (counter === 1) { + expect(cmd).to.be('git'); + expect(args).to.eql(['ls-remote', '--heads', testSource1]); + expect(options.env.GIT_CURL_VERBOSE).to.be('2'); + + return Q.all([ + 'stdout', + multiline(function() { + /* foo: bar Content-Type: application/x-git-upload-pack-advertisement 1234: 5678 */ - })]); - } - else { - expect(cmd).to.be('git'); - expect(args).to.eql([ 'ls-remote', '--heads', testSource2 ]); - expect(options.env.GIT_CURL_VERBOSE).to.be('2'); - - return Q.all(['stdout', multiline(function () {/* + }) + ]); + } else { + expect(cmd).to.be('git'); + expect(args).to.eql(['ls-remote', '--heads', testSource2]); + expect(options.env.GIT_CURL_VERBOSE).to.be('2'); + + return Q.all([ + 'stdout', + multiline(function() { + /* foo: barbaz Content-Type: application/x-git-upload-pack-advertisement 1234: 5678 */ - })]); - } + }) + ]); } - ); + }); - var resolver = new MyGitRemoteResolver({ source: testSource1 }, defaultConfig({ shallowCloneHosts: ['foo', 'foo.bar.baz'] }), logger); + var resolver = new MyGitRemoteResolver( + { source: testSource1 }, + defaultConfig({ shallowCloneHosts: ['foo', 'foo.bar.baz'] }), + logger + ); - resolver._shallowClone().then(function (shallowCloningSupported) { + resolver._shallowClone().then(function(shallowCloningSupported) { expect(shallowCloningSupported).to.be(true); - var resolver2 = new MyGitRemoteResolver({ source: testSource2 }, defaultConfig({ shallowCloneHosts: ['foo', 'foo.bar.baz'] }), logger); - - resolver2._shallowClone().then(function (shallowCloningSupported) { - expect(shallowCloningSupported).to.be(true); - - next(); - }, function (err) { - next(err); - }); + var resolver2 = new MyGitRemoteResolver( + { source: testSource2 }, + defaultConfig({ + shallowCloneHosts: ['foo', 'foo.bar.baz'] + }), + logger + ); + + resolver2._shallowClone().then( + function(shallowCloningSupported) { + expect(shallowCloningSupported).to.be(true); + + next(); + }, + function(err) { + next(err); + } + ); }); }); }); diff --git a/test/core/resolvers/gitResolver.js b/test/core/resolvers/gitResolver.js index 92a4242e0..73699fed8 100644 --- a/test/core/resolvers/gitResolver.js +++ b/test/core/resolvers/gitResolver.js @@ -12,17 +12,17 @@ var copy = require('../../../lib/util/copy'); var GitResolver = require('../../../lib/core/resolvers/GitResolver'); var defaultConfig = require('../../../lib/config'); -describe('GitResolver', function () { +describe('GitResolver', function() { var tempDir = path.resolve(__dirname, '../../tmp/tmp'); var originalrefs = GitResolver.refs; var originalEnv = process.env; var logger; - before(function () { + before(function() { logger = new Logger(); }); - afterEach(function () { + afterEach(function() { logger.removeAllListeners(); process.env = originalEnv; }); @@ -40,46 +40,53 @@ describe('GitResolver', function () { return new GitResolver(decEndpoint, defaultConfig(), logger); } - describe('misc', function () { + describe('misc', function() { it.skip('should error out if git is not installed'); it.skip('should setup git template dir to an empty folder'); - it('should set process.env.GIT_SSL_NO_VERIFY when strictSSL is false', function () { + it('should set process.env.GIT_SSL_NO_VERIFY when strictSSL is false', function() { var resolver; - var decEndpoint = { source: 'foo'}; + var decEndpoint = { source: 'foo' }; expect(process.env).to.not.have.property('GIT_SSL_NO_VERIFY'); resolver = new GitResolver(decEndpoint, defaultConfig(), logger); expect(process.env).to.not.have.property('GIT_SSL_NO_VERIFY'); - resolver = new GitResolver(decEndpoint, defaultConfig({strictSsl: false}), logger); + resolver = new GitResolver( + decEndpoint, + defaultConfig({ strictSsl: false }), + logger + ); expect(process.env).to.have.property('GIT_SSL_NO_VERIFY', 'true'); delete process.env.GIT_SSL_NO_VERIFY; // git only checks the existence of GIT_SSL_NO_VERIFY. // git does NOT check whether is true of false. // Hence not exporting GIT_SSL_NO_VERIFY is effectively equivalent to 'false' - resolver = new GitResolver(decEndpoint, defaultConfig({strictSsl: true}), logger); + resolver = new GitResolver( + decEndpoint, + defaultConfig({ strictSsl: true }), + logger + ); expect(process.env).to.not.have.property('GIT_SSL_NO_VERIFY'); }); }); - describe('.hasNew', function () { - before(function () { + describe('.hasNew', function() { + before(function() { mkdirp.sync(tempDir); }); - afterEach(function (next) { + afterEach(function(next) { clearResolverRuntimeCache(); rimraf(path.join(tempDir, '.bower.json'), next); }); - after(function (next) { + after(function(next) { rimraf(tempDir, next); }); - - it('should be true when the resolution type is different', function (next) { + it('should be true when the resolution type is different', function(next) { var resolver; var pkgMeta = { @@ -92,22 +99,23 @@ describe('GitResolver', function () { } }; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ - 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/master' // same commit hash on purpose + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/master' // same commit hash on purpose ]); }; resolver = create('foo'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(true); - next(); - }) - .done(); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); }); - it('should be true when a higher version for a range is available', function (next) { + it('should be true when a higher version for a range is available', function(next) { var resolver; var pkgMeta = { @@ -120,24 +128,25 @@ describe('GitResolver', function () { } }; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/1.0.0', - 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/1.0.1' // same commit hash on purpose + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/1.0.1' // same commit hash on purpose ]); }; resolver = create('foo'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(true); - next(); - }) - .done(); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); }); - it('should be true when a resolved to a lower version of a range', function (next) { + it('should be true when a resolved to a lower version of a range', function(next) { var resolver; var pkgMeta = { @@ -150,7 +159,7 @@ describe('GitResolver', function () { } }; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/1.0.0' @@ -158,15 +167,16 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(true); - next(); - }) - .done(); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); }); - it('should be false when resolved to the same tag (with same commit hash) for a given range', function (next) { + it('should be false when resolved to the same tag (with same commit hash) for a given range', function(next) { var resolver; var pkgMeta = { @@ -179,7 +189,7 @@ describe('GitResolver', function () { } }; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/1.0.0', @@ -188,15 +198,16 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(false); - next(); - }) - .done(); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(false); + next(); + }) + .done(); }); - it('should be true when resolved to the same tag (with different commit hash) for a given range', function (next) { + it('should be true when resolved to the same tag (with different commit hash) for a given range', function(next) { var resolver; var pkgMeta = { @@ -209,7 +220,7 @@ describe('GitResolver', function () { } }; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/1.0.0', @@ -218,15 +229,16 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(true); - next(); - }) - .done(); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); }); - it('should be true when a different commit hash for a given branch is available', function (next) { + it('should be true when a different commit hash for a given branch is available', function(next) { var resolver; var pkgMeta = { @@ -238,22 +250,23 @@ describe('GitResolver', function () { } }; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/master' ]); }; resolver = create('foo'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(true); - next(); - }) - .done(); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); }); - it('should be false when resolved to the the same commit hash for a given branch', function (next) { + it('should be false when resolved to the the same commit hash for a given branch', function(next) { var resolver; var pkgMeta = { @@ -265,22 +278,23 @@ describe('GitResolver', function () { } }; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master' ]); }; resolver = create('foo'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(false); - next(); - }) - .done(); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(false); + next(); + }) + .done(); }); - it('should be false when targeting commit hashes', function (next) { + it('should be false when targeting commit hashes', function(next) { var resolver; var pkgMeta = { @@ -291,26 +305,27 @@ describe('GitResolver', function () { } }; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/master' ]); }; resolver = create('foo'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(true); - next(); - }) - .done(); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); }); }); - describe('._resolve', function () { + describe('._resolve', function() { afterEach(clearResolverRuntimeCache); - it('should call the necessary functions by the correct order', function (next) { + it('should call the necessary functions by the correct order', function(next) { var resolver; function DummyResolver() { @@ -321,150 +336,179 @@ describe('GitResolver', function () { util.inherits(DummyResolver, GitResolver); mout.object.mixIn(DummyResolver, GitResolver); - DummyResolver.prototype.getStack = function () { + DummyResolver.prototype.getStack = function() { return this._stack; }; - DummyResolver.refs = function () { + DummyResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master' ]); }; - DummyResolver.prototype.resolve = function () { + DummyResolver.prototype.resolve = function() { this._stack = []; return GitResolver.prototype.resolve.apply(this, arguments); }; - DummyResolver.prototype._findResolution = function () { + DummyResolver.prototype._findResolution = function() { this._stack.push('before _findResolution'); - return GitResolver.prototype._findResolution.apply(this, arguments) - .then(function (val) { - this._stack.push('after _findResolution'); - return val; - }.bind(this)); + return GitResolver.prototype._findResolution + .apply(this, arguments) + .then( + function(val) { + this._stack.push('after _findResolution'); + return val; + }.bind(this) + ); }; - DummyResolver.prototype._checkout = function () { + DummyResolver.prototype._checkout = function() { this._stack.push('before _checkout'); - return Q.resolve() - .then(function (val) { - this._stack.push('after _checkout'); - return val; - }.bind(this)); + return Q.resolve().then( + function(val) { + this._stack.push('after _checkout'); + return val; + }.bind(this) + ); }; - DummyResolver.prototype._cleanup = function () { + DummyResolver.prototype._cleanup = function() { this._stack.push('before _cleanup'); - return GitResolver.prototype._cleanup.apply(this, arguments) - .then(function (val) { - this._stack.push('after _cleanup'); - return val; - }.bind(this)); + return GitResolver.prototype._cleanup + .apply(this, arguments) + .then( + function(val) { + this._stack.push('after _cleanup'); + return val; + }.bind(this) + ); }; - resolver = new DummyResolver({ source: 'foo', target: 'master' }, defaultConfig(), logger); - - resolver.resolve() - .then(function () { - expect(resolver.getStack()).to.eql([ - 'before _findResolution', - 'after _findResolution', - 'before _checkout', - 'after _checkout', - 'before _cleanup', - 'after _cleanup' - ]); - next(); - }) - .done(); + resolver = new DummyResolver( + { source: 'foo', target: 'master' }, + defaultConfig(), + logger + ); + + resolver + .resolve() + .then(function() { + expect(resolver.getStack()).to.eql([ + 'before _findResolution', + 'after _findResolution', + 'before _checkout', + 'after _checkout', + 'before _cleanup', + 'after _cleanup' + ]); + next(); + }) + .done(); }); - it('should reject the promise if _checkout is not implemented', function (next) { + it('should reject the promise if _checkout is not implemented', function(next) { var resolver = create('foo'); - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master' ]); }; - resolver.resolve() - .then(function () { - next(new Error('Should have rejected the promise')); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.message).to.contain('_checkout not implemented'); - next(); - }) - .done(); - }); - - it('should reject the promise if #refs is not implemented', function (next) { + resolver + .resolve() + .then( + function() { + next(new Error('Should have rejected the promise')); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.message).to.contain( + '_checkout not implemented' + ); + next(); + } + ) + .done(); + }); + + it('should reject the promise if #refs is not implemented', function(next) { var resolver = create('foo'); - resolver._checkout = function () { + resolver._checkout = function() { return Q.resolve(); }; - resolver.resolve() - .then(function () { - next(new Error('Should have rejected the promise')); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.message).to.contain('refs not implemented'); - next(); - }) - .done(); + resolver + .resolve() + .then( + function() { + next(new Error('Should have rejected the promise')); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.message).to.contain('refs not implemented'); + next(); + } + ) + .done(); }); }); - describe('._findResolution', function () { + describe('._findResolution', function() { afterEach(clearResolverRuntimeCache); - it('should resolve to an object', function (next) { + it('should resolve to an object', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master' ]); }; resolver = create('foo'); - resolver._findResolution('*') - .then(function (resolution) { - expect(resolution).to.be.an('object'); - next(); - }) - .done(); + resolver + ._findResolution('*') + .then(function(resolution) { + expect(resolution).to.be.an('object'); + next(); + }) + .done(); }); - it('should fail to resolve * if no tags/heads are found', function (next) { + it('should fail to resolve * if no tags/heads are found', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([]); }; resolver = create('foo'); - resolver._findResolution('*') - .then(function () { - next(new Error('Should have failed')); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.message).to.match(/branch master does not exist/i); - expect(err.details).to.match(/no branches found/i); - expect(err.code).to.equal('ENORESTARGET'); - next(); - }) - .done(); - }); - - it('should resolve "*" to the latest commit on master if a repository has no valid semver tags', function (next) { + resolver + ._findResolution('*') + .then( + function() { + next(new Error('Should have failed')); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.message).to.match( + /branch master does not exist/i + ); + expect(err.details).to.match(/no branches found/i); + expect(err.code).to.equal('ENORESTARGET'); + next(); + } + ) + .done(); + }); + + it('should resolve "*" to the latest commit on master if a repository has no valid semver tags', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/some-branch', @@ -473,72 +517,75 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('*') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'branch', - branch: 'master', - commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' - }); - next(); - }) - .done(); + resolver + ._findResolution('*') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'branch', + branch: 'master', + commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + }); + next(); + }) + .done(); }); - it('should resolve "*" to the latest version if a repository has valid semver tags, ignoring pre-releases', function (next) { + it('should resolve "*" to the latest version if a repository has valid semver tags, ignoring pre-releases', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.1.0', 'cccccccccccccccccccccccccccccccccccccccc refs/tags/v0.1.1', - 'dddddddddddddddddddddddddddddddddddddddd refs/tags/0.2.0-rc.1' // Should ignore release candidates + 'dddddddddddddddddddddddddddddddddddddddd refs/tags/0.2.0-rc.1' // Should ignore release candidates ]); }; resolver = create('foo'); - resolver._findResolution('*') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'version', - tag: 'v0.1.1', - commit: 'cccccccccccccccccccccccccccccccccccccccc' - }); - next(); - }) - .done(); + resolver + ._findResolution('*') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: 'v0.1.1', + commit: 'cccccccccccccccccccccccccccccccccccccccc' + }); + next(); + }) + .done(); }); - it('should resolve "0.1.*" to the latest version if a repository has valid semver tags, ignoring pre-releases', function (next) { + it('should resolve "0.1.*" to the latest version if a repository has valid semver tags, ignoring pre-releases', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.1.0', 'cccccccccccccccccccccccccccccccccccccccc refs/tags/v0.1.1', - 'dddddddddddddddddddddddddddddddddddddddd refs/tags/0.1.2-rc.1' // Should ignore release candidates + 'dddddddddddddddddddddddddddddddddddddddd refs/tags/0.1.2-rc.1' // Should ignore release candidates ]); }; resolver = create('foo'); - resolver._findResolution('0.1.*') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'version', - tag: 'v0.1.1', - commit: 'cccccccccccccccccccccccccccccccccccccccc' - }); - next(); - }) - .done(); + resolver + ._findResolution('0.1.*') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: 'v0.1.1', + commit: 'cccccccccccccccccccccccccccccccccccccccc' + }); + next(); + }) + .done(); }); - it('should resolve "*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { + it('should resolve "*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.1.0-rc.1', @@ -547,22 +594,23 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('*') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'version', - tag: '0.1.0-rc.2', - commit: 'cccccccccccccccccccccccccccccccccccccccc' - }); - next(); - }) - .done(); + resolver + ._findResolution('*') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: '0.1.0-rc.2', + commit: 'cccccccccccccccccccccccccccccccccccccccc' + }); + next(); + }) + .done(); }); - it('should resolve "0.1.*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { + it('should resolve "0.1.*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.1.0-rc.1', @@ -571,22 +619,23 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('0.1.*') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'version', - tag: '0.1.0-rc.2', - commit: 'cccccccccccccccccccccccccccccccccccccccc' - }); - next(); - }) - .done(); + resolver + ._findResolution('0.1.*') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: '0.1.0-rc.2', + commit: 'cccccccccccccccccccccccccccccccccccccccc' + }); + next(); + }) + .done(); }); - it('should resolve to the latest version that matches a range/version', function (next) { + it('should resolve to the latest version that matches a range/version', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.1.0', @@ -597,23 +646,24 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('~0.2.0') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'version', - tag: 'v0.2.1', - commit: 'ffffffffffffffffffffffffffffffffffffffff' - }); - next(); - }) - .done(); + resolver + ._findResolution('~0.2.0') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: 'v0.2.1', + commit: 'ffffffffffffffffffffffffffffffffffffffff' + }); + next(); + }) + .done(); }); - it('should resolve to a branch even if target is a range/version that does not exist', function (next) { + it('should resolve to a branch even if target is a range/version that does not exist', function(next) { var resolver; // See #771 - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/3.0.0-wip', @@ -622,22 +672,23 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('3.0.0-wip') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'branch', - branch: '3.0.0-wip', - commit: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' - }); - next(); - }) - .done(); + resolver + ._findResolution('3.0.0-wip') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'branch', + branch: '3.0.0-wip', + commit: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + }); + next(); + }) + .done(); }); - it('should resolve to a tag even if target is a range that does not exist', function (next) { + it('should resolve to a tag even if target is a range that does not exist', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/1.0' @@ -645,22 +696,23 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('1.0') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'tag', - tag: '1.0', - commit: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' - }); - next(); - }) - .done(); + resolver + ._findResolution('1.0') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'tag', + tag: '1.0', + commit: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + }); + next(); + }) + .done(); }); - it('should resolve to the latest pre-release version that matches a range/version', function (next) { + it('should resolve to the latest pre-release version that matches a range/version', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.1.0', @@ -671,22 +723,23 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('~0.2.1') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'version', - tag: 'v0.2.1-rc.1', - commit: 'ffffffffffffffffffffffffffffffffffffffff' - }); - next(); - }) - .done(); + resolver + ._findResolution('~0.2.1') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: 'v0.2.1-rc.1', + commit: 'ffffffffffffffffffffffffffffffffffffffff' + }); + next(); + }) + .done(); }); - it('should resolve to the exact version if exists', function (next) { + it('should resolve to the exact version if exists', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.8.1', @@ -697,22 +750,23 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('0.8.1+build.2') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'version', - tag: '0.8.1+build.2', - commit: 'dddddddddddddddddddddddddddddddddddddddd' - }); - next(); - }) - .done(); + resolver + ._findResolution('0.8.1+build.2') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: '0.8.1+build.2', + commit: 'dddddddddddddddddddddddddddddddddddddddd' + }); + next(); + }) + .done(); }); - it('should fail to resolve if none of the versions matched a range/version', function (next) { + it('should fail to resolve if none of the versions matched a range/version', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.1.0', @@ -721,23 +775,31 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('~0.2.0') - .then(function () { - next(new Error('Should have failed')); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.message).to.match(/was able to satisfy ~0.2.0/i); - expect(err.details).to.match(/available versions in foo: 0\.1\.1, 0\.1\.0/i); - expect(err.code).to.equal('ENORESTARGET'); - next(); - }) - .done(); - }); - - it('should fail to resolve if there are no versions to match a range/version', function (next) { + resolver + ._findResolution('~0.2.0') + .then( + function() { + next(new Error('Should have failed')); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.message).to.match( + /was able to satisfy ~0.2.0/i + ); + expect(err.details).to.match( + /available versions in foo: 0\.1\.1, 0\.1\.0/i + ); + expect(err.code).to.equal('ENORESTARGET'); + next(); + } + ) + .done(); + }); + + it('should fail to resolve if there are no versions to match a range/version', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master' ]); @@ -745,65 +807,75 @@ describe('GitResolver', function () { resolver = create('foo'); - resolver._findResolution('~0.2.0') - .then(function () { - next(new Error('Should have failed')); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.message).to.match(/was able to satisfy ~0.2.0/i); - expect(err.details).to.match(/no versions found in foo/i); - expect(err.code).to.equal('ENORESTARGET'); - next(); - }) - .done(); - }); - - it('should resolve to the specified commit', function (next) { + resolver + ._findResolution('~0.2.0') + .then( + function() { + next(new Error('Should have failed')); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.message).to.match( + /was able to satisfy ~0.2.0/i + ); + expect(err.details).to.match( + /no versions found in foo/i + ); + expect(err.code).to.equal('ENORESTARGET'); + next(); + } + ) + .done(); + }); + + it('should resolve to the specified commit', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master' ]); }; resolver = create('foo'); - resolver._findResolution('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'commit', - commit: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' - }); - next(); - }) - .done(); + resolver + ._findResolution('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'commit', + commit: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + }); + next(); + }) + .done(); }); - it('should resolve to the specified short commit', function (next) { + it('should resolve to the specified short commit', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master' ]); }; resolver = create('foo'); - resolver._findResolution('bbbbbbb') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'commit', - commit: 'bbbbbbb' - }); - next(); - }) - .done(); + resolver + ._findResolution('bbbbbbb') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'commit', + commit: 'bbbbbbb' + }); + next(); + }) + .done(); }); - it('should resolve to the specified tag if it exists', function (next) { + it('should resolve to the specified tag if it exists', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/some-tag' @@ -811,22 +883,23 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('some-tag') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'tag', - tag: 'some-tag', - commit: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' - }); - next(); - }) - .done(); + resolver + ._findResolution('some-tag') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'tag', + tag: 'some-tag', + commit: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + }); + next(); + }) + .done(); }); - it('should resolve to the specified branch if it exists', function (next) { + it('should resolve to the specified branch if it exists', function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/some-branch' @@ -834,22 +907,23 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('some-branch') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'branch', - branch: 'some-branch', - commit: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' - }); - next(); - }) - .done(); + resolver + ._findResolution('some-branch') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'branch', + branch: 'some-branch', + commit: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + }); + next(); + }) + .done(); }); - it('should fail to resolve to the specified tag/branch if it doesn\'t exists', function (next) { + it("should fail to resolve to the specified tag/branch if it doesn't exists", function(next) { var resolver; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/some-tag' @@ -857,334 +931,399 @@ describe('GitResolver', function () { }; resolver = create('foo'); - resolver._findResolution('some-branch') - .then(function () { - next(new Error('Should have failed')); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.message).to.match(/tag\/branch some-branch does not exist/i); - expect(err.details).to.match(/available branches: master/i); - expect(err.details).to.match(/available tags: some-tag/i); - expect(err.code).to.equal('ENORESTARGET'); - next(); - }) - .done(); + resolver + ._findResolution('some-branch') + .then( + function() { + next(new Error('Should have failed')); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.message).to.match( + /tag\/branch some-branch does not exist/i + ); + expect(err.details).to.match( + /available branches: master/i + ); + expect(err.details).to.match( + /available tags: some-tag/i + ); + expect(err.code).to.equal('ENORESTARGET'); + next(); + } + ) + .done(); }); }); - describe('._cleanup', function () { - beforeEach(function () { + describe('._cleanup', function() { + beforeEach(function() { mkdirp.sync(tempDir); }); - afterEach(function (next) { + afterEach(function(next) { clearResolverRuntimeCache(); // Need to chmodr before removing..at least on windows // because .git has some read only files - chmodr(tempDir, 0777, function () { + chmodr(tempDir, 0777, function() { rimraf(tempDir, next); }); }); - it('should remove the .git folder from the temp dir', function (next) { + it('should remove the .git folder from the temp dir', function(next) { var resolver = create('foo'); var dst = path.join(tempDir, '.git'); // Copy .git folder to the tempDir - copy.copyDir(path.resolve(__dirname, '../../assets/package-a/.git'), dst, { - mode: 0777 - }) - .then(function () { - resolver._tempDir = tempDir; - - return resolver._cleanup() - .then(function () { - expect(fs.existsSync(dst)).to.be(false); - next(); - }); - }) - .done(); + copy + .copyDir( + path.resolve(__dirname, '../../assets/package-a/.git'), + dst, + { + mode: 0777 + } + ) + .then(function() { + resolver._tempDir = tempDir; + + return resolver._cleanup().then(function() { + expect(fs.existsSync(dst)).to.be(false); + next(); + }); + }) + .done(); }); - it('should not fail if .git does not exist for some reason', function (next) { + it('should not fail if .git does not exist for some reason', function(next) { var resolver = create('foo'); var dst = path.join(tempDir, '.git'); resolver._tempDir = tempDir; - resolver._cleanup() - .then(function () { - expect(fs.existsSync(dst)).to.be(false); - next(); - }) - .done(); + resolver + ._cleanup() + .then(function() { + expect(fs.existsSync(dst)).to.be(false); + next(); + }) + .done(); }); - it('should sill run even if _checkout fails for some reason', function (next) { + it('should sill run even if _checkout fails for some reason', function(next) { var resolver = create('foo'); var called = false; - GitResolver.refs = function () { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master' ]); }; resolver._tempDir = tempDir; - resolver._checkout = function () { + resolver._checkout = function() { return Q.reject(new Error('Some error')); }; - resolver._cleanup = function () { + resolver._cleanup = function() { called = true; return GitResolver.prototype._cleanup.apply(this, arguments); }; - resolver.resolve() - .then(function () { - next(new Error('Should have failed')); - }, function () { - expect(called).to.be(true); - next(); - }) - .done(); + resolver + .resolve() + .then( + function() { + next(new Error('Should have failed')); + }, + function() { + expect(called).to.be(true); + next(); + } + ) + .done(); }); }); - describe('._savePkgMeta', function () { - before(function () { + describe('._savePkgMeta', function() { + before(function() { mkdirp.sync(tempDir); }); - afterEach(function (next) { + afterEach(function(next) { rimraf(path.join(tempDir, '.bower.json'), next); }); - after(function (next) { + after(function(next) { rimraf(tempDir, next); }); - it('should save the resolution to the .bower.json to be used later by .hasNew', function (next) { + it('should save the resolution to the .bower.json to be used later by .hasNew', function(next) { var resolver = create('foo'); resolver._resolution = { type: 'version', tag: '0.0.1' }; resolver._tempDir = tempDir; - resolver._savePkgMeta({ name: 'foo', version: '0.0.1' }) - .then(function () { - return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - - expect(json._resolution).to.eql(resolver._resolution); - next(); - }) - .done(); + resolver + ._savePkgMeta({ name: 'foo', version: '0.0.1' }) + .then(function() { + return Q.nfcall( + fs.readFile, + path.join(tempDir, '.bower.json') + ); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + + expect(json._resolution).to.eql(resolver._resolution); + next(); + }) + .done(); }); - it('should save the release in the package meta', function (next) { + it('should save the release in the package meta', function(next) { var resolver = create('foo'); var metaFile = path.join(tempDir, '.bower.json'); // Test with type 'version' - resolver._resolution = { type: 'version', tag: '0.0.1', commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' }; + resolver._resolution = { + type: 'version', + tag: '0.0.1', + commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + }; resolver._tempDir = tempDir; - resolver._savePkgMeta({ name: 'foo', version: '0.0.1' }) - .then(function () { - return Q.nfcall(fs.readFile, metaFile); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json._release).to.equal('0.0.1'); - }) - // Test with type 'version' + build metadata - .then(function () { - resolver._resolution = { type: 'version', tag: '0.0.1+build.5', commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' }; - return resolver._savePkgMeta({ name: 'foo' }); - }) - .then(function () { - return Q.nfcall(fs.readFile, metaFile); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json._release).to.equal('0.0.1+build.5'); - }) - // Test with type 'tag' - .then(function () { - resolver._resolution = { type: 'tag', tag: '0.0.1', commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' }; - return resolver._savePkgMeta({ name: 'foo' }); - }) - .then(function () { - return Q.nfcall(fs.readFile, metaFile); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json._release).to.equal('0.0.1'); - }) - // Test with type 'branch' - // In this case, it should be the commit - .then(function () { - resolver._resolution = { type: 'branch', branch: 'foo', commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' }; - return resolver._savePkgMeta({ name: 'foo' }); - }) - .then(function () { - return Q.nfcall(fs.readFile, metaFile); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json._release).to.equal('aaaaaaaaaa'); - }) - // Test with type 'commit' - .then(function () { - resolver._resolution = { type: 'commit', commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' }; - return resolver._savePkgMeta({ name: 'foo' }); - }) - .then(function () { - return Q.nfcall(fs.readFile, metaFile); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json._release).to.equal('aaaaaaaaaa'); - next(); - }) - .done(); - }); - - it('should add the version to the package meta if not present and resolution is a version', function (next) { + resolver + ._savePkgMeta({ name: 'foo', version: '0.0.1' }) + .then(function() { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('0.0.1'); + }) + // Test with type 'version' + build metadata + .then(function() { + resolver._resolution = { + type: 'version', + tag: '0.0.1+build.5', + commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + }; + return resolver._savePkgMeta({ name: 'foo' }); + }) + .then(function() { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('0.0.1+build.5'); + }) + // Test with type 'tag' + .then(function() { + resolver._resolution = { + type: 'tag', + tag: '0.0.1', + commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + }; + return resolver._savePkgMeta({ name: 'foo' }); + }) + .then(function() { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('0.0.1'); + }) + // Test with type 'branch' + // In this case, it should be the commit + .then(function() { + resolver._resolution = { + type: 'branch', + branch: 'foo', + commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + }; + return resolver._savePkgMeta({ name: 'foo' }); + }) + .then(function() { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('aaaaaaaaaa'); + }) + // Test with type 'commit' + .then(function() { + resolver._resolution = { + type: 'commit', + commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + }; + return resolver._savePkgMeta({ name: 'foo' }); + }) + .then(function() { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('aaaaaaaaaa'); + next(); + }) + .done(); + }); + + it('should add the version to the package meta if not present and resolution is a version', function(next) { var resolver = create('foo'); resolver._resolution = { type: 'version', tag: 'v0.0.1' }; resolver._tempDir = tempDir; - resolver._savePkgMeta({ name: 'foo' }) - .then(function () { - return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json.version).to.equal('0.0.1'); + resolver + ._savePkgMeta({ name: 'foo' }) + .then(function() { + return Q.nfcall( + fs.readFile, + path.join(tempDir, '.bower.json') + ); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json.version).to.equal('0.0.1'); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should remove the version from the package meta if resolution is not a version', function (next) { + it('should remove the version from the package meta if resolution is not a version', function(next) { var resolver = create('foo'); - resolver._resolution = { type: 'commit', commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' }; + resolver._resolution = { + type: 'commit', + commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + }; resolver._tempDir = tempDir; - resolver._savePkgMeta({ name: 'foo', version: '0.0.1' }) - .then(function () { - return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json).to.not.have.property('version'); + resolver + ._savePkgMeta({ name: 'foo', version: '0.0.1' }) + .then(function() { + return Q.nfcall( + fs.readFile, + path.join(tempDir, '.bower.json') + ); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json).to.not.have.property('version'); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should warn if the resolution version is different than the package meta version', function (next) { + it('should warn if the resolution version is different than the package meta version', function(next) { var resolver = create('foo'); var notified = false; resolver._resolution = { type: 'version', tag: '0.0.1' }; resolver._tempDir = tempDir; - logger.on('log', function (log) { + logger.on('log', function(log) { expect(log).to.be.an('object'); if (log.level === 'warn' && log.id === 'mismatch') { - expect(log.message).to.match(/\(0\.0\.0\).*different.*\(0\.0\.1\)/); + expect(log.message).to.match( + /\(0\.0\.0\).*different.*\(0\.0\.1\)/ + ); notified = true; } }); - resolver._savePkgMeta({ name: 'foo', version: '0.0.0' }) - .then(function () { - return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json.version).to.equal('0.0.1'); - expect(notified).to.be(true); + resolver + ._savePkgMeta({ name: 'foo', version: '0.0.0' }) + .then(function() { + return Q.nfcall( + fs.readFile, + path.join(tempDir, '.bower.json') + ); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json.version).to.equal('0.0.1'); + expect(notified).to.be(true); - next(); - }) - .done(); + next(); + }) + .done(); }); - it('should not warn if the resolution version and the package meta version are the same', function (next) { + it('should not warn if the resolution version and the package meta version are the same', function(next) { var resolver = create('foo'); var notified = false; resolver._resolution = { type: 'version', tag: 'v0.0.1' }; resolver._tempDir = tempDir; - resolver._savePkgMeta({ name: 'foo', version: '0.0.1' }) - .then(function () { - return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); - }, null) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json.version).to.equal('0.0.1'); - expect(notified).to.be(false); + resolver + ._savePkgMeta({ name: 'foo', version: '0.0.1' }) + .then(function() { + return Q.nfcall( + fs.readFile, + path.join(tempDir, '.bower.json') + ); + }, null) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json.version).to.equal('0.0.1'); + expect(notified).to.be(false); - next(); - }) - .done(); + next(); + }) + .done(); }); }); - describe('#branches', function () { + describe('#branches', function() { afterEach(clearResolverRuntimeCache); - it('should resolve to an empty object if no heads are found', function (next) { - GitResolver.refs = function () { + it('should resolve to an empty object if no heads are found', function(next) { + GitResolver.refs = function() { return Q.resolve([]); }; GitResolver.branches('foo') - .then(function (branches) { - expect(branches).to.be.an('object'); - expect(branches).to.eql({}); - next(); - }) - .done(); + .then(function(branches) { + expect(branches).to.be.an('object'); + expect(branches).to.eql({}); + next(); + }) + .done(); }); - it('should resolve to an object where keys are branches and values their commit hashes', function (next) { - GitResolver.refs = function () { + it('should resolve to an object where keys are branches and values their commit hashes', function(next) { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/some-branch', - 'foo refs/heads/invalid', // invalid - 'cccccccccccccccccccccccccccccccccccccccc refs/heads/', // invalid - 'dddddddddddddddddddddddddddddddddddddddd refs/heads', // invalid + 'foo refs/heads/invalid', // invalid + 'cccccccccccccccccccccccccccccccccccccccc refs/heads/', // invalid + 'dddddddddddddddddddddddddddddddddddddddd refs/heads', // invalid 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee refs/tags/some-tag', 'ffffffffffffffffffffffffffffffffffffffff refs/tags/0.1.1' ]); }; GitResolver.branches('foo') - .then(function (branches) { - expect(branches).to.eql({ - 'master': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', - 'some-branch': 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' - }); - next(); - }) - .done(); - }); - - it('should cache the result for each source', function (next) { - GitResolver.refs = function (source) { + .then(function(branches) { + expect(branches).to.eql({ + master: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + 'some-branch': + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + }); + next(); + }) + .done(); + }); + + it('should cache the result for each source', function(next) { + GitResolver.refs = function(source) { if (source === 'foo') { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', @@ -1199,87 +1338,89 @@ describe('GitResolver', function () { }; GitResolver.branches('foo') - .then(function (branches) { - expect(branches).to.eql({ - 'master': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', - 'some-branch': 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' - }); - - return GitResolver.branches('bar'); - }) - .then(function (branches) { - expect(branches).to.eql({ - 'master': 'cccccccccccccccccccccccccccccccccccccccc', - 'other-branch': 'dddddddddddddddddddddddddddddddddddddddd' - }); - - // Manipulate the cache and check if it resolves for the cached ones - delete GitResolver._cache.branches.get('foo').master; - delete GitResolver._cache.branches.get('bar').master; - - return GitResolver.branches('foo'); - }) - .then(function (branches) { - expect(branches).to.eql({ - 'some-branch': 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' - }); - - return GitResolver.branches('bar'); - }) - .then(function (branches) { - expect(branches).to.eql({ - 'other-branch': 'dddddddddddddddddddddddddddddddddddddddd' - }); - - next(); - }) - .done(); - }); - - it('should work if requested in parallel for the same source', function (next) { - GitResolver.refs = function () { + .then(function(branches) { + expect(branches).to.eql({ + master: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + 'some-branch': + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + }); + + return GitResolver.branches('bar'); + }) + .then(function(branches) { + expect(branches).to.eql({ + master: 'cccccccccccccccccccccccccccccccccccccccc', + 'other-branch': + 'dddddddddddddddddddddddddddddddddddddddd' + }); + + // Manipulate the cache and check if it resolves for the cached ones + delete GitResolver._cache.branches.get('foo').master; + delete GitResolver._cache.branches.get('bar').master; + + return GitResolver.branches('foo'); + }) + .then(function(branches) { + expect(branches).to.eql({ + 'some-branch': + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + }); + + return GitResolver.branches('bar'); + }) + .then(function(branches) { + expect(branches).to.eql({ + 'other-branch': + 'dddddddddddddddddddddddddddddddddddddddd' + }); + + next(); + }) + .done(); + }); + + it('should work if requested in parallel for the same source', function(next) { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/some-branch' ]); }; - Q.all([ - GitResolver.branches('foo'), - GitResolver.branches('foo') - ]) - .spread(function (branches1, branches2) { - expect(branches1).to.eql({ - 'master': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', - 'some-branch': 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' - }); - expect(branches1).to.eql(branches2); - - next(); - }) - .done(); + Q.all([GitResolver.branches('foo'), GitResolver.branches('foo')]) + .spread(function(branches1, branches2) { + expect(branches1).to.eql({ + master: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + 'some-branch': + 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + }); + expect(branches1).to.eql(branches2); + + next(); + }) + .done(); }); }); - describe('#tags', function () { + describe('#tags', function() { afterEach(clearResolverRuntimeCache); - it('should resolve to an empty hash if no tags are found', function (next) { - GitResolver.refs = function () { + it('should resolve to an empty hash if no tags are found', function(next) { + GitResolver.refs = function() { return Q.resolve([]); }; GitResolver.tags('foo') - .then(function (tags) { - expect(tags).to.be.an('object'); - expect(tags).to.eql({}); - next(); - }) - .done(); + .then(function(tags) { + expect(tags).to.be.an('object'); + expect(tags).to.eql({}); + next(); + }) + .done(); }); - it('should resolve to an hash of tags', function (next) { - GitResolver.refs = function () { + it('should resolve to an hash of tags', function(next) { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/some-branch', @@ -1287,27 +1428,27 @@ describe('GitResolver', function () { 'dddddddddddddddddddddddddddddddddddddddd refs/tags/0.1.0', 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee refs/tags/v0.1.1', 'abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/some-tag', - 'foo refs/tags/invalid', // invalid - 'ffffffffffffffffffffffffffffffffffffffff refs/tags/', // invalid - 'abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags' // invalid + 'foo refs/tags/invalid', // invalid + 'ffffffffffffffffffffffffffffffffffffffff refs/tags/', // invalid + 'abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags' // invalid ]); }; GitResolver.tags('foo') - .then(function (tags) { - expect(tags).to.eql({ - '0.2.1': 'cccccccccccccccccccccccccccccccccccccccc', - '0.1.0': 'dddddddddddddddddddddddddddddddddddddddd', - 'v0.1.1': 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', - 'some-tag': 'abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' - }); - next(); - }) - .done(); - }); - - it('should cache the result for each source', function (next) { - GitResolver.refs = function (source) { + .then(function(tags) { + expect(tags).to.eql({ + '0.2.1': 'cccccccccccccccccccccccccccccccccccccccc', + '0.1.0': 'dddddddddddddddddddddddddddddddddddddddd', + 'v0.1.1': 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', + 'some-tag': 'abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + }); + next(); + }) + .done(); + }); + + it('should cache the result for each source', function(next) { + GitResolver.refs = function(source) { if (source === 'foo') { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/tags/0.2.1', @@ -1322,120 +1463,116 @@ describe('GitResolver', function () { }; GitResolver.tags('foo') - .then(function (versions) { - expect(versions).to.eql({ - '0.2.1': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', - 'some-tag': 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' - }); - - return GitResolver.tags('bar'); - }) - .then(function (versions) { - expect(versions).to.eql({ - '0.3.1': 'cccccccccccccccccccccccccccccccccccccccc', - 'some-tag': 'dddddddddddddddddddddddddddddddddddddddd' - }); - - - // Manipulate the cache and check if it resolves for the cached ones - delete GitResolver._cache.tags.get('foo')['0.2.1']; - delete GitResolver._cache.tags.get('bar')['0.3.1']; - - return GitResolver.tags('foo'); - }) - .then(function (tags) { - expect(tags).to.eql({ - 'some-tag': 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' - }); - - return GitResolver.tags('bar'); - }) - .then(function (tags) { - expect(tags).to.eql({ - 'some-tag': 'dddddddddddddddddddddddddddddddddddddddd' - }); - - next(); - }) - .done(); - }); - - it('should work if requested in parallel for the same source', function (next) { - GitResolver.refs = function () { + .then(function(versions) { + expect(versions).to.eql({ + '0.2.1': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + 'some-tag': 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + }); + + return GitResolver.tags('bar'); + }) + .then(function(versions) { + expect(versions).to.eql({ + '0.3.1': 'cccccccccccccccccccccccccccccccccccccccc', + 'some-tag': 'dddddddddddddddddddddddddddddddddddddddd' + }); + + // Manipulate the cache and check if it resolves for the cached ones + delete GitResolver._cache.tags.get('foo')['0.2.1']; + delete GitResolver._cache.tags.get('bar')['0.3.1']; + + return GitResolver.tags('foo'); + }) + .then(function(tags) { + expect(tags).to.eql({ + 'some-tag': 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + }); + + return GitResolver.tags('bar'); + }) + .then(function(tags) { + expect(tags).to.eql({ + 'some-tag': 'dddddddddddddddddddddddddddddddddddddddd' + }); + + next(); + }) + .done(); + }); + + it('should work if requested in parallel for the same source', function(next) { + GitResolver.refs = function() { return Q.resolve([ 'cccccccccccccccccccccccccccccccccccccccc refs/tags/0.3.1', 'dddddddddddddddddddddddddddddddddddddddd refs/tags/some-tag' ]); }; - Q.all([ - GitResolver.tags('foo'), - GitResolver.tags('foo') - ]) - .spread(function (tags1, tags2) { - expect(tags1).to.eql({ - '0.3.1': 'cccccccccccccccccccccccccccccccccccccccc', - 'some-tag': 'dddddddddddddddddddddddddddddddddddddddd' - }); - expect(tags2).to.eql(tags1); - - next(); - }) - .done(); + Q.all([GitResolver.tags('foo'), GitResolver.tags('foo')]) + .spread(function(tags1, tags2) { + expect(tags1).to.eql({ + '0.3.1': 'cccccccccccccccccccccccccccccccccccccccc', + 'some-tag': 'dddddddddddddddddddddddddddddddddddddddd' + }); + expect(tags2).to.eql(tags1); + + next(); + }) + .done(); }); }); - describe('#clearRuntimeCache', function () { + describe('#clearRuntimeCache', function() { // Use a class that inherit the GitResolver to see if it uses // late binding when clearing the cache function CustomGitResolver() {} util.inherits(CustomGitResolver, GitResolver); mout.object.mixIn(CustomGitResolver, GitResolver); - it('should clear refs cache', function () { + it('should clear refs cache', function() { CustomGitResolver._cache.refs.set('foo', {}); CustomGitResolver.clearRuntimeCache(); expect(CustomGitResolver._cache.refs.has('foo')).to.be(false); }); - it('should clear branches cache', function () { + it('should clear branches cache', function() { CustomGitResolver._cache.branches.set('foo', {}); CustomGitResolver.clearRuntimeCache(); expect(CustomGitResolver._cache.branches.has('foo')).to.be(false); }); - it('should clear tags cache', function () { + it('should clear tags cache', function() { CustomGitResolver._cache.tags.set('foo', {}); CustomGitResolver.clearRuntimeCache(); expect(CustomGitResolver._cache.tags.has('foo')).to.be(false); }); - it('should clear versions cache', function () { + it('should clear versions cache', function() { CustomGitResolver._cache.versions.set('foo', {}); CustomGitResolver.clearRuntimeCache(); expect(CustomGitResolver._cache.versions.has('foo')).to.be(false); }); }); - describe('#versions', function () { + describe('#versions', function() { afterEach(clearResolverRuntimeCache); - it('should resolve to an empty array if no tags are found', function (next) { - GitResolver.refs = function () { + it('should resolve to an empty array if no tags are found', function(next) { + GitResolver.refs = function() { return Q.resolve([]); }; GitResolver.versions('foo') - .then(function (versions) { - expect(versions).to.be.an('array'); - expect(versions).to.eql([]); - next(); - }) - .done(); + .then(function(versions) { + expect(versions).to.be.an('array'); + expect(versions).to.eql([]); + next(); + }) + .done(); }); - it('should resolve to an empty array if no valid semver tags', function (next) { - GitResolver.refs = function () { + it('should resolve to an empty array if no valid semver tags', function(next) { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/some-branch', @@ -1444,48 +1581,60 @@ describe('GitResolver', function () { }; GitResolver.versions('foo') - .then(function (versions) { - expect(versions).to.be.an('array'); - expect(versions).to.eql([]); - next(); - }) - .done(); + .then(function(versions) { + expect(versions).to.be.an('array'); + expect(versions).to.eql([]); + next(); + }) + .done(); }); - it('should resolve to an array of versions, ignoring invalid semver tags', function (next) { - GitResolver.refs = function () { + it('should resolve to an array of versions, ignoring invalid semver tags', function(next) { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/heads/master', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/heads/some-branch', 'cccccccccccccccccccccccccccccccccccccccc refs/tags/0.2.1', 'dddddddddddddddddddddddddddddddddddddddd refs/tags/0.1.0', 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee refs/tags/v0.1.1', - 'foo refs/tags/invalid', // invalid - 'ffffffffffffffffffffffffffffffffffffffff refs/tags/', // invalid - 'abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags' // invalid + 'foo refs/tags/invalid', // invalid + 'ffffffffffffffffffffffffffffffffffffffff refs/tags/', // invalid + 'abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags' // invalid ]); }; GitResolver.versions('foo', true) - .then(function (versions) { - expect(versions).to.eql([ - { version: '0.2.1', tag: '0.2.1', commit: 'cccccccccccccccccccccccccccccccccccccccc' }, - { version: '0.1.1', tag: 'v0.1.1', commit: 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' }, - { version: '0.1.0', tag: '0.1.0', commit: 'dddddddddddddddddddddddddddddddddddddddd' } - ]); - }) - .then(function () { - return GitResolver.versions('foo'); - }) - .then(function (versions) { - expect(versions).to.eql(['0.2.1', '0.1.1', '0.1.0']); - next(); - }) - .done(); - }); - - it('should order the versions according to the semver spec', function (next) { - GitResolver.refs = function () { + .then(function(versions) { + expect(versions).to.eql([ + { + version: '0.2.1', + tag: '0.2.1', + commit: 'cccccccccccccccccccccccccccccccccccccccc' + }, + { + version: '0.1.1', + tag: 'v0.1.1', + commit: 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' + }, + { + version: '0.1.0', + tag: '0.1.0', + commit: 'dddddddddddddddddddddddddddddddddddddddd' + } + ]); + }) + .then(function() { + return GitResolver.versions('foo'); + }) + .then(function(versions) { + expect(versions).to.eql(['0.2.1', '0.1.1', '0.1.0']); + next(); + }) + .done(); + }); + + it('should order the versions according to the semver spec', function(next) { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/tags/0.1.0', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.1.1+build.11', @@ -1498,23 +1647,51 @@ describe('GitResolver', function () { }; GitResolver.versions('foo', true) - .then(function (versions) { - expect(versions).to.eql([ - { version: '0.2.1', tag: 'v0.2.1', commit: 'abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' }, - { version: '0.1.1+build.11', tag: '0.1.1+build.11', commit: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' }, - { version: '0.1.1+build.100', tag: '0.1.1+build.100', commit: 'cccccccccccccccccccccccccccccccccccccccc' }, - { version: '0.1.1', tag: '0.1.1', commit: 'ffffffffffffffffffffffffffffffffffffffff' }, - { version: '0.1.1-rc.200', tag: '0.1.1-rc.200', commit: 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' }, - { version: '0.1.1-rc.22', tag: '0.1.1-rc.22', commit: 'dddddddddddddddddddddddddddddddddddddddd' }, - { version: '0.1.0', tag: '0.1.0', commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' } - ]); - next(); - }) - .done(); + .then(function(versions) { + expect(versions).to.eql([ + { + version: '0.2.1', + tag: 'v0.2.1', + commit: 'abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + }, + { + version: '0.1.1+build.11', + tag: '0.1.1+build.11', + commit: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + }, + { + version: '0.1.1+build.100', + tag: '0.1.1+build.100', + commit: 'cccccccccccccccccccccccccccccccccccccccc' + }, + { + version: '0.1.1', + tag: '0.1.1', + commit: 'ffffffffffffffffffffffffffffffffffffffff' + }, + { + version: '0.1.1-rc.200', + tag: '0.1.1-rc.200', + commit: 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' + }, + { + version: '0.1.1-rc.22', + tag: '0.1.1-rc.22', + commit: 'dddddddddddddddddddddddddddddddddddddddd' + }, + { + version: '0.1.0', + tag: '0.1.0', + commit: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + } + ]); + next(); + }) + .done(); }); - it('should cache the result for each source', function (next) { - GitResolver.refs = function (source) { + it('should cache the result for each source', function(next) { + GitResolver.refs = function(source) { if (source === 'foo') { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/tags/0.2.1', @@ -1529,52 +1706,48 @@ describe('GitResolver', function () { }; GitResolver.versions('foo') - .then(function (versions) { - expect(versions).to.eql(['0.2.1', '0.1.0']); - - return GitResolver.versions('bar'); - }) - .then(function (versions) { - expect(versions).to.eql(['0.3.1', '0.3.0']); - - - // Manipulate the cache and check if it resolves for the cached ones - GitResolver._cache.versions.get('foo').splice(1, 1); - GitResolver._cache.versions.get('bar').splice(1, 1); - - return GitResolver.versions('foo'); - }) - .then(function (versions) { - expect(versions).to.eql(['0.2.1']); - - return GitResolver.versions('bar'); - }) - .then(function (versions) { - expect(versions).to.eql(['0.3.1']); - next(); - }) - .done(); + .then(function(versions) { + expect(versions).to.eql(['0.2.1', '0.1.0']); + + return GitResolver.versions('bar'); + }) + .then(function(versions) { + expect(versions).to.eql(['0.3.1', '0.3.0']); + + // Manipulate the cache and check if it resolves for the cached ones + GitResolver._cache.versions.get('foo').splice(1, 1); + GitResolver._cache.versions.get('bar').splice(1, 1); + + return GitResolver.versions('foo'); + }) + .then(function(versions) { + expect(versions).to.eql(['0.2.1']); + + return GitResolver.versions('bar'); + }) + .then(function(versions) { + expect(versions).to.eql(['0.3.1']); + next(); + }) + .done(); }); - it('should work if requested in parallel for the same source', function (next) { - GitResolver.refs = function () { + it('should work if requested in parallel for the same source', function(next) { + GitResolver.refs = function() { return Q.resolve([ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa refs/tags/0.2.1', 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb refs/tags/0.1.0' ]); }; - Q.all([ - GitResolver.versions('foo'), - GitResolver.versions('foo') - ]) - .spread(function (versions1, versions2) { - expect(versions1).to.eql(['0.2.1', '0.1.0']); - expect(versions2).to.eql(versions1); - - next(); - }) - .done(); + Q.all([GitResolver.versions('foo'), GitResolver.versions('foo')]) + .spread(function(versions1, versions2) { + expect(versions1).to.eql(['0.2.1', '0.1.0']); + expect(versions2).to.eql(versions1); + + next(); + }) + .done(); }); }); }); diff --git a/test/core/resolvers/pluginResolverFactory.js b/test/core/resolvers/pluginResolverFactory.js index 22609bcef..681292639 100644 --- a/test/core/resolvers/pluginResolverFactory.js +++ b/test/core/resolvers/pluginResolverFactory.js @@ -6,38 +6,36 @@ var pluginResolverFactory = require('../../../lib/core/resolvers/pluginResolverF var defaultConfig = require('../../../lib/config'); var Q = require('q'); -describe('pluginResolverFactory', function () { +describe('pluginResolverFactory', function() { var testPackage = path.resolve(__dirname, '../../assets/package-a'); var logger; - before(function () { + before(function() { logger = new Logger(); }); - afterEach(function () { + afterEach(function() { logger.removeAllListeners(); }); var mockPluginResolver = function resolver(bower) { - return { - - match: function (source) { + match: function(source) { return true; }, - locate: function (source) { + locate: function(source) { return source; }, - releases: function (source) { + releases: function(source) { return [ { target: 'v1.0.0', version: '1.0.0' }, { target: 'v1.0.1', version: '1.0.1' } ]; }, - fetch: function (endpoint, cached) { + fetch: function(endpoint, cached) { if (cached && cached.version) { return; } @@ -54,29 +52,37 @@ describe('pluginResolverFactory', function () { if (typeof decEndpoint === 'string') { decEndpoint = { source: decEndpoint }; } - var PluginResolver = pluginResolverFactory(mockPluginResolver, - defaultConfig()); + var PluginResolver = pluginResolverFactory( + mockPluginResolver, + defaultConfig() + ); return new PluginResolver(decEndpoint); } - describe('.constructor', function () { - it('should internally add decEndpoint', function () { + describe('.constructor', function() { + it('should internally add decEndpoint', function() { var resolver; resolver = create('file://' + testPackage); expect(typeof resolver._decEndpoint).to.equal('object'); - expect(resolver._decEndpoint.source).to.equal('file://' + testPackage); + expect(resolver._decEndpoint.source).to.equal( + 'file://' + testPackage + ); }); - it('should throw when invalid resolverFactory is provided', function () { - expect(function () { - pluginResolverFactory('not-a-function', - defaultConfig()); - }).to.throwException(createError('Resolver has "string" type instead of "function" type.', 'ERESOLERAPI')); + it('should throw when invalid resolverFactory is provided', function() { + expect(function() { + pluginResolverFactory('not-a-function', defaultConfig()); + }).to.throwException( + createError( + 'Resolver has "string" type instead of "function" type.', + 'ERESOLERAPI' + ) + ); }); }); - describe('.getEndpoint', function () { - it('should return endpoint', function () { + describe('.getEndpoint', function() { + it('should return endpoint', function() { var resolver, endPoint; resolver = create('file://' + testPackage); endPoint = resolver.getEndpoint(); @@ -89,8 +95,8 @@ describe('pluginResolverFactory', function () { }); }); - describe('.getSource', function () { - it('should return endpoint', function () { + describe('.getSource', function() { + it('should return endpoint', function() { var resolver, source; resolver = create('file://' + testPackage); source = resolver.getSource(); @@ -98,8 +104,8 @@ describe('pluginResolverFactory', function () { }); }); - describe('.getTarget', function () { - it('should return target', function () { + describe('.getTarget', function() { + it('should return target', function() { var resolver, source; resolver = create({ source: 'file://' + testPackage, @@ -108,7 +114,7 @@ describe('pluginResolverFactory', function () { source = resolver.getTarget(); expect(source).to.equal('some-target'); }); - it('should return * when no target is specified', function () { + it('should return * when no target is specified', function() { var resolver, source; resolver = create('file://' + testPackage); source = resolver.getTarget(); @@ -116,13 +122,12 @@ describe('pluginResolverFactory', function () { }); }); - describe('.getName', function () { - it('should return target', function () { - }); + describe('.getName', function() { + it('should return target', function() {}); }); - describe('.getPkgMeta', function () { - it('should return package meta', function () { + describe('.getPkgMeta', function() { + it('should return package meta', function() { var resolver, pkgMeta; resolver = create('file://' + testPackage); resolver._pkgMeta = { version: 'v1.0.1' }; @@ -133,8 +138,8 @@ describe('pluginResolverFactory', function () { }); }); - describe('.isCacheable', function () { - it('should always return true', function () { + describe('.isCacheable', function() { + it('should always return true', function() { var resolver, isCacheable; resolver = create('file://' + testPackage); isCacheable = resolver.isCacheable(); @@ -142,35 +147,33 @@ describe('pluginResolverFactory', function () { }); }); - describe('.hasNew', function () { - it('should return existing hasNewPromise if its set', function () { + describe('.hasNew', function() { + it('should return existing hasNewPromise if its set', function() { var resolver; resolver = create('file://' + testPackage); - resolver.hasNewPromise = Q.fcall(function () { + resolver.hasNewPromise = Q.fcall(function() { return 'some-dummy-value'; }); - resolver.hasNew().then(function (resolvedtestValue) { + resolver.hasNew().then(function(resolvedtestValue) { expect(resolvedtestValue).to.be('some-dummy-value'); }); }); - it('should return target', function () { - }); + it('should return target', function() {}); }); - describe('.resolve', function () { - it('should throw \'Resolver did not provide releases of package.\'', function (next) { + describe('.resolve', function() { + it("should throw 'Resolver did not provide releases of package.'", function(next) { var mockPluginResolverWithEmptyReleases = function resolver(bower) { return { - - match: function (source) { + match: function(source) { return true; }, - releases: function (source) { + releases: function(source) { return null; }, - fetch: function (endpoint, cached) { + fetch: function(endpoint, cached) { if (cached && cached.version) { return; } @@ -183,32 +186,34 @@ describe('pluginResolverFactory', function () { }; }; - var PluginResolver = pluginResolverFactory(mockPluginResolverWithEmptyReleases, - defaultConfig()); + var PluginResolver = pluginResolverFactory( + mockPluginResolverWithEmptyReleases, + defaultConfig() + ); var path = 'file://' + testPackage; var resolver = new PluginResolver(path); - resolver.resolve() - .catch(function (e) { - expect(e.message).to - .equal('Resolver did not provide releases of package.'); + resolver.resolve().catch(function(e) { + expect(e.message).to.equal( + 'Resolver did not provide releases of package.' + ); next(); }); }); - it('should throw \'No version found that was able to satisfy *.\'', function (next) { - var mockPluginResolverWithNoMatchingTarget = function resolver(bower) { - + it("should throw 'No version found that was able to satisfy *.'", function(next) { + var mockPluginResolverWithNoMatchingTarget = function resolver( + bower + ) { return { - - match: function (source) { + match: function(source) { return true; }, - releases: function (source) { + releases: function(source) { return []; }, - fetch: function (endpoint, cached) { + fetch: function(endpoint, cached) { if (cached && cached.version) { return; } @@ -227,24 +232,23 @@ describe('pluginResolverFactory', function () { ); var path = 'file://' + testPackage; var resolver = new PluginResolver(path); - resolver.resolve() - .catch(function (e) { - expect(e.message).to - .equal('No version found that was able to satisfy *'); - expect(e.code).to - .equal('ENORESTARGET'); + resolver.resolve().catch(function(e) { + expect(e.message).to.equal( + 'No version found that was able to satisfy *' + ); + expect(e.code).to.equal('ENORESTARGET'); next(); }); }); - it('should throw \'Resolver does not accept version ranges\'', function (next) { + it("should throw 'Resolver does not accept version ranges'", function(next) { var mockPluginResolverWithInvalidTarget = function resolver(bower) { return { - match: function (source) { + match: function(source) { return true; }, releases: null, - fetch: function (endpoint, cached) { + fetch: function(endpoint, cached) { if (cached && cached.version) { return; } @@ -265,22 +269,21 @@ describe('pluginResolverFactory', function () { source: path, target: '2.0.0' }); - resolver.resolve() - .catch(function (e) { - expect(e.message).to - .equal('Resolver does not accept version ranges (2.0.0)'); - next(); - }); + resolver.resolve().catch(function(e) { + expect(e.message).to.equal( + 'Resolver does not accept version ranges (2.0.0)' + ); + next(); + }); }); - - it('should throw \'Resolver does not implement the "fetch" method.\'', function (next) { + it('should throw \'Resolver does not implement the "fetch" method.\'', function(next) { var mockPluginResolverWithoutFetch = function resolver(bower) { return { - match: function (source) { + match: function(source) { return true; }, - releases: function (source) { + releases: function(source) { return [ { target: 'v1.0.0', version: '1.0.0' }, { target: 'v1.0.1', version: '1.0.1' } @@ -295,74 +298,73 @@ describe('pluginResolverFactory', function () { ); var path = 'file://' + testPackage; var resolver = new PluginResolver(path); - resolver.resolve() - .catch(function (e) { - expect(e.message).to - .equal('Resolver does not implement the "fetch" method.'); + resolver.resolve().catch(function(e) { + expect(e.message).to.equal( + 'Resolver does not implement the "fetch" method.' + ); next(); }); }); - it('should throw \'Resolver did not provide path to extracted contents of package\'', - function (next) { - var mockPluginResolverWithoutTempPath = function resolver(bower) { - return { - - match: function (source) { - return true; - }, + it("should throw 'Resolver did not provide path to extracted contents of package'", function(next) { + var mockPluginResolverWithoutTempPath = function resolver(bower) { + return { + match: function(source) { + return true; + }, - releases: function (source) { - return [ + releases: function(source) { + return [ { target: 'v1.0.0', version: '1.0.0' }, { target: 'v1.0.1', version: '1.0.1' } - ]; - }, - - fetch: function (endpoint, cached) { - if (cached && cached.version) { - return; - } - - return { - tempPath: null, - removeIgnores: true - }; - } - }; - }; - var PluginResolver = pluginResolverFactory( + ]; + }, + + fetch: function(endpoint, cached) { + if (cached && cached.version) { + return; + } + + return { + tempPath: null, + removeIgnores: true + }; + } + }; + }; + var PluginResolver = pluginResolverFactory( mockPluginResolverWithoutTempPath, defaultConfig() ); - var path = 'file://' + testPackage; - var resolver = new PluginResolver(path); - resolver.resolve() - .catch(function (e) { - expect(e.message).to - .equal('Resolver did not provide path to extracted contents of package.'); + var path = 'file://' + testPackage; + var resolver = new PluginResolver(path); + resolver.resolve().catch(function(e) { + expect(e.message).to.equal( + 'Resolver did not provide path to extracted contents of package.' + ); next(); }); - }); - + }); }); - describe('.isTargetable', function () { - it('should accept mockPluginResolverWithReleasesFn', function () { - var PluginResolver = pluginResolverFactory(mockPluginResolver, - defaultConfig()); + describe('.isTargetable', function() { + it('should accept mockPluginResolverWithReleasesFn', function() { + var PluginResolver = pluginResolverFactory( + mockPluginResolver, + defaultConfig() + ); expect(PluginResolver.isTargetable()).to.be.ok(); }); - it('should reject mockPluginResolverWithoutReleasesFn', function () { + it('should reject mockPluginResolverWithoutReleasesFn', function() { var mockPluginResolverWithoutReleasesFn = function resolver(bower) { return { - match: function (source) { + match: function(source) { return true; }, - locate: function (source) { + locate: function(source) { return source; }, - fetch: function (endpoint, cached) { + fetch: function(endpoint, cached) { if (cached && cached.version) { return; } @@ -374,32 +376,32 @@ describe('pluginResolverFactory', function () { } }; }; - var PluginResolver = pluginResolverFactory(mockPluginResolverWithoutReleasesFn, - defaultConfig()); + var PluginResolver = pluginResolverFactory( + mockPluginResolverWithoutReleasesFn, + defaultConfig() + ); expect(PluginResolver.isTargetable()).to.not.be.ok(); }); }); - describe('.clearRuntimeCache', function () { - it('', function () { + describe('.clearRuntimeCache', function() { + it('', function() { //Unable to test private variable `resolver` }); }); - describe('.match', function () { - it('should throw when plugin does not implement .match', function () { + describe('.match', function() { + it('should throw when plugin does not implement .match', function() { var mockPluginResolverWithoutMatch = function resolver(bower) { - return { - - releases: function (source) { + releases: function(source) { return [ { target: 'v1.0.0', version: '1.0.0' }, { target: 'v1.0.1', version: '1.0.1' } ]; }, - fetch: function (endpoint, cached) { + fetch: function(endpoint, cached) { if (cached && cached.version) { return; } @@ -412,45 +414,49 @@ describe('pluginResolverFactory', function () { }; }; - var PluginResolver = pluginResolverFactory(mockPluginResolverWithoutMatch, - defaultConfig()); + var PluginResolver = pluginResolverFactory( + mockPluginResolverWithoutMatch, + defaultConfig() + ); var source = 'git://github.com/jquery/jquery.git'; - expect(function () { + expect(function() { PluginResolver.match(source); - }).to.throwException(createError('Resolver is missing "match"' + - 'method.', - 'ERESOLVERAPI')); + }).to.throwException( + createError( + 'Resolver is missing "match"' + 'method.', + 'ERESOLVERAPI' + ) + ); }); - it('should match given source', function () { - var PluginResolver = pluginResolverFactory(mockPluginResolver, - defaultConfig()); + it('should match given source', function() { + var PluginResolver = pluginResolverFactory( + mockPluginResolver, + defaultConfig() + ); var source = 'git://github.com/jquery/jquery.git'; - PluginResolver.match(source).then(function (result) { + PluginResolver.match(source).then(function(result) { expect(result).to.be.ok(); }); }); }); - describe('.locate', function () { - it('should return source when plugin does not implement .locate', function () { - + describe('.locate', function() { + it('should return source when plugin does not implement .locate', function() { var mockPluginResolverWithoutLocate = function resolver(bower) { - return { - - match: function (source) { + match: function(source) { return true; }, - releases: function (source) { + releases: function(source) { return [ { target: 'v1.0.0', version: '1.0.0' }, { target: 'v1.0.1', version: '1.0.1' } ]; }, - fetch: function (endpoint, cached) { + fetch: function(endpoint, cached) { if (cached && cached.version) { return; } @@ -463,17 +469,21 @@ describe('pluginResolverFactory', function () { }; }; - var PluginResolver = pluginResolverFactory(mockPluginResolverWithoutLocate, - defaultConfig()); + var PluginResolver = pluginResolverFactory( + mockPluginResolverWithoutLocate, + defaultConfig() + ); var path = 'file://' + testPackage; expect(PluginResolver.locate(path)).to.be(path); }); - it('should locate the source', function () { - var PluginResolver = pluginResolverFactory(mockPluginResolver, - defaultConfig()); + it('should locate the source', function() { + var PluginResolver = pluginResolverFactory( + mockPluginResolver, + defaultConfig() + ); var source = 'jquery/jquery'; - PluginResolver.locate(source).then(function (result) { + PluginResolver.locate(source).then(function(result) { expect(result).to.be(source); }); }); diff --git a/test/core/resolvers/resolver.js b/test/core/resolvers/resolver.js index 49abf8515..08f43eb9a 100644 --- a/test/core/resolvers/resolver.js +++ b/test/core/resolvers/resolver.js @@ -12,14 +12,14 @@ var copy = require('../../../lib/util/copy'); var Resolver = require('../../../lib/core/resolvers/Resolver'); var defaultConfig = require('../../../lib/config'); -describe('Resolver', function () { +describe('Resolver', function() { var tempDir = path.resolve(__dirname, '../../tmp/tmp'); var testPackage = path.resolve(__dirname, '../../assets/package-a'); var logger; var dirMode0777; var config = defaultConfig(); - before(function () { + before(function() { var stat; mkdirp.sync(tempDir); @@ -30,7 +30,7 @@ describe('Resolver', function () { logger = new Logger(); }); - afterEach(function () { + afterEach(function() { logger.removeAllListeners(); }); @@ -42,231 +42,259 @@ describe('Resolver', function () { return new Resolver(decEndpoint, config, logger); } - describe('.getSource', function () { - it('should return the resolver source', function () { + describe('.getSource', function() { + it('should return the resolver source', function() { var resolver = create('foo'); expect(resolver.getSource()).to.equal('foo'); }); }); - describe('.getName', function () { - it('should return the resolver name', function () { + describe('.getName', function() { + it('should return the resolver name', function() { var resolver = create({ source: 'foo', name: 'bar' }); expect(resolver.getName()).to.equal('bar'); }); - it('should return the resolver source if none is specified (default guess mechanism)', function () { + it('should return the resolver source if none is specified (default guess mechanism)', function() { var resolver = create('foo'); expect(resolver.getName()).to.equal('foo'); }); }); - describe('.getTarget', function () { - it('should return the resolver target', function () { + describe('.getTarget', function() { + it('should return the resolver target', function() { var resolver = create({ source: 'foo', target: '~2.1.0' }); expect(resolver.getTarget()).to.equal('~2.1.0'); }); - it('should return * if none was configured', function () { + it('should return * if none was configured', function() { var resolver = create('foo'); expect(resolver.getTarget()).to.equal('*'); }); - it('should return * if latest was configured (for backwards compatibility)', function () { + it('should return * if latest was configured (for backwards compatibility)', function() { var resolver = create('foo'); expect(resolver.getTarget()).to.equal('*'); }); }); - describe('.hasNew', function () { - before(function () { + describe('.hasNew', function() { + before(function() { mkdirp.sync(tempDir); }); - beforeEach(function () { - fs.writeFileSync(path.join(tempDir, '.bower.json'), JSON.stringify({ - name: 'test' - })); + beforeEach(function() { + fs.writeFileSync( + path.join(tempDir, '.bower.json'), + JSON.stringify({ + name: 'test' + }) + ); }); - after(function (next) { + after(function(next) { rimraf(tempDir, next); }); - it('should throw an error if already working (resolving)', function (next) { + it('should throw an error if already working (resolving)', function(next) { var resolver = create('foo'); var succeeded; - resolver._resolve = function () {}; + resolver._resolve = function() {}; + + resolver + .resolve() + .then(function() { + // Test if resolve can be called again when done + resolver.resolve().then(function() { + next( + succeeded ? new Error('Should have failed') : null + ); + }); + }) + .done(); - resolver.resolve() - .then(function () { - // Test if resolve can be called again when done - resolver.resolve() - .then(function () { - next(succeeded ? new Error('Should have failed') : null); - }); - }) - .done(); - - resolver.hasNew({}) - .then(function () { - succeeded = true; - }, function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.equal('EWORKING'); - expect(err.message).to.match(/already working/i); - }); + resolver.hasNew({}).then( + function() { + succeeded = true; + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.equal('EWORKING'); + expect(err.message).to.match(/already working/i); + } + ); }); - it('should throw an error if already working (checking for newer version)', function (next) { + it('should throw an error if already working (checking for newer version)', function(next) { var resolver = create('foo'); var succeeded; - resolver.hasNew({}) - .then(function () { - // Test if hasNew can be called again when done - resolver.hasNew({}) - .then(function () { - next(succeeded ? new Error('Should have failed') : null); - }); - }) - .done(); - - resolver.hasNew({}) - .then(function () { - succeeded = true; - }, function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.equal('EWORKING'); - expect(err.message).to.match(/already working/i); - }); + resolver + .hasNew({}) + .then(function() { + // Test if hasNew can be called again when done + resolver.hasNew({}).then(function() { + next( + succeeded ? new Error('Should have failed') : null + ); + }); + }) + .done(); + + resolver.hasNew({}).then( + function() { + succeeded = true; + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.equal('EWORKING'); + expect(err.message).to.match(/already working/i); + } + ); }); - it('should resolve to true by default', function (next) { + it('should resolve to true by default', function(next) { var resolver = create('foo'); - resolver.hasNew({}) - .then(function (hasNew) { - expect(hasNew).to.equal(true); - next(); - }) - .done(); + resolver + .hasNew({}) + .then(function(hasNew) { + expect(hasNew).to.equal(true); + next(); + }) + .done(); }); - it('should call _hasNew with the package meta', function (next) { + it('should call _hasNew with the package meta', function(next) { var resolver = create('foo'); var meta; - resolver._hasNew = function (pkgMeta) { + resolver._hasNew = function(pkgMeta) { meta = pkgMeta; return Q.resolve(true); }; - resolver.hasNew({ name: 'test' }) - .then(function () { - expect(meta).to.be.an('object'); - expect(meta.name).to.equal('test'); - next(); - }) - .done(); + resolver + .hasNew({ name: 'test' }) + .then(function() { + expect(meta).to.be.an('object'); + expect(meta.name).to.equal('test'); + next(); + }) + .done(); }); - it('should not read the package meta if already passed', function (next) { + it('should not read the package meta if already passed', function(next) { var resolver = create('foo'); var meta; - resolver._hasNew = function (pkgMeta) { + resolver._hasNew = function(pkgMeta) { meta = pkgMeta; return Q.resolve(true); }; - resolver.hasNew({ - name: 'foo' - }) - .then(function () { - expect(meta).to.be.an('object'); - expect(meta.name).to.equal('foo'); - next(); - }) - .done(); + resolver + .hasNew({ + name: 'foo' + }) + .then(function() { + expect(meta).to.be.an('object'); + expect(meta.name).to.equal('foo'); + next(); + }) + .done(); }); }); - describe('.resolve', function () { - it('should reject the promise if _resolve is not implemented', function (next) { + describe('.resolve', function() { + it('should reject the promise if _resolve is not implemented', function(next) { var resolver = create('foo'); - resolver.resolve() - .then(function () { - next(new Error('Should have rejected the promise')); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.message).to.contain('_resolve not implemented'); - next(); - }) - .done(); + resolver + .resolve() + .then( + function() { + next(new Error('Should have rejected the promise')); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.message).to.contain( + '_resolve not implemented' + ); + next(); + } + ) + .done(); }); - it('should throw an error if already working (resolving)', function (next) { + it('should throw an error if already working (resolving)', function(next) { var resolver = create('foo'); var succeeded; - resolver._resolve = function () {}; + resolver._resolve = function() {}; + + resolver + .resolve() + .then(function() { + // Test if resolve can be called again when done + resolver.resolve().then(function() { + next( + succeeded ? new Error('Should have failed') : null + ); + }); + }) + .done(); - resolver.resolve() - .then(function () { - // Test if resolve can be called again when done - resolver.resolve() - .then(function () { - next(succeeded ? new Error('Should have failed') : null); - }); - }) - .done(); - - resolver.resolve() - .then(function () { - succeeded = true; - }, function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.equal('EWORKING'); - expect(err.message).to.match(/already working/i); - }); + resolver.resolve().then( + function() { + succeeded = true; + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.equal('EWORKING'); + expect(err.message).to.match(/already working/i); + } + ); }); - it('should throw an error if already working (checking newer version)', function (next) { + it('should throw an error if already working (checking newer version)', function(next) { var resolver = create('foo'); var succeeded; - resolver._resolve = function () {}; + resolver._resolve = function() {}; + + resolver + .hasNew({}) + .then(function() { + // Test if hasNew can be called again when done + resolver.hasNew({}).then(function() { + next( + succeeded ? new Error('Should have failed') : null + ); + }); + }) + .done(); - resolver.hasNew({}) - .then(function () { - // Test if hasNew can be called again when done - resolver.hasNew({}) - .then(function () { - next(succeeded ? new Error('Should have failed') : null); - }); - }) - .done(); - - resolver.resolve() - .then(function () { - succeeded = true; - }, function (err) { - expect(err).to.be.an(Error); - expect(err.code).to.equal('EWORKING'); - expect(err.message).to.match(/already working/i); - }); + resolver.resolve().then( + function() { + succeeded = true; + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.code).to.equal('EWORKING'); + expect(err.message).to.match(/already working/i); + } + ); }); - it('should call all the functions necessary to resolve by the correct order', function (next) { + it('should call all the functions necessary to resolve by the correct order', function(next) { var resolver; function DummyResolver() { @@ -276,343 +304,385 @@ describe('Resolver', function () { util.inherits(DummyResolver, Resolver); - DummyResolver.prototype.getStack = function () { + DummyResolver.prototype.getStack = function() { return this._stack; }; - DummyResolver.prototype.resolve = function () { + DummyResolver.prototype.resolve = function() { this._stack = []; return Resolver.prototype.resolve.apply(this, arguments); }; - DummyResolver.prototype._createTempDir = function () { + DummyResolver.prototype._createTempDir = function() { this._stack.push('before _createTempDir'); - return Resolver.prototype._createTempDir.apply(this, arguments) - .then(function (val) { - this._stack.push('after _createTempDir'); - return val; - }.bind(this)); + return Resolver.prototype._createTempDir + .apply(this, arguments) + .then( + function(val) { + this._stack.push('after _createTempDir'); + return val; + }.bind(this) + ); }; - DummyResolver.prototype._resolve = function () {}; - DummyResolver.prototype._readJson = function () { + DummyResolver.prototype._resolve = function() {}; + DummyResolver.prototype._readJson = function() { this._stack.push('before _readJson'); - return Resolver.prototype._readJson.apply(this, arguments) - .then(function (val) { - this._stack.push('after _readJson'); - return val; - }.bind(this)); + return Resolver.prototype._readJson.apply(this, arguments).then( + function(val) { + this._stack.push('after _readJson'); + return val; + }.bind(this) + ); }; - DummyResolver.prototype._applyPkgMeta = function () { + DummyResolver.prototype._applyPkgMeta = function() { this._stack.push('before _applyPkgMeta'); - return Resolver.prototype._applyPkgMeta.apply(this, arguments) - .then(function (val) { - this._stack.push('after _applyPkgMeta'); - return val; - }.bind(this)); + return Resolver.prototype._applyPkgMeta + .apply(this, arguments) + .then( + function(val) { + this._stack.push('after _applyPkgMeta'); + return val; + }.bind(this) + ); }; - DummyResolver.prototype._savePkgMeta = function () { + DummyResolver.prototype._savePkgMeta = function() { this._stack.push('before _savePkgMeta'); - return Resolver.prototype._savePkgMeta.apply(this, arguments) - .then(function (val) { - this._stack.push('after _savePkgMeta'); - return val; - }.bind(this)); + return Resolver.prototype._savePkgMeta + .apply(this, arguments) + .then( + function(val) { + this._stack.push('after _savePkgMeta'); + return val; + }.bind(this) + ); }; - resolver = new DummyResolver({ source: 'foo'}, config, logger); - - resolver.resolve() - .then(function () { - expect(resolver.getStack()).to.eql([ - 'before _createTempDir', - 'after _createTempDir', - 'before _readJson', - 'after _readJson', - // Both below are called in parallel - 'before _applyPkgMeta', - 'after _applyPkgMeta', - 'before _savePkgMeta', - 'after _savePkgMeta' - ]); - next(); - }) - .done(); - }); - - it('should resolve with the canonical dir (folder)', function (next) { + resolver = new DummyResolver({ source: 'foo' }, config, logger); + + resolver + .resolve() + .then(function() { + expect(resolver.getStack()).to.eql([ + 'before _createTempDir', + 'after _createTempDir', + 'before _readJson', + 'after _readJson', + // Both below are called in parallel + 'before _applyPkgMeta', + 'after _applyPkgMeta', + 'before _savePkgMeta', + 'after _savePkgMeta' + ]); + next(); + }) + .done(); + }); + + it('should resolve with the canonical dir (folder)', function(next) { var resolver = create('foo'); - resolver._resolve = function () {}; + resolver._resolve = function() {}; - resolver.resolve() - .then(function (folder) { - expect(folder).to.be.a('string'); - expect(fs.existsSync(folder)).to.be(true); - next(); - }) - .done(); + resolver + .resolve() + .then(function(folder) { + expect(folder).to.be.a('string'); + expect(fs.existsSync(folder)).to.be(true); + next(); + }) + .done(); }); }); - describe('.getTempDir', function () { - it('should return null if resolver is not yet resolved', function () { + describe('.getTempDir', function() { + it('should return null if resolver is not yet resolved', function() { var resolver = create('foo'); expect(resolver.getTempDir() == null).to.be(true); }); - it('should still return null if resolve failed', function () { - it('should still return null', function (next) { + it('should still return null if resolve failed', function() { + it('should still return null', function(next) { var resolver = create('foo'); - resolver._resolve = function () { - throw new Error('I\'ve failed to resolve'); + resolver._resolve = function() { + throw new Error("I've failed to resolve"); }; - resolver.resolve() - .fail(function () { + resolver.resolve().fail(function() { expect(resolver.getTempDir() == null).to.be(true); next(); }); }); }); - it('should return the canonical dir (folder) if resolve succeeded', function (next) { + it('should return the canonical dir (folder) if resolve succeeded', function(next) { var resolver = create('foo'); - resolver._resolve = function () {}; + resolver._resolve = function() {}; - resolver.resolve() - .then(function () { - var dir = resolver.getTempDir(); + resolver + .resolve() + .then(function() { + var dir = resolver.getTempDir(); - expect(dir).to.be.a('string'); - expect(fs.existsSync(dir)).to.be(true); - next(); - }) - .done(); + expect(dir).to.be.a('string'); + expect(fs.existsSync(dir)).to.be(true); + next(); + }) + .done(); }); }); - describe('.getPkgMeta', function () { - it('should return null if resolver is not yet resolved', function () { + describe('.getPkgMeta', function() { + it('should return null if resolver is not yet resolved', function() { var resolver = create('foo'); expect(resolver.getPkgMeta() == null).to.be(true); }); - it('should still return null if resolve failed', function () { - it('should still return null', function (next) { + it('should still return null if resolve failed', function() { + it('should still return null', function(next) { var resolver = create('foo'); - resolver._resolve = function () { - throw new Error('I\'ve failed to resolve'); + resolver._resolve = function() { + throw new Error("I've failed to resolve"); }; - resolver.resolve() - .fail(function () { + resolver.resolve().fail(function() { expect(resolver.getPkgMeta() == null).to.be(true); next(); }); }); }); - it('should return the package meta if resolve succeeded', function (next) { + it('should return the package meta if resolve succeeded', function(next) { var resolver = create('foo'); - resolver._resolve = function () {}; + resolver._resolve = function() {}; - resolver.resolve() - .then(function () { - expect(resolver.getPkgMeta()).to.be.an('object'); - next(); - }) - .done(); + resolver + .resolve() + .then(function() { + expect(resolver.getPkgMeta()).to.be.an('object'); + next(); + }) + .done(); }); }); - describe('._createTempDir', function () { - it('should create a directory inside a "username/bower" folder, located within the OS temp folder', function (next) { + describe('._createTempDir', function() { + it('should create a directory inside a "username/bower" folder, located within the OS temp folder', function(next) { var resolver = create('foo'); - resolver._createTempDir() - .then(function (dir) { - var dirname; - var osTempDir; + resolver + ._createTempDir() + .then(function(dir) { + var dirname; + var osTempDir; - expect(dir).to.be.a('string'); - expect(fs.existsSync(dir)).to.be(true); + expect(dir).to.be.a('string'); + expect(fs.existsSync(dir)).to.be(true); - dirname = path.dirname(dir); - osTempDir = path.resolve(tmp.tmpdir); + dirname = path.dirname(dir); + osTempDir = path.resolve(tmp.tmpdir); - expect(dir.indexOf(osTempDir)).to.be(0); - expect(dir.indexOf(config.tmp)).to.be(0); + expect(dir.indexOf(osTempDir)).to.be(0); + expect(dir.indexOf(config.tmp)).to.be(0); - expect(path.basename(dirname)).to.equal('bower'); - expect(path.dirname(path.dirname(dirname))).to.equal(osTempDir); - next(); - }) - .done(); + expect(path.basename(dirname)).to.equal('bower'); + expect(path.dirname(path.dirname(dirname))).to.equal( + osTempDir + ); + next(); + }) + .done(); }); - it('should set the dir mode the same as the process', function (next) { + it('should set the dir mode the same as the process', function(next) { var resolver = create('foo'); - resolver._createTempDir() - .then(function (dir) { - var stat = fs.statSync(dir); - var expectedMode = dirMode0777 & ~process.umask(); + resolver + ._createTempDir() + .then(function(dir) { + var stat = fs.statSync(dir); + var expectedMode = dirMode0777 & ~process.umask(); - expect(stat.mode).to.equal(expectedMode); - next(); - }) - .done(); + expect(stat.mode).to.equal(expectedMode); + next(); + }) + .done(); }); - it('should remove the folder after execution', function (next) { - this.timeout(15000); // Give some time to execute + it('should remove the folder after execution', function(next) { + this.timeout(15000); // Give some time to execute - rimraf(config.tmp, function (err) { + rimraf(config.tmp, function(err) { if (err) return next(err); - cmd('node', ['test/assets/test-temp-dir/test.js'], { cwd: path.resolve(__dirname, '../../..') }) - .then(function () { - expect(fs.existsSync(config.tmp)).to.be(true); - expect(fs.readdirSync(config.tmp)).to.eql([]); - next(); - }, function (err) { - next(new Error(err.details)); + cmd('node', ['test/assets/test-temp-dir/test.js'], { + cwd: path.resolve(__dirname, '../../..') }) - .done(); + .then( + function() { + expect(fs.existsSync(config.tmp)).to.be(true); + expect(fs.readdirSync(config.tmp)).to.eql([]); + next(); + }, + function(err) { + next(new Error(err.details)); + } + ) + .done(); }); }); - it('should remove the folder on an uncaught exception', function (next) { - rimraf(config.tmp, function (err) { + it('should remove the folder on an uncaught exception', function(next) { + rimraf(config.tmp, function(err) { if (err) return next(err); - cmd('node', ['test/assets/test-temp-dir/test-exception.js'], { cwd: path.resolve(__dirname, '../../..') }) - .then(function () { - next(new Error('The command should have failed')); - }, function () { - expect(fs.existsSync(config.tmp)).to.be(true); - expect(fs.readdirSync(config.tmp)).to.eql([]); - next(); + cmd('node', ['test/assets/test-temp-dir/test-exception.js'], { + cwd: path.resolve(__dirname, '../../..') }) - .done(); + .then( + function() { + next(new Error('The command should have failed')); + }, + function() { + expect(fs.existsSync(config.tmp)).to.be(true); + expect(fs.readdirSync(config.tmp)).to.eql([]); + next(); + } + ) + .done(); }); }); - it('should set _tempDir with the created directory', function (next) { + it('should set _tempDir with the created directory', function(next) { var resolver = create('foo'); - resolver._createTempDir() - .then(function (dir) { - expect(resolver._tempDir).to.be.ok(); - expect(resolver._tempDir).to.equal(dir); - next(); - }) - .done(); + resolver + ._createTempDir() + .then(function(dir) { + expect(resolver._tempDir).to.be.ok(); + expect(resolver._tempDir).to.equal(dir); + next(); + }) + .done(); }); - it('should remove @ from directory names', function (next) { + it('should remove @ from directory names', function(next) { var resolver = create('foo@bar'); - resolver._createTempDir() - .then(function (dir) { - expect(resolver._tempDir).to.be.ok(); - expect(resolver._tempDir.indexOf('@')).to.equal(-1); - next(); - }) - .done(); + resolver + ._createTempDir() + .then(function(dir) { + expect(resolver._tempDir).to.be.ok(); + expect(resolver._tempDir.indexOf('@')).to.equal(-1); + next(); + }) + .done(); }); }); - describe('._cleanTempDir', function () { - it('should not error out if temporary dir is not yet created', function (next) { + describe('._cleanTempDir', function() { + it('should not error out if temporary dir is not yet created', function(next) { var resolver = create('foo'); - resolver._cleanTempDir() - .then(next.bind(null)) - .done(); + resolver + ._cleanTempDir() + .then(next.bind(null)) + .done(); }); - it('should delete the temporary folder contents', function (next) { + it('should delete the temporary folder contents', function(next) { var resolver = create('foo'); - resolver._createTempDir() - .then(resolver._cleanTempDir.bind(resolver)) - .then(function (dir) { - expect(dir).to.equal(resolver.getTempDir()); - expect(fs.readdirSync(dir).length).to.be(0); - next(); - }) - .done(); + resolver + ._createTempDir() + .then(resolver._cleanTempDir.bind(resolver)) + .then(function(dir) { + expect(dir).to.equal(resolver.getTempDir()); + expect(fs.readdirSync(dir).length).to.be(0); + next(); + }) + .done(); }); - it('should keep the mode', function (next) { + it('should keep the mode', function(next) { var resolver = create('foo'); - resolver._createTempDir() - .then(resolver._cleanTempDir.bind(resolver)) - .then(function (dir) { - var stat = fs.statSync(dir); - var expectedMode = dirMode0777 & ~process.umask(); + resolver + ._createTempDir() + .then(resolver._cleanTempDir.bind(resolver)) + .then(function(dir) { + var stat = fs.statSync(dir); + var expectedMode = dirMode0777 & ~process.umask(); - expect(stat.mode).to.equal(expectedMode); - next(); - }) - .done(); + expect(stat.mode).to.equal(expectedMode); + next(); + }) + .done(); }); - it('should keep the dir path', function (next) { + it('should keep the dir path', function(next) { var resolver = create('foo'); var tempDir; - resolver._createTempDir() - .then(function (dir) { - tempDir = dir; - return resolver._cleanTempDir(); - }) - .then(function (dir) { - expect(dir).to.equal(tempDir); - next(); - }) - .done(); + resolver + ._createTempDir() + .then(function(dir) { + tempDir = dir; + return resolver._cleanTempDir(); + }) + .then(function(dir) { + expect(dir).to.equal(tempDir); + next(); + }) + .done(); }); }); - describe('._readJson', function () { - afterEach(function (next) { + describe('._readJson', function() { + afterEach(function(next) { rimraf(tempDir, next); }); - it('should read the bower.json file', function (next) { + it('should read the bower.json file', function(next) { var resolver = create('foo'); mkdirp.sync(tempDir); - fs.writeFileSync(path.join(tempDir, 'bower.json'), JSON.stringify({ name: 'foo', version: '0.0.0' })); - fs.writeFileSync(path.join(tempDir, 'component.json'), JSON.stringify({ name: 'bar', version: '0.0.0' })); - - resolver._readJson(tempDir) - .then(function (meta) { - expect(meta).to.be.an('object'); - expect(meta.name).to.equal('foo'); - expect(meta.version).to.equal('0.0.0'); - next(); - }) - .done(); + fs.writeFileSync( + path.join(tempDir, 'bower.json'), + JSON.stringify({ name: 'foo', version: '0.0.0' }) + ); + fs.writeFileSync( + path.join(tempDir, 'component.json'), + JSON.stringify({ name: 'bar', version: '0.0.0' }) + ); + + resolver + ._readJson(tempDir) + .then(function(meta) { + expect(meta).to.be.an('object'); + expect(meta.name).to.equal('foo'); + expect(meta.version).to.equal('0.0.0'); + next(); + }) + .done(); }); - it('should fallback to component.json (notifying a warn)', function (next) { + it('should fallback to component.json (notifying a warn)', function(next) { var resolver = create('foo'); var notified = false; mkdirp.sync(tempDir); - fs.writeFileSync(path.join(tempDir, 'component.json'), JSON.stringify({ name: 'bar', version: '0.0.0' })); + fs.writeFileSync( + path.join(tempDir, 'component.json'), + JSON.stringify({ name: 'bar', version: '0.0.0' }) + ); - logger.on('log', function (log) { + logger.on('log', function(log) { expect(log).to.be.an('object'); if (log.level === 'warn' && /deprecated/i.test(log.id)) { expect(log.message).to.contain('component.json'); @@ -620,61 +690,65 @@ describe('Resolver', function () { } }); - resolver._readJson(tempDir) - .then(function (meta) { - expect(meta).to.be.an('object'); - expect(meta.name).to.equal('bar'); - expect(meta.version).to.equal('0.0.0'); - expect(notified).to.be(true); - next(); - }) - .done(); + resolver + ._readJson(tempDir) + .then(function(meta) { + expect(meta).to.be.an('object'); + expect(meta.name).to.equal('bar'); + expect(meta.version).to.equal('0.0.0'); + expect(notified).to.be(true); + next(); + }) + .done(); }); - it('should resolve to an inferred json if no json file was found', function (next) { + it('should resolve to an inferred json if no json file was found', function(next) { var resolver = create('foo'); - resolver._readJson(tempDir) - .then(function (meta) { - expect(meta).to.be.an('object'); - expect(meta.name).to.equal('foo'); - next(); - }) - .done(); + resolver + ._readJson(tempDir) + .then(function(meta) { + expect(meta).to.be.an('object'); + expect(meta.name).to.equal('foo'); + next(); + }) + .done(); }); - it.skip('should apply normalisation, defaults and validation to the json object'); + it.skip( + 'should apply normalisation, defaults and validation to the json object' + ); }); - describe('._applyPkgMeta', function () { - afterEach(function (next) { + describe('._applyPkgMeta', function() { + afterEach(function(next) { rimraf(tempDir, next); }); - it('should resolve with the same package meta', function (next) { + it('should resolve with the same package meta', function(next) { var resolver = create('foo'); var meta = { name: 'foo' }; mkdirp.sync(tempDir); resolver._tempDir = tempDir; - resolver._applyPkgMeta(meta) - .then(function (retMeta) { - expect(retMeta).to.equal(meta); + resolver + ._applyPkgMeta(meta) + .then(function(retMeta) { + expect(retMeta).to.equal(meta); - // Test also with the ignore property because the code is different - meta = { name: 'foo', ignore: ['somefile'] }; + // Test also with the ignore property because the code is different + meta = { name: 'foo', ignore: ['somefile'] }; - return resolver._applyPkgMeta(meta) - .then(function (retMeta) { - expect(retMeta).to.equal(meta); - next(); - }); - }) - .done(); + return resolver._applyPkgMeta(meta).then(function(retMeta) { + expect(retMeta).to.equal(meta); + next(); + }); + }) + .done(); }); - it('should remove files that match the ignore patterns excluding main files', function (next) { + it('should remove files that match the ignore patterns excluding main files', function(next) { var resolver = create({ source: 'foo', name: 'foo' }); mkdirp.sync(tempDir); @@ -682,162 +756,188 @@ describe('Resolver', function () { // Checkout test package version 0.2.1 which has a bower.json // with ignores cmd('git', ['checkout', '0.2.2'], { cwd: testPackage }) - // Copy its contents to the temporary dir - .then(function () { - return copy.copyDir(testPackage, tempDir); - }) - .then(function () { - var json; - - // This is a very rudimentary check - // Complete checks are made in the 'describe' below - resolver._tempDir = tempDir; - json = JSON.parse(fs.readFileSync(path.join(tempDir, 'bower.json')).toString()); - - return resolver._applyPkgMeta(json) - .then(function () { - expect(fs.existsSync(path.join(tempDir, 'foo'))).to.be(true); - expect(fs.existsSync(path.join(tempDir, 'baz'))).to.be(true); - expect(fs.existsSync(path.join(tempDir, 'test'))).to.be(false); - expect(fs.existsSync(path.join(tempDir, 'bower.json'))).to.be(true); - expect(fs.existsSync(path.join(tempDir, 'main.js'))).to.be(true); - expect(fs.existsSync(path.join(tempDir, 'more/docs'))).to.be(false); - expect(fs.existsSync(path.join(tempDir, 'more/assets'))).to.be(false); - next(); - }); - }) - .done(); + // Copy its contents to the temporary dir + .then(function() { + return copy.copyDir(testPackage, tempDir); + }) + .then(function() { + var json; + + // This is a very rudimentary check + // Complete checks are made in the 'describe' below + resolver._tempDir = tempDir; + json = JSON.parse( + fs + .readFileSync(path.join(tempDir, 'bower.json')) + .toString() + ); + + return resolver._applyPkgMeta(json).then(function() { + expect(fs.existsSync(path.join(tempDir, 'foo'))).to.be( + true + ); + expect(fs.existsSync(path.join(tempDir, 'baz'))).to.be( + true + ); + expect(fs.existsSync(path.join(tempDir, 'test'))).to.be( + false + ); + expect( + fs.existsSync(path.join(tempDir, 'bower.json')) + ).to.be(true); + expect( + fs.existsSync(path.join(tempDir, 'main.js')) + ).to.be(true); + expect( + fs.existsSync(path.join(tempDir, 'more/docs')) + ).to.be(false); + expect( + fs.existsSync(path.join(tempDir, 'more/assets')) + ).to.be(false); + next(); + }); + }) + .done(); }); - describe('handling of ignore property according to the .gitignore spec', function () { - it.skip('A blank line matches no files, so it can serve as a separator for readability.'); + describe('handling of ignore property according to the .gitignore spec', function() { + it.skip( + 'A blank line matches no files, so it can serve as a separator for readability.' + ); it.skip('A line starting with # serves as a comment.'); - it.skip('An optional prefix ! which negates the pattern; any matching file excluded by a previous pattern will become included again...', function () { + it.skip('An optional prefix ! which negates the pattern; any matching file excluded by a previous pattern will become included again...', function() { // If a negated pattern matches, this will override lower precedence patterns sources. Put a backslash ("\") in front of the first "!" for patterns that begin with a literal "!", for example, "\!important!.txt". }); - it.skip('If the pattern ends with a slash, it is removed for the purpose of the following description, but it would only find a match with a directory...', function () { + it.skip('If the pattern ends with a slash, it is removed for the purpose of the following description, but it would only find a match with a directory...', function() { // In other words, foo/ will match a directory foo and paths underneath it, but will not match a regular file or a symbolic link foo (this is consistent with the way how pathspec works in general in git). }); - it.skip('If the pattern does not contain a slash /, git treats it as a shell glob pattern and checks for a match against the pathname without leading directories.'); - it.skip('Otherwise, git treats the pattern as a shell glob suitable for consumption by fnmatch(3) with the FNM_PATHNAME flag..', function () { + it.skip( + 'If the pattern does not contain a slash /, git treats it as a shell glob pattern and checks for a match against the pathname without leading directories.' + ); + it.skip('Otherwise, git treats the pattern as a shell glob suitable for consumption by fnmatch(3) with the FNM_PATHNAME flag..', function() { // wildcards in the pattern will not match a / in the pathname. For example, "Documentation/*.html" matches "Documentation/git.html" but not "Documentation/ppc/ppc.html" or "tools/perf/Documentation/perf.html". }); }); }); - describe('._savePkgMeta', function () { - before(function () { + describe('._savePkgMeta', function() { + before(function() { mkdirp.sync(tempDir); }); - afterEach(function (next) { + afterEach(function(next) { rimraf(path.join(tempDir, '.bower.json'), next); }); - after(function (next) { + after(function(next) { rimraf(tempDir, next); }); - it('should resolve with the same package meta', function (next) { + it('should resolve with the same package meta', function(next) { var resolver = create('foo'); var meta = { name: 'foo' }; resolver._tempDir = tempDir; - resolver._savePkgMeta(meta) - .then(function (retMeta) { - expect(retMeta).to.equal(meta); - next(); - }) - .done(); + resolver + ._savePkgMeta(meta) + .then(function(retMeta) { + expect(retMeta).to.equal(meta); + next(); + }) + .done(); }); - it('should set the original source and target in package meta file', function (next) { + it('should set the original source and target in package meta file', function(next) { var resolver = create({ source: 'bar', target: '~2.0.0' }); var meta = { name: 'foo' }; resolver._tempDir = tempDir; - resolver._savePkgMeta(meta) - .then(function (retMeta) { - expect(retMeta._source).to.equal('bar'); - expect(retMeta._target).to.equal('~2.0.0'); - next(); - }) - .done(); + resolver + ._savePkgMeta(meta) + .then(function(retMeta) { + expect(retMeta._source).to.equal('bar'); + expect(retMeta._target).to.equal('~2.0.0'); + next(); + }) + .done(); }); - it('should save the package meta to the package meta file (.bower.json)', function (next) { + it('should save the package meta to the package meta file (.bower.json)', function(next) { var resolver = create('foo'); resolver._tempDir = tempDir; - resolver._savePkgMeta({ name: 'bar' }) - .then(function (retMeta) { - fs.readFile(path.join(tempDir, '.bower.json'), function (err, contents) { - if (err) return next(err); - - contents = contents.toString(); - expect(JSON.parse(contents)).to.eql(retMeta); - next(); - }); - }) - .done(); + resolver + ._savePkgMeta({ name: 'bar' }) + .then(function(retMeta) { + fs.readFile(path.join(tempDir, '.bower.json'), function( + err, + contents + ) { + if (err) return next(err); + + contents = contents.toString(); + expect(JSON.parse(contents)).to.eql(retMeta); + next(); + }); + }) + .done(); }); }); - describe('#isTargetable', function () { - it('should return true by default', function () { + describe('#isTargetable', function() { + it('should return true by default', function() { expect(Resolver.isTargetable()).to.be(true); }); }); - describe('#versions', function () { - it('should resolve to an array by default', function (next) { + describe('#versions', function() { + it('should resolve to an array by default', function(next) { Resolver.versions() - .then(function (versions) { - expect(versions).to.be.an('array'); - expect(versions.length).to.be(0); + .then(function(versions) { + expect(versions).to.be.an('array'); + expect(versions.length).to.be(0); - next(); - }) - .done(); + next(); + }) + .done(); }); - }); - describe('#isCacheable', function () { - it('caches for normal name', function () { + describe('#isCacheable', function() { + it('caches for normal name', function() { var resolver = new Resolver({ source: 'foo' }); expect(resolver.isCacheable()).to.be(true); }); - it('does not cache for absolute paths', function () { + it('does not cache for absolute paths', function() { var resolver = new Resolver({ source: '/foo' }); expect(resolver.isCacheable()).to.be(false); }); - it('does not cache for relative paths', function () { + it('does not cache for relative paths', function() { var resolver = new Resolver({ source: './foo' }); expect(resolver.isCacheable()).to.be(false); }); - it('does not cache for parent paths', function () { + it('does not cache for parent paths', function() { var resolver = new Resolver({ source: '../foo' }); expect(resolver.isCacheable()).to.be(false); }); - it('does not cache for file:/// prefix', function () { + it('does not cache for file:/// prefix', function() { var resolver = new Resolver({ source: 'file:///foo' }); expect(resolver.isCacheable()).to.be(false); }); - it('does not cache for windows paths', function () { + it('does not cache for windows paths', function() { var resolver = new Resolver({ source: '..\\foo' }); expect(resolver.isCacheable()).to.be(false); }); - it('does not cache for windows absolute paths', function () { + it('does not cache for windows absolute paths', function() { var resolver = new Resolver({ source: 'C:\\foo' }); expect(resolver.isCacheable()).to.be(false); }); diff --git a/test/core/resolvers/svnResolver.js b/test/core/resolvers/svnResolver.js index c30b69081..f3fff779a 100644 --- a/test/core/resolvers/svnResolver.js +++ b/test/core/resolvers/svnResolver.js @@ -11,1042 +11,1146 @@ var SvnResolver = require('../../../lib/core/resolvers/SvnResolver'); var defaultConfig = require('../../../lib/config'); var helpers = require('../../helpers'); -if (!helpers.hasSvn()) describe.skip('SvnResolver', function () {}); -else describe('SvnResolver', function () { - var tempDir = path.resolve(__dirname, '../../tmp/tmp'); - var testPackage = path.resolve(__dirname, '../../assets/package-svn/repo'); - // var testPackageAdmin = path.resolve(__dirname, '../../assets/package-svn/admin'); - var originaltags = SvnResolver.tags; - var logger; - - before(function () { - logger = new Logger(); - }); - - afterEach(function () { - logger.removeAllListeners(); - }); - - function clearResolverRuntimeCache() { - SvnResolver.tags = originaltags; - SvnResolver.clearRuntimeCache(); - } - - function create(decEndpoint) { - if (typeof decEndpoint === 'string') { - decEndpoint = { source: decEndpoint }; - } - - return new SvnResolver(decEndpoint, defaultConfig(), logger); - } - - describe('misc', function () { - it.skip('should error out if svn is not installed'); - it.skip('should setup svn template dir to an empty folder'); - }); - - describe('.hasNew', function () { - before(function () { - mkdirp.sync(tempDir); - }); - - afterEach(function (next) { - clearResolverRuntimeCache(); - rimraf(path.join(tempDir, '.bower.json'), next); +if (!helpers.hasSvn()) describe.skip('SvnResolver', function() {}); +else + describe('SvnResolver', function() { + var tempDir = path.resolve(__dirname, '../../tmp/tmp'); + var testPackage = path.resolve( + __dirname, + '../../assets/package-svn/repo' + ); + // var testPackageAdmin = path.resolve(__dirname, '../../assets/package-svn/admin'); + var originaltags = SvnResolver.tags; + var logger; + + before(function() { + logger = new Logger(); }); - after(function (next) { - rimraf(tempDir, next); + afterEach(function() { + logger.removeAllListeners(); }); + function clearResolverRuntimeCache() { + SvnResolver.tags = originaltags; + SvnResolver.clearRuntimeCache(); + } - it('should be true when the resolution type is different', function (next) { - var resolver; - - var pkgMeta = { - name: 'foo', - version: '0.0.0', - _resolution: { - type: 'version', - tag: '0.0.0', - commit: 123 - } - }; + function create(decEndpoint) { + if (typeof decEndpoint === 'string') { + decEndpoint = { source: decEndpoint }; + } - SvnResolver.tags = function () { - return Q.resolve({ - 'boo': 123 // same commit hash on purpose - }); - }; + return new SvnResolver(decEndpoint, defaultConfig(), logger); + } - SvnResolver.branches = function () { - return Q.resolve({ - 'trunk': '*' - }); - }; - - resolver = create('foo'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(true); - next(); - }) - .done(); + describe('misc', function() { + it.skip('should error out if svn is not installed'); + it.skip('should setup svn template dir to an empty folder'); }); - it('should be true when a higher version for a range is available', function (next) { - var resolver; + describe('.hasNew', function() { + before(function() { + mkdirp.sync(tempDir); + }); - var pkgMeta = { - name: 'foo', - version: '1.0.0', - _resolution: { - type: 'version', - tag: '1.0.0', - commit: 3 - } - }; + afterEach(function(next) { + clearResolverRuntimeCache(); + rimraf(path.join(tempDir, '.bower.json'), next); + }); - SvnResolver.tags = function () { - return Q.resolve({ - '1.0.0': 2, - '1.0.1': 2 // same commit hash on purpose - }); - }; - - resolver = create('foo'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(true); - next(); - }) - .done(); - }); + after(function(next) { + rimraf(tempDir, next); + }); - it('should be true when a resolved to a lower version of a range', function (next) { - var resolver; + it('should be true when the resolution type is different', function(next) { + var resolver; - var pkgMeta = { - name: 'foo', - version: '1.0.1', - _resolution: { - type: 'version', - tag: '1.0.1', - commit: 3 - } - }; + var pkgMeta = { + name: 'foo', + version: '0.0.0', + _resolution: { + type: 'version', + tag: '0.0.0', + commit: 123 + } + }; - SvnResolver.tags = function () { - return Q.resolve({ - '1.0.0': 2 - }); - }; - - resolver = create('foo'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(true); - next(); - }) - .done(); - }); + SvnResolver.tags = function() { + return Q.resolve({ + boo: 123 // same commit hash on purpose + }); + }; - it('should be false when resolved to the same tag (with same commit hash) for a given range', function (next) { - var resolver; + SvnResolver.branches = function() { + return Q.resolve({ + trunk: '*' + }); + }; + + resolver = create('foo'); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); + }); - var pkgMeta = { - name: 'foo', - version: '1.0.1', - _resolution: { - type: 'version', - tag: '1.0.1', - commit: 2 - } - }; + it('should be true when a higher version for a range is available', function(next) { + var resolver; - SvnResolver.tags = function () { - return Q.resolve({ - '1.0.0': 1, - '1.0.1': 2 - }); - }; - - resolver = create('foo'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(false); - next(); - }) - .done(); - }); + var pkgMeta = { + name: 'foo', + version: '1.0.0', + _resolution: { + type: 'version', + tag: '1.0.0', + commit: 3 + } + }; - it('should be true when resolved to the same tag (with different commit hash) for a given range', function (next) { - var resolver; + SvnResolver.tags = function() { + return Q.resolve({ + '1.0.0': 2, + '1.0.1': 2 // same commit hash on purpose + }); + }; + + resolver = create('foo'); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); + }); - var pkgMeta = { - name: 'foo', - version: '1.0.1', - _resolution: { - type: 'version', - tag: '1.0.1', - commit: 3 - } - }; + it('should be true when a resolved to a lower version of a range', function(next) { + var resolver; - SvnResolver.tags = function () { - return Q.resolve({ - '1.0.0': 2, - '1.0.1': 4 - }); - }; - - resolver = create('foo'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(true); - next(); - }) - .done(); - }); + var pkgMeta = { + name: 'foo', + version: '1.0.1', + _resolution: { + type: 'version', + tag: '1.0.1', + commit: 3 + } + }; + SvnResolver.tags = function() { + return Q.resolve({ + '1.0.0': 2 + }); + }; + + resolver = create('foo'); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); + }); - it('should be false when targeting commit hashes', function (next) { - var resolver; + it('should be false when resolved to the same tag (with same commit hash) for a given range', function(next) { + var resolver; - var pkgMeta = { - name: 'foo', - _resolution: { - type: 'commit', - commit: 1 - } - }; + var pkgMeta = { + name: 'foo', + version: '1.0.1', + _resolution: { + type: 'version', + tag: '1.0.1', + commit: 2 + } + }; - SvnResolver.tags = function () { - return Q.resolve({ - '1.0.0': 2 - }); - }; - - resolver = create('foo'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(true); - next(); - }) - .done(); - }); - }); + SvnResolver.tags = function() { + return Q.resolve({ + '1.0.0': 1, + '1.0.1': 2 + }); + }; + + resolver = create('foo'); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(false); + next(); + }) + .done(); + }); - describe('._resolve', function () { - afterEach(clearResolverRuntimeCache); + it('should be true when resolved to the same tag (with different commit hash) for a given range', function(next) { + var resolver; - it('should call the necessary functions by the correct order', function (next) { - var resolver; + var pkgMeta = { + name: 'foo', + version: '1.0.1', + _resolution: { + type: 'version', + tag: '1.0.1', + commit: 3 + } + }; - function DummyResolver() { - SvnResolver.apply(this, arguments); - this._stack = []; - } + SvnResolver.tags = function() { + return Q.resolve({ + '1.0.0': 2, + '1.0.1': 4 + }); + }; + + resolver = create('foo'); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); + }); - util.inherits(DummyResolver, SvnResolver); - mout.object.mixIn(DummyResolver, SvnResolver); + it('should be false when targeting commit hashes', function(next) { + var resolver; - DummyResolver.prototype.getStack = function () { - return this._stack; - }; + var pkgMeta = { + name: 'foo', + _resolution: { + type: 'commit', + commit: 1 + } + }; - DummyResolver.tags = function () { - return Q.resolve({ - '1.0.0': 1 - }); - }; - - DummyResolver.prototype.resolve = function () { - this._stack = []; - return SvnResolver.prototype.resolve.apply(this, arguments); - }; - - DummyResolver.prototype._findResolution = function () { - this._stack.push('before _findResolution'); - return SvnResolver.prototype._findResolution.apply(this, arguments) - .then(function (val) { - this._stack.push('after _findResolution'); - return val; - }.bind(this)); - }; - - DummyResolver.prototype._export = function () { - this._stack.push('before _export'); - return Q.resolve() - .then(function (val) { - this._stack.push('after _export'); - return val; - }.bind(this)); - }; - - resolver = new DummyResolver({ source: 'foo', target: '1.0.0' }, defaultConfig(), logger); - - resolver.resolve() - .then(function () { - expect(resolver.getStack()).to.eql([ - 'before _findResolution', - 'after _findResolution', - 'before _export', - 'after _export' - ]); - next(); - }) - .done(); + SvnResolver.tags = function() { + return Q.resolve({ + '1.0.0': 2 + }); + }; + + resolver = create('foo'); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); + }); }); - }); - - describe('._findResolution', function () { - afterEach(clearResolverRuntimeCache); + describe('._resolve', function() { + afterEach(clearResolverRuntimeCache); - it('should resolve to an object', function (next) { - var resolver; + it('should call the necessary functions by the correct order', function(next) { + var resolver; - SvnResolver.tags = function () { - return Q.resolve({}); - }; + function DummyResolver() { + SvnResolver.apply(this, arguments); + this._stack = []; + } - resolver = create('foo'); - resolver._findResolution('*') - .then(function (resolution) { - expect(resolution).to.be.an('object'); - next(); - }) - .done(); - }); + util.inherits(DummyResolver, SvnResolver); + mout.object.mixIn(DummyResolver, SvnResolver); - it('should resolve "*" to the trunk if a repository has no valid semver tags', function (next) { - var resolver; + DummyResolver.prototype.getStack = function() { + return this._stack; + }; - SvnResolver.tags = function () { - return Q.resolve({ - 'some-tag': 1 - }); - }; - - resolver = create('foo'); - resolver._findResolution('*') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'branch', - branch: 'trunk', - commit: '*' - }); - next(); - }) - .done(); + DummyResolver.tags = function() { + return Q.resolve({ + '1.0.0': 1 + }); + }; + + DummyResolver.prototype.resolve = function() { + this._stack = []; + return SvnResolver.prototype.resolve.apply(this, arguments); + }; + + DummyResolver.prototype._findResolution = function() { + this._stack.push('before _findResolution'); + return SvnResolver.prototype._findResolution + .apply(this, arguments) + .then( + function(val) { + this._stack.push('after _findResolution'); + return val; + }.bind(this) + ); + }; + + DummyResolver.prototype._export = function() { + this._stack.push('before _export'); + return Q.resolve().then( + function(val) { + this._stack.push('after _export'); + return val; + }.bind(this) + ); + }; + + resolver = new DummyResolver( + { source: 'foo', target: '1.0.0' }, + defaultConfig(), + logger + ); + + resolver + .resolve() + .then(function() { + expect(resolver.getStack()).to.eql([ + 'before _findResolution', + 'after _findResolution', + 'before _export', + 'after _export' + ]); + next(); + }) + .done(); + }); }); - it('should resolve "*" to the latest version if a repository has valid semver tags, ignoring pre-releases', function (next) { - var resolver; + describe('._findResolution', function() { + afterEach(clearResolverRuntimeCache); - SvnResolver.tags = function () { - return Q.resolve({ - '0.1.0': 1, - 'v0.1.1': 2, - '0.2.0-rc.1': 3 // Should ignore release candidates - }); - }; + it('should resolve to an object', function(next) { + var resolver; - resolver = create('foo'); - resolver._findResolution('*') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'version', - tag: 'v0.1.1', - commit: 2 - }); - next(); - }) - .done(); - }); + SvnResolver.tags = function() { + return Q.resolve({}); + }; - it('should resolve "*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function (next) { - var resolver; + resolver = create('foo'); + resolver + ._findResolution('*') + .then(function(resolution) { + expect(resolution).to.be.an('object'); + next(); + }) + .done(); + }); - SvnResolver.tags = function () { - return Q.resolve({ - '0.1.0-rc.1': 1, - '0.1.0-rc.2': 2 - }); - }; + it('should resolve "*" to the trunk if a repository has no valid semver tags', function(next) { + var resolver; - resolver = create('foo'); - resolver._findResolution('*') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'version', - tag: '0.1.0-rc.2', - commit: 2 - }); - next(); - }) - .done(); - }); + SvnResolver.tags = function() { + return Q.resolve({ + 'some-tag': 1 + }); + }; + + resolver = create('foo'); + resolver + ._findResolution('*') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'branch', + branch: 'trunk', + commit: '*' + }); + next(); + }) + .done(); + }); - it('should resolve to the latest version that matches a range/version', function (next) { - var resolver; + it('should resolve "*" to the latest version if a repository has valid semver tags, ignoring pre-releases', function(next) { + var resolver; - SvnResolver.tags = function () { - return Q.resolve({ - '0.1.0': 1, - 'v0.1.1': 2, - '0.2.0': 3, - 'v0.2.1': 4 - }); - }; + SvnResolver.tags = function() { + return Q.resolve({ + '0.1.0': 1, + 'v0.1.1': 2, + '0.2.0-rc.1': 3 // Should ignore release candidates + }); + }; + + resolver = create('foo'); + resolver + ._findResolution('*') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: 'v0.1.1', + commit: 2 + }); + next(); + }) + .done(); + }); - resolver = create('foo'); - resolver._findResolution('~0.2.0') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'version', - tag: 'v0.2.1', - commit: 4 - }); - next(); - }) - .done(); - }); + it('should resolve "*" to the latest version if a repository has valid semver tags, not ignoring pre-releases if they are the only versions', function(next) { + var resolver; - it('should resolve to a tag even if target is a range that does not exist', function (next) { - var resolver; + SvnResolver.tags = function() { + return Q.resolve({ + '0.1.0-rc.1': 1, + '0.1.0-rc.2': 2 + }); + }; + + resolver = create('foo'); + resolver + ._findResolution('*') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: '0.1.0-rc.2', + commit: 2 + }); + next(); + }) + .done(); + }); - SvnResolver.tags = function () { - return Q.resolve({ - '1.0': 1 - }); - }; - - resolver = create('foo'); - resolver._findResolution('1.0') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'tag', - tag: '1.0', - commit: 1 - }); - next(); - }) - .done(); - }); + it('should resolve to the latest version that matches a range/version', function(next) { + var resolver; - it('should resolve to the latest pre-release version that matches a range/version', function (next) { - var resolver; + SvnResolver.tags = function() { + return Q.resolve({ + '0.1.0': 1, + 'v0.1.1': 2, + '0.2.0': 3, + 'v0.2.1': 4 + }); + }; + + resolver = create('foo'); + resolver + ._findResolution('~0.2.0') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: 'v0.2.1', + commit: 4 + }); + next(); + }) + .done(); + }); - SvnResolver.tags = function () { - return Q.resolve({ - '0.1.0': 1, - 'v0.1.1': 2, - '0.2.0': 3, - 'v0.2.1-rc.1': 4 - }); - }; + it('should resolve to a tag even if target is a range that does not exist', function(next) { + var resolver; - resolver = create('foo'); - resolver._findResolution('~0.2.1') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'version', - tag: 'v0.2.1-rc.1', - commit: 4 - }); - next(); - }) - .done(); - }); + SvnResolver.tags = function() { + return Q.resolve({ + '1.0': 1 + }); + }; + + resolver = create('foo'); + resolver + ._findResolution('1.0') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'tag', + tag: '1.0', + commit: 1 + }); + next(); + }) + .done(); + }); - it('should resolve to the exact version if exists', function (next) { - var resolver; + it('should resolve to the latest pre-release version that matches a range/version', function(next) { + var resolver; - SvnResolver.tags = function () { - return Q.resolve({ - '0.8.1' : 1, - '0.8.1+build.1': 2, - '0.8.1+build.2': 3, - '0.8.1+build.3': 4 - }); - }; + SvnResolver.tags = function() { + return Q.resolve({ + '0.1.0': 1, + 'v0.1.1': 2, + '0.2.0': 3, + 'v0.2.1-rc.1': 4 + }); + }; + + resolver = create('foo'); + resolver + ._findResolution('~0.2.1') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: 'v0.2.1-rc.1', + commit: 4 + }); + next(); + }) + .done(); + }); - resolver = create('foo'); - resolver._findResolution('0.8.1+build.2') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'version', - tag: '0.8.1+build.2', - commit: 3 - }); - next(); - }) - .done(); - }); + it('should resolve to the exact version if exists', function(next) { + var resolver; - it('should fail to resolve if none of the versions matched a range/version', function (next) { - var resolver; + SvnResolver.tags = function() { + return Q.resolve({ + '0.8.1': 1, + '0.8.1+build.1': 2, + '0.8.1+build.2': 3, + '0.8.1+build.3': 4 + }); + }; + + resolver = create('foo'); + resolver + ._findResolution('0.8.1+build.2') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'version', + tag: '0.8.1+build.2', + commit: 3 + }); + next(); + }) + .done(); + }); - SvnResolver.tags = function () { - return Q.resolve({ - '0.1.0': 1, - 'v0.1.1': 2 - }); - }; - - resolver = create('foo'); - resolver._findResolution('~0.2.0') - .then(function () { - next(new Error('Should have failed')); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.message).to.match(/was able to satisfy ~0.2.0/i); - expect(err.details).to.match(/available versions in foo: 0\.1\.1, 0\.1\.0/i); - expect(err.code).to.equal('ENORESTARGET'); - next(); - }) - .done(); - }); + it('should fail to resolve if none of the versions matched a range/version', function(next) { + var resolver; - it('should fail to resolve if there are no versions to match a range/version', function (next) { - var resolver; + SvnResolver.tags = function() { + return Q.resolve({ + '0.1.0': 1, + 'v0.1.1': 2 + }); + }; + + resolver = create('foo'); + resolver + ._findResolution('~0.2.0') + .then( + function() { + next(new Error('Should have failed')); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.message).to.match( + /was able to satisfy ~0.2.0/i + ); + expect(err.details).to.match( + /available versions in foo: 0\.1\.1, 0\.1\.0/i + ); + expect(err.code).to.equal('ENORESTARGET'); + next(); + } + ) + .done(); + }); - SvnResolver.tags = function () { - return Q.resolve({ - 'foo': 1 - }); - }; - - resolver = create('foo'); - - resolver._findResolution('~0.2.0') - .then(function () { - next(new Error('Should have failed')); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.message).to.match(/was able to satisfy ~0.2.0/i); - expect(err.details).to.match(/no versions found in foo/i); - expect(err.code).to.equal('ENORESTARGET'); - next(); - }) - .done(); - }); + it('should fail to resolve if there are no versions to match a range/version', function(next) { + var resolver; - it('should resolve to the specified commit', function (next) { - var resolver; + SvnResolver.tags = function() { + return Q.resolve({ + foo: 1 + }); + }; + + resolver = create('foo'); + + resolver + ._findResolution('~0.2.0') + .then( + function() { + next(new Error('Should have failed')); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.message).to.match( + /was able to satisfy ~0.2.0/i + ); + expect(err.details).to.match( + /no versions found in foo/i + ); + expect(err.code).to.equal('ENORESTARGET'); + next(); + } + ) + .done(); + }); - SvnResolver.tags = function () { - return Q.resolve({ - 'some-tag': 1 - }); - }; - - resolver = create('foo'); - resolver._findResolution('r1') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'commit', - commit: 1 - }); - next(); - }) - .done(); - }); + it('should resolve to the specified commit', function(next) { + var resolver; - it('should resolve to the specified tag if it exists', function (next) { - var resolver; + SvnResolver.tags = function() { + return Q.resolve({ + 'some-tag': 1 + }); + }; + + resolver = create('foo'); + resolver + ._findResolution('r1') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'commit', + commit: 1 + }); + next(); + }) + .done(); + }); - SvnResolver.tags = function () { - return Q.resolve({ - 'some-tag': 1 - }); - }; - - resolver = create('foo'); - resolver._findResolution('some-tag') - .then(function (resolution) { - expect(resolution).to.eql({ - type: 'tag', - tag: 'some-tag', - commit: 1 - }); - next(); - }) - .done(); - }); + it('should resolve to the specified tag if it exists', function(next) { + var resolver; - it('should fail to resolve to the specified tag if it doesn\'t exists', function (next) { - var resolver; + SvnResolver.tags = function() { + return Q.resolve({ + 'some-tag': 1 + }); + }; + + resolver = create('foo'); + resolver + ._findResolution('some-tag') + .then(function(resolution) { + expect(resolution).to.eql({ + type: 'tag', + tag: 'some-tag', + commit: 1 + }); + next(); + }) + .done(); + }); - SvnResolver.tags = function () { - return Q.resolve({ - 'some-tag': 2 - }); - }; - - resolver = create('foo'); - resolver._findResolution('some-branch') - .then(function () { - next(new Error('Should have failed')); - }, function (err) { - expect(err).to.be.an(Error); - expect(err.message).to.match(/target some-branch does not exist/i); - expect(err.details).to.match(/available tags: some-tag/i); - expect(err.code).to.equal('ENORESTARGET'); - next(); - }) - .done(); - }); - }); + it("should fail to resolve to the specified tag if it doesn't exists", function(next) { + var resolver; - describe('._savePkgMeta', function () { - before(function () { - mkdirp.sync(tempDir); + SvnResolver.tags = function() { + return Q.resolve({ + 'some-tag': 2 + }); + }; + + resolver = create('foo'); + resolver + ._findResolution('some-branch') + .then( + function() { + next(new Error('Should have failed')); + }, + function(err) { + expect(err).to.be.an(Error); + expect(err.message).to.match( + /target some-branch does not exist/i + ); + expect(err.details).to.match( + /available tags: some-tag/i + ); + expect(err.code).to.equal('ENORESTARGET'); + next(); + } + ) + .done(); + }); }); - afterEach(function (next) { - rimraf(path.join(tempDir, '.bower.json'), next); - }); + describe('._savePkgMeta', function() { + before(function() { + mkdirp.sync(tempDir); + }); - after(function (next) { - rimraf(tempDir, next); - }); + afterEach(function(next) { + rimraf(path.join(tempDir, '.bower.json'), next); + }); - it('should save the resolution to the .bower.json to be used later by .hasNew', function (next) { - var resolver = create('foo'); + after(function(next) { + rimraf(tempDir, next); + }); - resolver._resolution = { type: 'version', tag: '0.0.1' }; - resolver._tempDir = tempDir; + it('should save the resolution to the .bower.json to be used later by .hasNew', function(next) { + var resolver = create('foo'); + + resolver._resolution = { type: 'version', tag: '0.0.1' }; + resolver._tempDir = tempDir; + + resolver + ._savePkgMeta({ name: 'foo', version: '0.0.1' }) + .then(function() { + return Q.nfcall( + fs.readFile, + path.join(tempDir, '.bower.json') + ); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + + expect(json._resolution).to.eql(resolver._resolution); + next(); + }) + .done(); + }); - resolver._savePkgMeta({ name: 'foo', version: '0.0.1' }) - .then(function () { - return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); + it('should save the release in the package meta', function(next) { + var resolver = create('foo'); + var metaFile = path.join(tempDir, '.bower.json'); - expect(json._resolution).to.eql(resolver._resolution); - next(); - }) - .done(); - }); + // Test with type 'version' + resolver._resolution = { + type: 'version', + tag: '0.0.1', + commit: '1' + }; + resolver._tempDir = tempDir; + + resolver + ._savePkgMeta({ name: 'foo', version: '0.0.1' }) + .then(function() { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('0.0.1'); + }) + // Test with type 'version' + build metadata + .then(function() { + resolver._resolution = { + type: 'version', + tag: '0.0.1+build.5', + commit: '1' + }; + return resolver._savePkgMeta({ name: 'foo' }); + }) + .then(function() { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('0.0.1+build.5'); + }) + // Test with type 'tag' + .then(function() { + resolver._resolution = { + type: 'tag', + tag: '0.0.1', + commit: '1' + }; + return resolver._savePkgMeta({ name: 'foo' }); + }) + .then(function() { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('0.0.1'); + }) + // Test with type 'branch' + // In this case, it should be the commit + .then(function() { + resolver._resolution = { + type: 'branch', + branch: 'foo', + commit: '1' + }; + return resolver._savePkgMeta({ name: 'foo' }); + }) + .then(function() { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('1'); + }) + // Test with type 'commit' + .then(function() { + resolver._resolution = { type: 'commit', commit: '1' }; + return resolver._savePkgMeta({ name: 'foo' }); + }) + .then(function() { + return Q.nfcall(fs.readFile, metaFile); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json._release).to.equal('1'); + next(); + }) + .done(); + }); - it('should save the release in the package meta', function (next) { - var resolver = create('foo'); - var metaFile = path.join(tempDir, '.bower.json'); - - // Test with type 'version' - resolver._resolution = { type: 'version', tag: '0.0.1', commit: '1' }; - resolver._tempDir = tempDir; - - resolver._savePkgMeta({ name: 'foo', version: '0.0.1' }) - .then(function () { - return Q.nfcall(fs.readFile, metaFile); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json._release).to.equal('0.0.1'); - }) - // Test with type 'version' + build metadata - .then(function () { - resolver._resolution = { type: 'version', tag: '0.0.1+build.5', commit: '1' }; - return resolver._savePkgMeta({ name: 'foo' }); - }) - .then(function () { - return Q.nfcall(fs.readFile, metaFile); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json._release).to.equal('0.0.1+build.5'); - }) - // Test with type 'tag' - .then(function () { - resolver._resolution = { type: 'tag', tag: '0.0.1', commit: '1' }; - return resolver._savePkgMeta({ name: 'foo' }); - }) - .then(function () { - return Q.nfcall(fs.readFile, metaFile); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json._release).to.equal('0.0.1'); - }) - // Test with type 'branch' - // In this case, it should be the commit - .then(function () { - resolver._resolution = { type: 'branch', branch: 'foo', commit: '1' }; - return resolver._savePkgMeta({ name: 'foo' }); - }) - .then(function () { - return Q.nfcall(fs.readFile, metaFile); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json._release).to.equal('1'); - }) - // Test with type 'commit' - .then(function () { - resolver._resolution = { type: 'commit', commit: '1' }; - return resolver._savePkgMeta({ name: 'foo' }); - }) - .then(function () { - return Q.nfcall(fs.readFile, metaFile); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json._release).to.equal('1'); - next(); - }) - .done(); - }); + it('should add the version to the package meta if not present and resolution is a version', function(next) { + var resolver = create('foo'); + + resolver._resolution = { type: 'version', tag: 'v0.0.1' }; + resolver._tempDir = tempDir; + + resolver + ._savePkgMeta({ name: 'foo' }) + .then(function() { + return Q.nfcall( + fs.readFile, + path.join(tempDir, '.bower.json') + ); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json.version).to.equal('0.0.1'); + + next(); + }) + .done(); + }); - it('should add the version to the package meta if not present and resolution is a version', function (next) { - var resolver = create('foo'); + it('should remove the version from the package meta if resolution is not a version', function(next) { + var resolver = create('foo'); - resolver._resolution = { type: 'version', tag: 'v0.0.1' }; - resolver._tempDir = tempDir; + resolver._resolution = { type: 'commit', commit: '1' }; + resolver._tempDir = tempDir; + + resolver + ._savePkgMeta({ name: 'foo', version: '0.0.1' }) + .then(function() { + return Q.nfcall( + fs.readFile, + path.join(tempDir, '.bower.json') + ); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json).to.not.have.property('version'); + + next(); + }) + .done(); + }); - resolver._savePkgMeta({ name: 'foo' }) - .then(function () { - return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json.version).to.equal('0.0.1'); + it('should warn if the resolution version is different than the package meta version', function(next) { + var resolver = create('foo'); + var notified = false; - next(); - }) - .done(); - }); + resolver._resolution = { type: 'version', tag: '0.0.1' }; + resolver._tempDir = tempDir; - it('should remove the version from the package meta if resolution is not a version', function (next) { - var resolver = create('foo'); + logger.on('log', function(log) { + expect(log).to.be.an('object'); - resolver._resolution = { type: 'commit', commit: '1' }; - resolver._tempDir = tempDir; + if (log.level === 'warn' && log.id === 'mismatch') { + expect(log.message).to.match( + /\(0\.0\.0\).*different.*\(0\.0\.1\)/ + ); + notified = true; + } + }); - resolver._savePkgMeta({ name: 'foo', version: '0.0.1' }) - .then(function () { - return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json).to.not.have.property('version'); + resolver + ._savePkgMeta({ name: 'foo', version: '0.0.0' }) + .then(function() { + return Q.nfcall( + fs.readFile, + path.join(tempDir, '.bower.json') + ); + }) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json.version).to.equal('0.0.1'); + expect(notified).to.be(true); + + next(); + }) + .done(); + }); - next(); - }) - .done(); + it('should not warn if the resolution version and the package meta version are the same', function(next) { + var resolver = create('foo'); + var notified = false; + + resolver._resolution = { type: 'version', tag: 'v0.0.1' }; + resolver._tempDir = tempDir; + + resolver + ._savePkgMeta({ name: 'foo', version: '0.0.1' }) + .then(function() { + return Q.nfcall( + fs.readFile, + path.join(tempDir, '.bower.json') + ); + }, null) + .then(function(contents) { + var json = JSON.parse(contents.toString()); + expect(json.version).to.equal('0.0.1'); + expect(notified).to.be(false); + + next(); + }) + .done(); + }); }); - it('should warn if the resolution version is different than the package meta version', function (next) { - var resolver = create('foo'); - var notified = false; - - resolver._resolution = { type: 'version', tag: '0.0.1' }; - resolver._tempDir = tempDir; - - logger.on('log', function (log) { - expect(log).to.be.an('object'); - - if (log.level === 'warn' && log.id === 'mismatch') { - expect(log.message).to.match(/\(0\.0\.0\).*different.*\(0\.0\.1\)/); - notified = true; - } + describe('#clearRuntimeCache', function() { + // Use a class that inherit the SvnResolver to see if it uses + // late binding when clearing the cache + function CustomSvnResolver() {} + util.inherits(CustomSvnResolver, SvnResolver); + mout.object.mixIn(CustomSvnResolver, SvnResolver); + + it('should clear tags cache', function() { + CustomSvnResolver._cache.tags.set('foo', {}); + CustomSvnResolver.clearRuntimeCache(); + expect(CustomSvnResolver._cache.tags.has('foo')).to.be(false); }); - resolver._savePkgMeta({ name: 'foo', version: '0.0.0' }) - .then(function () { - return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); - }) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json.version).to.equal('0.0.1'); - expect(notified).to.be(true); - - next(); - }) - .done(); + it('should clear versions cache', function() { + CustomSvnResolver._cache.versions.set('foo', {}); + CustomSvnResolver.clearRuntimeCache(); + expect(CustomSvnResolver._cache.versions.has('foo')).to.be( + false + ); + }); }); - it('should not warn if the resolution version and the package meta version are the same', function (next) { - var resolver = create('foo'); - var notified = false; - - resolver._resolution = { type: 'version', tag: 'v0.0.1' }; - resolver._tempDir = tempDir; - - resolver._savePkgMeta({ name: 'foo', version: '0.0.1' }) - .then(function () { - return Q.nfcall(fs.readFile, path.join(tempDir, '.bower.json')); - }, null) - .then(function (contents) { - var json = JSON.parse(contents.toString()); - expect(json.version).to.equal('0.0.1'); - expect(notified).to.be(false); - - next(); - }) - .done(); - }); - }); + describe('#versions', function() { + afterEach(clearResolverRuntimeCache); - describe('#clearRuntimeCache', function () { - // Use a class that inherit the SvnResolver to see if it uses - // late binding when clearing the cache - function CustomSvnResolver() {} - util.inherits(CustomSvnResolver, SvnResolver); - mout.object.mixIn(CustomSvnResolver, SvnResolver); + it('should resolve to an empty array if no tags are found', function(next) { + SvnResolver.tags = function() { + return Q.resolve({}); + }; + SvnResolver.versions('foo') + .then(function(versions) { + expect(versions).to.be.an('array'); + expect(versions).to.eql([]); + next(); + }) + .done(); + }); - it('should clear tags cache', function () { - CustomSvnResolver._cache.tags.set('foo', {}); - CustomSvnResolver.clearRuntimeCache(); - expect(CustomSvnResolver._cache.tags.has('foo')).to.be(false); - }); + it('should resolve to an empty array if no valid semver tags', function(next) { + SvnResolver.tags = function() { + return Q.resolve({ + foo: 1, + bar: 2, + baz: 3 + }); + }; - it('should clear versions cache', function () { - CustomSvnResolver._cache.versions.set('foo', {}); - CustomSvnResolver.clearRuntimeCache(); - expect(CustomSvnResolver._cache.versions.has('foo')).to.be(false); - }); - }); + SvnResolver.versions('foo') + .then(function(versions) { + expect(versions).to.be.an('array'); + expect(versions).to.eql([]); + next(); + }) + .done(); + }); - describe('#versions', function () { - afterEach(clearResolverRuntimeCache); - - it('should resolve to an empty array if no tags are found', function (next) { - SvnResolver.tags = function () { - return Q.resolve({}); - }; - - SvnResolver.versions('foo') - .then(function (versions) { - expect(versions).to.be.an('array'); - expect(versions).to.eql([]); - next(); - }) - .done(); - }); + it('should resolve to an array of versions, ignoring invalid semver tags', function(next) { + SvnResolver.tags = function() { + return Q.resolve({ + '0.2.1': 1, + 'v0.1.1': 2, + '0.1.0': 3, + invalid: 4, // invalid + '/': 5, // invalid + '': 6 // invalid + }); + }; + + SvnResolver.versions('foo', true) + .then(function(versions) { + expect(versions).to.eql([ + { version: '0.2.1', tag: '0.2.1', commit: 1 }, + { version: '0.1.1', tag: 'v0.1.1', commit: 2 }, + { version: '0.1.0', tag: '0.1.0', commit: 3 } + ]); + }) + .then(function() { + return SvnResolver.versions('foo'); + }) + .then(function(versions) { + expect(versions).to.eql(['0.2.1', '0.1.1', '0.1.0']); + next(); + }) + .done(); + }); - it('should resolve to an empty array if no valid semver tags', function (next) { - SvnResolver.tags = function () { - return Q.resolve({ - 'foo': 1, - 'bar': 2, - 'baz': 3 - }); - }; - - SvnResolver.versions('foo') - .then(function (versions) { - expect(versions).to.be.an('array'); - expect(versions).to.eql([]); - next(); - }) - .done(); - }); + it('should order the versions according to the semver spec', function(next) { + SvnResolver.tags = function() { + return Q.resolve({ + '0.1.0': 1, + '0.1.1+build.11': 2, + '0.1.1+build.100': 3, + '0.1.1-rc.22': 4, + '0.1.1-rc.200': 5, + '0.1.1': 6, + 'v0.2.1': 7 + }); + }; + + SvnResolver.versions('foo', true) + .then(function(versions) { + expect(versions).to.eql([ + { version: '0.2.1', tag: 'v0.2.1', commit: '7' }, + { + version: '0.1.1+build.11', + tag: '0.1.1+build.11', + commit: '2' + }, + { + version: '0.1.1+build.100', + tag: '0.1.1+build.100', + commit: '3' + }, + { version: '0.1.1', tag: '0.1.1', commit: '6' }, + { + version: '0.1.1-rc.200', + tag: '0.1.1-rc.200', + commit: '5' + }, + { + version: '0.1.1-rc.22', + tag: '0.1.1-rc.22', + commit: '4' + }, + { version: '0.1.0', tag: '0.1.0', commit: '1' } + ]); + next(); + }) + .done(); + }); - it('should resolve to an array of versions, ignoring invalid semver tags', function (next) { - SvnResolver.tags = function () { - return Q.resolve({ - '0.2.1': 1, - 'v0.1.1': 2, - '0.1.0': 3, - 'invalid': 4, // invalid - '/': 5, // invalid - '': 6 // invalid - }); - }; - - SvnResolver.versions('foo', true) - .then(function (versions) { - expect(versions).to.eql([ - { version: '0.2.1', tag: '0.2.1', commit: 1 }, - { version: '0.1.1', tag: 'v0.1.1', commit: 2 }, - { version: '0.1.0', tag: '0.1.0', commit: 3 } - ]); - }) - .then(function () { - return SvnResolver.versions('foo'); - }) - .then(function (versions) { - expect(versions).to.eql(['0.2.1', '0.1.1', '0.1.0']); - next(); - }) - .done(); - }); + it('should cache the result for each source', function(next) { + SvnResolver.tags = function(source) { + if (source === 'foo') { + return Q.resolve({ + '0.2.1': 123, + '0.1.0': 456 + }); + } - it('should order the versions according to the semver spec', function (next) { - SvnResolver.tags = function () { - return Q.resolve({ - '0.1.0': 1, - '0.1.1+build.11': 2, - '0.1.1+build.100': 3, - '0.1.1-rc.22': 4, - '0.1.1-rc.200': 5, - '0.1.1': 6, - 'v0.2.1': 7 - }); - }; - - SvnResolver.versions('foo', true) - .then(function (versions) { - expect(versions).to.eql([ - { version: '0.2.1', tag: 'v0.2.1', commit: '7' }, - { version: '0.1.1+build.11', tag: '0.1.1+build.11', commit: '2' }, - { version: '0.1.1+build.100', tag: '0.1.1+build.100', commit: '3' }, - { version: '0.1.1', tag: '0.1.1', commit: '6' }, - { version: '0.1.1-rc.200', tag: '0.1.1-rc.200', commit: '5' }, - { version: '0.1.1-rc.22', tag: '0.1.1-rc.22', commit: '4' }, - { version: '0.1.0', tag: '0.1.0', commit: '1' } - ]); - next(); - }) - .done(); - }); + return Q.resolve({ + '0.3.1': 7, + '0.3.0': 8 + }); + }; + + SvnResolver.versions('foo') + .then(function(versions) { + expect(versions).to.eql(['0.2.1', '0.1.0']); + + return SvnResolver.versions('bar'); + }) + .then(function(versions) { + expect(versions).to.eql(['0.3.1', '0.3.0']); + + // Manipulate the cache and check if it resolves for the cached ones + SvnResolver._cache.versions.get('foo').splice(1, 1); + SvnResolver._cache.versions.get('bar').splice(1, 1); + + return SvnResolver.versions('foo'); + }) + .then(function(versions) { + expect(versions).to.eql(['0.2.1']); + + return SvnResolver.versions('bar'); + }) + .then(function(versions) { + expect(versions).to.eql(['0.3.1']); + next(); + }) + .done(); + }); - it('should cache the result for each source', function (next) { - SvnResolver.tags = function (source) { - if (source === 'foo') { + it('should work if requested in parallel for the same source', function(next) { + SvnResolver.tags = function() { return Q.resolve({ '0.2.1': 123, '0.1.0': 456 }); - } - - return Q.resolve({ - '0.3.1': 7, - '0.3.0': 8 - }); - - }; - - SvnResolver.versions('foo') - .then(function (versions) { - expect(versions).to.eql(['0.2.1', '0.1.0']); - - return SvnResolver.versions('bar'); - }) - .then(function (versions) { - expect(versions).to.eql(['0.3.1', '0.3.0']); - - - // Manipulate the cache and check if it resolves for the cached ones - SvnResolver._cache.versions.get('foo').splice(1, 1); - SvnResolver._cache.versions.get('bar').splice(1, 1); - - return SvnResolver.versions('foo'); - }) - .then(function (versions) { - expect(versions).to.eql(['0.2.1']); - - return SvnResolver.versions('bar'); - }) - .then(function (versions) { - expect(versions).to.eql(['0.3.1']); - next(); - }) - .done(); - }); - - it('should work if requested in parallel for the same source', function (next) { - SvnResolver.tags = function () { - return Q.resolve({ - '0.2.1': 123, - '0.1.0': 456 - }); - }; - - Q.all([ - SvnResolver.versions('foo'), - SvnResolver.versions('foo') - ]) - .spread(function (versions1, versions2) { - expect(versions1).to.eql(['0.2.1', '0.1.0']); - expect(versions2).to.eql(versions1); - - next(); - }) - .done(); + }; + + Q.all([ + SvnResolver.versions('foo'), + SvnResolver.versions('foo') + ]) + .spread(function(versions1, versions2) { + expect(versions1).to.eql(['0.2.1', '0.1.0']); + expect(versions2).to.eql(versions1); + + next(); + }) + .done(); + }); }); - }); - - describe('#parseSubversionListOutput', function () { - var list = [ - ' 12345 username Jan 1 12:34 ./', - ' 12346 username Feb 2 12:34 branch-name/', - ' 12347 username Mar 3 12:34 branch_name/', - ' 12348 username Apr 4 12:34 branch.1.2.3/', - ' 12349 username Jun 5 12:34 BranchName/' - ].join('\r\n'); + describe('#parseSubversionListOutput', function() { + var list = [ + ' 12345 username Jan 1 12:34 ./', + ' 12346 username Feb 2 12:34 branch-name/', + ' 12347 username Mar 3 12:34 branch_name/', + ' 12348 username Apr 4 12:34 branch.1.2.3/', + ' 12349 username Jun 5 12:34 BranchName/' + ].join('\r\n'); - it('should not include the . (dot)path', function () { - var actual = SvnResolver.parseSubversionListOutput(list); + it('should not include the . (dot)path', function() { + var actual = SvnResolver.parseSubversionListOutput(list); - expect(actual).to.not.have.keys('.'); - }); + expect(actual).to.not.have.keys('.'); + }); - it('should parse path names with alphanumerics, dashes, dots and underscores', function () { - var actual = SvnResolver.parseSubversionListOutput(list); + it('should parse path names with alphanumerics, dashes, dots and underscores', function() { + var actual = SvnResolver.parseSubversionListOutput(list); - expect(actual).to.eql({ - 'branch-name' : '12346', - 'branch_name' : '12347', - 'branch.1.2.3' : '12348', - 'BranchName' : '12349' + expect(actual).to.eql({ + 'branch-name': '12346', + branch_name: '12347', + 'branch.1.2.3': '12348', + BranchName: '12349' + }); }); }); - }); - // remote resolver tests - describe('.constructor', function () { - it('should guess the name from the path', function () { - var resolver; + // remote resolver tests + describe('.constructor', function() { + it('should guess the name from the path', function() { + var resolver; - resolver = create(helpers.localSource(testPackage)); - expect(resolver.getName()).to.equal('repo'); + resolver = create(helpers.localSource(testPackage)); + expect(resolver.getName()).to.equal('repo'); - resolver = create('svn+http://yii.googlecode.com/svn'); - expect(resolver.getName()).to.equal('svn'); + resolver = create('svn+http://yii.googlecode.com/svn'); + expect(resolver.getName()).to.equal('svn'); + }); }); - }); - - describe('.resolve', function () { - it('should export correctly if resolution is a tag', function (next) { - var resolver = create({ source: testPackage, target: '0.0.1' }); + describe('.resolve', function() { + it('should export correctly if resolution is a tag', function(next) { + var resolver = create({ source: testPackage, target: '0.0.1' }); - resolver.resolve() - .then(function (dir) { - expect(dir).to.be.a('string'); + resolver + .resolve() + .then(function(dir) { + expect(dir).to.be.a('string'); - var files = fs.readdirSync(dir); + var files = fs.readdirSync(dir); - expect(files).to.contain('foo'); - expect(files).to.not.contain('bar'); - next(); - }) - .done(); - }); + expect(files).to.contain('foo'); + expect(files).to.not.contain('bar'); + next(); + }) + .done(); + }); - it('should export correctly if resolution is a commit', function (next) { - var resolver = create({ source: testPackage, target: 'r1' }); + it('should export correctly if resolution is a commit', function(next) { + var resolver = create({ source: testPackage, target: 'r1' }); - resolver.resolve() - .then(function (dir) { - expect(dir).to.be.a('string'); + resolver + .resolve() + .then(function(dir) { + expect(dir).to.be.a('string'); - var files = fs.readdirSync(dir); + var files = fs.readdirSync(dir); - expect(files).to.not.contain('foo'); - expect(files).to.not.contain('bar'); - expect(files).to.not.contain('baz'); - next(); - }) - .done(); + expect(files).to.not.contain('foo'); + expect(files).to.not.contain('bar'); + expect(files).to.not.contain('baz'); + next(); + }) + .done(); + }); }); }); -}); diff --git a/test/core/resolvers/urlResolver.js b/test/core/resolvers/urlResolver.js index ee03b7cb1..b112c20ce 100644 --- a/test/core/resolvers/urlResolver.js +++ b/test/core/resolvers/urlResolver.js @@ -10,20 +10,22 @@ var cmd = require('../../../lib/util/cmd'); var UrlResolver = require('../../../lib/core/resolvers/UrlResolver'); var defaultConfig = require('../../../lib/config'); -describe('UrlResolver', function () { +describe('UrlResolver', function() { var testPackage = path.resolve(__dirname, '../../assets/package-a'); var tempDir = path.resolve(__dirname, '../../tmp/tmp'); var logger; - before(function (next) { + before(function(next) { logger = new Logger(); // Checkout test package version 0.2.1 - cmd('git', ['checkout', '0.2.1'], { cwd: testPackage }) - .then(next.bind(next, null), next); + cmd('git', ['checkout', '0.2.1'], { cwd: testPackage }).then( + next.bind(next, null), + next + ); }); - afterEach(function () { + afterEach(function() { logger.removeAllListeners(); }); @@ -35,26 +37,29 @@ describe('UrlResolver', function () { return new UrlResolver(decEndpoint, defaultConfig(), logger); } - describe('.constructor', function () { - it('should guess the name from the URL', function () { + describe('.constructor', function() { + it('should guess the name from the URL', function() { var resolver = create('http://bower.io/foo.txt'); expect(resolver.getName()).to.equal('foo'); }); - it('should remove ?part from the URL when guessing the name', function () { + it('should remove ?part from the URL when guessing the name', function() { var resolver = create('http://bower.io/foo.txt?bar'); expect(resolver.getName()).to.equal('foo'); }); - it('should not guess the name or remove ?part from the URL if not guessing', function () { - var resolver = create({ source: 'http://bower.io/foo.txt?bar', name: 'baz' }); + it('should not guess the name or remove ?part from the URL if not guessing', function() { + var resolver = create({ + source: 'http://bower.io/foo.txt?bar', + name: 'baz' + }); expect(resolver.getName()).to.equal('baz'); }); - it('should error out if a target was specified', function (next) { + it('should error out if a target was specified', function(next) { var resolver; try { @@ -70,698 +75,944 @@ describe('UrlResolver', function () { }); }); - describe('.hasNew', function () { - before(function () { + describe('.hasNew', function() { + before(function() { mkdirp.sync(tempDir); }); - afterEach(function (next) { + afterEach(function(next) { rimraf(path.join(tempDir, '.bower.json'), next); }); - after(function (next) { + after(function(next) { rimraf(tempDir, next); }); - it('should resolve to true if the response is not in the 2xx range', function (next) { + it('should resolve to true if the response is not in the 2xx range', function(next) { var resolver = create('http://bower.io/foo.js'); nock('http://bower.io') - .head('/foo.js') - .reply(500); + .head('/foo.js') + .reply(500); var pkgMeta = { name: 'foo', version: '0.0.0' }; - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(true); - next(); - }) - .done(); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); }); - it('should resolve to true if cache headers changed', function (next) { + it('should resolve to true if cache headers changed', function(next) { var resolver = create('http://bower.io/foo.js'); nock('http://bower.io') - .head('/foo.js') - .reply(200, '', { - 'ETag': '686897696a7c876b7e', - 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' - }); + .head('/foo.js') + .reply(200, '', { + ETag: '686897696a7c876b7e', + 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' + }); var pkgMeta = { name: 'foo', version: '0.0.0', _cacheHeaders: { - 'ETag': 'fk3454fdmmlw20i9nf', + ETag: 'fk3454fdmmlw20i9nf', 'Last-Modified': 'Tue, 16 Nov 2012 13:35:29 GMT' } }; - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(true); - next(); - }) - .done(); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(true); + next(); + }) + .done(); }); - it('should resolve to false if cache headers haven\'t changed', function (next) { + it("should resolve to false if cache headers haven't changed", function(next) { var resolver = create('http://bower.io/foo.js'); nock('http://bower.io') - .head('/foo.js') - .reply(200, '', { - 'ETag': '686897696a7c876b7e', - 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' - }); + .head('/foo.js') + .reply(200, '', { + ETag: '686897696a7c876b7e', + 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' + }); var pkgMeta = { name: 'foo', version: '0.0.0', _cacheHeaders: { - 'ETag': '686897696a7c876b7e', + ETag: '686897696a7c876b7e', 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' } }; - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(false); - next(); - }) - .done(); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(false); + next(); + }) + .done(); }); - it('should resolve to true if server responds with 304 (ETag mechanism)', function (next) { + it('should resolve to true if server responds with 304 (ETag mechanism)', function(next) { var resolver = create('http://bower.io/foo.js'); nock('http://bower.io') - .head('/foo.js') - .matchHeader('If-None-Match', '686897696a7c876b7e') - .reply(304, '', { - 'ETag': '686897696a7c876b7e', - 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' - }); + .head('/foo.js') + .matchHeader('If-None-Match', '686897696a7c876b7e') + .reply(304, '', { + ETag: '686897696a7c876b7e', + 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' + }); var pkgMeta = { name: 'foo', version: '0.0.0', _cacheHeaders: { - 'ETag': '686897696a7c876b7e', + ETag: '686897696a7c876b7e', 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' } }; - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(false); - next(); - }) - .done(); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(false); + next(); + }) + .done(); }); - it('should work with redirects', function (next) { + it('should work with redirects', function(next) { var redirectingUrl = 'http://redirecting-url.com'; var redirectingToUrl = 'http://bower.io'; var resolver; nock(redirectingUrl) - .head('/foo.js') - .reply(302, '', { location: redirectingToUrl + '/foo.js' }); + .head('/foo.js') + .reply(302, '', { location: redirectingToUrl + '/foo.js' }); nock(redirectingToUrl) - .head('/foo.js') - .reply(200, 'foo contents', { - 'ETag': '686897696a7c876b7e', - 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' - }); - + .head('/foo.js') + .reply(200, 'foo contents', { + ETag: '686897696a7c876b7e', + 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' + }); var pkgMeta = { name: 'foo', version: '0.0.0', _cacheHeaders: { - 'ETag': '686897696a7c876b7e', + ETag: '686897696a7c876b7e', 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' } }; resolver = create(redirectingUrl + '/foo.js'); - resolver.hasNew(pkgMeta) - .then(function (hasNew) { - expect(hasNew).to.be(false); - next(); - }) - .done(); + resolver + .hasNew(pkgMeta) + .then(function(hasNew) { + expect(hasNew).to.be(false); + next(); + }) + .done(); }); }); - describe('.resolve', function () { + describe('.resolve', function() { // Function to assert that the main property of the // package meta of a canonical dir is set to the // expected value function assertMain(dir, singleFile) { - return Q.nfcall(fs.readFile, path.join(dir, '.bower.json')) - .then(function (contents) { - var pkgMeta = JSON.parse(contents.toString()); + return Q.nfcall(fs.readFile, path.join(dir, '.bower.json')).then( + function(contents) { + var pkgMeta = JSON.parse(contents.toString()); - expect(pkgMeta.main).to.equal(singleFile); + expect(pkgMeta.main).to.equal(singleFile); - return pkgMeta; - }); + return pkgMeta; + } + ); } - it('should download file, renaming it to index', function (next) { + it('should download file, renaming it to index', function(next) { var resolver; nock('http://bower.io') - .get('/foo.js') - .reply(200, 'foo contents'); + .get('/foo.js') + .reply(200, 'foo contents'); resolver = create('http://bower.io/foo.js'); - resolver.resolve() - .then(function (dir) { - var contents; + resolver + .resolve() + .then(function(dir) { + var contents; - expect(fs.existsSync(path.join(dir, 'index.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(false); + expect(fs.existsSync(path.join(dir, 'index.js'))).to.be( + true + ); + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be( + false + ); - contents = fs.readFileSync(path.join(dir, 'index.js')).toString(); - expect(contents).to.equal('foo contents'); + contents = fs + .readFileSync(path.join(dir, 'index.js')) + .toString(); + expect(contents).to.equal('foo contents'); - assertMain(dir, 'index.js') - .then(next.bind(next, null)); - }) - .done(); + assertMain(dir, 'index.js').then(next.bind(next, null)); + }) + .done(); }); - it('should extract if source is an archive', function (next) { + it('should extract if source is an archive', function(next) { var resolver; nock('http://bower.io') - .get('/package-zip.zip') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip.zip')); + .get('/package-zip.zip') + .replyWithFile( + 200, + path.resolve(__dirname, '../../assets/package-zip.zip') + ); resolver = create('http://bower.io/package-zip.zip'); - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip.zip'))).to.be(false); - next(); - }) - .done(); + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect( + fs.existsSync(path.join(dir, 'package-zip.zip')) + ).to.be(false); + next(); + }) + .done(); }); - it('should extract if source is an archive (case insensitive)', function (next) { + it('should extract if source is an archive (case insensitive)', function(next) { var resolver; nock('http://bower.io') - .get('/package-zip.ZIP') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip.zip')); + .get('/package-zip.ZIP') + .replyWithFile( + 200, + path.resolve(__dirname, '../../assets/package-zip.zip') + ); resolver = create('http://bower.io/package-zip.ZIP'); - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip.ZIP'))).to.be(false); - next(); - }) - .done(); + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect( + fs.existsSync(path.join(dir, 'package-zip.ZIP')) + ).to.be(false); + next(); + }) + .done(); }); - it('should copy extracted folder contents if archive contains only a folder inside', function (next) { + it('should copy extracted folder contents if archive contains only a folder inside', function(next) { var resolver; nock('http://bower.io') - .get('/package-zip-folder.zip') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip-folder.zip')); + .get('/package-zip-folder.zip') + .replyWithFile( + 200, + path.resolve( + __dirname, + '../../assets/package-zip-folder.zip' + ) + ); nock('http://bower.io') - .get('/package-zip.zip') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip-folder.zip')); + .get('/package-zip.zip') + .replyWithFile( + 200, + path.resolve( + __dirname, + '../../assets/package-zip-folder.zip' + ) + ); resolver = create('http://bower.io/package-zip-folder.zip'); - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip-folder'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip-folder.zip'))).to.be(false); - - resolver = create({ source: 'http://bower.io/package-zip.zip', name: 'package-zip' }); - - return resolver.resolve(); - }) - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip.zip'))).to.be(false); - - next(); - }) - .done(); + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be( + false + ); + expect( + fs.existsSync(path.join(dir, 'package-zip-folder')) + ).to.be(false); + expect( + fs.existsSync(path.join(dir, 'package-zip-folder.zip')) + ).to.be(false); + + resolver = create({ + source: 'http://bower.io/package-zip.zip', + name: 'package-zip' + }); + + return resolver.resolve(); + }) + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be( + false + ); + expect( + fs.existsSync(path.join(dir, 'package-zip.zip')) + ).to.be(false); + + next(); + }) + .done(); }); - it('should extract if source is an archive and rename to index if it\'s only one file inside', function (next) { + it("should extract if source is an archive and rename to index if it's only one file inside", function(next) { var resolver; nock('http://bower.io') - .get('/package-zip-single-file.zip') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip-single-file.zip')); + .get('/package-zip-single-file.zip') + .replyWithFile( + 200, + path.resolve( + __dirname, + '../../assets/package-zip-single-file.zip' + ) + ); resolver = create('http://bower.io/package-zip-single-file.zip'); - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'index.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip-single-file'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip-single-file.zip'))).to.be(false); - - return assertMain(dir, 'index.js') - .then(next.bind(next, null)); - }) - .done(); + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'index.js'))).to.be( + true + ); + expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be( + false + ); + expect( + fs.existsSync(path.join(dir, 'package-zip-single-file')) + ).to.be(false); + expect( + fs.existsSync( + path.join(dir, 'package-zip-single-file.zip') + ) + ).to.be(false); + + return assertMain(dir, 'index.js').then( + next.bind(next, null) + ); + }) + .done(); }); - it('should extract if source is an archive and not rename to index if inside it\'s just a just bower.json/component.json file in it', function (next) { + it("should extract if source is an archive and not rename to index if inside it's just a just bower.json/component.json file in it", function(next) { var resolver; nock('http://bower.io') - .get('/package-zip-single-bower-json.zip') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip-single-bower-json.zip')) - .get('/package-zip-single-component-json.zip') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip-single-component-json.zip')); - - resolver = create('http://bower.io/package-zip-single-bower-json.zip'); - - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'bower.json'))).to.be(true); - - resolver = create('http://bower.io/package-zip-single-component-json.zip'); - }) - .then(function () { - return resolver.resolve(); - }) - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'component.json'))).to.be(true); - next(); - }) - .done(); + .get('/package-zip-single-bower-json.zip') + .replyWithFile( + 200, + path.resolve( + __dirname, + '../../assets/package-zip-single-bower-json.zip' + ) + ) + .get('/package-zip-single-component-json.zip') + .replyWithFile( + 200, + path.resolve( + __dirname, + '../../assets/package-zip-single-component-json.zip' + ) + ); + + resolver = create( + 'http://bower.io/package-zip-single-bower-json.zip' + ); + + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'bower.json'))).to.be( + true + ); + + resolver = create( + 'http://bower.io/package-zip-single-component-json.zip' + ); + }) + .then(function() { + return resolver.resolve(); + }) + .then(function(dir) { + expect( + fs.existsSync(path.join(dir, 'component.json')) + ).to.be(true); + next(); + }) + .done(); }); - it('should rename single file from a single folder to index when source is an archive', function (next) { + it('should rename single file from a single folder to index when source is an archive', function(next) { var resolver; nock('http://bower.io') - .get('/package-zip-folder-single-file.zip') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip-folder-single-file.zip')); - - resolver = create('http://bower.io/package-zip-folder-single-file.zip'); - - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'index.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip-folder-single-file'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip-folder-single-file.zip'))).to.be(false); - - return assertMain(dir, 'index.js') - .then(next.bind(next, null)); - }) - .done(); + .get('/package-zip-folder-single-file.zip') + .replyWithFile( + 200, + path.resolve( + __dirname, + '../../assets/package-zip-folder-single-file.zip' + ) + ); + + resolver = create( + 'http://bower.io/package-zip-folder-single-file.zip' + ); + + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'index.js'))).to.be( + true + ); + expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be( + false + ); + expect( + fs.existsSync( + path.join(dir, 'package-zip-folder-single-file') + ) + ).to.be(false); + expect( + fs.existsSync( + path.join(dir, 'package-zip-folder-single-file.zip') + ) + ).to.be(false); + + return assertMain(dir, 'index.js').then( + next.bind(next, null) + ); + }) + .done(); }); - it('should extract if response content-type is an archive', function (next) { + it('should extract if response content-type is an archive', function(next) { var resolver; nock('http://bower.io') - .get('/package-zip') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip.zip'), { - 'Content-Type': 'application/zip' - }) - - .get('/package-zip2') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip.zip'), { - 'Content-Type': 'application/zip; charset=UTF-8' - }) - - .get('/package-zip3') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip.zip'), { - 'Content-Type': ' application/zip ; charset=UTF-8' - }) - - .get('/package-zip4') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip.zip'), { - 'Content-Type': '"application/x-zip"' // Test with quotes - }) - - .get('/package-tar') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-tar.tar.gz'), { - 'Content-Type': ' application/x-tgz ; charset=UTF-8' - }) - - .get('/package-tar.tar.gz') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-tar.tar.gz'), { - 'Content-Type': ' application/x-tgz ; charset=UTF-8' - }) - - .get('/package-tar2.tar.gz') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-tar.tar.gz'), { - 'Content-Type': ' application/octet-stream ; charset=UTF-8' - }); + .get('/package-zip') + .replyWithFile( + 200, + path.resolve(__dirname, '../../assets/package-zip.zip'), + { + 'Content-Type': 'application/zip' + } + ) + + .get('/package-zip2') + .replyWithFile( + 200, + path.resolve(__dirname, '../../assets/package-zip.zip'), + { + 'Content-Type': 'application/zip; charset=UTF-8' + } + ) + + .get('/package-zip3') + .replyWithFile( + 200, + path.resolve(__dirname, '../../assets/package-zip.zip'), + { + 'Content-Type': ' application/zip ; charset=UTF-8' + } + ) + + .get('/package-zip4') + .replyWithFile( + 200, + path.resolve(__dirname, '../../assets/package-zip.zip'), + { + 'Content-Type': '"application/x-zip"' // Test with quotes + } + ) + + .get('/package-tar') + .replyWithFile( + 200, + path.resolve(__dirname, '../../assets/package-tar.tar.gz'), + { + 'Content-Type': ' application/x-tgz ; charset=UTF-8' + } + ) + + .get('/package-tar.tar.gz') + .replyWithFile( + 200, + path.resolve(__dirname, '../../assets/package-tar.tar.gz'), + { + 'Content-Type': ' application/x-tgz ; charset=UTF-8' + } + ) + + .get('/package-tar2.tar.gz') + .replyWithFile( + 200, + path.resolve(__dirname, '../../assets/package-tar.tar.gz'), + { + 'Content-Type': + ' application/octet-stream ; charset=UTF-8' + } + ); resolver = create('http://bower.io/package-zip'); - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip.zip'))).to.be(false); - - resolver = create('http://bower.io/package-zip2'); - - return resolver.resolve(); - }) - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip3.zip'))).to.be(false); - - resolver = create('http://bower.io/package-zip3'); - - return resolver.resolve(); - }) - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip4.zip'))).to.be(false); - - resolver = create('http://bower.io/package-zip4'); - - return resolver.resolve(); - }) - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-tar'))).to.be(false); - - resolver = create('http://bower.io/package-tar'); - - return resolver.resolve(); - }) - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-tar'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-tar.tar.gz'))).to.be(false); - - resolver = create('http://bower.io/package-tar.tar.gz'); - - return resolver.resolve(); - }) - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-tar'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-tar.tar.gz'))).to.be(false); - - resolver = create('http://bower.io/package-tar2.tar.gz'); - - return resolver.resolve(); - }) - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-tar'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-tar.tar.gz'))).to.be(false); - - next(); - }) - .done(); + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be( + false + ); + expect( + fs.existsSync(path.join(dir, 'package-zip.zip')) + ).to.be(false); + + resolver = create('http://bower.io/package-zip2'); + + return resolver.resolve(); + }) + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be( + false + ); + expect( + fs.existsSync(path.join(dir, 'package-zip3.zip')) + ).to.be(false); + + resolver = create('http://bower.io/package-zip3'); + + return resolver.resolve(); + }) + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be( + false + ); + expect( + fs.existsSync(path.join(dir, 'package-zip4.zip')) + ).to.be(false); + + resolver = create('http://bower.io/package-zip4'); + + return resolver.resolve(); + }) + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'package-tar'))).to.be( + false + ); + + resolver = create('http://bower.io/package-tar'); + + return resolver.resolve(); + }) + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'package-tar'))).to.be( + false + ); + expect( + fs.existsSync(path.join(dir, 'package-tar.tar.gz')) + ).to.be(false); + + resolver = create('http://bower.io/package-tar.tar.gz'); + + return resolver.resolve(); + }) + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'package-tar'))).to.be( + false + ); + expect( + fs.existsSync(path.join(dir, 'package-tar.tar.gz')) + ).to.be(false); + + resolver = create('http://bower.io/package-tar2.tar.gz'); + + return resolver.resolve(); + }) + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'package-tar'))).to.be( + false + ); + expect( + fs.existsSync(path.join(dir, 'package-tar.tar.gz')) + ).to.be(false); + + next(); + }) + .done(); }); - it('should extract if response content-disposition filename is an archive', function (next) { + it('should extract if response content-disposition filename is an archive', function(next) { var resolver; nock('http://bower.io') - .get('/package-zip') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip.zip'), { - 'Content-Disposition': 'attachment; filename="package-zip.zip"' - }); + .get('/package-zip') + .replyWithFile( + 200, + path.resolve(__dirname, '../../assets/package-zip.zip'), + { + 'Content-Disposition': + 'attachment; filename="package-zip.zip"' + } + ); resolver = create('http://bower.io/package-zip'); - resolver.resolve() - .then(function (dir) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip.zip'))).to.be(false); - next(); - }) - .done(); + resolver + .resolve() + .then(function(dir) { + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be( + false + ); + expect( + fs.existsSync(path.join(dir, 'package-zip.zip')) + ).to.be(false); + next(); + }) + .done(); }); - it('should save the release if there\'s a E-Tag', function (next) { + it("should save the release if there's a E-Tag", function(next) { var resolver; nock('http://bower.io') - .get('/foo.js') - .reply(200, 'foo contents', { - 'ETag': '686897696a7c876b7e', - 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' - }); + .get('/foo.js') + .reply(200, 'foo contents', { + ETag: '686897696a7c876b7e', + 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' + }); resolver = create('http://bower.io/foo.js'); - resolver.resolve() - .then(function (dir) { - assertMain(dir, 'index.js') - .then(function (pkgMeta) { - expect(pkgMeta._release).to.equal('e-tag:686897696a'); - next(); - }); - }) - .done(); + resolver + .resolve() + .then(function(dir) { + assertMain(dir, 'index.js').then(function(pkgMeta) { + expect(pkgMeta._release).to.equal('e-tag:686897696a'); + next(); + }); + }) + .done(); }); - it('should allow for query strings in URL', function (next) { + it('should allow for query strings in URL', function(next) { var resolver; nock('http://bower.io') - .get('/foo.js?bar=baz') - .reply(200, 'foo contents'); + .get('/foo.js?bar=baz') + .reply(200, 'foo contents'); resolver = create('http://bower.io/foo.js?bar=baz'); - resolver.resolve() - .then(function (dir) { - var contents; - - expect(fs.existsSync(path.join(dir, 'index.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'foo.js?bar=baz'))).to.be(false); - - contents = fs.readFileSync(path.join(dir, 'index.js')).toString(); - expect(contents).to.equal('foo contents'); - - assertMain(dir, 'index.js') - .then(next.bind(next, null)); - }) - .done(); + resolver + .resolve() + .then(function(dir) { + var contents; + + expect(fs.existsSync(path.join(dir, 'index.js'))).to.be( + true + ); + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be( + false + ); + expect( + fs.existsSync(path.join(dir, 'foo.js?bar=baz')) + ).to.be(false); + + contents = fs + .readFileSync(path.join(dir, 'index.js')) + .toString(); + expect(contents).to.equal('foo contents'); + + assertMain(dir, 'index.js').then(next.bind(next, null)); + }) + .done(); }); - it('should save cache headers', function (next) { + it('should save cache headers', function(next) { var resolver; nock('http://bower.io') - .get('/foo.js') - .reply(200, 'foo contents', { - 'ETag': '686897696a7c876b7e', - 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' - }); + .get('/foo.js') + .reply(200, 'foo contents', { + ETag: '686897696a7c876b7e', + 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' + }); resolver = create('http://bower.io/foo.js'); - resolver.resolve() - .then(function (dir) { - assertMain(dir, 'index.js') - .then(function (pkgMeta) { - expect(pkgMeta._cacheHeaders).to.eql({ - 'ETag': '686897696a7c876b7e', - 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' + resolver + .resolve() + .then(function(dir) { + assertMain(dir, 'index.js').then(function(pkgMeta) { + expect(pkgMeta._cacheHeaders).to.eql({ + ETag: '686897696a7c876b7e', + 'Last-Modified': 'Tue, 15 Nov 2012 12:45:26 GMT' + }); + next(); }); - next(); - }); - }) - .done(); + }) + .done(); }); - it('should work with redirects', function (next) { + it('should work with redirects', function(next) { var redirectingUrl = 'http://redirecting-url.com'; var redirectingToUrl = 'http://bower.io'; var resolver; nock(redirectingUrl) - .get('/foo.js') - .reply(302, '', { - location: redirectingToUrl + '/foo.js' - }); + .get('/foo.js') + .reply(302, '', { + location: redirectingToUrl + '/foo.js' + }); nock(redirectingToUrl) - .get('/foo.js') - .reply(200, 'foo contents'); + .get('/foo.js') + .reply(200, 'foo contents'); resolver = create(redirectingUrl + '/foo.js'); - resolver.resolve() - .then(function (dir) { - var contents; + resolver + .resolve() + .then(function(dir) { + var contents; - expect(fs.existsSync(path.join(dir, 'index.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(false); + expect(fs.existsSync(path.join(dir, 'index.js'))).to.be( + true + ); + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be( + false + ); - contents = fs.readFileSync(path.join(dir, 'index.js')).toString(); - expect(contents).to.equal('foo contents'); + contents = fs + .readFileSync(path.join(dir, 'index.js')) + .toString(); + expect(contents).to.equal('foo contents'); - assertMain(dir, 'index.js') - .then(next.bind(next, null)); - }) - .done(); + assertMain(dir, 'index.js').then(next.bind(next, null)); + }) + .done(); }); it.skip('it should error out if the status code is not within 200-299'); it.skip('should report progress when it takes too long to download'); - describe('content-disposition validation', function () { + describe('content-disposition validation', function() { function performTest(header, extraction) { var resolver; nock('http://bower.io') - .get('/package-zip') - .replyWithFile(200, path.resolve(__dirname, '../../assets/package-zip.zip'), { - 'Content-Disposition': header - }); + .get('/package-zip') + .replyWithFile( + 200, + path.resolve(__dirname, '../../assets/package-zip.zip'), + { + 'Content-Disposition': header + } + ); resolver = create('http://bower.io/package-zip'); - return resolver.resolve() - .then(function (dir) { + return resolver.resolve().then(function(dir) { if (extraction) { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(true); - expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be( + true + ); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be( + true + ); + expect( + fs.existsSync(path.join(dir, 'package-zip')) + ).to.be(false); } else { - expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'package-zip'))).to.be(false); - expect(fs.existsSync(path.join(dir, 'index'))).to.be(true); + expect(fs.existsSync(path.join(dir, 'foo.js'))).to.be( + false + ); + expect(fs.existsSync(path.join(dir, 'bar.js'))).to.be( + false + ); + expect( + fs.existsSync(path.join(dir, 'package-zip')) + ).to.be(false); + expect(fs.existsSync(path.join(dir, 'index'))).to.be( + true + ); } }); } - it('should work with and without quotes', function (next) { + it('should work with and without quotes', function(next) { performTest('attachment; filename="package-zip.zip"', true) - .then(function () { - return performTest('attachment; filename=package-zip.zip', true); - }) - .then(next.bind(next, null)) - .done(); + .then(function() { + return performTest( + 'attachment; filename=package-zip.zip', + true + ); + }) + .then(next.bind(next, null)) + .done(); }); - it('should not work with partial quotes', function (next) { + it('should not work with partial quotes', function(next) { performTest('attachment; filename="package-zip.zip', false) - .then(function () { - // This one works, and the last quote is simply ignored - return performTest('attachment; filename=package-zip.zip"', true); - }) - .then(next.bind(next, null)) - .done(); + .then(function() { + // This one works, and the last quote is simply ignored + return performTest( + 'attachment; filename=package-zip.zip"', + true + ); + }) + .then(next.bind(next, null)) + .done(); }); - it('should not work if the filename contain chars other than alphanumerical, dashes, spaces and dots', function (next) { + it('should not work if the filename contain chars other than alphanumerical, dashes, spaces and dots', function(next) { performTest('attachment; filename="1package01 _-zip.zip"', true) - .then(function () { - return performTest('attachment; filename="package$%"', false); - }) - .then(function () { - return performTest('attachment; filename=packagé', false); - }) - .then(function () { - // This one works, but since the filename is truncated once a space is found - // the extraction will not happen because the file has no .zip extension - return performTest('attachment; filename=1package01 _-zip.zip"', false); - }) - .then(function () { - return performTest('attachment; filename=1package01.zip _-zip.zip"', true); - }) - .then(next.bind(next, null)) - .done(); + .then(function() { + return performTest( + 'attachment; filename="package$%"', + false + ); + }) + .then(function() { + return performTest( + 'attachment; filename=packagé', + false + ); + }) + .then(function() { + // This one works, but since the filename is truncated once a space is found + // the extraction will not happen because the file has no .zip extension + return performTest( + 'attachment; filename=1package01 _-zip.zip"', + false + ); + }) + .then(function() { + return performTest( + 'attachment; filename=1package01.zip _-zip.zip"', + true + ); + }) + .then(next.bind(next, null)) + .done(); }); - it('should trim leading and trailing spaces', function (next) { + it('should trim leading and trailing spaces', function(next) { performTest('attachment; filename=" package.zip "', true) - .then(next.bind(next, null)) - .done(); + .then(next.bind(next, null)) + .done(); }); - it('should not work if the filename ends with a dot', function (next) { + it('should not work if the filename ends with a dot', function(next) { performTest('attachment; filename="package.zip."', false) - .then(function () { - return performTest('attachment; filename="package.zip. "', false); - }) - .then(function () { - return performTest('attachment; filename=package.zip.', false); - }) - .then(function () { - return performTest('attachment; filename="package.zip ."', false); - }) - .then(function () { - return performTest('attachment; filename="package.zip. "', false); - }) - .then(next.bind(next, null)) - .done(); + .then(function() { + return performTest( + 'attachment; filename="package.zip. "', + false + ); + }) + .then(function() { + return performTest( + 'attachment; filename=package.zip.', + false + ); + }) + .then(function() { + return performTest( + 'attachment; filename="package.zip ."', + false + ); + }) + .then(function() { + return performTest( + 'attachment; filename="package.zip. "', + false + ); + }) + .then(next.bind(next, null)) + .done(); }); - it('should be case insensitive', function (next) { + it('should be case insensitive', function(next) { performTest('attachment; FILENAME="package.zip"', true) - .then(function () { - return performTest('attachment; filename="package.ZIP"', true); - }) - .then(function () { - return performTest('attachment; FILENAME=package.zip', true); - }) - .then(function () { - return performTest('attachment; filename=package.ZIP', true); - }) - .then(next.bind(next, null)) - .done(); + .then(function() { + return performTest( + 'attachment; filename="package.ZIP"', + true + ); + }) + .then(function() { + return performTest( + 'attachment; FILENAME=package.zip', + true + ); + }) + .then(function() { + return performTest( + 'attachment; filename=package.ZIP', + true + ); + }) + .then(next.bind(next, null)) + .done(); }); }); }); - describe('#isTargetable', function () { - it('should return false', function () { + describe('#isTargetable', function() { + it('should return false', function() { expect(UrlResolver.isTargetable()).to.be(false); }); }); diff --git a/test/core/scripts.js b/test/core/scripts.js index 1e152f233..397d5ee0d 100644 --- a/test/core/scripts.js +++ b/test/core/scripts.js @@ -6,20 +6,27 @@ var fs = require('../../lib/util/fs'); var expect = require('expect.js'); var scripts = require('../../lib/core/scripts.js'); -describe('scripts', function () { - +describe('scripts', function() { var tempDir = path.join(__dirname, '../tmp/temp-scripts'); var packageName = 'package-zip'; var packageDir = path.join(__dirname, '../assets/' + packageName + '.zip'); // We cannot use pure touch, because Windows - var touch = function (file) { - return 'node -e "var fs = require(\'fs\'); fs.closeSync(fs.openSync(\'' + file + '\', \'w\'));"'; + var touch = function(file) { + return ( + "node -e \"var fs = require('fs'); fs.closeSync(fs.openSync('" + + file + + "', 'w'));\"" + ); }; // We cannot use pure touch, because Windows - var touchWithPid = function (file) { - return 'node -e "var fs = require(\'fs\'); fs.closeSync(fs.openSync(process.env.BOWER_PID + \'' + file + '\', \'w\'));"'; + var touchWithPid = function(file) { + return ( + "node -e \"var fs = require('fs'); fs.closeSync(fs.openSync(process.env.BOWER_PID + '" + + file + + "', 'w'));\"" + ); }; var config = { @@ -32,121 +39,158 @@ describe('scripts', function () { } }; - before(function (next) { + before(function(next) { mkdirp(tempDir, next); }); - after(function (next) { - rimraf(tempDir, next); + after(function(next) { + rimraf(tempDir, next); }); - it('should run preinstall and postinstall hooks.', function (next) { - + it('should run preinstall and postinstall hooks.', function(next) { bower.commands - .install([packageDir], undefined, config) - .on('end', function (installed) { - - expect(fs.existsSync(path.join(tempDir, 'preinstall_' + packageName + '_' + packageName))).to.be(true); - expect(fs.existsSync(path.join(tempDir, 'postinstall_' + packageName + '_' + packageName))).to.be(true); - - next(); - }); - + .install([packageDir], undefined, config) + .on('end', function(installed) { + expect( + fs.existsSync( + path.join( + tempDir, + 'preinstall_' + packageName + '_' + packageName + ) + ) + ).to.be(true); + expect( + fs.existsSync( + path.join( + tempDir, + 'postinstall_' + packageName + '_' + packageName + ) + ) + ).to.be(true); + + next(); + }); }); - it('should run preuninstall hook.', function (next) { - + it('should run preuninstall hook.', function(next) { bower.commands - .uninstall([packageName], undefined, config) - .on('end', function (installed) { - - expect(fs.existsSync(path.join(tempDir, 'preuninstall_' + packageName + '_' + packageName))).to.be(true); - - next(); - }); - + .uninstall([packageName], undefined, config) + .on('end', function(installed) { + expect( + fs.existsSync( + path.join( + tempDir, + 'preuninstall_' + packageName + '_' + packageName + ) + ) + ).to.be(true); + + next(); + }); }); - it('should run postuninstall hook.', function (next) { - + it('should run postuninstall hook.', function(next) { bower.commands - .uninstall([packageName], undefined, config) - .on('end', function (installed) { - - expect(fs.existsSync(path.join(tempDir, 'postuninstall_' + packageName + '_' + packageName))).to.be(true); - - next(); - }); - + .uninstall([packageName], undefined, config) + .on('end', function(installed) { + expect( + fs.existsSync( + path.join( + tempDir, + 'postuninstall_' + packageName + '_' + packageName + ) + ) + ).to.be(true); + + next(); + }); }); - it('should not break anything when no hooks configured.', function (next) { - + it('should not break anything when no hooks configured.', function(next) { bower.commands - .uninstall([packageName], undefined, { cwd: tempDir }) - .on('end', function (installed) { - - //no exception then we're good - - next(); - }); + .uninstall([packageName], undefined, { cwd: tempDir }) + .on('end', function(installed) { + //no exception then we're good + next(); + }); }); - it('should reorder packages by dependencies, while trying to maintain order from bower.json, correctly.', function () { - - var mockAngularUI = { dependencies: { - 'angular': '*' - }}; - var mockJQuery = { dependencies: { - }}; - var mockAngular = { dependencies: { - 'jquery': '*' - }}; - var mockMoment = { dependencies: { - }}; - var mockSelect2 = { dependencies: { - 'jquery': '*' - }}; - var mockBadPackage = { dependencies: { - 'something-not-installed': '*' - }}; + it('should reorder packages by dependencies, while trying to maintain order from bower.json, correctly.', function() { + var mockAngularUI = { + dependencies: { + angular: '*' + } + }; + var mockJQuery = { + dependencies: {} + }; + var mockAngular = { + dependencies: { + jquery: '*' + } + }; + var mockMoment = { + dependencies: {} + }; + var mockSelect2 = { + dependencies: { + jquery: '*' + } + }; + var mockBadPackage = { + dependencies: { + 'something-not-installed': '*' + } + }; var packages = { - 'select2': mockSelect2, + select2: mockSelect2, 'angular-ui': mockAngularUI, - 'jquery': mockJQuery, + jquery: mockJQuery, 'bad-package': mockBadPackage, - 'angular': mockAngular, - 'moment': mockMoment + angular: mockAngular, + moment: mockMoment }; var installed = []; - var mockBowerJson = { dependencies: { - 'jquery': '*', - 'select2': '*', - 'angular-ui': '*', - 'angular': '*', - 'moment': '*' - } }; - - var ordered = scripts._orderByDependencies(packages, installed, mockBowerJson); - expect(ordered).to.eql(['jquery', 'select2', 'angular', 'angular-ui', 'moment', 'bad-package']); + var mockBowerJson = { + dependencies: { + jquery: '*', + select2: '*', + 'angular-ui': '*', + angular: '*', + moment: '*' + } + }; + var ordered = scripts._orderByDependencies( + packages, + installed, + mockBowerJson + ); + expect(ordered).to.eql([ + 'jquery', + 'select2', + 'angular', + 'angular-ui', + 'moment', + 'bad-package' + ]); }); - it('should process scripts with quotes and vars in the cmd properly.', function (next) { - + it('should process scripts with quotes and vars in the cmd properly.', function(next) { config.scripts.preinstall = touchWithPid(' %'); bower.commands - .install([packageDir], undefined, config) - .on('end', function (installed) { - - expect(fs.existsSync(path.join(tempDir, process.pid + ' ' + packageName))).to.be(true); - - next(); - }); - + .install([packageDir], undefined, config) + .on('end', function(installed) { + expect( + fs.existsSync( + path.join(tempDir, process.pid + ' ' + packageName) + ) + ).to.be(true); + + next(); + }); }); - }); diff --git a/test/helpers.js b/test/helpers.js index 9ae69ce69..bd5ddfb37 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -10,7 +10,9 @@ var fs = require('../lib/util/fs'); var glob = require('glob'); var os = require('os'); var which = require('which'); -var proxyquire = require('proxyquire').noCallThru().noPreserveCache(); +var proxyquire = require('proxyquire') + .noCallThru() + .noPreserveCache(); var spawnSync = require('spawn-sync'); var config = require('../lib/config'); var nock = require('nock'); @@ -21,13 +23,13 @@ Q.longStackSupport = true; // Those are needed for Travis or not configured git environment var env = { - 'GIT_AUTHOR_DATE': 'Sun Apr 7 22:13:13 2013 +0000', - 'GIT_AUTHOR_NAME': 'André Cruz', - 'GIT_AUTHOR_EMAIL': 'amdfcruz@gmail.com', - 'GIT_COMMITTER_DATE': 'Sun Apr 7 22:13:13 2013 +0000', - 'GIT_COMMITTER_NAME': 'André Cruz', - 'GIT_COMMITTER_EMAIL': 'amdfcruz@gmail.com', - 'NODE_ENV': 'test' + GIT_AUTHOR_DATE: 'Sun Apr 7 22:13:13 2013 +0000', + GIT_AUTHOR_NAME: 'André Cruz', + GIT_AUTHOR_EMAIL: 'amdfcruz@gmail.com', + GIT_COMMITTER_DATE: 'Sun Apr 7 22:13:13 2013 +0000', + GIT_COMMITTER_NAME: 'André Cruz', + GIT_COMMITTER_EMAIL: 'amdfcruz@gmail.com', + NODE_ENV: 'test' }; object.mixIn(process.env, env); @@ -38,7 +40,7 @@ var tmpLocation = path.join( uuid.v4().slice(0, 8) ); -exports.require = function (name, stubs) { +exports.require = function(name, stubs) { if (stubs) { return proxyquire(path.join(__dirname, '../', name), stubs); } else { @@ -47,27 +49,27 @@ exports.require = function (name, stubs) { }; // We need to reset cache because tests are reusing temp directories -beforeEach(function () { +beforeEach(function() { config.reset(); }); -after(function () { +after(function() { rimraf.sync(tmpLocation); }); -exports.TempDir = (function () { +exports.TempDir = (function() { function TempDir(defaults) { this.path = path.join(tmpLocation, uuid.v4()); this.defaults = defaults; } - TempDir.prototype.create = function (files, defaults) { + TempDir.prototype.create = function(files, defaults) { var that = this; defaults = defaults || this.defaults || {}; files = object.merge(files || {}, defaults); - this.meta = function (tag) { + this.meta = function(tag) { if (tag) { return files[tag]['bower.json']; } else { @@ -76,7 +78,7 @@ exports.TempDir = (function () { }; if (files) { - object.forOwn(files, function (contents, filepath) { + object.forOwn(files, function(contents, filepath) { if (typeof contents === 'object') { contents = JSON.stringify(contents, null, ' ') + '\n'; } @@ -90,7 +92,7 @@ exports.TempDir = (function () { return this; }; - TempDir.prototype.prepare = function (files) { + TempDir.prototype.prepare = function(files) { rimraf.sync(this.path); mkdirp.sync(this.path); this.create(files); @@ -99,7 +101,7 @@ exports.TempDir = (function () { }; // TODO: Rewrite to synchronous form - TempDir.prototype.prepareGit = function (revisions) { + TempDir.prototype.prepareGit = function(revisions) { var that = this; revisions = object.merge(revisions || {}, this.defaults); @@ -110,42 +112,45 @@ exports.TempDir = (function () { this.git('init'); - this.glob('./!(.git)').map(function (removePath) { + this.glob('./!(.git)').map(function(removePath) { var fullPath = path.join(that.path, removePath); rimraf.sync(fullPath); }); - object.forOwn(revisions, function (files, tag) { - this.create(files, {}); - this.git('add', '-A'); - this.git('commit', '-m"commit"'); - this.git('tag', tag); - }.bind(this)); + object.forOwn( + revisions, + function(files, tag) { + this.create(files, {}); + this.git('add', '-A'); + this.git('commit', '-m"commit"'); + this.git('tag', tag); + }.bind(this) + ); return this; }; - TempDir.prototype.glob = function (pattern) { + TempDir.prototype.glob = function(pattern) { return glob.sync(pattern, { cwd: this.path, dot: true }); }; - TempDir.prototype.getPath = function (name) { + TempDir.prototype.getPath = function(name) { return path.join(this.path, name); }; - TempDir.prototype.read = function (name) { + TempDir.prototype.read = function(name) { return fs.readFileSync(this.getPath(name), 'utf8'); }; - TempDir.prototype.readJson = function (name) { + TempDir.prototype.readJson = function(name) { return JSON.parse(this.read(name)); }; - TempDir.prototype.git = function () { + TempDir.prototype.git = function() { var args = Array.prototype.slice.call(arguments); var result = spawnSync('git', args, { cwd: this.path }); @@ -156,10 +161,12 @@ exports.TempDir = (function () { } }; - TempDir.prototype.latestGitTag = function () { + TempDir.prototype.latestGitTag = function() { var versions = this.git('tag') .split(/\r?\n/) - .map(function (t) { return t[0] == 'v' ? t.slice(1) : t; }) + .map(function(t) { + return t[0] == 'v' ? t.slice(1) : t; + }) .filter(semver.valid) .sort(semver.compare); @@ -170,7 +177,7 @@ exports.TempDir = (function () { } }; - TempDir.prototype.exists = function (name) { + TempDir.prototype.exists = function(name) { return fs.existsSync(path.join(this.path, name)); }; @@ -180,18 +187,18 @@ exports.TempDir = (function () { exports.expectEvent = function expectEvent(emitter, eventName) { var deferred = Q.defer(); - emitter.once(eventName, function () { + emitter.once(eventName, function() { deferred.resolve(arguments); }); - emitter.once('error', function (reason) { + emitter.once('error', function(reason) { deferred.reject(reason); }); return deferred.promise; }; -exports.command = function (command, stubs) { +exports.command = function(command, stubs) { var rawCommand; var commandStubs = {}; @@ -199,19 +206,18 @@ exports.command = function (command, stubs) { var cwd = stubs.cwd; delete stubs.cwd; - rawCommand = exports.require( - 'lib/commands/' + command, stubs - ); + rawCommand = exports.require('lib/commands/' + command, stubs); - commandStubs['./' + command] = function () { + commandStubs['./' + command] = function() { var args = [].slice.call(arguments); - args[rawCommand.length - 1] = object.merge({ cwd: cwd }, args[rawCommand.length - 1] || {}); + args[rawCommand.length - 1] = object.merge( + { cwd: cwd }, + args[rawCommand.length - 1] || {} + ); return rawCommand.apply(null, args); }; - var instance = exports.require( - 'lib/commands/index', commandStubs - ); + var instance = exports.require('lib/commands/index', commandStubs); var commandParts = command.split('/'); @@ -224,7 +230,7 @@ exports.command = function (command, stubs) { } // TODO: refactor tests, so they can use readOptions directly - instance.readOptions = function (argv) { + instance.readOptions = function(argv) { argv = ['node', 'bower'].concat(argv); argv = command.split('/').concat(argv); @@ -234,11 +240,11 @@ exports.command = function (command, stubs) { return instance; }; -exports.run = function (command, args) { +exports.run = function(command, args) { var logger = command.apply(null, args || []); // Hack so we can intercept prompring for data - logger.prompt = function (data) { + logger.prompt = function(data) { logger.emit('confirm', data); }; @@ -250,35 +256,37 @@ exports.run = function (command, args) { }; // Captures all stdout and stderr -exports.capture = function (callback) { +exports.capture = function(callback) { var oldStdout = process.stdout.write; var oldStderr = process.stderr.write; var stdout = ''; var stderr = ''; - process.stdout.write = function (text) { + process.stdout.write = function(text) { stdout += text; }; - process.stderr.write = function (text) { + process.stderr.write = function(text) { stderr += text; }; - return Q.fcall(callback).then(function () { - process.stdout.write = oldStdout; - process.stderr.write = oldStderr; + return Q.fcall(callback) + .then(function() { + process.stdout.write = oldStdout; + process.stderr.write = oldStderr; - return [stdout, stderr]; - }).fail(function (e) { - process.stdout.write = oldStdout; - process.stderr.write = oldStderr; + return [stdout, stderr]; + }) + .fail(function(e) { + process.stdout.write = oldStdout; + process.stderr.write = oldStderr; - throw e; - }); + throw e; + }); }; -exports.hasSvn = function () { +exports.hasSvn = function() { try { which.sync('svn'); return true; @@ -287,11 +295,11 @@ exports.hasSvn = function () { } }; -exports.isWin = function () { +exports.isWin = function() { return process.platform === 'win32'; }; -exports.localSource = function (localPath) { +exports.localSource = function(localPath) { localPath = path.normalize(localPath); if (!exports.isWin()) { @@ -302,7 +310,7 @@ exports.localSource = function (localPath) { }; // Used for example by "svn checkout" and "svn export" -exports.localUrl = function (localPath) { +exports.localUrl = function(localPath) { localPath = path.normalize(localPath); if (!exports.isWin()) { @@ -316,13 +324,12 @@ exports.localUrl = function (localPath) { // Returns the result of executing the bower binary + args // example: runBin('install') --> $ bower install -exports.runBin = function (args) { - args = args || []; +exports.runBin = function(args) { + args = args || []; args.unshift(path.resolve(__dirname, '../bin/bower')); return spawnSync('node', args); }; - -afterEach(function () { +afterEach(function() { nock.cleanAll(); }); diff --git a/test/packages-svn.js b/test/packages-svn.js index dabeca980..26d398590 100644 --- a/test/packages-svn.js +++ b/test/packages-svn.js @@ -10,11 +10,11 @@ var cmd = require('../lib/util/cmd'); var packages = require('./packages-svn.json'); var nopt = require('nopt'); -var isWin = function () { +var isWin = function() { return process.platform === 'win32'; }; -var pathToUrl = function (localPath) { +var pathToUrl = function(localPath) { localPath = path.normalize(localPath); if (!isWin()) { @@ -26,12 +26,14 @@ var pathToUrl = function (localPath) { return localPath; }; - -var options = nopt({ - 'force': Boolean -}, { - 'f': '--force' -}); +var options = nopt( + { + force: Boolean + }, + { + f: '--force' + } +); var env = {}; @@ -43,60 +45,73 @@ function ensurePackage(admin, dir) { // If force is specified, delete folder if (options.force) { - promise = promise.then(function () { + promise = promise.then(function() { return Q.nfcall(rimraf, admin); }); - promise = promise.then(function () { + promise = promise.then(function() { return Q.nfcall(rimraf, dir); }); - promise = promise.then(function () { + promise = promise.then(function() { throw new Error(); }); - // Otherwise check if .git is already created + // Otherwise check if .git is already created } else { promise = Q.nfcall(fs.stat, path.join(dir, '.svn')); } // Only create if stat failed - return promise.fail(function () { + return promise.fail(function() { // Create dir - return Q.nfcall(mkdirp, dir) - // Init svn repo - .then(cmd.bind(null, 'svnadmin', ['create', admin], {})) - // checkout the repo - .then(cmd.bind(null, 'svn', ['checkout', pathToUrl(admin), dir], {})) - // create directory structure - .then(cmd.bind(null, 'svn', ['mkdir', 'trunk'], { cwd: dir })) - .then(cmd.bind(null, 'svn', ['mkdir', 'tags'], { cwd: dir })) - .then(cmd.bind(null, 'svn', ['mkdir', 'branches'], { cwd: dir })) - // Commit - .then(function () { - return cmd('svn', ['commit', '-m"Initial commit."'], { - cwd: dir, - env: env - }); - }) - .then(function () { - return dir; - }); + return ( + Q.nfcall(mkdirp, dir) + // Init svn repo + .then(cmd.bind(null, 'svnadmin', ['create', admin], {})) + // checkout the repo + .then( + cmd.bind( + null, + 'svn', + ['checkout', pathToUrl(admin), dir], + {} + ) + ) + // create directory structure + .then(cmd.bind(null, 'svn', ['mkdir', 'trunk'], { cwd: dir })) + .then(cmd.bind(null, 'svn', ['mkdir', 'tags'], { cwd: dir })) + .then( + cmd.bind(null, 'svn', ['mkdir', 'branches'], { cwd: dir }) + ) + // Commit + .then(function() { + return cmd('svn', ['commit', '-m"Initial commit."'], { + cwd: dir, + env: env + }); + }) + .then(function() { + return dir; + }) + ); }); } function checkRelease(dir, release) { if (semver.valid(release)) { - return cmd('svn', ['list', 'tags'], { cwd: dir }) - .spread(function (stdout) { - return stdout.split(/\/\s*\r*\n\s*/).some(function (tag) { + return cmd('svn', ['list', 'tags'], { cwd: dir }).spread(function( + stdout + ) { + return stdout.split(/\/\s*\r*\n\s*/).some(function(tag) { return semver.clean(tag) === release; }); }); } - return cmd('svn', ['list', 'branches'], { cwd: dir }) - .spread(function (stdout) { - return stdout.split(/\/\s*\r*\n\s*/).some(function (branch) { + return cmd('svn', ['list', 'branches'], { cwd: dir }).spread(function( + stdout + ) { + return stdout.split(/\/\s*\r*\n\s*/).some(function(branch) { branch = branch.trim().replace(/^\*?\s*/, ''); return branch === release; }); @@ -105,71 +120,84 @@ function checkRelease(dir, release) { function createRelease(admin, dir, release, files) { // checkout the repo - return cmd('svn', ['checkout', pathToUrl(admin), dir]) - // Attempt to delete branch, ignoring the error - .then(function () { - return cmd('svn', ['delete', dir + '/branches/' + release], { cwd: dir }) - .fail(function () {}); - }) - // Attempt to delete tag, ignoring the error - .then(function () { - return cmd('svn', ['delete', dir + '/tags/' + release], { cwd: dir }) - .fail(function (err) {}); - }) - // Create files - .then(function () { - var promise; - var promises = []; - - mout.object.forOwn(files, function (contents, name) { - name = path.join(dir + '/trunk', name); - - // Convert contents to JSON if they are not a string - if (typeof contents !== 'string') { - contents = JSON.stringify(contents, null, ' '); - } - - promise = Q.nfcall(mkdirp, path.dirname(name)) - .then(function () { - return Q.nfcall(fs.writeFile, name, contents); - }); + return ( + cmd('svn', ['checkout', pathToUrl(admin), dir]) + // Attempt to delete branch, ignoring the error + .then(function() { + return cmd('svn', ['delete', dir + '/branches/' + release], { + cwd: dir + }).fail(function() {}); + }) + // Attempt to delete tag, ignoring the error + .then(function() { + return cmd('svn', ['delete', dir + '/tags/' + release], { + cwd: dir + }).fail(function(err) {}); + }) + // Create files + .then(function() { + var promise; + var promises = []; - promises.push(promise); - }); + mout.object.forOwn(files, function(contents, name) { + name = path.join(dir + '/trunk', name); - return Q.all(promises); - }) - // Stage files - .then(cmd.bind(null, 'svn', ['add', '--force', '.'], { cwd: dir })) - // create tag - .then(function () { - if (!semver.valid(release)) { - return; - } + // Convert contents to JSON if they are not a string + if (typeof contents !== 'string') { + contents = JSON.stringify(contents, null, ' '); + } - return cmd('svn', ['copy', dir + '/trunk', dir + '/tags/' + release], { cwd: dir }); - }) - // create branch - .then(function () { - if (!semver.valid(release)) { - return; - } + promise = Q.nfcall(mkdirp, path.dirname(name)).then( + function() { + return Q.nfcall(fs.writeFile, name, contents); + } + ); - return cmd('svn', ['copy', dir + '/trunk', dir + '/branches/' + release], { cwd: dir }); - }) - // commit all - .then(function () { - return cmd('svn', ['commit', '-m"SVN Setup'], { - cwd: dir, - env: env - }); - }); + promises.push(promise); + }); + + return Q.all(promises); + }) + // Stage files + .then(cmd.bind(null, 'svn', ['add', '--force', '.'], { cwd: dir })) + // create tag + .then(function() { + if (!semver.valid(release)) { + return; + } + + return cmd( + 'svn', + ['copy', dir + '/trunk', dir + '/tags/' + release], + { cwd: dir } + ); + }) + // create branch + .then(function() { + if (!semver.valid(release)) { + return; + } + + return cmd( + 'svn', + ['copy', dir + '/trunk', dir + '/branches/' + release], + { cwd: dir } + ); + }) + // commit all + .then(function() { + return cmd('svn', ['commit', '-m"SVN Setup'], { + cwd: dir, + env: env + }); + }) + ); } var promises = []; // Process packages.json -mout.object.forOwn(packages, function (pkg, name) { +mout.object.forOwn(packages, function(pkg, name) { var promise; var admin = path.join(__dirname, 'assets', name, 'admin'); var dir = path.join(__dirname, 'assets', name, 'repo'); @@ -177,41 +205,59 @@ mout.object.forOwn(packages, function (pkg, name) { // Ensure package is created promise = ensurePackage(admin, dir); - promise = promise.fail(function (err) { + promise = promise.fail(function(err) { console.log('Failed to create ' + name); console.log(err.message); }); - mout.object.forOwn(pkg, function (files, release) { + mout.object.forOwn(pkg, function(files, release) { // Check if the release already exists - promise = promise.then(checkRelease.bind(null, dir, release)) - .then(function (exists) { - // Skip it if already created - if (exists) { - return console.log(chalk.cyan('> ') + 'Package ' + name + '#' + release + ' already created'); - } - - // Create it based on the metadata - return createRelease(admin, dir, release, files) - .then(function () { - console.log(chalk.green('> ') + 'Package ' + name + '#' + release + ' successfully created'); + promise = promise + .then(checkRelease.bind(null, dir, release)) + .then(function(exists) { + // Skip it if already created + if (exists) { + return console.log( + chalk.cyan('> ') + + 'Package ' + + name + + '#' + + release + + ' already created' + ); + } + + // Create it based on the metadata + return createRelease(admin, dir, release, files).then( + function() { + console.log( + chalk.green('> ') + + 'Package ' + + name + + '#' + + release + + ' successfully created' + ); + } + ); + }) + .fail(function(err) { + console.log( + chalk.red('> ') + 'Failed to create ' + name + '#' + release + ); + console.log(err.message.trim()); + if (err.details) { + console.log(err.details.trim()); + } + console.log(err.stack); }); - }) - .fail(function (err) { - console.log(chalk.red('> ') + 'Failed to create ' + name + '#' + release); - console.log(err.message.trim()); - if (err.details) { - console.log(err.details.trim()); - } - console.log(err.stack); - }); }); promises.push(promise); }); -Q.allSettled(promises, function (results) { - results.forEach(function (result) { +Q.allSettled(promises, function(results) { + results.forEach(function(result) { if (result.state !== 'fulfilled') { process.exit(1); } diff --git a/test/packages.js b/test/packages.js index 954047dda..fd5b34916 100644 --- a/test/packages.js +++ b/test/packages.js @@ -10,19 +10,22 @@ var cmd = require('../lib/util/cmd'); var packages = require('./packages.json'); var nopt = require('nopt'); -var options = nopt({ - 'force': Boolean -}, { - 'f': '--force' -}); +var options = nopt( + { + force: Boolean + }, + { + f: '--force' + } +); var env = { - 'GIT_AUTHOR_DATE': 'Sun Apr 7 22:13:13 2013 +0000', - 'GIT_AUTHOR_NAME': 'André Cruz', - 'GIT_AUTHOR_EMAIL': 'amdfcruz@gmail.com', - 'GIT_COMMITTER_DATE': 'Sun Apr 7 22:13:13 2013 +0000', - 'GIT_COMMITTER_NAME': 'André Cruz', - 'GIT_COMMITTER_EMAIL': 'amdfcruz@gmail.com' + GIT_AUTHOR_DATE: 'Sun Apr 7 22:13:13 2013 +0000', + GIT_AUTHOR_NAME: 'André Cruz', + GIT_AUTHOR_EMAIL: 'amdfcruz@gmail.com', + GIT_COMMITTER_DATE: 'Sun Apr 7 22:13:13 2013 +0000', + GIT_COMMITTER_NAME: 'André Cruz', + GIT_COMMITTER_EMAIL: 'amdfcruz@gmail.com' }; // Preserve the original environment @@ -33,56 +36,61 @@ function ensurePackage(dir) { // If force is specified, delete folder if (options.force) { - promise = Q.nfcall(rimraf, dir) - .then(function () { + promise = Q.nfcall(rimraf, dir).then(function() { throw new Error(); }); - // Otherwise check if .git is already created + // Otherwise check if .git is already created } else { promise = Q.nfcall(fs.stat, path.join(dir, '.git')); } // Only create if stat failed - return promise.fail(function () { + return promise.fail(function() { // Create dir - return Q.nfcall(mkdirp, dir) - // Init git repo - .then(cmd.bind(null, 'git', ['init'], { cwd: dir })) - // Create dummy file - .then(function () { - return Q.nfcall(fs.writeFile, path.join(dir, '.master'), 'based on master'); - }) - // Stage files - .then(cmd.bind(null, 'git', ['add', '-A'], { cwd: dir })) - // Commit - // Note that we force a specific date and author so that the same - // commit-sha's are always equal - // These commit-sha's are used internally in tests! - .then(function () { - return cmd('git', ['commit', '-m"Initial commit."'], { - cwd: dir, - env: env - }); - }) - .then(function () { - return dir; - }); + return ( + Q.nfcall(mkdirp, dir) + // Init git repo + .then(cmd.bind(null, 'git', ['init'], { cwd: dir })) + // Create dummy file + .then(function() { + return Q.nfcall( + fs.writeFile, + path.join(dir, '.master'), + 'based on master' + ); + }) + // Stage files + .then(cmd.bind(null, 'git', ['add', '-A'], { cwd: dir })) + // Commit + // Note that we force a specific date and author so that the same + // commit-sha's are always equal + // These commit-sha's are used internally in tests! + .then(function() { + return cmd('git', ['commit', '-m"Initial commit."'], { + cwd: dir, + env: env + }); + }) + .then(function() { + return dir; + }) + ); }); } function checkRelease(dir, release) { if (semver.valid(release)) { - return cmd('git', ['tag', '-l'], { cwd: dir }) - .spread(function (stdout) { - return stdout.split(/\s*\r*\n\s*/).some(function (tag) { + return cmd('git', ['tag', '-l'], { cwd: dir }).spread(function(stdout) { + return stdout.split(/\s*\r*\n\s*/).some(function(tag) { return semver.clean(tag) === release; }); }); } - return cmd('git', ['branch', '--list'], { cwd: dir }) - .spread(function (stdout) { - return stdout.split(/\s*\r*\n\s*/).some(function (branch) { + return cmd('git', ['branch', '--list'], { cwd: dir }).spread(function( + stdout + ) { + return stdout.split(/\s*\r*\n\s*/).some(function(branch) { branch = branch.trim().replace(/^\*?\s*/, ''); return branch === release; }); @@ -93,110 +101,151 @@ function createRelease(dir, release, files) { var branch = semver.valid(release) ? 'branch-' + release : release; // Checkout master - return cmd('git', ['checkout', 'master', '-f'], { cwd: dir }) - // Attempt to delete branch, ignoring the error - .then(function () { - return cmd('git', ['branch', '-D', branch], { cwd: dir }) - .fail(function () {}); - }) - // Checkout based on master - .then(cmd.bind(null, 'git', ['checkout', '-b', branch, 'master'], { cwd: dir })) - // Create files - .then(function () { - var promise; - var promises = []; - - mout.object.forOwn(files, function (contents, name) { - name = path.join(dir, name); - - // Convert contents to JSON if they are not a string - if (typeof contents !== 'string') { - contents = JSON.stringify(contents, null, ' '); - } - - promise = Q.nfcall(mkdirp, path.dirname(name)) - .then(function () { - return Q.nfcall(fs.writeFile, name, contents); - }); - - promises.push(promise); - }); - - // Delete dummy .master file that is present on the master branch - promise = Q.nfcall(fs.unlink, path.join(dir, '.master')); - promises.push(promise); - - return Q.all(promises); - }) - // Stage files - .then(cmd.bind(null, 'git', ['add', '-A'], { cwd: dir })) - // Commit - // Note that we force a specific date and author so that the same - // commit-sha's are always equal - // These commit-sha's are used internally in tests! - .then(function () { - return cmd('git', ['commit', '-m"Commit for ' + branch + '."'], { - cwd: dir, - env: env - }); - }) - // Tag - .then(function () { - if (!semver.valid(release)) { - return; - } - - return cmd('git', ['tag', '-f', release], { cwd: dir }) - // Delete branch (not necessary anymore) - .then(cmd.bind(null, 'git', ['checkout', 'master', '-f'], { cwd: dir })) - .then(cmd.bind(null, 'git', ['branch', '-D', branch], { cwd: dir })); - }); + return ( + cmd('git', ['checkout', 'master', '-f'], { cwd: dir }) + // Attempt to delete branch, ignoring the error + .then(function() { + return cmd('git', ['branch', '-D', branch], { cwd: dir }).fail( + function() {} + ); + }) + // Checkout based on master + .then( + cmd.bind(null, 'git', ['checkout', '-b', branch, 'master'], { + cwd: dir + }) + ) + // Create files + .then(function() { + var promise; + var promises = []; + + mout.object.forOwn(files, function(contents, name) { + name = path.join(dir, name); + + // Convert contents to JSON if they are not a string + if (typeof contents !== 'string') { + contents = JSON.stringify(contents, null, ' '); + } + + promise = Q.nfcall(mkdirp, path.dirname(name)).then( + function() { + return Q.nfcall(fs.writeFile, name, contents); + } + ); + + promises.push(promise); + }); + + // Delete dummy .master file that is present on the master branch + promise = Q.nfcall(fs.unlink, path.join(dir, '.master')); + promises.push(promise); + + return Q.all(promises); + }) + // Stage files + .then(cmd.bind(null, 'git', ['add', '-A'], { cwd: dir })) + // Commit + // Note that we force a specific date and author so that the same + // commit-sha's are always equal + // These commit-sha's are used internally in tests! + .then(function() { + return cmd( + 'git', + ['commit', '-m"Commit for ' + branch + '."'], + { + cwd: dir, + env: env + } + ); + }) + // Tag + .then(function() { + if (!semver.valid(release)) { + return; + } + + return ( + cmd('git', ['tag', '-f', release], { cwd: dir }) + // Delete branch (not necessary anymore) + .then( + cmd.bind( + null, + 'git', + ['checkout', 'master', '-f'], + { cwd: dir } + ) + ) + .then( + cmd.bind(null, 'git', ['branch', '-D', branch], { + cwd: dir + }) + ) + ); + }) + ); } var promises = []; // Process packages.json -mout.object.forOwn(packages, function (pkg, name) { +mout.object.forOwn(packages, function(pkg, name) { var promise; var dir = path.join(__dirname, 'assets', name); // Ensure package is created promise = ensurePackage(dir); - promise = promise.fail(function (err) { + promise = promise.fail(function(err) { console.log('Failed to create ' + name); console.log(err.message); }); - mout.object.forOwn(pkg, function (files, release) { + mout.object.forOwn(pkg, function(files, release) { // Check if the release already exists - promise = promise.then(checkRelease.bind(null, dir, release)) - .then(function (exists) { - // Skip it if already created - if (exists) { - return console.log(chalk.cyan('> ') + 'Package ' + name + '#' + release + ' already created'); - } - - // Create it based on the metadata - return createRelease(dir, release, files) - .then(function () { - console.log(chalk.green('> ') + 'Package ' + name + '#' + release + ' successfully created'); + promise = promise + .then(checkRelease.bind(null, dir, release)) + .then(function(exists) { + // Skip it if already created + if (exists) { + return console.log( + chalk.cyan('> ') + + 'Package ' + + name + + '#' + + release + + ' already created' + ); + } + + // Create it based on the metadata + return createRelease(dir, release, files).then(function() { + console.log( + chalk.green('> ') + + 'Package ' + + name + + '#' + + release + + ' successfully created' + ); + }); + }) + .fail(function(err) { + console.log( + chalk.red('> ') + 'Failed to create ' + name + '#' + release + ); + console.log(err.message.trim()); + if (err.details) { + console.log(err.details.trim()); + } + console.log(err.stack); }); - }) - .fail(function (err) { - console.log(chalk.red('> ') + 'Failed to create ' + name + '#' + release); - console.log(err.message.trim()); - if (err.details) { - console.log(err.details.trim()); - } - console.log(err.stack); - }); }); promises.push(promise); }); -Q.allSettled(promises, function (results) { - results.forEach(function (result) { +Q.allSettled(promises, function(results) { + results.forEach(function(result) { if (result.state !== 'fulfilled') { process.exit(1); } diff --git a/test/renderers/JsonRenderer.js b/test/renderers/JsonRenderer.js index fe9cf19e2..fa144a425 100644 --- a/test/renderers/JsonRenderer.js +++ b/test/renderers/JsonRenderer.js @@ -4,55 +4,64 @@ var multiline = require('multiline').stripIndent; var JsonRenderer = helpers.require('lib/renderers/JsonRenderer'); -var jsonRendererWithPrompt = function (stubs) { +var jsonRendererWithPrompt = function(stubs) { return helpers.require('lib/renderers/JsonRenderer', { promptly: stubs }); }; // When cloning on Windows it's possible carrets are used -var normalize = function (string) { +var normalize = function(string) { return string.replace(/\r\n|\r/g, '\n'); }; -describe('JsonRenderer', function () { +describe('JsonRenderer', function() { + it('logs simple message to stderr', function() { + return helpers + .capture(function() { + var renderer = new JsonRenderer(); + renderer.log({ + id: 'foobar', + message: 'hello world' + }); - it('logs simple message to stderr', function () { - return helpers.capture(function () { - var renderer = new JsonRenderer(); - renderer.log({ - id: 'foobar', - message: 'hello world' - }); - - renderer.end(); - }).spread(function (stdout, stderr) { - expect(stderr).to.eq(normalize(multiline(function () {/* + renderer.end(); + }) + .spread(function(stdout, stderr) { + expect(stderr).to.eq( + normalize( + multiline(function() { + /* [{ "id": "foobar", "message": "hello world" }] - */}))); - }); + */ + }) + ) + ); + }); }); - it('logs error message to stderr', function () { - return helpers.capture(function () { - var renderer = new JsonRenderer(); - renderer.error({ - id: 'foobar', - message: 'hello world', - data: { - foo: 'bar' - }, - stacktrace: [ - './foo:23', - './bar:23' - ] - }); - }).spread(function (stdout, stderr) { - expect(stderr).to.eq(normalize(multiline(function () {/* + it('logs error message to stderr', function() { + return helpers + .capture(function() { + var renderer = new JsonRenderer(); + renderer.error({ + id: 'foobar', + message: 'hello world', + data: { + foo: 'bar' + }, + stacktrace: ['./foo:23', './bar:23'] + }); + }) + .spread(function(stdout, stderr) { + expect(stderr).to.eq( + normalize( + multiline(function() { + /* [{ "id": "error", "data": { @@ -63,33 +72,43 @@ describe('JsonRenderer', function () { "message": "hello world" }] - */}))); - }); + */ + }) + ) + ); + }); }); - it('prompts for answer', function () { + it('prompts for answer', function() { var JsonRenderer = jsonRendererWithPrompt({ - prompt: function (name, opts, callback) { + prompt: function(name, opts, callback) { callback(null, 'something2'); } }); var renderer = new JsonRenderer(); - return helpers.capture(function () { - return renderer.prompt([ - { - type: 'input', - name: 'field', - message: 'Please enter something', - default: 'something' - } - ]).then(function (response) { - expect(response.field).to.eq('something2'); - renderer.end(); - }); - }).spread(function (stdout, stderr) { - expect(stderr).to.eq(normalize(multiline(function () {/* + return helpers + .capture(function() { + return renderer + .prompt([ + { + type: 'input', + name: 'field', + message: 'Please enter something', + default: 'something' + } + ]) + .then(function(response) { + expect(response.field).to.eq('something2'); + renderer.end(); + }); + }) + .spread(function(stdout, stderr) { + expect(stderr).to.eq( + normalize( + multiline(function() { + /* [{ "type": "input", "name": "field", @@ -98,7 +117,10 @@ describe('JsonRenderer', function () { "level": "prompt" }] - */}))); - }); + */ + }) + ) + ); + }); }); }); diff --git a/test/renderers/StandardRenderer.js b/test/renderers/StandardRenderer.js index 7617302e2..bf3aa1f83 100644 --- a/test/renderers/StandardRenderer.js +++ b/test/renderers/StandardRenderer.js @@ -7,244 +7,314 @@ var multiline = require('multiline').stripIndent; var StandardRenderer = helpers.require('lib/renderers/StandardRenderer'); -describe('StandardRenderer', function () { - - it('logs generic simple message', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer(); - renderer.log({ - id: 'foobar', - message: 'hello world' - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.eq(multiline(function () {/* +describe('StandardRenderer', function() { + it('logs generic simple message', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer(); + renderer.log({ + id: 'foobar', + message: 'hello world' + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.eq( + multiline(function() { + /* bower foobar hello world - */})); - }); + */ + }) + ); + }); }); - it('logs simple error', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer(); - renderer.error({ - code: 'EFOOBAR', - message: 'Hello error' - }); - }).spread(function (stdout, stderr) { - expect(stderr).to.eq(multiline(function () {/* + it('logs simple error', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer(); + renderer.error({ + code: 'EFOOBAR', + message: 'Hello error' + }); + }) + .spread(function(stdout, stderr) { + expect(stderr).to.eq( + multiline(function() { + /* bower EFOOBAR Hello error - */})); - }); + */ + }) + ); + }); }); - it('logs error with details', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer(); - renderer.error({ - code: 'EFOOBAR', - message: 'Hello error', - details: ' Some awesome details\nMultiline! ' - }); - }).spread(function (stdout, stderr) { - expect(stderr).to.eq(multiline(function () {/* + it('logs error with details', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer(); + renderer.error({ + code: 'EFOOBAR', + message: 'Hello error', + details: ' Some awesome details\nMultiline! ' + }); + }) + .spread(function(stdout, stderr) { + expect(stderr).to.eq( + multiline(function() { + /* bower EFOOBAR Hello error Additional error details: Some awesome details Multiline! - */})); - }); + */ + }) + ); + }); }); - it('logs system details in verbose mode', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer(undefined, { verbose: true }); - renderer.error({ - code: 'EFOOBAR', - message: 'Hello error', - details: ' Some awesome details\nMultiline! ' - }); - }).spread(function (stdout, stderr) { - expect(stderr).to.match(new RegExp(multiline(function () {/* + it('logs system details in verbose mode', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer(undefined, { + verbose: true + }); + renderer.error({ + code: 'EFOOBAR', + message: 'Hello error', + details: ' Some awesome details\nMultiline! ' + }); + }) + .spread(function(stdout, stderr) { + expect(stderr).to.match( + new RegExp( + multiline(function() { + /* System info: Bower version: [^\r\n]+ Node version: [^\r\n]+ OS: [^\r\n]+ - */}))); - }); + */ + }) + ) + ); + }); }); - it('logs stack trace in verbose mode', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer(undefined, { verbose: true }); - renderer.error({ - code: 'EFOOBAR', - message: 'Hello error', - details: ' Some awesome details\nMultiline! ', - stack: [ - './one.js:1', - './two.js:2' - ] - }); - }).spread(function (stdout, stderr) { - expect(stderr).to.string(multiline(function () {/* + it('logs stack trace in verbose mode', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer(undefined, { + verbose: true + }); + renderer.error({ + code: 'EFOOBAR', + message: 'Hello error', + details: ' Some awesome details\nMultiline! ', + stack: ['./one.js:1', './two.js:2'] + }); + }) + .spread(function(stdout, stderr) { + expect(stderr).to.string( + multiline(function() { + /* Stack trace: ./one.js:1 ./two.js:2 - */})); - }); + */ + }) + ); + }); }); - it('logs console trace in verbose mode', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer(undefined, { verbose: true }); - renderer.error({ - code: 'EFOOBAR', - message: 'Hello error', - details: ' Some awesome details\nMultiline! ' - }); - }).spread(function (stdout, stderr) { - expect(stderr).to.match(new RegExp(multiline(function () {/* + it('logs console trace in verbose mode', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer(undefined, { + verbose: true + }); + renderer.error({ + code: 'EFOOBAR', + message: 'Hello error', + details: ' Some awesome details\nMultiline! ' + }); + }) + .spread(function(stdout, stderr) { + expect(stderr).to.match( + new RegExp( + multiline(function() { + /* Console trace: Error \s+at StandardRenderer.error \(.+?\) - */}))); - }); + */ + }) + ) + ); + }); }); - it('outputs checkout command log', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer(); - renderer.log({ - id: 'checkout', - origin: 'jquery#master', - message: 'foobar' - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + it('outputs checkout command log', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer(); + renderer.log({ + id: 'checkout', + origin: 'jquery#master', + message: 'foobar' + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* bower checkout jquery#foobar - */})); - }); + */ + }) + ); + }); }); - it('outputs full progress for wide command', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('install'); - renderer.log({ - id: 'progress', - origin: 'jquery#master', - message: 'foobar' - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + it('outputs full progress for wide command', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('install'); + renderer.log({ + id: 'progress', + origin: 'jquery#master', + message: 'foobar' + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* bower jquery#master progress foobar - */})); - }); + */ + }) + ); + }); }); - it('outputs full progress for narrow command', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('help'); - renderer.log({ - id: 'progress', - origin: 'jquery#master', - message: 'foobar' - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + it('outputs full progress for narrow command', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('help'); + renderer.log({ + id: 'progress', + origin: 'jquery#master', + message: 'foobar' + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* bower progress jquery#master foobar - */})); - }); + */ + }) + ); + }); }); - it('outputs extract log just as progress log', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('install'); - renderer.log({ - id: 'extract', - origin: 'jquery#master', - message: 'foobar' - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + it('outputs extract log just as progress log', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('install'); + renderer.log({ + id: 'extract', + origin: 'jquery#master', + message: 'foobar' + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* bower jquery#master extract foobar - */})); - }); + */ + }) + ); + }); }); - it('outputs incompatible log with suitable package', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer(); - renderer.log({ - id: 'incompatible', - data: { - resolution: '~0.1.1', - suitable: { - pkgMeta: { - _release: '0.1.2' - }, - endpoint: { - name: 'foobar' - } - }, - picks: [ - { + it('outputs incompatible log with suitable package', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer(); + renderer.log({ + id: 'incompatible', + data: { + resolution: '~0.1.1', + suitable: { pkgMeta: { - _release: '0.0.0' + _release: '0.1.2' }, endpoint: { - name: 'fizfuz', - target: '~0.0.0' - }, - dependants: [ - { - pkgMeta: { - _release: 'release1' - }, - endpoint: { - name: 'dependant1' - } + name: 'foobar' + } + }, + picks: [ + { + pkgMeta: { + _release: '0.0.0' + }, + endpoint: { + name: 'fizfuz', + target: '~0.0.0' }, - { - pkgMeta: { - _release: 'release2' + dependants: [ + { + pkgMeta: { + _release: 'release1' + }, + endpoint: { + name: 'dependant1' + } }, - endpoint: { - name: 'dependant2' + { + pkgMeta: { + _release: 'release2' + }, + endpoint: { + name: 'dependant2' + } } - } - ] - }, - { - endpoint: { - name: 'fizfuz2' + ] }, - dependants: [ - { - pkgMeta: { - // no release - }, - endpoint: { - name: 'jquery2' + { + endpoint: { + name: 'fizfuz2' + }, + dependants: [ + { + pkgMeta: { + // no release + }, + endpoint: { + name: 'jquery2' + } } - } - ] - } - ] - } - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + ] + } + ] + } + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* Please note that, dependant1#release1, dependant2#release2 depends on fizfuz#~0.0.0 which resolved to fizfuz#0.0.0 @@ -253,65 +323,71 @@ describe('StandardRenderer', function () { Code incompatibilities may occur. - */})); - }); + */ + }) + ); + }); }); - it('outputs solver log without suitable package', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer(); - renderer.log({ - id: 'solved', - data: { - resolution: '~0.1.1', - picks: [ - { - pkgMeta: { - _release: '0.0.0' - }, - endpoint: { - name: 'fizfuz', - target: '~0.0.0' - }, - dependants: [ - { - pkgMeta: { - _release: 'release1' - }, - endpoint: { - name: 'dependant1' - } + it('outputs solver log without suitable package', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer(); + renderer.log({ + id: 'solved', + data: { + resolution: '~0.1.1', + picks: [ + { + pkgMeta: { + _release: '0.0.0' }, - { - pkgMeta: { - _release: 'release2' + endpoint: { + name: 'fizfuz', + target: '~0.0.0' + }, + dependants: [ + { + pkgMeta: { + _release: 'release1' + }, + endpoint: { + name: 'dependant1' + } }, - endpoint: { - name: 'dependant2' + { + pkgMeta: { + _release: 'release2' + }, + endpoint: { + name: 'dependant2' + } } - } - ] - }, - { - endpoint: { - name: 'fizfuz2' + ] }, - dependants: [ - { - pkgMeta: { - // no release - }, - endpoint: { - name: 'jquery2' + { + endpoint: { + name: 'fizfuz2' + }, + dependants: [ + { + pkgMeta: { + // no release + }, + endpoint: { + name: 'jquery2' + } } - } - ] - } - ] - } - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + ] + } + ] + } + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* Unable to find a suitable version for , please choose one by typing one of the numbers below: 1) fizfuz#~0.0.0 which resolved to 0.0.0 and is required by dependant1#release1, dependant2#release2 @@ -320,26 +396,32 @@ describe('StandardRenderer', function () { Prefix the choice with ! to persist it to bower.json - */})); - }); + */ + }) + ); + }); }); - it('outputs json log', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer(); - renderer.log({ - id: 'json', - data: { - json: { - foo: 'bar', - fiz: { - fuz: 'faz' + it('outputs json log', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer(); + renderer.log({ + id: 'json', + data: { + json: { + foo: 'bar', + fiz: { + fuz: 'faz' + } } } - } - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* { foo: 'bar', @@ -349,192 +431,210 @@ describe('StandardRenderer', function () { } - */})); - }); - }); - - it('outputs cached entry log', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('install'); - renderer.log({ - id: 'cached-entry', - origin: 'origin', - message: 'message' + */ + }) + ); }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* - bower origin cached message - - */})); - }); }); - it('adjusts whitespace when package id too long', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('install', {}); - renderer.log({ - id: 'generic', - origin: 'short-origin', - message: 'message' - }); + it('outputs cached entry log', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('install'); + renderer.log({ + id: 'cached-entry', + origin: 'origin', + message: 'message' + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* + bower origin cached message - renderer.log({ - id: 'generic', - origin: 'very-very-long-origin-string', - message: 'message' + */ + }) + ); }); + }); - renderer.log({ - id: 'generic', - origin: 'short-origin', - message: 'message' - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + it('adjusts whitespace when package id too long', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('install', {}); + renderer.log({ + id: 'generic', + origin: 'short-origin', + message: 'message' + }); + + renderer.log({ + id: 'generic', + origin: 'very-very-long-origin-string', + message: 'message' + }); + + renderer.log({ + id: 'generic', + origin: 'short-origin', + message: 'message' + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* bower short-origin generic message bower very-very-long-origin-string generic message bower short-origin generic message - */})); - }); + */ + }) + ); + }); }); - it('outputs install command log', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('install', { - cwd: '/tmp' - }); + it('outputs install command log', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('install', { + cwd: '/tmp' + }); - renderer.end([ - { - canonicalDir: '/tmp/components/jquery', - pkgMeta: { - _release: '0.1.2' - }, - endpoint: { - name: 'jquery' - } - }, - { - canonicalDir: '/tmp/components/jquery', - pkgMeta: { - version: '0.1.2' - }, - endpoint: { - name: 'jquery' - } - }, - { - canonicalDir: '/tmp/components/jquery', - pkgMeta: { - _release: '0.1.2' - }, - endpoint: { - name: 'jquery' - }, - missing: true - }, - { - canonicalDir: '/tmp/components/jquery', - pkgMeta: { - _release: '0.1.2' - }, - endpoint: { - name: 'jquery' - }, - different: true - }, - { - canonicalDir: '/tmp/components/jquery', - pkgMeta: { - _release: '0.1.2' - }, - endpoint: { - name: 'jquery' - }, - linked: true - }, - { - canonicalDir: '/tmp/components/jquery', - pkgMeta: { - _release: '0.1.2' + renderer.end([ + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery' + } }, - endpoint: { - name: 'jquery', - target: '~0.1.2' + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + version: '0.1.2' + }, + endpoint: { + name: 'jquery' + } }, - incompatible: true - }, - { - canonicalDir: '/tmp/components/jquery', - pkgMeta: { - _release: '0.1.2' + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery' + }, + missing: true }, - endpoint: { - name: 'jquery', - target: '~0.1.2' + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery' + }, + different: true }, - extraneous: true - }, - { - canonicalDir: '/tmp/components/jquery', - pkgMeta: { - _release: '0.1.2' + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery' + }, + linked: true }, - endpoint: { - name: 'jquery', - target: '~0.1.2' + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery', + target: '~0.1.2' + }, + incompatible: true }, - update: { - target: '0.1.5', - latest: '0.2.0' - } - }, - { - canonicalDir: '/tmp/components/jquery', - pkgMeta: { - _release: '0.1.2' + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery', + target: '~0.1.2' + }, + extraneous: true }, - endpoint: { - name: 'jquery' + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery', + target: '~0.1.2' + }, + update: { + target: '0.1.5', + latest: '0.2.0' + } }, - dependencies: { - angular: { - canonicalDir: '/tmp/components/angular', - pkgMeta: { - _release: '0.1.3' - }, - endpoint: { - name: 'angular' - } + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' }, - ember: { - canonicalDir: '/tmp/components/ember', - pkgMeta: { - _release: '0.2.3' - }, - endpoint: { - name: 'ember' + endpoint: { + name: 'jquery' + }, + dependencies: { + angular: { + canonicalDir: '/tmp/components/angular', + pkgMeta: { + _release: '0.1.3' + }, + endpoint: { + name: 'angular' + } }, - dependencies: { - // Should be ingored (only one level) - react: { - canonicalDir: '/tmp/components/react', - pkgMeta: { - _release: '0.2.3' - }, - endpoint: { - name: 'react' + ember: { + canonicalDir: '/tmp/components/ember', + pkgMeta: { + _release: '0.2.3' + }, + endpoint: { + name: 'ember' + }, + dependencies: { + // Should be ingored (only one level) + react: { + canonicalDir: '/tmp/components/react', + pkgMeta: { + _release: '0.2.3' + }, + endpoint: { + name: 'react' + } } } } } } - } - ]); - }).spread(function (stdout, stderr) { - if (helpers.isWin()) { - expect(stdout).to.equal(multiline(function () {/* + ]); + }) + .spread(function(stdout, stderr) { + if (helpers.isWin()) { + expect(stdout).to.equal( + multiline(function() { + /* jquery#0.1.2 components\jquery @@ -556,9 +656,13 @@ describe('StandardRenderer', function () { ├── angular#0.1.3 └── ember#0.2.3 - */})); - } else { - expect(stdout).to.equal(multiline(function () {/* + */ + }) + ); + } else { + expect(stdout).to.equal( + multiline(function() { + /* jquery#0.1.2 components/jquery @@ -580,48 +684,60 @@ describe('StandardRenderer', function () { ├── angular#0.1.3 └── ember#0.2.3 - */})); - } - }); + */ + }) + ); + } + }); }); - it('outputs short info command log', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('info', {}); - renderer.end({ - version: '1.2.3' - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + it('outputs short info command log', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('info', {}); + renderer.end({ + version: '1.2.3' + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* { version: '1.2.3' } - */})); - }); + */ + }) + ); + }); }); - it('outputs full info command log', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('info', {}); - renderer.end({ - name: 'foo', - latest: { - version: '1.2.3' - }, - versions: [ - '1.2.0', - '1.2.1', - '1.2.2', - '1.2.3+build-1234', - '1.2.8-build.2098+sha.cb9c0f2', - '1.3.0-rc.5', - '1.3.0-beta.18' - ] - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + it('outputs full info command log', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('info', {}); + renderer.end({ + name: 'foo', + latest: { + version: '1.2.3' + }, + versions: [ + '1.2.0', + '1.2.1', + '1.2.2', + '1.2.3+build-1234', + '1.2.8-build.2098+sha.cb9c0f2', + '1.3.0-rc.5', + '1.3.0-beta.18' + ] + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* { version: '1.2.3' @@ -635,30 +751,36 @@ describe('StandardRenderer', function () { Show 4 additional prereleases with ‘bower info foo --verbose’ You can request info for a specific version with 'bower info foo#' - */})); - }); + */ + }) + ); + }); }); - it('outputs full info command log with prereleases', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('info', { verbose: true }); - renderer.end({ - name: 'foo', - latest: { - version: '1.2.3' - }, - versions: [ - '1.2.0', - '1.2.1', - '1.2.2', - '1.2.3+build-1234', - '1.2.8-build.2098+sha.cb9c0f2', - '1.3.0-rc.5', - '1.3.0-beta.18' - ] - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + it('outputs full info command log with prereleases', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('info', { verbose: true }); + renderer.end({ + name: 'foo', + latest: { + version: '1.2.3' + }, + versions: [ + '1.2.0', + '1.2.1', + '1.2.2', + '1.2.3+build-1234', + '1.2.8-build.2098+sha.cb9c0f2', + '1.3.0-rc.5', + '1.3.0-beta.18' + ] + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* { version: '1.2.3' @@ -675,97 +797,127 @@ describe('StandardRenderer', function () { You can request info for a specific version with 'bower info foo#' - */})); - }); + */ + }) + ); + }); }); - it('outputs lookup command log', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('lookup', {}); - renderer.end({ - name: 'bower', - url: 'http://bower.io' - }); - renderer.end({ - name: 'bower' - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + it('outputs lookup command log', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('lookup', {}); + renderer.end({ + name: 'bower', + url: 'http://bower.io' + }); + renderer.end({ + name: 'bower' + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* bower http://bower.io Package not found. - */})); - }); + */ + }) + ); + }); }); - it('outputs link command log', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('link', { cwd: '/tmp' }); - renderer.end({ - src: './foo', - dst: './bar', - installed: [{ - canonicalDir: '/tmp/components/jquery', - pkgMeta: { - _release: '0.1.2' - }, - endpoint: { - name: 'jquery' - } - }] - }); - }).spread(function (stdout, stderr) { - if (helpers.isWin()) { - expect(stdout).to.equal(multiline(function () {/* + it('outputs link command log', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('link', { cwd: '/tmp' }); + renderer.end({ + src: './foo', + dst: './bar', + installed: [ + { + canonicalDir: '/tmp/components/jquery', + pkgMeta: { + _release: '0.1.2' + }, + endpoint: { + name: 'jquery' + } + } + ] + }); + }) + .spread(function(stdout, stderr) { + if (helpers.isWin()) { + expect(stdout).to.equal( + multiline(function() { + /* bower link ./bar > ./foo jquery#0.1.2 components\jquery - */})); - } else { - expect(stdout).to.equal(multiline(function () {/* + */ + }) + ); + } else { + expect(stdout).to.equal( + multiline(function() { + /* bower link ./bar > ./foo jquery#0.1.2 components/jquery - */})); - } - }); + */ + }) + ); + } + }); }); - it('outputs search command log', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('search'); - renderer.end([ - { - name: 'jquery', - url: 'http://jquery.io' - }, - { - name: 'bower', - url: 'http://bower.io' - } - ]); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + it('outputs search command log', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('search'); + renderer.end([ + { + name: 'jquery', + url: 'http://jquery.io' + }, + { + name: 'bower', + url: 'http://bower.io' + } + ]); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* Search results: jquery http://jquery.io bower http://bower.io - */})); - }); + */ + }) + ); + }); }); - it('outputs register command log', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('register'); - renderer.end({ - name: 'jquery', - url: 'http://jquery.io' - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + it('outputs register command log', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('register'); + renderer.end({ + name: 'jquery', + url: 'http://jquery.io' + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* Package jquery registered successfully! All valid semver tags on http://jquery.io will be available as versions. @@ -773,59 +925,72 @@ describe('StandardRenderer', function () { Run bower info jquery to list the available versions. - */})); - }); + */ + }) + ); + }); }); - it('outputs cache list command log', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('cache list'); - renderer.end([ - { - pkgMeta: { - name: 'awesome-jquery', - _target: '0.1.1', - _source: 'jquery' + it('outputs cache list command log', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('cache list'); + renderer.end([ + { + pkgMeta: { + name: 'awesome-jquery', + _target: '0.1.1', + _source: 'jquery' + } } - } - ]); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + ]); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* awesome-jquery=jquery#0.1.1 - */})); - }); + */ + }) + ); + }); }); - it('outputs help command log', function () { - return helpers.capture(function () { - var renderer = new StandardRenderer('help'); - renderer.end({ - 'command': 'uninstall', - 'description': 'Uninstalls a package locally from your bower_components directory', - 'usage': [ - 'uninstall [ ..] []' - ], - 'options': [ - { - 'shorthand': '-h', - 'flag': '--help', - 'description': 'Show this help message' - }, - { - 'shorthand': '-S', - 'flag': '--save', - 'description': 'Remove uninstalled packages from the project\'s bower.json dependencies' - }, - { - 'shorthand': '-D', - 'flag': '--save-dev', - 'description': 'Remove uninstalled packages from the project\'s bower.json devDependencies' - } - ] - }); - }).spread(function (stdout, stderr) { - expect(stdout).to.equal(multiline(function () {/* + it('outputs help command log', function() { + return helpers + .capture(function() { + var renderer = new StandardRenderer('help'); + renderer.end({ + command: 'uninstall', + description: + 'Uninstalls a package locally from your bower_components directory', + usage: ['uninstall [ ..] []'], + options: [ + { + shorthand: '-h', + flag: '--help', + description: 'Show this help message' + }, + { + shorthand: '-S', + flag: '--save', + description: + "Remove uninstalled packages from the project's bower.json dependencies" + }, + { + shorthand: '-D', + flag: '--save-dev', + description: + "Remove uninstalled packages from the project's bower.json devDependencies" + } + ] + }); + }) + .spread(function(stdout, stderr) { + expect(stdout).to.equal( + multiline(function() { + /* Usage: @@ -842,7 +1007,9 @@ describe('StandardRenderer', function () { Uninstalls a package locally from your bower_components directory - */})); - }); + */ + }) + ); + }); }); }); diff --git a/test/util/createLink.js b/test/util/createLink.js index d56926d6c..5dece8e10 100644 --- a/test/util/createLink.js +++ b/test/util/createLink.js @@ -5,8 +5,7 @@ var expect = require('expect.js'); var helpers = require('../helpers'); var createLink = require('../../lib/util/createLink'); -describe('createLink', function () { - +describe('createLink', function() { var srcDir = new helpers.TempDir({ someFile: 'Hello World', someDirectory: { @@ -16,42 +15,37 @@ describe('createLink', function () { var dstDir = new helpers.TempDir(); - beforeEach(function () { + beforeEach(function() { srcDir.prepare(); dstDir.prepare(); }); - it('creates a symlink to a file', function () { - + it('creates a symlink to a file', function() { var src = path.join(srcDir.path, 'someFile'), dst = path.join(dstDir.path, 'someFile'); - return createLink(src, dst) - .then(function () { - return Q.nfcall(fs.readlink, dst) - .then(function (linkString) { + return createLink(src, dst).then(function() { + return Q.nfcall(fs.readlink, dst).then(function(linkString) { expect(linkString).to.be.equal(src); }); }); }); - it('throws an error when destination already exists', function () { - + it('throws an error when destination already exists', function() { var src = path.join(srcDir.path, 'someFile'), dst = path.join(dstDir.path); var deferred = Q.defer(); createLink(src, dst) - .catch(function (err) { - expect(err.code).to.be.equal('EEXIST'); - deferred.resolve(); - }) - .then(function () { - deferred.reject(); - }); + .catch(function(err) { + expect(err.code).to.be.equal('EEXIST'); + deferred.resolve(); + }) + .then(function() { + deferred.reject(); + }); return deferred.promise; }); - }); diff --git a/test/util/download.js b/test/util/download.js index 4df551a7a..827238209 100644 --- a/test/util/download.js +++ b/test/util/download.js @@ -7,8 +7,7 @@ var Q = require('q'); var fs = require('../../lib/util/fs'); var download = require('../../lib/util/download'); -describe('download', function () { - +describe('download', function() { var tempDir = new helpers.TempDir(), source = path.resolve(__dirname, '../assets/package-tar.tar.gz'), destination = tempDir.getPath('package.tar.gz'); @@ -18,44 +17,53 @@ describe('download', function () { tempDir.prepare(); - opts.response( - nock('http://bower.io', opts.nockOpts) - ); - - download(opts.sourceUrl || 'http://bower.io/package.tar.gz', opts.destinationPath || destination, opts.downloadOpts) - .then(function (result) { - if (opts.expect) { - opts.expect(result); - deferred.resolve(); - } else { - deferred.reject(new Error('Error expected. Got successful response.')); - } - }, function (error) { - if (opts.expectError) { - opts.expectError(error); - deferred.resolve(); - } else { - deferred.reject(error); + opts.response(nock('http://bower.io', opts.nockOpts)); + + download( + opts.sourceUrl || 'http://bower.io/package.tar.gz', + opts.destinationPath || destination, + opts.downloadOpts + ) + .then( + function(result) { + if (opts.expect) { + opts.expect(result); + deferred.resolve(); + } else { + deferred.reject( + new Error( + 'Error expected. Got successful response.' + ) + ); + } + }, + function(error) { + if (opts.expectError) { + opts.expectError(error); + deferred.resolve(); + } else { + deferred.reject(error); + } } - }) + ) .done(); return deferred.promise; } - it('download file to directory', function () { + it('download file to directory', function() { return downloadTest({ - response: function (nock) { + response: function(nock) { nock.get('/package.tar.gz').replyWithFile(200, source); }, - expect: function () { + expect: function() { expect(fs.existsSync(destination)).to.be(true); expect(fs.readdirSync(tempDir.path)).to.have.length(1); } }); }); - it('pass custom user-agent to server', function () { + it('pass custom user-agent to server', function() { var userAgent = 'Custom User-Agent'; return downloadTest({ nockOpts: { @@ -68,46 +76,49 @@ describe('download', function () { 'User-Agent': userAgent } }, - response: function (nock) { + response: function(nock) { nock.get('/package.tar.gz').replyWithFile(200, source); }, - expect: function () { + expect: function() { expect(fs.existsSync(destination)).to.be(true); expect(fs.readdirSync(tempDir.path)).to.have.length(1); } }); }); - it('handle server response 404', function () { + it('handle server response 404', function() { return downloadTest({ - response: function (nock) { + response: function(nock) { nock.get('/package.tar.gz').reply(404); }, - expectError: function () { + expectError: function() { expect(fs.readdirSync(tempDir.path)).to.be.empty(); } }); }); - it('handle network error', function () { + it('handle network error', function() { return downloadTest({ - response: function (nock) { + response: function(nock) { nock.get('/package.tar.gz').replyWithError('network error'); }, - expectError: function () { + expectError: function() { expect(fs.readdirSync(tempDir.path)).to.be.empty(); } }); }); - - it('handles connection timeout', function () { + it('handles connection timeout', function() { return downloadTest({ - response: function (nock) { + response: function(nock) { // First connection + 5 retries - nock.get('/package.tar.gz').times(6).delayConnection(1000).replyWithFile(200, source); + nock + .get('/package.tar.gz') + .times(6) + .delayConnection(1000) + .replyWithFile(200, source); }, - expectError: function (e) { + expectError: function(e) { expect(e.code).to.be('ESOCKETTIMEDOUT'); expect(fs.readdirSync(tempDir.path)).to.be.empty(); }, @@ -119,13 +130,17 @@ describe('download', function () { }); }); - it('handles socket timeout', function () { + it('handles socket timeout', function() { return downloadTest({ - response: function (nock) { + response: function(nock) { // First connection + 5 retries - nock.get('/package.tar.gz').times(6).socketDelay(1000).replyWithFile(200, source); + nock + .get('/package.tar.gz') + .times(6) + .socketDelay(1000) + .replyWithFile(200, source); }, - expectError: function (e) { + expectError: function(e) { expect(e.code).to.be('ESOCKETTIMEDOUT'); expect(fs.readdirSync(tempDir.path)).to.be.empty(); }, @@ -137,15 +152,19 @@ describe('download', function () { }); }); - it('handles retries correctly', function () { + it('handles retries correctly', function() { return downloadTest({ - response: function (nock) { + response: function(nock) { // First connection + 5 retries - nock.get('/package.tar.gz').times(5).delayConnection(1000).replyWithFile(200, source); + nock + .get('/package.tar.gz') + .times(5) + .delayConnection(1000) + .replyWithFile(200, source); // Success last time nock.get('/package.tar.gz').replyWithFile(200, source); }, - expect: function () { + expect: function() { expect(fs.existsSync(destination)).to.be(true); expect(fs.readdirSync(tempDir.path)).to.have.length(1); }, @@ -157,15 +176,19 @@ describe('download', function () { }); }); - it('fails on incorrect Content-Length match', function () { + it('fails on incorrect Content-Length match', function() { return downloadTest({ - response: function (nock) { + response: function(nock) { // First connection + 5 retries - nock.get('/package.tar.gz').replyWithFile(200, source, { 'Content-Length': 5000 }); + nock + .get('/package.tar.gz') + .replyWithFile(200, source, { 'Content-Length': 5000 }); }, - expectError: function (e) { + expectError: function(e) { expect(e.code).to.be('EINCOMPLETE'); - expect(e.message).to.be('Transfer closed with 4636 bytes remaining to read'); + expect(e.message).to.be( + 'Transfer closed with 4636 bytes remaining to read' + ); }, downloadOpts: { timeout: 10, @@ -175,34 +198,37 @@ describe('download', function () { }); }); - describe('gzipped files', function () { - + describe('gzipped files', function() { function testGzip(sourceFilename) { - var sourceFile = path.resolve(__dirname, '../assets/' + sourceFilename); + var sourceFile = path.resolve( + __dirname, + '../assets/' + sourceFilename + ); var destinationPath = tempDir.getPath(sourceFilename); return downloadTest({ - response: function (nock) { + response: function(nock) { nock - .get('/' + sourceFilename) - .replyWithFile(200, sourceFile, { - 'Content-Encoding' : 'gzip' - }); + .get('/' + sourceFilename) + .replyWithFile(200, sourceFile, { + 'Content-Encoding': 'gzip' + }); }, - expect: function () { - expect(fs.readFileSync(destinationPath, 'ascii')) - .to.be('Hello World!\n'); + expect: function() { + expect(fs.readFileSync(destinationPath, 'ascii')).to.be( + 'Hello World!\n' + ); }, sourceUrl: 'http://bower.io/' + sourceFilename, destinationPath: destinationPath }); } - it('correctly decodes gzipped files without gz extension', function () { + it('correctly decodes gzipped files without gz extension', function() { return testGzip('test-gz.txt'); }); - it('correctly decodes gzipped files with gz extension', function () { + it('correctly decodes gzipped files with gz extension', function() { return testGzip('test-gz.txt.gz'); }); }); diff --git a/test/util/index.js b/test/util/index.js index c955d56f7..936c1718e 100644 --- a/test/util/index.js +++ b/test/util/index.js @@ -1,4 +1,4 @@ -describe('util', function () { +describe('util', function() { require('./removeIgnores'); require('./download'); require('./isPathAbsolute'); diff --git a/test/util/isPathAbsolute.js b/test/util/isPathAbsolute.js index 0866744b5..8bed5ad47 100644 --- a/test/util/isPathAbsolute.js +++ b/test/util/isPathAbsolute.js @@ -1,14 +1,12 @@ var expect = require('expect.js'); var isPathAbsolute = require('../../lib/util/isPathAbsolute'); -describe('isPathAbsolute', function () { - - it('returns true when a path begins with /', function () { +describe('isPathAbsolute', function() { + it('returns true when a path begins with /', function() { expect(isPathAbsolute('/tmp/foo')).to.be.ok(); }); - it('returns false when a path does not begin with /', function () { + it('returns false when a path does not begin with /', function() { expect(isPathAbsolute('./tmp/foo')).to.not.be.ok(); }); - }); diff --git a/test/util/relativeToBaseDir.js b/test/util/relativeToBaseDir.js index c956c2c4c..8559e410e 100644 --- a/test/util/relativeToBaseDir.js +++ b/test/util/relativeToBaseDir.js @@ -2,17 +2,24 @@ var path = require('path'); var expect = require('expect.js'); var relativeToBaseDir = require('../../lib/util/relativeToBaseDir'); -describe('relativeToBaseDir', function () { - +describe('relativeToBaseDir', function() { var joinOrReturnAbsolutePath = relativeToBaseDir('/tmp'); - it('returns a partial function that joins paths of the partials first arguments', function () { - expect(joinOrReturnAbsolutePath('foo')).to.be.equal(path.resolve('/tmp/foo')); - expect(joinOrReturnAbsolutePath('./foo')).to.be.equal(path.resolve('/tmp/foo')); + it('returns a partial function that joins paths of the partials first arguments', function() { + expect(joinOrReturnAbsolutePath('foo')).to.be.equal( + path.resolve('/tmp/foo') + ); + expect(joinOrReturnAbsolutePath('./foo')).to.be.equal( + path.resolve('/tmp/foo') + ); }); - it('returns a partial function that returns it\'s first argument when it begins with /', function () { - expect(joinOrReturnAbsolutePath('/foo')).to.be.equal(path.resolve('/foo')); - expect(joinOrReturnAbsolutePath('/foo/bar')).to.be.equal(path.resolve('/foo/bar')); + it("returns a partial function that returns it's first argument when it begins with /", function() { + expect(joinOrReturnAbsolutePath('/foo')).to.be.equal( + path.resolve('/foo') + ); + expect(joinOrReturnAbsolutePath('/foo/bar')).to.be.equal( + path.resolve('/foo/bar') + ); }); }); diff --git a/test/util/removeIgnores.js b/test/util/removeIgnores.js index 6b0ffc933..88229b6af 100644 --- a/test/util/removeIgnores.js +++ b/test/util/removeIgnores.js @@ -5,21 +5,20 @@ var Q = require('q'); var removeIgnores = require('../../lib/util/removeIgnores'); -describe('removeIgnores', function () { - +describe('removeIgnores', function() { var tempDir = new helpers.TempDir({ 'bower.json': {}, 'index.js': 'Not to ignore', 'node_modules/underscore/index.js': 'Should be ignored' }); - var ignoreTest = function (dir, meta, leftovers) { + var ignoreTest = function(dir, meta, leftovers) { tempDir.prepare(); var deferred = Q.defer(); - removeIgnores(dir, meta).then(function () { - glob('**/*.*', { cwd: dir }, function (cb, files) { + removeIgnores(dir, meta).then(function() { + glob('**/*.*', { cwd: dir }, function(cb, files) { expect(files).to.eql(leftovers); deferred.resolve(); }); @@ -28,48 +27,45 @@ describe('removeIgnores', function () { return deferred.promise; }; - it('removes all files in directory', function () { - return ignoreTest(tempDir.path, - { ignore: [ 'node_modules/**/*' ] }, - [ 'bower.json', 'index.js' ] - ); + it('removes all files in directory', function() { + return ignoreTest(tempDir.path, { ignore: ['node_modules/**/*'] }, [ + 'bower.json', + 'index.js' + ]); }); - it('removes whole directory', function () { - return ignoreTest(tempDir.path, - { ignore: [ 'node_modules/' ] }, - [ 'bower.json', 'index.js' ] - ); + it('removes whole directory', function() { + return ignoreTest(tempDir.path, { ignore: ['node_modules/'] }, [ + 'bower.json', + 'index.js' + ]); }); - it('removes whole directory (no ending slash)', function () { - return ignoreTest(tempDir.path, - { ignore: [ 'node_modules' ] }, - [ 'bower.json', 'index.js' ] - ); + it('removes whole directory (no ending slash)', function() { + return ignoreTest(tempDir.path, { ignore: ['node_modules'] }, [ + 'bower.json', + 'index.js' + ]); }); - it('removes all but one file', function () { - return ignoreTest(tempDir.path, - { ignore: [ '**/*', '!bower.json' ] }, - [ 'bower.json' ] - ); + it('removes all but one file', function() { + return ignoreTest(tempDir.path, { ignore: ['**/*', '!bower.json'] }, [ + 'bower.json' + ]); }); - it('refuses to ignore bower.json', function () { - return ignoreTest(tempDir.path, - { ignore: [ '**/*', '!index.js' ] }, - [ 'bower.json', 'index.js' ] - ); + it('refuses to ignore bower.json', function() { + return ignoreTest(tempDir.path, { ignore: ['**/*', '!index.js'] }, [ + 'bower.json', + 'index.js' + ]); }); - it('removes all but one file deep down the tree', function () { - return ignoreTest(tempDir.path, - { ignore: [ '**/*', '!node_modules/underscore/index.js' ] }, - [ - 'bower.json', - 'node_modules/underscore/index.js' - ] + it('removes all but one file deep down the tree', function() { + return ignoreTest( + tempDir.path, + { ignore: ['**/*', '!node_modules/underscore/index.js'] }, + ['bower.json', 'node_modules/underscore/index.js'] ); }); }); diff --git a/test/util/template.js b/test/util/template.js index 3d17fa7d5..ceef4868c 100644 --- a/test/util/template.js +++ b/test/util/template.js @@ -2,51 +2,51 @@ var expect = require('expect.js'); var template = require('../../lib/util/template'); var fs = require('fs'); -describe('template: util template methods for templates in lib/templates', function () { - describe('.render() - Renders a handlebars template', function () { +describe('template: util template methods for templates in lib/templates', function() { + describe('.render() - Renders a handlebars template', function() { var testTemplateName = 'test-template.tpl'; - var testTemplatePath = __dirname + '/../../lib/templates/' + testTemplateName; - beforeEach(function () { + var testTemplatePath = + __dirname + '/../../lib/templates/' + testTemplateName; + beforeEach(function() { fs.writeFileSync(testTemplatePath, '{{foo}}'); console.log(); }); - it('.render() returns a compiled test-template template', function () { - var compiledStr = template.render( - testTemplateName, - { foo: 'foo value' } - ); - expect(compiledStr).to.be.equal( - 'foo value' - ); - }); - it('.render() throws when a non existent template is provided', function () { - expect(function () { - template.render( - 'test-template.not-present.tpl', - { foo: 'foo value' } - ); + it('.render() returns a compiled test-template template', function() { + var compiledStr = template.render(testTemplateName, { + foo: 'foo value' + }); + expect(compiledStr).to.be.equal('foo value'); + }); + it('.render() throws when a non existent template is provided', function() { + expect(function() { + template.render('test-template.not-present.tpl', { + foo: 'foo value' + }); }).to.throwException(); }); - afterEach(function () { + afterEach(function() { fs.unlinkSync(testTemplatePath); }); }); - describe('.exists() - Checks existence of a template', function () { + describe('.exists() - Checks existence of a template', function() { var testTemplateName = 'test-template.tpl'; - var testTemplatePath = __dirname + '/../../lib/templates/' + testTemplateName; - beforeEach(function () { + var testTemplatePath = + __dirname + '/../../lib/templates/' + testTemplateName; + beforeEach(function() { fs.writeFileSync(testTemplatePath, '{{foo}}'); }); - it('.exists() returns true for an existing template', function () { + it('.exists() returns true for an existing template', function() { var templateExists = template.exists(testTemplateName); expect(templateExists).to.be.ok(); }); - it('.exists() returns false for a non existing template', function () { - var templateExists = template.exists('test-template.not-present.tpl'); + it('.exists() returns false for a non existing template', function() { + var templateExists = template.exists( + 'test-template.not-present.tpl' + ); expect(templateExists).to.not.be.ok(); }); - afterEach(function () { + afterEach(function() { fs.unlinkSync(testTemplatePath); }); }); diff --git a/yarn.lock b/yarn.lock index 03aae3237..beaa18844 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,24 @@ # yarn lockfile v1 +"@babel/code-frame@^7.0.0-beta.35": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.42.tgz#a9c83233fa7cd06b39dc77adbb908616ff4f1962" + dependencies: + "@babel/highlight" "7.0.0-beta.42" + +"@babel/highlight@7.0.0-beta.42": + version "7.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.42.tgz#a502a1c0d6f99b2b0e81d468a1b0c0e81e3f3623" + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +abab@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" + abbrev@1, abbrev@^1.0.5: version "1.1.0" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" @@ -10,6 +28,12 @@ abbrev@1.0.x: version "1.0.9" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" +acorn-globals@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538" + dependencies: + acorn "^5.0.0" + acorn-jsx@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" @@ -20,6 +44,10 @@ acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" +acorn@^5.0.0, acorn@^5.3.0: + version "5.5.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" + acorn@^5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.2.tgz#911cb53e036807cf0fa778dc5d370fbd864246d7" @@ -35,6 +63,15 @@ ajv@^4.7.0, ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" +ajv@^5.1.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -47,7 +84,7 @@ amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" -ansi-escapes@^1.1.0: +ansi-escapes@^1.0.0, ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" @@ -63,10 +100,24 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + ansicolors@~0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef" +any-observable@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.2.0.tgz#c67870058003579009083f54ac0abafb5c33d242" + +app-root-path@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.0.1.tgz#cd62dcf8e4fd5a417efc664d2e5b10653c651b46" + archy@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" @@ -83,14 +134,26 @@ arr-diff@^2.0.0: dependencies: arr-flatten "^1.0.1" -arr-flatten@^1.0.1: +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + array-differ@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + array-filter@~0.0.0: version "0.0.1" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" @@ -117,6 +180,14 @@ array-uniq@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + arrify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -137,6 +208,14 @@ assertion-error@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + async@1.x, async@^1.4.0, async@^1.5.0, async@~1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" @@ -155,11 +234,19 @@ asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" +atob@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.0.tgz#ab2b150e51d7b122b9efc8d7340c06b6c41076bc" + aws-sign2@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" -aws4@^1.2.1: +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + +aws4@^1.2.1, aws4@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" @@ -167,6 +254,18 @@ balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + bcrypt-pbkdf@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" @@ -213,6 +312,18 @@ boom@2.x.x: dependencies: hoek "2.x.x" +boom@4.x.x: + version "4.3.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" + dependencies: + hoek "4.x.x" + +boom@5.x.x: + version "5.2.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + dependencies: + hoek "4.x.x" + bower-config@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/bower-config/-/bower-config-1.4.1.tgz#85fd9df367c2b8dbbd0caa4c5f2bad40cd84c2cc" @@ -270,6 +381,41 @@ brace-expansion@^1.0.0, brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.1.tgz#7086c913b4e5a08dbe37ac0ee6a2500c4ba691bb" + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + define-property "^1.0.0" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + kind-of "^6.0.2" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +browser-process-hrtime@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e" + +browser-resolve@^1.11.2: + version "1.11.2" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" + dependencies: + resolve "1.1.7" + buffers@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" @@ -286,6 +432,20 @@ bytes@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -296,6 +456,10 @@ callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + camelcase-keys@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" @@ -372,6 +536,14 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3, chalk@~1.1.1: strip-ansi "^3.0.0" supports-color "^2.0.0" +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + check-error@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" @@ -384,16 +556,40 @@ chownr@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" +ci-info@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.3.tgz#710193264bb05c77b8c90d02f5aaf22216a667b2" + circular-json@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" -cli-cursor@^1.0.1: +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cli-cursor@^1.0.1, cli-cursor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" dependencies: restore-cursor "^1.0.1" +cli-spinners@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" + +cli-truncate@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + cli-width@^1.0.1: version "1.1.1" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-1.1.1.tgz#a4d293ef67ebb7b88d4a4d42c0ccf00c4d1e366d" @@ -422,10 +618,33 @@ coffee-script@~1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.10.0.tgz#12938bcf9be1948fa006f92e0c4c9e81705108c0" +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + dependencies: + color-name "^1.1.1" + +color-name@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + colors@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" +combined-stream@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" + dependencies: + delayed-stream "~1.0.0" + combined-stream@^1.0.5, combined-stream@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" @@ -440,10 +659,18 @@ commander@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" +commander@^2.14.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + commander@^2.9.0: version "2.11.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" +component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -470,14 +697,31 @@ configstore@^2.0.0: write-file-atomic "^1.1.2" xdg-basedir "^2.0.0" +content-type-parser@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7" + content-type@~1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" +cosmiconfig@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + require-from-string "^2.0.1" + coveralls@^2.11.9: version "2.13.1" resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-2.13.1.tgz#d70bb9acc1835ec4f063ff9dac5423c17b11f178" @@ -494,12 +738,36 @@ create-error-class@^3.0.1: dependencies: capture-stack-trace "^1.0.0" +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + cryptiles@2.x.x: version "2.0.5" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" dependencies: boom "2.x.x" +cryptiles@3.x.x: + version "3.1.2" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" + dependencies: + boom "5.x.x" + +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b" + +"cssstyle@>= 0.2.37 < 0.3.0": + version "0.2.37" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-0.2.37.tgz#541097234cb2513c83ceed3acddc27ff27987d54" + dependencies: + cssom "0.3.x" + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -518,6 +786,10 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +date-fns@^1.27.2: + version "1.29.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" + dateformat@~1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" @@ -537,6 +809,12 @@ debug@^2.1.1: dependencies: ms "2.0.0" +debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + debug@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" @@ -547,6 +825,10 @@ decamelize@^1.0.0, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + decompress-zip@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/decompress-zip/-/decompress-zip-0.2.1.tgz#5c2a2d06136f26ebb458453c2efb2ead8b593fed" @@ -559,6 +841,10 @@ decompress-zip@^0.2.1: readable-stream "^1.1.8" touch "0.0.3" +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + deep-eql@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" @@ -587,6 +873,25 @@ deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + del@^2.0.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" @@ -615,6 +920,10 @@ diff@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" +diff@^3.2.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + doctrine@^1.2.2: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" @@ -622,6 +931,12 @@ doctrine@^1.2.2: esutils "^2.0.2" isarray "^1.0.0" +domexception@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + dependencies: + webidl-conversions "^4.0.2" + dot-prop@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" @@ -644,6 +959,10 @@ ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" +elegant-spinner@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" @@ -654,7 +973,7 @@ ends-with@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/ends-with/-/ends-with-0.2.0.tgz#2f9da98d57a50cfda4571ce4339000500f4e6b8a" -error-ex@^1.2.0: +error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" dependencies: @@ -731,6 +1050,17 @@ escodegen@1.8.x: optionalDependencies: source-map "~0.2.0" +escodegen@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.1.tgz#dbae17ef96c8e4bedb1356f4504fa4cc2f7cb7e2" + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + escope@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" @@ -789,6 +1119,10 @@ esprima@2.7.x, esprima@^2.6.0, esprima@^2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" +esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + esprima@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" @@ -827,6 +1161,18 @@ eventemitter2@~0.4.13: version "0.4.14" resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab" +execa@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.9.0.tgz#adb7ce62cf985071f60580deb4a88b9e34712d01" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + exit-hook@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" @@ -835,10 +1181,45 @@ exit@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + expect.js@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/expect.js/-/expect.js-0.3.1.tgz#b0a59a0d2eff5437544ebf0ceaa6015841d09b5b" +expect@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-22.4.3.tgz#d5a29d0a0e1fb2153557caef2674d4547e914674" + dependencies: + ansi-styles "^3.2.0" + jest-diff "^22.4.3" + jest-get-type "^22.4.3" + jest-matcher-utils "^22.4.3" + jest-message-util "^22.4.3" + jest-regex-util "^22.4.3" + ext-list@^2.0.0: version "2.2.2" resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" @@ -854,14 +1235,54 @@ ext-name@^3.0.0: meow "^3.1.0" sort-keys-length "^1.0.0" -extend@~3.0.0: +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + extsprintf@1.3.0, extsprintf@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -872,7 +1293,7 @@ faye-websocket@~0.10.0: dependencies: websocket-driver ">=0.5.1" -figures@^1.3.5: +figures@^1.3.5, figures@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" dependencies: @@ -886,6 +1307,10 @@ file-entry-cache@^1.1.1: flat-cache "^1.2.1" object-assign "^4.0.1" +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + fill-keys@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/fill-keys/-/fill-keys-1.0.2.tgz#9a8fa36f4e8ad634e3bf6b4f3c8882551452eb20" @@ -893,10 +1318,33 @@ fill-keys@^1.0.2: is-object "~1.0.1" merge-descriptors "~1.0.0" +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + filled-array@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/filled-array/-/filled-array-1.1.0.tgz#c3c4f6c663b923459a9aa29912d2d031f1507f84" +find-parent-dir@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -919,6 +1367,16 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -939,6 +1397,20 @@ form-data@~2.1.1: combined-stream "^1.0.5" mime-types "^2.1.12" +form-data@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" + dependencies: + asynckit "^0.4.0" + combined-stream "1.0.6" + mime-types "^2.1.12" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + dependencies: + map-cache "^0.2.2" + fs-write-stream-atomic@1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.8.tgz#e49aaddf288f87d46ff9e882f216a13abc40778b" @@ -989,10 +1461,22 @@ get-func-name@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" +get-own-enumerable-property-symbols@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz#5c4ad87f2834c4b9b4e84549dc1e0650fb38c24b" + get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + getobject@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/getobject/-/getobject-0.1.0.tgz#047a449789fa160d018f5486ed91320b6ec7885c" @@ -1009,6 +1493,19 @@ github@^0.2.3: dependencies: mime "^1.2.11" +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + glob@3.2.11: version "3.2.11" resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" @@ -1035,7 +1532,7 @@ glob@^5.0.15, glob@~5.0.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.3, glob@^7.0.5, glob@~7.1.1: +glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@~7.1.1: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: @@ -1211,6 +1708,10 @@ har-schema@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + har-validator@~2.0.2, har-validator@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" @@ -1227,6 +1728,13 @@ har-validator@~4.2.1: ajv "^4.9.1" har-schema "^1.0.5" +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -1237,6 +1745,37 @@ has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + hawk@~3.1.0, hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" @@ -1246,10 +1785,23 @@ hawk@~3.1.0, hawk@~3.1.3: hoek "2.x.x" sntp "1.x.x" +hawk@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" + dependencies: + boom "4.x.x" + cryptiles "3.x.x" + hoek "4.x.x" + sntp "2.x.x" + hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" +hoek@4.x.x: + version "4.2.1" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" + hooker@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/hooker/-/hooker-0.2.3.tgz#b834f723cc4a242aa65963459df6d984c5d3d959" @@ -1258,6 +1810,12 @@ hosted-git-info@^2.1.4: version "2.5.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + dependencies: + whatwg-encoding "^1.0.1" + http-errors@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.3.1.tgz#197e22cdebd4198585e8694ef6786197b91ed942" @@ -1277,11 +1835,27 @@ http-signature@~1.1.0: jsprim "^1.2.2" sshpk "^1.7.0" +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +husky@^0.14.3: + version "0.14.3" + resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3" + dependencies: + is-ci "^1.0.10" + normalize-path "^1.0.0" + strip-indent "^2.0.0" + iconv-lite@0.4.13: version "0.4.13" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" -iconv-lite@~0.4.13: +iconv-lite@0.4.19, iconv-lite@~0.4.13: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" @@ -1307,6 +1881,10 @@ indent-string@^2.1.0: dependencies: repeating "^2.0.0" +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -1361,6 +1939,18 @@ intersect@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/intersect/-/intersect-1.0.1.tgz#332650e10854d8c0ac58c192bdc27a8bf7e7a30c" +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + dependencies: + kind-of "^6.0.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -1375,36 +1965,134 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" +is-ci@^1.0.10: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" dependencies: - number-is-nan "^1.0.0" + ci-info "^1.0.0" -is-fullwidth-code-point@^1.0.0: +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" dependencies: - number-is-nan "^1.0.0" + kind-of "^6.0.0" -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" -is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: - version "2.16.1" - resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11" +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" dependencies: - generate-function "^2.0.0" - generate-object-property "^1.1.0" - jsonpointer "^4.0.0" - xtend "^4.0.0" + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + dependencies: + is-extglob "^2.1.1" + +is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" -is-obj@^1.0.0: +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + +is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" @@ -1412,6 +2100,18 @@ is-object@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" +is-observable@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2" + dependencies: + symbol-observable "^0.2.2" + +is-odd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" + dependencies: + is-number "^4.0.0" + is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" @@ -1432,6 +2132,24 @@ is-plain-obj@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + dependencies: + isobject "^3.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + is-property@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" @@ -1440,6 +2158,10 @@ is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + is-resolvable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" @@ -1454,7 +2176,7 @@ is-root@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-root/-/is-root-1.0.0.tgz#07b6c233bc394cd9d02ba15c966bd6660d6342d5" -is-stream@^1.0.0: +is-stream@^1.0.0, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -1466,11 +2188,15 @@ is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" -isarray@^1.0.0, isarray@~1.0.0: +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -1478,6 +2204,16 @@ isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -1508,6 +2244,136 @@ jade@0.26.3: commander "0.6.1" mkdirp "0.3.0" +jest-config@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-22.4.3.tgz#0e9d57db267839ea31309119b41dc2fa31b76403" + dependencies: + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^22.4.3" + jest-environment-node "^22.4.3" + jest-get-type "^22.4.3" + jest-jasmine2 "^22.4.3" + jest-regex-util "^22.4.3" + jest-resolve "^22.4.3" + jest-util "^22.4.3" + jest-validate "^22.4.3" + pretty-format "^22.4.3" + +jest-diff@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-22.4.3.tgz#e18cc3feff0aeef159d02310f2686d4065378030" + dependencies: + chalk "^2.0.1" + diff "^3.2.0" + jest-get-type "^22.4.3" + pretty-format "^22.4.3" + +jest-environment-jsdom@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz#d67daa4155e33516aecdd35afd82d4abf0fa8a1e" + dependencies: + jest-mock "^22.4.3" + jest-util "^22.4.3" + jsdom "^11.5.1" + +jest-environment-node@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-22.4.3.tgz#54c4eaa374c83dd52a9da8759be14ebe1d0b9129" + dependencies: + jest-mock "^22.4.3" + jest-util "^22.4.3" + +jest-get-type@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" + +jest-jasmine2@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-22.4.3.tgz#4daf64cd14c793da9db34a7c7b8dcfe52a745965" + dependencies: + chalk "^2.0.1" + co "^4.6.0" + expect "^22.4.3" + graceful-fs "^4.1.11" + is-generator-fn "^1.0.0" + jest-diff "^22.4.3" + jest-matcher-utils "^22.4.3" + jest-message-util "^22.4.3" + jest-snapshot "^22.4.3" + jest-util "^22.4.3" + source-map-support "^0.5.0" + +jest-matcher-utils@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz#4632fe428ebc73ebc194d3c7b65d37b161f710ff" + dependencies: + chalk "^2.0.1" + jest-get-type "^22.4.3" + pretty-format "^22.4.3" + +jest-message-util@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-22.4.3.tgz#cf3d38aafe4befddbfc455e57d65d5239e399eb7" + dependencies: + "@babel/code-frame" "^7.0.0-beta.35" + chalk "^2.0.1" + micromatch "^2.3.11" + slash "^1.0.0" + stack-utils "^1.0.1" + +jest-mock@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-22.4.3.tgz#f63ba2f07a1511772cdc7979733397df770aabc7" + +jest-regex-util@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-22.4.3.tgz#a826eb191cdf22502198c5401a1fc04de9cef5af" + +jest-resolve@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-22.4.3.tgz#0ce9d438c8438229aa9b916968ec6b05c1abb4ea" + dependencies: + browser-resolve "^1.11.2" + chalk "^2.0.1" + +jest-snapshot@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-22.4.3.tgz#b5c9b42846ffb9faccb76b841315ba67887362d2" + dependencies: + chalk "^2.0.1" + jest-diff "^22.4.3" + jest-matcher-utils "^22.4.3" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^22.4.3" + +jest-util@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-22.4.3.tgz#c70fec8eec487c37b10b0809dc064a7ecf6aafac" + dependencies: + callsites "^2.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.11" + is-ci "^1.0.10" + jest-message-util "^22.4.3" + mkdirp "^0.5.1" + source-map "^0.6.0" + +jest-validate@^22.4.0, jest-validate@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-22.4.3.tgz#0780954a5a7daaeec8d3c10834b9280865976b30" + dependencies: + chalk "^2.0.1" + jest-config "^22.4.3" + jest-get-type "^22.4.3" + leven "^2.1.0" + pretty-format "^22.4.3" + +js-tokens@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + js-yaml@3.6.1: version "3.6.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30" @@ -1522,6 +2388,13 @@ js-yaml@3.x, js-yaml@^3.5.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^3.9.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + js-yaml@~3.5.2: version "3.5.5" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.5.5.tgz#0377c38017cabc7322b0d1fbcd25a491641f2fbe" @@ -1533,6 +2406,45 @@ jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" +jsdom@^11.5.1: + version "11.6.2" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.6.2.tgz#25d1ef332d48adf77fc5221fe2619967923f16bb" + dependencies: + abab "^1.0.4" + acorn "^5.3.0" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + browser-process-hrtime "^0.1.2" + content-type-parser "^1.0.2" + cssom ">= 0.3.2 < 0.4.0" + cssstyle ">= 0.2.37 < 0.3.0" + domexception "^1.0.0" + escodegen "^1.9.0" + html-encoding-sniffer "^1.0.2" + left-pad "^1.2.0" + nwmatcher "^1.4.3" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.83.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.3" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-url "^6.4.0" + ws "^4.0.0" + xml-name-validator "^3.0.0" + +json-parse-better-errors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz#50183cd1b2d25275de069e9e71b467ac9eab973a" + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -1568,12 +2480,26 @@ junk@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/junk/-/junk-1.0.3.tgz#87be63488649cbdca6f53ab39bec9ccd2347f592" -kind-of@^3.0.2: +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" dependencies: is-buffer "^1.1.5" +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + latest-version@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-2.0.0.tgz#56f8d6139620847b8017f8f1f4d78e211324168b" @@ -1588,6 +2514,14 @@ lcov-parse@0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" +left-pad@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.2.0.tgz#d30a73c6b8201d8f7d8e7956ba9616087a68e0ee" + +leven@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -1595,6 +2529,80 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lint-staged@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-7.0.0.tgz#57926c63201e7bd38ca0576d74391efa699b4a9d" + dependencies: + app-root-path "^2.0.1" + chalk "^2.3.1" + commander "^2.14.1" + cosmiconfig "^4.0.0" + debug "^3.1.0" + dedent "^0.7.0" + execa "^0.9.0" + find-parent-dir "^0.3.0" + is-glob "^4.0.0" + jest-validate "^22.4.0" + listr "^0.13.0" + lodash "^4.17.5" + log-symbols "^2.2.0" + micromatch "^3.1.8" + npm-which "^3.0.1" + p-map "^1.1.1" + path-is-inside "^1.0.2" + pify "^3.0.0" + please-upgrade-node "^3.0.1" + staged-git-files "1.1.0" + stringify-object "^3.2.2" + +listr-silent-renderer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + +listr-update-renderer@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7" + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^1.0.2" + strip-ansi "^3.0.1" + +listr-verbose-renderer@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35" + dependencies: + chalk "^1.1.3" + cli-cursor "^1.0.2" + date-fns "^1.27.2" + figures "^1.7.0" + +listr@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.13.0.tgz#20bb0ba30bae660ee84cc0503df4be3d5623887d" + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + figures "^1.7.0" + indent-string "^2.1.0" + is-observable "^0.2.0" + is-promise "^2.1.0" + is-stream "^1.1.0" + listr-silent-renderer "^1.1.1" + listr-update-renderer "^0.4.0" + listr-verbose-renderer "^0.4.0" + log-symbols "^1.0.2" + log-update "^1.0.2" + ora "^0.2.3" + p-map "^1.1.1" + rxjs "^5.4.2" + stream-to-observable "^0.2.0" + strip-ansi "^3.0.1" + livereload-js@^2.2.0: version "2.2.2" resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.2.2.tgz#6c87257e648ab475bc24ea257457edcc1f8d0bc2" @@ -1622,6 +2630,10 @@ lockfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.3.tgz#2638fc39a0331e9cac1a04b71799931c9c50df79" +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + lodash@^3.10.1, lodash@^3.3.1, lodash@~3.10.1: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" @@ -1630,7 +2642,7 @@ lodash@^4.0.0, lodash@^4.14.0, lodash@^4.3.0, lodash@~4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" -lodash@^4.17.5: +lodash@^4.13.1, lodash@^4.17.5: version "4.17.5" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" @@ -1642,6 +2654,25 @@ log-driver@1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056" +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + dependencies: + chalk "^1.0.0" + +log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + dependencies: + chalk "^2.0.1" + +log-update@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" + dependencies: + ansi-escapes "^1.0.0" + cli-cursor "^1.0.2" + longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" @@ -1661,10 +2692,27 @@ lru-cache@2, lru-cache@^2.3.0, lru-cache@^2.5.0: version "2.7.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" +lru-cache@^4.0.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.2.tgz#45234b2e6e2f2b33da125624c4664929a0224c3f" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + dependencies: + object-visit "^1.0.0" + md5-hex@^1.0.2: version "1.3.0" resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" @@ -1698,16 +2746,62 @@ merge-descriptors@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" +micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +micromatch@^3.1.8: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + mime-db@^1.28.0, mime-db@~1.30.0: version "1.30.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" +mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" + mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.7: version "2.1.17" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" dependencies: mime-db "~1.30.0" +mime-types@~2.1.17: + version "2.1.18" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" + dependencies: + mime-db "~1.33.0" + mime@^1.2.11: version "1.4.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.0.tgz#69e9e0db51d44f2a3b56e48b7817d7d137f1a343" @@ -1743,6 +2837,13 @@ minimist@~0.0.1, minimist@~0.0.7: version "0.0.10" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + mkdirp@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" @@ -1825,6 +2926,27 @@ mute-stream@~0.0.4: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" +nanomatch@^1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-odd "^2.0.0" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + nested-error-stacks@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.0.0.tgz#98b2ffaefb4610fa3936f1e71435d30700de2840" @@ -1874,11 +2996,45 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" +normalize-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" + +normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +npm-path@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" + dependencies: + which "^1.2.10" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +npm-which@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" + dependencies: + commander "^2.9.0" + npm-path "^2.0.2" + which "^1.2.10" + number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" -oauth-sign@~0.8.0, oauth-sign@~0.8.1: +nwmatcher@^1.4.3: + version "1.4.4" + resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.4.tgz#2285631f34a95f0d0395cd900c96ed39b58f346e" + +oauth-sign@~0.8.0, oauth-sign@~0.8.1, oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" @@ -1886,6 +3042,33 @@ object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + dependencies: + isobject "^3.0.0" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + dependencies: + isobject "^3.0.1" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -1927,6 +3110,15 @@ optionator@^0.8.1: type-check "~0.3.2" wordwrap "~1.0.0" +ora@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" + dependencies: + chalk "^1.1.1" + cli-cursor "^1.0.2" + cli-spinners "^0.1.2" + object-assign "^4.0.1" + os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" @@ -1946,6 +3138,14 @@ osenv@^0.1.0, osenv@^0.1.3: os-homedir "^1.0.0" os-tmpdir "^1.0.0" +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-map@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + p-throttler@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/p-throttler/-/p-throttler-0.1.1.tgz#15246409d225d3eefca85c50de710a83a78cca6a" @@ -1961,16 +3161,40 @@ package-json@^2.0.0: registry-url "^3.0.3" semver "^5.1.0" +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + parse-json@^2.1.0, parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" dependencies: error-ex "^1.2.0" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + parseurl@~1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" @@ -1981,10 +3205,14 @@ path-is-absolute@^1.0.0, path-is-absolute@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -path-is-inside@^1.0.1: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + path-parse@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" @@ -2005,10 +3233,18 @@ performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" @@ -2025,10 +3261,22 @@ pkg-up@^1.0.0: dependencies: find-up "^1.0.0" +please-upgrade-node@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.0.1.tgz#0a681f2c18915e5433a5ca2cd94e0b8206a782db" + pluralize@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -2037,6 +3285,21 @@ prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +prettier@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.1.tgz#61e43fc4cd44e68f2b0dfc2c38cd4bb0fccdcc75" + +pretty-format@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-22.4.3.tgz#f873d780839a9c02e9664c8a082e9ee79eaac16f" + dependencies: + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" + process-nextick-args@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" @@ -2063,6 +3326,10 @@ proxyquire@^1.7.9: module-not-found-error "^1.0.0" resolve "~1.1.7" +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + pump@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.2.tgz#3b3ee6512f94f0e575538c17995f9f16990a5d51" @@ -2074,6 +3341,10 @@ punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" +punycode@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + q@^1.1.2: version "1.5.0" resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" @@ -2086,7 +3357,7 @@ qs@5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.0.tgz#a9f31142af468cb72b25b30136ba2456834916be" -qs@^6.5.1: +qs@^6.5.1, qs@~6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" @@ -2106,6 +3377,13 @@ qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" +randomatic@^1.1.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + raw-body@~2.1.5: version "2.1.7" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.1.7.tgz#adfeace2e4fb3098058014d08c072dcc59758774" @@ -2213,6 +3491,19 @@ redeyed@~0.4.0: dependencies: esprima "~1.0.4" +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + registry-auth-token@^3.0.1: version "3.3.1" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006" @@ -2226,7 +3517,15 @@ registry-url@^3.0.3: dependencies: rc "^1.0.1" -repeat-string@^1.5.2: +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" @@ -2242,6 +3541,20 @@ request-progress@0.3.1: dependencies: throttleit "~0.0.2" +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + dependencies: + lodash "^4.13.1" + +request-promise-native@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" + dependencies: + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + request-replay@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/request-replay/-/request-replay-0.2.0.tgz#9b693a5d118b39f5c596ead5ed91a26444057f60" @@ -2325,6 +3638,37 @@ request@^2.51.0: tunnel-agent "^0.6.0" uuid "^3.0.0" +request@^2.83.0: + version "2.85.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + stringstream "~0.0.5" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + +require-from-string@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.1.tgz#c545233e9d7da6616e9d59adfb39fc9f588676ff" + require-uncached@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" @@ -2354,7 +3698,11 @@ resolve-pkg@^0.1.0: dependencies: resolve-from "^2.0.0" -resolve@1.1.x, resolve@~1.1.0, resolve@~1.1.7: +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + +resolve@1.1.7, resolve@1.1.x, resolve@~1.1.0, resolve@~1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" @@ -2375,6 +3723,10 @@ restore-cursor@^1.0.1: exit-hook "^1.0.0" onetime "^1.0.0" +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + retry@0.6.1, retry@~0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/retry/-/retry-0.6.1.tgz#fdc90eed943fde11b893554b8cc63d0e899ba918" @@ -2405,10 +3757,26 @@ rx-lite@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" -safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +rxjs@^5.4.2: + version "5.5.8" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.8.tgz#b2b0809a57614ad6254c03d7446dea0d83ca3791" + dependencies: + symbol-observable "1.0.1" + +safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + dependencies: + ret "~0.1.10" + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" @@ -2431,6 +3799,34 @@ semver@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + shell-quote@^1.4.2: version "1.6.1" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" @@ -2452,6 +3848,10 @@ signal-exit@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" @@ -2460,12 +3860,45 @@ slide@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + sntp@1.x.x: version "1.0.9" resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" dependencies: hoek "2.x.x" +sntp@2.x.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" + dependencies: + hoek "4.x.x" + sort-keys-length@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" @@ -2478,22 +3911,46 @@ sort-keys@^1.0.0: dependencies: is-plain-obj "^1.0.0" +source-map-resolve@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.1.tgz#7ad0f593f2281598e854df80f19aae4b92d7a11a" + dependencies: + atob "^2.0.0" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.5.0: + version "0.5.4" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.4.tgz#54456efa89caa9270af7cd624cc2f123e51fbae8" + dependencies: + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + source-map@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" dependencies: amdefine ">=0.0.4" +source-map@^0.5.6, source-map@~0.5.1: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +source-map@^0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + source-map@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" dependencies: amdefine ">=0.0.4" -source-map@~0.5.1: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - spawn-sync@1.0.15: version "1.0.15" resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476" @@ -2515,6 +3972,12 @@ spdx-license-ids@^1.0.2: version "1.2.2" resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + dependencies: + extend-shallow "^3.0.0" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -2533,10 +3996,35 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" +stack-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" + +staged-git-files@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.0.tgz#1a9bb131c1885601023c7aaddd3d54c22142c526" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + statuses@1: version "1.3.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + +stream-to-observable@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.2.0.tgz#59d6ea393d87c2c0ddac10aa0d561bc6ba6f0e10" + dependencies: + any-observable "^0.2.0" + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -2566,11 +4054,19 @@ stringify-object@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-1.0.1.tgz#86d35e7dbfbce9aa45637d7ecdd7847e159db8a2" -stringstream@~0.0.4: +stringify-object@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.2.tgz#9853052e5a88fb605a44cd27445aa257ad7ffbcd" + dependencies: + get-own-enumerable-property-symbols "^2.0.1" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +stringstream@~0.0.4, stringstream@~0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" -strip-ansi@^3.0.0: +strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" dependencies: @@ -2588,12 +4084,20 @@ strip-bom@^2.0.0: dependencies: is-utf8 "^0.2.0" +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + strip-indent@^1.0.0, strip-indent@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" dependencies: get-stdin "^4.0.1" +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + strip-json-comments@0.1.x: version "0.1.3" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-0.1.3.tgz#164c64e370a8a3cc00c9e01b539e569823f0ee54" @@ -2620,6 +4124,24 @@ supports-color@^3.1.0: dependencies: has-flag "^1.0.0" +supports-color@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" + dependencies: + has-flag "^3.0.0" + +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + +symbol-observable@^0.2.2: + version "0.2.4" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" + +symbol-tree@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" + table@^3.7.8: version "3.8.3" resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" @@ -2686,12 +4208,40 @@ to-iso-string@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/to-iso-string/-/to-iso-string-0.0.2.tgz#4dc19e664dfccbe25bd8db508b00c6da158255d1" +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + touch@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/touch/-/touch-0.0.3.tgz#51aef3d449571d4f287a5d87c9c8b49181a0db1d" dependencies: nopt "~1.0.10" +tough-cookie@>=2.3.3, tough-cookie@^2.3.3, tough-cookie@~2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" + dependencies: + punycode "^1.4.1" + tough-cookie@~2.2.0: version "2.2.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.2.2.tgz#c83a1830f4e5ef0b93ef2a3488e724f8de016ac7" @@ -2702,6 +4252,12 @@ tough-cookie@~2.3.0: dependencies: punycode "^1.4.1" +tr46@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + dependencies: + punycode "^2.1.0" + "traverse@>=0.3.0 <0.4": version "0.3.9" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" @@ -2774,10 +4330,26 @@ underscore.string@~3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.2.3.tgz#806992633665d5e5fcb4db1fb3a862eb68e9e6da" +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + unpipe@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + untildify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" @@ -2799,12 +4371,22 @@ update-notifier@^0.6.0: latest-version "^2.0.0" semver-diff "^2.0.0" +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + url-parse-lax@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" dependencies: prepend-http "^1.0.1" +use@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.0.tgz#14716bf03fdfefd03040aef58d8b4b85f3a7c544" + dependencies: + kind-of "^6.0.2" + user-home@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" @@ -2827,6 +4409,10 @@ uuid@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" +uuid@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" + validate-npm-package-license@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" @@ -2842,6 +4428,16 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + dependencies: + browser-process-hrtime "^0.1.2" + +webidl-conversions@^4.0.1, webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + websocket-driver@>=0.5.1: version "0.7.0" resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" @@ -2853,7 +4449,21 @@ websocket-extensions@>=0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.2.tgz#0e18781de629a18308ce1481650f67ffa2693a5d" -which@^1.0.8, which@^1.1.1: +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3" + dependencies: + iconv-lite "0.4.19" + +whatwg-url@^6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.4.0.tgz#08fdf2b9e872783a7a1f6216260a1d66cc722e08" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.0" + webidl-conversions "^4.0.1" + +which@^1.0.8, which@^1.1.1, which@^1.2.10, which@^1.2.9: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" dependencies: @@ -2909,16 +4519,31 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" +ws@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + xdg-basedir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2" dependencies: os-homedir "^1.0.0" +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + xtend@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" From c22c09546e785183c2065de2a19cee12f57747b6 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 28 Mar 2018 19:33:16 +0200 Subject: [PATCH 1010/1021] Disable testing per commit and update changelog --- CHANGELOG.md | 4 ++++ package.json | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da85d254a..b4afe1749 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Newer releases + +Please see: https://github.com/bower/bower/releases + ## 1.8.0 - 2016-11-07 - Download tar archives from GitHub when possible (#2263) diff --git a/package.json b/package.json index 984c33bdd..36add04f7 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "coveralls": "coveralls", "prepublish": "in-publish && echo 'You need to use \"grunt publish\" to publish bower' && false || not-in-publish", "format": "prettier --write --single-quote --tab-width 4 '**/*.js'", - "precommit": "lint-staged && npm test" + "precommit": "lint-staged" }, "lint-staged": { "*.js": [ From 275601601a6196e596598bc3f6fe8b482db733bb Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 28 Mar 2018 19:52:42 +0200 Subject: [PATCH 1011/1021] Bump to 1.8.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 36add04f7..14012bde7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.8.0", + "version": "1.8.3", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 2aa1f27367f9f21c00b0ed1c8ddf8e1e12381abf Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 28 Mar 2018 20:16:27 +0200 Subject: [PATCH 1012/1021] Update publish script --- Gruntfile.js | 63 ++++++---------------------------------------------- 1 file changed, 7 insertions(+), 56 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 850c79594..f414c42fe 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -75,53 +75,8 @@ module.exports = function(grunt) { 'publish', 'Perform final checks and publish Bower', function() { - var npmVersion = JSON.parse( - childProcess.execSync('npm version --json').toString() - ).npm.split('.'); - var npmMajor = parseInt(npmVersion[0], 10); - var npmMinor = parseInt(npmVersion[1], 10); - var jsonPackage = require('./package'); - if (npmMajor !== 3 || npmMinor < 5) { - grunt.log.writeln( - 'You need to use at least npm@3.5 to publish bower.' - ); - grunt.log.writeln( - 'It is because npm 2.x produces too long paths that Windows does not handle.' - ); - grunt.log.writeln('Please upgrade it: npm install -g npm'); - process.exit(1); - } - - var version = jsonPackage.version; - var changelog = fs.readFileSync('./CHANGELOG.md'); - - if (changelog.indexOf('## ' + version) === -1) { - grunt.log.writeln( - 'Please add changelog.md entry for this bower version (' + - version + - ')' - ); - - var lastRelease = childProcess - .execSync('git tag | tail -1') - .toString() - .trim(); - - grunt.log.writeln( - 'Commits since last release (' + lastRelease + '): \n' - ); - - grunt.log.writeln( - childProcess - .execSync('git log --oneline ' + lastRelease + '..') - .toString() - ); - - process.exit(1); - } - if ( childProcess .execSync('git rev-parse --abbrev-ref HEAD') @@ -137,12 +92,12 @@ module.exports = function(grunt) { if (process.env.SKIP_TESTS !== '1') { grunt.log.writeln('Reinstalling dependencies...'); - childProcess.execSync('rm -rf node_modules && npm install', { + childProcess.execSync('rm -rf node_modules && yarn', { stdio: [0, 1, 2] }); grunt.log.writeln('Running test suite...'); - childProcess.execSync('grunt test', { stdio: [0, 1, 2] }); + childProcess.execSync('yarn test', { stdio: [0, 1, 2] }); } var dir = tmp.dirSync().name; @@ -155,7 +110,7 @@ module.exports = function(grunt) { }); grunt.log.writeln('Installing production dependencies...'); - childProcess.execSync('npm install --production --silent', { + childProcess.execSync('yarn --production', { cwd: dir, stdio: [0, 1, 2] }); @@ -220,13 +175,6 @@ module.exports = function(grunt) { message: 'Did you review all the changes with "git diff"?', default: false }, - { - type: 'confirm', - name: 'changelog', - message: - 'Are you sure the CHANGELOG.md contains all changes?', - default: false - }, { type: 'confirm', name: 'tests', @@ -264,11 +212,14 @@ module.exports = function(grunt) { } grunt.log.writeln( - '\nPlease remember to tag this relese, and add a release on Github!' + '\nPlease remember to tag this release, and add a release with changelog on Github!' ); grunt.log.writeln( '\nAlso, please remember to test published Bower one more time!' ); + grunt.log.writeln( + '\nYou can promote this bower release with "npm dist-tag add bower@' + jsonPackage.version + ' latest"' + ); grunt.log.writeln('\nPublishing Bower...'); childProcess.execSync('npm publish --tag beta', { From 1c15deadc035714a8911a81807ec1e25d6e27683 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 28 Mar 2018 20:43:29 +0200 Subject: [PATCH 1013/1021] Bump to 1.8.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 14012bde7..448d4524a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.8.3", + "version": "1.8.4", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 51feb8f925d57d069de6a54bc56e4164ec7245ec Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 19 Apr 2018 11:07:03 +0200 Subject: [PATCH 1014/1021] Fix release script --- Gruntfile.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index f414c42fe..1a33b6895 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -75,8 +75,25 @@ module.exports = function(grunt) { 'publish', 'Perform final checks and publish Bower', function() { + var npmVersion = JSON.parse( + childProcess.execSync('npm version --json').toString() + ).npm.split('.'); + var npmMajor = parseInt(npmVersion[0], 10); + var npmMinor = parseInt(npmVersion[1], 10); + var jsonPackage = require('./package'); + if (npmMajor !== 3 || npmMinor < 5) { + grunt.log.writeln( + 'You need to use at npm@3.5 to publish bower.' + ); + grunt.log.writeln( + 'It is because npm 2.x produces too long paths that Windows does not handle and newer npm drops lib/node_modules' + ); + grunt.log.writeln('Please upgrade it: npm install -g npm@3'); + process.exit(1); + } + if ( childProcess .execSync('git rev-parse --abbrev-ref HEAD') @@ -200,7 +217,6 @@ module.exports = function(grunt) { inquirer.prompt(questions, function(answers) { if ( !answers.review || - !answers.changelog || !answers.tests || !answers.publish ) { @@ -218,7 +234,7 @@ module.exports = function(grunt) { '\nAlso, please remember to test published Bower one more time!' ); grunt.log.writeln( - '\nYou can promote this bower release with "npm dist-tag add bower@' + jsonPackage.version + ' latest"' + '\nYou can promote this bower release with "npm dist-tag add bower@' + jsonPackage.version + ' latest' ); grunt.log.writeln('\nPublishing Bower...'); From e8b94ecbd07376996eb0bea6cb30c20deb7e89b6 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sat, 23 Jun 2018 18:06:56 +0200 Subject: [PATCH 1015/1021] Mention parcel --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f5a5388dd..548af4244 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Backers on Open Collective](https://opencollective.com/bower/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/bower/sponsors/badge.svg)](#sponsors) -> ..psst! While Bower is maintained, we recommend [yarn](https://yarnpkg.com/) and [webpack](https://webpack.js.org/) for new front-end projects! +> ..psst! While Bower is maintained, we recommend [yarn](https://yarnpkg.com/) and [webpack](https://webpack.js.org/) or [parcel](https://parceljs.org/) for new front-end projects! [![Unix CI](https://img.shields.io/travis/bower/bower/master.svg?maxAge=2592000)](https://travis-ci.org/bower/bower) [![Windows CI](https://img.shields.io/appveyor/ci/bower/bower/master.svg)](https://ci.appveyor.com/project/bower/bower) From 6390815c5fb8766e527129cc5b63d1393d59ecd1 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 17 Jan 2019 13:03:49 +0100 Subject: [PATCH 1016/1021] Update decompress-zip --- package.json | 2 +- yarn.lock | 751 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 749 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 448d4524a..52456dc23 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "chalk": "^1.0.0", "chmodr": "^1.0.2", "configstore": "^2.0.0", - "decompress-zip": "^0.2.1", + "decompress-zip": "^0.3.2", "destroy": "^1.0.3", "findup-sync": "^0.3.0", "fs-write-stream-atomic": "1.0.8", diff --git a/yarn.lock b/yarn.lock index beaa18844..befc4389e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,12 +5,14 @@ "@babel/code-frame@^7.0.0-beta.35": version "7.0.0-beta.42" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.42.tgz#a9c83233fa7cd06b39dc77adbb908616ff4f1962" + integrity sha512-L8i94FLSyaLQpRfDo/qqSm8Ndb44zMtXParXo0MebJICG1zoCCL4+GkzUOlB4BNTRSXXQdb3feam/qw7bKPipQ== dependencies: "@babel/highlight" "7.0.0-beta.42" "@babel/highlight@7.0.0-beta.42": version "7.0.0-beta.42" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.42.tgz#a502a1c0d6f99b2b0e81d468a1b0c0e81e3f3623" + integrity sha512-X3Ur/A/lIbbP8W0pmwgqtDXIxhQmxPaiwY9SKP7kF9wvZfjZRwMvbJE92ozUhF3UDK3DCKaV7oGqmI1rP/zqWA== dependencies: chalk "^2.0.0" esutils "^2.0.2" @@ -19,46 +21,56 @@ abab@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" + integrity sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4= abbrev@1, abbrev@^1.0.5: version "1.1.0" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" + integrity sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8= abbrev@1.0.x: version "1.0.9" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= acorn-globals@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538" + integrity sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ== dependencies: acorn "^5.0.0" acorn-jsx@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s= dependencies: acorn "^3.0.4" acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= acorn@^5.0.0, acorn@^5.3.0: version "5.5.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" + integrity sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ== acorn@^5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.2.tgz#911cb53e036807cf0fa778dc5d370fbd864246d7" + integrity sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA== ajv-keywords@^1.0.0: version "1.5.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + integrity sha1-MU3QpLM2j609/NxU7eYXG4htrzw= ajv@^4.7.0, ajv@^4.9.1: version "4.11.8" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + integrity sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY= dependencies: co "^4.6.0" json-stable-stringify "^1.0.1" @@ -66,6 +78,7 @@ ajv@^4.7.0, ajv@^4.9.1: ajv@^5.1.0: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= dependencies: co "^4.6.0" fast-deep-equal "^1.0.0" @@ -75,6 +88,7 @@ ajv@^5.1.0: align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + integrity sha1-DNkKVhCT810KmSVsIrcGlDP60Rc= dependencies: kind-of "^3.0.2" longest "^1.0.1" @@ -83,180 +97,222 @@ align-text@^0.1.1, align-text@^0.1.3: amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= ansi-escapes@^1.0.0, ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" ansicolors@~0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.2.1.tgz#be089599097b74a5c9c4a84a0cdbcdb62bd87aef" + integrity sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8= any-observable@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.2.0.tgz#c67870058003579009083f54ac0abafb5c33d242" + integrity sha1-xnhwBYADV5AJCD9UrAq6+1wz0kI= app-root-path@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.0.1.tgz#cd62dcf8e4fd5a417efc664d2e5b10653c651b46" + integrity sha1-zWLc+OT9WkF+/GZNLlsQZTxlG0Y= archy@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= argparse@^1.0.2, argparse@^1.0.7: version "1.0.9" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + integrity sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY= dependencies: sprintf-js "~1.0.2" arr-diff@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= dependencies: arr-flatten "^1.0.1" arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= arr-flatten@^1.0.1, arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== arr-union@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= array-differ@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= array-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= array-filter@~0.0.0: version "0.0.1" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" + integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= array-map@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" + integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= array-reduce@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" + integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= dependencies: array-uniq "^1.0.1" array-uniq@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= array-unique@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= arrify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= asn1@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + integrity sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y= assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= assert-plus@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + integrity sha1-104bh+ev/A24qttwIfP+SBAasjQ= assertion-error@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" + integrity sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw= assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== async@1.x, async@^1.4.0, async@^1.5.0, async@~1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= async@^0.2.8: version "0.2.10" resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E= async@^2.0.1: version "2.5.0" resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" + integrity sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw== dependencies: lodash "^4.14.0" asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= atob@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.0.tgz#ab2b150e51d7b122b9efc8d7340c06b6c41076bc" + integrity sha512-SuiKH8vbsOyCALjA/+EINmt/Kdl+TQPrtFgW7XZZcwtryFu9e5kQoX3bjCW6mIvGH1fbeAZZuvwGR5IlBRznGw== aws-sign2@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + integrity sha1-FDQt0428yU0OW4fXY81jYSwOeU8= aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= aws4@^1.2.1, aws4@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + integrity sha1-g+9cqGCysy5KDe7e6MdxudtXRx4= balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== dependencies: cache-base "^1.0.1" class-utils "^0.3.5" @@ -269,12 +325,14 @@ base@^0.11.1: bcrypt-pbkdf@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + integrity sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40= dependencies: tweetnacl "^0.14.3" binary@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" + integrity sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk= dependencies: buffers "~0.1.1" chainsaw "~0.1.0" @@ -282,18 +340,21 @@ binary@^0.3.0: bl@^1.0.0: version "1.2.1" resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.1.tgz#cac328f7bee45730d404b692203fcb590e172d5e" + integrity sha1-ysMo977kVzDUBLaSID/LWQ4XLV4= dependencies: readable-stream "^2.0.5" bl@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/bl/-/bl-1.0.3.tgz#fc5421a28fd4226036c3b3891a66a25bc64d226e" + integrity sha1-/FQhoo/UImA2w7OJGmaiW8ZNIm4= dependencies: readable-stream "~2.0.5" body-parser@~1.14.0: version "1.14.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.14.2.tgz#1015cb1fe2c443858259581db53332f8d0cf50f9" + integrity sha1-EBXLH+LEQ4WCWVgdtTMy+NDPUPk= dependencies: bytes "2.2.0" content-type "~1.0.1" @@ -309,24 +370,28 @@ body-parser@~1.14.0: boom@2.x.x: version "2.10.1" resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + integrity sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8= dependencies: hoek "2.x.x" boom@4.x.x: version "4.3.1" resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" + integrity sha1-T4owBctKfjiJ90kDD9JbluAdLjE= dependencies: hoek "4.x.x" boom@5.x.x: version "5.2.0" resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + integrity sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw== dependencies: hoek "4.x.x" bower-config@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/bower-config/-/bower-config-1.4.1.tgz#85fd9df367c2b8dbbd0caa4c5f2bad40cd84c2cc" + integrity sha1-hf2d82fCuNu9DKpMXyutQM2Ewsw= dependencies: graceful-fs "^4.1.3" mout "^1.0.0" @@ -337,10 +402,12 @@ bower-config@^1.4.1: bower-endpoint-parser@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/bower-endpoint-parser/-/bower-endpoint-parser-0.2.2.tgz#00b565adbfab6f2d35addde977e97962acbcb3f6" + integrity sha1-ALVlrb+rby01rd3pd+l5Yqy8s/Y= bower-json@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/bower-json/-/bower-json-0.8.1.tgz#96c14723241ae6466a9c52e16caa32623a883843" + integrity sha1-lsFHIyQa5kZqnFLhbKoyYjqIOEM= dependencies: deep-extend "^0.4.0" ext-name "^3.0.0" @@ -350,10 +417,12 @@ bower-json@^0.8.1: bower-logger@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/bower-logger/-/bower-logger-0.2.2.tgz#39be07e979b2fc8e03a94634205ed9422373d381" + integrity sha1-Ob4H6Xmy/I4DqUY0IF7ZQiNz04E= bower-registry-client@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/bower-registry-client/-/bower-registry-client-1.0.0.tgz#697c3499067549a106b49f26d03e6dd1017a9241" + integrity sha1-aXw0mQZ1SaEGtJ8m0D5t0QF6kkE= dependencies: async "^0.2.8" graceful-fs "^4.0.0" @@ -366,6 +435,7 @@ bower-registry-client@^1.0.0: boxen@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/boxen/-/boxen-0.3.1.tgz#a7d898243ae622f7abb6bb604d740a76c6a5461b" + integrity sha1-p9iYJDrmIvertrtgTXQKdsalRhs= dependencies: chalk "^1.1.1" filled-array "^1.0.0" @@ -377,6 +447,7 @@ boxen@^0.3.1: brace-expansion@^1.0.0, brace-expansion@^1.1.7: version "1.1.8" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + integrity sha1-wHshHHyVLsH479Uad+8NHTmQopI= dependencies: balanced-match "^1.0.0" concat-map "0.0.1" @@ -384,6 +455,7 @@ brace-expansion@^1.0.0, brace-expansion@^1.1.7: braces@^1.8.2: version "1.8.5" resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= dependencies: expand-range "^1.8.1" preserve "^0.2.0" @@ -392,6 +464,7 @@ braces@^1.8.2: braces@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.1.tgz#7086c913b4e5a08dbe37ac0ee6a2500c4ba691bb" + integrity sha512-SO5lYHA3vO6gz66erVvedSCkp7AKWdv6VcQ2N4ysXfPxdAlxAMMAdwegGGcv1Bqwm7naF1hNdk5d6AAIEHV2nQ== dependencies: arr-flatten "^1.1.0" array-unique "^0.3.2" @@ -409,32 +482,39 @@ braces@^2.3.1: browser-process-hrtime@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e" + integrity sha1-Ql1opY00R/AqBKqJQYf86K+Le44= browser-resolve@^1.11.2: version "1.11.2" resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" + integrity sha1-j/CbCixCFxihBRwmCzLkj0QpOM4= dependencies: resolve "1.1.7" buffers@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" + integrity sha1-skV5w77U1tOWru5tmorn9Ugqt7s= builtin-modules@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= bytes@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.2.0.tgz#fd35464a403f6f9117c2de3609ecff9cae000588" + integrity sha1-/TVGSkA/b5EXwt42Cez/nK4ABYg= bytes@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" + integrity sha1-fZcZb51br39pNeJZhVSe3SpsIzk= cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== dependencies: collection-visit "^1.0.0" component-emitter "^1.2.1" @@ -449,20 +529,24 @@ cache-base@^1.0.1: caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= dependencies: callsites "^0.2.0" callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= callsites@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= camelcase-keys@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= dependencies: camelcase "^2.0.0" map-obj "^1.0.0" @@ -470,18 +554,22 @@ camelcase-keys@^2.0.0: camelcase@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk= camelcase@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= capture-stack-trace@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" + integrity sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0= cardinal@0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/cardinal/-/cardinal-0.4.4.tgz#ca5bb68a5b511b90fe93b9acea49bdee5c32bfe2" + integrity sha1-ylu2iltRG5D+k7ms6km97lwyv+I= dependencies: ansicolors "~0.2.1" redeyed "~0.4.0" @@ -489,14 +577,17 @@ cardinal@0.4.4: caseless@~0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + integrity sha1-cVuW6phBWTzDMGeSP17GDr2k99c= caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= center-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + integrity sha1-qg0yYptu6XIgBBHL1EYckHvCt60= dependencies: align-text "^0.1.3" lazy-cache "^1.0.3" @@ -504,6 +595,7 @@ center-align@^0.1.1: chai@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" + integrity sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc= dependencies: assertion-error "^1.0.1" deep-eql "^0.1.3" @@ -512,6 +604,7 @@ chai@^3.5.0: chai@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" + integrity sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw= dependencies: assertion-error "^1.0.1" check-error "^1.0.1" @@ -523,12 +616,14 @@ chai@^4.1.2: chainsaw@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" + integrity sha1-XqtQsor+WAdNDVgpE4iCi15fvJg= dependencies: traverse ">=0.3.0 <0.4" chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3, chalk@~1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= dependencies: ansi-styles "^2.2.1" escape-string-regexp "^1.0.2" @@ -539,6 +634,7 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3, chalk@~1.1.1: chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65" + integrity sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" @@ -547,26 +643,32 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.1: check-error@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= chmodr@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/chmodr/-/chmodr-1.0.2.tgz#04662b932d0f02ec66deaa2b0ea42811968e3eb9" + integrity sha1-BGYrky0PAuxm3qorDqQoEZaOPrk= chownr@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + integrity sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE= ci-info@^1.0.0: version "1.1.3" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.3.tgz#710193264bb05c77b8c90d02f5aaf22216a667b2" + integrity sha512-SK/846h/Rcy8q9Z9CAwGBLfCJ6EkjJWdpelWDufQpqVDYq2Wnnv8zlSO6AMQap02jvhVruKKpEtQOufo3pFhLg== circular-json@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== dependencies: arr-union "^3.1.0" define-property "^0.2.5" @@ -576,16 +678,19 @@ class-utils@^0.3.5: cli-cursor@^1.0.1, cli-cursor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc= dependencies: restore-cursor "^1.0.1" cli-spinners@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" + integrity sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw= cli-truncate@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ= dependencies: slice-ansi "0.0.4" string-width "^1.0.1" @@ -593,14 +698,17 @@ cli-truncate@^0.2.1: cli-width@^1.0.1: version "1.1.1" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-1.1.1.tgz#a4d293ef67ebb7b88d4a4d42c0ccf00c4d1e366d" + integrity sha1-pNKT72frt7iNSk1CwMzwDE0eNm0= cli-width@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= cliui@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + integrity sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE= dependencies: center-align "^0.1.1" right-align "^0.1.1" @@ -609,18 +717,22 @@ cliui@^2.1.0: co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= coffee-script@~1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.10.0.tgz#12938bcf9be1948fa006f92e0c4c9e81705108c0" + integrity sha1-EpOLz5vhlI+gBvkuDEyegXBRCMA= collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= dependencies: map-visit "^1.0.0" object-visit "^1.0.0" @@ -628,56 +740,68 @@ collection-visit@^1.0.0: color-convert@^1.9.0: version "1.9.1" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + integrity sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ== dependencies: color-name "^1.1.1" color-name@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= colors@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM= combined-stream@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" + integrity sha1-cj599ugBrFYTETp+RFqbactjKBg= dependencies: delayed-stream "~1.0.0" combined-stream@^1.0.5, combined-stream@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + integrity sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk= dependencies: delayed-stream "~1.0.0" commander@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" + integrity sha1-+mihT2qUXVTbvlDYzbMyDp47GgY= commander@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" + integrity sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM= commander@^2.14.1: version "2.15.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== commander@^2.9.0: version "2.11.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + integrity sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ== component-emitter@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= concat-stream@^1.4.6, concat-stream@^1.4.7: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + integrity sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc= dependencies: inherits "^2.0.3" readable-stream "^2.2.2" @@ -686,6 +810,7 @@ concat-stream@^1.4.6, concat-stream@^1.4.7: configstore@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/configstore/-/configstore-2.1.0.tgz#737a3a7036e9886102aa6099e47bb33ab1aba1a1" + integrity sha1-c3o6cDbpiGECqmCZ5HuzOrGroaE= dependencies: dot-prop "^3.0.0" graceful-fs "^4.1.2" @@ -700,22 +825,27 @@ configstore@^2.0.0: content-type-parser@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7" + integrity sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ== content-type@~1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= cosmiconfig@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" + integrity sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ== dependencies: is-directory "^0.3.1" js-yaml "^3.9.0" @@ -725,6 +855,7 @@ cosmiconfig@^4.0.0: coveralls@^2.11.9: version "2.13.1" resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-2.13.1.tgz#d70bb9acc1835ec4f063ff9dac5423c17b11f178" + integrity sha1-1wu5rMGDXsTwY/+drFQjwXsR8Xg= dependencies: js-yaml "3.6.1" lcov-parse "0.0.10" @@ -735,12 +866,14 @@ coveralls@^2.11.9: create-error-class@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= dependencies: capture-stack-trace "^1.0.0" cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= dependencies: lru-cache "^4.0.1" shebang-command "^1.2.0" @@ -749,50 +882,59 @@ cross-spawn@^5.0.1: cryptiles@2.x.x: version "2.0.5" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + integrity sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g= dependencies: boom "2.x.x" cryptiles@3.x.x: version "3.1.2" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" + integrity sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4= dependencies: boom "5.x.x" cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": version "0.3.2" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b" + integrity sha1-uANhcMefB6kP8vFuIihAJ6JDhIs= "cssstyle@>= 0.2.37 < 0.3.0": version "0.2.37" resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-0.2.37.tgz#541097234cb2513c83ceed3acddc27ff27987d54" + integrity sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ= dependencies: cssom "0.3.x" currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= dependencies: array-find-index "^1.0.1" d@1: version "1.0.0" resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8= dependencies: es5-ext "^0.10.9" dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= dependencies: assert-plus "^1.0.0" date-fns@^1.27.2: version "1.29.0" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" + integrity sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw== dateformat@~1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" + integrity sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk= dependencies: get-stdin "^4.0.1" meow "^3.3.0" @@ -800,38 +942,45 @@ dateformat@~1.0.12: debug@2.2.0, debug@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + integrity sha1-+HBX6ZWxofauaklgZkE3vFbwOdo= dependencies: ms "0.7.1" debug@^2.1.1: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + integrity sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw= dependencies: ms "2.0.0" debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" debug@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== dependencies: ms "2.0.0" decamelize@^1.0.0, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= -decompress-zip@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/decompress-zip/-/decompress-zip-0.2.1.tgz#5c2a2d06136f26ebb458453c2efb2ead8b593fed" +decompress-zip@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/decompress-zip/-/decompress-zip-0.3.2.tgz#f3fa2841666abce394604f4a9e8a7085c202d464" + integrity sha512-Ab1QY4LrWMrUuo53lLnmGOby7v8ryqxJ+bKibKSiPisx+25mhut1dScVBXAYx14i/PqSrFZvR2FRRazhLbvL+g== dependencies: binary "^0.3.0" graceful-fs "^4.1.3" @@ -844,50 +993,60 @@ decompress-zip@^0.2.1: dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= deep-eql@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" + integrity sha1-71WKyrjeJSBs1xOQbXTlaTDrafI= dependencies: type-detect "0.1.1" deep-eql@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== dependencies: type-detect "^4.0.0" deep-equal@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= deep-extend@^0.4.0, deep-extend@~0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" + integrity sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8= deep-extend@~0.2.5: version "0.2.11" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.2.11.tgz#7a16ba69729132340506170494bc83f7076fe08f" + integrity sha1-eha6aXKRMjQFBhcElLyD9wdv4I8= deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= dependencies: is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= dependencies: is-descriptor "^1.0.0" define-property@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== dependencies: is-descriptor "^1.0.2" isobject "^3.0.1" @@ -895,6 +1054,7 @@ define-property@^2.0.2: del@^2.0.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + integrity sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag= dependencies: globby "^5.0.0" is-path-cwd "^1.0.0" @@ -907,26 +1067,32 @@ del@^2.0.2: delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= depd@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" + integrity sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k= destroy@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= diff@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" + integrity sha1-fyjS657nsVqX79ic5j3P2qPMur8= diff@^3.2.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== doctrine@^1.2.2: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= dependencies: esutils "^2.0.2" isarray "^1.0.0" @@ -934,54 +1100,64 @@ doctrine@^1.2.2: domexception@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== dependencies: webidl-conversions "^4.0.2" dot-prop@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" + integrity sha1-G3CK8JSknJoOfbyteQq6U52sEXc= dependencies: is-obj "^1.0.0" duplexer2@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + integrity sha1-ixLauHjA1p4+eJEFFmKjL8a93ME= dependencies: readable-stream "^2.0.2" ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + integrity sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU= dependencies: jsbn "~0.1.0" ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= elegant-spinner@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" + integrity sha1-epDYM+/abPpurA9JSduw+tOmMgY= dependencies: once "^1.4.0" ends-with@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/ends-with/-/ends-with-0.2.0.tgz#2f9da98d57a50cfda4571ce4339000500f4e6b8a" + integrity sha1-L52pjVelDP2kVxzkM5AAUA9Oa4o= error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + integrity sha1-+FWobOYa3E6GIcPNoh56dhLDqNw= dependencies: is-arrayish "^0.2.1" es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: version "0.10.30" resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.30.tgz#7141a16836697dbabfaaaeee41495ce29f52c939" + integrity sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk= dependencies: es6-iterator "2" es6-symbol "~3.1" @@ -989,6 +1165,7 @@ es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" + integrity sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI= dependencies: d "1" es5-ext "^0.10.14" @@ -997,6 +1174,7 @@ es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: es6-map@^0.1.3: version "0.1.5" resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA= dependencies: d "1" es5-ext "~0.10.14" @@ -1008,6 +1186,7 @@ es6-map@^0.1.3: es6-set@~0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE= dependencies: d "1" es5-ext "~0.10.14" @@ -1018,6 +1197,7 @@ es6-set@~0.1.5: es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= dependencies: d "1" es5-ext "~0.10.14" @@ -1025,6 +1205,7 @@ es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbo es6-weak-map@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + integrity sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8= dependencies: d "1" es5-ext "^0.10.14" @@ -1034,14 +1215,17 @@ es6-weak-map@^2.0.1: escape-string-regexp@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" + integrity sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE= escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= escodegen@1.8.x: version "1.8.1" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= dependencies: esprima "^2.7.1" estraverse "^1.9.1" @@ -1053,6 +1237,7 @@ escodegen@1.8.x: escodegen@^1.9.0: version "1.9.1" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.1.tgz#dbae17ef96c8e4bedb1356f4504fa4cc2f7cb7e2" + integrity sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q== dependencies: esprima "^3.1.3" estraverse "^4.2.0" @@ -1064,6 +1249,7 @@ escodegen@^1.9.0: escope@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM= dependencies: es6-map "^0.1.3" es6-weak-map "^2.0.1" @@ -1073,6 +1259,7 @@ escope@^3.6.0: eslint@^2.0.0: version "2.13.1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-2.13.1.tgz#e4cc8fa0f009fb829aaae23855a29360be1f6c11" + integrity sha1-5MyPoPAJ+4KaquI4VaKTYL4fbBE= dependencies: chalk "^1.1.3" concat-stream "^1.4.6" @@ -1111,6 +1298,7 @@ eslint@^2.0.0: espree@^3.1.6: version "3.5.0" resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.0.tgz#98358625bdd055861ea27e2867ea729faf463d8d" + integrity sha1-mDWGJb3QVYYeon4oZ+pyn69GPY0= dependencies: acorn "^5.1.1" acorn-jsx "^3.0.0" @@ -1118,22 +1306,27 @@ espree@^3.1.6: esprima@2.7.x, esprima@^2.6.0, esprima@^2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= esprima@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= esprima@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + integrity sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw== esprima@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad" + integrity sha1-n1V+CPw7TSbs6d00+Pv0drYlha0= esrecurse@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" + integrity sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM= dependencies: estraverse "^4.1.0" object-assign "^4.0.1" @@ -1141,18 +1334,22 @@ esrecurse@^4.1.0: estraverse@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= event-emitter@~0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= dependencies: d "1" es5-ext "~0.10.14" @@ -1160,10 +1357,12 @@ event-emitter@~0.3.5: eventemitter2@~0.4.13: version "0.4.14" resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab" + integrity sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas= execa@^0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.9.0.tgz#adb7ce62cf985071f60580deb4a88b9e34712d01" + integrity sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA== dependencies: cross-spawn "^5.0.1" get-stream "^3.0.0" @@ -1176,20 +1375,24 @@ execa@^0.9.0: exit-hook@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g= exit@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= dependencies: is-posix-bracket "^0.1.0" expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= dependencies: debug "^2.3.3" define-property "^0.2.5" @@ -1202,16 +1405,19 @@ expand-brackets@^2.1.4: expand-range@^1.8.1: version "1.8.2" resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= dependencies: fill-range "^2.1.0" expect.js@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/expect.js/-/expect.js-0.3.1.tgz#b0a59a0d2eff5437544ebf0ceaa6015841d09b5b" + integrity sha1-sKWaDS7/VDdUTr8M6qYBWEHQm1s= expect@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/expect/-/expect-22.4.3.tgz#d5a29d0a0e1fb2153557caef2674d4547e914674" + integrity sha512-XcNXEPehqn8b/jm8FYotdX0YrXn36qp4HWlrVT4ktwQas1l1LPxiVWncYnnL2eyMtKAmVIaG0XAp0QlrqJaxaA== dependencies: ansi-styles "^3.2.0" jest-diff "^22.4.3" @@ -1223,12 +1429,14 @@ expect@^22.4.3: ext-list@^2.0.0: version "2.2.2" resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" + integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA== dependencies: mime-db "^1.28.0" ext-name@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-3.0.0.tgz#07e4418737cb1f513c32c6ea48d8b8c8e0471abb" + integrity sha1-B+RBhzfLH1E8MsbqSNi4yOBHGrs= dependencies: ends-with "^0.2.0" ext-list "^2.0.0" @@ -1238,12 +1446,14 @@ ext-name@^3.0.0: extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= dependencies: is-extendable "^0.1.0" extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= dependencies: assign-symbols "^1.0.0" is-extendable "^1.0.1" @@ -1251,16 +1461,19 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + integrity sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ= extglob@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= dependencies: is-extglob "^1.0.0" extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== dependencies: array-unique "^0.3.2" define-property "^1.0.0" @@ -1274,28 +1487,34 @@ extglob@^2.0.4: extsprintf@1.3.0, extsprintf@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= fast-deep-equal@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ= fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= faye-websocket@~0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= dependencies: websocket-driver ">=0.5.1" figures@^1.3.5, figures@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= dependencies: escape-string-regexp "^1.0.5" object-assign "^4.1.0" @@ -1303,6 +1522,7 @@ figures@^1.3.5, figures@^1.7.0: file-entry-cache@^1.1.1: version "1.3.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-1.3.1.tgz#44c61ea607ae4be9c1402f41f44270cbfe334ff8" + integrity sha1-RMYepgeuS+nBQC9B9EJwy/4zT/g= dependencies: flat-cache "^1.2.1" object-assign "^4.0.1" @@ -1310,10 +1530,12 @@ file-entry-cache@^1.1.1: filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= fill-keys@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/fill-keys/-/fill-keys-1.0.2.tgz#9a8fa36f4e8ad634e3bf6b4f3c8882551452eb20" + integrity sha1-mo+jb06K1jTjv2tPPIiCVRRS6yA= dependencies: is-object "~1.0.1" merge-descriptors "~1.0.0" @@ -1321,6 +1543,7 @@ fill-keys@^1.0.2: fill-range@^2.1.0: version "2.2.3" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + integrity sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM= dependencies: is-number "^2.1.0" isobject "^2.0.0" @@ -1331,6 +1554,7 @@ fill-range@^2.1.0: fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= dependencies: extend-shallow "^2.0.1" is-number "^3.0.0" @@ -1340,14 +1564,17 @@ fill-range@^4.0.0: filled-array@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/filled-array/-/filled-array-1.1.0.tgz#c3c4f6c663b923459a9aa29912d2d031f1507f84" + integrity sha1-w8T2xmO5I0WamqKZEtLQMfFQf4Q= find-parent-dir@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + integrity sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ= find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= dependencies: path-exists "^2.0.0" pinkie-promise "^2.0.0" @@ -1355,12 +1582,14 @@ find-up@^1.0.0: findup-sync@^0.3.0, findup-sync@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.3.0.tgz#37930aa5d816b777c03445e1966cc6790a4c0b16" + integrity sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY= dependencies: glob "~5.0.0" flat-cache@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" + integrity sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y= dependencies: circular-json "^0.3.1" del "^2.0.2" @@ -1370,20 +1599,24 @@ flat-cache@^1.2.1: for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= for-own@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= dependencies: for-in "^1.0.1" forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= form-data@~1.0.0-rc3: version "1.0.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.1.tgz#ae315db9a4907fa065502304a66d7733475ee37c" + integrity sha1-rjFduaSQf6BlUCMEpm13M0de43w= dependencies: async "^2.0.1" combined-stream "^1.0.5" @@ -1392,6 +1625,7 @@ form-data@~1.0.0-rc3: form-data@~2.1.1: version "2.1.4" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + integrity sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE= dependencies: asynckit "^0.4.0" combined-stream "^1.0.5" @@ -1400,6 +1634,7 @@ form-data@~2.1.1: form-data@~2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" + integrity sha1-SXBJi+YEwgwAXU9cI67NIda0kJk= dependencies: asynckit "^0.4.0" combined-stream "1.0.6" @@ -1408,12 +1643,14 @@ form-data@~2.3.1: fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= dependencies: map-cache "^0.2.2" fs-write-stream-atomic@1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.8.tgz#e49aaddf288f87d46ff9e882f216a13abc40778b" + integrity sha1-5Jqt3yiPh9Rv+eiC8hahOrxAd4s= dependencies: graceful-fs "^4.1.2" iferr "^0.1.5" @@ -1423,10 +1660,12 @@ fs-write-stream-atomic@1.0.8: fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fstream-ignore@^1.0.2: version "1.0.5" resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + integrity sha1-nDHa40dnAY/h0kmyTa2mfQktoQU= dependencies: fstream "^1.0.0" inherits "2" @@ -1435,6 +1674,7 @@ fstream-ignore@^1.0.2: fstream@^1.0.0, fstream@^1.0.3: version "1.0.11" resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= dependencies: graceful-fs "^4.1.2" inherits "~2.0.0" @@ -1444,58 +1684,70 @@ fstream@^1.0.0, fstream@^1.0.3: gaze@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.2.tgz#847224677adb8870d679257ed3388fdb61e40105" + integrity sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU= dependencies: globule "^1.0.0" generate-function@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + integrity sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ= generate-object-property@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + integrity sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA= dependencies: is-property "^1.0.0" get-func-name@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= get-own-enumerable-property-symbols@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz#5c4ad87f2834c4b9b4e84549dc1e0650fb38c24b" + integrity sha512-TtY/sbOemiMKPRUDDanGCSgBYe7Mf0vbRsWnBZ+9yghpZ1MvcpSpuZFjHdEeY/LZjZy0vdLjS77L6HosisFiug== get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= getobject@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/getobject/-/getobject-0.1.0.tgz#047a449789fa160d018f5486ed91320b6ec7885c" + integrity sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw= getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= dependencies: assert-plus "^1.0.0" github@^0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/github/-/github-0.2.4.tgz#24fa7f0e13fa11b946af91134c51982a91ce538b" + integrity sha1-JPp/DhP6EblGr5ETTFGYKpHOU4s= dependencies: mime "^1.2.11" glob-base@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= dependencies: glob-parent "^2.0.0" is-glob "^2.0.0" @@ -1503,12 +1755,14 @@ glob-base@^0.3.0: glob-parent@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= dependencies: is-glob "^2.0.0" glob@3.2.11: version "3.2.11" resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" + integrity sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0= dependencies: inherits "2" minimatch "0.3" @@ -1516,6 +1770,7 @@ glob@3.2.11: glob@^4.3.2: version "4.5.3" resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f" + integrity sha1-xstz0yJsHv7wTePFbQEvAzd+4V8= dependencies: inflight "^1.0.4" inherits "2" @@ -1525,6 +1780,7 @@ glob@^4.3.2: glob@^5.0.15, glob@~5.0.0: version "5.0.15" resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= dependencies: inflight "^1.0.4" inherits "2" @@ -1535,6 +1791,7 @@ glob@^5.0.15, glob@~5.0.0: glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@~7.1.1: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -1546,6 +1803,7 @@ glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@~7.1.1: glob@~7.0.0: version "7.0.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" + integrity sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo= dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -1557,10 +1815,12 @@ glob@~7.0.0: globals@^9.2.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== globby@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + integrity sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0= dependencies: array-union "^1.0.1" arrify "^1.0.0" @@ -1572,6 +1832,7 @@ globby@^5.0.0: globule@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.0.tgz#1dc49c6822dd9e8a2fa00ba2a295006e8664bd09" + integrity sha1-HcScaCLdnoovoAuiopUAboZkvQk= dependencies: glob "~7.1.1" lodash "~4.17.4" @@ -1580,6 +1841,7 @@ globule@^1.0.0: got@^5.0.0: version "5.7.1" resolved "https://registry.yarnpkg.com/got/-/got-5.7.1.tgz#5f81635a61e4a6589f180569ea4e381680a51f35" + integrity sha1-X4FjWmHkplifGAVp6k44FoClHzU= dependencies: create-error-class "^3.0.1" duplexer2 "^0.1.4" @@ -1600,14 +1862,17 @@ got@^5.0.0: graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= growl@1.9.2: version "1.9.2" resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8= grunt-cli@^1.1.0, grunt-cli@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/grunt-cli/-/grunt-cli-1.2.0.tgz#562b119ebb069ddb464ace2845501be97b35b6a8" + integrity sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg= dependencies: findup-sync "~0.3.0" grunt-known-options "~1.1.0" @@ -1617,6 +1882,7 @@ grunt-cli@^1.1.0, grunt-cli@~1.2.0: grunt-contrib-watch@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/grunt-contrib-watch/-/grunt-contrib-watch-1.0.0.tgz#84a1a7a1d6abd26ed568413496c73133e990018f" + integrity sha1-hKGnodar0m7VaEE0lscxM+mQAY8= dependencies: async "^1.5.0" gaze "^1.0.0" @@ -1626,6 +1892,7 @@ grunt-contrib-watch@^1.0.0: grunt-eslint@^18.1.0: version "18.1.0" resolved "https://registry.yarnpkg.com/grunt-eslint/-/grunt-eslint-18.1.0.tgz#ea700e220ecddf962ae8c317f15ebedb65a97c86" + integrity sha1-6nAOIg7N35Yq6MMX8V6+22WpfIY= dependencies: chalk "^1.0.0" eslint "^2.0.0" @@ -1633,14 +1900,17 @@ grunt-eslint@^18.1.0: grunt-exec@^0.4.7: version "0.4.7" resolved "https://registry.yarnpkg.com/grunt-exec/-/grunt-exec-0.4.7.tgz#40051ffa4eb0c9657e053b95e88d44352a1c2c25" + integrity sha1-QAUf+k6wyWV+BTuV6I1ENSocLCU= grunt-known-options@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/grunt-known-options/-/grunt-known-options-1.1.0.tgz#a4274eeb32fa765da5a7a3b1712617ce3b144149" + integrity sha1-pCdO6zL6dl2lp6OxcSYXzjsUQUk= grunt-legacy-log-utils@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/grunt-legacy-log-utils/-/grunt-legacy-log-utils-1.0.0.tgz#a7b8e2d0fb35b5a50f4af986fc112749ebc96f3d" + integrity sha1-p7ji0Ps1taUPSvmG/BEnSevJbz0= dependencies: chalk "~1.1.1" lodash "~4.3.0" @@ -1648,6 +1918,7 @@ grunt-legacy-log-utils@~1.0.0: grunt-legacy-log@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/grunt-legacy-log/-/grunt-legacy-log-1.0.0.tgz#fb86f1809847bc07dc47843f9ecd6cacb62df2d5" + integrity sha1-+4bxgJhHvAfcR4Q/ns1srLYt8tU= dependencies: colors "~1.1.2" grunt-legacy-log-utils "~1.0.0" @@ -1658,6 +1929,7 @@ grunt-legacy-log@~1.0.0: grunt-legacy-util@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/grunt-legacy-util/-/grunt-legacy-util-1.0.0.tgz#386aa78dc6ed50986c2b18957265b1b48abb9b86" + integrity sha1-OGqnjcbtUJhsKxiVcmWxtIq7m4Y= dependencies: async "~1.5.2" exit "~0.1.1" @@ -1670,12 +1942,14 @@ grunt-legacy-util@~1.0.0: grunt-simple-mocha@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/grunt-simple-mocha/-/grunt-simple-mocha-0.4.1.tgz#579449249eaf0a81878fa72f3edab5145d45fd77" + integrity sha1-V5RJJJ6vCoGHj6cvPtq1FF1F/Xc= dependencies: mocha "^2.3.4" grunt@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/grunt/-/grunt-1.0.1.tgz#e8778764e944b18f32bb0f10b9078475c9dfb56b" + integrity sha1-6HeHZOlEsY8yuw8QuQeEdcnftWs= dependencies: coffee-script "~1.10.0" dateformat "~1.0.12" @@ -1697,6 +1971,7 @@ grunt@^1.0.1: handlebars@^4.0.1, handlebars@^4.0.5: version "4.0.10" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f" + integrity sha1-PTDHGLCaPZbyPqTMH0A8TTup/08= dependencies: async "^1.4.0" optimist "^0.6.1" @@ -1707,14 +1982,17 @@ handlebars@^4.0.1, handlebars@^4.0.5: har-schema@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + integrity sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4= har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= har-validator@~2.0.2, har-validator@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + integrity sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0= dependencies: chalk "^1.1.1" commander "^2.9.0" @@ -1724,6 +2002,7 @@ har-validator@~2.0.2, har-validator@~2.0.6: har-validator@~4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + integrity sha1-M0gdDxu/9gDdID11gSpqX7oALio= dependencies: ajv "^4.9.1" har-schema "^1.0.5" @@ -1731,6 +2010,7 @@ har-validator@~4.2.1: har-validator@~5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + integrity sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0= dependencies: ajv "^5.1.0" har-schema "^2.0.0" @@ -1738,20 +2018,24 @@ har-validator@~5.0.3: has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= dependencies: ansi-regex "^2.0.0" has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= dependencies: get-value "^2.0.3" has-values "^0.1.4" @@ -1760,6 +2044,7 @@ has-value@^0.3.1: has-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= dependencies: get-value "^2.0.6" has-values "^1.0.0" @@ -1768,10 +2053,12 @@ has-value@^1.0.0: has-values@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= has-values@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= dependencies: is-number "^3.0.0" kind-of "^4.0.0" @@ -1779,6 +2066,7 @@ has-values@^1.0.0: hawk@~3.1.0, hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + integrity sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ= dependencies: boom "2.x.x" cryptiles "2.x.x" @@ -1788,6 +2076,7 @@ hawk@~3.1.0, hawk@~3.1.3: hawk@~6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" + integrity sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ== dependencies: boom "4.x.x" cryptiles "3.x.x" @@ -1797,28 +2086,34 @@ hawk@~6.0.2: hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + integrity sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0= hoek@4.x.x: version "4.2.1" resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" + integrity sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA== hooker@~0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/hooker/-/hooker-0.2.3.tgz#b834f723cc4a242aa65963459df6d984c5d3d959" + integrity sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk= hosted-git-info@^2.1.4: version "2.5.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" + integrity sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg== html-encoding-sniffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== dependencies: whatwg-encoding "^1.0.1" http-errors@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.3.1.tgz#197e22cdebd4198585e8694ef6786197b91ed942" + integrity sha1-GX4izevUGYWF6GlO9nhhl7ke2UI= dependencies: inherits "~2.0.1" statuses "1" @@ -1826,10 +2121,12 @@ http-errors@~1.3.1: http-parser-js@>=0.4.0: version "0.4.6" resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.6.tgz#195273f58704c452d671076be201329dd341dc55" + integrity sha1-GVJz9YcExFLWcQdr4gEyndNB3FU= http-signature@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + integrity sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8= dependencies: assert-plus "^0.2.0" jsprim "^1.2.2" @@ -1838,6 +2135,7 @@ http-signature@~1.1.0: http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= dependencies: assert-plus "^1.0.0" jsprim "^1.2.2" @@ -1846,6 +2144,7 @@ http-signature@~1.2.0: husky@^0.14.3: version "0.14.3" resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3" + integrity sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA== dependencies: is-ci "^1.0.10" normalize-path "^1.0.0" @@ -1854,40 +2153,49 @@ husky@^0.14.3: iconv-lite@0.4.13: version "0.4.13" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" + integrity sha1-H4irpKsLFQjoMSrMOTRfNumS4vI= iconv-lite@0.4.19, iconv-lite@~0.4.13: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + integrity sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ== iferr@^0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= ignore@^3.1.2: version "3.3.5" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.5.tgz#c4e715455f6073a8d7e5dae72d2fc9d71663dba6" + integrity sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw== imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= in-publish@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" + integrity sha1-4g/146KvwmkDILbcVSaCqcf631E= indent-string@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= dependencies: repeating "^2.0.0" indent-string@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= dependencies: once "^1.3.0" wrappy "1" @@ -1895,14 +2203,17 @@ inflight@^1.0.4: inherits@2, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= ini@~1.3.0: version "1.3.4" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + integrity sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4= inquirer@0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.10.0.tgz#48cd3e23f8d989a52d47dc5e10ec75324387e908" + integrity sha1-SM0+I/jZiaUtR9xeEOx1MkOH6Qg= dependencies: ansi-escapes "^1.1.0" ansi-regex "^2.0.0" @@ -1920,6 +2231,7 @@ inquirer@0.10.0: inquirer@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + integrity sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34= dependencies: ansi-escapes "^1.1.0" ansi-regex "^2.0.0" @@ -1938,54 +2250,64 @@ inquirer@^0.12.0: intersect@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/intersect/-/intersect-1.0.1.tgz#332650e10854d8c0ac58c192bdc27a8bf7e7a30c" + integrity sha1-MyZQ4QhU2MCsWMGSvcJ6i/fnoww= is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= dependencies: kind-of "^3.0.2" is-accessor-descriptor@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== dependencies: kind-of "^6.0.0" is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= is-buffer@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" + integrity sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw= is-builtin-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= dependencies: builtin-modules "^1.0.0" is-ci@^1.0.10: version "1.1.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" + integrity sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg== dependencies: ci-info "^1.0.0" is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= dependencies: kind-of "^3.0.2" is-data-descriptor@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== dependencies: kind-of "^6.0.0" is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== dependencies: is-accessor-descriptor "^0.1.6" is-data-descriptor "^0.1.4" @@ -1994,6 +2316,7 @@ is-descriptor@^0.1.0: is-descriptor@^1.0.0, is-descriptor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== dependencies: is-accessor-descriptor "^1.0.0" is-data-descriptor "^1.0.0" @@ -2002,70 +2325,84 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-directory@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= is-equal-shallow@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= dependencies: is-primitive "^2.0.0" is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= is-extendable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== dependencies: is-plain-object "^2.0.4" is-extglob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-finite@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= dependencies: number-is-nan "^1.0.0" is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= dependencies: number-is-nan "^1.0.0" is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= is-generator-fn@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + integrity sha1-lp1J4bszKfa7fwkIm+JleLLd1Go= is-glob@^2.0.0, is-glob@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= dependencies: is-extglob "^1.0.0" is-glob@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= dependencies: is-extglob "^2.1.1" is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: version "2.16.1" resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz#5a846777e2c2620d1e69104e5d3a03b1f6088f11" + integrity sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ== dependencies: generate-function "^2.0.0" generate-object-property "^1.1.0" @@ -2075,152 +2412,185 @@ is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= dependencies: kind-of "^3.0.2" is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= dependencies: kind-of "^3.0.2" is-number@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= is-object@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= is-observable@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2" + integrity sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI= dependencies: symbol-observable "^0.2.2" is-odd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" + integrity sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ== dependencies: is-number "^4.0.0" is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= is-path-in-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + integrity sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw= dependencies: is-path-inside "^1.0.0" is-path-inside@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + integrity sha1-/AbloWg/vaE95mev9xe7wQpI838= dependencies: path-is-inside "^1.0.1" is-plain-obj@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: isobject "^3.0.1" is-posix-bracket@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= is-primitive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= is-property@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ= is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= is-resolvable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" + integrity sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI= dependencies: tryit "^1.0.1" is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= is-root@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-root/-/is-root-1.0.0.tgz#07b6c233bc394cd9d02ba15c966bd6660d6342d5" + integrity sha1-B7bCM7w5TNnQK6FclmvWZg1jQtU= is-stream@^1.0.0, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= dependencies: isarray "1.0.0" isobject@^3.0.0, isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= istanbul@^0.4.3: version "0.4.5" resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" + integrity sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs= dependencies: abbrev "1.0.x" async "1.x" @@ -2240,6 +2610,7 @@ istanbul@^0.4.3: jade@0.26.3: version "0.26.3" resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c" + integrity sha1-jxDXl32NefL2/4YqgbBRPMslaGw= dependencies: commander "0.6.1" mkdirp "0.3.0" @@ -2247,6 +2618,7 @@ jade@0.26.3: jest-config@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-22.4.3.tgz#0e9d57db267839ea31309119b41dc2fa31b76403" + integrity sha512-KSg3EOToCgkX+lIvenKY7J8s426h6ahXxaUFJxvGoEk0562Z6inWj1TnKoGycTASwiLD+6kSYFALcjdosq9KIQ== dependencies: chalk "^2.0.1" glob "^7.1.1" @@ -2263,6 +2635,7 @@ jest-config@^22.4.3: jest-diff@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-22.4.3.tgz#e18cc3feff0aeef159d02310f2686d4065378030" + integrity sha512-/QqGvCDP5oZOF6PebDuLwrB2BMD8ffJv6TAGAdEVuDx1+uEgrHpSFrfrOiMRx2eJ1hgNjlQrOQEHetVwij90KA== dependencies: chalk "^2.0.1" diff "^3.2.0" @@ -2272,6 +2645,7 @@ jest-diff@^22.4.3: jest-environment-jsdom@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz#d67daa4155e33516aecdd35afd82d4abf0fa8a1e" + integrity sha512-FviwfR+VyT3Datf13+ULjIMO5CSeajlayhhYQwpzgunswoaLIPutdbrnfUHEMyJCwvqQFaVtTmn9+Y8WCt6n1w== dependencies: jest-mock "^22.4.3" jest-util "^22.4.3" @@ -2280,6 +2654,7 @@ jest-environment-jsdom@^22.4.3: jest-environment-node@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-22.4.3.tgz#54c4eaa374c83dd52a9da8759be14ebe1d0b9129" + integrity sha512-reZl8XF6t/lMEuPWwo9OLfttyC26A5AMgDyEQ6DBgZuyfyeNUzYT8BFo6uxCCP/Av/b7eb9fTi3sIHFPBzmlRA== dependencies: jest-mock "^22.4.3" jest-util "^22.4.3" @@ -2287,10 +2662,12 @@ jest-environment-node@^22.4.3: jest-get-type@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" + integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w== jest-jasmine2@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-22.4.3.tgz#4daf64cd14c793da9db34a7c7b8dcfe52a745965" + integrity sha512-yZCPCJUcEY6R5KJB/VReo1AYI2b+5Ky+C+JA1v34jndJsRcLpU4IZX4rFJn7yDTtdNbO/nNqg+3SDIPNH2ecnw== dependencies: chalk "^2.0.1" co "^4.6.0" @@ -2307,6 +2684,7 @@ jest-jasmine2@^22.4.3: jest-matcher-utils@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz#4632fe428ebc73ebc194d3c7b65d37b161f710ff" + integrity sha512-lsEHVaTnKzdAPR5t4B6OcxXo9Vy4K+kRRbG5gtddY8lBEC+Mlpvm1CJcsMESRjzUhzkz568exMV1hTB76nAKbA== dependencies: chalk "^2.0.1" jest-get-type "^22.4.3" @@ -2315,6 +2693,7 @@ jest-matcher-utils@^22.4.3: jest-message-util@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-22.4.3.tgz#cf3d38aafe4befddbfc455e57d65d5239e399eb7" + integrity sha512-iAMeKxhB3Se5xkSjU0NndLLCHtP4n+GtCqV0bISKA5dmOXQfEbdEmYiu2qpnWBDCQdEafNDDU6Q+l6oBMd/+BA== dependencies: "@babel/code-frame" "^7.0.0-beta.35" chalk "^2.0.1" @@ -2325,14 +2704,17 @@ jest-message-util@^22.4.3: jest-mock@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-22.4.3.tgz#f63ba2f07a1511772cdc7979733397df770aabc7" + integrity sha512-+4R6mH5M1G4NK16CKg9N1DtCaFmuxhcIqF4lQK/Q1CIotqMs/XBemfpDPeVZBFow6iyUNu6EBT9ugdNOTT5o5Q== jest-regex-util@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-22.4.3.tgz#a826eb191cdf22502198c5401a1fc04de9cef5af" + integrity sha512-LFg1gWr3QinIjb8j833bq7jtQopiwdAs67OGfkPrvy7uNUbVMfTXXcOKXJaeY5GgjobELkKvKENqq1xrUectWg== jest-resolve@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-22.4.3.tgz#0ce9d438c8438229aa9b916968ec6b05c1abb4ea" + integrity sha512-u3BkD/MQBmwrOJDzDIaxpyqTxYH+XqAXzVJP51gt29H8jpj3QgKof5GGO2uPGKGeA1yTMlpbMs1gIQ6U4vcRhw== dependencies: browser-resolve "^1.11.2" chalk "^2.0.1" @@ -2340,6 +2722,7 @@ jest-resolve@^22.4.3: jest-snapshot@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-22.4.3.tgz#b5c9b42846ffb9faccb76b841315ba67887362d2" + integrity sha512-JXA0gVs5YL0HtLDCGa9YxcmmV2LZbwJ+0MfyXBBc5qpgkEYITQFJP7XNhcHFbUvRiniRpRbGVfJrOoYhhGE0RQ== dependencies: chalk "^2.0.1" jest-diff "^22.4.3" @@ -2351,6 +2734,7 @@ jest-snapshot@^22.4.3: jest-util@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-22.4.3.tgz#c70fec8eec487c37b10b0809dc064a7ecf6aafac" + integrity sha512-rfDfG8wyC5pDPNdcnAlZgwKnzHvZDu8Td2NJI/jAGKEGxJPYiE4F0ss/gSAkG4778Y23Hvbz+0GMrDJTeo7RjQ== dependencies: callsites "^2.0.0" chalk "^2.0.1" @@ -2363,6 +2747,7 @@ jest-util@^22.4.3: jest-validate@^22.4.0, jest-validate@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-22.4.3.tgz#0780954a5a7daaeec8d3c10834b9280865976b30" + integrity sha512-CfFM18W3GSP/xgmA4UouIx0ljdtfD2mjeBC6c89Gg17E44D4tQhAcTrZmf9djvipwU30kSTnk6CzcxdCCeSXfA== dependencies: chalk "^2.0.1" jest-config "^22.4.3" @@ -2373,10 +2758,12 @@ jest-validate@^22.4.0, jest-validate@^22.4.3: js-tokens@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= js-yaml@3.6.1: version "3.6.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30" + integrity sha1-bl/mfYsgXOTSL60Ft3geja3MSzA= dependencies: argparse "^1.0.7" esprima "^2.6.0" @@ -2384,6 +2771,7 @@ js-yaml@3.6.1: js-yaml@3.x, js-yaml@^3.5.1: version "3.10.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" + integrity sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -2391,6 +2779,7 @@ js-yaml@3.x, js-yaml@^3.5.1: js-yaml@^3.9.0: version "3.11.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" + integrity sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -2398,6 +2787,7 @@ js-yaml@^3.9.0: js-yaml@~3.5.2: version "3.5.5" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.5.5.tgz#0377c38017cabc7322b0d1fbcd25a491641f2fbe" + integrity sha1-A3fDgBfKvHMisNH7zSWkkWQfL74= dependencies: argparse "^1.0.2" esprima "^2.6.0" @@ -2405,10 +2795,12 @@ js-yaml@~3.5.2: jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= jsdom@^11.5.1: version "11.6.2" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.6.2.tgz#25d1ef332d48adf77fc5221fe2619967923f16bb" + integrity sha512-pAeZhpbSlUp5yQcS6cBQJwkbzmv4tWFaYxHbFVSxzXefqjvtRA851Z5N2P+TguVG9YeUDcgb8pdeVQRJh0XR3Q== dependencies: abab "^1.0.4" acorn "^5.3.0" @@ -2440,36 +2832,44 @@ jsdom@^11.5.1: json-parse-better-errors@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz#50183cd1b2d25275de069e9e71b467ac9eab973a" + integrity sha512-xyQpxeWWMKyJps9CuGJYeng6ssI5bpqS9ltQpdVQ90t4ql6NdnxFKh95JcRt2cun/DjMVNrdjniLPuMA69xmCw== json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= dependencies: jsonify "~0.0.0" json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= jsonpointer@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk= jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= dependencies: assert-plus "1.0.0" extsprintf "1.3.0" @@ -2479,52 +2879,63 @@ jsprim@^1.2.2: junk@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/junk/-/junk-1.0.3.tgz#87be63488649cbdca6f53ab39bec9ccd2347f592" + integrity sha1-h75jSIZJy9ym9Tqzm+yczSNH9ZI= kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= dependencies: is-buffer "^1.1.5" kind-of@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= dependencies: is-buffer "^1.1.5" kind-of@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== latest-version@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-2.0.0.tgz#56f8d6139620847b8017f8f1f4d78e211324168b" + integrity sha1-VvjWE5YghHuAF/jx9NeOIRMkFos= dependencies: package-json "^2.0.0" lazy-cache@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= lcov-parse@0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" + integrity sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM= left-pad@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.2.0.tgz#d30a73c6b8201d8f7d8e7956ba9616087a68e0ee" + integrity sha1-0wpzxrggHY99jnlWupYWCHpo4O4= leven@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= dependencies: prelude-ls "~1.1.2" type-check "~0.3.2" @@ -2532,6 +2943,7 @@ levn@^0.3.0, levn@~0.3.0: lint-staged@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-7.0.0.tgz#57926c63201e7bd38ca0576d74391efa699b4a9d" + integrity sha512-6Z89we28Qy1Ez7ZxO8yYfPKqzdxkSjnURq1d3RS2gKkZrA135xN+ptF3EWHrcHyBMmgA20vA7dGCQGj+OMS22g== dependencies: app-root-path "^2.0.1" chalk "^2.3.1" @@ -2558,10 +2970,12 @@ lint-staged@^7.0.0: listr-silent-renderer@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= listr-update-renderer@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7" + integrity sha1-NE2YDaLKLosUW6MFkI8yrj9MyKc= dependencies: chalk "^1.1.3" cli-truncate "^0.2.1" @@ -2575,6 +2989,7 @@ listr-update-renderer@^0.4.0: listr-verbose-renderer@^0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35" + integrity sha1-ggb0z21S3cWCfl/RSYng6WWTOjU= dependencies: chalk "^1.1.3" cli-cursor "^1.0.2" @@ -2584,6 +2999,7 @@ listr-verbose-renderer@^0.4.0: listr@^0.13.0: version "0.13.0" resolved "https://registry.yarnpkg.com/listr/-/listr-0.13.0.tgz#20bb0ba30bae660ee84cc0503df4be3d5623887d" + integrity sha1-ILsLowuuZg7oTMBQPfS+PVYjiH0= dependencies: chalk "^1.1.3" cli-truncate "^0.2.1" @@ -2606,10 +3022,12 @@ listr@^0.13.0: livereload-js@^2.2.0: version "2.2.2" resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.2.2.tgz#6c87257e648ab475bc24ea257457edcc1f8d0bc2" + integrity sha1-bIclfmSKtHW8JOoldFftzB+NC8I= load-grunt-tasks@^3.5.0: version "3.5.2" resolved "https://registry.yarnpkg.com/load-grunt-tasks/-/load-grunt-tasks-3.5.2.tgz#0728561180fd20ff8a6927505852fc58aaea0c88" + integrity sha1-ByhWEYD9IP+KaSdQWFL8WKrqDIg= dependencies: arrify "^1.0.0" multimatch "^2.0.0" @@ -2619,6 +3037,7 @@ load-grunt-tasks@^3.5.0: load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= dependencies: graceful-fs "^4.1.2" parse-json "^2.2.0" @@ -2629,46 +3048,56 @@ load-json-file@^1.0.0: lockfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.3.tgz#2638fc39a0331e9cac1a04b71799931c9c50df79" + integrity sha1-Jjj8OaAzHpysGgS3F5mTHJxQ33k= lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= lodash@^3.10.1, lodash@^3.3.1, lodash@~3.10.1: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" + integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y= lodash@^4.0.0, lodash@^4.14.0, lodash@^4.3.0, lodash@~4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + integrity sha1-eCA6TRwyiuHYbcpkYONptX9AVa4= lodash@^4.13.1, lodash@^4.17.5: version "4.17.5" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" + integrity sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw== lodash@~4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.3.0.tgz#efd9c4a6ec53f3b05412429915c3e4824e4d25a4" + integrity sha1-79nEpuxT87BUEkKZFcPkgk5NJaQ= log-driver@1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056" + integrity sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY= log-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= dependencies: chalk "^1.0.0" log-symbols@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== dependencies: chalk "^2.0.1" log-update@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" + integrity sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE= dependencies: ansi-escapes "^1.0.0" cli-cursor "^1.0.2" @@ -2676,10 +3105,12 @@ log-update@^1.0.2: longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= loud-rejection@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= dependencies: currently-unhandled "^0.4.1" signal-exit "^3.0.0" @@ -2687,14 +3118,17 @@ loud-rejection@^1.0.0: lowercase-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY= lru-cache@2, lru-cache@^2.3.0, lru-cache@^2.5.0: version "2.7.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI= lru-cache@^4.0.1: version "4.1.2" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.2.tgz#45234b2e6e2f2b33da125624c4664929a0224c3f" + integrity sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ== dependencies: pseudomap "^1.0.2" yallist "^2.1.2" @@ -2702,34 +3136,41 @@ lru-cache@^4.0.1: map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= dependencies: object-visit "^1.0.0" md5-hex@^1.0.2: version "1.3.0" resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" + integrity sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ= dependencies: md5-o-matic "^0.1.1" md5-o-matic@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + integrity sha1-givM1l4RfFFPqxdrJZRdVBAKA8M= media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= meow@^3.1.0, meow@^3.3.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= dependencies: camelcase-keys "^2.0.0" decamelize "^1.1.2" @@ -2745,10 +3186,12 @@ meow@^3.1.0, meow@^3.3.0: merge-descriptors@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= micromatch@^2.3.11: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= dependencies: arr-diff "^2.0.0" array-unique "^0.2.1" @@ -2767,6 +3210,7 @@ micromatch@^2.3.11: micromatch@^3.1.8: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" @@ -2785,30 +3229,36 @@ micromatch@^3.1.8: mime-db@^1.28.0, mime-db@~1.30.0: version "1.30.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" + integrity sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE= mime-db@~1.33.0: version "1.33.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" + integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ== mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.7: version "2.1.17" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" + integrity sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo= dependencies: mime-db "~1.30.0" mime-types@~2.1.17: version "2.1.18" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" + integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ== dependencies: mime-db "~1.33.0" mime@^1.2.11: version "1.4.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.0.tgz#69e9e0db51d44f2a3b56e48b7817d7d137f1a343" + integrity sha512-n9ChLv77+QQEapYz8lV+rIZAW3HhAPW2CXnzb1GN5uMkuczshwvkW7XPsbzU0ZQN3sP47Er2KVkp2p3KyqZKSQ== minimatch@0.3: version "0.3.0" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" + integrity sha1-J12O2qxPG7MyZHIInnlJyDlGmd0= dependencies: lru-cache "2" sigmund "~1.0.0" @@ -2816,30 +3266,36 @@ minimatch@0.3: "minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.0, minimatch@~3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" minimatch@^2.0.1: version "2.0.10" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" + integrity sha1-jQh8OcazjAAbl/ynzm0OHoCvusc= dependencies: brace-expansion "^1.0.0" minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= minimist@1.2.0, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= minimist@~0.0.1, minimist@~0.0.7: version "0.0.10" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= mixin-deep@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== dependencies: for-in "^1.0.2" is-extendable "^1.0.1" @@ -2847,30 +3303,36 @@ mixin-deep@^1.2.0: mkdirp@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" + integrity sha1-G79asbqCevI1dRQ0kEJkVfSB/h4= mkdirp@0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12" + integrity sha1-HXMHam35hs2TROFecfzAWkyavxI= dependencies: minimist "0.0.8" mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" mkdirp@^0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7" + integrity sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc= mkpath@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/mkpath/-/mkpath-0.1.0.tgz#7554a6f8d871834cc97b5462b122c4c124d6de91" + integrity sha1-dVSm+Nhxg0zJe1RisSLEwSTW3pE= mocha@^2.3.4, mocha@^2.5.3: version "2.5.3" resolved "https://registry.yarnpkg.com/mocha/-/mocha-2.5.3.tgz#161be5bdeb496771eb9b35745050b622b5aefc58" + integrity sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg= dependencies: commander "2.3.0" debug "2.2.0" @@ -2886,32 +3348,39 @@ mocha@^2.3.4, mocha@^2.5.3: module-not-found-error@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/module-not-found-error/-/module-not-found-error-1.0.1.tgz#cf8b4ff4f29640674d6cdd02b0e3bc523c2bbdc0" + integrity sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA= mout@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/mout/-/mout-0.11.1.tgz#ba3611df5f0e5b1ffbfd01166b8f02d1f5fa2b99" + integrity sha1-ujYR318OWx/7/QEWa48C0fX6K5k= mout@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mout/-/mout-1.0.0.tgz#9bdf1d4af57d66d47cb353a6335a3281098e1501" + integrity sha1-m98dSvV9ZtR8s1OmM1oygQmOFQE= ms@0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + integrity sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg= ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= multiline@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/multiline/-/multiline-1.0.2.tgz#69b1f25ff074d2828904f244ddd06b7d96ef6c93" + integrity sha1-abHyX/B00oKJBPJE3dBrfZbvbJM= dependencies: strip-indent "^1.0.0" multimatch@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= dependencies: array-differ "^1.0.0" array-union "^1.0.1" @@ -2921,14 +3390,17 @@ multimatch@^2.0.0: mute-stream@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" + integrity sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA= mute-stream@~0.0.4: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= nanomatch@^1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" + integrity sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA== dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" @@ -2946,16 +3418,19 @@ nanomatch@^1.2.9: natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= nested-error-stacks@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.0.0.tgz#98b2ffaefb4610fa3936f1e71435d30700de2840" + integrity sha1-mLL/rvtGEPo5NvHnFDXTBwDeKEA= dependencies: inherits "~2.0.1" nock@^9.2.3: version "9.2.3" resolved "https://registry.yarnpkg.com/nock/-/nock-9.2.3.tgz#39738087d6a0497d3a165fb352612b38a2f9b92f" + integrity sha512-4XYNSJDJ/PvNoH+cCRWcGOOFsq3jtZdNTRIlPIBA7CopGWJO56m5OaPEjjJ3WddxNYfe5HL9sQQAtMt8oyR9AA== dependencies: chai "^4.1.2" debug "^3.1.0" @@ -2970,26 +3445,31 @@ nock@^9.2.3: node-status-codes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/node-status-codes/-/node-status-codes-1.0.0.tgz#5ae5541d024645d32a58fcddc9ceecea7ae3ac2f" + integrity sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8= node-uuid@^1.4.7, node-uuid@~1.4.7: version "1.4.8" resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" + integrity sha1-sEDrCSOWivq/jTL7HxfxFn/auQc= nopt@3.x, nopt@^3.0.1, nopt@~3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= dependencies: abbrev "1" nopt@~1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= dependencies: abbrev "1" normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== dependencies: hosted-git-info "^2.1.4" is-builtin-module "^1.0.0" @@ -2999,28 +3479,33 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: normalize-path@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" + integrity sha1-MtDkcvkf80VwHBWoMRAY07CpA3k= normalize-path@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= dependencies: remove-trailing-separator "^1.0.1" npm-path@^2.0.2: version "2.0.4" resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" + integrity sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw== dependencies: which "^1.2.10" npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= dependencies: path-key "^2.0.0" npm-which@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" + integrity sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo= dependencies: commander "^2.9.0" npm-path "^2.0.2" @@ -3029,22 +3514,27 @@ npm-which@^3.0.1: number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= nwmatcher@^1.4.3: version "1.4.4" resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.4.tgz#2285631f34a95f0d0395cd900c96ed39b58f346e" + integrity sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ== oauth-sign@~0.8.0, oauth-sign@~0.8.1, oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= dependencies: copy-descriptor "^0.1.0" define-property "^0.2.5" @@ -3053,12 +3543,14 @@ object-copy@^0.1.0: object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= dependencies: isobject "^3.0.0" object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= dependencies: for-own "^0.1.4" is-extendable "^0.1.1" @@ -3066,28 +3558,33 @@ object.omit@^2.0.0: object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= dependencies: isobject "^3.0.1" on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= dependencies: ee-first "1.1.1" once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" onetime@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k= opn@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" + integrity sha1-erwi5kTf9jsKltWrfyeQwPAavJU= dependencies: object-assign "^4.0.1" pinkie-promise "^2.0.0" @@ -3095,6 +3592,7 @@ opn@^4.0.0: optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= dependencies: minimist "~0.0.1" wordwrap "~0.0.2" @@ -3102,6 +3600,7 @@ optimist@^0.6.1: optionator@^0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= dependencies: deep-is "~0.1.3" fast-levenshtein "~2.0.4" @@ -3113,6 +3612,7 @@ optionator@^0.8.1: ora@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" + integrity sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q= dependencies: chalk "^1.1.1" cli-cursor "^1.0.2" @@ -3122,18 +3622,22 @@ ora@^0.2.3: os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= os-shim@^0.1.2: version "0.1.3" resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917" + integrity sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc= os-tmpdir@^1.0.0, os-tmpdir@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= osenv@^0.1.0, osenv@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" + integrity sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ= dependencies: os-homedir "^1.0.0" os-tmpdir "^1.0.0" @@ -3141,20 +3645,24 @@ osenv@^0.1.0, osenv@^0.1.3: p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= p-map@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== p-throttler@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/p-throttler/-/p-throttler-0.1.1.tgz#15246409d225d3eefca85c50de710a83a78cca6a" + integrity sha1-FSRkCdIl0+78qFxQ3nEKg6eMymo= dependencies: q "~0.9.2" package-json@^2.0.0: version "2.4.0" resolved "https://registry.yarnpkg.com/package-json/-/package-json-2.4.0.tgz#0d15bd67d1cbbddbb2ca222ff2edb86bcb31a8bb" + integrity sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs= dependencies: got "^5.0.0" registry-auth-token "^3.0.1" @@ -3164,6 +3672,7 @@ package-json@^2.0.0: parse-glob@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= dependencies: glob-base "^0.3.0" is-dotfile "^1.0.0" @@ -3173,12 +3682,14 @@ parse-glob@^3.0.4: parse-json@^2.1.0, parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= dependencies: error-ex "^1.2.0" parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= dependencies: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" @@ -3186,40 +3697,49 @@ parse-json@^4.0.0: parse5@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== parseurl@~1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= dependencies: pinkie-promise "^2.0.0" path-is-absolute@^1.0.0, path-is-absolute@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= path-key@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= path-parse@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + integrity sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME= path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= dependencies: graceful-fs "^4.1.2" pify "^2.0.0" @@ -3228,74 +3748,91 @@ path-type@^1.0.0: pathval@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + integrity sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU= performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= dependencies: pinkie "^2.0.0" pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= pkg-up@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26" + integrity sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY= dependencies: find-up "^1.0.0" please-upgrade-node@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.0.1.tgz#0a681f2c18915e5433a5ca2cd94e0b8206a782db" + integrity sha1-CmgfLBiRXlQzpcos2U4Lggangts= pluralize@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" + integrity sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU= pn@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= prettier@^1.11.1: version "1.11.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.1.tgz#61e43fc4cd44e68f2b0dfc2c38cd4bb0fccdcc75" + integrity sha512-T/KD65Ot0PB97xTrG8afQ46x3oiVhnfGjGESSI9NWYcG92+OUPZKkwHqGWXH2t9jK1crnQjubECW0FuOth+hxw== pretty-format@^22.4.3: version "22.4.3" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-22.4.3.tgz#f873d780839a9c02e9664c8a082e9ee79eaac16f" + integrity sha512-S4oT9/sT6MN7/3COoOy+ZJeA92VmOnveLHgrwBE3Z1W5N9S2A1QGNYiE1z75DAENbJrXXUb+OWXhpJcg05QKQQ== dependencies: ansi-regex "^3.0.0" ansi-styles "^3.2.0" @@ -3303,24 +3840,29 @@ pretty-format@^22.4.3: process-nextick-args@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= progress@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + integrity sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74= promptly@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/promptly/-/promptly-0.2.0.tgz#73ef200fa8329d5d3a8df41798950b8646ca46d9" + integrity sha1-c+8gD6gynV06jfQXmJULhkbKRtk= dependencies: read "~1.0.4" propagate@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/propagate/-/propagate-1.0.0.tgz#00c2daeedda20e87e3782b344adba1cddd6ad709" + integrity sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk= proxyquire@^1.7.9: version "1.8.0" resolved "https://registry.yarnpkg.com/proxyquire/-/proxyquire-1.8.0.tgz#02d514a5bed986f04cbb2093af16741535f79edc" + integrity sha1-AtUUpb7ZhvBMuyCTrxZ0FTX3ntw= dependencies: fill-keys "^1.0.2" module-not-found-error "^1.0.0" @@ -3329,10 +3871,12 @@ proxyquire@^1.7.9: pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= pump@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.2.tgz#3b3ee6512f94f0e575538c17995f9f16990a5d51" + integrity sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE= dependencies: end-of-stream "^1.1.0" once "^1.3.1" @@ -3340,46 +3884,57 @@ pump@^1.0.0: punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= punycode@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + integrity sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0= q@^1.1.2: version "1.5.0" resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" + integrity sha1-3QG6ydBtMObyGa7LglPunr3DCPE= q@~0.9.2: version "0.9.7" resolved "https://registry.yarnpkg.com/q/-/q-0.9.7.tgz#4de2e6cb3b29088c9e4cbc03bf9d42fb96ce2f75" + integrity sha1-TeLmyzspCIyeTLwDv51C+5bOL3U= qs@5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.0.tgz#a9f31142af468cb72b25b30136ba2456834916be" + integrity sha1-qfMRQq9GjLcrJbMBNrokVoNJFr4= qs@^6.5.1, qs@~6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + integrity sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A== qs@~5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/qs/-/qs-5.1.0.tgz#4d932e5c7ea411cca76a312d39a606200fd50cd9" + integrity sha1-TZMuXH6kEcynajEtOaYGIA/VDNk= qs@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.1.tgz#801fee030e0b9450d6385adc48a4cc55b44aedfc" + integrity sha1-gB/uAw4LlFDWOFrcSKTMVbRK7fw= qs@~6.3.0: version "6.3.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" + integrity sha1-51vV9uJoEioqDgvaYwslUMFmUCw= qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + integrity sha1-E+JtKK1rD/qpExLNO/cI7TUecjM= randomatic@^1.1.3: version "1.1.7" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" + integrity sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how== dependencies: is-number "^3.0.0" kind-of "^4.0.0" @@ -3387,6 +3942,7 @@ randomatic@^1.1.3: raw-body@~2.1.5: version "2.1.7" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.1.7.tgz#adfeace2e4fb3098058014d08c072dcc59758774" + integrity sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q= dependencies: bytes "2.4.0" iconv-lite "0.4.13" @@ -3395,6 +3951,7 @@ raw-body@~2.1.5: rc@^1.0.1, rc@^1.1.6: version "1.2.1" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95" + integrity sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU= dependencies: deep-extend "~0.4.0" ini "~1.3.0" @@ -3404,6 +3961,7 @@ rc@^1.0.1, rc@^1.1.6: rc@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/rc/-/rc-1.0.3.tgz#51bf28d21f13a9324528a9633460161ad9a39f77" + integrity sha1-Ub8o0h8TqTJFKKljNGAWGtmjn3c= dependencies: deep-extend "~0.2.5" ini "~1.3.0" @@ -3413,6 +3971,7 @@ rc@~1.0.0: read-all-stream@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/read-all-stream/-/read-all-stream-3.1.0.tgz#35c3e177f2078ef789ee4bfafa4373074eaef4fa" + integrity sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po= dependencies: pinkie-promise "^2.0.0" readable-stream "^2.0.0" @@ -3420,6 +3979,7 @@ read-all-stream@^3.0.0: read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= dependencies: find-up "^1.0.0" read-pkg "^1.0.0" @@ -3427,6 +3987,7 @@ read-pkg-up@^1.0.1: read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= dependencies: load-json-file "^1.0.0" normalize-package-data "^2.3.2" @@ -3435,12 +3996,14 @@ read-pkg@^1.0.0: read@~1.0.4: version "1.0.7" resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= dependencies: mute-stream "~0.0.4" "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.2.2: version "2.3.3" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" + integrity sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -3453,6 +4016,7 @@ read@~1.0.4: readable-stream@^1.1.8: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= dependencies: core-util-is "~1.0.0" inherits "~2.0.1" @@ -3462,6 +4026,7 @@ readable-stream@^1.1.8: readable-stream@~2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + integrity sha1-j5A0HmilPMySh4jaz80Rs265t44= dependencies: core-util-is "~1.0.0" inherits "~2.0.1" @@ -3473,6 +4038,7 @@ readable-stream@~2.0.5: readline2@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + integrity sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU= dependencies: code-point-at "^1.0.0" is-fullwidth-code-point "^1.0.0" @@ -3481,6 +4047,7 @@ readline2@^1.0.1: redent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= dependencies: indent-string "^2.1.0" strip-indent "^1.0.1" @@ -3488,18 +4055,21 @@ redent@^1.0.0: redeyed@~0.4.0: version "0.4.4" resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-0.4.4.tgz#37e990a6f2b21b2a11c2e6a48fd4135698cba97f" + integrity sha1-N+mQpvKyGyoRwuakj9QTVpjLqX8= dependencies: esprima "~1.0.4" regex-cache@^0.4.2: version "0.4.4" resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== dependencies: is-equal-shallow "^0.1.3" regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== dependencies: extend-shallow "^3.0.2" safe-regex "^1.1.0" @@ -3507,6 +4077,7 @@ regex-not@^1.0.0, regex-not@^1.0.2: registry-auth-token@^3.0.1: version "3.3.1" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006" + integrity sha1-+w0yie4Nmtosu1KvXf5mywcNMAY= dependencies: rc "^1.1.6" safe-buffer "^5.0.1" @@ -3514,42 +4085,50 @@ registry-auth-token@^3.0.1: registry-url@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= dependencies: rc "^1.0.1" remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= repeat-element@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + integrity sha1-7wiaF40Ug7quTZPrmLT55OEdmQo= repeat-string@^1.5.2, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= repeating@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= dependencies: is-finite "^1.0.0" request-progress@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-0.3.1.tgz#0721c105d8a96ac6b2ce8b2c89ae2d5ecfcf6b3a" + integrity sha1-ByHBBdipasayzossia4tXs/Pazo= dependencies: throttleit "~0.0.2" request-promise-core@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + integrity sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY= dependencies: lodash "^4.13.1" request-promise-native@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" + integrity sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU= dependencies: request-promise-core "1.1.1" stealthy-require "^1.1.0" @@ -3558,12 +4137,14 @@ request-promise-native@^1.0.5: request-replay@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/request-replay/-/request-replay-0.2.0.tgz#9b693a5d118b39f5c596ead5ed91a26444057f60" + integrity sha1-m2k6XRGLOfXFlurV7ZGiZEQFf2A= dependencies: retry "~0.6.0" request@2.67.0: version "2.67.0" resolved "https://registry.yarnpkg.com/request/-/request-2.67.0.tgz#8af74780e2bf11ea0ae9aa965c11f11afd272742" + integrity sha1-ivdHgOK/EeoK6aqWXBHxGv0nJ0I= dependencies: aws-sign2 "~0.6.0" bl "~1.0.0" @@ -3589,6 +4170,7 @@ request@2.67.0: request@2.79.0: version "2.79.0" resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" + integrity sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4= dependencies: aws-sign2 "~0.6.0" aws4 "^1.2.1" @@ -3614,6 +4196,7 @@ request@2.79.0: request@^2.51.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + integrity sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA= dependencies: aws-sign2 "~0.6.0" aws4 "^1.2.1" @@ -3641,6 +4224,7 @@ request@^2.51.0: request@^2.83.0: version "2.85.0" resolved "https://registry.yarnpkg.com/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa" + integrity sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg== dependencies: aws-sign2 "~0.7.0" aws4 "^1.6.0" @@ -3668,10 +4252,12 @@ request@^2.83.0: require-from-string@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.1.tgz#c545233e9d7da6616e9d59adfb39fc9f588676ff" + integrity sha1-xUUjPp19pmFunVmt+zn8n1iGdv8= require-uncached@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= dependencies: caller-path "^0.1.0" resolve-from "^1.0.0" @@ -3679,6 +4265,7 @@ require-uncached@^1.0.2: requireg@^0.1.5: version "0.1.7" resolved "https://registry.yarnpkg.com/requireg/-/requireg-0.1.7.tgz#9d5210d2af9c718bdaba3c2a0cefebbc846b56c5" + integrity sha1-nVIQ0q+ccYvaujwqDO/rvIRrVsU= dependencies: nested-error-stacks "~2.0.0" rc "~1.0.0" @@ -3687,38 +4274,46 @@ requireg@^0.1.5: resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= resolve-from@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" + integrity sha1-lICrIOlP+h2egKgEx+oUdhGWa1c= resolve-pkg@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/resolve-pkg/-/resolve-pkg-0.1.0.tgz#02cc993410e2936962bd97166a1b077da9725531" + integrity sha1-AsyZNBDik2livZcWahsHfalyVTE= dependencies: resolve-from "^2.0.0" resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@1.1.7, resolve@1.1.x, resolve@~1.1.0, resolve@~1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= resolve@^1.1.7: version "1.4.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86" + integrity sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q== dependencies: path-parse "^1.0.5" resolve@~0.6.1: version "0.6.3" resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46" + integrity sha1-3ZV5gufnNt699TtYpN2RdUV13UY= restore-cursor@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + integrity sha1-NGYfRohjJ/7SmRR5FSJS35LapUE= dependencies: exit-hook "^1.0.0" onetime "^1.0.0" @@ -3726,82 +4321,99 @@ restore-cursor@^1.0.1: ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== retry@0.6.1, retry@~0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/retry/-/retry-0.6.1.tgz#fdc90eed943fde11b893554b8cc63d0e899ba918" + integrity sha1-/ckO7ZQ/3hG4k1VLjMY9DombqRg= right-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + integrity sha1-YTObci/mo1FWiSENJOFMlhSGE+8= dependencies: align-text "^0.1.1" rimraf@2, rimraf@^2.2.0, rimraf@^2.2.8: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== dependencies: glob "^7.0.5" rimraf@~2.2.8: version "2.2.8" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" + integrity sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI= run-async@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + integrity sha1-yK1KXhEGYeQCp9IbUw4AnyX444k= dependencies: once "^1.3.0" rx-lite@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI= rxjs@^5.4.2: version "5.5.8" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.8.tgz#b2b0809a57614ad6254c03d7446dea0d83ca3791" + integrity sha512-Bz7qou7VAIoGiglJZbzbXa4vpX5BmTTN2Dj/se6+SwADtw4SihqBIiEa7VmTXJ8pynvq0iFr5Gx9VLyye1rIxQ== dependencies: symbol-observable "1.0.1" safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= dependencies: ret "~0.1.10" sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= dependencies: semver "^5.0.3" semver-utils@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/semver-utils/-/semver-utils-1.1.1.tgz#27d92fec34d27cfa42707d3b40d025ae9855f2df" + integrity sha1-J9kv7DTSfPpCcH07QNAlrphV8t8= "semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== semver@^2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-2.3.2.tgz#b9848f25d6cf36333073ec9ef8856d42f1233e52" + integrity sha1-uYSPJdbPNjMwc+ye+IVtQvEjPlI= semver@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== set-value@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -3811,6 +4423,7 @@ set-value@^0.4.3: set-value@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== dependencies: extend-shallow "^2.0.1" is-extendable "^0.1.1" @@ -3820,16 +4433,19 @@ set-value@^2.0.0: shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= dependencies: shebang-regex "^1.0.0" shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= shell-quote@^1.4.2: version "1.6.1" resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= dependencies: array-filter "~0.0.0" array-map "~0.0.0" @@ -3839,30 +4455,37 @@ shell-quote@^1.4.2: shelljs@^0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.6.1.tgz#ec6211bed1920442088fe0f70b2837232ed2c8a8" + integrity sha1-7GIRvtGSBEIIj+D3Cyg3Iy7SyKg= sigmund@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= signal-exit@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= slide@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== dependencies: define-property "^1.0.0" isobject "^3.0.0" @@ -3871,12 +4494,14 @@ snapdragon-node@^2.0.1: snapdragon-util@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== dependencies: kind-of "^3.2.0" snapdragon@^0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== dependencies: base "^0.11.1" debug "^2.2.0" @@ -3890,30 +4515,35 @@ snapdragon@^0.8.1: sntp@1.x.x: version "1.0.9" resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + integrity sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg= dependencies: hoek "2.x.x" sntp@2.x.x: version "2.1.0" resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" + integrity sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg== dependencies: hoek "4.x.x" sort-keys-length@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" + integrity sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg= dependencies: sort-keys "^1.0.0" sort-keys@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= dependencies: is-plain-obj "^1.0.0" source-map-resolve@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.1.tgz#7ad0f593f2281598e854df80f19aae4b92d7a11a" + integrity sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A== dependencies: atob "^2.0.0" decode-uri-component "^0.2.0" @@ -3924,36 +4554,43 @@ source-map-resolve@^0.5.0: source-map-support@^0.5.0: version "0.5.4" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.4.tgz#54456efa89caa9270af7cd624cc2f123e51fbae8" + integrity sha512-PETSPG6BjY1AHs2t64vS2aqAgu6dMIMXJULWFBGbh2Gr8nVLbCFDo6i/RMMvviIQ2h1Z8+5gQhVKSn2je9nmdg== dependencies: source-map "^0.6.0" source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= source-map@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + integrity sha1-66T12pwNyZneaAMti092FzZSA2s= dependencies: amdefine ">=0.0.4" source-map@^0.5.6, source-map@~0.5.1: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= source-map@^0.6.0, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== source-map@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= dependencies: amdefine ">=0.0.4" spawn-sync@1.0.15: version "1.0.15" resolved "https://registry.yarnpkg.com/spawn-sync/-/spawn-sync-1.0.15.tgz#b00799557eb7fb0c8376c29d44e8a1ea67e57476" + integrity sha1-sAeZVX63+wyDdsKdROih6mfldHY= dependencies: concat-stream "^1.4.7" os-shim "^0.1.2" @@ -3961,30 +4598,36 @@ spawn-sync@1.0.15: spdx-correct@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + integrity sha1-SzBz2TP/UfORLwOsVRlJikFQ20A= dependencies: spdx-license-ids "^1.0.2" spdx-expression-parse@~1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + integrity sha1-m98vIOH0DtRH++JzJmGR/O1RYmw= spdx-license-ids@^1.0.2: version "1.2.2" resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + integrity sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc= split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== dependencies: extend-shallow "^3.0.0" sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= sshpk@^1.7.0: version "1.13.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + integrity sha1-US322mKHFEMW3EwY/hzx2UBzm+M= dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -3999,14 +4642,17 @@ sshpk@^1.7.0: stack-utils@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" + integrity sha1-1PM6tU6OOHeLDKXP07OvsS22hiA= staged-git-files@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.0.tgz#1a9bb131c1885601023c7aaddd3d54c22142c526" + integrity sha1-GpuxMcGIVgECPHqt3T1UwiFCxSY= static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= dependencies: define-property "^0.2.5" object-copy "^0.1.0" @@ -4014,20 +4660,24 @@ static-extend@^0.1.1: statuses@1: version "1.3.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4= stealthy-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= stream-to-observable@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.2.0.tgz#59d6ea393d87c2c0ddac10aa0d561bc6ba6f0e10" + integrity sha1-WdbqOT2HwsDdrBCqDVYbxrpvDhA= dependencies: any-observable "^0.2.0" string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= dependencies: code-point-at "^1.0.0" is-fullwidth-code-point "^1.0.0" @@ -4036,6 +4686,7 @@ string-width@^1.0.1: string-width@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== dependencies: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" @@ -4043,20 +4694,24 @@ string-width@^2.0.0: string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= string_decoder@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + integrity sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ== dependencies: safe-buffer "~5.1.0" stringify-object@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-1.0.1.tgz#86d35e7dbfbce9aa45637d7ecdd7847e159db8a2" + integrity sha1-htNefb+86apFY31+zdeEfhWduKI= stringify-object@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.2.2.tgz#9853052e5a88fb605a44cd27445aa257ad7ffbcd" + integrity sha512-O696NF21oLiDy8PhpWu8AEqoZHw++QW6mUv0UvKZe8gWSdSvMXkiLufK7OmnP27Dro4GU5kb9U7JIO0mBuCRQg== dependencies: get-own-enumerable-property-symbols "^2.0.1" is-obj "^1.0.1" @@ -4065,86 +4720,104 @@ stringify-object@^3.2.2: stringstream@~0.0.4, stringstream@~0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + integrity sha1-TkhM1N5aC7vuGORjB3EKioFiGHg= strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= dependencies: ansi-regex "^2.0.0" strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= dependencies: ansi-regex "^3.0.0" strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= dependencies: is-utf8 "^0.2.0" strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= strip-indent@^1.0.0, strip-indent@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= dependencies: get-stdin "^4.0.1" strip-indent@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= strip-json-comments@0.1.x: version "0.1.3" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-0.1.3.tgz#164c64e370a8a3cc00c9e01b539e569823f0ee54" + integrity sha1-Fkxk43Coo8wAyeAbU55WmCPw7lQ= strip-json-comments@~1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" + integrity sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E= strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= supports-color@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-1.2.0.tgz#ff1ed1e61169d06b3cf2d588e188b18d8847e17e" + integrity sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4= supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= supports-color@^3.1.0: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= dependencies: has-flag "^1.0.0" supports-color@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" + integrity sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg== dependencies: has-flag "^3.0.0" symbol-observable@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + integrity sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ= symbol-observable@^0.2.2: version "0.2.4" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" + integrity sha1-lag9smGG1q9+ehjb2XYKL4bQj0A= symbol-tree@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" + integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY= table@^3.7.8: version "3.8.3" resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" + integrity sha1-K7xULw/amGGnVdOUf+/Ys/UThV8= dependencies: ajv "^4.7.0" ajv-keywords "^1.0.0" @@ -4156,6 +4829,7 @@ table@^3.7.8: tar-fs@^1.4.1: version "1.15.3" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.15.3.tgz#eccf935e941493d8151028e636e51ce4c3ca7f20" + integrity sha1-7M+TXpQUk9gVECjmNuUc5MPKfyA= dependencies: chownr "^1.0.1" mkdirp "^0.5.1" @@ -4165,6 +4839,7 @@ tar-fs@^1.4.1: tar-stream@^1.1.2: version "1.5.4" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.4.tgz#36549cf04ed1aee9b2a30c0143252238daf94016" + integrity sha1-NlSc8E7RrumyowwBQyUiONr5QBY= dependencies: bl "^1.0.0" end-of-stream "^1.0.0" @@ -4174,22 +4849,27 @@ tar-stream@^1.1.2: text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= throttleit@~0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf" + integrity sha1-z+34jmDADdlpe2H90qg0OptoDq8= through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= timed-out@^3.0.0: version "3.1.3" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.1.3.tgz#95860bfcc5c76c277f8f8326fd0f5b2e20eba217" + integrity sha1-lYYL/MXHbCd/j4Mm/Q9bLiDrohc= tiny-lr@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-0.2.1.tgz#b3fdba802e5d56a33c2f6f10794b32e477ac729d" + integrity sha1-s/26gC5dVqM8L28QeUsy5Hescp0= dependencies: body-parser "~1.14.0" debug "~2.2.0" @@ -4201,22 +4881,26 @@ tiny-lr@^0.2.1: tmp@0.0.28: version "0.0.28" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.28.tgz#172735b7f614ea7af39664fa84cf0de4e515d120" + integrity sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA= dependencies: os-tmpdir "~1.0.1" to-iso-string@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/to-iso-string/-/to-iso-string-0.0.2.tgz#4dc19e664dfccbe25bd8db508b00c6da158255d1" + integrity sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE= to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= dependencies: kind-of "^3.0.2" to-regex-range@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= dependencies: is-number "^3.0.0" repeat-string "^1.6.1" @@ -4224,6 +4908,7 @@ to-regex-range@^2.1.0: to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== dependencies: define-property "^2.0.2" extend-shallow "^3.0.2" @@ -4233,78 +4918,94 @@ to-regex@^3.0.1, to-regex@^3.0.2: touch@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/touch/-/touch-0.0.3.tgz#51aef3d449571d4f287a5d87c9c8b49181a0db1d" + integrity sha1-Ua7z1ElXHU8oel2Hyci0kYGg2x0= dependencies: nopt "~1.0.10" tough-cookie@>=2.3.3, tough-cookie@^2.3.3, tough-cookie@~2.3.3: version "2.3.4" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" + integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA== dependencies: punycode "^1.4.1" tough-cookie@~2.2.0: version "2.2.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.2.2.tgz#c83a1830f4e5ef0b93ef2a3488e724f8de016ac7" + integrity sha1-yDoYMPTl7wuT7yo0iOck+N4Basc= tough-cookie@~2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" + integrity sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo= dependencies: punycode "^1.4.1" tr46@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= dependencies: punycode "^2.1.0" "traverse@>=0.3.0 <0.4": version "0.3.9" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" + integrity sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk= trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= tryit@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" + integrity sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics= tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= dependencies: safe-buffer "^5.0.1" tunnel-agent@~0.4.1: version "0.4.3" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + integrity sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us= tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= dependencies: prelude-ls "~1.1.2" type-detect@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" + integrity sha1-C6XsKohWQORw6k6FBZcZANrFiCI= type-detect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" + integrity sha1-diIXzAbbJY7EiQihKY6LlRIejqI= type-detect@^4.0.0: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== type-is@~1.6.10: version "1.6.15" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" + integrity sha1-yrEPtJCeRByChC6v4a1kbIGARBA= dependencies: media-typer "0.3.0" mime-types "~2.1.15" @@ -4312,10 +5013,12 @@ type-is@~1.6.10: typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= uglify-js@^2.6: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + integrity sha1-KcVzMUgFe7Th913zW3qcty5qWd0= dependencies: source-map "~0.5.1" yargs "~3.10.0" @@ -4325,14 +5028,17 @@ uglify-js@^2.6: uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + integrity sha1-bgkk1r2mta/jSeOabWMoUKD4grc= underscore.string@~3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.2.3.tgz#806992633665d5e5fcb4db1fb3a862eb68e9e6da" + integrity sha1-gGmSYzZl1eX8tNsfs6hi62jp5to= union-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= dependencies: arr-union "^3.1.0" get-value "^2.0.6" @@ -4342,10 +5048,12 @@ union-value@^1.0.0: unpipe@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= dependencies: has-value "^0.3.1" isobject "^3.0.0" @@ -4353,16 +5061,19 @@ unset-value@^1.0.0: untildify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" + integrity sha1-F+soB5h/dpUunASF/DEdBqgmouA= dependencies: os-homedir "^1.0.0" unzip-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" + integrity sha1-uYTwh3/AqJwsdzzB73tbIytbBv4= update-notifier@^0.6.0: version "0.6.3" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-0.6.3.tgz#776dec8daa13e962a341e8a1d98354306b67ae08" + integrity sha1-d23sjaoT6WKjQeih2YNUMGtnrgg= dependencies: boxen "^0.3.1" chalk "^1.0.0" @@ -4374,48 +5085,58 @@ update-notifier@^0.6.0: urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= url-parse-lax@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= dependencies: prepend-http "^1.0.1" use@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/use/-/use-3.1.0.tgz#14716bf03fdfefd03040aef58d8b4b85f3a7c544" + integrity sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw== dependencies: kind-of "^6.0.2" user-home@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + integrity sha1-K1viOjK2Onyd640PKNSFcko98ZA= user-home@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8= dependencies: os-homedir "^1.0.0" util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= uuid@^2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + integrity sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho= uuid@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" + integrity sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g== uuid@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" + integrity sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA== validate-npm-package-license@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + integrity sha1-KAS6vnEq0zeUWaz74kdGqywwP7w= dependencies: spdx-correct "~1.0.0" spdx-expression-parse "~1.0.0" @@ -4423,6 +5144,7 @@ validate-npm-package-license@^3.0.1: verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= dependencies: assert-plus "^1.0.0" core-util-is "1.0.2" @@ -4431,16 +5153,19 @@ verror@1.10.0: w3c-hr-time@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU= dependencies: browser-process-hrtime "^0.1.2" webidl-conversions@^4.0.1, webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== websocket-driver@>=0.5.1: version "0.7.0" resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" + integrity sha1-DK+dLXVdk67gSdS90NP+LMoqJOs= dependencies: http-parser-js ">=0.4.0" websocket-extensions ">=0.1.1" @@ -4448,16 +5173,19 @@ websocket-driver@>=0.5.1: websocket-extensions@>=0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.2.tgz#0e18781de629a18308ce1481650f67ffa2693a5d" + integrity sha1-Dhh4HeYpoYMIzhSBZQ9n/6JpOl0= whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3" + integrity sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw== dependencies: iconv-lite "0.4.19" whatwg-url@^6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.4.0.tgz#08fdf2b9e872783a7a1f6216260a1d66cc722e08" + integrity sha512-Z0CVh/YE217Foyb488eo+iBv+r7eAQ0wSTyApi9n06jhcA3z6Nidg/EGvl0UFkg7kMdKxfBzzr+o9JF+cevgMg== dependencies: lodash.sortby "^4.7.0" tr46 "^1.0.0" @@ -4466,48 +5194,58 @@ whatwg-url@^6.4.0: which@^1.0.8, which@^1.1.1, which@^1.2.10, which@^1.2.9: version "1.3.0" resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" + integrity sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg== dependencies: isexe "^2.0.0" which@~1.2.1: version "1.2.14" resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" + integrity sha1-mofEN48D6CfOyvGs31bHNsAcFOU= dependencies: isexe "^2.0.0" widest-line@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-1.0.0.tgz#0c09c85c2a94683d0d7eaf8ee097d564bf0e105c" + integrity sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw= dependencies: string-width "^1.0.1" window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0= wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + integrity sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8= wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= wordwrap@~0.0.2: version "0.0.3" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= wrench@^1.5.8: version "1.5.9" resolved "https://registry.yarnpkg.com/wrench/-/wrench-1.5.9.tgz#411691c63a9b2531b1700267279bdeca23b2142a" + integrity sha1-QRaRxjqbJTGxcAJnJ5veyiOyFCo= write-file-atomic@^1.1.2: version "1.3.4" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" + integrity sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8= dependencies: graceful-fs "^4.1.11" imurmurhash "^0.1.4" @@ -4516,12 +5254,14 @@ write-file-atomic@^1.1.2: write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= dependencies: mkdirp "^0.5.1" ws@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289" + integrity sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA== dependencies: async-limiter "~1.0.0" safe-buffer "~5.1.0" @@ -4529,24 +5269,29 @@ ws@^4.0.0: xdg-basedir@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-2.0.0.tgz#edbc903cc385fc04523d966a335504b5504d1bd2" + integrity sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I= dependencies: os-homedir "^1.0.0" xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== xtend@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + integrity sha1-9+572FfdfB0tOMDnTvvWgdFDH9E= dependencies: camelcase "^1.0.2" cliui "^2.1.0" From 43894f5149e43f246fa448012b95e2546003a821 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 17 Jan 2019 14:19:04 +0100 Subject: [PATCH 1017/1021] Bump to 1.8.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 52456dc23..44d26b8ce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.8.4", + "version": "1.8.5", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 206046b27120b8420a22b5c199479c103cb970f0 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 17 Jan 2019 14:44:28 +0100 Subject: [PATCH 1018/1021] Bump to 1.8.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 44d26b8ce..71edcc7dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.8.5", + "version": "1.8.6", "description": "The browser package manager", "author": "Twitter", "license": "MIT", From 4f68fc7daa4d6f0a3dfd0da2afdbb8f0b87558af Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Thu, 17 Jan 2019 23:35:49 +0100 Subject: [PATCH 1019/1021] Update decompress-zip and bump --- package.json | 4 ++-- yarn.lock | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 71edcc7dc..4dd1bede6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.8.6", + "version": "1.8.7", "description": "The browser package manager", "author": "Twitter", "license": "MIT", @@ -26,7 +26,7 @@ "chalk": "^1.0.0", "chmodr": "^1.0.2", "configstore": "^2.0.0", - "decompress-zip": "^0.3.2", + "decompress-zip": "^0.2.2", "destroy": "^1.0.3", "findup-sync": "^0.3.0", "fs-write-stream-atomic": "1.0.8", diff --git a/yarn.lock b/yarn.lock index befc4389e..85a1a8b62 100644 --- a/yarn.lock +++ b/yarn.lock @@ -977,10 +977,10 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= -decompress-zip@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/decompress-zip/-/decompress-zip-0.3.2.tgz#f3fa2841666abce394604f4a9e8a7085c202d464" - integrity sha512-Ab1QY4LrWMrUuo53lLnmGOby7v8ryqxJ+bKibKSiPisx+25mhut1dScVBXAYx14i/PqSrFZvR2FRRazhLbvL+g== +decompress-zip@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/decompress-zip/-/decompress-zip-0.2.2.tgz#f03eaa719914868d7f5ccbdfb36930cc98cfb260" + integrity sha512-v+Na3Ck86Px7s2ix+f77pMQC3GlkxHHN+YyvnkEW7+xX5F39pcDpIV/VFvGYk8MznTFcMoPjL3XNWEJLXWoSPw== dependencies: binary "^0.3.0" graceful-fs "^4.1.3" From 45c6bfa86f6e57731b153baca9e0b41a1cc699e3 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 23 Jan 2019 22:14:48 +0100 Subject: [PATCH 1020/1021] Fix .tar.gz extract vulnerability --- lib/util/extract.js | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/util/extract.js b/lib/util/extract.js index 7ba285c14..ac04f062c 100644 --- a/lib/util/extract.js +++ b/lib/util/extract.js @@ -130,8 +130,8 @@ function extractGz(archive, dst) { return deferred.promise; } -function isSymlink(entry) { - return entry.type === 'SymbolicLink'; +function isSymlink(_, entry) { + return entry.type === 'symlink'; } function filterSymlinks(entry) { diff --git a/package.json b/package.json index 4dd1bede6..57820e547 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "test": "grunt test", "ci": "grunt travis", "coveralls": "coveralls", - "prepublish": "in-publish && echo 'You need to use \"grunt publish\" to publish bower' && false || not-in-publish", + "prepublishOnly": "in-publish && echo 'You need to use \"grunt publish\" to publish bower' && false || not-in-publish", "format": "prettier --write --single-quote --tab-width 4 '**/*.js'", "precommit": "lint-staged" }, From 67741b4bfe465ef0b816f7f2811ce6ba6d065c1a Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Wed, 23 Jan 2019 22:15:30 +0100 Subject: [PATCH 1021/1021] Bump to 1.8.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 57820e547..bab949a21 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bower", - "version": "1.8.7", + "version": "1.8.8", "description": "The browser package manager", "author": "Twitter", "license": "MIT",