|  |  | @@ -1,7 +1,63 @@ | 
		
	
		
			
			|  |  |  | var statuslog = require('./result') | 
		
	
		
			
			|  |  |  | var path = require('path'); | 
		
	
		
			
			|  |  |  | var path = require('path'); | 
		
	
		
			
			|  |  |  | var utils = require('bbhverse'); | 
		
	
		
			
			|  |  |  | var any = utils.any; | 
		
	
		
			
			|  |  |  | var Tasq = utils.Tasq | 
		
	
		
			
			|  |  |  | var statuslog = utils.Traq | 
		
	
		
			
			|  |  |  | Tasq.addlistener(statuslog.statuslog) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 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); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var p = new Promise(function(resolve, reject){ | 
		
	
		
			
			|  |  |  | if(!opts.detached) { | 
		
	
		
			
			|  |  |  | var messages = []; // PB : TODO -- Explore stream for Task level  aggregation to prevent interleaved messages from multiple tasks... | 
		
	
		
			
			|  |  |  | var success = true; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if(opts.stdio !== 'ignore') { | 
		
	
		
			
			|  |  |  | child.stdout.setEncoding('utf8'); | 
		
	
		
			
			|  |  |  | child.stderr.setEncoding('utf8'); | 
		
	
		
			
			|  |  |  | 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.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) | 
		
	
		
			
			|  |  |  | }); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | child.on('close', (code) => { | 
		
	
		
			
			|  |  |  | if(+code !== 0 || opts.haserrors) success = false; | 
		
	
		
			
			|  |  |  | if(opts.stdio !== 'ignore') { | 
		
	
		
			
			|  |  |  | var logEntry = { result: `${opts.title} exited with code ${code}`, messages } | 
		
	
		
			
			|  |  |  | logEntry.success = success; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(opts.runas){ | 
		
	
		
			
			|  |  |  | // success ? logEntry.success = true : null; | 
		
	
		
			
			|  |  |  | fs.writeFileSync('run.log', ', ' + JSON.stringify(logEntry), {'flag':'a+'} ) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | // console.log( messages.join('') ) | 
		
	
		
			
			|  |  |  | process.stdout.write( messages.join('') ) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | if(code !== 0 || opts.haserrors) return reject(logEntry) | 
		
	
		
			
			|  |  |  | resolve(logEntry) | 
		
	
		
			
			|  |  |  | }); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | child.unref() | 
		
	
		
			
			|  |  |  | resolve(true); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | }); | 
		
	
		
			
			|  |  |  | p.process = child; | 
		
	
		
			
			|  |  |  | return p; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // 'use strict'; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // PB : TODO -- make sure folder context is proper coz we can now run elxr from anywhere. | 
		
	
	
		
			
			|  |  | @@ -92,7 +148,68 @@ var brandName = 'elixir'; | 
		
	
		
			
			|  |  |  | 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 exludeMergeRepos = []; | 
		
	
		
			
			|  |  |  | var useGitPull = processedArgs.useGitPull || false; | 
		
	
		
			
			|  |  |  | var getPullCmd = (repo)=>{ | 
		
	
		
			
			|  |  |  | // console.log(useGitPull) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var pullCmd = [ gitInstallDir | 
		
	
		
			
			|  |  |  | , ['-c', 'for i in `git remote`; do git pull $i master; done;'] | 
		
	
		
			
			|  |  |  | , { cwd : repo, title : 'pull all origins for ' + repo }] | 
		
	
		
			
			|  |  |  | // var pullCmd = ['pullall', [], { cwd : repo }] | 
		
	
		
			
			|  |  |  | if(useGitPull) pullCmd = ['git', ['pull'], { | 
		
	
		
			
			|  |  |  | inherit : true, shell: true, | 
		
	
		
			
			|  |  |  | cwd : repo | 
		
	
		
			
			|  |  |  | // , env: process.env | 
		
	
		
			
			|  |  |  | , runas : processedArgs.runas | 
		
	
		
			
			|  |  |  | , title : `git pull ${repo}` | 
		
	
		
			
			|  |  |  | }] | 
		
	
		
			
			|  |  |  | return pullCmd | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var performPull = (repo) => { | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(exludeMergeRepos[repo]) return Promise.resolve({ 'skipped' : true }) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(existsSync(repo)) { | 
		
	
		
			
			|  |  |  | console.log('pulling ' + repo) | 
		
	
		
			
			|  |  |  | return nodeShellExec.apply(null, getPullCmd(repo)).catch((e)=>{ console.error(e) }) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | console.log('cloning ' + repo) | 
		
	
		
			
			|  |  |  | // PB : TODO -- detect if a clonable repo exists in currentGitAuthUser | 
		
	
		
			
			|  |  |  | return nodeShellExec('git', ['clone', '-c', 'core.symlinks=true', defaultRepoServer + `/${defaultRepoOwner}/` + repo + '.git'], | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | inherit : true, shell: true, | 
		
	
		
			
			|  |  |  | env: process.env | 
		
	
		
			
			|  |  |  | , runas : processedArgs.runas | 
		
	
		
			
			|  |  |  | }).catch((e)=>{ console.error(e) }).then(()=>{ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return nodeShellExec('git', ['config', '--replace-all' , 'core.symlinks', true], | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | inherit : true, shell: true, | 
		
	
		
			
			|  |  |  | env: process.env | 
		
	
		
			
			|  |  |  | , cwd : repo | 
		
	
		
			
			|  |  |  | , runas : processedArgs.runas | 
		
	
		
			
			|  |  |  | , title : `git core.symlinks --replace-all true for ${defaultRepoServer + `/${defaultRepoOwner}/` + repo + '.git'}` | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var configrepo = brandName+'-config-'+nodeenv | 
		
	
		
			
			|  |  |  | var configpath = '../' + configrepo; | 
		
	
		
			
			|  |  |  | var configPromise = null | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(!existsSync(configpath)){ | 
		
	
		
			
			|  |  |  | configPromise = performPull(configrepo) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else configPromise = Promise.resolve(true) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | configPromise.then(()=>{ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var manifestpath = '../'+brandName+'-config-'+nodeenv+'/repo-manifest'; | 
		
	
		
			
			|  |  |  | // var manifestpath = '../'+brandName+'-config-'+'production'+'/repo-manifest'; | 
		
	
		
			
			|  |  |  | console.dir(manifestpath) | 
		
	
		
			
			|  |  |  | var repomanifest = require(manifestpath)() | 
		
	
	
		
			
			|  |  | @@ -104,7 +221,7 @@ var gitRepos = repomanifest.repos | 
		
	
		
			
			|  |  |  | // | 
		
	
		
			
			|  |  |  | var elevatedRunasRepos = repomanifest.elevated | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var exludeMergeRepos = repomanifest.exludeMergeRepos | 
		
	
		
			
			|  |  |  | exludeMergeRepos = repomanifest.exludeMergeRepos | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // var productionRepos = [ 'elixir-config-production' ] | 
		
	
		
			
			|  |  |  | // var productionIsAllowed = (nodeenv === 'production'); | 
		
	
	
		
			
			|  |  | @@ -568,55 +685,6 @@ var __runcmd = function(label){ | 
		
	
		
			
			|  |  |  | //   env: env | 
		
	
		
			
			|  |  |  | // }) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var useGitPull = processedArgs.useGitPull || false; | 
		
	
		
			
			|  |  |  | var getPullCmd = (repo)=>{ | 
		
	
		
			
			|  |  |  | // console.log(useGitPull) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var pullCmd = [ gitInstallDir | 
		
	
		
			
			|  |  |  | , ['-c', 'for i in `git remote`; do git pull $i master; done;'] | 
		
	
		
			
			|  |  |  | , { cwd : repo, title : 'pull all origins for ' + repo }] | 
		
	
		
			
			|  |  |  | // var pullCmd = ['pullall', [], { cwd : repo }] | 
		
	
		
			
			|  |  |  | if(useGitPull) pullCmd = ['git', ['pull'], { | 
		
	
		
			
			|  |  |  | inherit : true, shell: true, | 
		
	
		
			
			|  |  |  | cwd : repo | 
		
	
		
			
			|  |  |  | // , env: process.env | 
		
	
		
			
			|  |  |  | , runas : processedArgs.runas | 
		
	
		
			
			|  |  |  | , title : `git pull ${repo}` | 
		
	
		
			
			|  |  |  | }] | 
		
	
		
			
			|  |  |  | return pullCmd | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var performPull = (repo) => { | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(exludeMergeRepos[repo]) return Promise.resolve({ 'skipped' : true }) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(existsSync(repo)) { | 
		
	
		
			
			|  |  |  | console.log('pulling ' + repo) | 
		
	
		
			
			|  |  |  | return nodeShellExec.apply(null, getPullCmd(repo)).catch((e)=>{ console.error(e) }) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | console.log('cloning ' + repo) | 
		
	
		
			
			|  |  |  | // PB : TODO -- detect if a clonable repo exists in currentGitAuthUser | 
		
	
		
			
			|  |  |  | return nodeShellExec('git', ['clone', '-c', 'core.symlinks=true', defaultRepoServer + `/${defaultRepoOwner}/` + repo + '.git'], | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | inherit : true, shell: true, | 
		
	
		
			
			|  |  |  | env: process.env | 
		
	
		
			
			|  |  |  | , runas : processedArgs.runas | 
		
	
		
			
			|  |  |  | }).catch((e)=>{ console.error(e) }).then(()=>{ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return nodeShellExec('git', ['config', '--replace-all' , 'core.symlinks', true], | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | inherit : true, shell: true, | 
		
	
		
			
			|  |  |  | env: process.env | 
		
	
		
			
			|  |  |  | , cwd : repo | 
		
	
		
			
			|  |  |  | , runas : processedArgs.runas | 
		
	
		
			
			|  |  |  | , title : `git core.symlinks --replace-all true for ${defaultRepoServer + `/${defaultRepoOwner}/` + repo + '.git'}` | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(!processedArgs.runas) gitRepos.forEach(performPull) | 
		
	
		
			
			|  |  |  | return isRunningElevated().then( | 
		
	
		
			
			|  |  |  | (isElevated) => { | 
		
	
	
		
			
			|  |  | @@ -752,20 +820,7 @@ var __runcmd = function(label){ | 
		
	
		
			
			|  |  |  | 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); | 
		
	
		
			
			|  |  |  | // }) | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | }).finally(Traq.finally) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
			|  |  | @@ -784,57 +839,76 @@ var __runcmd = function(label){ | 
		
	
		
			
			|  |  |  | var npmbuildrepos = ['loopback-jsonapi-model-serializer'] | 
		
	
		
			
			|  |  |  | npmbuildrepos.forEach(repo => { | 
		
	
		
			
			|  |  |  | tasks.push(()=>{ | 
		
	
		
			
			|  |  |  | var p = nodeShellExec('npm', ['run build'], { | 
		
	
		
			
			|  |  |  | var p = nodeShellExec('npm', ['i --force'], { | 
		
	
		
			
			|  |  |  | inherit : true, shell: true | 
		
	
		
			
			|  |  |  | , cwd : repo | 
		
	
		
			
			|  |  |  | , env: process.env | 
		
	
		
			
			|  |  |  | , title : `npm build for ${repo}` | 
		
	
		
			
			|  |  |  | }).catch((e)=>{ console.error(e) }) | 
		
	
		
			
			|  |  |  | return p; | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | bowerRepos.forEach(repo => { | 
		
	
		
			
			|  |  |  | tasks.push(()=>{ | 
		
	
		
			
			|  |  |  | var p = nodeShellExec('bower', ['install'], { | 
		
	
		
			
			|  |  |  | inherit : true, shell: true | 
		
	
		
			
			|  |  |  | , cwd : repo | 
		
	
		
			
			|  |  |  | , env: process.env | 
		
	
		
			
			|  |  |  | , title : `bower i for ${repo}` | 
		
	
		
			
			|  |  |  | }).catch((e)=>{ console.error(e) }) | 
		
	
		
			
			|  |  |  | , title : `npm i for ${repo}` | 
		
	
		
			
			|  |  |  | }).catch((e)=>{ | 
		
	
		
			
			|  |  |  | console.error('Ignoring Benign Error'); console.error(e) | 
		
	
		
			
			|  |  |  | }).then(()=>{ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return nodeShellExec('npm', ['run build'], { | 
		
	
		
			
			|  |  |  | inherit : true, shell: true | 
		
	
		
			
			|  |  |  | , cwd : repo | 
		
	
		
			
			|  |  |  | , env: process.env | 
		
	
		
			
			|  |  |  | , title : `npm run build for ${repo}` | 
		
	
		
			
			|  |  |  | }).catch(Tasq.catch) | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return p; | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | gitRepos = gitRepos.concat(elevatedRunasRepos); | 
		
	
		
			
			|  |  |  | gitRepos.push('client/server'); | 
		
	
		
			
			|  |  |  | gitRepos.forEach(repo => { | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | console.log('npm i for ' + repo) | 
		
	
		
			
			|  |  |  | // nodeShellExec('pwd', [], { | 
		
	
		
			
			|  |  |  | //   // inherit : true, shell: true | 
		
	
		
			
			|  |  |  | //   cwd : repo | 
		
	
		
			
			|  |  |  | //   // , env: process.env | 
		
	
		
			
			|  |  |  | //   , title : `pwd  for ${repo}` | 
		
	
		
			
			|  |  |  | // }).catch((e)=>{ console.error(e) }) | 
		
	
		
			
			|  |  |  | nodeShellExec('rm', ['package-lock.json'], { | 
		
	
		
			
			|  |  |  | inherit : true, shell: true | 
		
	
		
			
			|  |  |  | , cwd : repo | 
		
	
		
			
			|  |  |  | , env: process.env | 
		
	
		
			
			|  |  |  | , title : `rm 'package-lock.json' for ${repo}` | 
		
	
		
			
			|  |  |  | }).catch((e)=>{ console.error(e) }) | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | any(tasks).then(()=>{ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if( npmbuildrepos.indexOf(repo) < 0) { | 
		
	
		
			
			|  |  |  | tasks.push(()=>{ | 
		
	
		
			
			|  |  |  | var p = nodeShellExec('npm', ['i --force'], { | 
		
	
		
			
			|  |  |  | gitRepos = gitRepos.concat(elevatedRunasRepos); | 
		
	
		
			
			|  |  |  | gitRepos.push('client/server'); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var repotasks = [] | 
		
	
		
			
			|  |  |  | gitRepos.forEach(repo => { | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | console.log('npm i for ' + repo) | 
		
	
		
			
			|  |  |  | repotasks.push( | 
		
	
		
			
			|  |  |  | nodeShellExec('rm', ['package-lock.json'], { | 
		
	
		
			
			|  |  |  | inherit : true, shell: true | 
		
	
		
			
			|  |  |  | , cwd : repo | 
		
	
		
			
			|  |  |  | , env: process.env | 
		
	
		
			
			|  |  |  | , title : `npm i for ${repo}` | 
		
	
		
			
			|  |  |  | }).catch((e)=>{ console.error(e) }) | 
		
	
		
			
			|  |  |  | , title : `rm 'package-lock.json' for ${repo}` | 
		
	
		
			
			|  |  |  | }).catch((e)=>{console.error(e)}) | 
		
	
		
			
			|  |  |  | .then(()=>{ | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if( npmbuildrepos.indexOf(repo) < 0) { | 
		
	
		
			
			|  |  |  | // tasks.push(()=>{ | 
		
	
		
			
			|  |  |  | var p = nodeShellExec('npm', ['i --force'], { | 
		
	
		
			
			|  |  |  | inherit : true, shell: true | 
		
	
		
			
			|  |  |  | , cwd : repo | 
		
	
		
			
			|  |  |  | , env: process.env | 
		
	
		
			
			|  |  |  | , title : `npm i for ${repo}` | 
		
	
		
			
			|  |  |  | }).catch(Tasq.catch) | 
		
	
		
			
			|  |  |  | return p; | 
		
	
		
			
			|  |  |  | // }) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | ) | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | bowerRepos.forEach(repo => { | 
		
	
		
			
			|  |  |  | repotasks.push(()=>{ | 
		
	
		
			
			|  |  |  | var p = nodeShellExec('bower', ['install'], { | 
		
	
		
			
			|  |  |  | inherit : true, shell: true | 
		
	
		
			
			|  |  |  | , cwd : repo | 
		
	
		
			
			|  |  |  | , env: process.env | 
		
	
		
			
			|  |  |  | , title : `bower i for ${repo}` | 
		
	
		
			
			|  |  |  | }).catch(Tasq.catch) | 
		
	
		
			
			|  |  |  | return p; | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | any(tasks); | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return any(repotasks); | 
		
	
		
			
			|  |  |  | }).catch(e=>{ | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | }).finally(statuslog.finally) | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | , 'start' : (label)=>{ | 
		
	
	
		
			
			|  |  | @@ -1242,53 +1316,6 @@ if(processedArgs.runas) { | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else __runcmd(processedArgs.label || processedArgs._[0] || 'h'); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 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); | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | var p = new Promise(function(resolve, reject){ | 
		
	
		
			
			|  |  |  | if(!opts.detached) { | 
		
	
		
			
			|  |  |  | var messages = []; // PB : TODO -- Explore stream for Task level  aggregation to prevent interleaved messages from multiple tasks... | 
		
	
		
			
			|  |  |  | var success = true; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | if(opts.stdio !== 'ignore') { | 
		
	
		
			
			|  |  |  | child.stdout.setEncoding('utf8'); | 
		
	
		
			
			|  |  |  | child.stderr.setEncoding('utf8'); | 
		
	
		
			
			|  |  |  | 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.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) | 
		
	
		
			
			|  |  |  | }); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | child.on('close', (code) => { | 
		
	
		
			
			|  |  |  | if(+code !== 0 || opts.haserrors) success = false; | 
		
	
		
			
			|  |  |  | if(opts.stdio !== 'ignore') { | 
		
	
		
			
			|  |  |  | var logEntry = { result: `${opts.title} exited with code ${code}`, messages } | 
		
	
		
			
			|  |  |  | logEntry.success = success; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(opts.runas){ | 
		
	
		
			
			|  |  |  | // success ? logEntry.success = true : null; | 
		
	
		
			
			|  |  |  | fs.writeFileSync('run.log', ', ' + JSON.stringify(logEntry), {'flag':'a+'} ) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | // console.log( messages.join('') ) | 
		
	
		
			
			|  |  |  | process.stdout.write( messages.join('') ) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | if(code !== 0 || opts.haserrors) return reject(logEntry) | 
		
	
		
			
			|  |  |  | resolve(logEntry) | 
		
	
		
			
			|  |  |  | }); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | child.unref() | 
		
	
		
			
			|  |  |  | resolve(true); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | }); | 
		
	
		
			
			|  |  |  | p.process = child; | 
		
	
		
			
			|  |  |  | return p; | 
		
	
		
			
			|  |  |  | } |