Aksha Thomas 3 år sedan
förälder
incheckning
0f1b5a9f73
3 ändrade filer med 633 tillägg och 253 borttagningar
  1. 30
    4
      cliverse.js
  2. 546
    206
      i.win.js
  3. 57
    43
      index.js

+ 30
- 4
cliverse.js Visa fil

@@ -6,14 +6,34 @@ function nodeShellExec() {
var args = Array.from(arguments);
var opts = args[2] = args[2] || {}
opts.title ? null : opts.title = `${args[0]} ${args[1] }`
const child = spawn(...arguments);
// // const spawn = require('child_process').spawn;
// const s = spawn(
// 'C:\\Program Files\\Git\\bin\\sh.exe'
// , ['notepad', 'index'], { cwd: __dirname });



// var interval = null;
// var t = setTimeout(function(){
// interval = setInterval(function(){
// console.log('Awaiting close : ' + child.spawnargs)
// }, 1500)
// // console.log('Awaiting close : ' + child.spawnargs)

// }, 0)

// child.on('close', (code) => {
// console.error('Prematurely closed even before promise...')
// })
// D:\chess\instances\elixir_01\elxr/.elxr/run-1630002739610/download.bat https://github.com/git-for-windows/git/releases/download/v2.33.0.windows.2/Git-2.33.0.2-64-bit.exe D:\\chess\\instances\\elixir_01\\elxr/Downloads/Git-2.33.0.2-64-bit.exe
// D:\\chess\\instances\\elixir_01\\elxr/.elxr/run-1630002923584/download.bat https://github.com/git-for-windows/git/releases/download/v2.33.0.windows.2/Git-2.33.0.2-64-bit.exe D:\\chess\\instances\\elixir_01\\elxr/Downloads/Git-2.33.0.2-64-bit.exe
var p = new Promise(function(resolve, reject){
console.log(...args)
const child = spawn(...args);
if(!opts.detached) {
var messages = []; // PB : TODO -- Explore stream for Task level aggregation to prevent interleaved messages from multiple tasks...
var success = true;
@@ -25,7 +45,9 @@ function nodeShellExec() {
chunk.trim() === '' ? null : messages.push(chunk); /* console.log('d: ' + chunk) */
process.stdout.write( chunk )
});
child.on('error', (chunk) => { success = false; messages.push(chunk); /* console.error('e: ' + chunk) */ } );
child.on('error', (chunk) => { success = false; messages.push(chunk); /* console.error('e: ' + chunk) */
console.log('Error exit not handled.')
} );
child.stderr.on('data', (chunk) => {
if(messages.join('').indexOf('fatal: not a git repository') > -1) opts.haserrors = true;
messages.push(chunk);
@@ -34,6 +56,7 @@ function nodeShellExec() {
});
}
child.on('close', (code) => {
console.log('Proper close was fired')
var logEntry = { code, success }
if(+code !== 0 || opts.haserrors) { success = false; logEntry = { result: `${opts.title} exited with code ${code}`, success, code }};
if(opts.stdio !== 'ignore') {
@@ -49,16 +72,18 @@ function nodeShellExec() {
process.stdout.write( messages.join('') )
}
}
// clearInterval(interval)
if(code !== 0 || opts.haserrors) return reject(logEntry)
resolve(logEntry)
});
}
else {
child.unref()
// clearInterval(interval)
resolve(true);
}
});
p.process = child;
// p.process = child;
return p;
}

@@ -68,7 +93,7 @@ var prompt = function(choices, label, defaultchoice){
).then(choice => {
if(!choice) return defaultchoice || choices[0];
if(choice && isNaN(+choice)) return choice;
return choices[choice + 1];
return choices[(+choice) - 1];
})
}

