Browse Source

Refactored for Windows Script Host JScript

master
pb 3 years ago
parent
commit
4443ee58a8
1 changed files with 390 additions and 0 deletions
  1. 390
    0
      i.win.js

+ 390
- 0
i.win.js View File

@@ -0,0 +1,390 @@

var BUILD_VERSION = '[VI]Version: {version} - built on {date}[/VI]';
var runtimestamp = (new Date()).getTime();
function getVersion() { return BUILD_VERSION; }
WScript.echo(getVersion())

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])
}

var console = { log : function(m) {WScript.Echo(m)}, error : function(m) {WScript.Echo(m)} }
var Promise = function(fn){

// Detect error
var state = Promise.PENDING;
var chain = [];
chain.forEach = forEach;

function reject(e){
if(state !== Promise.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;
try {
for(var i = __i; i < chain.length; i++, __i = i) if(chain[i].isCatch) { chain[i](__e); break; }
__e = null;
}
catch(e){ __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); } }
catch(e){
do {
try {
for(var i = __i; i < chain.length; i++, __i = i) if(chain[i].isCatch) { chain[i](__e); break; }
__e = null;
}
catch(e){ __e = e}
} while(__e)
}
} while ( __i < chain.length )
state = Promise.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 )
p.result = result;
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;
}
catch(e){ __e = e}
} while(__e)
}
} while ( __i < chain.length )
state = Promise.FULFILLED;
};
var p = {
then : function(thenfn){
thenfn.isThen = true
chain.push(thenfn)
return p;
}
, pcatch : function(catchfn) {
catchfn.isCatch = true
chain.push(catchfn)
return p;
}
, start : function(){
try { fn(resolve, reject) }
catch(e){ reject(e) }
}
}
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)
});
}

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

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


function waitForResult(p){
while(p.state === Promise.PENDING) WScript.Sleep(500)
return true
}

var stampedFilePfx = function(date) {
return date.getFullYear() +
('0' + (date.getMonth() + 1)).slice(-2) +
('0' + date.getDate()).slice(-2) +
('0' + date.getHours()).slice(-2) +
('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 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)) {
return filePath;
}
ensureDirectoryExistence(dirname);
fs.mkdirSync(dirname);
return filePath;
}

var getTaskCheckExists = function(command, options) {
options = options || {}
return function() {
var p = nodeShellExec.apply(null, ['where', [command]])
if (options.ignorefailures) {
return p.then(function(v) {
// WScript.Echo('firstThen ' + v);
return v }).pcatch( function(e) { // Ignore. Not a major error.
return false;
})
}
else return p.then(function() {
// WScript.Echo('firstThen ddd');
return v });
}
}

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 \
::**************************************************************************";
fs.writeFileSync('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);
})
}
}
));
p.start()
});
return Promise.all(downloadtasks).then(function(){ return any(installtasks) })
}


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'
, installcmd: ['cmd', ['/c', 'start',
'/WAIT', downloadsdir + '/' + 'Git-2.31.0-64-bit.exe'
, '/VERYSILENT'
// , '/MERGETASKS=!runcode' // This is required only for vscode...
]]
, preinstallsteps: function() {
var prompt = cli.prompter;
var steps = [
function(){
if (!existsSync(downloadsdir + '/' + this.installer)) {
return nodeShellExec(selectedinstance.root + '/.elxr/run-${runtimestamp}/download.bat', [this.url, downloadsdir + '/' + this.installer])
}
else return Promise.resolve(true)
}
]
var prompts = [
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)])
}
, installsteps: function () {
return any([this.installcmd].map(callsheltask))
}
, postinstallsteps: function(){
var prompt = cli.prompter;
var gitUser = 'guest';
var gitEmail = 'guest@bbh.org.in';
var prompts = [];
prompts.push(
function(){
var choices = { 0 : 'guest', 1 : 'chessdemo' }
return cli.prompt(choices, 'git user name').then(function(gituser) { gitUser = gituser})
}
)

prompts.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 any(prompts).then(function(){
var steps = [
['git', ['config', '--global', '--add', 'user.name', gitUser]]
, ['git', ['config', '--global', '--add', 'user.email', gitEmail]]
]
return any(steps.map(callsheltask)).then(function(){

})
});
}
, install: function () {
return any([ /*this.preinstallsteps,*/ this.installsteps.bind(this), this.postinstallsteps.bind(this)])
}
, verifyAndInstall : function(){
var self = this;
return self.exists().then( function(exits) {
if(exists) return self.getUser(null, self.postinstallsteps.bind(self))
else return self.install();
})
}
, 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 true;
}
else return false
})
}
, getUser : function(repo, onNoResult){
onNoResult = onNoResult || function(){return false}
var globalOrLocal = '--global';
if(!repo) globalOrLocal = '--global';
else globalOrLocal = '--local'

return any([['git', ['config', globalOrLocal, '--get-all', 'user.name']]].map(callsheltask)).then(function(result){
// not yet configured.
if(!result.success) return onNoResult()
else {
var users = result.messages[0].trim().split('\n');
if(users.length === 0 ||
users.length === 1 && users[0] === 'guest') {
return onNoResult()
}
else return users[0]; // PB : TODO == We should probably prompt with all the users available for selection !
}
})
.pcatch(function(e){
console.log(e)
return onNoResult()
})
}
}
,
{
shellcmd: 'node',
url: 'https://nodejs.org/dist/v14.16.0/node-v14.16.0-x64.msi'
, installer: 'node-v14.16.0-x64.msi'
, installcmd: ['MSIEXEC.exe', ['/i'
, downloadsdir + '/' + 'node-v14.16.0-x64.msi'
, 'ACCEPT=YES', '/passive']]
, install : function() { return any([this.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
}
})
}
, preinstallsteps : function(){
return true;
}
}
]

prerequisites.forEach = forEach;

verifyAndInstallPrerequisites()

Loading…
Cancel
Save