Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

executable file 238 lines (185 sloc) 4.817 kB
#!/usr/bin/env node
/**
* Module dependencies.
*/
var program = require('commander')
, component = require('..')
, fs = require('fs')
, exists = fs.existsSync
, utils = component.utils
, log = utils.log
, error = utils.error
, url = require('url')
, path = require('path')
, resolve = path.resolve;
// options
program
.usage('[name ...]')
.option('-d, --dev', 'install development dependencies')
.option('-r, --remotes <urls>', 'remotes to try installing from')
.option('-o, --out <dir>', 'output components to the given <dir>')
.option('-f, --force', 'force installation even if previously installed')
// examples
program.on('--help', function(){
console.log(' Examples:');
console.log();
console.log(' # install deps in ./component.json');
console.log(' $ component install');
console.log();
console.log(' # install a single component');
console.log(' $ component install component/tip');
console.log();
console.log(' # install several components');
console.log(' $ component install component/tip component/popover');
console.log();
console.log(' # shell brace expansion ftw');
console.log(' $ component install component/{tip,popover,dialog}');
console.log();
console.log(' # install a specific tag / sha');
console.log(' $ component install component/tip@8bf1ffc3f');
console.log();
console.log(' # install regular & development deps in .');
console.log(' $ component install -d');
console.log();
});
// parse argv
program.parse(process.argv);
// pkgs
var pkgs = program.args;
// install from ./component.json
var local = 0 == pkgs.length;
// component.json required
if (local && !exists('component.json')) utils.fatal('missing component.json');
// read json
var conf = loadConfig();
// install from ./component.json
if (local) {
if (conf.dependencies) {
pkgs = normalize(conf.dependencies);
}
if (conf.development && program.dev) {
pkgs = pkgs.concat(normalize(conf.development));
}
if (conf.local) {
conf.local.forEach(function(pkg){
try {
var deps = component.dependenciesOf(pkg, conf.paths);
deps.map(normalize).forEach(function(deps){
pkgs = pkgs.concat(deps);
});
} catch (err) {
utils.fatal(err.message);
}
});
}
}
// save to ./component.json
if (!local) {
conf.dependencies = conf.dependencies || {};
pkgs.forEach(function(pkg){
pkg = parsePackage(pkg);
conf.dependencies[pkg.name] = pkg.version || '*';
});
saveConfig();
}
// implicit remotes
conf.remotes = conf.remotes || [];
// explicit remotes
if (program.remotes) {
conf.remotes = program.remotes.split(',').concat(conf.remotes);
}
// default to github
conf.remotes.push('https://raw.github.com');
// install
console.log();
pkgs.forEach(function(pkg){
pkg = parsePackage(pkg);
install(pkg.name, pkg.version || 'master');
});
// parse package identifier
function parsePackage(pkg) {
var parts = pkg.split('@');
return {
name: parts.shift(),
version: parts.shift()
};
}
// map deps to args
function normalize(deps) {
return Object.keys(deps).map(function(name){
return name + '@' + deps[name];
});
}
// reporter
function report(pkg, options) {
options = options || {};
if (pkg.inFlight) return;
log('install', pkg.name + '@' + pkg.version);
pkg.on('error', function(err){
if (404 != err.status) utils.fatal(err.stack);
if (err.fatal) {
error(err.message);
process.exit(1);
}
});
pkg.on('dep', function(dep){
log('dep', dep.name + '@' + dep.version);
report(dep, options);
});
pkg.on('exists', function(dep){
log('exists', dep.name + '@' + dep.version);
});
pkg.on('file', function(file){
log('fetch', pkg.name + ':' + file);
});
pkg.on('end', function(){
log('complete', pkg.name);
});
}
// padding
process.on('exit', function(){
console.log();
});
/**
* Install package `name` at the given `version`
* from all specified remotes.
*
* @param {String} name
* @param {String} version
* @api private
*/
function install(name, version) {
// kick off installation
var pkg = component.install(name, version, {
dest: program.out,
force: program.force,
dev: program.dev,
remotes: conf.remotes
});
report(pkg);
// TODO: add callback
pkg.install();
}
/**
* Read / create ./component.json.
*
* @return {Object}
* @api private
*/
function loadConfig() {
var path = resolve('component.json');
if (exists('component.json')) {
return require(path);
} else {
return {};
}
}
/**
* Save configuration.
*
* @api private
*/
function saveConfig() {
var path = resolve('component.json');
fs.writeFileSync(path, JSON.stringify(conf, null, 2));
}
Jump to Line
Something went wrong with that request. Please try again.