You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

i.win.js 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. var BUILD_VERSION = '[VI]Version: {version} - built on {date}[/VI]';
  2. var runtimestamp = (new Date()).getTime();
  3. function getVersion() { return BUILD_VERSION; }
  4. WScript.echo(getVersion())
  5. var fso = new ActiveXObject('Scripting.FileSystemObject');
  6. var shell = new ActiveXObject('shell.application');
  7. function forEach(eachFn){
  8. for(var i=0; i<this.length; i++) eachFn(this[i])
  9. }
  10. var console = { log : function(m) {WScript.Echo(m)}, error : function(m) {WScript.Echo(m)} }
  11. var Promise = function(fn){
  12. // Detect error
  13. var state = Promise.PENDING;
  14. var chain = [];
  15. chain.forEach = forEach;
  16. function reject(e){
  17. if(state !== Promise.PENDING) { console.error ('Error : Promise Rejection can only be called once')}
  18. var __i = 0;
  19. var __e = e;
  20. do {
  21. for(var i = __i; i < chain.length; i++, __i = i) if(chain[i].isCatch) break;
  22. try {
  23. for(var i = __i; i < chain.length; i++, __i = i) if(chain[i].isCatch) { chain[i](__e); break; }
  24. __e = null;
  25. }
  26. catch(e){ __e = e}
  27. } while(__e)
  28. do {
  29. try { for(var i = __i; i < chain.length; i++, __i = i) if(!chain[i].isCatch) { p.result = chain[i](p.result); } }
  30. catch(e){
  31. do {
  32. try {
  33. for(var i = __i; i < chain.length; i++, __i = i) if(chain[i].isCatch) { chain[i](__e); break; }
  34. __e = null;
  35. }
  36. catch(e){ __e = e}
  37. } while(__e)
  38. }
  39. } while ( __i < chain.length )
  40. state = Promise.REJECTED;
  41. }
  42. function resolve(result){
  43. if(state !== Promise.PENDING) { console.error ('Error : Promise Rejection can only be called once')}
  44. // console.log('main promise resolve... ' + chain.length )
  45. p.result = result;
  46. var __i = 0;
  47. do {
  48. try { for(var i = __i; i < chain.length; i++, __i = i) if(!chain[i].isCatch) { p.result = chain[i](p.result); } }
  49. catch(e){
  50. var __e = e;
  51. do {
  52. try {
  53. for(var i = __i; i < chain.length; i++, __i = i) if(chain[i].isCatch) { chain[i](__e); break; }
  54. __e = null;
  55. }
  56. catch(e){ __e = e}
  57. } while(__e)
  58. }
  59. } while ( __i < chain.length )
  60. state = Promise.FULFILLED;
  61. };
  62. var p = {
  63. then : function(thenfn){
  64. thenfn.isThen = true
  65. chain.push(thenfn)
  66. return p;
  67. }
  68. , pcatch : function(catchfn) {
  69. catchfn.isCatch = true
  70. chain.push(catchfn)
  71. return p;
  72. }
  73. , start : function(){
  74. try { fn(resolve, reject) }
  75. catch(e){ reject(e) }
  76. }
  77. }
  78. return p
  79. }
  80. Promise.all = function(arr){
  81. arr.forEach = forEach;
  82. var results = [];
  83. return new Promise(function(resolve, reject){
  84. arr.forEach(function(p){ results.push(waitForResult(p))} )
  85. resolve(results)
  86. });
  87. }
  88. any = function(arr){
  89. arr.forEach = forEach;
  90. var results = [];
  91. return new Promise(function(resolve, reject){
  92. arr.forEach(function(p){ results.push(waitForResult(p))} )
  93. resolve(results)
  94. });
  95. }
  96. Promise.PENDING = 1
  97. Promise.FULFILLED = 2
  98. Promise.REJECTED = 3
  99. function waitForResult(p){
  100. while(p.state === Promise.PENDING) WScript.Sleep(500)
  101. return true
  102. }
  103. var stampedFilePfx = function(date) {
  104. return date.getFullYear() +
  105. ('0' + (date.getMonth() + 1)).slice(-2) +
  106. ('0' + date.getDate()).slice(-2) +
  107. ('0' + date.getHours()).slice(-2) +
  108. ('0' + date.getMinutes()).slice(-2) +
  109. ('0' + date.getSeconds()).slice(-2);
  110. }
  111. function nodeShellExec(cmd, cargs){
  112. var p = new Promise(function(resolve, reject){
  113. var runFile = selectedinstance.root + '\\' + stampedFilePfx(new Date()) + cmd + cargs + "out.txt";
  114. // console.log(runFile)
  115. shell.ShellExecute('cmd', '/c ' + cmd + ' ' + cargs + " > " + runFile , "", "", 1);
  116. // var WshFinished = 1
  117. // var WshFailed = 2
  118. // var strOutput = 'Did not work'
  119. // switch(shell.Status){
  120. // case WshFinished :
  121. // strOutput = oShell.StdOut.ReadAll;
  122. // break;
  123. // case WshFailed :
  124. // strOutput = oShell.StdErr.ReadAll;
  125. // break;
  126. // }
  127. // WScript.Echo(strOutput)
  128. while(!fso.FileExists(runFile)) {
  129. WScript.Sleep(500)
  130. }
  131. var objFileToRead = fso.OpenTextFile(runFile,1)
  132. var strFileText = objFileToRead.ReadAll()
  133. objFileToRead.Close()
  134. fso.DeleteFile(runFile)
  135. resolve(strFileText)
  136. })
  137. return p;
  138. }
  139. // Detect or specify install directory.
  140. var selectedinstance = {
  141. root : fso.GetAbsolutePathName(".")
  142. }
  143. var downloadsdir = selectedinstance.root + '/Downloads';
  144. var fs = {
  145. writeFileSync : function(filepath, text) {
  146. WScript.echo(filepath)
  147. var fh = fso.CreateTextFile(filepath, true);
  148. fh.WriteLine(text);
  149. fh.Close();
  150. },
  151. existsSync : function(path){
  152. // fso.FileExists(path)
  153. return fso.FolderExists(path)
  154. }
  155. , mkdirSync : function(path) {
  156. fso.CreateFolder(path)
  157. }
  158. }
  159. var path = {
  160. dirname : function(filepath) {
  161. var normalized = filepath.replace(/\//g,'\\');
  162. var li = normalized.lastIndexOf("\\")
  163. if( li > -1) {
  164. return normalized.substring(0, li)
  165. }
  166. }
  167. }
  168. function ensureDirectoryExistence(filePath) {
  169. var dirname = path.dirname(filePath);
  170. if (fs.existsSync(dirname)) {
  171. return filePath;
  172. }
  173. ensureDirectoryExistence(dirname);
  174. fs.mkdirSync(dirname);
  175. return filePath;
  176. }
  177. var getTaskCheckExists = function(command, options) {
  178. options = options || {}
  179. return function() {
  180. var p = nodeShellExec.apply(null, ['where', [command]])
  181. if (options.ignorefailures) {
  182. return p.then(function(v) {
  183. // WScript.Echo('firstThen ' + v);
  184. return v }).pcatch( function(e) { // Ignore. Not a major error.
  185. return false;
  186. })
  187. }
  188. else return p.then(function() {
  189. // WScript.Echo('firstThen ddd');
  190. return v });
  191. }
  192. }
  193. function verifyAndInstallPrerequisites() {
  194. fs.writeFileSync(ensureDirectoryExistence(downloadsdir + '/readme.txt'), getVersion() + ' Your local downloads for this instance');
  195. var downloadbatch =
  196. "::************************************************************************** \
  197. :Download_ <url> <File> \
  198. Powershell.exe ^ \
  199. $AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'; ^ \
  200. [System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols; ^ \
  201. (New-Object System.Net.WebClient).DownloadFile('%1','%2') \
  202. exit /b \
  203. ::**************************************************************************";
  204. fs.writeFileSync('download.bat', downloadbatch);
  205. var downloadtasks = [];
  206. var installtasks = [];
  207. prerequisites.forEach(function(preq) {
  208. var p = null;
  209. downloadtasks.push(
  210. p = preq.exists().then(function(exists) {
  211. if (exists) console.log( preq.shellcmd + ' exists');
  212. else {
  213. console.log(preq.shellcmd + ' is not installed');
  214. return preq.preinstallsteps().then(function(){
  215. installtasks.push(task.install);
  216. })
  217. }
  218. }
  219. ));
  220. p.start()
  221. });
  222. return Promise.all(downloadtasks).then(function(){ return any(installtasks) })
  223. }
  224. var prerequisites = [
  225. {
  226. shellcmd: 'git',
  227. url: 'https://github.com/git-for-windows/git/releases/download/v2.31.0.windows.1/Git-2.31.0-64-bit.exe'
  228. , installer: 'Git-2.31.0-64-bit.exe'
  229. , installcmd: ['cmd', ['/c', 'start',
  230. '/WAIT', downloadsdir + '/' + 'Git-2.31.0-64-bit.exe'
  231. , '/VERYSILENT'
  232. // , '/MERGETASKS=!runcode' // This is required only for vscode...
  233. ]]
  234. , preinstallsteps: function() {
  235. var prompt = cli.prompter;
  236. var steps = [
  237. function(){
  238. if (!existsSync(downloadsdir + '/' + this.installer)) {
  239. return nodeShellExec(selectedinstance.root + '/.elxr/run-${runtimestamp}/download.bat', [this.url, downloadsdir + '/' + this.installer])
  240. }
  241. else return Promise.resolve(true)
  242. }
  243. ]
  244. var prompts = [
  245. function() {prompt.ask('git user name : ( <= ' + gitUser + ' )').then( function(user){ gitUser = user; })}
  246. , function() { prompt.ask('git email : ( <= ' + gitEmail + ' )').then(function(email) { gitEmail = email; })}
  247. ]
  248. return any([any(steps), any(prompts)])
  249. }
  250. , installsteps: function () {
  251. return any([this.installcmd].map(callsheltask))
  252. }
  253. , postinstallsteps: function(){
  254. var prompt = cli.prompter;
  255. var gitUser = 'guest';
  256. var gitEmail = 'guest@bbh.org.in';
  257. var prompts = [];
  258. prompts.push(
  259. function(){
  260. var choices = { 0 : 'guest', 1 : 'chessdemo' }
  261. return cli.prompt(choices, 'git user name').then(function(gituser) { gitUser = gituser})
  262. }
  263. )
  264. prompts.push(
  265. function(){
  266. var choices = { 0 : 'guest@bbh.org.in', 1 : 'chessdemo@bbh.org.in' }
  267. return cli.prompt(choices, 'git user email').then(function(gitemail) { gitEmail = gitemail})
  268. }
  269. )
  270. return any(prompts).then(function(){
  271. var steps = [
  272. ['git', ['config', '--global', '--add', 'user.name', gitUser]]
  273. , ['git', ['config', '--global', '--add', 'user.email', gitEmail]]
  274. ]
  275. return any(steps.map(callsheltask)).then(function(){
  276. })
  277. });
  278. }
  279. , install: function () {
  280. return any([ /*this.preinstallsteps,*/ this.installsteps.bind(this), this.postinstallsteps.bind(this)])
  281. }
  282. , verifyAndInstall : function(){
  283. var self = this;
  284. return self.exists().then( function(exits) {
  285. if(exists) return self.getUser(null, self.postinstallsteps.bind(self))
  286. else return self.install();
  287. })
  288. }
  289. , exists : function(next){
  290. var self = this;
  291. return getTaskCheckExists(this.shellcmd, { ignorefailures: true })().then(function(exists) {
  292. if(exists && exists.indexOf(self.shellcmd) > -1 ) {
  293. // console.log(exists + ' git exists')
  294. return true;
  295. }
  296. else return false
  297. })
  298. }
  299. , getUser : function(repo, onNoResult){
  300. onNoResult = onNoResult || function(){return false}
  301. var globalOrLocal = '--global';
  302. if(!repo) globalOrLocal = '--global';
  303. else globalOrLocal = '--local'
  304. return any([['git', ['config', globalOrLocal, '--get-all', 'user.name']]].map(callsheltask)).then(function(result){
  305. // not yet configured.
  306. if(!result.success) return onNoResult()
  307. else {
  308. var users = result.messages[0].trim().split('\n');
  309. if(users.length === 0 ||
  310. users.length === 1 && users[0] === 'guest') {
  311. return onNoResult()
  312. }
  313. else return users[0]; // PB : TODO == We should probably prompt with all the users available for selection !
  314. }
  315. })
  316. .pcatch(function(e){
  317. console.log(e)
  318. return onNoResult()
  319. })
  320. }
  321. }
  322. ,
  323. {
  324. shellcmd: 'node',
  325. url: 'https://nodejs.org/dist/v14.16.0/node-v14.16.0-x64.msi'
  326. , installer: 'node-v14.16.0-x64.msi'
  327. , installcmd: ['MSIEXEC.exe', ['/i'
  328. , downloadsdir + '/' + 'node-v14.16.0-x64.msi'
  329. , 'ACCEPT=YES', '/passive']]
  330. , install : function() { return any([this.installcmd].map(callsheltask)) }
  331. , exists : function(next){
  332. var self = this;
  333. return getTaskCheckExists(this.shellcmd, { ignorefailures: true })().then(function(exists) {
  334. if(exists && exists.indexOf(self.shellcmd) > -1 ) {
  335. // console.log(self.shellcmd + ' ' + exists + ' node exists')
  336. return true
  337. }
  338. else {
  339. // console.log(self.shellcmd + ' ' + exists + ' node doesnt exist')
  340. return false
  341. }
  342. })
  343. }
  344. , preinstallsteps : function(){
  345. return true;
  346. }
  347. }
  348. ]
  349. prerequisites.forEach = forEach;
  350. verifyAndInstallPrerequisites()