Skip to content

Instantly share code, notes, and snippets.

@h2non
Created October 7, 2013 07:31
Show Gist options
  • Save h2non/6863838 to your computer and use it in GitHub Desktop.
Save h2non/6863838 to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
/**
* A very basic Node.js Bower installer replacement for download private hosted components
* @version 0.1
* @license WTFPL
*
* Usage:
* node bower-private-install.js -u username -p password -f ../bower.json
*
* TODO:
* - Add support to download specific tag/branches
* - Update packages already installed
*/
var fs = require('fs'),
https = require('https'),
exec = require('child_process').exec,
path = require('path'),
util = require('util'),
emitter = new (require('events')).EventEmitter();
function echo(message) {
console.log(message);
}
function parseArgs(args) {
var i, value, opts = {};
for (i = 0; i < args.length; i += 1) {
if (args[i][0] == '-') {
if (args[i] === '-h') {
opts.h = true;
} else {
value = args[i + 1];
if (value && value[0] !== '-') {
opts[args[i].substring(1)] = util.format(value);
i += 1;
}
}
}
}
return opts;
}
function each(obj, callback) {
var i;
if (obj == null || typeof callback !== 'function') {
return false;
}
if (obj.constructor === Array) {
for (i = 0; i < obj.length; i += 1) {
callback(obj[i], i, obj);
}
} else {
for (i in obj) {
callback(i, obj[i], obj);
}
}
}
function deleteFolder(path) {
if (fs.existsSync(path)) {
fs.readdirSync(path).forEach(function (file,index) {
var curPath = path + "/" + file;
if(fs.statSync(curPath).isDirectory()) { // recurse
deleteFolder(curPath);
} else { // delete file
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(path);
}
}
function escapeChars(string) {
return string.replace(/\$/g, '\\$');
}
// Used by exec to print the result of executing a subprocess.
function puts(error, stdout, stderr) {
if (error) {
emitter.emit('error', error);
} else {
emitter.emit('info', stdout.trim());
if (stderr) {
emitter.emit('error', stderr.trim());
}
}
}
function gitClone(url, dir, callback) {
exec(util.format('git clone %s %s', url, dir), callback);
}
function getBowerPath(file) {
file = path.normalize(file || __dirname + '/../bower.json');
if (file === 'bower.json') {
file = './' + file;
}
return file;
}
function help() {
echo([
' Bower installer script', '',
' options: ',
' -u <username>',
' -p <password>',
' -f <bower.json> Path to bower.json file',
' -h Show this help', '',
' Usage: ',
' $ node bower-private-install.js -u username -p mypass -f myproject/bower.json', '',
' $ bower install', '',
' Note that Git SCM is required!'
].join('\n'));
process.exit(0);
}
emitter
.on('info', console.info)
.on('error', console.error)
.on('exit', function(err) {
console.error(err);
process.exit(1);
});
var opts = parseArgs(process.argv.slice(2)),
user = opts.u,
password = opts.p,
bowerFile = getBowerPath(opts.f),
installPath = path.dirname(bowerFile) + '/',
bowerRc, bower;
opts.h && help();
if (!user || !password) {
emitter.emit('exit', 'Missing required arguments: username or password are required');
}
if (!fs.existsSync(bowerFile)) {
emitter.emit('exit', 'Bower file do not exists');
}
try {
bower = require(bowerFile);
if (fs.existsSync(path.dirname(bowerFile) + '/.bowerrc')) {
bowerRc = JSON.parse(fs.readFileSync(path.dirname(bowerFile) + '/.bowerrc'));
if (bowerRc.directory) {
installPath += bowerRc.directory;
} else {
installPath += 'src/bower_components';
}
}
} catch (e) {
emitter.emit('exit', 'Invalid Bower JSON: ' + e);
}
if (!fs.existsSync(installPath)) {
fs.mkdirSync(installPath);
}
echo('Cloning dependencies...');
each(bower.dependencies, function (name, uri, obj) {
if (/^(http|git|https):/.test(uri)) {
uri = uri.split('://');
var protocol = uri[0],
path = uri[1],
url = escapeChars(protocol + '://' + user.trim() + ':' + password.trim() + '@' + path).split('#')[0],
installDir = installPath + '/' + name;
if (fs.existsSync(installDir)) {
deleteFolder(installDir);
emitter.emit('info', 'Package "' + name + '"" already exists. Force updating ');
}
gitClone(url, installDir, function (error) {
puts.apply(null, arguments);
if (!error) {
echo('Web components "' + name + '" installed in ' + installDir);
}
});
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment