|
|
@@ -10,10 +10,13 @@ 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()) |
|
|
|
console.log(getVersion()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 'use strict'; |
|
|
|
|
|
|
@@ -27,7 +30,29 @@ console.log(getVersion()) |
|
|
|
// 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; |
|
|
@@ -40,6 +65,14 @@ console.dir(processedArgs) |
|
|
|
// } |
|
|
|
// }) |
|
|
|
|
|
|
|
var clioverrides = { } |
|
|
|
processedArgs._[1] ? clioverrides.instanceName = processedArgs._[1]: null; |
|
|
|
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; |
|
|
|
|
|
|
|
Object.keys(clioverrides).forEach( prop => { }) |
|
|
|
|
|
|
|
var globSync = require('glob').sync; |
|
|
|
|
|
|
|
var ENV = Object.assign({}, process.env); // Shallow clone it. |
|
|
@@ -55,10 +88,11 @@ const dirs = async (perform, path) => { |
|
|
|
|
|
|
|
var getShellTask = (command, args, options) => { |
|
|
|
options = options || {} |
|
|
|
var callshell = command === 'rm' ? callgitbashtask : callsheltask; |
|
|
|
return () => { |
|
|
|
var p = nodeShellExec.apply(null, [command, args, Object.assign({ |
|
|
|
inherit: true, shell: true, env: ENV, title: `${command} ${args}` |
|
|
|
}, options) |
|
|
|
var p = callshell( [command, args, Object.assign({ |
|
|
|
inherit: true, shell: true, env: ENV, title: `${command} ${args}` |
|
|
|
}, options) |
|
|
|
]) |
|
|
|
if (options.ignorefailures) { |
|
|
|
return p.catch(e => { |
|
|
@@ -69,12 +103,12 @@ var getShellTask = (command, args, options) => { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
var callsheltask = (args) => { return () => { return nodeShellExec.apply(null, args) } } |
|
|
|
var callsheltask = (args) => { |
|
|
|
return args[0] === 'rm' ? callgitbashtask(args) : () => { return nodeShellExec.apply(null, args) } } |
|
|
|
var callgitbashtask = (args) => { return () => { |
|
|
|
return nodeShellExec( `"${gitbash}"`, ['-c', `"${args[0]} ${args[1].join(' ')}"`], args[2]) } |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var getTaskCheckExists = (command, options) => { |
|
|
|
options = options || {} |
|
|
|
return () => { |
|
|
@@ -1117,12 +1151,12 @@ var op = { |
|
|
|
// () => { |
|
|
|
// console.log(`--rm package-lock.json for ${repodef.repo}--------------------`) |
|
|
|
// return nodeShellExec(`"${gitbash}"`, ['-c', '"rm package-lock.json"'], { |
|
|
|
nodeShellExec('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) }) |
|
|
@@ -1963,6 +1997,7 @@ var acquireConfig = function (selected) { |
|
|
|
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; |
|
|
@@ -1973,65 +2008,27 @@ var acquireConfig = function (selected) { |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
var launchpath = process.cwd().replace(/\\/, '/') |
|
|
|
var thisscriptdir = __dirname |
|
|
|
var instanceroot = launchpath; |
|
|
|
var detectInstance = function () { |
|
|
|
console.log(`launchpath = ${launchpath}`) |
|
|
|
console.log(`thisscriptdir = ${thisscriptdir}`) |
|
|
|
|
|
|
|
var root = launchpath; |
|
|
|
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 ; |
|
|
|
|
|
|
|
// We need a reference to the root director for elxr cli to be properly oriented. |
|
|
|
if ((launchpath + path.normalize('/elxr')) === thisscriptdir) { |
|
|
|
// We ran unbuilt from the proper root with elxr subfolder. |
|
|
|
console.log(`Instance Path : ${root}`) |
|
|
|
} |
|
|
|
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. |
|
|
|
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. |
|
|
|
root = path.normalize(launchpath + '/..'); |
|
|
|
} |
|
|
|
else { |
|
|
|
// Assume launchpath is meaningless. |
|
|
|
// Figure it out from the input instance name and environment parameters if we are in the right location. |
|
|
|
root = path.normalize(launchpath + '/' + processedArgs._[1] + '/' + processedArgs.node_env) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
instanceroot = root.replace(/\\/, '/'); |
|
|
|
__default.root = root; |
|
|
|
return Promise.resolve(__default); |
|
|
|
} |
|
|
|
|
|
|
|
// |
|
|
|
var __default = { |
|
|
|
|
|
|
|
// Default is public server only. |
|
|
|
// All public repos are by default available. |
|
|
|
reposervers: ['https://git.bbh.org.in'] |
|
|
|
, repos: [ |
|
|
|
'setup' |
|
|
|
, 'elxr' |
|
|
|
, 'loopback-connector-mysql' |
|
|
|
, 'loopback-jsonapi-model-serializer' |
|
|
|
, 'loopback-component-jsonapi' |
|
|
|
, 'ember-service-worker' |
|
|
|
, 'ember-service-worker-asset-cache' |
|
|
|
, 'ember-service-worker-cache-fallback' |
|
|
|
, 'ember-service-worker-index' |
|
|
|
, 'ember-sw-client-route' |
|
|
|
{ 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: [] |
|
|
@@ -2041,29 +2038,214 @@ var __default = { |
|
|
|
, node_env: 'development' |
|
|
|
} |
|
|
|
|
|
|
|
var __interactve_promts = { |
|
|
|
get reposerver(){ |
|
|
|
return cli.prompt(this.reposervers, 'git default repo').then(reposerver => { |
|
|
|
Object.defineProperty(this, 'reposerver', { |
|
|
|
value: reposerver, |
|
|
|
writable: false, |
|
|
|
configurable : true, |
|
|
|
enumerable : true |
|
|
|
}); |
|
|
|
return reposerver |
|
|
|
}) |
|
|
|
} |
|
|
|
, set reposerver(reposerver){ |
|
|
|
Object.defineProperty(this, 'reposerver', { |
|
|
|
value: reposerver, |
|
|
|
writable: false, |
|
|
|
configurable : true, |
|
|
|
enumerable : true |
|
|
|
}); |
|
|
|
return reposerver |
|
|
|
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 __interactve_promts = function( target ){ |
|
|
|
|
|
|
|
return { |
|
|
|
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 : [], defaultchoice : 'chess'} |
|
|
|
, instanceType : { label : `Enter Instance Type ( <= ${target.instanceType || 'development'} ) : `, choices : [], defaultchoice : 'development'} |
|
|
|
, reposerver : { label : `Enter Instance Name ( <= ${target.reposerver || 'https://git.bbh.org.in'} ) : `, choices : [], defaultchoice : 'https://git.bbh.org.in'} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var downloadsdir = '../Downloads'; |
|
|
|
var prerequisites = [ |
|
|
|
{ |
|
|
@@ -2299,64 +2481,143 @@ function verifyAndInstallPrerequisites() { |
|
|
|
return Promise.all(downloadtasks).then(() => { return any(installtasks) }) |
|
|
|
} |
|
|
|
|
|
|
|
var getPromptableAsyncPropDescriptor = function(propName, choices, defaultchoise){ |
|
|
|
var getPromptableAsyncPropDescriptor = function(propName, promptable){ |
|
|
|
return { |
|
|
|
get (){ |
|
|
|
return cli.prompt( choices, propName, defaultchoise).then(propValue => { |
|
|
|
Object.defineProperty(this, propName, { |
|
|
|
value: propValue, |
|
|
|
writable: false, |
|
|
|
configurable : true, |
|
|
|
enumerable : true |
|
|
|
}); |
|
|
|
return propValue |
|
|
|
return cli.prompt( promptable.choices, promptable.label, promptable.defaultchoice ).then(propValue => { |
|
|
|
if(promptable.interpret){ |
|
|
|
return propName = promptable.interpret(propValue).then( |
|
|
|
()=>{ |
|
|
|
Object.defineProperty(this, propName, { |
|
|
|
value: propValue, |
|
|
|
writable: true, |
|
|
|
configurable : true, |
|
|
|
enumerable : true |
|
|
|
}); |
|
|
|
return propValue |
|
|
|
} |
|
|
|
) |
|
|
|
} |
|
|
|
else return propValue |
|
|
|
}) |
|
|
|
} |
|
|
|
// , set (propValue){ |
|
|
|
// Object.defineProperty(this, propName, { |
|
|
|
// value: propValue, |
|
|
|
// writable: false, |
|
|
|
// 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 = { |
|
|
|
// Try not to prompt anything unless absolutely necessary or reconfirm is forced. |
|
|
|
// 'instanceName' : true |
|
|
|
// , 'node_env' : true |
|
|
|
} |
|
|
|
|
|
|
|
function createChessInsance( cfg ){ |
|
|
|
var inst = {}; |
|
|
|
var __new = Object.assign({}, __default, cfg) |
|
|
|
inst[cfg.node_env] = __new; return inst; |
|
|
|
} |
|
|
|
|
|
|
|
acquireElevationState().then(() => { |
|
|
|
var skipprerequisites = false; |
|
|
|
var clioverrides = { } |
|
|
|
function initinstances(selected) { |
|
|
|
// PB : TODO -- processedArgs should already be part of selected. |
|
|
|
var instanceName = processedArgs._[1] = processedArgs._[1] || chessinstances.current_run.instanceName || selected.instanceName; |
|
|
|
var node_env = processedArgs.node_env = processedArgs.node_env || chessinstances.current_run.node_env || selected.node_env; |
|
|
|
chessinstances[instanceName] = chessinstances[instanceName] || {} |
|
|
|
chessinstances[instanceName][node_env] = chessinstances[instanceName][node_env] || selected; |
|
|
|
chessinstances['current_run'] = chessinstances[instanceName][selected.node_env] ? |
|
|
|
{ instanceName: instanceName, node_env: node_env } : (chessinstances['current_run'] || { instanceName: instanceName, node_env: node_env }) |
|
|
|
var instanceName = processedArgs._[1] |
|
|
|
|| chessinstances.current_run.instanceName |
|
|
|
|| selected.instanceName |
|
|
|
|| clioverrides.instanceName; |
|
|
|
|
|
|
|
var node_env = processedArgs.node_env |
|
|
|
|| chessinstances.current_run.node_env |
|
|
|
|| selected.node_env |
|
|
|
|| clioverrides.node_env; |
|
|
|
|
|
|
|
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'] = 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'] = promptkeys['reposerver'] || __default.reposervers[0]; |
|
|
|
} |
|
|
|
|
|
|
|
// chessinstances[chessinstances.current_run.instanceName] = chessinstances[chessinstances.current_run.instanceName] || {} |
|
|
|
chessinstances[instanceName] = chessinstances[instanceName] || createChessInsance( { |
|
|
|
instanceName, node_env, root : selected.root, reposerver : promptkeys['reposerver'] } ); |
|
|
|
chessinstances['current_run'] = { instanceName: instanceName, node_env: node_env } |
|
|
|
|
|
|
|
if(path.normalize(selected.root) !== path.normalize(chessinstances[instanceName][node_env].root)) { |
|
|
|
throw "Mismatched chessinstances config found " + chessinstances[instanceName][node_env].root + ' does not match ' + selected.root |
|
|
|
} |
|
|
|
// Override sequence. |
|
|
|
// __default, chessinstances[current_run], instanceName-config-development, cliargs, interactve_promts |
|
|
|
selectedinstance = Object.assign( |
|
|
|
selectedinstance = utils.assign( |
|
|
|
selected |
|
|
|
, chessinstances[instanceName][node_env] |
|
|
|
, clioverrides |
|
|
|
// , __interactve_promts -- Cant just override. Also need selectedinstance to be ready... |
|
|
|
); |
|
|
|
|
|
|
|
chessinstances[instanceName] = chessinstances[instanceName] || {} |
|
|
|
chessinstances[instanceName][node_env] = chessinstances[instanceName][node_env] || {} |
|
|
|
// 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 } }) |
|
|
@@ -2376,12 +2637,7 @@ acquireElevationState().then(() => { |
|
|
|
|
|
|
|
return chessinstances |
|
|
|
} |
|
|
|
function acquirelocalinstances(selected){ |
|
|
|
var chessinstances = utils.assign(require(path.normalize(selected.root + '/chessinstances.js'))); |
|
|
|
return chessinstances |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var noprerequisites = { |
|
|
|
add : true, 'set-url' : true, 'repo-relocate' : true |
|
|
|
, remote : true |
|
|
@@ -2428,94 +2684,106 @@ acquireElevationState().then(() => { |
|
|
|
return elxrworker() |
|
|
|
} |
|
|
|
|
|
|
|
return detectInstance().then((detectedInstance)=>{ |
|
|
|
|
|
|
|
processedArgs._[1] ? clioverrides.instanceName = processedArgs._[1]: null; |
|
|
|
processedArgs.node_env ? clioverrides.node_env = (process.env.NODE_ENV && process.env.NODE_ENV.trim()) || 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; |
|
|
|
|
|
|
|
clioverrides.reconfirm = processedArgs.reconfirm |
|
|
|
|
|
|
|
selectedinstance = Object.assign(detectedInstance, clioverrides); |
|
|
|
var todo = Promise.resolve(true); |
|
|
|
var promptkeys = { 'instanceName' : processedArgs._[1] } |
|
|
|
return detectinstances().then((detectedinstanceoptions)=>{ |
|
|
|
|
|
|
|
var getchoices = function(){ |
|
|
|
detectedinstanceoptions.splice(0,0, __default) |
|
|
|
|
|
|
|
var instances = [] |
|
|
|
var reposervers = []; |
|
|
|
var instnaceNames = [] |
|
|
|
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) |
|
|
|
instnaceNames.push(instance.instanceName) |
|
|
|
}) |
|
|
|
}) |
|
|
|
instances = instances.concat(detectedinstanceoptions) |
|
|
|
|
|
|
|
if(clioverrides.reconfirm) { |
|
|
|
var reconfirm = { |
|
|
|
'instanceName' : selectedinstance['instanceName'] === 'chess' |
|
|
|
if(promptkeys['instanceName']) instnaceNames.push(selectedinstance['instanceName']) |
|
|
|
if(promptkeys['instanceName']) instnaceNames.push(promptkeys['instanceName']) |
|
|
|
if(selectedinstance['reposervers']) reposervers = reposervers.concat(selectedinstance['reposervers']) |
|
|
|
|
|
|
|
var choices = { |
|
|
|
'instanceName' : Array.from( new Set(instnaceNames) ) |
|
|
|
, 'reposerver' : Array.from( new Set(reposervers) ) |
|
|
|
, 'instanceType' : Array.from( new Set(instanceTypes) ) |
|
|
|
} |
|
|
|
|
|
|
|
return choices; |
|
|
|
} |
|
|
|
else { |
|
|
|
var reconfirm = {}; |
|
|
|
|
|
|
|
// 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, clioverrides) |
|
|
|
|
|
|
|
if(clioverrides.reconfirm) { |
|
|
|
var reconfirm = { 'instanceName' : selectedinstance['instanceName'] === 'chess' } |
|
|
|
} |
|
|
|
else { var reconfirm = {}; } |
|
|
|
var prompts = []; |
|
|
|
|
|
|
|
var eachPrompt = function(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. |
|
|
|
if(promptkeys[k] && selectedinstance[k] !== promptkeys[k] || promptkeys[k] === undefined && selectedinstance[k] === undefined |
|
|
|
// PB : TODO -- selectedinstance === __default check to prompt everything... |
|
|
|
if( (promptkeys[k] !== undefined && promptkeys[k] !== null) && selectedinstance[k] !== promptkeys[k] |
|
|
|
|| (promptkeys[k] === undefined || promptkeys[k] === null) && (selectedinstance[k] === undefined || selectedinstance[k] === null) |
|
|
|
|| reconfirm[k]) { |
|
|
|
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); |
|
|
|
Object.defineProperty(selectedinstance, k, getPromptableAsyncPropDescriptor(k, choices[k], promptkeys[k] || selectedinstance[k] )); |
|
|
|
promptables[k].choices = choices[k] |
|
|
|
Object.defineProperty(selectedinstance, k, getPromptableAsyncPropDescriptor(k, promptables[k])); |
|
|
|
return await selectedinstance[k] |
|
|
|
}) |
|
|
|
} |
|
|
|
delete promptkeys[k] |
|
|
|
} |
|
|
|
try { |
|
|
|
|
|
|
|
chessinstances = acquirelocalinstances(selectedinstance); |
|
|
|
initinstances(selectedinstance) |
|
|
|
|
|
|
|
var instanceNameChoices = new Set(Object.keys( chessinstances) ) |
|
|
|
instanceNameChoices.delete('current_run') |
|
|
|
instanceNameChoices.add(selectedinstance['instanceName']) |
|
|
|
if(promptkeys['instanceName']) instanceNameChoices.add(promptkeys['instanceName']) |
|
|
|
|
|
|
|
var choices = { |
|
|
|
'instanceName' : Array.from(instanceNameChoices) |
|
|
|
, 'reposerver' : selectedinstance['reposervers'] |
|
|
|
} |
|
|
|
|
|
|
|
findlocalinstances(chessinstances, detectedinstanceoptions) |
|
|
|
|
|
|
|
var choices = getchoices() |
|
|
|
|
|
|
|
Object.keys(__interactve_promts).forEach(eachPrompt, __interactve_promts) |
|
|
|
Object.keys(promptkeys).forEach(eachPrompt, promptkeys) |
|
|
|
var promptables = __interactve_promts(selectedinstance) |
|
|
|
Object.keys(promptables).forEach(eachPrompt, selectedinstance) |
|
|
|
|
|
|
|
todo = any(prompts).then(()=>{ return selectedinstance }) |
|
|
|
|
|
|
|
var todo = Promise.resolve(true); |
|
|
|
|
|
|
|
todo = any(prompts).then(()=>{ |
|
|
|
return initinstances(selectedinstance) |
|
|
|
}) |
|
|
|
} |
|
|
|
catch (e) { |
|
|
|
console.error(e) // Missing chessinstances is not an error... |
|
|
|
|
|
|
|
initinstances(selectedinstance) |
|
|
|
|
|
|
|
var instanceNameChoices = new Set(Object.keys( chessinstances) ) |
|
|
|
instanceNameChoices.delete('current_run') |
|
|
|
instanceNameChoices.add(selectedinstance['instanceName']) |
|
|
|
if(promptkeys['instanceName']) instanceNameChoices.add(promptkeys['instanceName']) |
|
|
|
|
|
|
|
var choices = { |
|
|
|
'instanceName' : Array.from(instanceNameChoices) |
|
|
|
, 'reposerver' : selectedinstance['reposervers'] |
|
|
|
} |
|
|
|
|
|
|
|
Object.keys(__interactve_promts).forEach(eachPrompt, __interactve_promts) |
|
|
|
Object.keys(promptkeys).forEach(eachPrompt, promptkeys) |
|
|
|
// PB : TODO -- verbose mode warning.. console.warn(e) // Missing chessinstances is not an error... |
|
|
|
var choices = getchoices() |
|
|
|
|
|
|
|
var promptables = __interactve_promts(selectedinstance) |
|
|
|
Object.keys(promptables).forEach(eachPrompt, selectedinstance) |
|
|
|
|
|
|
|
todo = any(prompts).then(()=>{ return selectedinstance }) |
|
|
|
todo = any(prompts).then(()=>{ return initinstances(selectedinstance) }) |
|
|
|
|
|
|
|
if(!processedArgs._[0] || !selectedinstance.node_env || !selectedinstance.instanceName){ |
|
|
|
// Weve been told what to do. |
|
|
|
// 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) |
|
|
|
} |
|
|
|
catch (e) { |
|
|
@@ -2536,7 +2804,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) |