Created
October 7, 2013 07:31
-
-
Save h2non/6863838 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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