|
|
@@ -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() |