Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

executable file 345 lines (287 sloc) 6.62 kb
#!/usr/bin/env node
/**
* Module dependencies.
*/
var asset = require('../')
, exec = require('child_process').exec
, tty = require('tty')
, fs = require('fs');
/**
* Arguments.
*/
var args = process.argv.slice(2);
/**
* Assets to install.
*/
var assets = [];
/**
* Default options.
*/
var options = {
out: 'public'
, compress: false
};
/**
* Usage information.
*/
var usage = [
''
, ' Usage: asset [command] [options]'
, ''
, ' Commands:'
, ''
, ' install <name ...> installs the given asset <name ...>'
, ' search [query] search available assets with optional [query]'
, ' info <name ...> display verbose information for the given asset <name ...>'
, ' none install dependencies from ./assets.json'
, ''
, ' Options:'
, ''
, ' -c, --compress compress assets'
, ' -o, --out <dir> output directory defaulting to ./public'
, ' -V, --version output program version'
, ' -h, --help display help information'
, ''
].join('\n');
/**
* Configuration.
*/
var config = readJSON(process.cwd() + '/.asset')
|| readJSON(process.env.HOME + '/.asset')
|| {};
/**
* Repository.
*/
var repo = readJSON(process.env.HOME + '/.assets')
|| readJSON(__dirname + '/../assets.json')
|| {};
// merge config
Object.keys(config).forEach(function(key){
options[key] = config[key];
});
// parse arguments
var arg;
while (args.length) {
arg = args.shift();
switch (arg) {
case '-h':
case '--help':
case 'help':
console.log(usage);
process.exit();
break;
case '-V':
case '--version':
console.log(asset.version);
process.exit();
break;
case '-c':
case '--compress':
options.compress = true;
break;
case 'install':
// ignore
break;
case 'search':
console.log();
search(args.shift());
console.log();
process.exit();
break;
case 'info':
console.log();
while (args.length) {
info(args.shift());
console.log();
}
process.exit();
break;
case '-o':
case '--out':
options.out = required(arg);
break;
default:
if (~arg.indexOf('/')) {
options.out = arg;
} else {
assets.push(arg);
}
}
}
// parse the asset strings or ./assets.json
if (assets.length) {
assets = assets.map(parse);
} else {
assets = assetsFromObject(readJSON('assets.json'));
}
// ensure we have assets
if (!assets.length) abort('asset <name ...> required');
// install the assets
console.log();
mkdir(options.out, function(err){
if (err) abort(err.message);
install(assets);
});
process.on('exit', function(){ console.log(); });
/**
* Install assets from JSON `obj`.
*
* @param {Object} obj
*/
function assetsFromObject(obj) {
var arr = [];
for (var asset in obj) {
arr.push({ name: asset, version: obj[asset], compress: options.compress });
}
return arr;
}
/**
* Install the given `assets`.
*
* @param {Array} assets
*/
function install(assets) {
var install = asset.install(assets, repo, options.out);
install.on('unknown', function(asset){
abort('unregistered asset ' + asset.name);
});
install.on('install', function(asset){
log('install', name(asset));
});
install.on('download', function(asset, res){
log('download', name(asset));
});
install.on('file download', function(asset, file, res){
log('download', name(asset) + ' ' + file);
});
install.on('dependency', function(asset, dep){
log('dependency', name(dep));
});
install.on('complete', function(asset, path){
log('complete', name(asset) + ' ' + path);
});
install.on('complete files', function(asset, files){
log('complete', name(asset) + ' ' + files.length + ' files');
});
install.on('error', function(err){
abort(err.message);
});
}
/**
* Display info for asset `name`.
*
* @param {String} name
*/
function info(name){
var asset = repo[name];
if (!asset) abort('failed to lookup asset "' + name + '"');
log('name', name);
log('description', asset.description);
log('url', asset.url);
if (asset.version) log('version', asset.version);
if (asset.filename) log('filename', asset.filename);
if (asset.dependencies) log('dependencies', Object.keys(asset.dependencies).join(', '));
}
/**
* Search using the given `query` string.
*
* @param {String} query
*/
function search(query) {
var size = Array.isArray(tty.getWindowSize()) ? tty.getWindowSize().reverse() : process.stdout.getWindowSize()
, padding = 30
, width = size.shift() - padding
, height = size.shift();
asset.search(repo, query, function(name, entry){
var desc = entry.description;
if (desc.length > width) {
desc = desc.substr(0, width - 3) + '...';
}
desc = desc
? '\033[90m: ' + desc + '\033[0m'
: '';
log(name, entry.version + ' ' + desc);
});
}
/**
* Log key / val.
*
* @param {String} key
* @param {String} val
*/
function log(key, val) {
var width = 15
, len = key.length;
if (len < width) key = Array(width - len).join(' ') + key;
console.log(' \033[90m%s :\033[0m \033[36m%s\033[0m', key, val);
}
/**
* Normalize `asset` string, returning an object
* representation of what is to be installed.
*
* Syntax:
*
* <name> ['@' version] [':' 'compress']
*
* @param {String} asset
* @return {Object}
*/
function parse(asset) {
var captures = asset.match(/([^:@]+)(?:@([^:]+))?((:\w+)*)/)
, modifiers = captures[3].split(':').slice(1);
return {
name: captures[1]
, version: captures[2]
, compress: ~modifiers.indexOf('compress') || options.compress
};
}
/**
* Require argument for `flag`.
*
* @param {String} flag
* @return {String}
*/
function required(flag) {
if (args.length) return args.shift();
abort(flag + ' argument required');
}
/**
* Abort with `msg`.
*
* @param {String} msg
*/
function abort(msg) {
console.error(' \033[31m%s\033[0m', msg);
process.exit(1);
}
/**
* Return asset name/
*
* @param {Object} asset
* @return {String}
*/
function name(asset) {
return asset.name + '@' + asset.version;
}
/**
* Attempt to read config json at `path`.
*
* @param {String} path
* @return {Object}
*/
function readJSON(path) {
try {
return JSON.parse(fs.readFileSync(path, 'utf8'));
} catch (err) {
// ignore
}
}
/**
* Mkdir -p.
*
* @param {String} path
* @param {Function} fn
*/
function mkdir(path, fn) {
exec('mkdir -p ' + path, fn);
}
Jump to Line
Something went wrong with that request. Please try again.