| // PB : TODO -- If we are run from an elevated shell it never moves forward and simply exits. | // PB : TODO -- If we are run from an elevated shell it never moves forward and simply exits. | ||||
| // -- Currently workaround is to always run from a non-elevated shell. | // -- Currently workaround is to always run from a non-elevated shell. | ||||
| var __isElevated = null; | |||||
| var __isElevated = null; // We assume non-Elevated until someone evaluates and sets this variable. | |||||
| var isRunningElevated = ()=>{ | var isRunningElevated = ()=>{ | ||||
| if(__isElevated === null) { | if(__isElevated === null) { | ||||
| return nodeShellExec( "fsutil", ["dirty", "query", "C:"], { | return nodeShellExec( "fsutil", ["dirty", "query", "C:"], { | ||||
| var gitInstallDir = "C:\\Program Files\\Git\\bin\\sh.exe" | var gitInstallDir = "C:\\Program Files\\Git\\bin\\sh.exe" | ||||
| // var gitInstallDir = "G:\\Installed\\Git\\bin\\sh.exe" | // var gitInstallDir = "G:\\Installed\\Git\\bin\\sh.exe" | ||||
| // Relevant git repos | // Relevant git repos | ||||
| var gitRepos = [ | |||||
| 'ember-masonry-grid' | |||||
| , 'bbhverse' | |||||
| , 'clientverse' | |||||
| , 'serververse' | |||||
| , 'client' | |||||
| // , 'client/server' | |||||
| , 'elxr' | |||||
| , 'ember-searchable-select' | |||||
| , 'loopback-component-jsonapi' | |||||
| , 'loopback-jsonapi-model-serializer' | |||||
| , 'loopback-connector-mysql' | |||||
| , 'elixir-config-development' | |||||
| , 'elixir-config-test' | |||||
| , 'cihsr-config-development' | |||||
| , 'cihsr-data' | |||||
| , 'elixir-data' | |||||
| , 'loopback-connector-ds' | |||||
| , 'chess-server-lib' | |||||
| , 'setup' | |||||
| , 'elixir-client-todos' | |||||
| , 'elixir-client-unlinked' | |||||
| , 'elixir-client' | |||||
| , 'ember-service-worker' | |||||
| , 'ember-service-worker-asset-cache' | |||||
| , 'ember-service-worker-cache-fallback' | |||||
| , 'ember-service-worker-index' | |||||
| , 'ember-sw-client-route' | |||||
| , 'global-this' | |||||
| ] | |||||
| var brandName = 'elixir'; | |||||
| // Runas windowshta clobbers and removes the NODE_ENV !!! We therefore pass it in. | |||||
| var nodeenv = process.env.NODE_ENV || processedArgs.node_env || 'development' | |||||
| if(nodeenv.trim() === 'production') nodeenv = 'production' | |||||
| // var repomanifest = require('../'+brandName+'-config-'+ nodeenv +'/repo-manifest')() | |||||
| var manifestpath = '../'+brandName+'-config-'+nodeenv+'/repo-manifest'; | |||||
| // var manifestpath = '../'+brandName+'-config-'+'production'+'/repo-manifest'; | |||||
| console.dir(manifestpath) | |||||
| var repomanifest = require(manifestpath)() | |||||
| console.dir(repomanifest) | |||||
| var gitRepos = repomanifest.repos | |||||
| // Repositiories that have symlinks that required elevated priviletes in windows to create symlinks | // Repositiories that have symlinks that required elevated priviletes in windows to create symlinks | ||||
| // | // | ||||
| var elevatedRunasRepos = [ | |||||
| 'elixir-server' | |||||
| , 'cihsr-server' | |||||
| , 'chess-server' | |||||
| ] | |||||
| var exludeMergeRepos = { | |||||
| 'elixir-config-development' : true, 'elixir-config-test': true, 'elixir-config-production' : true | |||||
| , 'elixir-data' : true | |||||
| ,'cihsr-config-development' : true, 'cihsr-config-test': true, 'cihsr-config-production' : true | |||||
| , 'cihsr-data' : true | |||||
| } | |||||
| var elevatedRunasRepos = repomanifest.elevated | |||||
| var exludeMergeRepos = repomanifest.exludeMergeRepos | |||||
| var productionRepos = [ | |||||
| 'elixir-config-production' | |||||
| ] | |||||
| var productionIsAllowed = (process.env.NODE_ENV === 'production'); | |||||
| if(productionIsAllowed) gitRepos = gitRepos.concat(productionRepos) | |||||
| // var productionRepos = [ 'elixir-config-production' ] | |||||
| // var productionIsAllowed = (nodeenv === 'production'); | |||||
| // if(productionIsAllowed) gitRepos = gitRepos.concat(productionRepos) | |||||
| var env = Object.assign({}, process.env); // Shallow clone it. | var env = Object.assign({}, process.env); // Shallow clone it. | ||||
| var __runcmd = function(label){ | var __runcmd = function(label){ | ||||
| catch(e) { } //Ignore | catch(e) { } //Ignore | ||||
| // Find node path to send to hta. | // Find node path to send to hta. | ||||
| nodeShellExec('where', ['node']).then(r => { | |||||
| return nodeShellExec('where', ['node']).then(r => { | |||||
| console.log('result : ' + r) | console.log('result : ' + r) | ||||
| // throw 'rrrrrrrrrrrrrrrrr' | // throw 'rrrrrrrrrrrrrrrrr' | ||||
| // PB : TODO -- Convert all the cli args back to string. | // PB : TODO -- Convert all the cli args back to string. | ||||
| var namedArgs = []; | var namedArgs = []; | ||||
| Object.keys(processedArgs).forEach((v)=>{ v!='_' ? namedArgs.push('--'+v+'='+processedArgs[v]) : null; }) | Object.keys(processedArgs).forEach((v)=>{ v!='_' ? namedArgs.push('--'+v+'='+processedArgs[v]) : null; }) | ||||
| //console.log(' namedArgs : ' + namedArgs) | //console.log(' namedArgs : ' + namedArgs) | ||||
| process.env.NODE_ENV = process.env.NODE_ENV || 'development'; | |||||
| var env = Object.assign({}, process.env); // Shallow clone it. | |||||
| // console.dir(env) | |||||
| env.NODE_ENV = process.env.NODE_ENV || 'development'; | |||||
| var args = [__dirname + '/windowselevate.hta'].concat(processedArgs._).concat(namedArgs.join(' ')); args.push('--runas=self'); | var args = [__dirname + '/windowselevate.hta'].concat(processedArgs._).concat(namedArgs.join(' ')); args.push('--runas=self'); | ||||
| args.push('--nodepath='+r[r.length-1]) | args.push('--nodepath='+r[r.length-1]) | ||||
| nodeShellExec('MSHTA', [`"${args.join('" "')}"`] | |||||
| args.push('--node_env='+env.NODE_ENV) | |||||
| // args.push('--debug=true') // Enable to debug elevated.. | |||||
| return nodeShellExec('MSHTA', [`"${args.join('" "')}"`] | |||||
| , { | , { | ||||
| inherit : true | inherit : true | ||||
| , shell: true | , shell: true | ||||
| , env: process.env | |||||
| , env: env | |||||
| , runas : 'self' | , runas : 'self' | ||||
| , title : `runas` | , title : `runas` | ||||
| } | } | ||||
| try { | try { | ||||
| var runaslog = JSON.parse('[ { "success" : true, "result" : "runas Log" }' + fs.readFileSync('run.log', { flags : 'a+'}) + ']'); | var runaslog = JSON.parse('[ { "success" : true, "result" : "runas Log" }' + fs.readFileSync('run.log', { flags : 'a+'}) + ']'); | ||||
| runaslog.forEach((logEntry)=>{ | runaslog.forEach((logEntry)=>{ | ||||
| statuslog.statuslog(logEntry.success ? null : (logEntry.messages || []).join(' ')) | |||||
| logEntry.success ? (console.log(['success :' + logEntry.result]), console.log((logEntry.messages || []).join(' '))) : (console.error(['error :' + logEntry.result]), console.error((logEntry.messages || []).join(' '))) | logEntry.success ? (console.log(['success :' + logEntry.result]), console.log((logEntry.messages || []).join(' '))) : (console.error(['error :' + logEntry.result]), console.error((logEntry.messages || []).join(' '))) | ||||
| }) | }) | ||||
| } | } | ||||
| return pullCmd | return pullCmd | ||||
| } | } | ||||
| var errors = []; | |||||
| var performPull = (repo) => { | var performPull = (repo) => { | ||||
| if(existsSync(repo)) { | if(existsSync(repo)) { | ||||
| console.log('pulling ' + repo) | console.log('pulling ' + repo) | ||||
| return nodeShellExec.apply(null, getPullCmd(repo)).then((srepo)=>{ | |||||
| statuslog.statuslog(null, srepo)}).catch((e)=>{ statuslog.statuslog(e, srepo); console.error(e) }) | |||||
| return nodeShellExec.apply(null, getPullCmd(repo)).then(()=>{ | |||||
| if(__isElevated) { | |||||
| fs.writeFileSync('run.log', ', ' + JSON.stringify({ repo, success:true}), {'flag':'a+'} ) | |||||
| } | |||||
| else statuslog.statuslog(null, repo) | |||||
| }) | |||||
| .catch((e)=>{ | |||||
| e.repo = repo; | |||||
| if(__isElevated) { | |||||
| fs.writeFileSync('run.log', ', ' + JSON.stringify(e), {'flag':'a+'} ) | |||||
| } | |||||
| else statuslog.statuslog(e); console.error(e) | |||||
| }) | |||||
| } | } | ||||
| else { | else { | ||||
| // PB : TODO -- detect if a clonable repo exists in currentGitAuthUser | // PB : TODO -- detect if a clonable repo exists in currentGitAuthUser | ||||
| env: process.env | env: process.env | ||||
| , runas : processedArgs.runas | , runas : processedArgs.runas | ||||
| }).catch((e)=>{ | }).catch((e)=>{ | ||||
| errors.push({ repo , e}) | |||||
| console.error(e) | |||||
| throw e; | |||||
| }).then(()=>{ | }).then(()=>{ | ||||
| return nodeShellExec('git', ['config', '--replace-all' , 'core.symlinks', true], | return nodeShellExec('git', ['config', '--replace-all' , 'core.symlinks', true], | ||||
| , runas : processedArgs.runas | , runas : processedArgs.runas | ||||
| , title : `git core.symlinks --replace-all true for ${defaultRepoServer + `/${defaultRepoOwner}/` + repo + '.git'}` | , title : `git core.symlinks --replace-all true for ${defaultRepoServer + `/${defaultRepoOwner}/` + repo + '.git'}` | ||||
| }) | }) | ||||
| .then(()=>{ | |||||
| if(__isElevated) { | |||||
| fs.writeFileSync('run.log', ', ' + JSON.stringify({ repo, success:true}), {'flag':'a+'} ) | |||||
| } | |||||
| else statuslog.statuslog(null, repo) | |||||
| }) | |||||
| .catch((e)=>{ | |||||
| e.repo = repo; | |||||
| if(__isElevated) { | |||||
| fs.writeFileSync('run.log', ', ' + JSON.stringify(e), {'flag':'a+'} ) | |||||
| } | |||||
| else statuslog.statuslog(e); | |||||
| }) | |||||
| }) | |||||
| .catch(e=>{ | |||||
| e.repo = repo; | |||||
| if(__isElevated) { | |||||
| fs.writeFileSync('run.log', ', ' + JSON.stringify(e), {'flag':'a+'} ) | |||||
| } | |||||
| else statuslog.statuslog(e); | |||||
| }) | }) | ||||
| } | } | ||||
| } | } | ||||
| if(!processedArgs.runas) { | |||||
| var pendingpulls = []; | |||||
| gitRepos.forEach( (r)=>{ | |||||
| pendingpulls.push(performPull(r)) | |||||
| } ) | |||||
| Promise.all(pendingpulls).then(results =>{ | |||||
| // console.log(statuslog.log.SUCCESS) | |||||
| console.log('Total : ' + (statuslog.log.SKIPPED.length + statuslog.log.SUCCESS.length + statuslog.log.FAILURE.length)) | |||||
| console.log('Pass : ' + statuslog.log.SUCCESS.length ) | |||||
| console.log('Fail : ' + statuslog.log.FAILURE.length) | |||||
| console.log('Skipped : ' + statuslog.log.SKIPPED.length) | |||||
| }) | |||||
| } | |||||
| return isRunningElevated().then( | return isRunningElevated().then( | ||||
| (isElevated) => { | (isElevated) => { | ||||
| if(isElevated) { | if(isElevated) { | ||||
| } | } | ||||
| ).catch( | ).catch( | ||||
| () => { | () => { | ||||
| op['runas']() | |||||
| op['runas']().then(()=>{ | |||||
| }) | |||||
| .catch(()=>{}) | |||||
| .finally(()=>{ | |||||
| if(!processedArgs.runas) { | |||||
| var pendingpulls = []; | |||||
| gitRepos.forEach( (r)=>{ pendingpulls.push(performPull(r)) } ) | |||||
| Promise.all(pendingpulls).then(results =>{ | |||||
| }).finally(()=>{ | |||||
| console.log('Total : ' + (statuslog.log.SKIPPED.length + statuslog.log.SUCCESS.length + statuslog.log.FAILURE.length)) | |||||
| console.log('Pass : ' + statuslog.log.SUCCESS.length ) | |||||
| console.log('Fail : ' + statuslog.log.FAILURE.length) | |||||
| console.log('Skipped : ' + statuslog.log.SKIPPED.length) | |||||
| console.log('FAILURES') | |||||
| console.log([JSON.stringify(statuslog.log.FAILURE)]) | |||||
| // statuslog.log.FAILURE.forEach(f => { | |||||
| // console.error(f); | |||||
| // }) | |||||
| }) | |||||
| } | |||||
| }) | |||||
| } | } | ||||
| ) | ) | ||||
| } | } | ||||
| child.stderr.setEncoding('utf8'); | child.stderr.setEncoding('utf8'); | ||||
| child.stdout.on('data', (chunk) => { chunk.trim() === '' ? null : messages.push(chunk); /* console.log('d: ' + chunk) */ }); | child.stdout.on('data', (chunk) => { chunk.trim() === '' ? null : messages.push(chunk); /* console.log('d: ' + 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) */ } ); | ||||
| child.stderr.on('data', (chunk) => { messages.push(chunk); | |||||
| child.stderr.on('data', (chunk) => { | |||||
| if(messages.join('').indexOf('fatal: not a git repository') > -1) opts.haserrors = true; | |||||
| messages.push(chunk); | |||||
| // console.error('stderr e: ' + chunk) | // console.error('stderr e: ' + chunk) | ||||
| }); | }); | ||||
| } | } | ||||
| child.on('close', (code) => { | child.on('close', (code) => { | ||||
| if(+code !== 0) success = false; | |||||
| if(+code !== 0 || opts.haserrors) success = false; | |||||
| if(opts.stdio !== 'ignore') { | if(opts.stdio !== 'ignore') { | ||||
| var logEntry = { result: `${opts.title} exited with code ${code}`, messages } | |||||
| logEntry.success = success; | |||||
| if(opts.runas){ | if(opts.runas){ | ||||
| var logEntry = { result: `${opts.title} exited with code ${code}`, messages : messages } | |||||
| success ? logEntry.success = true : null; | |||||
| // success ? logEntry.success = true : null; | |||||
| fs.writeFileSync('run.log', ', ' + JSON.stringify(logEntry), {'flag':'a+'} ) | fs.writeFileSync('run.log', ', ' + JSON.stringify(logEntry), {'flag':'a+'} ) | ||||
| } | } | ||||
| else { | else { | ||||
| success ? console.log(['success : ' + ` ${opts.title} exited with code ${code}`]) : console.error([`error : ${opts.title} exited with code ${code}`]) | |||||
| // console.log( messages.join('') ) | // console.log( messages.join('') ) | ||||
| process.stdout.write( messages.join('') ) | process.stdout.write( messages.join('') ) | ||||
| } | } | ||||
| } | } | ||||
| if(code !== 0) return reject(code) | |||||
| resolve(messages) | |||||
| if(code !== 0 || opts.haserrors) return reject(logEntry) | |||||
| resolve(logEntry) | |||||
| }); | }); | ||||
| } | } | ||||
| else { | else { |