Finished switching to bower.json

This commit is contained in:
Mat Scales
2013-04-05 16:56:20 +01:00
parent 3dfd95b1dd
commit ec6df96a85
12 changed files with 177 additions and 48 deletions

View File

@@ -12,7 +12,6 @@ var command;
var options;
var shorthand;
var input = process.argv;
var cmdList = Object.keys(bower.commands);
var nodeVer = process.version;
var reqVer = pkg.engines.node;
var errors = [];
@@ -51,6 +50,9 @@ bower.commands[bower.command || 'help'].line(input)
.on('end', function (data) {
if (data) process.stdout.write(data);
})
.on('warn', function (warning) {
process.stdout.write(template('warn', { message: warning }, true));
})
.on('error', function (err) {
if (options.verbose) throw err;
process.stdout.write(template('error', { message: err.message }, true));

View File

@@ -32,6 +32,7 @@ module.exports = function (paths, options) {
manager
.on('data', emitter.emit.bind(emitter, 'data'))
.on('warn', emitter.emit.bind(emitter, 'warn'))
.on('error', emitter.emit.bind(emitter, 'error'))
.on('resolve', function (resolved) {
// Handle save/save-dev

View File

@@ -27,6 +27,7 @@ function linkSelf(emitter) {
manager
.on('error', emitter.emit.bind('error'))
.on('warn', emitter.emit.bind('warn'))
.once('loadJSON', function () {
var destPath = path.join(config.links, manager.name);
var srcPath = process.cwd();

View File

@@ -187,6 +187,7 @@ module.exports = function (options) {
};
manager
.on('data', emitter.emit.bind(emitter, 'data'))
.on('warn', emitter.emit.bind(emitter, 'warn'))
.on('error', emitter.emit.bind(emitter, 'error'))
.on('list', function (packages) {
// console.log(packages);

View File

@@ -31,6 +31,7 @@ module.exports = function (names, options) {
options = options || {};
manager.on('data', emitter.emit.bind(emitter, 'data'));
manager.on('warn', emitter.emit.bind(emitter, 'warn'));
manager.on('error', emitter.emit.bind(emitter, 'error'));
var resolveLocal = function () {

View File

@@ -29,6 +29,7 @@ module.exports = function (names, options) {
});
manager.on('data', emitter.emit.bind(emitter, 'data'));
manager.on('warn', emitter.emit.bind(emitter, 'warn'));
manager.on('error', emitter.emit.bind(emitter, 'error'));
var installURLS = function (err, arr) {
@@ -50,6 +51,7 @@ module.exports = function (names, options) {
manager
.on('data', emitter.emit.bind(emitter, 'data'))
.on('warn', emitter.emit.bind(emitter, 'warn'))
.on('error', emitter.emit.bind(emitter, 'error'))
.on('resolve', function (resolved) {
// Handle save

View File

@@ -11,6 +11,7 @@
// - resolve: fired when deps resolved (with a true/false indicating success or error)
// - error: fired on all errors
// - data: fired when trying to output data
// - warn: fired when a discouraged but not fatal situation arises
// - end: fired when finished installing
// ==========================================
@@ -25,7 +26,7 @@ var _ = require('lodash');
var Package = require('./package');
var UnitWork = require('./unit_work');
var config = require('./config');
var fileExists = require('../util/file-exists');
var fallback = require('../util/fallback');
var template = require('../util/template');
var prune = require('../util/prune');
@@ -47,30 +48,17 @@ Manager.prototype = Object.create(events.EventEmitter.prototype);
Manager.prototype.constructor = Manager;
Manager.prototype.loadJSON = function () {
var json = path.join(this.cwd, config.json);
fileExists(json, function (exists) {
if (!exists) {
// If the json does not exist, assume one
this.json = {
name: path.basename(this.cwd),
version: '0.0.0'
},
this.name = this.json.name;
this.version = this.json.version;
return this.emit('loadJSON');
fallback(this.cwd, [config.json, 'component.json'], function (file) {
if (file !== null) {
if (file !== config.json) {
this.emit('warn', 'Using deprecated "component.json". Please use "bower.json" instead');
}
return this.readJSON(path.join(this.cwd, file));
}
fs.readFile(json, 'utf8', function (err, json) {
if (err) return this.emit('error', err);
try {
this.json = JSON.parse(json);
} catch (e) {
return this.emit('error', new Error('There was an error while reading the ' + config.json + ': ' + e.message));
}
this.name = this.json.name;
this.version = this.json.version;
this.emit('loadJSON', json.slice(-1) === '\n');
}.bind(this));
this.createJSON();
return this.emit('loadJSON');
}.bind(this));
return this;
@@ -178,6 +166,30 @@ Manager.prototype.resolveFromJson = function () {
};
// Private
Manager.prototype.createJSON = function () {
// If the json does not exist, assume one
this.json = {
name: path.basename(this.cwd),
version: '0.0.0'
},
this.name = this.json.name;
this.version = this.json.version;
};
Manager.prototype.readJSON = function (filename) {
fs.readFile(filename, 'utf8', function (err, json) {
if (err) return this.emit('error', err);
try {
this.json = JSON.parse(json);
} catch (e) {
return this.emit('error', new Error('There was an error while reading the ' + config.json + ': ' + e.message));
}
this.name = this.json.name;
this.version = this.json.version;
this.emit('loadJSON', json.slice(-1) === '\n');
}.bind(this));
};
Manager.prototype.getDeepDependencies = function () {
var result = {};
@@ -361,4 +373,4 @@ Manager.prototype.getDependencyList = function () {
}.bind(this), this.emit.bind(this, 'list', packages));
};
module.exports = Manager;
module.exports = Manager;

View File

@@ -36,6 +36,7 @@ var source = require('./source');
var template = require('../util/template');
var readJSON = require('../util/read-json');
var fileExists = require('../util/file-exists');
var fallback = require('../util/fallback');
var isRepo = require('../util/is-repo');
var git = require('../util/git-cmd');
var UnitWork = require('./unit_work');
@@ -117,6 +118,7 @@ var Package = function (name, endpoint, manager) {
if (this.manager) {
this.on('data', this.manager.emit.bind(this.manager, 'data'));
this.on('warn', this.manager.emit.bind(this.manager, 'warn'));
this.on('error', function (err, origin) {
// Unlock the unit of work automatically on error (only if the error is from this package)
if (!origin && this.unitWork.isLocked(this.cacheName)) this.unitWork.unlock(this.cacheName, this);
@@ -318,35 +320,27 @@ Package.prototype.uninstall = function () {
};
// Private
Package.prototype.findJSON = function () {
fallback(this.path, [config.json, 'bower.json', 'component.json'], function (name) {
if (name) {
if (name === 'component.json') {
this.emit('warn', 'Package ' + this.name + ' is still using the deprecated "component.json" file');
}
this.localConfig.json = name;
}
this.emit('readLocalConfig');
}.bind(this));
};
Package.prototype.readLocalConfig = function () {
if (this.localConfig) return this.emit('readLocalConfig');
var checkExistence = function () {
fileExists(path.join(this.path, this.localConfig.json), function (exists) {
if (!exists) {
this.localConfig.json = 'bower.json';
// For backwards compatibility with old packages we will fallback to component.json if bower.json does not exist
fileExists(path.join(this.path, this.localConfig.json), function (exists) {
if (!exists) {
this.localConfig.json = 'component.json';
this.emit('data', template('warn', { message: 'Package ' + this.name + ' is still using the deprecated "component.json" file' }, true));
}
this.emit('readLocalConfig');
}.bind(this));
} else {
this.emit('readLocalConfig');
}
}.bind(this));
}.bind(this);
fs.readFile(path.join(this.path, '.bowerrc'), function (err, file) {
// If the local .bowerrc file do not exists then we check if the
// json specific in the config exists (if not, we fallback to bower.json)
if (err) {
this.localConfig = { json: config.json };
checkExistence();
this.findJSON();
} else {
// If the local .bowerrc file exists, we read it and check if a custom json file
// is defined. If not, we check if the global config json file exists (if not, we fallback to bower.json)
@@ -358,7 +352,7 @@ Package.prototype.readLocalConfig = function () {
if (!this.localConfig.json) {
this.localConfig.json = config.json;
return checkExistence();
return this.findJSON();
}
this.emit('readLocalConfig');

32
lib/util/fallback.js Normal file
View File

@@ -0,0 +1,32 @@
// ==========================================
// BOWER: fallback
// ==========================================
// Copyright 2012 Twitter, Inc
// Licensed under The MIT License
// http://opensource.org/licenses/MIT
// ==========================================
// A function that takes a list of files and returns the first one that exists
// If none exists, return null
var fileExists = require('./file-exists');
var path = require('path');
var fallback = function (baseDir, files, callback) {
if (!Array.isArray(files) || files.length === 0) {
return callback(null);
}
var file = files.shift();
fileExists(path.join(baseDir, file), function (exists) {
if (!exists) {
return fallback(baseDir, files, callback);
} else {
return callback(file);
}
});
};
module.exports = fallback;

View File

@@ -33,4 +33,4 @@ module.exports = function (command, args, options, emitter) {
});
return cp;
};
};

View File

@@ -86,6 +86,44 @@ describe('manager', function () {
manager.resolve();
});
it('Should fallback to component.json if not overriden and bower.json does not exist', function (next) {
var manager = new Manager([]);
manager.cwd = __dirname + '/assets/project-old';
manager.on('resolve', function () {
assert.deepEqual(manager.dependencies['jquery-pjax'][0].version, '1.0.0');
assert.notEqual(manager.dependencies.jquery[0].version, null);
next();
});
manager.on('error', function (err) {
throw err;
});
manager.resolve();
});
it('Should emit a warning when falling back to component.json', function (next) {
var manager = new Manager([]);
var warning = '';
manager.cwd = __dirname + '/assets/project-old';
manager.on('resolve', function () {
assert(/deprecated "component.json"/.test(warning));
next();
});
manager.on('warn', function (message) {
warning = message;
});
manager.on('error', function (err) {
throw err;
});
manager.resolve();
});
it('Should override packages at the project level', function (next) {
var manager = new Manager([]);
manager.cwd = __dirname + '/assets/project-static';

View File

@@ -630,4 +630,49 @@ describe('package', function () {
pkg.resolve();
});
it('Should display a warning if a dependency is using the old component.json file', function (next) {
var pkg = new Package('project', __dirname + '/assets/project');
var warn = [];
pkg.on('resolve', function () {
// jQuery will get resolved twice as it is a dependency of both explicit dependencies.
assert.equal(warn.length, 4);
next();
});
pkg.on('warn', function (message) {
if (/deprecated "component.json"/.test(message)) {
warn.push(message);
}
});
pkg.on('error', function (err) {
throw err;
});
pkg.resolve();
});
it('Should not display a warning for dependencies using the new bower.json file', function (next) {
var pkg = new Package('project-new-deps', __dirname + '/assets/project-new-deps');
var warn = [];
pkg.on('resolve', function () {
assert.equal(warn.length, 0);
next();
});
pkg.on('warn', function (message) {
if (/deprecated "component.json"/.test(message)) {
warn.push(message);
}
});
pkg.on('error', function (err) {
throw err;
});
pkg.resolve();
});
});