Skip to content

Commit

Permalink
Merge pull request #2062 from contolini/update-save
Browse files Browse the repository at this point in the history
Add `bower update --save` functionality
  • Loading branch information
sheerun committed Nov 28, 2015
2 parents 107ad1d + 0eadbef commit 8fcbd36
Show file tree
Hide file tree
Showing 3 changed files with 244 additions and 10 deletions.
4 changes: 3 additions & 1 deletion lib/commands/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
21 changes: 21 additions & 0 deletions lib/core/Project.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 () {
Expand Down
229 changes: 220 additions & 9 deletions test/commands/update.js
Original file line number Diff line number Diff line change
@@ -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({
Expand Down Expand Up @@ -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');
};
Expand All @@ -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 () {
Expand Down Expand Up @@ -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': {
Expand Down

0 comments on commit 8fcbd36

Please sign in to comment.