| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526 | 
							- var path = require('path');
 - var utils = require('bbhverse');
 - var any = utils.any;
 - var Tasq = utils.Tasq
 - var statuslog = utils.Traq
 - var Traq = utils.Traq
 - Tasq.addlistener(statuslog.statuslog)
 - var cli = require('./cliverse')
 - var nodeShellExec = cli.nodeShellExec;
 - var chalk = require('chalk')
 - 
 - 
 - const __ALIAS__STAMP__ = '9e7bebe0-1f57-11ec-8f88-778ffeea9d1b'
 - const BUILD_VERSION = '[VI]Version: {version} - built on {date}[/VI]';
 - const runtimestamp = (new Date()).getTime();
 - function getVersion() { return BUILD_VERSION; }
 - console.log(getVersion());
 - 
 - // 'use strict';
 - 
 - // PB : TODO -- make sure folder context is proper coz we can now run elxr from anywhere.
 - 
 - // PB : TODO -- 
 - // runas bypass non elevated tasks when we request privelege
 - // runas message is always error needs to be fixed.
 - // runas wait needs to be parallelized.
 - // suppress elevation check error messages
 - // support runas lauched directly from shell.
 - // pass in environment in hta to shellexecute.
 - 
 - // PB : NOTE -- iife doesnt work if previous statement is not terminated by ;
 - (function () {
 -   "use strict";
 -   if (!Array.prototype.earlyreduce) {
 -     Array.prototype.earlyreduce = function(eachcallback, initialValue, donecallback){
 -       var iterable = this;
 -       var donecallback = donecallback || (a=>a)
 -       var result = { value : initialValue === undefined ? iterable[0] : initialValue };
 -       initialValue === undefined ? null : result = eachcallback(result, element, i, iterable);
 -       // function *earlyReduceGenerator(acc, v, i, a) {
 -         for(var i = initialValue === undefined ? 0 : 1; i < iterable.length; i++){
 -           var element = iterable[i]
 -           result = eachcallback(result, element, i, iterable)
 -           if(result.done) return donecallback(result)
 -         }
 -       // }
 -       return donecallback(result)
 -     }
 -   }
 - }());
 - 
 - const { existsSync } = require('fs');
 - const existsFolderSync = existsSync;
 - const fs = require('fs')
 - 
 - const cliargs = utils.cliargs;
 - const processedArgs = cliargs(process.argv.slice(2));
 - console.dir(processedArgs)
 - // PB : TODO -- defaults for valuless arguments if passed.
 - // Object.keys(processedArgs).forEach(a=>{
 - //   if(Object.prototype.toString.call(processedArgs[a]) === '[object Undefined]' || !processedArgs[a]) || trim(processedArgs[a])) == '') {
 - 
 - //   }
 - // })
 - 
 - // 
 - 
 - // elxr cli operations
 - var noprerequisites = {
 -     add : true, 'set-url' : true, 'repo-relocate' : true
 -   , remote : true, 'c' : true, 'h' : true
 -   , httpget : true, getuser : true
 -   , 'switch user' : true
 -   , 'switch' : true
 -   // , 'undefined' : true
 - }
 - 
 - var reconfirmcmds = { create : true }
 - 
 - var subcommandlabels = {
 -     remote : (`remote ${processedArgs._[1] || ''}`).trim()
 -   , switch : (`switch ${processedArgs._[1] || ''}`).trim()
 - }
 - 
 - var cmds = {
 -   remote : {
 -     // return a interpreted set of arguments for this comd run context.
 -     interpret() { 
 -       return { cmd : subcommandlabels['remote'], runchoice : 'c' }  
 -     }
 -   }
 -   , switch : {
 -     interpret() {
 -       return { cmd : subcommandlabels['switch'], runchoice : 'c', username : processedArgs._[2]
 -         , reposerver : __default.reposerver
 -       }  
 -     }
 -     , getPossiblePrompts(){ return { username : true, reposerver : 'http://git.bbh' } } // Requires only one argument...
 -   }
 -   , 'switch user' : {
 -     interpret() {
 -       return { cmd : subcommandlabels['switch'], runchoice : 'c', username : processedArgs._[2] }  
 -     }
 -     , getPossiblePrompts(){ return { username : true } } // Requires only one argument...
 -   }
 - }
 - 
 - var interpretrun = function(){
 - 
 -   var cmd = processedArgs._[0];
 -   var clioverrides = { cmd }   
 -   processedArgs.node_env ? clioverrides.node_env = processedArgs.node_env 
 -   : (process.env.NODE_ENV && process.env.NODE_ENV.trim()) 
 -       ? clioverrides.node_env = (process.env.NODE_ENV && process.env.NODE_ENV.trim()) : null;
 -   
 -   
 -   return cmds[cmd] ? cmds[cmd].interpret() : (function(){
 -     processedArgs._[1] ? clioverrides.instanceName = processedArgs._[1]: null;
 -     // return clioverrides
 -     cmds[cmd] = {
 -       interpret() {
 -         return Object.assign(clioverrides, { cmd, runchoice : 'c' })
 -       }
 -       , getPossiblePrompts(){ return { cmd, username : true, password : true, 
 -         instanceName : true, instanceType : true, reposerver : true } }
 -     }
 -     return cmds[cmd].interpret()
 -   })() 
 - }
 - 
 - var clioverrides = interpretrun()
 - console.dir(clioverrides)
 - 
 - // Object.keys(clioverrides).forEach( prop => { })
 - 
 - var globSync = require('glob').sync;
 - 
 - var ENV = Object.assign({}, process.env); // Shallow clone it.
 - 
 - const { readdir } = require("fs").promises
 - 
 - // Directory shallow walk and do perform on each dir.
 - const dirs = async (perform, path) => {
 -   for (const dir of await readdir(path || selectedinstance.root, { withFileTypes: true })) {
 -     if (dir.isDirectory()) perform(dir)
 -   }
 - }
 - 
 - var getShellTask = (command, args, options) => {
 -   options = options || {}
 -   var callshell = command === 'rm' ? getgitbashtask : getshelltask;
 -   return () => {
 -     var p = callshell( [command, args, Object.assign({
 -         inherit: true, shell: true, env: ENV, title: `${command} ${args}`
 -       }, options)
 -     ])()
 -     if (options.ignorefailures) {
 -       return p.catch(e => {
 -         // Ignore. Not a major error.
 -       })
 -     }
 -     else return p;
 -   }
 - }
 - 
 - var callshelltask = (args) => { 
 -   // console.dir(args)
 -   if( Object.prototype.toString.call(args) === '[object Function]' ) {
 -     return args;
 -   }
 -   return  getshelltask(args)() 
 - }
 - 
 - var getshelltask = (args) => { 
 -   return args[0] === 'rm' ? getgitbashtask(args) : () => { return nodeShellExec.apply(null, args) } }
 - var getgitbashtask = (args) => { return () => { 
 -   return nodeShellExec( `"${gitbash}"`, ['-c', `"${args[0]} ${args[1].join(' ')}"`], args[2]) } 
 - }
 - 
 - var getTaskCheckExists = (command, options) => {
 -   options = options || {}
 -   return () => {
 -     var p = nodeShellExec.apply(null, ['where', [command]])
 -     if (options.ignorefailures) {
 -       return p.then(() => { return true }).catch(e => { // Ignore. Not a major error.
 -         return false;
 -       })
 -     }
 -     else return p.then(() => { return true });
 -   }
 - }
 - 
 - var getTaskWithElevation = function(tasdef){
 -   return ()=>{
 -     if (__isElevated) { 
 -       return tasdef.elevatedpulltasks().then(()=>{
 -         // PB : TODO -- Every elevation should have its own messaging file. Async writes from multiple processes are a problem here...
 -         fs.writeFileSync('run.done', 'success')
 -       }).catch(e=>{
 -         fs.writeFileSync('run.done', 'failure')
 -       });
 -     }
 -     else {
 -       // PB : TODO -- Rename op['runas'] to 'elevate'
 - 
 -       var __runasresult = null;
 - 
 -       return op['runas']().then((r) => { return __runasresult = r; })
 -         .catch((e) => {
 -           console.error(e)
 -         })
 -         .finally(() => {
 -           if(__runasresult && !__runasresult.skipped) fs.unlinkSync('run.done')
 -           if (!processedArgs.runas) {  return tasdef.regularpulltasks(); }
 -         })
 -     }
 -   }
 - }
 - 
 - var getTaskWithoutElevation = function(tasdef){
 -   return ()=>{
 -     if(!processedArgs.runas) {  return tasdef.regularpulltasks(); }
 -     else Promise.resolve(true)
 -   }
 - }
 - 
 - var gitops = {
 - 
 -   getdiscoverbranchcmd : function(repo){
 - 
 -     var parameters = ['-c', 'branch=`git rev-parse --abbrev-ref HEAD`;for i in `git remote`; do git pull $i $branch; done;']
 -     var cmd = [gitbash
 -       , ['-c', 'branch=`git rev-parse --abbrev-ref HEAD`;for i in `git remote`; do git pull $i $branch; done;']
 -       , { cwd: instanceroot + '/' + repo, title: 'discoverbranch for ' + repo + ' ' + parameters.join(' ') }]
 -     return cmd
 -   }
 - }
 - 
 - var getPullCmd = (repo, branch) => {
 -   // console.log(useGitPull)var getPullCmd = (repo, branch) => {
 -   // console.log(useGitPull)
 - 
 -   var pullCmd = []
 -   if(!branch) {
 -     // console.warn('No branch was specified detecting from working client.')
 -     // First check if working client exists.
 -     // if (existsSync(instanceroot + '/' + repo)) {
 -       pullCmd= gitops.getdiscoverbranchcmd(repo)
 -     // }
 -     // else performpull
 -   }
 -   // var pullCmd = [gitInstallDir
 -   //   , ['-c', 'branch=`git rev-parse --abbrev-ref HEAD`;for i in `git remote`; do git pull $i $branch; done;']
 -   //   , { cwd: instanceroot + '/' + repo, title: 'pull all remotes for ' + repo }]
 -   if(branch) {
 -     var parameters = ['-c', 'for i in `git remote`; do git pull $i ' + branch + '; done;']
 -     var pullCmd = [ gitbash
 -       , ['-c', 'for i in `git remote`; do git pull $i ' + branch + '; done;']
 -       , { cwd: instanceroot + '/' + repo, title : 'pull all remotes for ' + branch + '  ' + repo + ' ' + parameters.join(' ') }]
 -   }
 -   // var pullCmd = ['pullall', [], { cwd : repo }]
 -   if (useGitPull) pullCmd = ['git', ['pull'], {
 -     inherit: true, shell: true,
 -     cwd: instanceroot + '/' + repo
 -     // , env: process.env
 -     , runas: processedArgs.runas
 -     , title: `git pull ${repo}`
 -   }]
 -   return pullCmd
 - }
 - 
 - var performPull = (repo, branch) => {
 -   // PB : TODO -- Handle no branch passed in case.
 -   // if(!branch) { throw 'No branch specified' }
 - 
 -   if (existsSync(instanceroot + '/' + repo)) {
 -     var branchprint =  branch ? ' branch :' + branch  : '';
 -     console.log('pulling ' + instanceroot + '/' + repo + branchprint )
 -     return nodeShellExec.apply(null, getPullCmd(repo, branch)).then(() => {
 -             if (__isElevated) {
 -         fs.writeFileSync('run.log', ', ' + JSON.stringify({ repo, success: true }), { 'flag': 'a+' })
 -       }
 -       else statuslog.statuslog(null, repo)
 -       return true;
 -     })
 -     .catch((e) => {
 -       e.repo = repo;
 -       if (__isElevated) {
 -         fs.writeFileSync('run.log', ', ' + JSON.stringify(e), { 'flag': 'a+' })
 -       }
 -       else statuslog.statuslog(e); console.error(e)
 -     })
 -   }
 -   else {
 -     console.log('cloning ' + repo)
 -     // PB : TODO -- detect if a clonable repo exists in currentGitAuthUser
 -     return nodeShellExec('git', ['clone', '-c', 'core.symlinks=true', selectedinstance.reposerver + `/${defaultRepoOwner}/` + repo + '.git'],
 -       {
 -         inherit: true, shell: true,
 -           env: process.env
 -         , cwd : instanceroot 
 -         , runas: processedArgs.runas
 -       }).catch((e) => {
 -         throw e;
 -       }).then(() => {
 - 
 -         return nodeShellExec('git', ['config', '--replace-all', 'core.symlinks', true],
 -           {
 -             inherit: true, shell: true,
 -             env: process.env
 -             , cwd: instanceroot + '/' + repo
 -             , runas: processedArgs.runas
 -             , title: `git core.symlinks --replace-all true for ${selectedinstance.reposerver + `/${defaultRepoOwner}/` + repo + '.git'}`
 -           })
 -           .then(() => {
 -             if (__isElevated) {
 -               fs.writeFileSync('run.log', ', ' + JSON.stringify({ repo, success: true }), { 'flag': 'a+' })
 -             }
 -             else statuslog.statuslog(null, repo)
 -           })
 -           .catch((e) => {
 -             e.repo = repo;
 -             if (__isElevated) {
 -               fs.writeFileSync('run.log', ', ' + JSON.stringify(e), { 'flag': 'a+' })
 -             }
 -             else statuslog.statuslog(e);
 -           })
 -       })
 -       .catch(e => {
 -         e.repo = repo;
 -         if (__isElevated) {
 -           fs.writeFileSync('run.log', ', ' + JSON.stringify(e), { 'flag': 'a+' })
 -         }
 -         else statuslog.statuslog(e);
 -       })
 -   }
 - }
 - 
 - // PB : TODO -- If we are run from an elevated shell it never moves forward and simply exits.
 - // -- Currently workaround is to always run from a non-elevated shell.
 - var __isElevated = null; // We assume non-Elevated until someone evaluates and sets this variable.
 - var acquireElevationState = () => {
 -   if (__isElevated === null) {
 -     return nodeShellExec("fsutil", ["dirty", "query", "C:"], {
 -       inherit: true
 -       // , shell: true
 -       , stdio: 'ignore'
 -       , env: process.env
 -       , title: `check privileged execution mode using "fsutil dirty query C:"`
 -     }).then((exitcode) => {
 -       console.log('Elevated')
 -       __isElevated = true;
 -       return true;
 -     }).catch(() => {
 -       __isElevated = false;
 -       console.log('Not Elevated');
 -       return false;
 -     });
 -   }
 -   else return Promise.resolve(__isElevated);
 - }
 - 
 - 
 - var currentGitAuthUser; // nodeShellExec('git', ['config', 'user.email']) ... PB : TODO-- get the current GITEA username 
 - var defaultRepoOwner = 'chess';
 - var elevatedRunasRepos = null
 - var gitRepos = null
 - 
 - // grep -qxF 'alias elxr="node elxr/index.js"'  ~/.bash_profile || echo 'alias elxr="node elxr/index.js"' >> ~/.bash_profile
 - 
 - 
 - // nodeShellExec('echo', ['elxr'], { inherit : true}) //, {stdio: "inherit"}
 - 
 - var dbForLabel = function (label) {
 -   var dbsForLabel = {
 -     devmysql: 'mysql'
 -     , development: 'mssql'
 -     , production: 'mssql'
 -   }
 -   return dbsForLabel[label] || 'mysql'
 - }
 - 
 - // SAM : TODO Use nodeshellexec where to detect git installation dir
 - var gitbash = "C:\\Program Files\\Git\\bin\\sh.exe"
 - // var gitbash = "G:\\Installed\\Git\\bin\\sh.exe"
 - // Relevant git repos
 - var exludeMergeRepos = [];
 - var useGitPull = processedArgs.useGitPull || false;
 - var configPromise = null
 - 
 - 
 - var op = {
 -     'h': () => { console.log(elxr.help()); return '-h' }
 -   , 'clean' : () => {
 -     // delete all node_module folders and links.
 -     var tasklist = [];
 -     dirs( (repodir)=> tasklist.push(getShellTask('rm',['-rf', 'node_modules'], { cwd : instanceroot + '/' + repodir.name })()), instanceroot )
 -     return Promise.all(tasklist)
 -   }
 -   // , 'undefined': () => { return acquireChoices( {} ); }
 -   , 'reset': () => {
 - 
 -     // Reset NPM packages semver so major versions can be updated.
 - 
 -     const fs = require('fs')
 -     const wipeDependencies = (__package) => {
 -       const file = fs.readFileSync(__package + '/package.json')
 -       const content = JSON.parse(file)
 -       for (var devDep in content.devDependencies) {
 -         if (content.devDependencies[devDep].match(/\W+\d+.\d+.\d+-?((alpha|beta|rc)?.\d+)?/g)) {
 -           content.devDependencies[devDep] = '*';
 -         }
 -       }
 -       for (var dep in content.dependencies) {
 -         if (content.dependencies[dep].match(/\W+\d+.\d+.\d+-?((alpha|beta|rc)?.\d+)?/g)) {
 -           content.dependencies[dep] = '*';
 -         }
 -       }
 -       fs.writeFileSync(__package + '/package.json', JSON.stringify(content))
 -     }
 - 
 -     var repos = ['client'];
 -     // repos = gitRepos;
 -     repos.forEach(wipeDependencies)
 -     // if (require.main === module) {
 -     // } else {
 -     //   module.exports = wipeDependencies
 -     // }
 - 
 -   }
 -   , 'upgrade': () => {
 -     console.log('upgrade.......')
 -     var tasks = [
 -       () => {
 -         var p = nodeShellExec('npm', ['i', '-g', 'npm-upgrade'], {
 -           inherit: true, shell: true
 -           , env: process.env
 -         }).catch((e) => { console.error(e) })
 -         p.position = 1;
 -         console.log('One')
 -         return p;
 -       }
 -       , () => {
 -         var p = nodeShellExec('npm', ['cache', 'clean', '-f'], {
 -           inherit: true, shell: true
 -           , env: process.env
 -         }).catch((e) => { console.error(e) })
 - 
 -         p.position = 2;
 -         console.log('Two')
 -         return p;
 -       }
 -       , () => {
 -         var p = nodeShellExec('npm', ['install', '-g', 'n'], {
 -           inherit: true, shell: true
 -           , env: process.env
 -         }).catch((e) => { console.error(e) })
 -         p.position = 3;
 -         console.log('Three')
 -         return p;
 -       }
 -       , () => {
 -         var p = nodeShellExec('n', ['latest'], {
 -           inherit: true, shell: true
 -           , env: process.env
 -         }).catch((e) => { console.error(e) })
 -         p.position = 4;
 -         console.log('Four')
 -         return p;
 -       }
 -     ]
 -     any(tasks)
 -     console.log('.......done')
 -     console.log('Running exlr upgrade in : ' + path.dirname(__dirname))
 -     console.log('Currently only upgrades ember : ' + path.dirname(__dirname));
 -     console.info('Uninstalling existing ember globally');
 -     var step1 = nodeShellExec('cmd', ['/c', 'npm', 'uninstall', '-g', 'ember-cli'], {
 -       stdio: ['pipe', process.stdout, process.stderr],
 -       inherit: true,
 -       shell: true,
 -       cwd: path.dirname(__dirname),
 -       env: env
 -     })
 -     step1.on('close', () => {
 -       console.info('Installing ember globally');
 -       var step2 = nodeShellExec('cmd', ['/c', 'npm', 'install', '-g', 'ember-cli'], {
 -         stdio: ['pipe', process.stdout, process.stderr],
 -         inherit: true,
 -         shell: true,
 -         cwd: path.dirname(__dirname),
 -         env: env
 -       })
 - 
 -       step2.on('close', () => {
 -         nodeShellExec('cmd', ['/c', 'ember', '--version'], {
 -           stdio: ['pipe', process.stdout, process.stderr],
 -           inherit: true,
 -           shell: true,
 -           cwd: path.dirname(__dirname),
 -           env: env
 -         })
 -       })
 -     })
 -   }
 -   , 'runas': () => {
 - 
 -     if(processedArgs.skipelevated) return Promise.resolve({ skipped : true });
 - 
 -     console.log('Testing Elevation')
 - 
 -     if (__isElevated) {
 -       try {
 -         op[processedArgs.label || processedArgs._[0] || 'undefined']()
 -       }
 -       catch (e) {
 -         console.error('Error Invalid command : ' + e)
 -         fs.writeFileSync('run.done', 'error')
 -       }
 -       finally {
 -       }
 -     }
 -     else {
 -       console.log('Requesting Elevated Privileges');
 -       // Wait for the runas to complete before we read it.
 -       try {
 -         fs.unlinkSync('run.done')
 -         fs.unlinkSync('run.log')
 -       }
 -       catch (e) { } //Ignore 
 - 
 -       // Find node path to send to hta.
 -       return nodeShellExec('where', ['node']).then(r => {
 -         var namedArgs = [];
 -         console.log('result : ' + JSON.stringify(r))
 -         Object.keys(processedArgs).forEach((v) => { v != '_' ? namedArgs.push('--' + v + '=' + processedArgs[v]) : null; })
 -         // PB : TODO -- Convert all the cli args back to string.
 -         var args = [`${selectedinstance.root}/.elxr/run-${runtimestamp}/windowselevate.hta`].concat(processedArgs._).concat(namedArgs.join(' ')); args.push('--runas=self');
 -         // args.push('--nodepath=' + r.messages[r.messages.length - 1])
 -         // if (!processedArgs.node_env) args.push('--node_env=' + ENV.NODE_ENV)
 -         // if (processedArgs.debug) args.push('--debug=true') // Enable to debug elevated..
 -         console.dir(processedArgs)
 - 
 -         return nodeShellExec('MSHTA', [`"${args.join('" "')}"`]
 -           , {
 -             inherit: true
 -             , shell: true
 -             , env: ENV
 -             , runas: 'self'
 -             , title: `runas`
 -           }
 -         ).then(() => {
 -           // runas returned.
 -           try {
 -             // PB : TODO -- Log is comma prefixed. Needs to be proper JSON.
 -             var runaslog = JSON.parse('[ { "success" : true, "result" : "started"}' + fs.readFileSync('run.log', { flags: 'a+' }) + ']');
 -             runaslog.forEach((logEntry) => {
 -               statuslog.statuslog(logEntry.success ? null : logEntry, logEntry)
 -               logEntry.success ? (console.log(['success :' + logEntry.result]), console.log((logEntry.messages || []).join(' '))) : (console.error(['error :' + logEntry.result]), console.error((logEntry.messages || []).join(' ')))
 -             })
 -           }
 -           catch (e) {
 -             // We must have a runas log
 -             statuslog.statuslog(e)
 -             console.error('Run log error probably was not created by runas : ' + e)
 -           }
 -         })
 -           .catch(err => console.error('Elevation failed : ' + err));
 -       })
 - 
 -     }
 -   }
 -   , 'push': () => {
 -     if (!processedArgs._[1]) { console.error('push all not supported. Specify repo name'); return }
 -     // init remote bare from local
 -     // pushandinitremotebare
 -     // https://www.jeffgeerling.com/blogs/jeff-geerling/push-your-git-repositories
 -     // connect to repo server -- net use 172.16.0.27 
 -     // cd 172.16.0.27/repos/
 -     // mkdir repo.git
 -     // cd repo.git
 -     // git init --bare
 -     // cd localrepo
 -     // git remote rename origin githubclone
 -     // git remote add origin //172.16.0.27/repos/repo.git
 -     // git push origin master
 - 
 -     var repo = processedArgs._[1];
 - 
 -     var sequentialTaskShellCommands = [];
 -     if (!existsSync(`Z:/${repo}.git`)) {
 -       sequentialTaskShellCommands = [
 -         // ['net', ['use', 'Z:', selectedinstance.reposerver.replace('/','\\')], {
 -         //   inherit : true, shell: true
 -         //   , env: process.env
 -         // }]
 -         ['pwd', { cwd: 'Z:', inherit: true }]
 -         , ['mkdir', [`${repo}.git`], {
 -           cwd: `Z:`
 -           , inherit: true, shell: true
 -           , env: process.env
 -         }]
 -         , ['pwd', { cwd: `Z:/${repo}.git`, inherit: true }]
 -         , ['git', ['init', '--bare'], {
 -           cwd: `Z:/${repo}.git`
 -           , inherit: true, shell: true
 -           , env: process.env
 -         }]
 -         // PB : TODO -- Do this conditionally only...
 -         , ['git', ['remote', 'rename', 'origin', 'githubclone'], { cwd: `${instanceroot + '/' + repo}` }, (err) => {
 -           console.log('Ignoring origin rename error : ' + err); return true; //return true to continue.
 -         }] // PB ; Todo -- new repositories created locally will not have origin. Handle this failure.
 -         , ['git', ['remote', 'add', 'origin', `${selectedinstance.reposerver}/${repo}.git`], { cwd: `${instanceroot + '/' + repo}` }]
 -         // PB : TODO -- If threre is a gitbubclone origin 
 -         // Set the master to pull from the local repo.
 -       ]
 -       if (!existsSync(`Z:`)) {
 -         sequentialTaskShellCommands.splice(0, 0, ['net', ['use', 'Z:', selectedinstance.reposerver.replace(/\//gm, '\\')], {
 -           inherit: true, shell: true
 -           , env: process.env
 -         }])
 -         console.warn('Adding network drive z: for repo server. ' + sequentialTaskShellCommands[0])
 -         // throw 'done'
 -       }
 -     }
 - 
 -     sequentialTaskShellCommands.push(['git', ['push', 'origin', 'master'], { cwd: `${instanceroot + '/' + repo}` }])
 -     // console.dir(sequentialTaskShellCommands);
 - 
 -     var tasks = [];
 -     sequentialTaskShellCommands.forEach(shellcmd => {
 -       // console.log(shellcmd)
 -       tasks.push(() => {
 - 
 -         var p = nodeShellExec.apply(null, shellcmd.slice(0, 3)).catch((e) => { if (shellcmd[3]) { return shellcmd[3]() } else { console.error(e); } })
 -         return p;
 -       })
 -     })
 -     any(tasks);
 - 
 -   }
 -   , 'is-git-repo': (dir) => {
 -     return nodeShellExec('git', ['-C', dir.name, 'rev-parse'], { stdio: 'ignore' })
 -   }
 -   // git remote equivalents...
 -   // git branch --set-upstream-to=elixir-unc/master master
 -   // git push --set-upstream elixir-unc branch..
 -   , 'remote': (args) => { 
 -     
 -     // Subcommands!
 -     // PB : TODO -- we can now pass in hypehnated args...
 -     if(!processedArgs.v) return false; // Only -v is supported presently..
 - 
 -     var serial_perform = (repo) => {
 -       var options = { cwd: instanceroot + '/' + repo }
 -       
 -       return [
 -         ['git', ['remote', '-v'], options]
 -       ]
 -     }
 - 
 -     var x = (args) => {
 -       var tasq = () => {
 -         // console.log(args)
 -         return nodeShellExec.apply(null, args).catch(e => {
 -           // We continue on failure.
 -           console.error(tasq.toString())
 -         })
 -       }
 -       tasq.toString = function(){
 -         return JSON.stringify(args)
 -       }
 -       return tasq;
 -     }
 - 
 -     var perform = (dir) => {
 -       return any(serial_perform(dir.name).map(x))
 -     }
 - 
 -     dirs(perform)
 -   }
 - 
 -   , 'remote set-url': (args) => {
 -     // git remote set-url elixir-unc //10.10.5.60/gitrepo/chess/bbhverse
 -     var __args = {
 -       remotename : args.remotename || processedArgs._[2]
 -       , url : args.url || processedArgs._[3]
 -     }
 - 
 -     // pushable doesn't mean the remote doesn't support being pushed to. 
 -     // Over here it just means we are disabling pushing to that remote by setting the push portion of the url the a junk remote called no-pushing. 
 -     // PB : TODO -- change this to enablepushing.
 -     // By default pushing should be disabled. Also developers permissions on the remote is a secondary check for pushing.
 -     var pushable = processedArgs.pushable || false;
 -     remotename = __args.remotename
 -     url = __args.url
 -     var serial_perform_git_seturl = (repo) => {
 -       var options = { cwd: instanceroot + '/' + repo }
 -       // console.log(repo)
 -       if (pushable) {
 -         return [
 -           ['git', ['remote', 'set-url', remotename, url + '/' + repo], { cwd: instanceroot + '/' + repo }]
 -           , ['git', ['remote', `set-url`, '--push', remotename, url + '/' + repo], { cwd: instanceroot + '/' + repo }]
 -         ]
 -       }
 -       else {
 -         return [
 -           ['git', ['remote', 'set-url', remotename, url + '/' + repo], { cwd: instanceroot + '/' + repo }]
 -           , ['git', ['remote', `set-url`, '--push', remotename, 'no-pushing'], { cwd: instanceroot + '/' + repo }]
 -         ]
 -       }
 - 
 -     }
 - 
 -     var x = (args) => {
 -       var tasq = () => {
 -         // console.log(args)
 -         return nodeShellExec.apply(null, args).catch(e => {
 -           // We continue on failure.
 -           console.error(tasq.toString())
 -         })
 -       }
 -       tasq.toString = function(){
 -         return JSON.stringify(args)
 -       }
 -       return tasq;
 -     }
 -     var perform_git_seturl = (dir) => {
 -       op['is-git-repo'](dir).then((logEntry) => {
 -         return any(serial_perform_git_seturl(dir.name).map(x))
 -       }).catch((e) => {
 -         // console.log('Failed : ' + dir.name)
 -       })
 -     }
 - 
 -     dirs(perform_git_seturl)
 -   }
 -   // , 'reset' : ()=>{ 
 -     // PB : TODO -- Cant have 2 resets !! | There is an npm reset that should be bundled.
 -   //   // Reset the whole installation pertaining to this elxr folder.
 -     
 -   // }
 - 
 -   , 'remote exists': (args) => {
 -     var __args = {
 -         remotename : args.remotename|| processedArgs._[2]
 -       , url : args.url || processedArgs._[3]
 -       , branch : args.branch || processedArgs._[4]
 -     }
 - 
 -     var options = args.repo ? { cwd: instanceroot + '/' + args.repo } : {}
 - 
 -     // PB : TODO -- We should evaluate a whole list of remotes passed in from args instead of just one.
 -     var commands = [
 -       // git remote -v| while read remote; do "${remote#origin/}" "$remote"; done
 -         // ['git', ['remote', '-v', '| while read remote; do "${remote#origin/}" "$remote"; done'], utils.assign( { 
 -         ['git', ['remote', '-v'], utils.assign( { 
 -           evaluateResult : function(err, result){ 
 -             // var found = result.messages.find( (r)=> { return r.includes( __args.remotename )  })
 -             var remotes = []
 -             var found = false;
 -             console.dir(result.messages)
 -             console.log(result + '---------------')
 -             result.messages.forEach( (line)=> { 
 -               console.log(line + '$$$$$$$$$$$$$$$$$$$$')
 -               var matches = line.match(/(.*)?\s\s([^\(]*)?\s?\(?([^\)]*)\)?/);
 -               if(matches) {
 -                 var remote = {};
 -                 remote[matches[1]] = matches[2];
 -                 if( (!matches[3].trim() ||  matches[3].trim() === 'fetch') && matches[1].trim() === remotename.trim()) {
 -                   found = true;
 -                   result.url = remote[remotename];
 -                 }
 -               }
 -             })
 -             console.dir(remotes)
 -             return [
 -                   found
 -                 , result
 -             ]
 -           } 
 -         } , options) ]
 -         , function(prevserialtaskresult) {
 -             console.log('================================')
 -             var url = __args || prevserialtaskresult.url;
 -             console.dir(prevserialtaskresult)
 -             return getshelltask(['git', ['ls-remote', url], utils.assign( { 
 -               evaluateResult : function(err, result){
 -                 // fatal: unable to access '${__args.url}/': Failed to connect to git.bbh port 80 after 21025 ms: Timed out
 -                 // `fatal: repository '${__args.url}/' not found`
 -                 var hasfailed = /^fatal: .*/.test(result.messages.join(' '))
 -                 return [
 -                     !hasfailed, result
 -                 ]
 -               } 
 -             } , options) ])() 
 -         } 
 -     ]
 -     var mapped = commands.map(callshelltask)  //.map( p => p.catch(e => e)) // Handle errors later.
 -     return any(mapped).then( allresolved =>{
 -       console.dir(allresolved)
 -       !allresolved[0][0] && !allresolved[1][0] ? console.log('was not added as a remote and url is currently inaccessible.')
 -         : allresolved[0][0] && allresolved[1][0] ? console.log('was added as a remote and url is accessible.')
 -         : allresolved[0][0] && !allresolved[1][0] ? console.log('was added as a remote but url is currently inaccessible.')
 -         : console.log('was not added as a remote but url is currently accessible.')
 -       
 -       return !allresolved[0][0] && !allresolved[1][0] ? [0, 0]
 -         : allresolved[0][0] && allresolved[1][0] ? [1, 1]   // => was added as a remote and url is accessible.
 -         : allresolved[0][0] && !allresolved[1][0] ? [1, 0]  // => was added as a remote but url is currently inaccessible.
 -         : [0, 1]  // => was not added and remote and url is accessible.
 -     })
 -   }
 - 
 -   , 'remote refresh': (args) => {
 -     var __args = {
 -         remotename : args.remotename|| processedArgs._[2]
 -       , url : args.url || processedArgs._[3]
 -       , branch : args.branch || processedArgs._[4]
 -     }
 - 
 -     // use the repo manifest to create missing remotes.
 -     function perform_remote_refresh(dir){
 -       var repo = dir.name
 -       var dscoverbranchcmd = gitops.getdiscoverbranchcmd(repo)
 -       try {
 -         var remotes = require(`${selectedinstance.root}/${dir.name}/repo-manifest.js`)( null, selectedinstance).remotes || [];
 -       }
 -       catch(e){
 -         var remotes = []
 -       }
 -       // console.log(`${dir.name}/repo-manifest.js` + '---------------------------')
 -       // console.dir(remotes)
 - 
 -       return nodeShellExec.apply(null, dscoverbranchcmd).then(__branch=>{ 
 -         console.log('Processing : ' + dir.name)
 -         var branch = __branch
 -         __args.repo = repo
 -         __args.branch = __branch
 -         var promises = []
 - 
 -         remotes.forEach(remote =>{
 -           Object.keys(remote).forEach(remotename => {
 -             __args.remotename = remotename
 -             __args.url = remote[remotename]
 -             promises.push( op['remote exists']( __args ).then( exists => {
 -                 if(!exists[0]) {
 -                   if(!exists[1]) { console.error( `Skipping inaccessible remote url ${__args.url}` ) }
 -                   else return op['remote add']( { remotename, 
 -                     // PB : TODO -- use the most accessible remote instead of the first available.
 -                     url : (utils.js.isArray(remote[remotename]) ? remote[remotename][0] : remote[remotename]), branch 
 -                   } )
 -                 }
 -               })
 -             )
 -           })
 -         })
 - 
 -         return Promise.all(promises)
 -       })
 -       .catch((e) => { console.log('Processing Error : ' + dir.name); console.error(e); return { error: true, message: repo } })
 -     }
 -     
 -     return dirs(perform_remote_refresh)
 -   }
 -   , 'remote add': (args) => {
 -     // PB : TODO -- set-upstream-to should be chosen and intentionally switched. Coz we can have multiple upstream remotes.
 -       // Also each upstream remote may need to have is own branch to switch to. We therefore need a branch nomenclature
 -       // That explicitly has a remote name prefix.
 -       // git branch branch_name --set-upstream-to your_new_remote/branch_name
 -       // git branch branch_name -u your_new_remote/branch_name -- older versions
 -       // git branch -vv -- Detect which branch are we tracking.
 -       // default upstream should be users own fork.
 -       // Also need alias branches to 
 -         // define a git alias which would git pull master from one repo, and then git pull master from other remotes.
 -         // probably git merge from all remotes... and relevant branches...
 -     // alias pushall='for i in `git remote`; do git push $i; done;'
 -     // alias pullall='for i in `git remote`; do git pull $i; done;'
 -     // args === processedArgs ? args = {} : null;
 -     var __args = {
 -       remotename : args.remotename|| processedArgs._[2]
 -       , url : args.url || processedArgs._[3]
 -       , branch : args.branch || processedArgs._[4]
 -     }
 -    
 -     var remotename = __args.remotename
 -     var url = __args.url
 -     var branch = __args.branch
 - 
 -     var pushable = processedArgs.pushable || false;
 - 
 - 
 -     var serial_perform_git_add = (repo) => {
 -       var options = { cwd: instanceroot + '/' + repo }
 -       // console.log(repo)
 -       if (pushable) {
 -         return [
 -           ['git', ['remote', 'add', remotename, url + '/' + repo], { cwd: instanceroot + '/' + repo }]
 -           , ['git', ['pull', remotename, branch], { cwd: instanceroot + '/' + repo }]
 -           , ['git', ['branch', `--set-upstream-to=${remotename}/${branch}`, branch], { cwd: instanceroot + '/' + repo }]
 -         ]
 -       }
 -       else {
 - 
 -         return [
 -           ['git', ['remote', 'add', remotename, url + '/' + repo], { cwd: instanceroot + '/' + repo }]
 -           , ['git', ['remote', `set-url`, '--push', remotename, 'no-pushing'], { cwd: instanceroot + '/' + repo }]
 -           , ['git', ['pull', remotename, branch], { cwd: instanceroot + '/' + repo }]
 -           , ['git', ['branch', `--set-upstream-to=${remotename}/${branch}`, branch], { cwd: instanceroot + '/' + repo }]
 -         ]
 -       }
 - 
 -     }
 -     var x = (args) => {
 -       return () => {
 -         // console.log(args)
 -         return nodeShellExec.apply(null, args)
 -       }
 -       // return Promise.resolve(true)
 -     }
 -     var perform_git_add = (dir) => {
 -       op['is-git-repo'](dir).then((logEntry) => {
 -         // console.log(code)
 -         if (logEntry.success) {
 -           nodeShellExec('git', ['remote', 'get-url', remotename], { cwd: dir.name, stdio: 'ignore' }).then(() => {
 -             console.log('skipped : ' + dir.name + ', reason : A remote with same name already exists.')
 -           })
 -           .catch((e) => {
 -             any(serial_perform_git_add(dir.name).map(x))
 -           })
 -         }
 -         // else console.log('Skipped : Not a Git Repo : ' + dir.name)
 -       }).catch((e) => {
 -         console.log('Failed : ' + dir.name)
 -       })
 -     }
 - 
 -     const { readdir } = require("fs").promises
 -     
 -     dirs(perform_git_add)
 -   }
 -   , 'remote remove': (args) => {
 -     
 -     var __args = {
 -       remotename : args.remotename|| processedArgs._[2]
 -     }
 -     var remotename = __args.remotename
 -     var serial_perform_git_remove = (repo) => {
 -       var options = { cwd: instanceroot + '/' + repo }
 -       // console.log(repo)
 -       return [
 -         ['git', ['remote', 'remove', remotename], { cwd: instanceroot + '/' + repo }]
 -       ]
 -     }
 -     var x = (args) => {
 -       return () => {
 -         // console.log(args)
 -         return nodeShellExec.apply(null, args)
 -       }
 -       // return Promise.resolve(true)
 -     }
 -     var perform_git_remove = (dir) => {
 -       op['is-git-repo'](dir).then((logEntry) => {
 -         // console.log(code)
 -         if (logEntry.success) {
 -           nodeShellExec('git', ['remote', 'get-url', remotename], { cwd: dir.name, stdio: 'ignore' }).then(() => {
 -             any(serial_perform_git_remove(dir.name).map(x))
 -           })
 -             .catch((e) => {
 -               console.log('skipped : ' + dir.name + `, reason : No remote named ${remotename}`)
 -             })
 -         }
 -         // else console.log('Skipped : Not a Git Repo : ' + dir.name)
 -       }).catch((e) => {
 -         // console.log('Failed : ' + dir.name)
 -       })
 -     }
 - 
 -     const { readdir } = require("fs").promises
 - 
 -     dirs(perform_git_remove)
 -   }
 -   , 'init-gitea': (user) => {
 -     user = user || processedArgs._[1]
 -     if (!user) throw 'User name required'
 -     var serial_perform_init_gitea = (repo) => {
 -       var options = { cwd: instanceroot + '/' + repo }
 -       // console.log(repo)
 -       return [
 -         ['git', ['remote', 'add', 'chess', `${selectedinstance.reposerver}/${user}/${repo}.git`], { cwd: instanceroot + '/' + repo }]
 -         , ['git', ['remote', 'set-url', '--push', 'chess', 'no-pushing'], { cwd: instanceroot + '/' + repo }]
 -         , ['git', ['remote', 'set-url', 'origin', `${selectedinstance.reposerver}/${user}/${repo}.git`], { cwd: instanceroot + '/' + repo }]
 -       ]
 -     }
 -     var x = (args) => {
 -       return () => {
 -         // console.log(args)
 -         return nodeShellExec.apply(null, args)
 -       }
 -       // return Promise.resolve(true)
 -     }
 -     var perform_init_gitea = (dir) => {
 -       op['is-git-repo'](dir).then((logEntry) => {
 -         // console.log(code)
 -         if (logEntry.success) {
 -           nodeShellExec('git', ['remote', 'get-url', 'chess'], { cwd: dir.name, stdio: 'ignore' }).then(() => {
 -             console.log('skipped : ' + dir.name + ', reason : Already has remote chess ')
 -           })
 -             .catch((e) => {
 -               any(serial_perform_init_gitea(dir.name).map(x))
 -             })
 -         }
 -         // else console.log('Skipped : Not a Git Repo : ' + dir.name)
 -       }).catch((e) => {
 -         // console.log('Failed : ' + dir.name)
 -       })
 -     }
 - 
 -     const { readdir } = require("fs").promises
 - 
 -     dirs(perform_init_gitea)
 -   }
 -   , 'syncmaster': (label) => {
 -     // Usage :
 -     // elxr pull -- Defaults to run config
 - 
 -     var env = Object.assign({}, process.env); // Shallow clone it.
 -     // console.dir(env)
 -     console.log('Running exlr pull : ' + path.dirname(__dirname))
 - 
 -     if (!processedArgs.runas) gitRepos.map((def) => performPull(def.repo, def.branch || 'master'))
 -     if (__isElevated) {
 -       return any(elevatedRunasRepos.map((def) => performPull(def.repo, def.branch || 'master'))).then(() => {
 -         fs.writeFileSync('run.done', 'success')
 -       }).catch(() => {
 -         fs.writeFileSync('run.done', 'error')
 -       })
 -     }
 -     else return op['runas']()
 -   }
 - 
 -   , 'repo-relocate' : function(args){
 -     // relocate a subfolder in source repo to same subfolder in target repo with history. 
 - 
 -     var args = args || {
 -         remotebase : processedArgs._[4] || 'http://git.bbh/chess/'
 -       , folder : processedArgs._[3] || 'server'
 -       , sourcerepo : processedArgs._[2] || 'client'
 -       , targetrepo : processedArgs._[1] || 'elixir-server'
 -     }
 -     var sourcerepooptions = { cwd: `${instanceroot}/relocate/${args.sourcerepo}`
 -       // , stdio: ['pipe', process.stdout, process.stderr]
 -       , inherit: true,
 -         shell: true,
 -         env: process.env
 -       , runas: processedArgs.runas
 -     }
 - 
 -     return op['repo-split'](args).then(()=>{
 -       return op['repo-merge'](args).then(()=>{
 -         
 -         // cleanup folder from source.
 -         var cmdseq = [
 -             ['rm', ['-rf', `${args.folder}`], sourcerepooptions ]
 -           // commits have to intentional...
 -           // , ['git', ['commit', '-a', '-m', `relocate folder ${args.folder} to ${targetrepo}`], sourcerepooptions ]
 -         ]
 - 
 -         return any(cmdseq.map(getshelltask))
 -       })
 -     }).catch(e=>{console.error(e)})
 -   }
 - 
 -   , 'repo-split' : function(args) {
 -     
 -     // https://gist.github.com/smdabdoub/17065c348289158277b5
 -     
 -     /**
 -      * Eg : folder, remotebase, sourcerepo, targetrepo
 -      *  args.folder = 'server'
 -      *  args.remotebase = 'https://git.bbh/chess/'
 -      *  args.sourcerepo = 'client'
 -      *  args.targetrepo = 'elixir-server'
 -      */
 - 
 -     var args = args || {
 -         folder : 'server'
 -       , remotebase : 'http://git.bbh/chess/'
 -       , sourcerepo : 'client'
 -       , targetrepo : 'elixir-server'
 -     }
 - 
 -     var options = { cwd: `${instanceroot}/relocate`
 -       // , stdio: ['pipe', process.stdout, process.stderr]
 -       ,  inherit: true,
 -         shell: true,
 -         env: process.env
 -       , runas: processedArgs.runas
 -     }
 -     
 -     var cmdseq = [
 -         // create a temporary working dir in current folder where we started execution.
 -         ['mkdir', [ '-p', `${instanceroot}/relocate`]]
 -       , ['git', ['clone', `${args.remotebase}${args.sourcerepo}`], options ]
 -       , ['git', ['clone', `${args.sourcerepo}`, `relocate-${args.sourcerepo}-${args.folder}`], options]
 -       , ['git', ['clone', `${args.remotebase}${args.targetrepo}`, `relocate-${args.targetrepo}-${args.folder}`], options]
 -     ]
 -       
 -     return any(cmdseq.map(getshelltask)).then(() => { 
 -       // , ['git', ['subtree', 'split', '-P', `${args.folder}`, '-b', `relocate-${args.sourcerepo}-${args.folder}`], sourcerepooptions] 
 -         // split doesnt retain folder structure we need to move and commit ourselves through a branch to retain history... 
 -           // , ['git', [`checkout relocate-${args.sourcerepo}-${args.folder}`], sourcerepooptions] 
 -           // , ['mkdir', [`${args.folder}`], sourcerepooptions]
 -           // , ['git', ['mv', `!(${args.folder})`, `${args.folder}`], sourcerepooptions ] // requires  shopt -s extglob
 -           // , ['git', ['commit', `-m`, 'Moved to same subfolder after subtree split in branch'] , sourcerepooptions]
 -           
 -       
 -       // subtree split and filter-branch are options. We currently use repo-filter. 
 -       return  op['filter-repo'](args)
 -     }).catch(e=>{console.error(e); throw 'failed'})
 -   }
 - 
 -   , 'repo-merge' : function(args) {
 -     // Merge source repo into target repo
 -     var args = args || {
 -         folder : 'server'
 -       , remotebase : 'http://git.bbh/chess/'
 -       , sourcerepo : 'client'
 -       , targetrepo : 'elixir-server'
 -     }
 - 
 -     var sourcerepooptions = { cwd: `${instanceroot}/relocate/relocate-${args.sourcerepo}-${args.folder}`
 -       // , stdio: ['pipe', process.stdout, process.stderr]
 -       , inherit: true,
 -         shell: true,
 -         env: process.env
 -       , runas: processedArgs.runas
 -     }
 -     var targetrepooptions = { cwd: `${instanceroot}/relocate/relocate-${args.targetrepo}-${args.folder}` 
 -       // , stdio: ['pipe', process.stdout, process.stderr]
 -       , inherit: true,
 -         shell: true,
 -         env: process.env
 -       , runas: processedArgs.runas
 -     }
 - 
 -     var cmdseq = [
 -         ['git', ['pull', `../relocate-${args.sourcerepo}-${args.folder}`, `master`, '--allow-unrelated-histories'] 
 -           , targetrepooptions ]
 -       // , ['git', ['push', targetrepooptions ] // manual push for now..
 -     ]
 -     return any(cmdseq.map(getshelltask)).catch(e=>{console.error(e)})
 -   }
 - 
 -   , 'filter-repo' : function(args){
 -       // Merge source repo into target repo
 -       var args = args || {
 -           folder : 'server'
 -         , remotebase : 'http://git.bbh/chess/'
 -         , targetrepo : 'elixir-server'
 -       }
 -   
 -       var targetrepooptions = { cwd: `${instanceroot}/relocate/relocate-${args.sourcerepo}-${args.folder}` 
 -         , inherit: true, shell: true
 -         , env: process.env
 -         , runas: processedArgs.runas
 -       }
 - 
 -       var cmdseq = [
 -         // git checkout -b feature/merge-old-project
 -               // git remote add src-project ../src-project
 -         ['git', ['filter-repo', '--path', `${args.folder}`], targetrepooptions ]
 -       ]
 -       return any(cmdseq.map(getshelltask)).catch(e=>{console.error(e); throw 'failed' })
 -   }
 - 
 -   , 'filter-branch' : function(preservefolder, repo){
 -     // https://stackoverflow.com/questions/359424/detach-move-subdirectory-into-separate-git-repository
 -     // git subtree split -P <name-of-folder> -b <name-of-new-branch>
 -     // Preserve a specific folder.
 -     // PB : TODO -- filter-branch has known issues. Explore subtree and filter-repo...
 -     /*
 -     git clone repo reposplit
 -     git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter {{folder}} -- --all 
 -     git remote rm origin
 -     */
 - 
 -     throw 'filter-repo-history not yet implmented pls refer to manual commands in code.'
 -   }
 - 
 -   // , 'repo-merge-folder' : function(mergetarget, mergesource, mergefolder){
 -   //   // Merge repo2 into a subfolder in repo1
 -   //   // https://alexharv074.github.io/puppet/2017/10/04/merge-a-git-repository-and-its-history-into-a-subdirectory-of-a-second-git-repository.html
 -   //   // https://thoughts.t37.net/merging-2-different-git-repositories-without-losing-your-history-de7a06bba804
 -   //   /*
 -   //     cd repo1
 -   //     git remote add -f tempmergesource ../{{mergesource}}/.git
 -   //     git merge -s ours --no-commit tempmergesource/master --allow-unrelated-histories
 -   //     git read-tree --prefix={{mergefolder}} -u tempmergesource/master:
 -   //     git commit
 - 
 -   //     // Repair History
 -   //     // === git filter-branch --tree-filter '(echo === $GIT_COMMIT:; git ls-tree $GIT_COMMIT) >> /tmp/tree.log'
 -           
 -   //             #!/usr/bin/env bash
 - 
 -   //                       first=ed4f16becc2f03820c164e0617bb98f12ff49ef0
 -   //                       last=038e26e21bd60fa265d6637261f3bc918780d2e8
 -   //                       subdir=server
 - 
 -   //                       git filter-branch --tree-filter '
 -   //                         first='"$first"'
 -   //                         last='"$last"'
 - 
 -   //                         subdir='"$subdir"'
 -   //                         log_file=/tmp/filter.log
 - 
 -   //                         [ "$GIT_COMMIT" = "$first" ] && seen_first=true
 - 
 -   //                         if [ "$seen_first" = "true" ] && [ "$seen_last" != "true" ]; then
 -   //                           echo "=== $GIT_COMMIT: making changes"
 -   //                           files=$(git ls-tree --name-only $GIT_COMMIT)
 -   //                           mkdir -p $subdir
 -   //                           for i in $files; do
 -   //                             mv $i $subdir || echo "ERR: mv $i $subdir failed"
 -   //                           done
 -   //                         else
 -   //                           echo "=== $GIT_COMMIT: ignoring"
 -   //                         fi \
 -   //                           >> $log_file
 - 
 -   //                         [ "$GIT_COMMIT" = "$last" ] && seen_last=true
 - 
 -   //                         status=0  # tell tree-filter never to fail
 -   //                       '
 - 
 -   //     git remote rm tempmergesource
 -   //   */
 -   //   // better alternative for history
 -   //   /**
 -   //    * 
 -   //     git clone git@server.com:old-project.git
 -   //     git clone git@server.com:new-project.git
 -     
 -   //     cd old-project
 -   //     mkdir old-project
 -   //     git mv !(old-project) old-project
 -   //     ls -la and gt mv hidden files ....
 -   //     git commit -a -S -m “Moving old project into its own subdirectory”
 -     
 -   //     cd ../new-project
 -   //     git remote add old-project ../old-project
 -   //     git fetch old-project
 -   //     git checkout -b feature/merge-old-project
 -   //     git merge -S --allow-unrelated-histories old-project/master
 -   //     git push origin feature/merge-old-project
 -   //     git remote rm old-project
 -   //   */  
 - 
 -   //   throw 'merge-repos not yet implmented pls refer to manual commands in code.'
 -   // }
 - 
 -   , 'pull' : (label) => {
 -     // Usage :
 -     // elxr pull -- Defaults to run config
 - 
 -     return elxr.getpulltask(selectedinstance)()
 -   }
 -   , 'isInstalled': () => {
 -     return nodeShellExec('where', [processedArgs._[1]], { inherit: true }).then(() => {
 -       console.log(processedArgs._[1] + ' exists.')
 -       return true;
 -     });
 -   }
 -   , 'c' : ()=>{
 - 
 -   }
 -   , 'i' : () => {
 -     var tasks = []
 -     // tasks.push(op['pull']);
 -     tasks.push(getShellTask.apply(null, ['rm', [instanceroot + '/run.js'], { ignorefailures: true }]))
 -     tasks.push(op['use'])
 -     if (!__isElevated) {
 -       tasks.push(op['npmi'])
 -     }
 - 
 -     // var tasksdefs = [
 -     //     ['elxr', ['pull']]
 -     //   , ['elxr', ['use', 'elixir']]
 -     //   , ['elxr', ['npmi']]
 -     // ]
 - 
 - 
 -     // tasksdefs.forEach(tasksdef=>{
 -     //   tasks.push( ()=> nodeShellExec.apply(null, tasksdef) )
 -     // })
 - 
 -     return any(tasks);
 - 
 -   }
 -   , 'npmi': () => {
 -     var tasks = [];
 - 
 -     // Build fails without babel...
 -     tasks.push(getShellTask(
 -       'npm',[ 'i', '-g', 'babel-cli' ]
 -     ) )
 - 
 -     var npmbuildrepos = ['loopback-jsonapi-model-serializer']
 -     // npmbuildrepos = []
 -     npmbuildrepos.forEach(repo => {
 -       tasks.push(() => {
 -         return nodeShellExec('npm', ['i --force'], {
 -           inherit: true, shell: true
 -           , cwd: instanceroot + '/' + repo
 -           , env: process.env
 -           , title: `npm i for ${repo}`
 -         }).catch((e) => {
 -           console.error('Ignoring Benign Error'); console.error(e);
 -         }).then(() => {
 -           console.log(`--npm run build for ${repo}--------------------`)
 -           return nodeShellExec('npm', ['run build'], {
 -             inherit: true, shell: true
 -             , cwd: instanceroot + '/' + repo
 -             , env: process.env
 -             , title: `npm run build for ${repo}`
 -           }).then(Tasq.then).catch(Tasq.catch)
 -         })
 -       })
 -     })
 - 
 -     return any(tasks).then(() => {
 - 
 -       gitRepos.push('chess-server-lib/server');
 -       gitRepos = gitRepos.concat(elevatedRunasRepos);
 - 
 -       // gitRepos = [
 -       //   // 'bbhverse', 'serververse', 'elixir-server', 
 -       //   // 'clientverse', 
 -       //   'client'
 -       // ];
 -       var rmtasks = []
 -       var repotasks = []
 -       var env = Object.assign({}, process.env)
 -       delete env.NODE_ENV
 -       gitRepos.forEach(repodef => {
 -         rmtasks.push(
 -           // () => {
 -             // console.log(`--rm package-lock.json for ${repodef.repo}--------------------`)
 -             // return nodeShellExec(`"${gitbash}"`, ['-c', '"rm  package-lock.json"'], {
 -             callshelltask(['rm', ['package-lock.json'], {
 -               inherit: true, shell: true
 -               , cwd: instanceroot + '/' + repodef.repo
 -               , env: process.env
 -               , title: `rm 'package-lock.json' for ${repodef.repo}`
 -             }])
 -             .then(()=>{
 -               console.log(`--rm package-lock.json for ${repodef.repo}--------------------`)
 -             }).catch((e) => { console.error(e) })
 -           // }
 -         )
 - 
 -         if (npmbuildrepos.indexOf(repodef.repo) < 0) {
 -           repotasks.push(
 -             () => {
 -               console.log(`--npm i for ${repodef.repo}--------------------`)
 -               var p = nodeShellExec('npm', ['i', '--force'], {
 -                 inherit: true, shell: true
 -                 , cwd: instanceroot + '/' + repodef.repo
 -                 , env
 -                 , title: `npm i for ${repodef.repo}`
 -               }).then(Tasq.then).catch(Tasq.catch)  
 -               return p;
 -             })
 -         }
 -       })
 - 
 - 
 -       // PB : NOTE -- npm i for client does not complete when NODE_ENV=production 
 -       // therefore bower doesn't get installed !!! which then fails installing the bower dependenciew !!!
 -       // We work around this by running npm i for client without any NODE_ENV which probably defualts to development.
 -       // PB : TODO -- Investigate why NODE_ENF has an impact on npm i !??
 -       // Second time try also doesnt work.
 -       // repotasks.push(
 -       //   () => {
 -       //     var env = Object.assign({}, process.env)
 -       //     delete env.NODE_ENV
 -       //     console.log(`--------------------second time npm i for client--------------------`)
 -       //     return nodeShellExec(`"${gitbash}"`, ['-c', '"npm i --force"'], {
 -       //     // return nodeShellExec('npm', ['i --force'], {
 -       //       inherit: true, shell: true
 -       //       , cwd: instanceroot + '/' + 'client'
 -       //       , env
 -       //       , title: `npm i for client`
 -       //     }).then(Tasq.then).catch(Tasq.catch)
 -       //   })
 - 
 -       var bowerRepos = [{ repo : 'client'}]
 -       bowerRepos.forEach(repodef => {
 -         repotasks.push(() => {
 -           console.log(instanceroot + '/' + repodef.repo + '/node_modules/bower/bin/bower')
 -           // var p = nodeShellExec('node_modules/bower/bin/bower', ['install'], {
 -           var p = nodeShellExec(`"${gitbash}"`, ['-c', '"node_modules/bower/bin/bower i"'], {
 - 
 -             inherit: true, shell: true
 -             , cwd: instanceroot + '/' + repodef.repo
 -             , env: process.env
 -             , title: `bower i for ${repodef.repo}`
 -           }).then(Tasq.then).catch(Tasq.catch)
 -           return p;
 -         })
 -       })
 -       // console.log('rmtasks.length : ' + rmtasks.length)
 -       return Promise.all(rmtasks).then(() => any(repotasks));
 -     }).catch(e => {
 -       console.error(e)
 -     }).finally(statuslog.finally)
 - 
 -   }
 -   , 'start': (label) => {
 -     console.log('Starting Elixir Server.');
 -     var env = Object.assign({}, process.env); // Shallow clone it.
 -     // console.dir(env)
 -     env.NODE_ENV = process.env.NODE_ENV || 'development';
 -     env.DEBUG = 'loopback:connector:' + dbForLabel(label)
 -     var cmd = env.NODE_ENV === 'development' ? 'nodemon' : 'node';
 -     // cmd = 'node'
 -     cmd = [cmd, ['--inspect=9228', 'elixir/server.js']]
 -     var childPromise = nodeShellExec(...cmd, {
 -       // inherit : true,
 -       shell: true,
 -       detached: true,
 -       stdio: 'ignore',
 -       cwd: instanceroot + '/' + 'elixir-server'
 -       , env: env
 -     })
 - 
 -     var child = childPromise.process;
 -     if (typeof child.pid !== 'undefined') {
 -       console.log(`started Elixir Server PID(${child.pid}) : NODE_ENV=${process.NODE_ENV} ${cmd}`);
 -       fs.writeFileSync('.elixir-server.elixir.server.pid', child.pid, {
 -         encoding: 'utf8'
 -       })
 -     }
 - 
 -     // nodeShellExec('node', ['--inspect=9226', ' bin/www'], {
 -     //   inherit : true, 
 -     //   shell: true, detached: true,
 -     //   cwd : 'qms/server',
 -     //   env: env,
 -     //   shell : true
 -     // })
 - 
 -     // nodeShellExec('ember', ['s'], {
 -     //   // inherit : true, 
 -     //   shell: true, detached: true,
 -     //   cwd : 'client/',
 -     //   env: env
 -     // })
 -     console.log('Starting Elixir Client Host.');
 -     var cmd = ['ember', ['s']]
 -     var childPromise = nodeShellExec(...cmd, {
 -       // var childPromise = nodeShellExec('node', ['--inspect=9227', './node_modules/.bin/ember', 's'], {
 -       // PB : TODO -- ember debugging.
 -       // inherit : true,
 -       shell: true,
 -       detached: true,
 -       stdio: 'ignore',
 -       cwd: instanceroot + '/' + 'client'
 -       , env: env
 -     })
 -     // .catch(e=>console.error(e))
 - 
 -     child = childPromise.process;
 -     if (typeof child.pid !== 'undefined') {
 -       console.log(`started Elixir Client Host PID(${child.pid}) : NODE_ENV=${process.NODE_ENV} ${cmd}`);
 -       fs.writeFileSync('.client.server.pid', child.pid, {
 -         encoding: 'utf8'
 -       })
 -     }
 - 
 -   }
 -   , 'stop': (label) => {
 -     const kill = require('tree-kill');
 - 
 -     var serverPid = fs.readFileSync('.elixir-server.elixir.server.pid', {
 -       encoding: 'utf8'
 -     })
 -     fs.unlinkSync('.elixir-server.elixir.server.pid')
 -     console.log(serverPid)
 -     kill(serverPid)
 - 
 -     serverPid = fs.readFileSync('.client.server.pid', {
 -       encoding: 'utf8'
 -     })
 -     fs.unlinkSync('.client.server.pid')
 -     console.log(serverPid)
 -     kill(serverPid)
 -   }
 -   , 'model' : () => {
 -     if (__isElevated) { 
 -       var tasks = [
 -         () => {
 -           var p = nodeShellExec('mklink', [ `${processedArgs._[2]}.json`
 -               , `..\\..\\node_modules\\chess-server-lib\\common\\models\\${processedArgs._[2]}.json`], {
 -             inherit: true, shell: true
 -             , cwd : instanceroot + `/${selectedinstance.instanceName}-server/${selectedinstance.instanceName}/models`
 -             , title: `mklink  ${processedArgs._[2]}.json ..\\..\\node_modules\\chess-server-lib\\common\\models\\${processedArgs._[2]}.json`
 -             , env: process.env
 -           }).catch((e) => { console.error(e) })
 -           return p;
 -         }
 -       ];
 -       return any(tasks).then(() => {
 -         fs.writeFileSync('run.done', 'success')
 -       }).catch(() => {
 -         fs.writeFileSync('run.done', 'error')
 -       })
 -     }
 -     else return op['runas']()
 -   }
 -   , 'use' : () => {
 -     // use a certain named instance.
 -     //  Eg : 
 -     // 1) elxr use elixir
 -     // 2) elxr use cihsr
 -     // If environment is not specified defaults to development.
 -     // 1) NODE=test elxr use elixir
 - 
 -     /*// Steps
 -     1) Delete Config and Data symlinks
 -     2) Make Links for config ({{name}}-config-{{node_env}}) and data with the NODE_ENV specified or default to dev 
 -     3) Iterates all repos and pull all. 'git', ['pull', '--all'].
 -     4) Iterates all repos and checkout to the ENV specified. 'git', ['checkout', checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV]
 -     5) Iterates all repos and merge from source configured in mergesource. 'git', ['merge', mergesource],
 -     */
 -     var runconfig = { NODE_ENV: selectedinstance.node_env }
 -     try { runconfig = Object.assign(runconfig, require(instanceroot + '/run.js')) } catch (e) { }
 -     // We no longer need to check ruans.. ??? if we were initiated from self invoked privileged shell ?
 -     if (( /*processedArgs.runas && processedArgs.runas !== 'self' &&*/ !processedArgs.force) &&
 -       runconfig.NODE_ENV && runconfig.NODE_ENV === (selectedinstance.node_env || runconfig.NODE_ENV) &&
 -       selectedinstance.instanceName && runconfig.use === selectedinstance.instanceName) {
 - 
 -       console.log(`No change detected. Already using requested specs : ${runconfig.NODE_ENV} ${runconfig.use}`)
 -       if (processedArgs.runas) { fs.writeFileSync('run.done', 'success') }
 -       if (existsSync('config') && existsSync('data')){
 -         return
 -       }
 -     }
 - 
 -     var tasks = [
 -       () => {
 -         if (existsSync('config')) {
 -           var p = nodeShellExec('rmdir', ['config'], { inherit: true, shell: true, env: process.env }
 -           ).catch((err) => { console.log('Ignoring benign error : ' + err); return true; })
 -           return p;
 -         }
 -         else return Promise.resolve(true);
 -       },
 -       () => {
 -         if (existsSync('data')) {
 -           var p = nodeShellExec('rmdir', ['data'], { inherit: true, shell: true, env: process.env }
 -           ).catch((err) => { console.log('Ignoring benign error : ' + err); return true; })
 -           return p;
 -         }
 -         else return Promise.resolve(true);
 -       },
 -     ];
 -     runconfig.NODE_ENV = process.env.NODE_ENV = process.env.NODE_ENV || runconfig.NODE_ENV || 'development';
 -     if (processedArgs._[1] && runconfig.use !== processedArgs._[1]) runconfig.use = processedArgs._[1];
 -     if (!runconfig.use) { throw 'unspecifed use not allowed. Please specify chess instance name.' }
 -     // console.log(process.env.cwd)
 -     fs.writeFileSync(instanceroot + '/run.js', 'module.exports = ' + JSON.stringify(runconfig))
 - 
 -     // Maps an environment to a branch. Not required if the branch is appropriately named.
 -     var checkoutMap = { 'development': 'master' }
 - 
 -     var branch = checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV
 -     
 -     var performPullOrCloneForBranch = (def)=>{
 -       var promise = Promise.resolve(true)
 -       if (!branch) {
 -         var dscoverbranchcmd = gitops.getdiscoverbranchcmd(repo)
 -         
 -         promise = nodeShellExec.apply(null, dscoverbranchcmd).then(__branch=>{ branch = __branch})
 -           .catch((e) => { console.error(e); return { error: true, message: repo } })
 -   
 -       }
 -         
 -       return promise = promise.then(()=>{ return elxr.getpulltask(def)() }).catch(e => { console.error( 'performPullOrCloneForBranch : Failed ' + e )})
 -     }
 - 
 -     var performCloneAndCheckout = null;
 -     // cant use git checkout -b it fails when branch already exists.
 -     var performCheckout = performCloneAndCheckout = (def) => {if (excludeCheckouts[def.repo]) return Promise.resolve({ 'skipped': true })
 -       
 -       return performPullOrCloneForBranch(def).then(()=>{
 -         nodeShellExec('git', ['checkout', def.branch || checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV], {
 -           // return nodeShellExec('git', ['switch', '-m', '-C', checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV], {
 -           // inherit : true, shell: true, 
 -           cwd: instanceroot + '/' + def.repo
 -           // , stdio : ignore // Use when we want to silence output completely.
 -           , runas: processedArgs.runas
 -           , title: `git checkout ${def.branch || checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV} for ${def.repo}`
 -         }).then(()=>{ console.log( `SUCCESS : git checkout ${def.branch || checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV} for ${def.repo}` ) }).catch((e) => { console.error(e); return { error: true, message: def.repo } })
 -       })
 -     }
 - 
 -     // var enqueueCheckout = function(def){ enqueue(elevatedqueue, performCheckout, def) }
 -     // var enqueueMerge = function(def){ enqueue(elevatedqueue, performMerge, def) }
 - 
 -     var elevatedqueue = [];
 -     var enqueueOnce = (queue, task, def) => {
 -       var found = queue.find(element => { 
 -         var keys = Object.keys( element ) 
 -         for(var k=0; k < keys.length; k++) { 
 -           if(element[keys[k]] !== def[k]) return false;
 -         } 
 -       })
 -       queue.push(function(){ return task(this)}.bind(def));
 -     }
 -     var enqueue = (queue, task, def) => {
 -       queue.push(function(){ return task(def)}.bind(def));
 -     }
 - 
 -     var mergeSources = {
 -       'development': null,
 -       'test': 'master',
 -       'production': 'master'
 -     }
 -     var mergesource = mergeSources[checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV]
 - 
 -     // Checkout is reduced to pull provided the current branch is the targetbranch 
 -     if(branch === mergesource) performCheckout = (def) => {   
 -       var dscoverbranchcmd = gitops.getdiscoverbranchcmd(repo)
 -       return nodeShellExec.apply(null, dscoverbranchcmd).then(__branch=>{ 
 -         
 -         if(branch === __branch) return performCloneAndCheckout(def)
 -         return performPullOrCloneForBranch(def) 
 -       })
 -       .catch((e) => { console.error(e); return { error: true, message: repo } })
 -     }
 -     // else performCheckout = (def) => { return performPullOrCloneForBranch(def) }
 - 
 -     var performPullAll = (def) => {
 -       if (excludeCheckouts[def.repo]) return Promise.resolve({ 'skipped': true })
 -       return nodeShellExec('git', ['pull', '--all'], {
 -         // inherit : true, shell: true, 
 -         cwd: instanceroot + '/' + def.repo
 -         , runas: processedArgs.runas
 -         , title: `git pull -all for ${checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV} ${def.repo}`
 -       }).catch((e) => { console.error(e); return { error: true, message: def.repo } })
 -     }
 -     
 -     var excludeCheckouts = Object.assign(exludeMergeRepos)
 -     delete excludeCheckouts[`elixir-config-${runconfig.NODE_ENV}`]
 -     delete excludeCheckouts[`cihsr-config-${runconfig.NODE_ENV}`]
 - 
 -     var performMerge = (def) => {
 -       if (exludeMergeRepos[def.repo]) return Promise.resolve({ 'skipped': true })
 -       return nodeShellExec('git', ['merge', mergesource], {
 -         inherit: true, shell: true,
 -         cwd: instanceroot + '/' + def.repo
 -         , runas: processedArgs.runas
 -       }).catch((e) => { console.error(e) })
 -     }
 -     if(!mergesource || branch === mergesource) performMerge = () => { return Promise.resolve(true) }
 - 
 -     // var performRepoOperation = function(def) {
 -     //   elevatedRunasRepos.map((repo) => enqueueCheckout({ repo, branch: def.branch, requiresElevation : true }))
 -     //   return any(gitRepos.map((repo) => performCheckout({ repo, branch: def.branch})))
 -     // }
 - 
 -     return any(tasks).then(() => {
 -       var pr = Promise.resolve(true)
 -       if (!__isElevated)  {
 -         pr = op['runas']()
 -         return pr.then(()=>{
 - 
 -           //target is the env is we specify in elxr use command. Default is dev
 -             //Switch to target branch
 -           return any(gitRepos.map((repodef) => { return performCheckout({ repo : repodef.repo, branch}).catch(e=>{ console.log(e); }) }   ))
 -           // pull or clone target branch
 -           .then(() => {
 -             if(!mergesource || branch === mergesource) return Promise.resolve(true)
 -             return any(gitRepos.map((repo) => performPullAll(repo))) 
 -           })
 -           // switch to source branch
 -           .then( () => {
 -               if(!mergesource || branch === mergesource ) return Promise.resolve(true)  // Dont do anything if there is no source to merge from.
 -               return any(gitRepos.map((repodef) => performCheckout({ repo : repodef.repo, branch: mergesource}))) 
 -           })
 -           //Pull on merge source branch
 -           .then( () => {
 -               if(!mergesource || branch === mergesource ) return Promise.resolve(true)
 -               return any(gitRepos.map((repo) => performPullAll(repo)))
 -             })
 -           //Switch to target branch
 -           .then( () => { 
 -             if(!mergesource || branch === mergesource ) return Promise.resolve(true)
 -             return any(gitRepos.map((repodef) => performCheckout({ repo : repodef.repo, branch}))) 
 -           })
 -           .then( //Merge source branch to target branch
 -             () => {
 -               if(!mergesource || branch === mergesource) return Promise.resolve(true)
 -               return any(gitRepos.map((repo) => performMerge( repo ))).catch(err => { console.error('error in performMerge ' + err) })
 -             })
 -         })
 -       }
 -       else {
 -         tasks = [
 -           () => {
 -             // Use junctions to avoid npm package issues
 -             var p = nodeShellExec('mklink', ['/J', 'config', runconfig.use + '-config' + '-' + process.env.NODE_ENV], {
 -               inherit: true, shell: true
 -               , cwd : instanceroot
 -               , env: process.env
 -             }).catch((e) => { console.error(e) })
 -             return p;
 -           }
 -         ];
 -         if (processedArgs._[1]) {
 -           tasks = tasks.concat(
 -             [
 -               () => {
 -                 var p = nodeShellExec('mklink', ['/J', 'data', runconfig.use + '-data'], {
 -                   inherit: true, shell: true
 -                   , cwd : instanceroot
 -                   , env: process.env
 -                 }).catch((e) => { console.error(e) })
 -                 return p;
 -               }
 -             ]
 -           )
 -         }
 -   
 -         return any(tasks).then(()=>{
 -               // checkout target branch
 -           return any(elevatedRunasRepos.map((repodef) => performCheckout({ repo : repodef.repo, branch, requiresElevation : true}))) 
 -             // pull or clone target branch
 -             .then(() => {
 -               if(!mergesource || branch === mergesource) return Promise.resolve(true)
 -               return any(elevatedRunasRepos.map((repo) => performPullAll(repo))) 
 -             })
 -             // switch to source branch
 -             .then( () => {
 -               if(!mergesource || branch === mergesource) return Promise.resolve(true)
 -               return any(elevatedRunasRepos.map((repodef) => performCheckout({ repo : repodef.repo, branch: mergesource, requiresElevation : true}))) 
 -             })
 -             //Pull on merge source branch
 -             .then( () => {
 -               if(!mergesource || branch === mergesource) return Promise.resolve(true)
 -                 return any(elevatedRunasRepos.map((repodef) => performPullAll({repo : repodef.repo, requiresElevation : true })))
 -               })
 -             //Switch to target branch
 -             .then( () => { 
 -               if(!mergesource || branch === mergesource) return Promise.resolve(true)
 -               return any(elevatedRunasRepos.map((repodef) => performCheckout({ repo : repodef.repo, branch, requiresElevation : true}))) 
 -             })
 -             .then( //Merge source branch to target branch
 -               () => {
 -                 if(!mergesource || branch === mergesource) return Promise.resolve(true)
 -                 return any(elevatedRunasRepos.map((repodef) => performMerge({ repo : repodef.repo, requiresElevation : true }))).catch(err => { console.error('error in performMerge ' + err) })
 -             })
 -             .then(() => {
 -               fs.writeFileSync('run.done', 'success')
 -             }).catch(() => {
 -               fs.writeFileSync('run.done', 'error')
 -             })
 -         })
 -       }
 - 
 -     }).catch(() => {
 -       fs.writeFileSync('run.done', 'error')
 -     })
 - 
 -     // Antibiotic stewardship program.
 -     // 1st use is fine.
 -     // Max vials dispense
 -     // 2nd use Pharmacy needs justification Form.
 -     // Approval after a certain period of time.
 -   }
 -   , 'g': () => {
 -     if (processedArgs.h) {
 - 
 -       console.log('elxr g [modelname] => generate a model named [modelname]');
 -       console.log('elxr g => regenerate all known models');
 -       return
 -     }
 -     // var child = nodeShellExec('mkdir', ['-p', label], { inherit : true} );
 -     // console.log('Starting directory: ' + process.cwd());
 -     // try {
 -     //     child = child.on('close', () => { process.chdir(label) } );
 -     //     console.log('New directory: ' + process.cwd()); 
 -     // }
 -     // catch (err) {
 -     //     console.log('chdir: ' + err);
 -     // }
 -     // child.on('close', function(){
 -     // var options = {
 -     //       shell : true 
 -     //     , inherit : true
 -     //     // , cwd : '' + process.cwd
 -     //     // , env : process.env
 -     // };
 -     // nodeShellExec('git', ['init'], { inherit : true});
 -     if (0) {
 -       // PB : TODO -- Special google chrome profile for tests etc.
 -       nodeShellExec('pwd', { inherit: true });
 -       // /c/Program\ Files\ \(x86\)/Google/Chrome/Application/chrome.exe --user-data-dir=/c/chess/instances/elixir_01/data/Google/Chrome/User\ Data --profile-directory="chess"
 -       // "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --user-data-dir="C:\chess\instances\elixir_01\data\Google\Chrome\User Data" --profile-directory="chess" http://localhost:4200/admin/crud/create/item
 -       // "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --user-data-dir="C:\chess\instances\elixir_01\data\Google\Chrome\User Data" --profile-directory="chess" http://localhost:4200/tests/index.html?grep=loopback
 -       nodeShellExec("C:/Program Files (x86)/Google/Chrome/Application/chrome.exe", [
 -         "--profile-directory=Profile 1"
 -         , 'http://localhost:4200/tests/index.html?grep=model convert ember to loopback' + '&filter=none' /*+ '&filter=model convert ember to loopback'*/]);
 - 
 -     }
 -     // nodeShellExec('npm', ['init', '-y'], options);
 -     // nodeShellExec('npm', ['init', '-y'], options);
 -     // })
 - 
 -     var g = {
 -       'client': () => {
 -         // ember new --skip-bower --no-welcome --skip-git -b {{blueprint}} 
 - 
 -         console.info('Creating new ember client named : ' + processedArgs._[2]);
 -         var step1 = nodeShellExec('cmd', ['/c', 'ember', 'new', processedArgs._[2]], {
 -           stdio: ['pipe', process.stdout, process.stderr],
 -           inherit: true,
 -           shell: true,
 -           cwd: path.dirname(__dirname),
 -           env: env
 -         })
 -       },
 - 
 -       'modelr': () => {
 -         var tasks = [
 -           () => {
 -             var p = nodeShellExec('"ember"', [
 -               'g'
 -               , 'modelr'
 -               , processedArgs._[2]], {
 -               inherit: true, shell: true, env: process.env
 -             }).then(() => {
 -               console.log('Blueprint generation complete for : ' + processedArgs._[2])
 -               return true;
 -             }).catch((e) => { console.error(e) })
 -             return p;
 -           },
 -           () => {
 -             var chromePrefsFile = "C:\\chess\\instances\\elixir_01\\data\\Google\\Chrome\\User Data\\chess\\Preferences";
 -             var chromeprefs = fs.readFileSync(chromePrefsFile, { encoding: 'utf8' })
 -             chromeprefs = JSON.parse(chromeprefs)
 -             var previous = chromeprefs.download.default_directory;
 -             var parentDir = path.dirname(__dirname);
 -             chromeprefs.download.default_directory = parentDir + "\\client\\app\\templates\\components\\resource";
 -             fs.writeFileSync(chromePrefsFile, JSON.stringify(chromeprefs))
 -             // PB : TODO -- detect where chrome is installed.
 -             // PB : TODO -- set the download dir to the place where files are needed.
 -             var p = nodeShellExec('"C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"', [
 -               '--user-data-dir="C:\\chess\\instances\\elixir_01\\data\\Google\\Chrome\\User Data"'
 -               , '--profile-directory="chess"'
 -               , 'http://localhost:4200/admin/crud/create/' + processedArgs._[2]], {
 -               inherit: true, shell: true
 -               , env: process.env
 -             }).then(() => {
 -               chromeprefs.download.default_directory = previous;
 -               fs.writeFileSync(chromePrefsFile, JSON.stringify(chromeprefs))
 -               return true;
 -             }).catch((e) => { console.error(e) })
 -             return p;
 -           }
 -           ,
 -           () => {
 -             console.log('Browser process should have closed here....')
 -             return true;
 -           }
 -         ]
 -         any(tasks)
 - 
 -       }
 - 
 -     }
 - 
 -     g[processedArgs._[1]]();
 -   }
 - 
 -   , 'create' : () => { 
 -     return createInstance(selectedinstance) }
 - 
 -   , 'httpget' : () => {
 -     // RESTAPI.get({
 -     //   hostname: 'git.bbh',
 -     //   // port: 443,
 -     //   protocol : 'http:',
 -     //   path: '/',
 -     //   method: 'GET'
 -     // }, function(data){ console.log(data)}, function(error){ console.log(error)} )
 -     return createInstance(selectedinstance)
 -   }
 - 
 -   , 'getuser' : ()=>{
 -     return prerequisites.git.getuser().then(u=>{ console.log(u)})
 -   }
 - 
 -   , 'switch user' : (tousername)=>{
 -     return GIT['switch user'](tousername)
 -   }
 - }
 - 
 - var util = require('util');
 - var cliname = 'elxr';
 - var ver = '1.1';
 - var readme = `
 -   Command syntax examples
 - 
 -   elxr
 -     Displays help. Same as elxr h
 - 
 -   elxr i
 -     Runs interactive propmts to help choose installation options.
 - 
 -   NODE_ENV={{yourenvironment}} elxr {{cmd}} {{instancename}} {{otheroptions}}
 -     General command syntax.
 -     Eg: NODE_ENV=development elxr pull elixir
 - 
 -     Note : Although {{instancename}} is generally a positional parameter supplied immediately after the cmd for most cmd's. 
 -       The specific cmd defines what the value is interpreted as.
 -       There are several cmds that do not require an {{instancename}} parameter.
 -         Eg: elxr remote remove origin 
 -           Git operations or passthrough external commands on all repository folders in you working directory.
 - 
 -   Main objectives.
 -     elxr cli is a wrapper around other shell commands and api based operations.
 -     One of the main objetives it achives is ease of use of repeating an individual cmd multiple times on all targets.
 -       Eg: A git operation like pull can be repeated consistently on a set of git repositories.
 -   
 - `;
 - var help = `
 -   ${readme}
 - 
 - 
 -   # list of commands... please refer dveloper documentation for ${cliname}
 -   \r\n\t${
 -     Object.keys(op).join('\r\n\t')
 -   }
 - `;
 - 
 - var elxr = {
 -   help() {
 -     return chalk.cyanBright(`
 - -------------------------------------------------------------------------------
 -   *** BBH Elixir ***  
 - -------------------------------------------------------------------------------
 -   elxr ${ver}
 -     A cli tool for chess
 -     ${help}
 - -------------------------------------------------------------------------------
 -     `)
 -   }
 -   , info() {
 -     return chalk.cyanBright(`
 - -------------------------------------------------------------------------------
 -   *** BBH Elixir ***  
 - -------------------------------------------------------------------------------
 -   elxr ${ver}
 -     A cli tool for chess
 - -------------------------------------------------------------------------------
 -   `)
 -   }
 -   , getpulltask(args){
 - 
 -     // def can be an instance config
 -     // Or an object with many repos and elevated repos
 -     // Or a single repo ( Either Elevated or normal. )
 - 
 -     
 -     // USAGE
 -     // elxr pull elixir origin master
 -     // elxr pull
 - 
 -     // not all remote branches are setup to be tracked locally (respective remotes and branches). 
 -     // pull --all is useless. As it fetches all remotes and branches but only merges current branch.  
 -     // apart from remote tracking branches We are interested in pulling from all remotes and relavant branches.
 -       // The branch pipline should feed back to master
 -       //   master -> test -> stage -> release[nnnn] -> production
 -       //   (master) <= git merge [all remotes] production && git merge [all remotes] release[nnnn]
 -             // git merge [all remotes] stage && git merge [all remotes] test  && git merge [all remotes] master 
 - 
 -     var __args = {
 -         remotename : args.remotename|| processedArgs._[2]
 -       , url : args.url || processedArgs._[3]
 -       , branch : args.branch || processedArgs._[4]  // If branch not specified opearte on the current branch of each working directorys
 -     }
 - 
 -     // var commands = [
 -     //     // ['git', ['checkout', __args.branch || checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV]]
 -     //   , 
 -     // ]
 - 
 -     // var parameters = ['-c', 'for i in `git remote`; do git pull $i ' + branch + '; done;']
 -     // var pullCmd = [ gitbash
 -     //   , ['-c', 'for i in `git remote`; do git pull $i ' + branch + '; done;']
 -     //   , { cwd: instanceroot + '/' + repo, title : 'pull all remotes for ' + branch + '  ' + repo + ' ' + parameters.join(' ') }]
 - 
 - 
 - 
 -     var def = args || {
 -       repos : selectedinstance.repos,
 -       elevated : selectedinstance.elevated
 -     }
 - 
 -     var elevatedpulltasks = null;
 -     if(def.repo) {
 -       // Single repo case.
 -       if(def.repo.requiresElevation) {
 -         elevatedpulltasks = function() {
 -           return performPull(def.repo).then(() => {
 -             return true;
 -           }).catch((e) => {
 -             console.error(e) 
 -           })
 -         }
 -         return 
 -       }
 -       else {
 -         var regularpulltasks = function(){
 -           var pendingpulls = [];
 -           pendingpulls.push(performPull(def.repo))
 -           return Promise.all(pendingpulls).finally(Traq.finally)
 -         }
 -       }
 -       if(elevatedpulltasks) return getTaskWithElevation( { elevatedpulltasks, regularpulltasks} )
 -       else return getTaskWithoutElevation({ regularpulltasks}) 
 -     }
 -     
 -     // console.log(`-------------------Processing pull for : ${def.repo} ${def.branch}`)
 -     console.dir(def)
 - 
 -     var env = Object.assign({}, process.env); // Shallow clone it.
 -     console.log('Running exlr pull : ' + path.dirname(__dirname))
 - 
 -     var useGitPull = processedArgs.useGitPull || false;
 - 
 -     if(def.elevated || def.repos) {
 -       if(def.elevated) def.requiresElevation = true;
 -       else delete def.requiresElevation;
 -     }
 -     else {
 -       if(def.requiresElevation) def.elevated = [def] 
 -       else def.repos = [def] 
 -     }
 - 
 -     
 -     var regularpulltasks = function(){ return Promise.resolve(true) }
 -     if(def.elevated){
 -       elevatedpulltasks = function() {
 -         return any(def.elevated.map((def) => performPull(def.repo))).then(() => {
 -           return true;
 -         }).catch((e) => {
 -           console.error(e) 
 -         })
 -       }
 -     }
 -     if(def.repos) {
 -       var regularpulltasks = function(){
 -         var pendingpulls = [];
 -         def.repos.forEach((def) => { pendingpulls.push(performPull(def.repo)) })
 -         return Promise.all(pendingpulls).finally(Traq.finally)
 -       }
 -     }
 -     if(elevatedpulltasks) return getTaskWithElevation( { elevatedpulltasks, regularpulltasks} )
 -     else return getTaskWithoutElevation({ regularpulltasks})
 -   }
 - }
 - 
 - function preworkerconfig(){
 -     // Everything runs after this check is completed. Elevation occurs out of process when needed.
 -     gitRepos = selectedinstance.repos
 -     // gitRepos = ['chess-server-lib'];
 -   
 -     // Repositiories that have symlinks that require elevated priviletes in windows to create symlinks
 -     elevatedRunasRepos = selectedinstance.elevated
 -     // Repos that should excluded from merge for releases...
 -     exludeMergeRepos = selectedinstance.exludeMergeRepos  
 - 
 -     // mysqldump --add-drop-table --no-data -u root -p db_name | grep 'DROP TABLE' ) > drop_all_tables.sql
 -     // mysql -u root -p db_name < drop_all_tables.sql
 - 
 -     var mysql = '../xampp/mysql/bin/mysql'
 -     var mysqldump = '../xampp/mysql/bin/mysqldump'
 - }
 - 
 - 
 - // The main elxr cli process
 - function elxrworker() {
 - 
 -   var __runcmd = function (label) {
 -     var distinquishedlabel = subcommandlabels[label] || label
 -     return op[distinquishedlabel] ? op[distinquishedlabel](processedArgs) : null;
 -   }
 - 
 - 
 -   // --runas
 -   if (processedArgs.runas) {
 -     // Weve been asked to run in priviledged mode. Check if we already are privileged.
 -     return __runcmd('runas')
 -   }
 -   else return __runcmd(processedArgs.label || processedArgs._[0] || 'undefined');
 - }
 - 
 - // function acquireChoices(selectedinstance) {
 - 
 - //   var hasconfig = false;
 - //   console.warn(chalk.cyan(`
 - // -------------------------------------------------------------------------------
 - // Could not locate your preferred configuration (you may not specified it)
 - // You should fork the default chess configuration to customize and make it 
 - // your own instance with a named config as 
 - //   {{yourowninstancename}}-config-{{yourchosenenvironment}} 
 - // And then run this tool as follows
 - //   NODE_ENV={{yourchosenenvironment}} elxr i {{yourowninstancename}} 
 - // OR
 - // Run this tool with the following command to use a quick start default.
 - //   elxr --default
 - // OR
 - // Choose one of the options below to run interactively.
 - 
 - // We will run your choice at the next prompt.
 - // -------------------------------------------------------------------------------
 - //   `))
 - 
 - //   var choices = getInteractionPoints(detectedinstanceoptions, __interactive_prompts) 
 - //   var todo = any( __interactive_prompts(selectedinstance, choices)  ).then(()=>{ 
 - //     return initinstances(selectedinstance)
 - //   })
 - 
 - //   // var prompt = cli.prompter;
 - //   // return prompt.ask(`Choose an option :
 - //   //     d) Install the default chess instance. 
 - //   //         => elxr i chess node_env=development --default
 - //   //     n) Create your custom new instance interactively
 - //   //         => elxr i {{instanceName}} node_env={{environment}}
 - //   //     i) Choose an instance and environment to install
 - //   //         => elxr i {{instanceName}} node_env={{environment}}
 - //   //     c) Choose a command to run ( pull, use, i, npmi ... ) <= pull
 - //   //         => elxr {{cmd}} {{instanceName}} node_env={{environment}}
 - //   //     h) Help
 - //   //     q) Quit
 - //   //       Default <= d
 - //   //   : `).then((choice) => {
 - //   //   if (choice && choice === 'd' || !choice) {
 - //   //     processedArgs._[0] = 'i'
 - //   //     selectedinstance.instanceName = processedArgs._[1] = processedArgs._[1] || 'chess'
 - //   //     selectedinstance.node_env = processedArgs.node_env = (process.env.NODE_ENV && process.env.NODE_ENV.trim()) || processedArgs.node_env || 'development'
 - //   //     selectedinstance.reposerver = 'https://git.bbh.org.in'
 - //   //   }
 - //   //   else if (choice === 'h') {
 - //   //     processedArgs._[0] = 'h'
 - //   //     fs.writeFileSync('run.done', 'noop help');
 - //   //     console.log(elxr.help()); process.exit()
 - //   //   }
 - //   //   else if (choice === 'n' || choice === 'i') {
 - //   //     var p1 = cli.prompter;
 - //   //     return p1.ask(`Enter Instance Name ( <= ${selectedinstance.instanceName} ) : `).then(function (instanceName) {
 - //   //       processedArgs._[0] = 'i'
 - //   //       selectedinstance.instanceName = processedArgs._[1] = instanceName || selectedinstance.instanceName;
 - //   //       return p1.ask(`Enter Environment ( <= ${selectedinstance.node_env} ) : `).then(function (node_env) {
 - //   //         selectedinstance.node_env = processedArgs.node_env = node_env || selectedinstance.node_env
 - //   //         if (choice === 'n') {
 - //   //           selectedinstance.reposerver = 'https://git.bbh.org.in'
 - //   //           console.warn(
 - //   //             chalk.magenta('No Option Available. Your account may not have privileges. You can request here http://git.bbh.org.in/chess'))
 - //   //           process.exit();
 - //   //         }
 - 
 - //   //         return p1.ask(`Enter preferred repo server ( <= ${selectedinstance.reposerver || selectedinstance.reposervers[0]} ) : `).then(function (reposerver) {
 - //   //           selectedinstance.reposerver = reposerver || selectedinstance.reposervers[0] || 'https://git.bbh.org.in'
 - //   //         })
 - //   //       })
 - //   //     })
 - //   //   } else if (choice === 'c') {
 - //   //     var p1 = cli.prompter;
 - //   //     return p1.ask(`Enter Instance Name ( <= ${selectedinstance.instanceName} ) : `).then(function (instanceName) {
 - //   //       selectedinstance.instanceName = processedArgs._[1] = instanceName || selectedinstance.instanceName
 - //   //       return p1.ask(`Enter Environment ( <= ${selectedinstance.node_env} ) : `).then(function (node_env) {
 - //   //         selectedinstance.node_env = processedArgs.node_env = node_env || selectedinstance.node_env
 - //   //         return p1.ask(`Enter cmd : 
 - //   //     p) pull
 - //   //       Default <= p
 - //   //     : `).then(function (cmd) {
 - //   //           if (!cmd || cmd === 'p') {
 - //   //             processedArgs._[0] = 'pull'
 - //   //           }
 - //   //           else processedArgs._[0] = cmd
 - //   //           return p1.ask(`Enter preferred repo server ( <= ${selectedinstance.reposerver || selectedinstance.reposervers[0]} ) : `).then(function (reposerver) {
 - //   //             selectedinstance.reposerver = reposerver || selectedinstance.reposerver || selectedinstance.reposervers[0] || 'https://git.bbh.org.in'
 - //   //           })
 - //   //         })
 - //   //       })
 - //   //     })
 - //   //   } else {
 - //   //     console.log(chalk.gray(`Default option not exercised. Please follow manual instructions to customize your instance here http://git.bbh.org.in/chess and try again.`));
 - //   //     fs.writeFileSync('run.log', ', ' + JSON.stringify({ success: 'quit without execution' }), { 'flag': 'a+' })
 - //   //     fs.writeFileSync('run.done', 'noop quit');
 - //   //     process.exit()
 - //   //   }
 - //   // })
 - // }
 - 
 - var mergeObjByKey = function(arrOfObjs, keyName) {
 - 
 -   var keyedDistinct = {}
 -   var distinctArrOfObjs = [] 
 - 
 -   arrOfObjs.forEach( o => {
 -     if(o) (keyedDistinct[o[keyName]] || (keyedDistinct[o[keyName]] = []) ).push(o) 
 -   })
 -   Object.keys(keyedDistinct).forEach(key => {
 -     distinctArrOfObjs.push(  utils.assign( ...keyedDistinct[key] ) ) // PB : TODO -- Shallow use utils.assign
 -   })
 - 
 -   return distinctArrOfObjs;
 - }
 - 
 - var cacheWriteInstanceConfig = function(chessinstances){
 -   var instanceName = chessinstances['current_run'].instanceName;
 -   var node_env = chessinstances['current_run'].node_env;
 -   chessinstances[instanceName][node_env].repos = mergeObjByKey(chessinstances[instanceName][node_env].repos, 'repo') ;
 -   chessinstances[instanceName][node_env].elevated = mergeObjByKey(chessinstances[instanceName][node_env].elevated, 'repo') ;
 -   fs.writeFileSync(instanceroot + '/chessinstances.js', 'module.exports = ' + JSON.stringify(chessinstances, null, 2) + '', { 'flag': 'w' })
 - }
 - 
 - var acquireConfig = function (selected) {
 - 
 -   var configrepo = selected.instanceName + '-config-' + selected.node_env;
 - 
 -   return performPull(configrepo).then(() => {
 -     var manifestpath = path.normalize(selected.root + '/' + selected.instanceName + '-config-' + selected.node_env + '/repo-manifest');
 -     selectedinstance = require(manifestpath)( null, selectedinstance)
 -     // Config from server always override merges into selection except for the current selection.
 -     // PB : TODO -- utils.assign Array merges are non-distinct...
 -     if(!selectedinstance.repos[0].repo) {
 -       console.warn('repo manifest has obsolete format. Attempting upgrade.')
 -       selectedinstance.repos = selectedinstance.repos.map(function(repo){ return { repo } })
 -     }
 -     if(selectedinstance.elevated[0] && !selectedinstance.elevated[0].repo) {
 -       console.warn('elevated repo manifest has obsolete format. Attempting upgrade.')
 -       selectedinstance.elevated = selectedinstance.elevated.map(function(repo){ return { repo } })
 -     }
 -     chessinstances[selected.instanceName][selected.node_env] = selectedinstance = utils.assign(selected, selectedinstance)
 -     chessinstances[selected.instanceName][selected.node_env].reposervers = Array.from(new Set(chessinstances[selected.instanceName][selected.node_env].reposervers))
 -     selectedinstance.reposerver = selectedinstance.reposerver || selectedinstance.reposervers[0] // PB : TODO -- Attempt first one that is available and online...
 -     cacheWriteInstanceConfig(chessinstances)
 -     ENV.NODE_ENV = selectedinstance.node_env;
 -   })
 -   .catch((e) => {
 -     console.error(e)
 -     console.error('Config acquisition failed.')
 -   })
 - }
 - 
 - var launchpath = path.normalize(process.cwd())
 - var thisscriptdir = path.normalize(__dirname); // PB : TODO -- Thisscriptdir could be dislocated when run as a standalone file... We need to detect this where and how we were run.
 - // The easisest would be to ask for a target directory and default to current dir.... 
 - var instanceroot = path.normalize(thisscriptdir) === path.normalize(launchpath) ? path.normalize(thisscriptdir + '/..') : launchpath ;
 - 
 - // PB : TODO -- Embed this in the build instead of inlining it.
 -   // Also attepmt to load from ../chess-config/...
 - var __default = ((name, options)=>{
 - 
 -   // Default set of users in main repos.
 -   var users = [
 -       { username : `${options.username}`, password : `${options.password}` }
 -     , { username : `chess` }
 -     // , { username : `baptistdev`, password : 'encrypted' }
 -     // , { username : `guest`, password : 'encrypted' }
 -   ]
 - 
 -   // ${options.reposerver} should be used to lookup current config.
 - 
 -   // User can always add more branches and remotes as needed. Mainifest only occupies 
 -       // well defined namespaces
 -   var remotes = {
 -       // these are both fetch and push remotes. Use push - remotes to override push.
 -       'chess' : { path : `/chess/`, push : 'no-pushing' }
 -     
 -     // Multiple urls dont tell us the current origin which may be 
 -     // different based on currently available/accessible based on device and client.
 -     // We just treat them as different remotes and merge as needed.
 -     // 
 -     , 'origin' : { path : `/${options.username}/` }
 -     , 'origin-public' : { path : `/${options.username}/` }
 -     , 'origin-unc' : { path : `/${options.username}/` }
 -     // , { `${options.username}` : `https://git.bbh.org.in/${options.username}/elxr.git` }
 -   }
 - 
 -     // , 'fetch-remotes' : [] // Multiple fetch remotes are not supported by git.
 -       // We therefore need to use 
 -       // - a pullall 
 -       // - or branch alias for multiple remote branch tracking branch strategy.
 -       // 		-- This is however limited to corresponding branch names 
 - 
 -     // tracking branches.
 -     // We at least need one branch for each remote that we wish to track.
 -     // , 'tracking-branches' : [
 -     //   { master : ['origin/master', 'chess/master'] }
 -     // ]
 - 
 -   var reposerverinstances = {
 -       'http://git.bbh' : { users, remotes }
 -     , 'https://git.bbh.org.in' : { users, remotes, external : true }
 -     , '//172.16.0.27/repos' : { users, remotes }
 -     , 'https://github.com' : {
 -         // We host a miniaml set of repositories in github. 
 -         get users() { return [{ username : `${this.username}` }]}, username : `baptistdev`
 -       , remotes : { get 'baptistdev-public'() { return {path : `/${this.username}/`, push : 'no-pushing'} }
 -         // , Add other remotes here. 
 -       }
 -       , external : true, public : true 
 -     }
 -   }
 -   return {
 -         reposervers : Object.keys(reposerverinstances)
 -       , reposerverinstances
 - 
 -       // Common baseline repos for all chess instances.
 -       , repos : [
 -         { repo : 'ember-masonry-grid' /*, branch : master*/ } // Default need not be specified.
 -       , { repo : 'bbhverse' }
 -       , { repo : 'clientverse' }
 -       , { repo : 'serververse' }
 -       , { repo : 'elxr' }
 -       , { repo : 'ember-searchable-select' }
 -       , { repo : 'loopback-component-jsonapi' }
 -       , { repo : 'loopback-jsonapi-model-serializer' }
 -       , { repo : 'loopback-connector-mysql' }
 -       , { repo : 'loopback-connector-ds' }
 -       , { repo : 'chess-server-lib' }
 -       , { repo : 'ember-service-worker' }
 -       , { repo : 'ember-service-worker-asset-cache' }
 -       , { repo : 'ember-service-worker-cache-fallback' }
 -       , { repo : 'ember-service-worker-index' }
 -       , { repo : 'ember-sw-client-route' }
 -       , { repo : 'global-this' }
 -     ]
 - 
 -     // PB : TODO -- lighter defaults for lite new instance creation..
 -     , repos: [
 -         { repo : 'setup' }
 -       , { repo : 'elxr' }
 -       , { repo : 'loopback-connector-mysql' }
 -       , { repo : 'loopback-jsonapi-model-serializer' }
 -       , { repo : 'loopback-component-jsonapi' }
 -       , { repo : 'ember-service-worker' }
 -       , { repo : 'ember-service-worker-asset-cache' }
 -       , { repo : 'ember-service-worker-cache-fallback' }
 -       , { repo : 'ember-service-worker-index' }
 -       , { repo : 'ember-sw-client-route' }
 -     ]
 - 
 -     , elevated : [ ]
 -     , exludeMergeRepos : { }
 -   }
 - 
 - })(
 -     '__default' // name
 -   , { username : 'guest', instanceName : 'chess', node_env : 'development', reposerver : 'https://git.bbh.org.in' } // options
 - )
 - // We first load the default and then override with a runconfig if it exists else we override with the interactive prompts.
 - // Then acquire and reload and replace this default.
 - 
 - 
 - var hasElxr = function(path, options, cb) {
 -   // PB : TOOD -- Navigate up the folder chain to discover the relevant .elxr directory.
 -   options = options || {};
 -   
 - 
 -   var tasks = [
 -       '/elxr' // Is there a subfolder named elxr 
 -     , '/elxr/.git' // which is self git repository
 -     , '/elxr/.elxr' // and has .elxr subfolder
 -     , '/elxr/.elxr/' + __ALIAS__STAMP__  // Which has our stamp.
 -   ]
 - 
 -   if(options.sync) { return tasks.earlyreduce((acc, tpath)=>{
 -     var value = existsFolderSync(path + tpath);
 -     return { value, done : acc && !value };
 -   }).value }
 - 
 -   if(cb) return cb(null, tasks.earlyreduce((acc, tpath)=>{
 -     var value = existsFolderSync(path + tpath);
 -     return { value, done : acc && !value };
 -   }).value );
 -   
 -   return Promise.resolve(tasks.earlyreduce((acc, tpath)=>{
 -     var value = existsFolderSync(path + tpath);
 -     return { value, done : acc && !value };
 -   }).value);
 - }
 - 
 - var hasElxrSync = function(path){ return hasElxr(path, { sync :true}); }
 - 
 - var detectfromroot = function(root){
 -   return { root, node_env : path.basename(root), instanceName : path.basename( path.dirname(root) ) }
 - }
 -   
 - var detectinstances = function () {
 -   console.log(`launchpath = ${launchpath}`)
 -   console.log(`thisscriptdir = ${thisscriptdir}`)
 - 
 -   // PB : TODO -- !Postpone this.
 -   console.log(`instanceroot = ${instanceroot}`) // Not yet confirmed...
 - 
 -   // Note : Paths should already be normalized fefore this.
 - 
 -   var root = instanceroot;
 -   var detected = { root };
 -   var instanceoptions = [clioverrides]
 - 
 -   return hasElxr(launchpath).then( (elxrCliExists) => {
 - 
 -     // We need a reference to the root director for elxr cli to be properly oriented.
 -     if (( elxrCliExists && path.normalize(launchpath + '/elxr')) === thisscriptdir) {
 -       // We were run from the proper root with elxr cli in the subfolder. 
 -       instanceroot = root = launchpath;
 -       instanceoptions.splice( 0, 0, detected = { root })
 -       instanceoptions.splice( 0, 0, detectfromroot(root))
 -     }
 -     else {
 -       if(path.normalize(launchpath + '/elxr') === thisscriptdir) {
 -         // elxrCliExists is false -- and yet thiscriptdir is still proper.
 -         // PB : TODO -- Maybe a warning / abort if for some reason this scriptdir should not be taken over...
 -         console.error('Warning : detected thisscriptdir as elxr subfolder but not recognized as elixir. git updates might fail.')
 -         instanceroot = root = launchpath;
 -         instanceoptions.splice( 0, 0, detected = { root })
 -         instanceoptions.splice( 0, 0, detectfromroot(root))
 -       }
 -       else if (launchpath === thisscriptdir) {
 -         
 -         var parentHasElxr = hasElxrSync(launchpath + '/..')
 -         // PB : TODO -- verify if we have .elxr folder in the parent...
 -         if(!parentHasElxr) {
 -           // ! thisscriptdir is not elxr.
 -           console.error('Invalid run location in subfolder that looks like elxr. We should probably abort as elxr will not sync.')
 -         }
 - 
 -         // Same directory doesn't mean we are being run from elxr sub  directory. 
 -         // In standalone build script we may or not be in the same location.
 -         if (BUILD_VERSION.indexOf('Version: {version} - built on {date}') > -1) {
 -           // Unbuilt therefore we are in the elxr sub directory.
 - 
 -           instanceroot = root = path.normalize(launchpath + '/..');
 -           instanceoptions.splice( 0, 0, detected = { root });
 -           instanceoptions.splice( 0, 0, detectfromroot(root));
 -         }
 -         else {
 -           // Built version.
 -           // We could have been run from the elxr subfolder. Highly likely that the built version isn't the full elxr.
 -           if(parentHasElxr) {
 -             // Built version was run from the full elxr subfolder. Should work 
 -             // PB : TODO -- but we should switch to the full version...
 -             instanceroot = root = path.normalize(launchpath + '/..');
 -             instanceoptions.splice( 0, 0, detected = { root })
 -             instanceoptions.splice( 0, 0, detectfromroot(root))
 -           }
 -           else {
 -             instanceroot = root = launchpath;
 -             instanceoptions.splice( 0, 0, detected = { root })
 -             instanceoptions.splice( 0, 0, detectfromroot(root))
 -             // Assume current launchpath is a new instance and create.
 -             // Figure out the instnace name and environment from parent folders as an alternative option with confirmation if not provided in the arguments.
 - 
 -             // if(clioverrides.instanceName) {
 -             //   if(clioverrides.node_env) {
 -             //     instanceroot = root = path.normalize(launchpath + '/' + clioverrides.instanceName + '/' + clioverrides.node_env)
 -             //     instanceoptions.splice( 0, 0, detected = { root, instanceName : clioverrides.instanceName, node_env : clioverrides.node_env })
 -             //     // instanceoptions.splice( 0, 0, detectfromroot(root)) // This can be an option but is unnecessary unless a confirmation is provided.
 -             //     // also folder names may have no relation to the actual instanceName and instanceType coz we need to have many 
 -             //       // eg : floder name can be elixir01 but instance name is elixr
 -             //   }
 -             //   else {
 -             //     instanceroot = root = path.normalize(launchpath + '/' + clioverrides.instanceName + '/' + 'development')
 -             //     instanceoptions.splice( 0, 0, detected = { root, instanceName : clioverrides.instanceName, node_env : 'development' })
 -             //     instanceoptions.splice( 0, 0, detectfromroot(root)) // A recessive option only.
 -             //   }
 -             // }
 -             // else {
 -             //   instanceroot = root = launchpath;
 -             //   if(clioverrides.node_env) {
 -             //     instanceoptions.splice( 0, 0, detected = { root, node_env : clioverrides.node_env })
 -             //     instanceoptions.splice( 0, 0, detectfromroot(root))
 -             //   }
 -             //   else {
 -             //     // Nothing was specified... We only have one option from root.
 -             //     instanceoptions.splice( 0, 0, detected = detectfromroot(launcpath))
 -             //   }
 -             // }
 -           }
 -         }
 -       }
 -       else {
 -         if(elxrCliExists) {
 -           instanceroot = root = launchpath;
 -           instanceoptions.splice( 0, 0, detected = { root })
 -           instanceoptions.splice( 0, 0, detectfromroot(root))
 -         }
 -       }
 -     }
 -    
 -     instanceroot = detected.root
 -     __default.root = root;
 -     clioverrides.root = clioverrides.root || root; 
 -     
 -     // Resolves empty array when No known instances detected.
 -     return Promise.resolve(instanceoptions)
 -   })
 - 
 - }
 - 
 - var getReconfirmAll = ()=>{return { instanceName : true, instanceType : true, reposerver : true, username : true, password : true } }
 - if(clioverrides.reconfirm) {
 -   var reconfirm = getReconfirmAll()
 - }
 - else { var reconfirm = {}; }
 - 
 - var shouldPrompt = function(k, possiblePrompts, target){
 -   return ((possiblePrompts[k] !== undefined && possiblePrompts[k] !== null) && target[k] !== possiblePrompts[k] 
 -       || (possiblePrompts[k] === undefined || possiblePrompts[k] === null) && (target[k] === undefined || target[k] === null) 
 -       || reconfirm[k])
 - }
 - 
 - var getBoundEachPrompt = function(target, possiblePrompts, promptables, choices, promptsfilter) {
 -   return function(prompts, k, i, a){
 -   
 -     
 -     // No local instances config found. We use a default initialized instance available in selectedinstance
 -     // Confirm those that were not supplied as user choices in runtime args and proceed to reattempt.
 -     // PB : TODO -- selectedinstance === __default check to prompt everything...
 -     if(  shouldPrompt(k, possiblePrompts, target) ) {
 -       delete reconfirm[k];
 -       // console.log(k)
 -       // console.dir(possiblePrompts); //console.dir(target)
 -       prompts.push(async ()=>{ 
 -         // PB : NOTE -- Important in async cases when this needs to be in the same state as when it was invoked.
 -           // We take a snapshot... Shallow.. !! If required deep should be used based on use case. 
 -           // If latest altered state is required we can reerence this directly.
 -         // var asyncthis = Object.assign(this); 
 -         promptables[k].choices = choices[k] 
 -         Object.defineProperty(target, k, getPromptableAsyncPropDescriptor(k, promptables[k]));
 -         return await target[k] 
 -       })
 -     }
 -     delete possiblePrompts[k] // PB : TODO We should keep this around instead of deleting so we can do a second pass if required.
 -     return prompts
 -   }
 - }
 - 
 - var __interactive_prompts = function( target, choices, promptsfilter ){
 - 
 -   Object.defineProperty(target, 'node_env', { get : function(){ return this.instanceType } });
 - 
 -   var interactionpoints = {
 -     runchoice : {
 -         label :  
 -         `Choose an option :
 -         d) Install the default chess instance. 
 -             => elxr i chess node_env=development --default
 -         n) Create your custom new instance interactively
 -             => elxr i {{instanceName}} node_env={{environment}}
 -         i) Choose an instance and environment to install
 -             => elxr i {{instanceName}} node_env={{environment}}
 -         c) Choose a command to run ( pull, use, i, npmi ... ) <= pull
 -             => elxr {{cmd}} {{instanceName}} node_env={{environment}}
 -         h) Help
 -         q) Quit
 -         : `
 -         , choices : []
 -         , defaultchoice : 'c'
 -         , interpret : function(choice){
 -           var interpret_map = {
 -             d : function(){
 -               processedArgs._[0] = 'i'
 -               target.instanceName = processedArgs._[1] = processedArgs._[1] || 'chess'
 -               target.node_env = processedArgs.node_env = (process.env.NODE_ENV && process.env.NODE_ENV.trim()) || processedArgs.node_env || 'development'
 -               target.reposerver = 'https://git.bbh.org.in'
 -             }
 -             , n : function() { processedArgs._[0] = 'i' }
 -             , i : function() { processedArgs._[0] = 'i' }
 -             , c : async function() {
 -               Object.defineProperty(this, 'cmd', getPromptableAsyncPropDescriptor('cmd', { 
 -                 label : `Enter cmd : 
 -                 p) pull
 -                   Default <= p
 -                 : `
 -                 , defaultchoice : 'pull'
 -                 }
 -               ));
 - 
 -               var cmd = await target['cmd'];
 -               if (!cmd || cmd === 'p') { target['cmd'] = processedArgs._[0] = 'pull' }
 -               else target['cmd'] = processedArgs._[0] = cmd
 -               return cmd;
 -             }
 -             , h : function() { console.log(elxr.help()); process.exit() }  // PB : TODO -- Why do we need log.
 -             , q : function() { process.exit() }
 -           }
 -           var __interpreter = interpret_map['c']
 -           // if(!choice) return interpret_map['c']() // This should not happen prompter should always give us a default choice.
 -           if(interpret_map[choice]) __interpreter = interpret_map[choice];
 -   
 -           return __interpreter.call(target)
 -         }
 -       }
 -     , instanceName : { label : `Enter Instance Name ( <= ${target.instanceName || 'chess'} ) : `
 -       , choices : choices['instanceName'], defaultchoice : 'chess'}
 -     , instanceType : { label : `Enter Instance Type ( <= ${target.instanceType || 'development'} ) : `
 -       , choices : choices['instanceType'], defaultchoice : 'development'}
 -     , reposerver   : { label : `Enter Instance Name ( <= ${target.reposerver || 'https://git.bbh.org.in'} ) : `
 -       , choices : choices['reposerver'], defaultchoice : 'https://git.bbh.org.in'}
 -     , username   : { label : `Enter User Id for ${target.reposerver} ( <= ${target.username || 'chess'} ) : `
 -       , choices : choices['username'], defaultchoice : 'chess'}
 -     , password   : { label : `Enter Password for ${target.username} @ ${target.reposerver} ( <= ${target.password || ''} ) : `
 -       , choices : choices['password'], defaultchoice : '***'}
 -     , email   : { label : `Enter Email for ${target.username} @ ${target.reposerver} ( <= ${target.email || ''} ) : `
 -       , choices : choices['email'], defaultchoice : 'guest@bbh.org.in'}
 -   }
 - 
 -   
 -   function getPromptKeys() {
 -     if(! (processedArgs.label || processedArgs._[0]) ) return Object.assign({}, interactionpoints);
 -     
 -     return promptkeys
 -   }
 -   var eachPrompt = getBoundEachPrompt( target, getPromptKeys() , interactionpoints, choices, promptsfilter)
 -   return   Object.keys(promptsfilter || interactionpoints).reduce(eachPrompt, [])
 - }
 - 
 - 
 - var downloadsdir = '../Downloads';
 - var prerequisites = [
 -   {
 -     shellcmd: 'git',
 -     name : 'git',
 -     url: 'https://github.com/git-for-windows/git/releases/download/v2.31.0.windows.1/Git-2.31.0-64-bit.exe'
 -     , installer: 'Git-2.31.0-64-bit.exe'
 -     , installcmd: ['cmd', ['/c', 'start',
 -       '/WAIT', path.resolve(downloadsdir + '/' + 'Git-2.31.0-64-bit.exe')
 -       , '/VERYSILENT'
 -       // , '/MERGETASKS=!runcode' // This is required only for vscode...
 -     ]]
 -     , preinstallsteps: function() {
 -       var steps = [
 -         () => {
 -           if (!existsSync(downloadsdir + '/' + this.installer)) {
 -             return nodeShellExec(`${selectedinstance.root}/.elxr/run-${runtimestamp}/download.bat`, [this.url, downloadsdir + '/' + this.installer])
 -           }
 -           else return Promise.resolve(true)
 -         }
 -       ]
 -       var prompts = this.getuser(null, ()=>{
 -         // console.log('preinstallsteps')
 -         // var gitUser = 'guest';
 -         // var gitEmail = 'guest@bbh.org.in';
 -         // var prompts = [];
 -         // prompts.push( ()=>{ return cli.prompt(choices['username'], 'git user name').then(gituser => gitUser = gituser) } )
 -         // prompts.push( ()=>{ return cli.prompt(choices['useremail'], 'git user email').then(gitemail => gitEmail = gitemail) } )
 -   
 -         // console.log('prompting in preinstallsteps')
 -         // return any(prompts).then(()=>{
 -         //   var steps = [
 -         //       ['git', ['config', '--global', '--add', 'user.name', `${gitUser}`]]
 -         //     , ['git', ['config', '--global', '--add', 'user.email', `${gitEmail}`]]
 -         //   ]
 -         //   return any(steps.map(getshelltask)).then(() => { 
 -   
 -         //   })
 -         // });
 - 
 -         return Promise.resolve(true)
 -       })
 -       
 -       return any([any(steps), prompts])
 -     }
 -     , installsteps: function () {
 -       return any([this.installcmd].map(getshelltask))
 -     }
 -     , postinstallsteps: function(err, users){
 -       return this.getuser(null, (err, data)=>{
 -         // ignore err and proceed with data as guest.
 -         console.dir(data)
 -         if(data && data.length === 1 && !shouldPrompt('username', promptkeys, selectedinstance)  ) {
 -           return username = data[0];
 -         }
 -         
 -         data = data || ['guest']
 -         choices['username'] =  Array.from( new Set( data.concat( (choices['username'] || []) )) )
 - 
 -         console.log('prompting in postinstallsteps')
 - 
 -         var username = 'guest';
 -         var email = 'guest@bbh.org.in';
 -         var password = '***';
 -         
 -         return any( getInteractionPoints(selectedinstance, promptkeys, { username, password, email})  ).then(()=>{
 -           if(!data.find(e => e === selectedinstance.username)) {
 -             var steps = [
 -                 ['git', ['config', '--global', '--add', 'user.name', `${username}`]]
 -               , ['git', ['config', '--global', '--add', 'user.email', `${email}`]]
 -             ]
 -             return any(steps.map(getshelltask)).then(() => { 
 -   
 -             })
 -           }
 -           else {
 -             return Promise.resolve(true)
 -           }
 -         });
 -       })
 -     }
 -     , install: function () {
 -       return any([ /*this.preinstallsteps,*/ this.installsteps.bind(this), this.postinstallsteps.bind(this)])
 -     }
 -     , verifyAndInstall : function(){
 -       return getTaskCheckExists(this.shellcmd, { ignorefailures: true })().then((exists) => {
 -         if(exists) {
 -           // return any(['git', ['config', '--global', '-l']].map(getshelltask))
 -           return this.postinstallsteps.bind(this)()
 -         }
 -         return this.install();
 -       });
 -     }
 -     , getuser : function(repo, onResult){
 - 
 -       var __onResult = onResult || function(e, data){
 -         data = data || []
 -         choices['username'] =  Array.from( new Set( data.concat( (choices['username'] || []) )) )
 -         // console.dir(choices)
 -         return data[0]
 -       }
 -  
 -       var globalOrLocal = '--global';
 -       if(repo) globalOrLocal = '--local'
 - 
 -       return any([['git', ['config', globalOrLocal, '--get-all', 'user.name']]].map(getshelltask)).then((result)=>{
 -         // not yet configured.
 -         if(!result.success) return __onResult(result)
 -         else {
 -           var users = result.messages[0].trim().split('\n');
 -           if(users.length === 0 ||
 -               users.length === 1 && users[0] === 'guest') {
 -             
 -             return __onResult(result)
 -           }
 -           else {
 -             return __onResult(null, Array.from( new Set( users ) ) ); }// PB : TODO == We should probably prompt with all the users available for selection ! 
 -         }
 -       })
 -       .catch((e)=>{ 
 -         console.log(e) 
 -         return __onResult(e)
 -       })
 -     }
 -   }
 -   ,
 -   {
 -     shellcmd: 'node',
 -     name : 'ndoe',
 -     url: 'https://nodejs.org/dist/v14.16.0/node-v14.16.0-x64.msi'
 -     , installer: 'node-v14.16.0-x64.msi'
 -     , installcmd: ['MSIEXEC.exe', ['/i'
 -       , path.resolve(downloadsdir + '/' + 'node-v14.16.0-x64.msi')
 -       , 'ACCEPT=YES', '/passive']]
 -     , install : function() { return any([this.installcmd].map(getshelltask)).then(() => { }) }
 -   }
 - ]
 - for(var i=0; i<prerequisites.length; i++) {
 -   prerequisites[prerequisites[i].name] = prerequisites[i];
 - }
 - 
 - prerequisites.forEach(p=>{ prerequisites[p.shellcmd] = p })
 - 
 - function ensureDirectoryExistence(filePath) {
 -   var dirname = path.dirname(filePath);
 -   if (fs.existsSync(dirname)) {
 -     return filePath;
 -   }
 -   ensureDirectoryExistence(dirname);
 -   fs.mkdirSync(dirname);
 -   return filePath;
 - }
 - 
 - var mainTasks = [];
 - function verifyAndInstallPrerequisites() {
 -   fs.writeFileSync(ensureDirectoryExistence(path.normalize(`${selectedinstance.root}/${downloadsdir}/readme.txt`)), `${getVersion()} Your local downloads for this instance`)
 -   
 -   // PB : TODO include and build from files... using rollup..
 -   var downloadbatch =
 -     `::**************************************************************************
 -   :Download_ <url> <File>
 -     Powershell.exe ^
 -     $AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'; ^
 -     [System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols; ^
 -     (New-Object System.Net.WebClient).DownloadFile('%1','%2')
 -   exit /b
 -   ::**************************************************************************`
 -   fs.writeFileSync(`${selectedinstance.root}/.elxr/run-${runtimestamp}/download.bat`, downloadbatch)
 - 
 -   
 -   var windowselevate =
 -     `     
 -       <html><HTA:APPLICATION  ID="windowselevate" icon="#"/>
 -       <script language="vbscript">
 -         document.title = "elxr control panel"
 -         self.ResizeTo 200,600
 -         
 -         Sub Window_Onload
 -         self.MoveTo (screen.availWidth - (document.body.clientWidth + 40)),10
 -         End Sub
 - 
 -         Set objShell = CreateObject("WScript.Shell")
 -         Set objENV = objShell.Environment("Process")
 -         dim NODE_ENV 
 -         NODE_ENV = objENV("NODE_ENV")
 -       </script>
 - 
 -       <script language="javascript">
 -         //WINDOWSTATE="minimize" SHOWINTASKBAR="no" SYSMENU="no" CAPTION="no"
 -         // https://devblogs.microsoft.com/scripting/how-can-i-pass-command-line-variables-to-an-hta-when-it-starts/
 -         // alert(windowselevate.commandLine)
 -         var args = windowselevate.commandLine.split('"').slice(3);
 -         // alert(args)
 -         var processedArgs = { _ : [] }
 -         var namedArgs = [];
 -         for(var item in args){
 -           if(args[item].charAt(0) === '-'){ 
 -             namedArgs.push(args[item])
 -             var split = args[item].split('=');
 -             processedArgs[split[0].slice(2)] = split[1] || true;
 -           } 
 -           else processedArgs._.push(args[item]);
 -         }
 -         // args = args.forEach(function(item){ })
 -         // alert('processedArgs._ : ' + processedArgs._);
 -         // alert(processedArgs.runas);
 -         
 -         // PB : TODO -- Convert all the cli args back to string.
 -         var cargs = (processedArgs.debug ? '--inspect-brk=9228' : '') + ' elxr ' + processedArgs._.join(' ') + ' ' +  namedArgs.join(' ');
 -         // alert(cargs)
 -         var shell = new ActiveXObject('shell.application'); 
 -         // alert('launching node privilged. ' + processedArgs['nodepath']) 
 -         // shell.ShellExecute('where', 'node', '', '', 10);
 -         shell.ShellExecute('node', cargs, '', 'runas', 1);
 -         // shell.ShellExecute(processedArgs['nodepath'], cargs, '', 'runas', 1);
 -         var fso = new ActiveXObject('Scripting.FileSystemObject');
 -         
 -         window.onload = function() {
 -           document.body.style.backgroundColor = 'black';
 -           document.body.style.fontFamily = 'arial';
 -           var log = document.createElement('div');
 -           log.innerHTML='Please Wait';
 -           function l(msg){ log.innerHTML+= msg; };
 -           log.style.color = 'blue';
 -           log.style.width = '95%';
 -           log.id = 'log';
 -           document.body.appendChild(log);  
 -           
 -           l('<Br/>Current config : ')
 -           l('<Br/>NODE_ENV = ' + NODE_ENV)
 -           l('<Br/>cmd = ' + processedArgs._[0])
 -           processedArgs._[1] === 'use' ? l('<Br/>using = ' + processedArgs._[2]) : null;
 -           l('<Br/><Br/>')
 -           
 -           var timer = function(){
 -             l('.');
 -             if(fso.FileExists("run.done")) close();
 -             else window.setTimeout(timer, 1000);
 -           };
 -           window.setTimeout(timer, 3000);
 -         };
 -         
 -       </script>
 -       </html>
 -     
 -     `
 -   fs.writeFileSync(`${selectedinstance.root}/.elxr/run-${runtimestamp}/windowselevate.hta`, windowselevate)
 - 
 -   var downloadtasks = [];
 -   var installtasks = [];
 -   prerequisites.forEach(preq => {
 -     downloadtasks.push(getTaskCheckExists(preq.shellcmd, { ignorefailures: true })().then((exists) => {
 -       if (exists) console.log(`${preq.shellcmd} exists`)
 -       else {
 -         console.log(`${preq.shellcmd} is not installed`)
 -         return preq.preinstallsteps.call(preq).then(() => {
 -           installtasks.push(preq.install.bind(preq))
 -         })
 -       }
 -     }))
 -   })
 -   return Promise.all(downloadtasks).then(() => { return any(installtasks) })
 - }
 - 
 - var getPromptableAsyncPropDescriptor = function(propName, promptable){
 -   return {
 -     get (){
 -       return cli.prompt( promptable.choices, promptable.label, promptable.defaultchoice ).then(propValue => {
 -         
 -         var asyncprop = Promise.resolve(propValue)
 -         if(promptable.interpret){
 -           asyncprop = promptable.interpret(propValue) 
 -         }
 - 
 -         return asyncprop.then(
 -           ()=>{
 -             Object.defineProperty(this, propName, {
 -               value: propValue,
 -               writable: true,
 -               configurable : true,
 -               enumerable : true
 -             });
 -             return propValue
 -           }
 -         )
 -       })
 -     }
 -     // , set (propValue){
 -     //   Object.defineProperty(this, propName, {
 -     //     value: propValue,
 -     //     writable: true, // PB : TODO -- Use this to fix value permanently until run is over.
 -     //     configurable : true,
 -     //     enumerable : true
 -     //   })
 -     //   return propValue;
 -     // }
 -     , configurable : true
 -     , enumerable : true
 -   }
 - }
 - 
 - 
 - 
 - 
 - function acquirelocalinstances(selected){
 -   // utils.assign is used to cleanup duplicates...
 -   var chessinstances = utils.assign(require(path.normalize(selected.root + '/chessinstances.js')));
 -   return chessinstances
 - }
 - 
 - function findlocalinstances(chessinstances, instanceoptions){
 -   // We can expect a .elxr at each level.
 -     ['' /* instanceroot */, '../' /* instanceTypes or node_env */, '../..' /* instanceNames */].
 -       earlyreduce( ( value, p, i, a )=>{
 -         var localinstancesPath = `${instanceroot}/${p}.elxr`;
 -         if(existsSync( localinstancesPath )) {
 -           try {
 -             var chessinstances = acquirelocalinstances( { localinstancesPath } )
 -             return Object.keys(chessinstances).earlyreduce( ( value, instanceName) => {
 -                 return Object.keys(chessinstances[instanceName]).earlyreduce( (value, instanceType) => { 
 -                       if(  path.normalize(chessinstances[instanceName][instanceType].root) === path.normalize( instanceroot) ) {
 -                         instanceoptions.splice( 0, 0, chessinstances[instanceName][instanceType])
 -                         return {
 -                             value : chessinstances[instanceName][instanceType]
 -                           , done : true
 -                         };
 -                       }
 -                     })
 -                 })
 -           }
 -           catch(e){ 
 -             return { }
 -           }
 -         }
 -         else return { }
 -       }
 -     )
 - }
 - 
 - 
 - // function updateselection(selected) { selectedinstance = utils.assign(selectedinstance, selected) }
 - var selectedinstance = null;
 - var chessinstances = { current_run : {} };
 - var promptkeys = { 
 -   cmd : processedArgs._[0] || 'pull'
 -   // Try not to prompt anything unless absolutely necessary or reconfirm is forced.
 -   //   'instanceName' : true
 -   // , 'node_env' : true 
 -   // , username : ''
 -   // , runchoice : 'c'
 - } 
 - // promptkeys.runchoice = promptkeys.cmd ? 'c' : undefined
 - 
 - function createChessInsance( cfg ){ 
 -   var inst = {};
 -   var __new = Object.assign({}, __default, cfg)
 -   inst[cfg.node_env] = __new; return inst; 
 - }
 - 
 - var choices = {
 -     'instanceName' : []
 -   , 'reposerver' : []
 -   , 'instanceType' : []
 -   , username : ['guest', 'chessdemo', 'demo']
 - }
 - 
 - var getInteractionPoints = function(detectedinstanceoptions, possiblePrompts, promptsfilter){
 - 
 -   var instances = []
 -   var reposervers = [];
 -   var instanceNames = []
 -   var instanceTypes = ['development', 'production'];
 -   Object.keys( chessinstances).forEach(instanceName => {
 -     if(instanceName === 'current_run') return;
 -     Object.keys( chessinstances[instanceName] ).forEach(node_env=>{
 -       var instance = chessinstances[instanceName][node_env];
 -       reposervers = reposervers.concat(instance.reposervers)
 -       if(instance.reposerver) reposervers.push(instance.reposerver)
 -       instances.push(instance)
 -       instanceTypes.push(instance.node_env)
 -       instanceNames.push(instance.instanceName)
 -     })
 -   })
 -   instances = instances.concat(detectedinstanceoptions)
 - 
 -   if(selectedinstance['instanceName']) instanceNames.push(selectedinstance['instanceName'])
 -   if(possiblePrompts['instanceName']) instanceNames.push(possiblePrompts['instanceName'])
 -   if(selectedinstance['reposervers'])  reposervers = reposervers.concat(selectedinstance['reposervers'])
 -   
 -   choices['instanceName'] =  Array.from( new Set(instanceNames.concat(choices['instanceName'])) )
 -   choices['reposerver'] =  Array.from( new Set(reposervers.concat(choices['reposerver'])) )
 -   choices['instanceType'] =  Array.from( new Set(instanceTypes.concat(choices['instanceType'])) )
 - 
 -   return __interactive_prompts(selectedinstance, choices, promptsfilter) 
 - }
 - 
 - var detection_state = {
 -   didWeFindInstance : false
 - }
 - 
 - const https = require('https')
 - const http = require('http')
 - const RESTAPI = (function(){
 - 
 -   // Singleton
 -   function RESTAPI(){}
 -   // RESTAPI.create = RESTAPI; // Returns the one singe instance which is the class itself
 -   // const options = {
 -   //   hostname: 'whatever.com',
 -   //   port: 443,
 -   //   path: '/todos',
 -   //   method: 'POST',
 -   //   headers: {
 -   //     'Content-Type': 'application/json',
 -   //     'Content-Length': data.length
 -   //   }
 -   // }
 -   RESTAPI.method = function(options, resolve, reject){
 -     var __method = function() {
 -       options.headers = options.headers || { 'Content-Type': 'application/json' }
 -       if(options.payload) {
 -         const data = new TextEncoder().encode( JSON.stringify(options.payload) )
 -         options.headers = options.headers || {
 -           'Content-Type': 'application/json',
 -           'Content-Length': data.length
 -         }
 -       }
 -       if(!options.authenticatepost) options.headers.Authorization = `token ${usertokens[options.username]}`
 - 
 -       var acquirer = getHTTPorS(options)    
 -       const req = acquirer.request(options, res => {
 -         if (res.statusCode < 200 || res.statusCode >= 300) {
 -           return reject(new Error('statusCode=' + res.statusCode));
 -         }
 -         var body = [];
 -         // res.setEncoding('utf8');
 -         res.on('data', function(chunk) {
 -             body.push(chunk);
 -         });
 -         res.on('end', function() {
 -             try {
 -                 body = JSON.parse(Buffer.concat(body).toString());
 -             } catch(e) {
 -                 reject(e);
 -             }
 -             resolve(body);
 -         });
 -       });
 -       
 -       req.on('error', error => {
 -         console.error(error)
 -         reject(error)
 -       })
 -       
 -       if(options.payload) req.write(data)
 -       req.end()
 -     }
 - 
 -     if(!options.authenticatepost && !usertokens[options.username]) {
 -       RESTAPI.authenticate(options, function(tokenresp){ 
 -         usertokens[options.username] = tokenresp.sha1
 -         __method(options, resolve, reject)
 -       },
 -       function(err){ throw err}
 -       )
 -     }
 -     else __method(options, resolve, reject)
 -   }
 - 
 -   RESTAPI.post = RESTAPI.method
 - 
 -   var usertokens = {}
 - 
 -   RESTAPI.authenticate = function(options, resolve, reject){
 -     options.headers = options.headers || { 'Content-Type': 'application/json' }
 - 
 -     if(!usertokens[options.username]) {
 -       // Authenticate and acquire token.
 -       // https://git.bbh/api/v1/users/<username>/tokens
 -       // curl -XPOST -H "Content-Type: application/json"  -k -d '{"name":"demo"}' -u demo:demo123 http://git.bbh/api/v1/users/demo/tokens
 -       var _options = Object.assign({}, options)
 -       // _options.username = 'demo'
 -       // _options.password = 'demo123'
 -       _options.method = 'POST'
 -       _options.headers.Authorization = `Basic ${Buffer.from(`${_options.username}:${_options.password}`).toString('base64')}`  
 -       _options.path = `/api/v1/users/${_options.username}/tokens`
 -       _options.authenticatepost = true
 - 
 -       var postoptions = { name : _options.username }
 -       delete _options.username
 -       delete _options.password
 -       _options.payload = postoptions
 -       RESTAPI.post( _options, function(tokenresp){ 
 -           // tokenresp = JSON.parse(tokenresp)
 -           usertokens[options.username] = tokenresp.sha1
 -           resolve(tokenresp)
 -         },
 -         function(err){ reject(err) }
 -       )
 -     }
 -     else resolve(tokenresp.sha1)
 -   }
 -   
 -   RESTAPI.get = RESTAPI.post = RESTAPI.method
 - 
 -   return RESTAPI
 - })();
 - 
 - var getHTTPorS = function(options){ return options.protocol.startsWith('https') ? https : http; }
 - 
 - const GITEA = (function(){
 - 
 -   function GITEA(){}
 -   GITEA.repository = {
 -     fork( httpoptions, cmdoptions, giteaoptions, resolve, reject ){
 -       // forkoptions = { owner : httpoptions.username, repo : {{reoptoFork}} }
 -       // giteaoptions = {
 -         // organization	string
 -             // --- organization name, if forking into an organization
 -         // }
 -       //  http://try.gitea.io/api/v1/repos/{owner}/{repo}/forks
 -       httpoptions.path = `/api/v1/repos/${cmdoptions.owner}/${cmdoptions.repo}/forks`
 -       httpoptions.method = 'POST'
 -       httpoptions.payload = giteaoptions;
 -       return RESTAPI.post(httpoptions, resolve || function(){}, reject || function(){} )
 -     }
 -     , updateattributes( httpoptions, cmdoptions, giteaoptions, resolve, reject ){
 -       httpoptions.path = `/api/v1/repos/${cmdoptions.owner}/${cmdoptions.repo}`
 -       httpoptions.method = 'PATCH'
 -       httpoptions.payload = giteaoptions;
 -       return RESTAPI.post(httpoptions, resolve || function(){}, reject || function(){} )
 -     }
 -   }
 - 
 -   GITEA.user = {
 -     getuser( httpoptions, cmdoptions, giteaoptions, resolve, reject ){
 -       // /users/{username} // Get a user
 -       httpoptions.path = `/api/v1/users/${httpoptions.username}`
 -       httpoptions.method = 'GET'
 -       return RESTAPI.get(httpoptions, giteaoptions, resolve || function(){}, reject || function(){} )
 -     }
 -   }
 - 
 -   return GITEA
 - })();
 - 
 - // Wrapper for Git shell operations. Some meta operations will map to a bunch of GIT commands.
 - const GIT = (function(){
 -   function GIT(){}
 - 
 -   Object.assign(GIT, {
 -     'switch user'(username){
 -       var server = new URL(selectedinstance.reposerver);
 -       
 -       return GITEA.user.getuser({ hostname : server.host, protocol : server.protocol
 -         , username : selectedinstance.username, password : selectedinstance.password
 -       }).then(()=>{
 -         return nodeShellExec('git', ['config', '--replace-all', 'user.name', username],
 -           {
 -             inherit: true, shell: true,
 -             env: process.env
 -             , cwd: instanceroot + '/' + repo
 -             , runas: processedArgs.runas
 -             , title: `git core.symlinks --replace-all true for ${selectedinstance.reposerver + `/${defaultRepoOwner}/` + repo + '.git'}`
 -           })
 -         }
 -       )
 -       .catch(e => {
 -         console.error(e + 'Could not switch. Probably no such user.')
 -       })
 - 
 -     }
 -   })
 - 
 -   return GIT
 - })();
 - 
 - function createInstance(selectedinstance) {
 - 
 -   // http://try.gitea.io/api/v1/org/{org}/repos
 -   console.dir(selectedinstance)
 -   var server = new URL(selectedinstance.reposerver);
 -   return GITEA.repository.fork( { hostname : server.host, protocol : server.protocol
 -         , username : selectedinstance.username, password : selectedinstance.password
 -       }
 -       // , { repo : `${selectedinstance.instanceName}-config-${selectedinstance.instanceType}`}
 -       , { repo : `chess-config`, owner : 'chess' }, {}, function( repository ){
 -         return GITEA.repository.updateattributes( { 
 -                 hostname : server.host, protocol : server.protocol
 -               , username : selectedinstance.username, password : selectedinstance.password
 -             }
 -             , { repo : `chess-config`, owner : selectedinstance.username }
 -             , { name : `${selectedinstance.instanceName}-config-${selectedinstance.instanceType}${selectedinstance.nodeName ? '-' + selectedinstance.nodeName : ''}`}
 -           )
 -       }
 -     )
 -   
 -   // GITEA.repository.updateattributes( { 
 -   //       hostname : server.host, protocol : server.protocol
 -   //     , username : selectedinstance.username, password : selectedinstance.password
 -   //   }
 -   //   , { repo : `chess-config`, owner : selectedinstance.username }
 -   //   , { name : `${selectedinstance.instanceName}-config-${selectedinstance.instanceType}${selectedinstance.nodeName ? '-' + selectedinstance.nodeName : ''}`}
 -   // )
 -    
 -   // return selectedinstance
 - }
 - 
 - acquireElevationState().then(() => {
 -   var skipprerequisites = false;
 -   function initinstances(selected_overrides) {
 -     var root = selected_overrides.root // We should always have this coz we are running at some place which is fixed by detectinstances.
 - 
 -     var instanceName = selected_overrides.instanceName
 -       || clioverrides.instanceName
 -       // || processedArgs._[1] 
 -       || chessinstances.current_run.instanceName 
 -       
 -     var node_env = selected_overrides.node_env 
 -       || clioverrides.node_env
 -       // || processedArgs.node_env
 -       || chessinstances.current_run.node_env
 - 
 -     var reposerver = selected_overrides.reposerver 
 -       || clioverrides.reposerver
 -       // || processedArgs.node_env
 -       || chessinstances.current_run.reposerver
 -     
 -     if(!instanceName) {
 -       promptkeys['instanceName'] = instanceName = chessinstances.current_run.instanceName = promptkeys['instanceName'] || __default.instanceName;
 -       promptkeys['node_env'] = node_env = chessinstances.current_run.node_env = promptkeys['node_env'] || __default.node_env;
 -       promptkeys['reposerver'] = reposerver = chessinstances.current_run.reposerver = promptkeys['reposerver'] || __default.reposervers[0];
 -     }
 -   
 -     if(!node_env) {
 -       promptkeys['node_env'] = node_env = chessinstances.current_run.node_env = promptkeys['node_env'] || __default.node_env;
 -       promptkeys['reposerver'] = reposerver = chessinstances.current_run.reposerver  = promptkeys['reposerver'] || __default.reposervers[0];
 -     }
 - 
 -     if(!reposerver) {
 -       promptkeys['reposerver'] = reposerver = chessinstances.current_run.reposerver  = promptkeys['reposerver'] || __default.reposervers[0];
 -     }
 - 
 -     chessinstances[instanceName] = chessinstances[instanceName] || createChessInsance( { 
 -       instanceName, node_env, root : selected_overrides.root, reposerver : promptkeys['reposerver'] } );
 -     chessinstances['current_run'] = { instanceName: instanceName, node_env, reposerver, root }
 - 
 -     if(path.normalize(selected_overrides.root) !== path.normalize(chessinstances[instanceName][node_env].root)) {
 -       throw "instanceName and instanceType specified doesn't match whats already present do you want to continue " + chessinstances[instanceName][node_env].root + ' does not match ' + selected_overrides.root
 -     }
 -     // Override sequence.
 -     // __default, chessinstances[current_run], instanceName-config-development, cliargs, interactve_promts
 -     selectedinstance = utils.assign(
 -         chessinstances[instanceName][node_env]
 -       , clioverrides
 -       , selected_overrides
 -       // , __interactive_prompts -- Cant just override. Also need selectedinstance to be ready...
 -     );
 - 
 -     // chessinstances[instanceName] = chessinstances[instanceName] || {}
 -     // chessinstances[instanceName][node_env] = chessinstances[instanceName][node_env] || {}
 -     
 -     // if(!selectedinstance.repos || selectedinstance.instanceName) {
 -     //   // Brand New.
 -     //   selectedinstance = Object.assign( __default, selectedinstance )
 -     // }
 -     
 -     if(!selectedinstance.repos[0].repo) {
 -       console.warn('repo manifest has obsolete format. Attempting upgrade.')
 -       selectedinstance.repos = selectedinstance.repos.map(function(repo){ return { repo } })
 -     }
 -     if(selectedinstance.elevated[0] && !selectedinstance.elevated[0].repo) {
 -       console.warn('elevated repo manifest has obsolete format. Attempting upgrade.')
 -       selectedinstance.elevated = selectedinstance.elevated.map(function(repo){ return { repo } })
 -     }
 -     
 -     // Config from server always override merges into selection except for the current selection.
 -     // PB : TODO -- utils.assign Array merges are non-distinct...
 -     chessinstances[instanceName][node_env] = selectedinstance;
 -     // chessinstances[selectedinstance.instanceName][selectedinstance.node_env] = selectedinstance;
 -     cacheWriteInstanceConfig(chessinstances)
 -     // PB : TODO -- We should probably write the new server config also...
 -     selectedinstance.reposerver = selectedinstance.reposerver || selectedinstance.reposervers[0] // PB : TODO -- Attempt first one that is available and online...
 - 
 -     return chessinstances
 -   }
 -   
 -   var skipprereqs = {}
 -   var maintask = () => {
 -     
 -     // Default cmd to run !
 -     processedArgs._[0] === processedArgs._[0] || 'pull';  
 -     // selectedinstance.reposerver = selectedinstance.reposervers[0] // PB : TODO -- Attempt first one that is available and online from all that are available.
 - 
 -     if(!noprerequisites[processedArgs._[0]]
 -         && !skipprereqs[processedArgs._[0]]
 -       ) {
 -       return prerequisites.git.verifyAndInstall().then(()=>{
 -         var e = { message : 'verifyAndInstall', success : true}
 -         var inittasks = []
 -         if(!detection_state.didWeFindInstance) {
 -           inittasks.push(createInstance(selectedinstance).then(() => { preworkerconfig(); return elxrworker(true) }))
 -         }
 -         else {
 -           inittasks.push(acquireConfig(selectedinstance).catch((err) => {
 -             e = err;
 -             console.error('Chosen cofiguraton failed or not found. Fix config and rerun or chose another.')
 -             console.error(err)
 -           }).then(() => { preworkerconfig(); return elxrworker(true) })
 -           // .finally(()=>{
 -           //   fs.writeFileSync('run.log', ', ' + JSON.stringify({ error: e.message }), { 'flag': 'a+' })
 -           //   if(!e.success) fs.writeFileSync('run.done', 'error');
 -           //   // return process.exit()
 -           // }))
 -           )
 -         }
 -         
 -         return any(inittasks) 
 -       })
 -     }
 -     else {
 -       console.log('cmd has no preqs or has been configured to skip preqs')
 -       preworkerconfig()
 -       return elxrworker()
 -     }
 - 
 -   }
 - 
 -   const retaincount = 2
 -   var min = runtimestamp;
 -   var collect = []
 - 
 -   if(reconfirmcmds[processedArgs.label || processedArgs._[0]]) {
 -     reconfirm = getReconfirmAll()
 -   }
 - 
 -   return detectinstances().then((detectedinstanceoptions)=>{
 -     
 -     detectedinstanceoptions.splice(0,0, __default)
 -     
 -     var cmdinstance = cmds[clioverrides.cmd]
 -     var cmdprompts =  cmdinstance.getPossiblePrompts()
 -     // PB : TODO -- Most recent should be at the tip ! at index 0 so utils.reverseassign is required !!!
 -     selectedinstance = utils.assign( ...detectedinstanceoptions.slice(-2), promptkeys )
 -     // promptkeys = utils.assign(promptkeys, clioverrides)
 - 
 -     if(cmdprompts.instanceName) {
 -       // not an instanceless cmd.
 -       console.dir(selectedinstance)
 -       try {
 -   
 -         chessinstances = acquirelocalinstances(selectedinstance);
 -         findlocalinstances(chessinstances, detectedinstanceoptions)
 -         initinstances(selectedinstance) // use the local instances for defaults if at all possible.        
 -         var todo = any( getInteractionPoints(detectedinstanceoptions, promptkeys)  ).then(()=>{ 
 -           var inst = initinstances(selectedinstance)
 -           detection_state.didWeFindInstance = true;
 -           return inst;
 -         })
 -       }
 -       catch (e) {
 -         // PB : TODO -- verbose mode warning.. console.warn(e) // Missing chessinstances is not an error...      
 -         var todo = any( getInteractionPoints(detectedinstanceoptions, promptkeys)  ).then(()=>{ 
 -           return initinstances(selectedinstance)
 -         })
 -   
 -         // if(!processedArgs._[0] || !selectedinstance.node_env || !selectedinstance.instanceName){
 -         //   // Weve not been told what to do.
 -         //   todo = todo.then(() => { return acquireChoices(selectedinstance) })
 -         // }
 -     
 -         todo = todo.then(() => {
 -           try {
 -             chessinstances = acquirelocalinstances(selectedinstance)
 -             findlocalinstances(chessinstances, detectedinstanceoptions)
 -             detectedinstanceoptions.splice(0,0, __default)
 -             initinstances(selectedinstance)
 -             detection_state.didWeFindInstance = true;
 -           }
 -           catch (e) {
 -             // console.error(e)
 -             console.log('No local instances config found in current root = ' + selectedinstance.root);
 -             console.log('A config will be createed with the instance and environment chosen...')
 -             // return (async ()=>{return await __default.reposerver})().then(()=>{
 -             //   // selectedinstance = Object.assign(detectedInstance, clioverrides);
 -             //   return selectedinstance = Object.assign(__default, selectedinstance);
 -             // })
 -             detection_state.didWeFindInstance = false;
 -             return selectedinstance
 -           }
 -         })
 -       }
 -       return todo
 -     }
 -     else return Promise.resolve(true)
 -   })
 -   .then(()=>{
 - 
 -     if(noprerequisites[processedArgs._[0]]
 -       || skipprereqs[processedArgs._[0]]
 -     ) {
 -       return elxrworker()
 -     }
 - 
 -     if(!__isElevated) {
 -       ensureDirectoryExistence(`${selectedinstance.root}/.elxr/${__ALIAS__STAMP__}`)
 -       // collect garbage
 -       return dirs( (dir)=>{
 -         var matches = /run-(.*)/gm.exec(dir.name)
 -         if(matches) {
 -           if(+(matches[1]) < min) {
 -             min = matches[1]
 -             collect.splice( 0, 0, matches[1] ) 
 -           }
 -           else collect.push(matches[1])
 -         }
 -   
 -       }, `${selectedinstance.root}/.elxr` ).then(()=>{
 -         // delete garbage
 -         if(collect.length > retaincount) {
 -   
 -           var asyncs = [];
 -           while((collect.length - asyncs.length) > retaincount) {
 -             asyncs.push(getShellTask('rm',['-rf', `run-${collect[asyncs.length]}`], { cwd : `${selectedinstance.root}/.elxr` })());
 -           }
 -           return Promise.all(asyncs)
 -         }
 -         else return true
 -       })
 -     }
 -     else return true;
 -   })
 -   .then(()=>{
 -     // PB : TODO -- Keep only the last n runs...
 -     // Currently it retains 2*n when proc needs to be relaunched in elevated mode !!!
 -     ensureDirectoryExistence(`${selectedinstance.root}/.elxr/run-${runtimestamp}/download.bat`)
 -     
 -     if (!skipprerequisites && !__isElevated || processedArgs.forceprereqs && !__isElevated ) mainTasks.push(verifyAndInstallPrerequisites);
 -     mainTasks.push(maintask)
 -     return any(mainTasks);
 -   })
 - })
 - 
 - // detect if alread installed -> Take no action.
 - // download if no installer avalable -> next()
 - // install 
 - function chackandinstall(items) {
 -   var tasks = []
 -   items.forEach(item => {
 -     tasks.push(getTaskCheckExists(item.shellcommand || prerequisites[item]))
 -   })
 - 
 -   return Promise.all(tasks).then(existances => {
 -     existances.forEach((exists, i) => {
 -       if (!exists) {
 -         return downloadandinstall([items[i]])
 -       }
 -     })
 -   })
 - }
 - 
 - function downloadandinstall(items) {
 -   var tasks = []
 -   items.forEach(item => {
 -     tasks.push(getTaskDownload(item))
 -   })
 -   return Promise.all(tasks)
 - }
 - 
 - 
 - 
 - 
 - // Sample instances config.
 - // var instances = {
 - //   "elixir": {
 - //     "production": {
 - //       "reposervers": ["http://git.bbh", "https://git.bbh.org.in"]
 - //       , "repos": ["ember-masonry-grid", "client", "elixir-client"]
 - //       , "exludeMergeRepos": {
 - //         "elixir-config-development": true, "elixir-config-test": true
 - //         , "elixir-config-production": true, "elixir-data": true
 - //       }
 - //       , "instanceName": "elixir", "node_env": "production"
 - //     }
 - //   }, 
 - //   "current_run": { "instanceName": "elixir", "node_env": "production" }
 - // }
 - 
 - // ,([^\}^\S\r]*?\}) // Regexp to eliminate extra comma at the end of an array or an object...
 
 
  |