|  |  | @@ -10,11 +10,14 @@ 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. | 
		
	
	
		
			
			|  |  | @@ -49,6 +52,7 @@ console.log(getVersion()); | 
		
	
		
			
			|  |  |  | }()); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | const { existsSync } = require('fs'); | 
		
	
		
			
			|  |  |  | const existsFolderSync = existsSync; | 
		
	
		
			
			|  |  |  | const fs = require('fs') | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | const cliargs = utils.cliargs; | 
		
	
	
		
			
			|  |  | @@ -2004,10 +2008,10 @@ var acquireConfig = function (selected) { | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var launchpath = process.cwd().replace(/\\/, '/') | 
		
	
		
			
			|  |  |  | var thisscriptdir = __dirname; // PB : TODO -- Thisscriptdir could be dislocated when run as a standalone file... We need to detect this where and how we were run. | 
		
	
		
			
			|  |  |  | 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) ? thisscriptdir + '/..' : launchpath ; | 
		
	
		
			
			|  |  |  | var instanceroot = path.normalize(thisscriptdir) === path.normalize(launchpath) ? path.normalize(thisscriptdir + '/..') : launchpath ; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var __default = { | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
			|  |  | @@ -2034,73 +2038,150 @@ var __default = { | 
		
	
		
			
			|  |  |  | , node_env: 'development' | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var detectInstance = function () { | 
		
	
		
			
			|  |  |  | 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(path.dirname(root)), instanceName : path.basename( path.dirname(path.dirname(root)) ) } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | var detectinstances = function () { | 
		
	
		
			
			|  |  |  | console.log(`launchpath = ${launchpath}`) | 
		
	
		
			
			|  |  |  | console.log(`thisscriptdir = ${thisscriptdir}`) | 
		
	
		
			
			|  |  |  | console.log(`instanceroot = ${instanceroot}`) | 
		
	
		
			
			|  |  |  | console.log(`instanceroot = ${instanceroot}`) // Not yet confirmed... | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // Note : Paths should already be normalized fefore this. | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var root = instanceroot; | 
		
	
		
			
			|  |  |  | var detected = { root }; | 
		
	
		
			
			|  |  |  | var instanceoptions = [clioverrides] | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // We need a reference to the root director for elxr cli to be properly oriented. | 
		
	
		
			
			|  |  |  | if ((launchpath + path.normalize('/elxr')) === thisscriptdir) { | 
		
	
		
			
			|  |  |  | // We ran from the proper root with elxr subfolder. | 
		
	
		
			
			|  |  |  | // PB : TODO --- Additional checks required to verify elxr is the right folder | 
		
	
		
			
			|  |  |  | // should be a git repo. has elxr signature | 
		
	
		
			
			|  |  |  | // and .elxr folder signature... in the launchpath. | 
		
	
		
			
			|  |  |  | console.log(`Instance Path : ${root}`) | 
		
	
		
			
			|  |  |  | instanceroot = root = launchpath | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | if (launchpath === thisscriptdir) { | 
		
	
		
			
			|  |  |  | // Same directory doesn't mean we are being run from elxr directory or the root directory. | 
		
	
		
			
			|  |  |  | // It could be a standalone elxr build which may or maynot be in the proper location. | 
		
	
		
			
			|  |  |  | if (BUILD_VERSION.indexOf('Version: {version} - built on {date}') > -1) { | 
		
	
		
			
			|  |  |  | // Unbuilt therefore we are in the elxr directory. | 
		
	
		
			
			|  |  |  | instanceroot = root = path.normalize(launchpath + '/..'); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | // Built version. | 
		
	
		
			
			|  |  |  | // check if we have a elxr subfolder. | 
		
	
		
			
			|  |  |  | if (fs.existsSync(launchpath + '/..' + path.normalize('/elxr'))) { | 
		
	
		
			
			|  |  |  | // Probably in the right place. | 
		
	
		
			
			|  |  |  | 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. | 
		
	
		
			
			|  |  |  | console.log(`Instance Path : ${root}`) | 
		
	
		
			
			|  |  |  | instanceroot = root = launchpath; | 
		
	
		
			
			|  |  |  | instanceoptions.splice( 0, 0, dedetected = { root }) | 
		
	
		
			
			|  |  |  | instanceoptions.splice( 0, 0, detectfromroot(root)) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | if (launchpath === thisscriptdir) { | 
		
	
		
			
			|  |  |  | // 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 directory. | 
		
	
		
			
			|  |  |  | instanceroot = root = path.normalize(launchpath + '/..'); | 
		
	
		
			
			|  |  |  | instanceoptions.splice( 0, 0, dedetected = { root }) | 
		
	
		
			
			|  |  |  | instanceoptions.splice( 0, 0, detectfromroot(root)) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | // Assume launchpath is meaningless. | 
		
	
		
			
			|  |  |  | // Figure it out from the input instance name and environment parameters if we are in the right location. | 
		
	
		
			
			|  |  |  | instanceroot = root = path.normalize(launchpath + '/' + processedArgs._[1] + '/' + processedArgs.node_env) | 
		
	
		
			
			|  |  |  | // Built version. | 
		
	
		
			
			|  |  |  | // We could have been run from the elxr subfolder. Highly likely that the built version isn't the full elxr. | 
		
	
		
			
			|  |  |  | if(hasElxrSync(launchpath + '/..')) { | 
		
	
		
			
			|  |  |  | // 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 { | 
		
	
		
			
			|  |  |  | // 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)) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | instanceroot = root.replace(/\\/g, '/'); | 
		
	
		
			
			|  |  |  | __default.root = root; | 
		
	
		
			
			|  |  |  | clioverrides.root = clioverrides.root || root; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // Resolves undefined when No known instances detected. | 
		
	
		
			
			|  |  |  | return Promise.resolve( | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | instanceroot = detected.root | 
		
	
		
			
			|  |  |  | __default.root = root; | 
		
	
		
			
			|  |  |  | clioverrides.root = clioverrides.root || root; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | // We can expect a .elxr at each level. | 
		
	
		
			
			|  |  |  | ['' /* instanceroot */, '../' /* instanceTypes or node_env */, '../..' /* instanceNames */].earlyreduce( ( acc, p, i, a )=>{ | 
		
	
		
			
			|  |  |  | var root = `${instanceroot}/${p}.elxr`; | 
		
	
		
			
			|  |  |  | if(existsSync( root )) { | 
		
	
		
			
			|  |  |  | try { | 
		
	
		
			
			|  |  |  | var chessinstances = acquirelocalinstances( { root } ) | 
		
	
		
			
			|  |  |  | return Object.keys(chessinstances).earlyreduce( ( acc, instanceName) => { | 
		
	
		
			
			|  |  |  | return Object.keys(chessinstances[instanceName]).earlyreduce( (acc, instanceType) => { | 
		
	
		
			
			|  |  |  | if(  path.normalize(chessinstances[instanceName][instanceType].root) === path.normalize(root) ) return { | 
		
	
		
			
			|  |  |  | value : chessinstances[instanceName][instanceType] | 
		
	
		
			
			|  |  |  | , done : true | 
		
	
		
			
			|  |  |  | };s | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | catch(e){ | 
		
	
		
			
			|  |  |  | return {} | 
		
	
		
			
			|  |  |  | ['' /* 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 { } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else return {} | 
		
	
		
			
			|  |  |  | }).value | 
		
	
		
			
			|  |  |  | ) | 
		
	
		
			
			|  |  |  | ) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // Resolves empty array when No known instances detected. | 
		
	
		
			
			|  |  |  | return Promise.resolve(instanceoptions) | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var __interactve_promts = { | 
		
	
	
		
			
			|  |  | @@ -2527,9 +2608,10 @@ acquireElevationState().then(() => { | 
		
	
		
			
			|  |  |  | return elxrworker() | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return detectInstance().then((detectedInstance)=>{ | 
		
	
		
			
			|  |  |  | return detectinstances().then((detectedinstanceoptions)=>{ | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | selectedinstance = utils.assign(detectedInstance || {}, clioverrides) | 
		
	
		
			
			|  |  |  | // PB : TODO -- Most recent should be at the tip ! at index 0 so utils.reverseassign is required !!! | 
		
	
		
			
			|  |  |  | selectedinstance = utils.assign( ...detectedinstanceoptions.slice(-2) ) | 
		
	
		
			
			|  |  |  | promptkeys = utils.assign(promptkeys, { 'instanceName' : clioverrides.instanceName, 'node_env' : clioverrides.node_env }) | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if(clioverrides.reconfirm) { | 
		
	
	
		
			
			|  |  | @@ -2626,7 +2708,7 @@ acquireElevationState().then(() => { | 
		
	
		
			
			|  |  |  | .then(()=>{ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(!__isElevated) { | 
		
	
		
			
			|  |  |  | ensureDirectoryExistence(`${selectedinstance.root}/.elxr/readme.txt`) | 
		
	
		
			
			|  |  |  | ensureDirectoryExistence(`${selectedinstance.root}/.elxr/${__ALIAS__STAMP__}`) | 
		
	
		
			
			|  |  |  | // collect garbage | 
		
	
		
			
			|  |  |  | return dirs( (dir)=>{ | 
		
	
		
			
			|  |  |  | var matches = /run-(.*)/gm.exec(dir.name) |