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.

index.js 49KB

3 yıl önce
3 yıl önce
6 yıl önce
4 yıl önce
4 yıl önce
3 yıl önce
5 yıl önce
6 yıl önce
3 yıl önce
4 yıl önce
6 yıl önce
5 yıl önce
6 yıl önce
4 yıl önce
3 yıl önce
3 yıl önce
4 yıl önce
4 yıl önce
6 yıl önce
5 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
3 yıl önce
3 yıl önce
3 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
3 yıl önce
3 yıl önce
3 yıl önce
3 yıl önce
3 yıl önce
4 yıl önce
3 yıl önce
3 yıl önce
3 yıl önce
5 yıl önce
4 yıl önce
5 yıl önce
5 yıl önce
5 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
4 yıl önce
5 yıl önce
4 yıl önce
5 yıl önce
3 yıl önce
5 yıl önce
4 yıl önce
5 yıl önce
4 yıl önce
3 yıl önce
4 yıl önce
3 yıl önce
5 yıl önce
6 yıl önce
5 yıl önce
6 yıl önce
5 yıl önce
6 yıl önce
6 yıl önce
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294
  1. var statuslog = require('./result')
  2. var path = require('path');
  3. var utils = require('bbhverse');
  4. var any = utils.any;
  5. // 'use strict';
  6. // PB : TODO -- make sure folder context is proper coz we can now run elxr from anywhere.
  7. // --------------
  8. // elxr
  9. // A cli tool for elixr.
  10. // PB : TODO --
  11. // runas bypass non elevated tasks when we request privelege
  12. // runas message is always error needs to be fixed.
  13. // runas wait needs to be parallelized.
  14. // suppress elevation check error messages
  15. // support runas lauched directly from shell.
  16. // pass in environment in hta to shellexecute.
  17. const { existsSync } = require('fs');
  18. const fs = require('fs')
  19. const { spawn, spawnSync } = require('child_process');
  20. const cliargs = utils.cliargs;
  21. const processedArgs = cliargs(process.argv.slice(2));
  22. console.dir(processedArgs)
  23. var globSync = require('glob').sync;
  24. var path = require('path');
  25. const { isMaster } = require('cluster');
  26. // Default Config...
  27. var reposervers = [
  28. 'http://git.bbh'
  29. , 'https://git.bbh.org.in'
  30. , '//172.16.0.27/repos'
  31. ]
  32. var defaultRepoServer = reposervers[0]
  33. var currentGitAuthUser ; // nodeShellExec('git', ['config', 'user.email']) ... PB : TODO-- get the current gittea username
  34. var defaultRepoOwner = 'chess';
  35. // PB : TODO -- If we are run from an elevated shell it never moves forward and simply exits.
  36. // -- Currently workaround is to always run from a non-elevated shell.
  37. var __isElevated = null; // We assume non-Elevated until someone evaluates and sets this variable.
  38. var isRunningElevated = ()=>{
  39. if(__isElevated === null) {
  40. return nodeShellExec( "fsutil", ["dirty", "query", "C:"], {
  41. inherit : true
  42. // , shell: true
  43. , stdio: 'ignore'
  44. , env: process.env
  45. , title : `check privileged execution mode using "fsutil dirty query C:"`
  46. }).then((exitcode)=>{
  47. console.log('Elevated')
  48. __isElevated = true;
  49. return true;
  50. }).catch(()=>{
  51. __isElevated = false;
  52. console.log('Not Elevated');
  53. throw false;
  54. });
  55. }
  56. else return Promise.resolve(__isElevated);
  57. }
  58. var cli = 'elxr';
  59. var ver = '#unversioned';
  60. var help = '#unkown list of commands... please refer dveloper documentation for ' + cli;
  61. // grep -qxF 'alias elxr="node elxr/index.js"' ~/.bash_profile || echo 'alias elxr="node elxr/index.js"' >> ~/.bash_profile
  62. // nodeShellExec('echo', ['elxr'], { inherit : true}) //, {stdio: "inherit"}
  63. var dbForLabel = function(label){
  64. var dbsForLabel = {
  65. devmysql : 'mysql'
  66. , development : 'mssql'
  67. , production : 'mssql'
  68. }
  69. return dbsForLabel[label] || 'mysql'
  70. }
  71. var gitInstallDir = "C:\\Program Files\\Git\\bin\\sh.exe"
  72. // var gitInstallDir = "G:\\Installed\\Git\\bin\\sh.exe"
  73. // Relevant git repos
  74. var brandName = 'elixir';
  75. // Runas windowshta clobbers and removes the NODE_ENV !!! We therefore pass it in.
  76. var nodeenv = process.env.NODE_ENV || processedArgs.node_env || 'development'
  77. if(nodeenv.trim() === 'production') nodeenv = 'production'
  78. // var repomanifest = require('../'+brandName+'-config-'+ nodeenv +'/repo-manifest')()
  79. var manifestpath = '../'+brandName+'-config-'+nodeenv+'/repo-manifest';
  80. // var manifestpath = '../'+brandName+'-config-'+'production'+'/repo-manifest';
  81. console.dir(manifestpath)
  82. var repomanifest = require(manifestpath)()
  83. console.dir(repomanifest)
  84. var gitRepos = repomanifest.repos
  85. // Repositiories that have symlinks that required elevated priviletes in windows to create symlinks
  86. //
  87. var elevatedRunasRepos = repomanifest.elevated
  88. var exludeMergeRepos = repomanifest.exludeMergeRepos
  89. // var productionRepos = [ 'elixir-config-production' ]
  90. // var productionIsAllowed = (nodeenv === 'production');
  91. // if(productionIsAllowed) gitRepos = gitRepos.concat(productionRepos)
  92. var env = Object.assign({}, process.env); // Shallow clone it.
  93. var __runcmd = function(label){
  94. var op = {
  95. 'h' : ()=>{ console.log(cli + ' ' + ver + ' ' + help); return '-h' }
  96. , 'undefined' : ()=>{ return op.h(); }
  97. , 'reset' : ()=>{
  98. // Reset NPM packages semver so major versions can be updated.
  99. const fs = require('fs')
  100. const wipeDependencies = (package) => {
  101. const file = fs.readFileSync(package + '/package.json')
  102. const content = JSON.parse(file)
  103. for (var devDep in content.devDependencies) {
  104. if (content.devDependencies[devDep].match(/\W+\d+.\d+.\d+-?((alpha|beta|rc)?.\d+)?/g)) {
  105. content.devDependencies[devDep] = '*';
  106. }
  107. }
  108. for (var dep in content.dependencies) {
  109. if (content.dependencies[dep].match(/\W+\d+.\d+.\d+-?((alpha|beta|rc)?.\d+)?/g)) {
  110. content.dependencies[dep] = '*';
  111. }
  112. }
  113. fs.writeFileSync(package + '/package.json', JSON.stringify(content))
  114. }
  115. var repos = ['client'];
  116. // repos = gitRepos;
  117. repos.forEach(wipeDependencies)
  118. // if (require.main === module) {
  119. // } else {
  120. // module.exports = wipeDependencies
  121. // }
  122. }
  123. , 'upgrade' : ()=>{
  124. console.log('upgrade.......')
  125. var tasks = [
  126. ()=>{
  127. var p = nodeShellExec('npm', ['i', '-g', 'npm-upgrade'], {
  128. inherit : true, shell: true
  129. , env: process.env
  130. }).catch((e)=>{ console.error(e) })
  131. p.position = 1;
  132. console.log('One')
  133. return p;
  134. }
  135. , ()=>{
  136. var p = nodeShellExec('npm', ['cache', 'clean', '-f'], {
  137. inherit : true, shell: true
  138. , env: process.env
  139. }).catch((e)=>{ console.error(e) })
  140. p.position = 2;
  141. console.log('Two')
  142. return p;
  143. }
  144. , ()=>{
  145. var p = nodeShellExec('npm', ['install', '-g', 'n'], {
  146. inherit : true, shell: true
  147. , env: process.env
  148. }).catch((e)=>{ console.error(e) })
  149. p.position = 3;
  150. console.log('Three')
  151. return p;
  152. }
  153. , ()=>{
  154. var p = nodeShellExec('n', ['latest'], {
  155. inherit : true, shell: true
  156. , env: process.env
  157. }).catch((e)=>{ console.error(e) })
  158. p.position = 4;
  159. console.log('Four')
  160. return p;
  161. }
  162. ]
  163. any(tasks)
  164. console.log('.......done')
  165. console.log('Running exlr upgrade in : ' + path.dirname(__dirname))
  166. console.log('Currently only upgrades ember : ' + path.dirname(__dirname));
  167. console.info('Uninstalling existing ember globally') ;
  168. var step1 = nodeShellExec('cmd', ['/c', 'npm', 'uninstall', '-g', 'ember-cli'], {
  169. stdio: ['pipe', process.stdout, process.stderr],
  170. inherit : true,
  171. shell: true,
  172. cwd : path.dirname(__dirname),
  173. env: env
  174. })
  175. step1.on('close', ()=>{
  176. console.info('Installing ember globally') ;
  177. var step2 = nodeShellExec('cmd', ['/c', 'npm', 'install', '-g', 'ember-cli'], {
  178. stdio: ['pipe', process.stdout, process.stderr],
  179. inherit : true,
  180. shell: true,
  181. cwd : path.dirname(__dirname),
  182. env: env
  183. })
  184. step2.on('close', ()=>{
  185. nodeShellExec('cmd', ['/c', 'ember', '--version'], {
  186. stdio: ['pipe', process.stdout, process.stderr],
  187. inherit : true,
  188. shell: true,
  189. cwd : path.dirname(__dirname),
  190. env: env
  191. })
  192. })
  193. })
  194. }
  195. , 'runas' : ()=>{
  196. console.log('Testing Elevation')
  197. return isRunningElevated().then(
  198. (isElevated) => {
  199. if(isElevated) {
  200. try {
  201. op[ processedArgs.label || processedArgs._[0] || 'h']()
  202. }
  203. catch(e){
  204. console.error('Error Invalid command : ' + e)
  205. fs.writeFileSync('run.done', 'success')
  206. }
  207. finally {
  208. }
  209. } else throw false;
  210. }
  211. )
  212. .catch(()=>{
  213. console.log('Requesting Elevated Privileges');
  214. // Wait for the runas to complete before we read it.
  215. try {
  216. fs.unlinkSync('run.done')
  217. fs.unlinkSync('run.log')
  218. }
  219. catch(e) { } //Ignore
  220. // Find node path to send to hta.
  221. return nodeShellExec('where', ['node']).then(r => {
  222. console.log('result : ' + r)
  223. // throw 'rrrrrrrrrrrrrrrrr'
  224. // PB : TODO -- Convert all the cli args back to string.
  225. var namedArgs = [];
  226. Object.keys(processedArgs).forEach((v)=>{ v!='_' ? namedArgs.push('--'+v+'='+processedArgs[v]) : null; })
  227. //console.log(' namedArgs : ' + namedArgs)
  228. var env = Object.assign({}, process.env); // Shallow clone it.
  229. // console.dir(env)
  230. env.NODE_ENV = process.env.NODE_ENV || 'development';
  231. var args = [__dirname + '/windowselevate.hta'].concat(processedArgs._).concat(namedArgs.join(' ')); args.push('--runas=self');
  232. args.push('--nodepath='+r[r.length-1])
  233. args.push('--node_env='+env.NODE_ENV)
  234. // args.push('--debug=true') // Enable to debug elevated..
  235. return nodeShellExec('MSHTA', [`"${args.join('" "')}"`]
  236. , {
  237. inherit : true
  238. , shell: true
  239. , env: env
  240. , runas : 'self'
  241. , title : `runas`
  242. }
  243. ).then(()=>{
  244. // runas returned.
  245. try {
  246. var runaslog = JSON.parse('[ { "success" : true, "result" : "runas Log" }' + fs.readFileSync('run.log', { flags : 'a+'}) + ']');
  247. runaslog.forEach((logEntry)=>{
  248. statuslog.statuslog(logEntry.success ? null : (logEntry.messages || []).join(' '))
  249. logEntry.success ? (console.log(['success :' + logEntry.result]), console.log((logEntry.messages || []).join(' '))) : (console.error(['error :' + logEntry.result]), console.error((logEntry.messages || []).join(' ')))
  250. })
  251. }
  252. catch(e){
  253. // Ignore nonexistent log
  254. console.warn('Run log error probably was not created by runas : ' + e)
  255. }
  256. })
  257. .catch(err => console.error('Elevation failed : ' + err));
  258. })
  259. })
  260. }
  261. , 'push' : ()=>{
  262. if(!processedArgs._[1]) { console.error('push all not supported. Specify repo name'); return }
  263. // init remote bare from local
  264. // pushandinitremotebare
  265. // https://www.jeffgeerling.com/blogs/jeff-geerling/push-your-git-repositories
  266. // connect to repo server -- net use 172.16.0.27
  267. // cd 172.16.0.27/repos/
  268. // mkdir repo.git
  269. // cd repo.git
  270. // git init --bare
  271. // cd localrepo
  272. // git remote rename origin githubclone
  273. // git remote add origin //172.16.0.27/repos/repo.git
  274. // git push origin master
  275. var repo = processedArgs._[1];
  276. var sequentialTaskShellCommands = [];
  277. if(!existsSync(`Z:/${repo}.git`)){
  278. sequentialTaskShellCommands = [
  279. // ['net', ['use', 'Z:', defaultRepoServer.replace('/','\\')], {
  280. // inherit : true, shell: true
  281. // , env: process.env
  282. // }]
  283. ['pwd', { cwd : 'Z:', inherit : true}]
  284. , ['mkdir', [`${repo}.git`], {
  285. cwd : `Z:`
  286. , inherit : true, shell: true
  287. , env: process.env
  288. }]
  289. , ['pwd', { cwd : `Z:/${repo}.git`, inherit : true}]
  290. , ['git', ['init', '--bare'], { cwd : `Z:/${repo}.git`
  291. , inherit : true, shell: true
  292. , env: process.env
  293. }]
  294. // PB : TODO -- Do this conditionally only...
  295. , ['git', ['remote', 'rename', 'origin', 'githubclone'], { cwd : `${repo}`}, (err)=>{
  296. console.log('Ignoring origin rename error : ' + err); return true; //return true to continue.
  297. } ] // PB ; Todo -- new repositories created locally will not have origin. Handle this failure.
  298. , ['git', ['remote', 'add', 'origin', `${defaultRepoServer}/${repo}.git`], { cwd : `${repo}`}]
  299. // PB : TODO -- If threre is a gitbubclone origin
  300. // Set the master to pull from the local repo.
  301. ]
  302. if(!existsSync(`Z:`)){
  303. sequentialTaskShellCommands.splice(0,0, ['net', ['use', 'Z:', defaultRepoServer.replace(/\//gm,'\\')], {
  304. inherit : true, shell: true
  305. , env: process.env
  306. }])
  307. console.warn('Adding network drive z: for repo server. ' + sequentialTaskShellCommands[0])
  308. // throw 'done'
  309. }
  310. }
  311. sequentialTaskShellCommands.push(['git', ['push', 'origin', 'master'], { cwd : `${repo}`}])
  312. // console.dir(sequentialTaskShellCommands);
  313. var tasks = [];
  314. sequentialTaskShellCommands.forEach(shellcmd => {
  315. // console.log(shellcmd)
  316. tasks.push(()=>{
  317. var p = nodeShellExec.apply(null, shellcmd.slice(0,3)).catch((e)=>{ if(shellcmd[3]) { return shellcmd[3]() } else { console.error(e);} })
  318. return p;
  319. })
  320. })
  321. any(tasks);
  322. }
  323. , 'is-git-repo' : (dir)=>{
  324. return nodeShellExec('git', ['-C', dir.name, 'rev-parse'], { stdio : 'ignore'})
  325. }
  326. , 'set-url' : (remotename, url) => {
  327. var pushable = processedArgs.pushable || false;
  328. remotename = remotename || processedArgs._[1]
  329. url = url || processedArgs._[2]
  330. var serial_perform_git_seturl = (repo)=>{
  331. var options = { cwd : repo }
  332. // console.log(repo)
  333. if(pushable) {
  334. return [
  335. ['git', ['remote', 'set-url', remotename, url + '/' + repo], { cwd : repo }]
  336. ]
  337. }
  338. else {
  339. console.error('not supported for non-pushable')
  340. }
  341. }
  342. var x = (args)=>{
  343. return ()=>{
  344. // console.log(args)
  345. return nodeShellExec.apply(null, args)
  346. }
  347. // return Promise.resolve(true)
  348. }
  349. var perform_git_seturl = (dir)=>{
  350. op['is-git-repo'](dir).then((code)=>{
  351. any( serial_perform_git_seturl(dir.name).map(x) )
  352. }).catch((e)=>{
  353. // console.log('Failed : ' + dir.name)
  354. })
  355. }
  356. const { readdir } = require("fs").promises
  357. const dirs = async (perform, path) => {
  358. for (const dir of await readdir(path || process.cwd(), { withFileTypes: true })) {
  359. if (dir.isDirectory()) perform(dir)
  360. }
  361. }
  362. dirs( perform_git_seturl)
  363. }
  364. , 'add' : (remotename, url, branch) => {
  365. var pushable = processedArgs.pushable || false;
  366. remotename = remotename || processedArgs._[1]
  367. url = url || processedArgs._[2]
  368. branch = branch || processedArgs._[3]
  369. var serial_perform_git_add = (repo)=>{
  370. var options = { cwd : repo }
  371. // console.log(repo)
  372. if(pushable) {
  373. return [
  374. ['git', ['remote', 'add', remotename, url + '/' + repo], { cwd : repo }]
  375. , ['git', ['pull', remotename, branch], { cwd : repo }]
  376. , ['git', ['branch', `--set-upstream-to=${remotename}/${branch}`, branch], { cwd : repo }]
  377. ]
  378. }
  379. else {
  380. return [
  381. ['git', ['remote', 'add', remotename, url + '/' + repo], { cwd : repo }]
  382. , ['git', ['remote', `set-url`, '--push', remotename, 'no-pushing'], { cwd : repo }]
  383. , ['git', ['pull', remotename, branch], { cwd : repo }]
  384. , ['git', ['branch', `--set-upstream-to=${remotename}/${branch}`, branch], { cwd : repo }]
  385. ]
  386. }
  387. }
  388. var x = (args)=>{
  389. return ()=>{
  390. // console.log(args)
  391. return nodeShellExec.apply(null, args)
  392. }
  393. // return Promise.resolve(true)
  394. }
  395. var perform_git_add = (dir)=>{
  396. op['is-git-repo'](dir).then((code)=>{
  397. // console.log(code)
  398. if(code) {
  399. nodeShellExec('git',['remote', 'get-url', remotename], { cwd : dir.name, stdio : 'ignore' }).then(()=>{
  400. console.log('skipped : ' + dir.name + ', reason : A remote with same name already exists.')
  401. })
  402. .catch((e)=>{
  403. any( serial_perform_git_add(dir.name).map(x) )
  404. })
  405. }
  406. // else console.log('Skipped : Not a Git Repo : ' + dir.name)
  407. }).catch((e)=>{
  408. // console.log('Failed : ' + dir.name)
  409. })
  410. }
  411. const { readdir } = require("fs").promises
  412. const dirs = async (perform, path) => {
  413. for (const dir of await readdir(path || process.cwd(), { withFileTypes: true })) {
  414. if (dir.isDirectory()) perform(dir)
  415. }
  416. }
  417. dirs(perform_git_add)
  418. }
  419. , 'remove' : (remotename) => {
  420. remotename = remotename || processedArgs._[1]
  421. var serial_perform_git_remove = (repo)=>{
  422. var options = { cwd : repo }
  423. // console.log(repo)
  424. return [
  425. ['git', ['remote', 'remove', remotename], { cwd : repo }]
  426. ]
  427. }
  428. var x = (args)=>{
  429. return ()=>{
  430. // console.log(args)
  431. return nodeShellExec.apply(null, args)
  432. }
  433. // return Promise.resolve(true)
  434. }
  435. var perform_git_remove = (dir)=>{
  436. op['is-git-repo'](dir).then((code)=>{
  437. // console.log(code)
  438. if(code) {
  439. nodeShellExec('git',['remote', 'get-url', remotename], { cwd : dir.name, stdio : 'ignore' }).then(()=>{
  440. any( serial_perform_git_remove(dir.name).map(x) )
  441. })
  442. .catch((e)=>{
  443. console.log('skipped : ' + dir.name + ', reason : No remote named origin')
  444. })
  445. }
  446. // else console.log('Skipped : Not a Git Repo : ' + dir.name)
  447. }).catch((e)=>{
  448. // console.log('Failed : ' + dir.name)
  449. })
  450. }
  451. const { readdir } = require("fs").promises
  452. const dirs = async (perform, path) => {
  453. for (const dir of await readdir(path || process.cwd(), { withFileTypes: true })) {
  454. if (dir.isDirectory()) perform(dir)
  455. }
  456. }
  457. dirs(perform_git_remove)
  458. }
  459. , 'init-gitea' : (user) => {
  460. user = user || processedArgs._[1]
  461. if(!user) throw 'User name required'
  462. var serial_perform_init_gitea = (repo)=>{
  463. var options = { cwd : repo }
  464. // console.log(repo)
  465. return [
  466. ['git', ['remote', 'add', 'chess', `${defaultRepoServer}/${user}/${repo}.git`], { cwd : repo }]
  467. , ['git', ['remote', 'set-url', '--push', 'chess', 'no-pushing'], { cwd : repo }]
  468. , ['git', ['remote', 'set-url', 'origin', `${defaultRepoServer}/${user}/${repo}.git`], { cwd : repo }]
  469. ]}
  470. var x = (args)=>{
  471. return ()=>{
  472. // console.log(args)
  473. return nodeShellExec.apply(null, args)
  474. }
  475. // return Promise.resolve(true)
  476. }
  477. var perform_init_gitea = (dir)=>{
  478. op['is-git-repo'](dir).then((code)=>{
  479. // console.log(code)
  480. if(code) {
  481. nodeShellExec('git',['remote', 'get-url', 'chess'], { cwd : dir.name, stdio : 'ignore' }).then(()=>{
  482. console.log('skipped : ' + dir.name + ', reason : Already has remote chess ')
  483. })
  484. .catch((e)=>{
  485. any( serial_perform_init_gitea(dir.name).map(x) )
  486. })
  487. }
  488. // else console.log('Skipped : Not a Git Repo : ' + dir.name)
  489. }).catch((e)=>{
  490. // console.log('Failed : ' + dir.name)
  491. })
  492. }
  493. const { readdir } = require("fs").promises
  494. const dirs = async (perform, path) => {
  495. for (const dir of await readdir(path || process.cwd(), { withFileTypes: true })) {
  496. if (dir.isDirectory()) perform(dir)
  497. }
  498. }
  499. dirs(perform_init_gitea)
  500. }
  501. , 'syncmaster' : (label) => {
  502. // Usage :
  503. // elxr pull -- Defaults to run config
  504. var env = Object.assign({}, process.env); // Shallow clone it.
  505. // console.dir(env)
  506. console.log('Running exlr pull : ' + path.dirname(__dirname))
  507. // nodeShellExec('cmd', ['/c', 'setup\\utility\\chess.bat', 'pull'], {
  508. // // nodeShellExec('cmd', ['/c', '..\\setup\\utility\\chess.bat', 'pull'], {
  509. // stdio: ['pipe', process.stdout, process.stderr],
  510. // inherit : true,
  511. // shell: true,
  512. // cwd : path.dirname(__dirname),
  513. // env: env
  514. // })
  515. var useGitPull = processedArgs.useGitPull || false;
  516. var getPullCmd = (repo)=>{
  517. // console.log(useGitPull)
  518. var pullCmd = [ gitInstallDir
  519. , ['-c', 'for i in `git remote`; do git pull $i master; done;']
  520. , { cwd : repo, title : 'pull all origins for ' + repo }]
  521. // var pullCmd = ['pullall', [], { cwd : repo }]
  522. if(useGitPull) pullCmd = ['git', ['pull'], {
  523. inherit : true, shell: true,
  524. cwd : repo
  525. // , env: process.env
  526. , runas : processedArgs.runas
  527. , title : `git pull ${repo}`
  528. }]
  529. return pullCmd
  530. }
  531. var performPull = (repo) => {
  532. if(exludeMergeRepos[repo]) return Promise.resolve({ 'skipped' : true })
  533. if(existsSync(repo)) {
  534. console.log('pulling ' + repo)
  535. return nodeShellExec.apply(null, getPullCmd(repo)).catch((e)=>{ console.error(e) })
  536. }
  537. else {
  538. console.log('cloning ' + repo)
  539. // PB : TODO -- detect if a clonable repo exists in currentGitAuthUser
  540. return nodeShellExec('git', ['clone', '-c', 'core.symlinks=true', defaultRepoServer + `/${defaultRepoOwner}/` + repo + '.git'],
  541. {
  542. inherit : true, shell: true,
  543. env: process.env
  544. , runas : processedArgs.runas
  545. }).catch((e)=>{ console.error(e) }).then(()=>{
  546. return nodeShellExec('git', ['config', '--replace-all' , 'core.symlinks', true],
  547. {
  548. inherit : true, shell: true,
  549. env: process.env
  550. , cwd : repo
  551. , runas : processedArgs.runas
  552. , title : `git core.symlinks --replace-all true for ${defaultRepoServer + `/${defaultRepoOwner}/` + repo + '.git'}`
  553. })
  554. })
  555. }
  556. }
  557. if(!processedArgs.runas) gitRepos.forEach(performPull)
  558. return isRunningElevated().then(
  559. (isElevated) => {
  560. if(isElevated) {
  561. any(elevatedRunasRepos.map((repo)=>performPull(repo))).then(()=>{
  562. fs.writeFileSync('run.done', 'success')
  563. }).catch(()=>{
  564. fs.writeFileSync('run.done', 'error')
  565. })
  566. }
  567. else throw false;
  568. }
  569. ).catch(
  570. () => {
  571. op['runas']()
  572. }
  573. )
  574. }
  575. , 'pull' : (label) => {
  576. // Usage :
  577. // elxr pull -- Defaults to run config
  578. var env = Object.assign({}, process.env); // Shallow clone it.
  579. // console.dir(env)
  580. console.log('Running exlr pull : ' + path.dirname(__dirname))
  581. // nodeShellExec('cmd', ['/c', 'setup\\utility\\chess.bat', 'pull'], {
  582. // // nodeShellExec('cmd', ['/c', '..\\setup\\utility\\chess.bat', 'pull'], {
  583. // stdio: ['pipe', process.stdout, process.stderr],
  584. // inherit : true,
  585. // shell: true,
  586. // cwd : path.dirname(__dirname),
  587. // env: env
  588. // })
  589. var useGitPull = processedArgs.useGitPull || false;
  590. var getPullCmd = (repo)=>{
  591. // console.log(useGitPull)
  592. var pullCmd = [ gitInstallDir
  593. , ['-c', 'branch=`git rev-parse --abbrev-ref HEAD`;for i in `git remote`; do git pull $i $branch; done;']
  594. , { cwd : repo, title : 'pull all origins for ' + repo }]
  595. // var pullCmd = ['pullall', [], { cwd : repo }]
  596. if(useGitPull) pullCmd = ['git', ['pull'], {
  597. inherit : true, shell: true,
  598. cwd : repo
  599. // , env: process.env
  600. , runas : processedArgs.runas
  601. , title : `git pull ${repo}`
  602. }]
  603. return pullCmd
  604. }
  605. var performPull = (repo) => {
  606. if(existsSync(repo)) {
  607. console.log('pulling ' + repo)
  608. return nodeShellExec.apply(null, getPullCmd(repo)).then(()=>{
  609. if(__isElevated) {
  610. fs.writeFileSync('run.log', ', ' + JSON.stringify({ repo, success:true}), {'flag':'a+'} )
  611. }
  612. else statuslog.statuslog(null, repo)
  613. })
  614. .catch((e)=>{
  615. e.repo = repo;
  616. if(__isElevated) {
  617. fs.writeFileSync('run.log', ', ' + JSON.stringify(e), {'flag':'a+'} )
  618. }
  619. else statuslog.statuslog(e); console.error(e)
  620. })
  621. }
  622. else {
  623. // PB : TODO -- detect if a clonable repo exists in currentGitAuthUser
  624. return nodeShellExec('git', ['clone', '-c', 'core.symlinks=true', defaultRepoServer + `/${defaultRepoOwner}/` + repo + '.git'],
  625. {
  626. inherit : true, shell: true,
  627. env: process.env
  628. , runas : processedArgs.runas
  629. }).catch((e)=>{
  630. throw e;
  631. }).then(()=>{
  632. return nodeShellExec('git', ['config', '--replace-all' , 'core.symlinks', true],
  633. {
  634. inherit : true, shell: true,
  635. env: process.env
  636. , cwd : repo
  637. , runas : processedArgs.runas
  638. , title : `git core.symlinks --replace-all true for ${defaultRepoServer + `/${defaultRepoOwner}/` + repo + '.git'}`
  639. })
  640. .then(()=>{
  641. if(__isElevated) {
  642. fs.writeFileSync('run.log', ', ' + JSON.stringify({ repo, success:true}), {'flag':'a+'} )
  643. }
  644. else statuslog.statuslog(null, repo)
  645. })
  646. .catch((e)=>{
  647. e.repo = repo;
  648. if(__isElevated) {
  649. fs.writeFileSync('run.log', ', ' + JSON.stringify(e), {'flag':'a+'} )
  650. }
  651. else statuslog.statuslog(e);
  652. })
  653. })
  654. .catch(e=>{
  655. e.repo = repo;
  656. if(__isElevated) {
  657. fs.writeFileSync('run.log', ', ' + JSON.stringify(e), {'flag':'a+'} )
  658. }
  659. else statuslog.statuslog(e);
  660. })
  661. }
  662. }
  663. return isRunningElevated().then(
  664. (isElevated) => {
  665. if(isElevated) {
  666. any(elevatedRunasRepos.map((repo)=>performPull(repo))).then(()=>{
  667. fs.writeFileSync('run.done', 'success')
  668. }).catch(()=>{
  669. fs.writeFileSync('run.done', 'error')
  670. })
  671. }
  672. else throw false;
  673. }
  674. ).catch(
  675. () => {
  676. op['runas']().then(()=>{
  677. })
  678. .catch(()=>{})
  679. .finally(()=>{
  680. if(!processedArgs.runas) {
  681. var pendingpulls = [];
  682. gitRepos.forEach( (r)=>{ pendingpulls.push(performPull(r)) } )
  683. Promise.all(pendingpulls).then(results =>{
  684. }).finally(()=>{
  685. console.log('Total : ' + (statuslog.log.SKIPPED.length + statuslog.log.SUCCESS.length + statuslog.log.FAILURE.length))
  686. console.log('Pass : ' + statuslog.log.SUCCESS.length )
  687. console.log('Fail : ' + statuslog.log.FAILURE.length)
  688. console.log('Skipped : ' + statuslog.log.SKIPPED.length)
  689. console.log('FAILURES')
  690. console.log([JSON.stringify(statuslog.log.FAILURE)])
  691. // statuslog.log.FAILURE.forEach(f => {
  692. // console.error(f);
  693. // })
  694. })
  695. }
  696. })
  697. }
  698. )
  699. }
  700. , 'isInstalled' : ()=>{
  701. return nodeShellExec('where', [processedArgs._[1]], { inherit : true} ).then(()=>{
  702. console.log(processedArgs._[1] + ' exists.')
  703. return true;
  704. });
  705. }
  706. , 'npmi' : ()=>{
  707. var tasks = [];
  708. var bowerRepos = ['client']
  709. var npmbuildrepos = ['loopback-jsonapi-model-serializer']
  710. npmbuildrepos.forEach(repo => {
  711. tasks.push(()=>{
  712. var p = nodeShellExec('npm', ['run build'], {
  713. inherit : true, shell: true
  714. , cwd : repo
  715. , env: process.env
  716. , title : `npm build for ${repo}`
  717. }).catch((e)=>{ console.error(e) })
  718. return p;
  719. })
  720. })
  721. bowerRepos.forEach(repo => {
  722. tasks.push(()=>{
  723. var p = nodeShellExec('bower', ['install'], {
  724. inherit : true, shell: true
  725. , cwd : repo
  726. , env: process.env
  727. , title : `bower i for ${repo}`
  728. }).catch((e)=>{ console.error(e) })
  729. return p;
  730. })
  731. })
  732. gitRepos = gitRepos.concat(elevatedRunasRepos);
  733. gitRepos.push('client/server');
  734. gitRepos.forEach(repo => {
  735. console.log('npm i for ' + repo)
  736. // nodeShellExec('pwd', [], {
  737. // // inherit : true, shell: true
  738. // cwd : repo
  739. // // , env: process.env
  740. // , title : `pwd for ${repo}`
  741. // }).catch((e)=>{ console.error(e) })
  742. nodeShellExec('rm', ['package-lock.json'], {
  743. inherit : true, shell: true
  744. , cwd : repo
  745. , env: process.env
  746. , title : `rm 'package-lock.json' for ${repo}`
  747. }).catch((e)=>{ console.error(e) })
  748. if( npmbuildrepos.indexOf(repo) < 0) {
  749. tasks.push(()=>{
  750. var p = nodeShellExec('npm', ['i --force'], {
  751. inherit : true, shell: true
  752. , cwd : repo
  753. , env: process.env
  754. , title : `npm i for ${repo}`
  755. }).catch((e)=>{ console.error(e) })
  756. return p;
  757. })
  758. }
  759. })
  760. any(tasks);
  761. }
  762. , 'start' : (label)=>{
  763. console.log('Starting Elixir Server.');
  764. var env = Object.assign({}, process.env); // Shallow clone it.
  765. // console.dir(env)
  766. env.NODE_ENV = process.env.NODE_ENV || 'development';
  767. env.DEBUG = 'loopback:connector:' + dbForLabel(label)
  768. var cmd = env.NODE_ENV === 'development' ? 'nodemon' : 'node';
  769. // cmd = 'node'
  770. cmd = [cmd, ['--inspect=9228', 'elixir/server.js']]
  771. var childPromise = nodeShellExec(...cmd, {
  772. // inherit : true,
  773. shell: true,
  774. detached: true,
  775. stdio: 'ignore',
  776. cwd : 'elixir-server'
  777. , env: env
  778. })
  779. var child = childPromise.process;
  780. if (typeof child.pid !== 'undefined') {
  781. console.log(`started Elixir Server PID(${child.pid}) : NODE_ENV=${process.NODE_ENV} ${cmd}`);
  782. fs.writeFileSync('.elixir-server.elixir.server.pid', child.pid, {
  783. encoding: 'utf8'
  784. })
  785. }
  786. // nodeShellExec('node', ['--inspect=9226', ' bin/www'], {
  787. // inherit : true,
  788. // shell: true, detached: true,
  789. // cwd : 'qms/server',
  790. // env: env,
  791. // shell : true
  792. // })
  793. // nodeShellExec('ember', ['s'], {
  794. // // inherit : true,
  795. // shell: true, detached: true,
  796. // cwd : 'client/',
  797. // env: env
  798. // })
  799. console.log('Starting Elixir Client Host.');
  800. var cmd = ['ember', ['s']]
  801. var childPromise = nodeShellExec(...cmd, {
  802. // var childPromise = nodeShellExec('node', ['--inspect=9227', './node_modules/.bin/ember', 's'], {
  803. // PB : TODO -- ember debugging.
  804. // inherit : true,
  805. shell: true,
  806. detached: true,
  807. stdio: 'ignore',
  808. cwd : 'client'
  809. , env: env
  810. })
  811. // .catch(e=>console.error(e))
  812. child = childPromise.process;
  813. if (typeof child.pid !== 'undefined') {
  814. console.log(`started Elixir Client Host PID(${child.pid}) : NODE_ENV=${process.NODE_ENV} ${cmd}`);
  815. fs.writeFileSync('.client.server.pid', child.pid, {
  816. encoding: 'utf8'
  817. })
  818. }
  819. }
  820. , 'stop' : (label)=>{
  821. const kill = require('tree-kill');
  822. var serverPid = fs.readFileSync('.elixir-server.elixir.server.pid', {
  823. encoding: 'utf8'
  824. })
  825. fs.unlinkSync('.elixir-server.elixir.server.pid')
  826. console.log(serverPid)
  827. kill(serverPid)
  828. serverPid = fs.readFileSync('.client.server.pid', {
  829. encoding: 'utf8'
  830. })
  831. fs.unlinkSync('.client.server.pid')
  832. console.log(serverPid)
  833. kill(serverPid)
  834. }
  835. , 'use' : ()=>{
  836. // use a certain named instance.
  837. // Eg :
  838. // 1) elxr use elixir
  839. // 2) elxr use cihsr
  840. // If environment is not specified defaults to development.
  841. // 1) NODE=test elxr use elixir
  842. /*// Steps
  843. 1) Delete Config and Data symlinks
  844. 2) Make Links for config ({{name}}-config-{{node_env}}) and data with the NODE_ENV specified or default to dev
  845. 3) Iterates all repos and pull all. 'git', ['pull', '--all'].
  846. 4) Iterates all repos and checkout to the ENV specified. 'git', ['checkout', checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV]
  847. 5) Iterates all repos and merge from source configured in mergeSource. 'git', ['merge', mergeSource],
  848. */
  849. var runconfig = { NODE_ENV : process.env.NODE_ENV }
  850. try { runconfig = Object.assign(runconfig, require('../run.js')) } catch(e) { }
  851. if((!processedArgs.runas || processedArgs.runas !== 'self') &&
  852. runconfig.NODE_ENV && runconfig.NODE_ENV === (process.env.NODE_ENV || runconfig.NODE_ENV) &&
  853. processedArgs._[1] && runconfig.use === processedArgs._[1]) {
  854. console.log(`No change detected. Already using requested specs : ${runconfig.NODE_ENV} ${runconfig.use}`)
  855. if(processedArgs.runas) { fs.writeFileSync('run.done', 'success') }
  856. return
  857. }
  858. var tasks = [
  859. ()=>{
  860. if(existsSync('config')) {
  861. var p = nodeShellExec('rmdir', ['config'], {inherit : true, shell: true, env: process.env }
  862. ).catch((err)=>{ console.log('Ignoring benign error : ' + err); return true; })
  863. return p;
  864. }
  865. else return Promise.resolve(true);
  866. },
  867. ()=>{
  868. if(existsSync('data')) {
  869. var p = nodeShellExec('rmdir', ['data'], { inherit : true, shell: true, env: process.env }
  870. ).catch((err)=>{ console.log('Ignoring benign error : ' + err); return true; })
  871. return p;
  872. }
  873. else return Promise.resolve(true);
  874. },
  875. ];
  876. runconfig.NODE_ENV = process.env.NODE_ENV = process.env.NODE_ENV || runconfig.NODE_ENV || 'development';
  877. if(processedArgs._[1] && runconfig.use !== processedArgs._[1]) runconfig.use = processedArgs._[1];
  878. if(!runconfig.use) { throw 'unspecifed use not allowed. Please specify chess instance name.' }
  879. // console.log(process.env.cwd)
  880. fs.writeFileSync('./run.js', 'module.exports = ' + JSON.stringify(runconfig))
  881. var checkoutMap = {
  882. 'development' : 'master',
  883. }
  884. // cant use git checkout -b it fails with branch already exists.
  885. var performCheckout = (repo, branch)=>{
  886. if(!branch) return Promise.resolve({ 'skipped' : true })
  887. if(excludeCheckouts[repo]) return Promise.resolve({ 'skipped' : true })
  888. return nodeShellExec('git', ['checkout', branch || checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV], {
  889. // return nodeShellExec('git', ['switch', '-m', '-C', checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV], {
  890. // inherit : true, shell: true,
  891. cwd : repo
  892. // , stdio : ignore // Use when we want to silcence output completely.
  893. , runas : processedArgs.runas
  894. , title : `git checkout ${branch ||checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV} for ${repo}`
  895. }).catch((e)=>{ console.error(e); return { error : true, message : repo} })
  896. }
  897. if(runconfig.NODE_ENV === 'development') performCheckout = ()=>{ return Promise.resolve(true) }
  898. var performPullAll = (repo)=>{
  899. if(excludeCheckouts[repo]) return Promise.resolve({ 'skipped' : true })
  900. return nodeShellExec('git', ['pull', '--all'], {
  901. // inherit : true, shell: true,
  902. cwd : repo
  903. , runas : processedArgs.runas
  904. , title : `git pull -all for ${checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV} ${repo}`
  905. }).catch((e)=>{ console.error(e); return { error : true, message : repo} })
  906. }
  907. var mergeSources = {
  908. 'development' : null,
  909. 'test' : 'master',
  910. 'production' : 'master'
  911. }
  912. var excludeCheckouts = Object.assign(exludeMergeRepos)
  913. delete excludeCheckouts[`elixir-config-${runconfig.NODE_ENV}`]
  914. delete excludeCheckouts[`cihsr-config-${runconfig.NODE_ENV}`]
  915. var mergeSource = mergeSources[checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV]
  916. var performMerge = (repo)=>{
  917. if(exludeMergeRepos[repo]) return Promise.resolve({ 'skipped' : true })
  918. return nodeShellExec('git', ['merge', mergeSource], {
  919. inherit : true, shell: true,
  920. cwd : repo
  921. , runas : processedArgs.runas
  922. }).catch((e)=>{ console.error(e) })
  923. }
  924. if(runconfig.NODE_ENV === 'development') performMerge = ()=>{ return Promise.resolve(true) }
  925. any(tasks).then(()=>{
  926. if(!processedArgs.runas) return op['runas']()
  927. tasks = [
  928. ()=>{
  929. // Use junctions to avoid npm package issues
  930. var p = nodeShellExec('mklink', ['/J', 'config', runconfig.use + '-config' + '-' + process.env.NODE_ENV ], {
  931. inherit : true, shell: true
  932. , env: process.env
  933. }).catch((e)=>{ console.error(e) })
  934. return p;
  935. }
  936. ];
  937. if(processedArgs._[1]) {
  938. tasks = tasks.concat(
  939. [
  940. ()=>{
  941. var p = nodeShellExec('mklink', ['/J', 'data', runconfig.use + '-data'], {
  942. inherit : true, shell: true
  943. , env: process.env
  944. }).catch((e)=>{ console.error(e) })
  945. return p;
  946. }
  947. ]
  948. )
  949. }
  950. return any(tasks)
  951. //target is the env is we specify in elxr use command. Default is dev
  952. .then( //Switch to target branch
  953. () => any([ any(gitRepos.map((repo)=>performCheckout(repo, process.env.NODE_ENV || 'development')))
  954. , any(elevatedRunasRepos.map((repo)=>performCheckout(repo, process.env.NODE_ENV || 'development')))]) )
  955. .then( //PULL from target branch
  956. () => any([ any(gitRepos.map((repo)=>performPullAll(repo))), any(elevatedRunasRepos.map((repo)=>performPullAll(repo)))]) )
  957. .then( //Switch to merge source branch
  958. () => any([ any(gitRepos.map((repo)=>performCheckout(repo, mergeSources[process.env.NODE_ENV || 'development'] )))
  959. , any(elevatedRunasRepos.map((repo)=>performCheckout(repo, mergeSources[process.env.NODE_ENV || 'development'])))]) )
  960. .then( //Pull on merge source branch
  961. () => any([ any(gitRepos.map((repo)=>performPullAll(repo))), any(elevatedRunasRepos.map((repo)=>performPullAll(repo)))]) )
  962. .then( //Switch to target branch
  963. () => any([ any(gitRepos.map((repo)=>performCheckout(repo, process.env.NODE_ENV || 'development')))
  964. , any(elevatedRunasRepos.map((repo)=>performCheckout(repo, process.env.NODE_ENV || 'development')))]) )
  965. .then( //Merge source branch to target branch
  966. () => any([ any(gitRepos.map((repo)=>performMerge(repo))).catch(err=>{ console.error('error in performMerge ' + err)}) ,
  967. any(elevatedRunasRepos.map((repo)=>performMerge(repo))).catch(err=>{ console.error('error in performMerge ' + err)})]) )
  968. .then( () => {
  969. // Move test config from dev.
  970. // if(process.env.NODE_ENV === 'test'){
  971. // var devcfgreponame = runconfig.use + '-config' + '-development';
  972. // var testcfgreponame = runconfig.use + '-config' + '-test';
  973. // var testcfgdir = path.dirname(__dirname) + '/' + testcfgreponame + '/'
  974. // var devcfgdir = path.dirname(__dirname) + '/' + devcfgreponame + '/' //eg (elxr/../elixir-config.development)
  975. // return any([
  976. // ()=>{
  977. // return nodeShellExec('git', ['checkout', 'test'], {
  978. // inherit : true, shell: true,
  979. // cwd : testcfgdir
  980. // // , env: process.env
  981. // , runas : processedArgs.runas
  982. // , title : `git checkout test for ${testcfgreponame}`
  983. // }).catch((e)=>{ console.error(e) })
  984. // }
  985. // , ()=> {
  986. // return nodeShellExec('git', ['checkout', 'master'], {
  987. // inherit : true, shell: true,
  988. // cwd : devcfgdir
  989. // // , env: process.env
  990. // , runas : processedArgs.runas
  991. // , title : `git checkout master for ${devcfgreponame}`
  992. // }).catch((e)=>{ console.error(e) })
  993. // }
  994. // , ()=> {
  995. // globSync( '**/*.test.js', {cwd : devcfgdir}).map((filename) => {
  996. // console.log('File found : ' + devcfgdir + filename)
  997. // fs.copyFileSync(devcfgdir + filename, testcfgdir+ filename);
  998. // })
  999. // return nodeShellExec('git', ['checkout', 'test'], {
  1000. // inherit : true, shell: true,
  1001. // cwd : devcfgdir
  1002. // // , env: process.env
  1003. // , runas : processedArgs.runas
  1004. // , title : `git checkout test for ${devcfgreponame}`
  1005. // }).catch((e)=>{ console.error(e) })
  1006. // }
  1007. // ])
  1008. // }
  1009. // else {
  1010. return Promise.resolve(true)
  1011. // }
  1012. })
  1013. .then(()=>{
  1014. fs.writeFileSync('run.done', 'success')
  1015. }).catch(()=>{
  1016. fs.writeFileSync('run.done', 'error')
  1017. })
  1018. }).catch(()=>{
  1019. fs.writeFileSync('run.done', 'error')
  1020. })
  1021. // Antibiotic stewardship program.
  1022. // 1st use is fine.
  1023. // Max vials dispense
  1024. // 2nd use Pharmacy needs justification Form.
  1025. // Approval after a certain period of time.
  1026. }
  1027. , 'g' : ()=>{
  1028. if(processedArgs.h) {
  1029. console.log('elxr g [modelname] => generate a model named [modelname]');
  1030. console.log('elxr g => regenerate all known models');
  1031. return
  1032. }
  1033. // var child = nodeShellExec('mkdir', ['-p', label], { inherit : true} );
  1034. // console.log('Starting directory: ' + process.cwd());
  1035. // try {
  1036. // child = child.on('close', () => { process.chdir(label) } );
  1037. // console.log('New directory: ' + process.cwd());
  1038. // }
  1039. // catch (err) {
  1040. // console.log('chdir: ' + err);
  1041. // }
  1042. // child.on('close', function(){
  1043. // var options = {
  1044. // shell : true
  1045. // , inherit : true
  1046. // // , cwd : '' + process.cwd
  1047. // // , env : process.env
  1048. // };
  1049. // nodeShellExec('git', ['init'], { inherit : true});
  1050. if(0){
  1051. // PB : TODO -- Special google chrome profile for tests etc.
  1052. nodeShellExec('pwd', { inherit : true});
  1053. // /c/Program\ Files\ \(x86\)/Google/Chrome/Application/chrome.exe --user-data-dir=/c/chess/instances/elixir_01/data/Google/Chrome/User\ Data --profile-directory="chess"
  1054. // "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --user-data-dir="C:\chess\instances\elixir_01\data\Google\Chrome\User Data" --profile-directory="chess" http://localhost:4200/admin/crud/create/item
  1055. // "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --user-data-dir="C:\chess\instances\elixir_01\data\Google\Chrome\User Data" --profile-directory="chess" http://localhost:4200/tests/index.html?grep=loopback
  1056. nodeShellExec("C:/Program Files (x86)/Google/Chrome/Application/chrome.exe", [
  1057. "--profile-directory=Profile 1"
  1058. , 'http://localhost:4200/tests/index.html?grep=model convert ember to loopback' + '&filter=none' /*+ '&filter=model convert ember to loopback'*/]);
  1059. }
  1060. // nodeShellExec('npm', ['init', '-y'], options);
  1061. // nodeShellExec('npm', ['init', '-y'], options);
  1062. // })
  1063. var g = {
  1064. 'client' : ()=>{
  1065. console.info('Creating new ember client named : ' + processedArgs._[2] ) ;
  1066. var step1 = nodeShellExec('cmd', ['/c', 'ember', 'new', processedArgs._[2]], {
  1067. stdio: ['pipe', process.stdout, process.stderr],
  1068. inherit : true,
  1069. shell: true,
  1070. cwd : path.dirname(__dirname),
  1071. env: env
  1072. })
  1073. },
  1074. 'modelr' : ()=>{
  1075. var tasks = [
  1076. ()=>{
  1077. var p = nodeShellExec('"ember"', [
  1078. 'g'
  1079. , 'modelr'
  1080. , processedArgs._[2]], {
  1081. inherit : true, shell: true, env: process.env
  1082. }).then(()=>{
  1083. console.log('Blueprint generation complete for : ' + processedArgs._[2])
  1084. return true;
  1085. }).catch((e)=>{ console.error(e) })
  1086. return p;
  1087. },
  1088. ()=>{
  1089. var chromePrefsFile = "C:\\chess\\instances\\elixir_01\\data\\Google\\Chrome\\User Data\\chess\\Preferences";
  1090. var chromeprefs = fs.readFileSync(chromePrefsFile, { encoding: 'utf8' })
  1091. chromeprefs = JSON.parse(chromeprefs)
  1092. var previous = chromeprefs.download.default_directory;
  1093. var parentDir = path.dirname(__dirname);
  1094. chromeprefs.download.default_directory = parentDir + "\\client\\app\\templates\\components\\resource";
  1095. fs.writeFileSync(chromePrefsFile, JSON.stringify(chromeprefs))
  1096. // PB : TODO -- detect where chrome is installed.
  1097. // PB : TODO -- set the download dir to the place where files are needed.
  1098. var p = nodeShellExec('"C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"', [
  1099. '--user-data-dir="C:\\chess\\instances\\elixir_01\\data\\Google\\Chrome\\User Data"'
  1100. , '--profile-directory="chess"'
  1101. , 'http://localhost:4200/admin/crud/create/' + processedArgs._[2]], {
  1102. inherit : true, shell: true
  1103. , env: process.env
  1104. }).then(()=>{
  1105. chromeprefs.download.default_directory = previous;
  1106. fs.writeFileSync(chromePrefsFile, JSON.stringify(chromeprefs))
  1107. return true;
  1108. }).catch((e)=>{ console.error(e) })
  1109. return p;
  1110. }
  1111. ,
  1112. ()=>{
  1113. console.log('Browser process should have closed here....')
  1114. return true;
  1115. }
  1116. ]
  1117. any(tasks)
  1118. }
  1119. }
  1120. g[processedArgs._[1]]();
  1121. }
  1122. }
  1123. return op[label] ? op[label]() : null;
  1124. }
  1125. // mysqldump --add-drop-table --no-data -u root -p db_name | grep 'DROP TABLE' ) > drop_all_tables.sql
  1126. // mysql -u root -p db_name < drop_all_tables.sql
  1127. var mysql = '../xampp/mysql/bin/mysql'
  1128. var mysqldump = '../xampp/mysql/bin/mysqldump'
  1129. // --runas
  1130. if(processedArgs.runas) {
  1131. // Weve been asked to run in priviledged mode. Check if we already are privileged.
  1132. __runcmd('runas')
  1133. }
  1134. else __runcmd(processedArgs.label || processedArgs._[0] || 'h');
  1135. function nodeShellExec() {
  1136. var args = Array.from(arguments);
  1137. var opts = args[2] = args[2] || {}
  1138. opts.title ? null : opts.title = `${args[0]} ${args[1] }`
  1139. const child = spawn(...arguments);
  1140. var p = new Promise(function(resolve, reject){
  1141. if(!opts.detached) {
  1142. var messages = []; // PB : TODO -- Explore stream for Task level aggregation to prevent interleaved messages from multiple tasks...
  1143. var success = true;
  1144. if(opts.stdio !== 'ignore') {
  1145. child.stdout.setEncoding('utf8');
  1146. child.stderr.setEncoding('utf8');
  1147. child.stdout.on('data', (chunk) => { chunk.trim() === '' ? null : messages.push(chunk); /* console.log('d: ' + chunk) */ });
  1148. child.on('error', (chunk) => { success = false; messages.push(chunk); /* console.error('e: ' + chunk) */ } );
  1149. child.stderr.on('data', (chunk) => {
  1150. if(messages.join('').indexOf('fatal: not a git repository') > -1) opts.haserrors = true;
  1151. messages.push(chunk);
  1152. // console.error('stderr e: ' + chunk)
  1153. });
  1154. }
  1155. child.on('close', (code) => {
  1156. if(+code !== 0 || opts.haserrors) success = false;
  1157. if(opts.stdio !== 'ignore') {
  1158. var logEntry = { result: `${opts.title} exited with code ${code}`, messages }
  1159. logEntry.success = success;
  1160. if(opts.runas){
  1161. // success ? logEntry.success = true : null;
  1162. fs.writeFileSync('run.log', ', ' + JSON.stringify(logEntry), {'flag':'a+'} )
  1163. }
  1164. else {
  1165. // console.log( messages.join('') )
  1166. process.stdout.write( messages.join('') )
  1167. }
  1168. }
  1169. if(code !== 0 || opts.haserrors) return reject(logEntry)
  1170. resolve(logEntry)
  1171. });
  1172. }
  1173. else {
  1174. child.unref()
  1175. resolve(true);
  1176. }
  1177. });
  1178. p.process = child;
  1179. return p;
  1180. }