niman
Version:
A Flexible Installation Manager for Node JS ( NVM plus )
940 lines (846 loc) • 46.7 kB
JavaScript
;
// this file is supposed to run under at least version 6.x.x of Node
// so instead to try to keep backward compatibility we decided to use a two stage bootloader strategy
// which nomatter which current version of node you have installed will start with a very small
// stage one that is where we'll keep backward compatibility, then run the app usin an own version
// of Node specified in the first sage and eventually download it if not installed already
//
// ----------------------------------- --------------------------- ---------------------------------
let none
, nodeRequired = []
, iojsRequired = []
, app // express app
, server // express server
, cmd
, files
, main
, symLinkCommand
, findNodeCommand
, activateCommand
, archPrfx
, activateArgs
, symLinkArgs
;
// ----------------------------------- --------------------------- ---------------------------------
const ND = undefined
, info = {} // to keep in sync, we now fill this from package.json
, _APP = {} // storing global references here ..
, Fs = require ('fs')
, Url = require ('url')
, Path = require ('path')
, w4it = require ('w4it')
, Http = require ('https')
, HttpD = require ('http-d')
, LeftPad = require ('left_pad')
, ChildProc = require ('child_process')
, Exec = ChildProc.execFileSync
, NIM = 'nim'
, _CON = console
, pathSep = Path.sep
, strFormat = function () {
var s = arguments[0]
, i = 1
;
return s.replace(/%((%)|s|d|i)/g, function (m) {
var val = arguments[i];
switch (m) {
case '%i':
val = parseInt (val);
break;
case '%d':
val = parseFloat (val);
break;
}
i++;
return val;
});
}
, qtd = (s) => { return "'"+s+"'"; }
, _cout = (t,...a) => { Function.apply.call(t ,_CON,a); }
, _log = (...a) => { _cout(_CON.log ,...a); }
, _wrn = (...a) => { _cout(_CON.warn ,...a); }
, _err = (...a) => { _cout(_CON.error ,...a); }
, toLocal = (s) => { return s.replace(new RegExp('/', 'g'),'\\'); }
, validArchs = { 'win' : ['x86','x64']
, 'arm' : ['arm64','arm6l','arm7l']
, 'darwin': ['x64']
}
, validArchPaths = { 'win' : [ ['','x86','win-x86']
, ['x64','win-x64'] ]
, 'arm' : [ [''],[''],[''] ]
, 'darwin': [ [''] ]
}
, nodeFolder = './inuse/' // default location
, nodeExtens = '.exe'
, nodeStoreDir = './dist/'
, nodeCacheFile = 'node_dist.json'
, nodeCacheList = 'node_dist.lst'
, iojsCacheFile = 'iojs_dist.json'
, iojsCacheList = 'iojs_dist.lst'
, nodeDistBase = 'https://nodejs.org/dist/'
, iojsDistBase = 'https://iojs.org/dist/'
///, npmDistBase = 'https://codeload.github.com/npm/npm/zip/'
, npmDistBase = 'https://registry.npmjs.org/npm/-/npm-' // + .tgz
, toLocalOs = (s) => {
switch (isOS){
case 'x86':
case 'x64':
return s.replace(/\//gi,'\\');
default:
return s;
}
}
, copyDirSync = (srcDir,trgDir) => {
Exec("cmd",["/C","xcopy","/E","/J","/I",toLocalOs(srcDir),toLocalOs(trgDir)],{ stdio: 'inherit' } );
}
, copyFileSync = (srcFile,trgFile) => {
Exec("cmd",["/C","copy",toLocalOs(srcFile),toLocalOs(trgFile)],{ stdio: 'inherit' } );
}
, removeDirSync = (dirName) => {
Exec("cmd",["/C","RMDIR","/S","/Q",toLocalOs(dirName)],{ stdio: 'inherit' } );
}
, normalizeVer = (ver) => { return (ver ? ver[0]=='v' ? ver : ver[0]=='V'? 'v'+ver.substring(1) : 'v'+ver : 'v_'); }
, normalizeArch = (arch) => { return archPrfx+ (arch || myArch); }
, usage = () => {
_.log('Usage:');
_.log('');
_.log(' '+NIM+' arch : Show whichever arch node is using.' );
_.log(' '+NIM+' install <version> [arch] : Version can be any Node version either from NodeJs of IOJS' );
_.log(' see: http://cloned2k16.github.io/jsNVM/' );
_.log(' '+NIM+' list [available | all] : List the current installation list or the availables to download' );
_.log(' '+NIM+' remove <version> [arch] : Uninstall specified version' );
_.log(' '+NIM+' use <version> [arch] : Switch to the specified version and optionally arch' );
_.log(' '+NIM+' root [path] : Set or Show where all the versions are stored into' );
_.log(' '+NIM+' version : Shows the version of this tool' );
_.log('');
_.log(' '+NIM+' on|off : Switches NIM version as primary (global) version' );
_.log(' '+NIM+' gui : Start an useful graphical interface (web) ' );
}
, downloadFiles = (url,dir,list
,npmUrl,npmVer) => {
try {
var rHead = Http.head(url,(res) => {
if ([200,301,302,304,307,308].indexOf(res.statusCode) >= 0) {
var i
, inProg = []
, inProgIdx = 0
;
//_.log(url,res.headers);
res.on('data', (chunk) => { _.log('@',chunk.toString()); });
try {
var pos =dir.lastIndexOf('/')
, vDir=dir.substring(0,pos)
;
try { Fs.mkdirSync(vDir); }catch (_e) {}
Fs.mkdirSync(dir);
}
catch (e){ if (e.code!='EEXIST'){ _.err(e); return -1; } }
for (i in list) {
var fName= list[i]
, fPath = dir+'/'+fName
;
_.log('downloading.. ',url+'/'+fName,' into: ',fPath);
if (Fs.existsSync(fPath)){
inProg[inProgIdx]=false;
continue;
}
inProg[inProgIdx]=true;
var
file = Fs.createWriteStream(fPath)
, endErr = ((ii,p) => { return (err) => { _.log('endErr',err,ii); Fs.unlink(p); inProg[ii]=false; }})(i,fPath)
, req = Http.get(url+'/'+fName, ((f,p,ii) => { return (res) =>{
if (res.statusCode !== 200) {
Fs.unlink(p);
return _.err(url+' status was ' + res.statusCode);
}
res.pipe(f);
f.on('finish', ((ii,ff) => { return () => {
let fn=list[ii];
_.log(fn,' done.');
ff.close();
if (fn.startsWith('iojs')) {
//_.log('link to: ',dir+'/'+fn.replace('iojs','node'));
Fs.linkSync(dir+'/'+fn, dir+'/'+fn.replace('iojs','node'))
}
inProg[ii]=false; }})(ii,f) );
}})(file,fPath,inProgIdx++));
req.on ('error', (err) => { endErr(err); });
file.on('error', (err) => { endErr(err); });
}
var fName = npmVer//+'.zip'
, fPath = dir+'/'+fName
;
if (!Fs.existsSync(fPath)){
inProg[inProgIdx]=true;
_.log('downloading.. ',npmUrl+'v'+npmVer,' into: ',fPath);
var file = Fs.createWriteStream(fPath)
, endErr = ((ii,p) => { return (err) => { _.log('endErr',err,ii); Fs.unlink(p); inProg[ii]=false; }})(i,fPath)
//, req = Http.get(npmUrl+'v'+npmVer, ((f,p,ii) => { return (res) =>{
, req = Http.get(npmUrl+npmVer, ((f,p,ii) => { return (res) =>{
if (res.statusCode !== 200) {
Fs.unlink(p);
return _.err('NPM status was ' + res.statusCode);
}
res.pipe(f);
f.on('finish', ((ii,ff) => { return () => {
let fn=fName;
_.log(fn,' done.');
ff.close();
inProg[ii]=false;
}})(ii,f) );
}})(file,fPath,inProgIdx++));
req.on ('error', (err) => { endErr(err); });
file.on('error', (err) => { endErr(err); });
}
//_.log('we have',inProgIdx,'downloads',inProg);
w4it.enableAnimation();
w4it.done ( () => {
for (i=0; i<inProgIdx; i++) { if (inProg[i]) return false; }
return true;
}
, () =>{
var npmDir = dir +'/node_modules'
, npmTempPath = npmDir +'/package'
, npmPath = npmDir +'/npm'
;
_.log('DONE');
_.log('unzipping NPM in ',npmTempPath)
try {
if (Fs.existsSync(npmPath))
Exec("cmd" ,[ "/C","RMDIR","/S","/Q", toLocalOs(npmPath) ] ,{ stdio: 'inherit' } )
if (Fs.existsSync(npmTempPath))
Exec("cmd" ,[ "/C","RMDIR","/S","/Q", toLocalOs(npmTempPath) ] ,{ stdio: 'inherit' } )
}
catch(ee){
//_.err("error:",ee.message);
}
//Exec("xtract",[ fPath, npmDir ] ,{ stdio: 'inherit' } )
Fs.mkdirSync(npmDir)
//var newDir=npmDir.replace(/\//g,'\\')
//_.log("mkdir: "+newDir)
//Exec("md" ,[newdir] , { stdio: 'inherit' } )
Exec("tar",[ '-xf', fPath, '-C', npmDir ] , { stdio: 'inherit' } )
Fs.renameSync (npmTempPath,npmPath);
copyFileSync (npmPath+'/bin/npm' ,dir+'/npm');
copyFileSync (npmPath+'/bin/npm.cmd' ,dir+'/npm.cmd');
return 0;
});
}
else {
return res.statusCode;
}
}).on('error', (err) => { _.err("Error downloading from:",url); });
}
catch (ex) { _.err(ex,-123); }
return -1;
}
, do_ARCH = (cmd,newA) => {
try {
// probably we better write it to a file instead
let nf = Fs.readlinkSync (nodeFolder)
, p1 = nf.lastIndexOf (pathSep)
, p2 = nf.lastIndexOf ('-')
, arc = nf.substring ((p2>0?p2:p1)+1)
, newA
;
newA = newA && newA.toLowerCase();
if (ND !== newA) {
_.log('set default ARCH:',newA)
try {
if (0 > validArchs.indexOf(newA)) throw Exception();
}
catch (e) {
_.log('sorry!, ',newA,' is a not valid Arch');
return null;
}
}
else {
_.log(arc);
return arc;
}
}
catch (ex) { // if there's no version 'in use' ..
_.log("it looks like we don't have any version in use (yet) ..");
return null;
}
}
, do_LIST = (cmd,avlbl) => {
avlbl = avlbl ? avlbl.toLowerCase() : ND;
var lstAll = 'all'
, av = 'available'.startsWith(avlbl) || avlbl==lstAll
, nodeVerURL = nodeDistBase+'index.json'
, iojsVerURL = iojsDistBase+'index.json'
;
if (av) {
_.ND = ND;
_.nodeList = _.ND;
_.nodeError = _.ND;
_.nodeReqInProgress = true;
_.iojsList = _.ND;
_.iojsError = _.ND;
_.iojsReqInProgress = true;
Http.get(nodeVerURL, ( response ) => {
try{
if (response.statusCode == 200) {
var body='';
response.on('data' , function (data) {
body += data.toString() ;
}) ;
response.on('end' , function() {
Fs.writeFile(nodeCacheFile, body, function(err) {
if(err) { _.log(err); }
else {
var guiCacheFile='.'+_.PUBLIC_HTML+'/'+nodeCacheFile
Fs.writeFileSync(guiCacheFile, Fs.readFileSync(nodeCacheFile));
}
});
var res = JSON.parse(body);
_.nodeList = res;
var vList = ""
, stable = []
, lts = []
;
for (var v in res) {
var ver=res[v];
if (!ver.lts) stable.push(ver);
else lts .push(ver);
vList+= strFormat(' %s\t\t[%s]\t\t%s\t\t%s\r\n',ver.version ,ver.lts?ver.lts:'',ver.date,ver.npm);
}
Fs.writeFile(nodeCacheList, vList, function(err) {
if(err) { _.log(err); }
else _.nodeReqInProgress = false;
});
}) ;
}
else { // TODO FixME!!
_.err (response.statusCode,err,_.log.error);
_.nodeError = { 'RES' : response , 'ERR' : err };
}
}
catch ( e ){
_.log("EXCEPTION: ",e);
}
}).on('error', (err) => { _.err(err); } );
Http.get(iojsVerURL, ( response ) => {
try{
if (response.statusCode == 200) {
var body='';
response.on('data' , function (data) {
body += data.toString() ;
}) ;
response.on('end' , function() {
Fs.writeFile(iojsCacheFile, body, function(err) {
if(err) { _.log(err); }
else {
var guiCacheFile='.'+_.PUBLIC_HTML+'/'+iojsCacheFile
Fs.writeFileSync(guiCacheFile, Fs.readFileSync(iojsCacheFile));
}
});
var res = JSON.parse(body)
, vList = ""
;
_.iojsList = res;
for (var v in res) {
var ver=res[v];
vList+= strFormat(' %s\t\t%s\t\t%s\r\n',ver.version, ver.date, ver.npm);
}
Fs.writeFile(iojsCacheList, vList, function(err) {
if(err) { _.log(err); }
else _.iojsReqInProgress = false;
});
}) ;
}
else { // TODO FixME!!
_.log (response.statusCode,err ,_.log.error);
_.iojsError = { 'RES' : response , 'ERR' : err };
}
}
catch (e) {
_.log("Exception: ",e);
}
}).on('error', (err) => { _.err(err); } );
var rawStdout = new Fs.SyncWriteStream(1, { autoClose: false })
, numeric = function ( vs ) {
vs = vs.substring(1);
vs = vs.split('.');
var len = vs.length;
if (len!=3) return 0;
var num= LeftPad(vs[0],3,0) + LeftPad(vs[1],3,0) + LeftPad(vs[2],4,0) ;
return num;
}
, compareVersion = function ( nV ,iV) { return numeric(nV) > numeric(iV); }
;
w4it.enableAnimation();
w4it.done( () => { return !(_.nodeReqInProgress || _.iojsReqInProgress); },
() => {
try{
var total = 0
, nodeLen = _.nodeList? _.nodeList.length : 0
, iojsLen = _.iojsList? _.iojsList.length : 0
, i
, j = 0
, k = 0
, merged = []
, empty = 'v'
, mileStones = []
;
if (_.nodeError) { _.log(_.nodeError); }//showError('NODE:',nodeError); }
else total += nodeLen;
if (_.iojsError) { _.log(_.iojsError); }//showError('IOJS:',iojsError); }
else total += iojsLen;
//_.log (total,nodeLen,iojsLen);
for (i=0; i < total; i++) {
var nodeVer = (_.nodeList && _.nodeList[j]) ? _.nodeList[j].version : empty
, iojsVer = (_.iojsList && _.iojsList[k]) ? _.iojsList[k].version : empty
;
if (compareVersion(nodeVer,iojsVer)) { merged[i]=_.nodeList[j++]; merged[i].origin='NODE'; }
else { merged[i]=_.iojsList[k++]; merged[i].origin='IO.JS'; }
}
var len=merged.length;
if (total != len) _.log('merged size missmatch! expected:',total,' actual:',len);
_.log('num of releases found:\nNode: ',nodeLen,' IoJs: ',iojsLen);
_APP.full_list=merged;
Fs.writeFile('full_list.json', JSON.stringify(merged), function(err) { if(err) { return _.log(err); } });
var rel
, curr
, last
;
j=0;
if (avlbl==lstAll){
mileStones=merged;
}
else{
for (i = 0; i < merged.length ; i++) {
rel = merged[i];
curr = numeric(rel.version).substring(0,3);
if (last!=curr) {
last=curr;
mileStones[j++]=rel;
}
}
}
_.log('\n\n\t_-== Version ==-_-== LTS ==-_-== ORIGIN ==-_\n');
for (i=0 ; i < mileStones.length ;i++) {
rel = mileStones[i];
_.log('\t ',rel.version ,'\t ',rel.lts ? rel.lts : '\t','\t',rel.origin);
}
}
catch ( e){
_.log("Exception: ",e);
}
});
return;
}
else if (avlbl) _.log('unknown option: ',avlbl);
_.log('installed versions:');
_.log();
let i
, name
, list = []
, ver
, arch
, p1
, fPath
, a
, vs
;
try {
ver = Fs.readlinkSync (nodeFolder);
p1 = ver.lastIndexOf (pathSep);
arch = ver.substring ( p1+1); //get arch
ver = ver.substring (0, p1 ); //strip arch
ver = ver.substring ( ver.lastIndexOf (pathSep)+1); //strip base path
p1 = arch.lastIndexOf('-')
arch = p1<0? arch : arch.substring( p1+1); //arch
_.log('in use:',LeftPad('',12),ver ,LeftPad(arch,16-ver.length),'\n');
}
catch (ee){
//_.log("sorry: can't find any version in use!"); return -1;
}
try {
files = Fs.readdirSync(nodeStoreDir);
if (files[0].name) {/* force err if not present */}
for (i in files){
name = files[i];
fPath = nodeStoreDir + name;
if (Fs.statSync(fPath).isDirectory()){
var archs=Fs.readdirSync(fPath);
for (a in archs) {
var archN = archs[a]
, nPath = fPath + '/' + archN + '/node'+ nodeExtens
;
try {
Fs.statSync(nPath)
p1 = archN.lastIndexOf('-')
archN = (p1<0?archN:archN.substring(p1+1));
_.log(LeftPad('',20),name,LeftPad('',10-name.length), LeftPad('('+archN+')',6));
vs = {};
vs[name] = archN;
if (ver==name && arch==archN) vs.xyw=true;
list[list.length]=vs;
}
catch (e){}
}
}
}
return list;
}
catch (exc){
_.err(exc);
_.log('sorry looks like you have none installed');
return null;
}
}
, do_ACTIVATE = (cmd) => {
var data = Fs.readFileSync('whereIsNode', "utf8")
, nodeProgPath
, nodeProgDir
, nodeFile
, nodeBasePath
;
data = data.replace('\r','');
data = data.split('\n')[0];
data = data.split(pathSep);
nodeFile = data.pop();
nodeProgDir = data.pop();
nodeBasePath= data.join(pathSep);
// OFF ------------------------------------------------------------------------------
if (cmd!=='on'){
_.log('switching NIM off ..');
if ( nodeBasePath == me.cwd()){
_.log('ok node does point here, so here we go ..');
}
else {
_.err('sorry , node found somewere else .. ->',nodeBasePath+pathSep+nodeProgDir);
return;
}
return; // get out we are done here!
}
// ON ------------------------------------------------------------------------------
if (!Fs.existsSync(nodeFolder)){
_.err("You need to have a node version in use before activation ...\n try to call 'nim use <version>' before");
return;
}
try{
var ver=Exec("cmd",["/C",toLocalOs(nodeFolder+'node'),"--version"] ).toString()
, vtk=ver.trim().split(/\./)
;
if (vtk[0].startsWith('v') && vtk.length==3){
_.log('working version:',ver);
}
else {
_.err('sorry! ,the folder:',nodeFolder,"doesn't look like it contain a working version!");
return;
}
}
catch (e){ _.err(e); return; }
if (nodeBasePath == me.cwd()){
_.err('sorry! ,looks like we are already switched on!');
return;
}
nodeProgPath= data.join(pathSep);
activateArgs.push(cmd);
activateArgs.push(qtd(nodeProgPath));
activateArgs.push(qtd(nodeProgDir));
activateArgs.push(nodeFolder.subStr(0,nodeFolder.length-1));
activateArgs.push("> activate.log");
Fs.writeFile('original.node.folder', nodeProgPath+pathSep+nodeProgDir , "utf8", ()=>{
_.log('backup info done');
});
// it should be safe here to switch to our 'inuse' version ..
return; // we need some more test, and a rollback plan !
child=ChildProc.spawn(activateCommand ,activateArgs,{ stdio: 'inherit' } );
child.on('error',function (err) { _.err(err); me.exit(-123); });
child.on('exit', function (code){ me.exit(code) });
}
, do_USE = (cmd,_ver,_arch) => {
let ver = normalizeVer (_ver)
, arch = normalizeArch (_arch)
, vPath = nodeStoreDir + ver
, found = false
, archs = validArchPaths.win[arch.endsWith('64')?1:0]
, aa,i
;
for (aa in archs){
var pp=vPath + '/' + archs[aa];
if (Fs.existsSync(pp)){
vPath = pp;
found=true;
break;
}
}
if (! found) {
_.err("version not found!");
return;
}
try {
files = Fs.readdirSync(vPath);
for (i in nodeRequired) if (0> files.indexOf(nodeRequired[i])) {
_.err("required file missing ["+nodeRequired[i]+"] ",files);
me.exitCode=-3;
}
try {
try { Fs.rmdirSync (nodeFolder); } catch(e) { }
symLinkArgs.push(toLocalOs(nodeFolder));
symLinkArgs.push(toLocalOs(vPath));
var out=Exec(symLinkCommand ,symLinkArgs);
_.log(out.toString()); // TODO check result here !!
}
catch (ex){ _.err(ex); }
}
catch (ex){
_.err("version ["+args[1]+"]("+arch+") not found in our store ..\n use install command to add it to the store");
me.exitCode = -2;
}
}
, do_INSTALL = (cmd,_ver,_arch) => {
var ver = normalizeVer (_ver)
, arch = normalizeArch (_arch)
, vPath = ver+'/'
, notFnd1 = false
, notFnd2 = false
, vList = _APP.full_list
, vInf
, found = false
, NPMv
, urlBase
, requires
, v
;
_.log('installing version: ',_ver);
if ( vList != ND ){
//_.log(vList);
for (v in vList){
vInf=vList[v];
if (vInf.version==('v'+_ver)){
_.log("FOUND! (released on:",vInf.date,")");
NPMv=vInf.npm;
_.log("we need NPM ver:",NPMv);
found=true;
switch (vInf.origin){
case 'NODE':
urlBase =nodeDistBase;
requires=nodeRequired;
break;
case 'IO.JS':
urlBase=iojsDistBase;
requires=iojsRequired;
break;
default:
_.err("unexpected source:",vInf.origin) ;
me.exit(66);
}
break;
}
}
if (!found){
_.log("SORRY NOT FOUND");
return;
}
}
else{
_.err("we can't find any version info, please run [nim list available] first!");
return;
}
try {
Http.head(urlBase+vPath,function (response) {
//_.log(urlBase+vPath, response.statusCode);
let vDir;
if (response.statusCode == 200) {
let a
, archs = validArchPaths.win[arch.endsWith('64')?1:0]
for (a in archs) {
vDir=vPath+archs[a];
downloadFiles(urlBase+vDir,nodeStoreDir+vDir,requires
//,npmDistBase,NPMv );
,npmDistBase,NPMv + '.tgz' );
}
}
else {
notFnd1 = true;
_.err("can't find actual version for",vDir,archs);
}
}).on('error',(err) => { _.err(err); } );
}
catch(ex){ _.err(ex.message); me.exit(66); }
_.log("exit install")
}
, do_REMOVE = (cmd,_ver,_arch) => {
var i
, e
, fileNa
, ver = normalizeVer (_ver)
, arch = normalizeArch(_arch)
, baseDir = nodeStoreDir + ver
, vPath = baseDir + '/' + arch
;
_.log('removing: ',vPath);
try {
try{ files = Fs.readdirSync(vPath); }catch(e){}
for (i in files){
fileNa=vPath+'/'+files[i];
if (Fs.lstatSync(fileNa).isDirectory()){
removeDirSync(fileNa);
}
else Fs.unlinkSync(fileNa);
}
try { Fs.rmdirSync (vPath); }catch(e){}
try { Fs.rmdirSync (baseDir); }catch(e){}
}
catch (e){ _.err(e)
_.err('not found: ['+ver+'] ('+arch+')');
}
}
, do_VERSION = (cmd) => {
_.log('Current Version:',info.version);
}
, do_ROOT = (cmd,where) => {
_.out('Current Root:',__dirname);
}
, do_GUI = (cmd,show) => {
try{
_.log(HttpD.Name,HttpD.Version);
HttpD.setStaticFolders ([__dirname + _.PUBLIC_HTML,__dirname + _.BOWER_DIR]);
HttpD.map ('/cmmnd' ,function (req,res,query) {
var fn = query;
switch (fn) {
case 'arch' :
var arch = do_ARCH(fn);
if (arch) return arch;
else return 'ERROR!';
break;
case 'list' :
var list = do_LIST(fn);
if (list) return JSON.stringify(list);
else return 'ERROR!';
break;
default:
res.send('unknown command');
}
});
HttpD.listen(_.LISTEN_PORT );
//TODO!
// _.log('Express server listening on '+_.URL_BASE+':'+_.LISTEN_PORT+'/');
if (!show){
var child=ChildProc.spawn("cmd",['/C','START',_.URL_BASE+':'+_.LISTEN_PORT, cmd] );
child.on('error',function (err) { _.err(err); me.exit(-123); });
child.on('exit', function (code){ _.log(); });
}
}
catch (ex) {
_.err(ex);
me.exit(-123);
}
}
;
// ----------------------------------- --------------------------- ---------------------------------
Http.head = (url, cb) => { // keep it simple :D
var options=Url.parse(url);
options.method='HEAD';
var req=Http.request(options,cb);
req.end();
return req;
}
// ----------------------------------- --------------------------- ---------------------------------
// ----------------------------------- --------------------------- ---------------------------------
// =====================================================
// ===================================================== GUI Configuration
_APP.PUBLIC_HTML = '/GUI';
_APP.BOWER_DIR = '/js-libs';
_APP.LISTEN_PORT = process.env.PORT || 1111;
_APP.URL_BASE = 'http://localhost';
_APP.out = _log
_APP.log = _log
_APP.wrn = _wrn
_APP.err = _err
_APP.timeSt = (name) => { return timers[name]= (new Date()).getTime();};
_APP.timeEn = (name) => { return (new Date()).valueOf() - timers[name];};
_APP.full_list = ND
let _ = _APP
, me = process
, isOS = me.arch
, args = me.argv
, cmdLn = args[0]
, myName = args[1]
, myArch = 'x64'
;
// =====================================================
// ----------------------------------- --------------------------- ---------------------------------
// ----------------------------------- --------------------------- ---------------------------------
Fs.readFile('./full_list.json', function read(err, data) {
if (err){
_.err("unexpected error",err)
return;
}
_APP.full_list = JSON.parse(data.toString());
});
// ----------------------------------- --------------------------- ---------------------------------
args.splice(0,2);
// ----------------------------------- --------------------------- ---------------------------------
me.on('exit', function (c) {
process.exit(c);
})
// ----------------------------------- --------------------------- ---------------------------------
Fs.readFile('package.json', "utf8", (err, data) => {
if (err) _.log(err);
else {
var oo=JSON.parse(data);
info.version = oo.version;
info.desc = oo.description;
info.author = oo.author;
}
});
// ----------------------------------- --------------------------- ---------------------------------
switch (isOS) {
case 'x86':
case 'x64':
findNodeCommand = 'findFile.cmd';
symLinkCommand = 'sudo.cmd';
activateCommand = 'sudo.cmd';
activateArgs = ['activate'];
symLinkArgs = ['mklink' ,'/D'];
nodeRequired = ['node.exe','node.lib'];
iojsRequired = ['iojs.exe','iojs.lib'];
archPrfx = 'win-';
break;
default:
//ERROR!!!
}
// ----------------------------------- --------------------------- ---------------------------------
try {
var child=ChildProc.spawn(findNodeCommand ,['node','>','whereIsNode'],{ stdio: 'inherit' } );
child.on('error',function (err) { _.err(err); me.exit(-123); });
child.on('exit', function (code){ main(); });
}
catch (ex) {
exit("can't find Node installation dir",ex);
}
// ----------------------------------- --------------------------- ---------------------------------
main = function () {
try {
cmd = args[0] && args[0].toLowerCase();
if ('arch' .startsWith(cmd)) do_ARCH (cmd,args[1]); // show or set default Arch
else if ('list' .startsWith(cmd)
|| 'ls' .startsWith(cmd)) do_LIST (cmd,args[1]); // show installed or availables
else if ('use' .startsWith(cmd)) do_USE (cmd,args[1],args[2]); // link current version to selected
else if ('install' .startsWith(cmd)) do_INSTALL (cmd,args[1],args[2]); // install a new version that can be used later locally
else if ('remove' .startsWith(cmd)
&& cmd.length==6 ) do_REMOVE (cmd,args[1],args[2]); // remove should be typed completeley to be shure you don't mistyped it
else if ('version' .startsWith(cmd)) do_VERSION (cmd);
else if ('gui' .startsWith(cmd)) do_GUI (cmd,args[1]); // run with web GUI
else if ('root' .startsWith(cmd)) do_ROOT (cmd,args[1]);
else if ('on' == cmd
|| 'off' == cmd) do_ACTIVATE (cmd); // activate deactivate globally
else usage();
}
catch (ex) { //_.err(ex);
if (!ex.message.startsWith("Cannot read property 'x'")) _.err(ex);
if (cmd) {
_.log('unknown command: '+cmd);
_.log();
}
usage();
me.exitCode = -1;
}
};
// ----------------------------------- --------------------------- ---------------------------------