@@ -83,6 +108,7 @@ var cli = {
return new Promise((resolve, reject)=>{
clii.question(q, (answer)=>{
clii.close();
console.log("resolve is being called");
resolve(answer)
})
})

+ 546
- 206
i.win.js Visa fil

@@ -1,116 +1,475 @@
// // --------------------------------------------
// // Cscript
// var console = { log : function(m) {WScript.Echo(m)}, error : function(m) {WScript.Echo(m)}
// , dir : function(o) {
// for(var i in o){ console.log(i + ' : ' + o[i])}
// }
// }
// var wait = function(cb, ms) { WScript.Sleep(ms); cb() }
// var fso = new ActiveXObject('Scripting.FileSystemObject');
// var shell = new ActiveXObject('shell.application');
// var existsSync = function(filepath){ return fso.FileExists(filepath) }
// var fs = {
// writeFileSync : function(filepath, text) {
// console.log(filepath)
// var fh = fso.CreateTextFile(filepath, true);
// fh.WriteLine(text);
// fh.Close();
// }
// , mkdirSync : function(path) {
// fso.CreateFolder(path)
// }
// , readFileSync : function(filepath){
// var objFileToRead = fso.OpenTextFile(filepath,1)
// var strFileText = objFileToRead.ReadAll()
// objFileToRead.Close()
// }
// , unlinkSync : function(filepath){ fso.DeleteFile(filepath) }
// }

var BUILD_VERSION = '[VI]Version: {version} - built on {date}[/VI]';
var runtimestamp = (new Date()).getTime();
function getVersion() { return BUILD_VERSION; }
WScript.echo(getVersion())
// var path = {
// resolve : function(path){ return fso.GetAbsolutePathName(path) }
// , dirname : function(filepath) {
// var normalized = this.normalize(filepath)
// var li = normalized.lastIndexOf("\\")
// if( li > -1) {
// return normalized.substring(0, li)
// }
// }
// , normalize : function(path){
// return path.replace(/\//g,'\\');
// }
// }
// var existsSyncFolder = function(path){
// return fso.FolderExists(path)
// }
// function nodeShellExec(cmd, cargs){
// var p = new Promise(function(resolve, reject){
// var runFile = selectedinstance.root + '\\' + stampedFilePfx(new Date()) + cmd + cargs + "out.txt";
// // console.log(runFile)
// shell.ShellExecute('cmd', '/c ' + cmd + ' ' + cargs + " > " + runFile , "", "", 1);
// // var WshFinished = 1
// // var WshFailed = 2
// // var strOutput = 'Did not work'
// // switch(shell.Status){
// // case WshFinished :
// // strOutput = oShell.StdOut.ReadAll;
// // break;
// // case WshFailed :
// // strOutput = oShell.StdErr.ReadAll;
// // break;
// // }
// // WScript.Echo(strOutput)

var fso = new ActiveXObject('Scripting.FileSystemObject');
var shell = new ActiveXObject('shell.application');
function forEach(eachFn){
for(var i=0; i<this.length; i++) eachFn(this[i])
}
// while(!existsSync(runFile)) { wait(500, function(){}) }

// var strFileText = fs.readFileSync(runFile)
// // console.log(strFileText)
// fs.unlinkSync(runFile)
// var result = { result : 'cmd /c ' + cmd + ' ' + cargs + " > " + runFile + ' exited with code ???', messages : [].push(strFileText), code : 0, success : true }
// console.log('resolving ' + result)
// resolve(result)
// })
// return p;
// }

var __Promise = {};
// var ovrrides = {
// resolve : function(v){
// if(v && v.then) return v;
// var p = new Promise(function(resolve, reject){ resolve(v) });
// return p;
// }
// };

var console = { log : function(m) {WScript.Echo(m)}, error : function(m) {WScript.Echo(m)} }
var Promise = function(fn){
try{ __Promise = Promise }
catch(e){
// __Promise = ovrrides
}

// Detect error
var state = Promise.PENDING;
var chain = [];
chain.forEach = forEach;
function createPromiseClass(overrides) {

function reject(e){
if(state !== Promise.PENDING) { console.error ('Error : Promise Rejection can only be called once')}
var p = this;
console.error(e)
if(p.state !== PromiseClass.PENDING) { console.error ('Error : Promise Rejection can only be called once')}
var __i = 0;
var __e = e;
do {
for(var i = __i; i < chain.length; i++, __i = i) if(chain[i].isCatch) break;
for(var i = __i; i < p.chain.length; i++, __i = i) if(p.chain[i].isCatch) break;
try {
for(var i = __i; i < chain.length; i++, __i = i) if(chain[i].isCatch) { chain[i](__e); break; }
for(var i = __i; i < p.chain.length; i++, __i = i) if(p.chain[i].isCatch) { p.chain[i](__e); break; }
__i++;
__e = null;
}
catch(e){ __e = e}
catch(e){ __i++; __e = e}
} while(__e)
do {
try { for(var i = __i; i < chain.length; i++, __i = i) if(!chain[i].isCatch) { p.result = chain[i](p.result); } }
try { for(var i = __i; i < p.chain.length; i++, __i = i) if(!p.chain[i].isCatch) { p.result = p.chain[i](p.result); } }
catch(e){
__i ++;
do {
try {
for(var i = __i; i < chain.length; i++, __i = i) if(chain[i].isCatch) { chain[i](__e); break; }
for(var i = __i; i < p.chain.length; i++, __i = i) if(p.chain[i].isCatch) { p.chain[i](__e); break; }
__i ++;
__e = null;
}
catch(e){ __e = e}
catch(e){ __i++; __e = e}
} while(__e)
}
} while ( __i < chain.length )
state = Promise.REJECTED;
} while ( __i < p.chain.length )
p.state = PromiseClass.REJECTED;
}

function resolve(result){
if(state !== Promise.PENDING) { console.error ('Error : Promise Rejection can only be called once')}
// console.log('main promise resolve... ' + chain.length )
// console.log(result + ' resolve was called ' + p.chain.length )
var p = this;
if(p.state !== PromiseClass.PENDING) { console.error ('Error : Promise Resolve can only be called once')}
p.result = result;
if(PromiseClass.resolve(p.result) === p.result) {
waitForResult(p.result, processchain.bind(p))
}
else {
// p.state = PromiseClass.FULFILLED;
return processchain.bind(p)(result)
}
};

function processchain(r){
var __i = 0;
do {
try { for(var i = __i; i < chain.length; i++, __i = i) if(!chain[i].isCatch) { p.result = chain[i](p.result); } }
catch(e){
var __e = e;
do {
try {
for(var i = __i; i < chain.length; i++, __i = i) if(chain[i].isCatch) { chain[i](__e); break; }
__e = null;
var i = __i;
var __e = null;
p = this;

function __processchain(r){

function waitForThen(p){
if(i < p.chain.length) {
if(!p.chain[i].isCatch) {
// console.log(i + ' Executing : then ' + p.result + ' ' + p.chain[i])
try {
p.result = p.chain[i](p.result)
if(PromiseClass.resolve(p.result) === p.result) {
waitForResult(p.result, function(r){
p.result = r; i++; __i = i;
waitForThen(p)
})
}
else {
i++; __i = i;
waitForThen(p)
}
}
catch(e) {
i++; __i = i;
__e = e;
console.log('failed on index ' + __i + p.chain[__i-1] )
console.dir(e)
waitForCatch(p);
}
}
else {
// console.log(i + ' Skipping catch : ' + p.result + ' ' + p.chain[i])
i++; __i = i;
waitForThen(p)
}
catch(e){ __e = e}
} while(__e)
}
} while ( __i < chain.length )
state = Promise.FULFILLED;
};
}
else return p.state = PromiseClass.FULFILLED;
}
function waitForCatch(p) {
if(i < p.chain.length) {
if(p.chain[i].isCatch) {
console.log(i + ' Executing : catch : ' + p.result + ' ' + p.chain[i])
try {
p.result = p.chain[i](__e);
var p = {
then : function(thenfn){
thenfn.isThen = true
chain.push(thenfn)
return p;
if(PromiseClass.resolve(p.result) === p.result) {
waitForResult(p.result, function(r){
p.result = r; i++; __i = i;
})
waitForThen(p)
}
else {
p.result = r; i++; __i = i;
waitForThen(p)
}
}
catch(e){ i++; __i = i;; __e = e; waitForCatch(p) }
}
else {
i++; __i = i;
waitForCatch(p)
}
}
else return p.state = PromiseClass.REJECTED
}
waitForThen(p);
}
__processchain(r)
}

var create = function(fn){
var p = {
then : function(thenfn){
thenfn.isThen = true
p.chain.push(thenfn)
return p;
}
, pcatch : function(catchfn) {
catchfn.isCatch = true
p.chain.push(catchfn)
return p;
}
, start : function(){
if(this.started) {
console.error('Cannot start more than once...')
return p
};
this.started = true;
this.fn = fn;
try { fn(resolve.bind(p), reject.bind(p)) }
catch(e){ reject(e) }
return p
}
, state : PromiseClass.PENDING
, chain : []
}
, pcatch : function(catchfn) {
catchfn.isCatch = true
chain.push(catchfn)
return p;

p.catch = p.pcatch
p.chain.forEach = forEach;
return p;
}

var PromiseClass = function(fn){
var p = create(fn)
setTimeout(p.start.bind(p), 0)
return p
}

PromiseClass.PENDING = 1
PromiseClass.FULFILLED = 2
PromiseClass.REJECTED = 3
PromiseClass.STARTED = 4
PromiseClass.isSETTLED = function(p){ p.state === PromiseClass.FULFILLED || p.state === PromiseClass.REJECTED }

PromiseClass.resolve = function(v){
if(v && v.then) return v;
var p = create(function(){});
p.result = v;
wait(0, function(){ processchain.bind(p)(v) })
return p;
}

function waitForResult(p, cb){
if(!p) return cb(p)
if(p.state !== PromiseClass.PENDING) cb(p.result)
if(p.runFile && false) {
while(!existsSync(p.runFile) && p.state === PromiseClass.PENDING) {
console.log('Waiting for ResultFle'); wait(500, function(){})
}
cb(p.result)
}
, start : function(){
try { fn(resolve, reject) }
catch(e){ reject(e) }
else {
// while(p.state === PromiseClass.PENDING) {
// console.log('Waiting for Result')
function waiter(){
// console.log(p.result)
if(p.state === PromiseClass.PENDING) wait(500, waiter);
else return cb(p.result)
}
wait(500, waiter)
// }
}
}
return p
}

Promise.all = function(arr){
arr.forEach = forEach;
var results = [];
return new Promise(function(resolve, reject){
arr.forEach(function(p){ results.push(waitForResult(p))} )
resolve(results)
});
PromiseClass.all = function(arr){
arr.forEach = forEach;
var resultPs = [];
var results = [];
console.log('All : ' + arr.length)
var pAll = new PromiseClass(function(resolve, reject){
arr.forEach(function(p){
if(!p.then) { var pfn = p; p = new PromiseClass(function(resolve, reject){ pfn() }) }
else {
// !p.start ? p.start = function(){return p} : null
// p.start()
// .then( function(){ waitForResult(p, function(r){ results.push(r) }) })
}
resultPs.push(p)
// waitForResult(p, function(r){ results.push(r) })
})
// PB : TODO -- This is the same as processchain!!!
var allwaitr = function(){
var allResolved = true
for(var rIdx =0; rIdx < resultPs.length; rIdx++ ){
if(resultPs[rIdx]) {
allResolved = false
waitForResult(resultPs[rIdx], function(r){ results[rIdx] = r; resultPs[rIdx] = null; })
break;
}
}
if(allResolved) resolve(results);
else wait(500, allwaitr)
}
wait(500, allwaitr)
})
// pAll.chain = arr;
return pAll
}
// PromiseClass.resolve = overrides.resolve;
Promise = PromiseClass;
return PromiseClass;
}

any = function(arr){
arr.forEach = forEach;
var results = [];
return new Promise(function(resolve, reject){
arr.forEach(function(p){ results.push(waitForResult(p))} )
resolve(results)
});
createPromiseClass(/*ovrrides*/)

// any = function(arr){
// arr.forEach = forEach;
// var results = [];
// console.log('Any : ' + arr.length)
// return new Promise(function(resolve, reject){
// arr.forEach(function(p){
// console.log('P is : ' + p)
// if(!p.then) { var pfn = p; p = new Promise(function(resolve, reject){ try{ resolve(pfn()) } catch(e){reject(e) } }).start() }
// else {
// !p.start ? p.start = function(){return p} : null
// p.start()
// }
// // results.push(waitForResult(p))
// } )
// resolve(results)
// }).start();
// }

// var any = function(iterable, continueOnFailure) {
// var cancelsignal = Symbol()
// return iterable.reduce(
// function(p, tasq, i ,a) {
// var handleError = function(err, pVal){
// if(err !== cancelsignal) {
// // Cancel only once on first failure.
// console.log('Failed : ' + err.message + ' ' + JSON.stringify(pVal))
// console.dir(p)
// console.warn('Possible failure for task with result : ' + JSON.stringify(pVal))
// if(i>0 && a[i-1].info) console.dir(a[i-1].info)
// console.error('Error : ' + err.stack)
// console.error(a[i-1])
// a[i-1] ? console.log("tasq : " + a[i-1].toString()) : null;
// if(!continueOnFailure) {console.log("Cancelling remaining on any one failure ..."); throw cancelsignal}
// else return pVal;
// // tasq ? console.log("tasq : " + tasq.toString()) : null; // Previous task is what failed not the one we are going to run.
// }
// }

// if(Promise.resolve(p) === p ) {
// if(i>0 && a[i-1].info) p.info = a[i-1].info;
// return p.then( function(pVal){
// // Falsy values are no longer treated as task failure exceptions. Specially for Promises.
// // Even tasq function wrappers are required to return promises that eventually either resolve or reject..
// // Failures are known for promises on reject.
// // In future if we support direct sync function execution with a result examination for failure
// // we could examine the result of the function as falsy's... or a result evaluator handler needs to be passed in...
// // if(!pVal) handleError({ error : true, message : 'Failed without result' }, pVal)

// // Truthy values are failures if obj has error=true.
// if(pVal && pVal.error) handleError(pVal, pVal)

// var trycall = function(tasq){
// try {
// var result = tasq() // PB : TODO -- Handle scope for call
// if(tasq.resultHandler) return tasq.resultHandler(result)
// // if(!result) throw result; // Default failure detection for functions is falsy values.
// return result
// } catch (error) {
// console.error(error);
// console.error('Error : ' + error ? error.stack : 'No stack')
// if(!continueOnFailure) throw error; // PB : TODO -- Support array of results for any with or without continueonfailure.
// }
// }
// var handleNext = function(){
// console.log('Task finished with result : ' + JSON.stringify(pVal))
// if(i>0 && a[i-1].info) console.dir(a[i-1].info)
// if(!tasq && !continueOnFailure) { console.log('Error : No task specified.'); throw false;}
// else if(!tasq) { console.log('Error : No task specified.'); return false;}
// return (Promise.resolve(tasq) === tasq ) ? tasq : trycall(tasq) ;
// }

// if(Promise.resolve(pVal) === pVal) {
// // Passed in function retured a promise. We still need to wait for it.
// pVal.then(function(pVal){ return handleNext(); })
// }
// else return handleNext()
// }).pcatch(function(error) {
// if(error !== cancelsignal) {
// console.log(`E3 : i = ${i} `);
// if(error.result) console.error(`error.result`)
// console.error('Error : ' + (error.message || error.messages))
// console.error('Error : ' + error.stack)
// tasq ? console.log("tasq : " + tasq.toString()) : null;
// console.log('debugData 3-------------------------');
// // handleError()
// throw error
// }
// else throw cancelsignal;
// })
// }
// else if(!p) {
// handleError({ error : true, message : 'Failed without result' }, pVal)
// console.log("Bypass remaining on prior failure");
// return false; // All remaining tasks will return false in the any results even if they are promisies still running or functions not initiated.
// }
// else return p; // A truthy value
// }
// , Promise.resolve(true)
// );
// }


// --------------------------------------------



// --------------------------------------------
// Node
var wait = function(ms, cb) {
return new __Promise(function(resolve){ setTimeout(resolve, ms) } ).then(function(){ cb() });
}
const fs = require('fs')
const { existsSync } = require('fs');
const existsSyncFolder = existsSync
const path = require('path');
var cli = require('./cliverse')
var nodeShellExec = cli.nodeShellExec;
var utils = require('bbhverse');
var any = utils.any;
// --------------------------------------------


Promise.PENDING = 1
Promise.FULFILLED = 2
Promise.REJECTED = 3

var callsheltask = function(args) { return function() { return nodeShellExec.apply(null, args) } }
var gitUser = 'guest';
var gitEmail = 'guest@bbh.org.in';

function waitForResult(p){
while(p.state === Promise.PENDING) WScript.Sleep(500)
return true
var BUILD_VERSION = '[VI]Version: {version} - built on {date}[/VI]';
var runtimestamp = (new Date()).getTime();
function getVersion() { return BUILD_VERSION; }
console.log(getVersion())

function forEach(eachFn){
for(var i=0; i<this.length; i++) eachFn(this[i])
}

var stampedFilePfx = function(date) {
@@ -121,76 +480,14 @@ var stampedFilePfx = function(date) {
('0' + date.getMinutes()).slice(-2) +
('0' + date.getSeconds()).slice(-2);
}
function nodeShellExec(cmd, cargs){
var p = new Promise(function(resolve, reject){
var runFile = selectedinstance.root + '\\' + stampedFilePfx(new Date()) + cmd + cargs + "out.txt";
// console.log(runFile)
shell.ShellExecute('cmd', '/c ' + cmd + ' ' + cargs + " > " + runFile , "", "", 1);
// var WshFinished = 1
// var WshFailed = 2
// var strOutput = 'Did not work'
// switch(shell.Status){
// case WshFinished :
// strOutput = oShell.StdOut.ReadAll;
// break;
// case WshFailed :
// strOutput = oShell.StdErr.ReadAll;
// break;
// }
// WScript.Echo(strOutput)

while(!fso.FileExists(runFile)) {
WScript.Sleep(500)
}

var objFileToRead = fso.OpenTextFile(runFile,1)
var strFileText = objFileToRead.ReadAll()
objFileToRead.Close()

fso.DeleteFile(runFile)
resolve(strFileText)
})
return p;
}

// Detect or specify install directory.
var selectedinstance = {
root : fso.GetAbsolutePathName(".")
}

var selectedinstance = { root : path.resolve(".") }
var downloadsdir = selectedinstance.root + '/Downloads';

var fs = {
writeFileSync : function(filepath, text) {
WScript.echo(filepath)
var fh = fso.CreateTextFile(filepath, true);
fh.WriteLine(text);
fh.Close();
},
existsSync : function(path){
// fso.FileExists(path)
return fso.FolderExists(path)
}
, mkdirSync : function(path) {
fso.CreateFolder(path)
}
}

var path = {
dirname : function(filepath) {
var normalized = filepath.replace(/\//g,'\\');
var li = normalized.lastIndexOf("\\")
if( li > -1) {
return normalized.substring(0, li)
}
}
}

function ensureDirectoryExistence(filePath) {
var dirname = path.dirname(filePath);
if (fs.existsSync(dirname)) {
if (existsSyncFolder(dirname)) {
return filePath;
}
ensureDirectoryExistence(dirname);
@@ -201,12 +498,18 @@ function ensureDirectoryExistence(filePath) {
var getTaskCheckExists = function(command, options) {
options = options || {}
return function() {
var runFile = path.normalize(selectedinstance.root + '/.elxr/run-' + runtimestamp + '/' + stampedFilePfx(new Date()) + command + "out.txt");
var p = nodeShellExec.apply(null, ['where', [command]])
p.runFile = runFile;
var catchr = 'pcatch'
if(p['catch']) { catchr = 'catch' } else { catchr = 'pcatch';}
if (options.ignorefailures) {
return p.then(function(v) {
// WScript.Echo('firstThen ' + v);
return v }).pcatch( function(e) { // Ignore. Not a major error.
return false;
return v })[catchr]( function(e) {
console.error(e);
// Ignore. Not a major error if where command fails !!!
throw e;
})
}
else return p.then(function() {
@@ -218,88 +521,118 @@ var getTaskCheckExists = function(command, options) {
function verifyAndInstallPrerequisites() {
fs.writeFileSync(ensureDirectoryExistence(downloadsdir + '/readme.txt'), getVersion() + ' Your local downloads for this instance');
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 \
"::************************************************************************** \r\n \
:Download_ <url> <File> \r\n \
Powershell.exe ^\r\n \
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'; ^\r\n \
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols; ^\r\n \
(New-Object System.Net.WebClient).DownloadFile('%1','%2') \r\n \
exit /b \r\n \
::**************************************************************************";
fs.writeFileSync('download.bat', downloadbatch);
ensureDirectoryExistence(path.normalize(selectedinstance.root + '/.elxr/run-' + runtimestamp + '/readme.txt'))
fs.writeFileSync(path.normalize(selectedinstance.root + '/.elxr/run-' + runtimestamp + '/download.bat'), downloadbatch);

var downloadtasks = [];
var installtasks = [];
prerequisites.forEach(function(preq) {
var p = null;
downloadtasks.push(
p = preq.exists().then(function(exists) {
if (exists) console.log( preq.shellcmd + ' exists');
else {
console.log(preq.shellcmd + ' is not installed');
return preq.preinstallsteps().then(function(){
installtasks.push(task.install);
})
}
var p = preq.exists().then(function(exists) {
if (exists && false) console.log( preq.shellcmd + ' exists');
else {
console.log(preq.shellcmd + ' is not installed');
return preq.preinstallsteps().then(function(){
console.log(' task.install : ' + preq.install)
installtasks.push(preq.install.bind(preq));
})
}
));
p.start()
})
// .then(function(res){ console.log( 'preinstallsteps ' + res)});
downloadtasks.push( p )
});
return Promise.all(downloadtasks).then(function(){ return any(installtasks) })
return Promise.all(downloadtasks).then(function(){
console.log('calling install tasks')
return any(installtasks) })
}

// var choiceHandler = function(choices, choice) {
// console.log('chosen : ' + choice)
// var decision = choices['d'];
// if (choice && choice === 'd' || !choice) {
// decision = choices['d']
// }
// else if (isNaN((+choice))) {
// decision = choice
// }
// else decision = choices[choice-1]
// if(!decision) throw 'Invalid selection : ' + decision
// return decision
// }

var prerequisites = [
{
shellcmd: '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'
url: 'https://github.com/git-for-windows/git/releases/download/v2.33.0.windows.2/Git-2.33.0.2-64-bit.exe'
, installer: 'Git-2.33.0.2-64-bit.exe'
, installcmd: ['cmd', ['/c', 'start',
'/WAIT', downloadsdir + '/' + 'Git-2.31.0-64-bit.exe'
'/WAIT', downloadsdir + '/' + 'Git-2.33.0.2-64-bit.exe'
, '/VERYSILENT'
// , '/MERGETASKS=!runcode' // This is required only for vscode...
]]
, preinstallsteps: function() {
var prompt = cli.prompter;
var steps = [
var self = this;
console.log('Git preinstall steps')

var steps = [];
steps.push(
function(){
var choices = { 0 : 'guest', 1 : 'chessdemo' }
return cli.prompt(choices, 'git user name', gitUser).then(function(choice){ gitUser = choice } )
}
)

steps.push(
function(){
var choices = { 0 : 'guest@bbh.org.in', 1 : 'chessdemo@bbh.org.in' }
return cli.prompt(choices, 'git user email', gitEmail).then(function(choice){ gitEmail = choice })
}
)
steps.push(
function(){
if (!existsSync(downloadsdir + '/' + this.installer)) {
return nodeShellExec(selectedinstance.root + '/.elxr/run-${runtimestamp}/download.bat', [this.url, downloadsdir + '/' + this.installer])
if (!existsSync(downloadsdir + '/' + self.installer)) {
return nodeShellExec(selectedinstance.root + '/.elxr/run-' + runtimestamp + '/download.bat', [self.url, downloadsdir + '/' + self.installer])
}
else {
console.log(self.installer + ' Already exits Download skipped.')
return Promise.resolve(true)
}
else return Promise.resolve(true)
}
]
var prompts = [
function() {prompt.ask('git user name : ( <= ' + gitUser + ' )').then( function(user){ gitUser = user; })}
, function() { prompt.ask('git email : ( <= ' + gitEmail + ' )').then(function(email) { gitEmail = email; })}
]
return any([any(steps), any(prompts)])
)
return any(steps)
// return any([any(steps), any(prompts)])
}
, installsteps: function () {
return any([this.installcmd].map(callsheltask))
var self = this;
return any([self.installcmd].map(callsheltask))
}
, postinstallsteps: function(){
var prompt = cli.prompter;
var gitUser = 'guest';
var gitEmail = 'guest@bbh.org.in';
var prompts = [];
prompts.push(

// PB : TODO -- Detect failure or cancellation before attenpting postinstall steps...
var steps = [];
steps.push(
function(){
var choices = { 0 : 'guest', 1 : 'chessdemo' }
return cli.prompt(choices, 'git user name').then(function(gituser) { gitUser = gituser})
return cli.prompt(choices, 'git user name', gitUser).then(function(choice){ gitUser = choice } )
}
)

prompts.push(
steps.push(
function(){
var choices = { 0 : 'guest@bbh.org.in', 1 : 'chessdemo@bbh.org.in' }
return cli.prompt(choices, 'git user email').then(function(gitemail) { gitEmail = gitemail})
return cli.prompt(choices, 'git user email', gitEmail).then(function(choice){ gitEmail = choice })
}
)

return any(prompts).then(function(){
return any(steps).then(function(){
var steps = [
['git', ['config', '--global', '--add', 'user.name', gitUser]]
, ['git', ['config', '--global', '--add', 'user.email', gitEmail]]
@@ -310,7 +643,8 @@ var prerequisites = [
});
}
, install: function () {
return any([ /*this.preinstallsteps,*/ this.installsteps.bind(this), this.postinstallsteps.bind(this)])
var self = this;
return any([ /*self.preinstallsteps,*/ self.installsteps.bind(self), self.postinstallsteps.bind(self)])
}
, verifyAndInstall : function(){
var self = this;
@@ -321,9 +655,9 @@ var prerequisites = [
}
, exists : function(next){
var self = this;
return getTaskCheckExists(this.shellcmd, { ignorefailures: true })().then(function(exists) {
if(exists && exists.indexOf(self.shellcmd) > -1 ) {
// console.log(exists + ' git exists')
return getTaskCheckExists(self.shellcmd, { ignorefailures: true })().then(function(exists) {
console.log(exists + ' git exists')
if(exists && exists.messages.join(' ').indexOf(self.shellcmd) > -1 ) {
return true;
}
else return false
@@ -359,32 +693,38 @@ var prerequisites = [
,
{
shellcmd: 'node',
url: 'https://nodejs.org/dist/v14.16.0/node-v14.16.0-x64.msi'
, installer: 'node-v14.16.0-x64.msi'
url: 'https://nodejs.org/dist/v14.16.0/node-v14.17.3-x64.msi'
, installer: 'node-v14.17.3-x64.msi'
, installcmd: ['MSIEXEC.exe', ['/i'
, downloadsdir + '/' + 'node-v14.16.0-x64.msi'
, path.normalize(downloadsdir + '/' + 'node-v14.17.3-x64.msi')
, 'ACCEPT=YES', '/passive']]
, install : function() { return any([this.installcmd].map(callsheltask)) }
, install : function() {
var self = this;
return any([self.installcmd].map(callsheltask))
}
, exists : function(next){
var self = this;
return getTaskCheckExists(this.shellcmd, { ignorefailures: true })().then(function(exists) {
if(exists && exists.indexOf(self.shellcmd) > -1 ) {
// console.log(self.shellcmd + ' ' + exists + ' node exists')
return true
}
else {
// console.log(self.shellcmd + ' ' + exists + ' node doesnt exist')
return false
}
return getTaskCheckExists(self.shellcmd, { ignorefailures: true })().then(function(exists) {
console.log(self.shellcmd + ' ' + exists + ' node exists')
// if(exists && exists.messages.join(' ').indexOf(self.shellcmd) > -1 ) {
// return true
// }
// else {
// // console.log(self.shellcmd + ' ' + exists + ' node doesnt exist')
// return false
// }
})
}
, preinstallsteps : function(){
return true;
return Promise.resolve(true);
}
}
]

prerequisites.forEach = forEach;

verifyAndInstallPrerequisites()
// nodeShellExec(selectedinstance.root + '/.elxr/run-' + '1629889572461' + '/download.bat'
// , ['https://github.com/git-for-windows/git/releases/download/v2.31.0.windows.1/Git-2.32.0.2-64-bit.exe'
// , downloadsdir + '/' + 'Git-2.32.0.2-64-bit.exe']).start()
verifyAndInstallPrerequisites()

+ 57
- 43
index.js Visa fil

@@ -148,7 +148,7 @@ var getPullCmd = (repo, branch) => {
, { cwd: instanceroot + '/' + repo, title : 'pull all origins for ' + branch + ' ' + repo + ' ' + parameters.join(' ') }]
}
else {
console.warn('No branch was specified detecting from working client.')
// console.warn('No branch was specified detecting from working client.')
// First check if working client exits.
// if (existsSync(instanceroot + '/' + repo)) {
var pullCmd = gitops.getdiscoverbranchcmd(repo)
@@ -258,7 +258,6 @@ var acquireElevationState = () => {
}


var repomanifest = null;
var currentGitAuthUser; // nodeShellExec('git', ['config', 'user.email']) ... PB : TODO-- get the current gittea username
var defaultRepoOwner = 'chess';
var elevatedRunasRepos = null
@@ -282,7 +281,6 @@ var dbForLabel = function (label) {
var gitbash = "C:\\Program Files\\Git\\bin\\sh.exe"
// var gitbash = "G:\\Installed\\Git\\bin\\sh.exe"
// Relevant git repos
// var repomanifest = require('../'+repomanifest.instanceName+'-config-'+ nodeenv +'/repo-manifest')()
var exludeMergeRepos = [];
var useGitPull = processedArgs.useGitPull || false;
var configPromise = null
@@ -1290,12 +1288,12 @@ var op = {
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: repomanifest.node_env }
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 === (repomanifest.node_env || runconfig.NODE_ENV) &&
repomanifest.instanceName && runconfig.use === repomanifest.instanceName) {
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') }
@@ -1710,8 +1708,8 @@ var elxr = {


def = def || {
repos : repomanifest.repos,
elevated : repomanifest.elevated
repos : selectedinstance.repos,
elevated : selectedinstance.elevated
}

var elevatedpulltasks = null;
@@ -1780,13 +1778,13 @@ var elxr = {

function preworkerconfig(){
// Everything runs after this check is completed. Elevation occurs out of process when needed.
gitRepos = repomanifest.repos
gitRepos = selectedinstance.repos
// gitRepos = ['chess-server-lib'];
// Repositiories that have symlinks that require elevated priviletes in windows to create symlinks
elevatedRunasRepos = repomanifest.elevated
elevatedRunasRepos = selectedinstance.elevated
// Repos that should excluded from merge for releases...
exludeMergeRepos = repomanifest.exludeMergeRepos
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
@@ -1816,14 +1814,6 @@ function elxrworker() {
else return __runcmd(processedArgs.label || processedArgs._[0] || 'h');
}

var getManifest = function () {
// Once choices are made we need to load config according to those choices.

// No trace of a previous run...
// Default Config...
return repomanifest = selectedinstance;
}

function acquireChoices(selectedinstance) {

var hasconfig = false;
@@ -1863,8 +1853,6 @@ We will run your choice at the next prompt.
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'
getManifest() // PB : TODO -- acquire the manifest directly from http url instead of clone before cloning the config. Since
// This is because the manifest at any server location can redirect to the preferred server..
}
else if (choice === 'h') {
processedArgs._[0] = 'h'
@@ -1942,25 +1930,26 @@ var cacheWriteInstanceConfig = function(chessinstances){
fs.writeFileSync(instanceroot + '/chessinstances.js', 'module.exports = ' + JSON.stringify(chessinstances, null, 2) + '', { 'flag': 'w' })
}

var acquireConfig = function (selected, chessinstances) {
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');
repomanifest = require(manifestpath)()
chessinstances = chessinstances || {};
chessinstances[selected.instanceName] = chessinstances[selected.instanceName] || {}
chessinstances[selected.instanceName][selected.node_env] = chessinstances[selected.instanceName][selected.node_env] || {}
chessinstances['current_run'] = { instanceName: selected.instanceName, node_env: selected.node_env }
selectedinstance = require(manifestpath)()
// Config from server always override merges into selection ecept for the current selection.
// PB : TODO -- utils.assign Array merges are non-distinct...
selectedinstance = utils.assign(chessinstances[selected.instanceName][selected.node_env], selected, repomanifest)
// chessinstances[selectedinstance.instanceName][selectedinstance.node_env] = selectedinstance;
cacheWriteInstanceConfig(chessinstances)
selectedinstance = chessinstances[selected.instanceName][selected.node_env]
// PB : TODO -- We should probably write the new server config also...
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)
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) => {
@@ -2328,20 +2317,45 @@ var chessinstances = { current_run : {} };
acquireElevationState().then(() => {
var skipprerequisites = false;
var clioverrides = { }
function initinstances(chessinstances, selected) {
chessinstances.current_run.instanceName = processedArgs._[1] = processedArgs._[1] || chessinstances.current_run.instanceName || selected.instanceName;
chessinstances.current_run.node_env = processedArgs.node_env = processedArgs.node_env || chessinstances.current_run.node_env || selected.node_env;
chessinstances[chessinstances.current_run.instanceName] = chessinstances[chessinstances.current_run.instanceName] || {}
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['current_run'] = chessinstances[instanceName][selected.node_env] ?
{ instanceName: instanceName, node_env: node_env } : chessinstances['current_run']
// chessinstances[chessinstances.current_run.instanceName] = chessinstances[chessinstances.current_run.instanceName] || {}

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(
selected
, chessinstances[chessinstances.current_run.instanceName][chessinstances.current_run.node_env]
, chessinstances[instanceName][node_env]
, clioverrides
// , __interactve_promts -- Cant just override. Also need selectedinstance to be ready...
);
repomanifest = selectedinstance

chessinstances[instanceName] = chessinstances[instanceName] || {}
chessinstances[instanceName][node_env] = chessinstances[instanceName][node_env] || {}
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 = utils.assign(selected, 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
}
function acquirelocalinstances(selected){
@@ -2359,14 +2373,14 @@ acquireElevationState().then(() => {
// Default cmd to run !
processedArgs._[0] === processedArgs._[0] || 'pull';
// selectedinstance.reposerver = repomanifest.reposervers[0] // PB : TODO -- Attempt first one that is available and online from all that are available...
// 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}
return acquireConfig(selectedinstance, chessinstances).catch((err) => {
return acquireConfig(selectedinstance).catch((err) => {
e = err;
console.error('Chosen cofiguraton failed or not found. Fix config and rerun or chose another.')
console.error(err)
@@ -2429,7 +2443,7 @@ acquireElevationState().then(() => {
}
try {
chessinstances = acquirelocalinstances(selectedinstance);
initinstances(chessinstances, selectedinstance)
initinstances(selectedinstance)
var instanceNameChoices = new Set(Object.keys( chessinstances) )
instanceNameChoices.delete('current_run')
@@ -2452,7 +2466,7 @@ acquireElevationState().then(() => {
catch (e) {
console.error(e) // Missing chessinstances is not an error...
initinstances(chessinstances, selectedinstance)
initinstances(selectedinstance)
var instanceNameChoices = new Set(Object.keys( chessinstances) )
instanceNameChoices.delete('current_run')
@@ -2477,7 +2491,7 @@ acquireElevationState().then(() => {
todo = todo.then(() => {
try {
chessinstances = acquirelocalinstances(selectedinstance)
initinstances(chessinstances, selectedinstance)
initinstances(selectedinstance)
}
catch (e) {
console.error(e)

Laddar…
Avbryt
Spara