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 50KB

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