roll-right 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,814 @@
1
+ const fs = require('fs')
2
+ const minify = require('html-minifier').minify;
3
+ const tar = require('tar')
4
+ const {exec} = require('child_process')
5
+ const path_util = require('path')
6
+ const util = require('util');
7
+ const asyc_exec = util.promisify(exec);
8
+ const Terser = require('terser')
9
+
10
+ const scp = require('node-scp')
11
+
12
+ var g_ssh_pass = process.argv[2]
13
+ console.log(g_ssh_pass)
14
+ if ( g_ssh_pass === undefined ) {
15
+ console.error('No ssh password provided')
16
+ process.exit(1)
17
+ }
18
+
19
+ var g_repeat_process = false
20
+ if ( process.argv[3] !== undefined ) {
21
+ g_repeat_process = true
22
+ }
23
+
24
+ var g_releaseObject = null
25
+ var g_config_file = 'release.json'
26
+ try {
27
+ var releaseObj_str = fs.readFileSync(g_config_file,'ascii').toString()
28
+ try {
29
+ g_releaseObject = JSON.parse(releaseObj_str)
30
+ } catch (e) {
31
+ console.error(`failed to parse the file '${g_config_file}'`)
32
+ console.error(e)
33
+ process.exit(0)
34
+ }
35
+ } catch (e) {
36
+ console.error(`failed to find the file '${g_config_file}'`)
37
+ process.exit(0)
38
+ }
39
+
40
+ console.dir(g_releaseObject)
41
+
42
+
43
+ // // // // // // // // // //
44
+
45
+ // extract_vars
46
+ // Finds all instances of variables of the form ${varname}
47
+ // Returns a list of them
48
+ function extract_vars(rm_ctl_tmpl) {
49
+ let varset = {}
50
+ let varlist = []
51
+ let parts = rm_ctl_tmpl.split('${')
52
+ if ( parts.length ) {
53
+ for ( let i = 1; i < parts.length; i++ ) {
54
+ let var_head = parts[i]
55
+ var_head = var_head.substr(0,var_head.indexOf('}'))
56
+ if ( varset[var_head] !== undefined ) {
57
+ varset[var_head]++
58
+ } else {
59
+ varset[var_head] = 1
60
+ }
61
+ }
62
+ }
63
+ varlist = varlist.concat(Object.keys(varset))
64
+ return varlist
65
+ }
66
+
67
+
68
+ function subst_vars(tmplt,srcObj) {
69
+ let var_list = extract_vars(tmplt)
70
+ let result = [tmplt]
71
+ if ( var_list.length ) {
72
+ var_list.forEach(aVar => {
73
+ let value = srcObj
74
+ let vaccess = aVar.split('.')
75
+ while ( vaccess.length ) {
76
+ let key = vaccess.shift()
77
+ if ( ( key === '$keys()' ) && ( typeof value === 'object' ) ) {
78
+ if ( value.length ) {
79
+ let vstore = []
80
+ value.forEach(val => {
81
+ for ( let k in val ) {
82
+ vstore.push(val[k])
83
+ }
84
+ })
85
+ value = vstore
86
+ } else {
87
+ let vstore = []
88
+ for ( let k in value ) {
89
+ vstore.push(value[k])
90
+ }
91
+ value = vstore
92
+ }
93
+ } else {
94
+ if ( ( typeof value === 'object' ) && value.length ) {
95
+ let nvalue = value.map(vobj => {
96
+ return(vobj[key] !== undefined ? vobj[key] : '' )
97
+ })
98
+ value = nvalue
99
+ } else {
100
+ value = value[key]
101
+ }
102
+ }
103
+ }
104
+ if ( typeof value === 'string' ) {
105
+ let finalResult = result.map( rtmplt => rtmplt.replace('${' + aVar + '}',value) )
106
+ result = finalResult
107
+ } else if ( ( typeof value === 'object' ) && value.length ) {
108
+ let nresult = []
109
+ value.forEach(val => {
110
+ let finalResult = result.map( rtmplt => rtmplt.replace('${' + aVar + '}',val) )
111
+ nresult = nresult.concat(finalResult)
112
+ })
113
+ result = nresult
114
+ }
115
+ })
116
+ }
117
+ return(result)
118
+ }
119
+
120
+
121
+ // extracToVar
122
+ // -------------------- -------------------- -------------------- --------------------
123
+ // Picks a section of a file and puts a variable in its place.
124
+ // Saves the extracted part for later restoring it to the place of the variable
125
+ // This is useful in file compressions since some HTML pages stop working if certain sections are compressed.
126
+ // For example: some plugin code for menu expansion fails if <ul> elements are not on separate lines.
127
+ //
128
+ function extracToVar(replVar,head_region,tail_region,fileString) {
129
+ let results = ['','']
130
+ //
131
+ let [header,rest] = fileString.split(head_region,2)
132
+ if ( header === undefined || rest === undefined ) {
133
+ return [undefined,undefined]
134
+ }
135
+ let end_parts = rest.split(tail_region)
136
+ if ( end_parts === undefined ) {
137
+ return [undefined,undefined]
138
+ }
139
+ //
140
+ console.log(end_parts.length)
141
+ let salvaged = end_parts.shift()
142
+ let backend = end_parts.join(tail_region)
143
+ //
144
+ results[0] = header + replVar + backend
145
+ results[1] = salvaged
146
+ //
147
+ return(results)
148
+ }
149
+
150
+
151
+ // ensureExists
152
+ // does what it says.
153
+ function ensureExists(path, mask) {
154
+ if (typeof mask == 'undefined') { // allow the `mask` parameter to be optional
155
+ cb = mask;
156
+ mask = 0777;
157
+ }
158
+ var p = new Promise((resolve,reject) => {
159
+ fs.mkdir(path, mask, function(err) {
160
+ if (err) {
161
+ if (err.code == 'EEXIST') resolve(null); // ignore the error if the folder already exists
162
+ else reject(err); // something else went wrong
163
+ } else resolve(null); // successfully created folder
164
+ });
165
+
166
+ })
167
+ return p
168
+ }
169
+
170
+ function ensurePathExists(path,mask) {
171
+ let where_all = path.split('/')
172
+ where = '.'
173
+ where_all.forEach(async level => {
174
+ where += '/' + level
175
+ try {
176
+ await ensureExists(`./${where}`,mask)
177
+ } catch (e) {
178
+ if (e.code != 'EEXIST') {
179
+ console.log(e)
180
+ }
181
+ }
182
+ })
183
+ return(where)
184
+ }
185
+
186
+
187
+ function instantiate_top_level(obj,directives) {
188
+ for ( let ky in obj ) {
189
+ let val = obj[ky]
190
+ if ( typeof val === 'string' ) {
191
+ if ( (val[0] === '@') && (val[0] !== '/') ) {
192
+ val = val.replace(val,directives[val])
193
+ }
194
+ }
195
+ obj[ky] = val
196
+ }
197
+ }
198
+
199
+ function subst_var(templt,substs) {
200
+ let output = templt
201
+ for ( let subst in substs ) {
202
+ let val = substs[subst]
203
+ let the_var = "${" + subst + "}"
204
+ let update = output.replace(the_var,val)
205
+ while ( update !== output ) {
206
+ output = update
207
+ update = output.replace(the_var,val)
208
+ }
209
+ }
210
+ return(output)
211
+ }
212
+
213
+
214
+ function calc_var(singlevar_calc,val) {
215
+ try {
216
+ let parts = singlevar_calc.split(':')
217
+ let the_var = parts[0]
218
+ let the_form = parts[1]
219
+ the_form = the_form.replace(the_var,val)
220
+ let vv = ''
221
+ the_form = 'vv = ' + the_form
222
+ eval(the_form)
223
+ return(vv)
224
+ } catch (e) {
225
+ console.log(e)
226
+ }
227
+ return('')
228
+ }
229
+
230
+ function drop_s(str) {
231
+ let c = str[str.length-1]
232
+ if ( c === 's' ) {
233
+ str = str.substr(0,str.length-1)
234
+ }
235
+ return(str)
236
+ }
237
+
238
+ // ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
239
+
240
+ async function output_nginx_dom_conf(dom_config,output) {
241
+ let where = dom_config.conf_loc
242
+ where = ensurePathExists(where)
243
+ where += dom_config.conf
244
+ fs.writeFileSync(where,output)
245
+ }
246
+
247
+ function nginx_releaser(config) {
248
+ if ( config === undefined ) {
249
+ console.warn("nginx cannot be configured")
250
+ return;
251
+ }
252
+ let conf_file_template_name = config.templates.top.src
253
+ let location_tmplt_name = config.templates.location.src
254
+ config.templates.top.text = fs.readFileSync(conf_file_template_name,'ascii').toString()
255
+ config.templates.location.text = fs.readFileSync(location_tmplt_name,'ascii').toString()
256
+ config.templates.ws_path = config.templates.top // @top to be calculated at some later date
257
+ //
258
+ for ( let tmpl in config.templates ) {
259
+ let template = config.templates[tmpl]
260
+ template.vars = extract_vars(template.text)
261
+ }
262
+ //
263
+ let map_calc = config.calc_maps
264
+ let plurals = map_calc.plurals
265
+ //
266
+ // not catching this exception
267
+ let doms = config.domains
268
+ for ( let dom in doms ) {
269
+ let domdef = doms[dom]
270
+ instantiate_top_level(domdef,{ "@key" : dom })
271
+ }
272
+ //
273
+ let conf_file_vars = config.templates.top.vars
274
+ //
275
+ for ( let dom in doms ) {
276
+ for ( let ky in config.templates ) {
277
+ let tmplt = config.templates[ky]
278
+ tmplt.output = tmplt.text
279
+ }
280
+ let domdef = doms[dom]
281
+ plurals.forEach(items => {
282
+ if ( conf_file_vars.indexOf(items) >= 0 ) {
283
+ if ( domdef[items] !== undefined ) {
284
+ let def_list = domdef[items]
285
+ let singlevar_calc = map_calc.single
286
+ let defKeys = Object.keys(def_list)
287
+ let item_var = calc_var(singlevar_calc,items)
288
+ let val_var = map_calc.single_var
289
+ let templt = config.templates[item_var].output
290
+ let vars = config.templates[item_var].vars
291
+ let expanded = defKeys.map(item => {
292
+ let val = def_list[item]
293
+ let substs = {}
294
+ substs[item_var] = item
295
+ substs[val_var] = val
296
+ let output = subst_var(templt,substs)
297
+ return(output)
298
+ })
299
+ let text = config.templates.top.output
300
+ let substs = {}
301
+ substs[items] = expanded.join('\n')
302
+ text = subst_var(text,substs)
303
+ config.templates.top.output = text
304
+ }
305
+ } else {
306
+ let def_list = domdef[items]
307
+ let singlevar_calc = map_calc.single
308
+ let defKeys = Object.keys(def_list)
309
+ let one_key = defKeys[0]
310
+ let item_var = calc_var(singlevar_calc,items)
311
+ if ( conf_file_vars.indexOf(item_var) >= 0 ) {
312
+ let templt = config.templates[item_var].output
313
+ let val = def_list[one_key]
314
+ let val_var = map_calc.single_var
315
+ let substs = {}
316
+ substs[item_var] = one_key
317
+ substs[val_var] = val
318
+ let output = subst_var(templt,substs)
319
+ config.templates[item_var].output = output
320
+ //
321
+ }
322
+ }
323
+ })
324
+ //
325
+ // done with plurals
326
+ for ( let defky in domdef ) {
327
+ if ( plurals.indexOf(defky) < 0 ) {
328
+ let val = domdef[defky]
329
+ let text = config.templates.top.output
330
+ substs = {}
331
+ substs[defky] = val
332
+ text = subst_var(text,substs)
333
+ config.templates.top.output = text
334
+ }
335
+ }
336
+
337
+ output_nginx_dom_conf(config.domains[dom],config.templates.top.output)
338
+
339
+ } // end of a dom
340
+ }
341
+
342
+
343
+ function prepare_entry_points(entry_points,nginx) {
344
+ let configs = entry_points.configs
345
+ let nginx_prefix = entry_points.config_key_prefix.split('.')
346
+ let nginx_path = nginx_prefix.map(entry => {
347
+ let key = entry.trim()
348
+ if ( key[0] === '(' ) {
349
+ key = key.replace('-','.').replace('-','.').replace('-','.').replace('-','.')
350
+ key = key.substr(1,key.length-2)
351
+ }
352
+ return(key)
353
+ })
354
+ for ( let confky in configs ) {
355
+ let conf = configs[confky]
356
+ let file = conf.file
357
+ delete conf.file
358
+ let service_conf_obj = fs.readFileSync(file,'ascii').toString()
359
+ service_conf_obj = JSON.parse(service_conf_obj)
360
+ //
361
+ for ( let ky in conf ) {
362
+ //
363
+ let val = nginx
364
+ let path = nginx_path.concat([])
365
+ let accessor = path.concat(conf[ky].split('.'))
366
+ accessor.forEach(fld => {
367
+ val = val[fld]
368
+ })
369
+ service_conf_obj[ky] = val
370
+ }
371
+ let rel_dir = entry_points.configs_release_dir
372
+ rel_dir = ensurePathExists(rel_dir)
373
+ file = rel_dir + '/' + file
374
+ let output = JSON.stringify(service_conf_obj,null,2)
375
+ fs.writeFileSync(file,output)
376
+ }
377
+ }
378
+
379
+
380
+ function compress_html_file(compressable) {
381
+ let result = minify(compressable, {
382
+ removeAttributeQuotes: false,
383
+ caseSensitive : true,
384
+ collapseWhitespace : true,
385
+ conservativeCollapse : true,
386
+ html5 : true,
387
+ keepClosingSlash : true,
388
+ minifyCSS : true,
389
+ minifyJS : true,
390
+ sortClassName : true
391
+ });
392
+ return result
393
+ }
394
+
395
+ async function compress_javascript_file(html_scripts) {
396
+ let parts = html_scripts.split('<script>') // very special case
397
+ let c_parts = [ parts.shift() ]
398
+ let n = parts.length
399
+ for ( let i = 0; i < n; i++ ) {
400
+ let script_n_rest = parts[i]
401
+ let end_script = script_n_rest.indexOf('</script>')
402
+ let script = script_n_rest.substr(0,end_script)
403
+ let follow = script_n_rest.substr(end_script)
404
+ let c_script_rslt = await Terser.minify(script, { mangle: false, ecma: 8 })
405
+ let c_script = c_script_rslt.code
406
+ let result = c_script + follow
407
+ c_parts.push(result)
408
+
409
+ }
410
+ let reconstructed = c_parts.join('<script>\n')
411
+ return(reconstructed)
412
+ }
413
+
414
+ // var g_siteURL = "localhost";
415
+ async function prepareHtmlFile(filePath,dmn) {
416
+ //
417
+ let url = dmn
418
+ ///
419
+ let fileString = fs.readFileSync(filePath,'utf8').toString()
420
+ fileString = fileString.replace('var g_siteURL = "localhost";',`var g_siteURL = "${url}";`)
421
+ fileString = fileString.replace('var g_siteURL = "localhost";',`var g_siteURL = "${url}";`)
422
+
423
+ // loop this
424
+ fileString = fileString.replace('localhost:',`${url}:`)
425
+ fileString = fileString.replace('localhost:',`${url}:`)
426
+ fileString = fileString.replace('localhost:',`${url}:`)
427
+ fileString = fileString.replace('localhost:',`${url}:`)
428
+ fileString = fileString.replace('localhost:',`${url}:`)
429
+ fileString = fileString.replace('localhost:',`${url}:`)
430
+
431
+ //
432
+ let pure_region_spec = g_releaseObject.dont_compress
433
+ let replVar = pure_region_spec.replace_var
434
+ let head_region = pure_region_spec.match_head
435
+ let tail_region = pure_region_spec.match_tail
436
+
437
+ let [compressable,salvaged] = extracToVar(replVar,head_region,tail_region,fileString)
438
+ if ( (compressable === undefined) || (salvaged === undefined) ) {
439
+ return
440
+ }
441
+ //
442
+ salvaged = head_region + salvaged + tail_region
443
+ //
444
+ fileString = compress_html_file(compressable)
445
+ fileString = fileString.replace(replVar,salvaged)
446
+ //
447
+ fileString = await compress_javascript_file(fileString)
448
+ //
449
+ fs.writeFileSync(filePath,fileString)
450
+ }
451
+
452
+ function process_remote_control() {
453
+ return(subst_vars(g_releaseObject.remote_control,g_releaseObject)[0])
454
+ }
455
+
456
+ /*
457
+ // testing for future ref... ignore
458
+ function process_remote_locations() {
459
+ return(subst_vars(g_releaseObject.remote_html,g_releaseObject))
460
+ }
461
+ function process_micro_servs_locations() {
462
+ return(subst_vars(g_releaseObject.remote_micros,g_releaseObject))
463
+ }
464
+ // // // // // // // // // // // // // // // //
465
+ var rm_command = process_remote_control()
466
+ console.log(rm_command)
467
+
468
+ var rm_locations = process_remote_locations()
469
+ console.log(rm_locations)
470
+
471
+ var micros_locations = process_micro_servs_locations()
472
+ console.log(micros_locations)
473
+ */
474
+
475
+ var g_html_web_directories = []
476
+
477
+ async function locate_html_directory(conf) {
478
+
479
+ let nginx_loc = conf.conf_location
480
+ let cmd = `grep -rpE 'root\\s+/' ${nginx_loc}/*.conf`
481
+ try {
482
+ const { stdout, stderr } = await asyc_exec(cmd)
483
+
484
+ let lines = stdout.split('\n')
485
+ let good_line = lines.filter(line => {
486
+ if ( line.length == 0 ) return(false)
487
+ line = line.split(':')[1]
488
+ let l = line.trim()
489
+ return(l[0] !== '#')
490
+ })
491
+
492
+ g_html_web_directories = good_line.map(line => {
493
+ line = line.split(':')[1].trim()
494
+ line = line.replace('root','')
495
+ line = line.trim()
496
+ line = line.replace(';','')
497
+ return(line)
498
+ })
499
+ } catch (e) {
500
+
501
+ }
502
+
503
+ console.log(g_html_web_directories)
504
+
505
+ // /etc/nginx/sites-enabled/default: root /var/www/html;
506
+ // /etc/nginx/sites-enabled/popsongnow.conf: root /var/www/html/popsongnow;
507
+
508
+ }
509
+
510
+
511
+ async function stage_html() {
512
+ let releaseDir = g_releaseObject.staging.folder
513
+ try {
514
+ await ensureExists(`./${releaseDir}` )
515
+ fs.copyFileSync(`${g_config_file}`,`./${releaseDir}/${g_config_file}`)
516
+ Object.keys(g_releaseObject.domains).forEach (async dmn => {
517
+ try {
518
+ let directive = g_releaseObject.domains[dmn]
519
+ if ( directive.html ) {
520
+ await ensureExists(`./${releaseDir}/${dmn}`)
521
+ console.dir(directive)
522
+ let srcpath = directive.html.from
523
+ let files = directive.html.files
524
+ if ( (files === undefined) && (undefined !== directive.html.file) ) {
525
+ files = [directive.html.file]
526
+ }
527
+ files.forEach (file => {
528
+ let filename = `${file}.html`
529
+ let destFile = `./${releaseDir}/${dmn}/${filename}`
530
+ fs.copyFileSync(`${srcpath}/${filename}`,destFile)
531
+ try {
532
+ prepareHtmlFile(destFile,dmn)
533
+ } catch (e) {
534
+ console.error(e)
535
+ }
536
+ })
537
+ }
538
+ } catch (e) {
539
+ console.error(e)
540
+ }
541
+ })
542
+ let static_folders = g_releaseObject.staging.statics
543
+ let cmd = `cp -R ${static_folders} ./${releaseDir}/${static_folders}/`
544
+ await asyc_exec(cmd)
545
+ //fs.copyDir
546
+ } catch(e) {
547
+ console.error(e)
548
+ }
549
+ }
550
+
551
+
552
+ async function stage_private_files(staging) {
553
+ let releaseDir = staging.folder
554
+ try {
555
+ await ensureExists(`./${releaseDir}`)
556
+ let dirs_defs = staging.private_dirs
557
+ for ( let dir in dirs_defs ) {
558
+ let dir_def = dirs_defs[dir]
559
+ let path = dir_def.path
560
+ let to_release = path.to ? path.to : dir
561
+ to_release = `./${releaseDir}/${to_release}`
562
+ let cmd = `cp -R ./${path} ./${to_release}/`
563
+ await asyc_exec(cmd)
564
+ }
565
+ } catch(e) {
566
+ console.error(e)
567
+ }
568
+ }
569
+
570
+
571
+ async function stage_micros() {
572
+ //
573
+ let releaseDir = g_releaseObject.staging.folder
574
+ try {
575
+ await ensureExists('./' + releaseDir)
576
+ Object.keys(g_releaseObject.domains).forEach (async dmn => {
577
+ try {
578
+ await ensureExists('./' + releaseDir + '/' + dmn)
579
+ await ensureExists('./' + releaseDir + '/' + dmn + '/home')
580
+ let dest = './' + releaseDir + '/' + dmn + '/home'
581
+ //
582
+ let directive = g_releaseObject.domains[dmn]
583
+ let srcpath = directive.micros.from
584
+ let file_map = directive.micros.files
585
+ let file_list = Object.keys(file_map)
586
+ //
587
+ file_list.forEach(async filename => {
588
+ if ( file_map[filename] ) {
589
+ let path = srcpath + '/' + filename
590
+ fs.copyFileSync(path,dest + '/' + filename)
591
+ }
592
+ })
593
+ //
594
+ let node_modules_src = srcpath + '/node_modules'
595
+ let module_dest = dest + '/node_modules'
596
+ await ensureExists(module_dest)
597
+ //
598
+ let special_node_modules = g_releaseObject.staging.special_node_modules
599
+ special_node_modules.forEach(async mod => {
600
+ await ensureExists(module_dest + `/${mod}`)
601
+ let mod_dest_file = `/${mod}/index.js`
602
+ fs.copyFileSync(node_modules_src + mod_dest_file,module_dest + mod_dest_file)
603
+ })
604
+ //
605
+ let spec_content_list = g_releaseObject.staging.special_content
606
+ spec_content_list.forEach(spc_content => {
607
+ let file = spc_content.file
608
+ let content_txt = spc_content.text
609
+ fs.writeFileSync(dest + `/${file}`,content_txt)
610
+ })
611
+ //
612
+ } catch (e) {
613
+ console.error(e)
614
+ }
615
+ })
616
+ } catch(e) {
617
+ console.error(e)
618
+ }
619
+ }
620
+
621
+
622
+ async function zip_release() {
623
+ let releaseDir = g_releaseObject.staging.folder
624
+ await tar.c(
625
+ {
626
+ gzip: true,
627
+ file: releaseDir + '.tgz'
628
+ },
629
+ [releaseDir]
630
+ )
631
+ }
632
+
633
+ async function upload_release() {
634
+ let releaseFile = g_releaseObject.staging.folder + '.tgz'
635
+ //let bashline = `scp ${releaseFile} ${dest_machine}:/home`
636
+ //await run_bash(bashline)
637
+
638
+ const c = await scp({
639
+ host: g_releaseObject.target.host,
640
+ port: 22,
641
+ username: g_releaseObject.target.user,
642
+ password: `${g_ssh_pass}`,
643
+ })
644
+ await c.uploadFile(releaseFile, '/home/release.tgz')
645
+ c.close() // remember to close connection after you finish
646
+ }
647
+
648
+
649
+ async function gen_bash_script() {
650
+ //
651
+ //
652
+ let script = ["pushd /home"]
653
+ let releaseDir = g_releaseObject.staging.folder
654
+ let repository_dir = g_releaseObject.staging.repository
655
+ if ( g_repeat_process ) {
656
+ script.push(`rm -r "${releaseDir}`)
657
+ script.push(`if [ -d "${releaseDir}-backup"]; then`)
658
+ script.push(` mv -r ${releaseDir}-backup ${releaseDir}`)
659
+ script.push(`fi`)
660
+ }
661
+ //
662
+ script.push(`mv ${releaseDir} ${releaseDir}-backup`)
663
+ script.push(`mkdir ${releaseDir}-backup/sites-enabled`)
664
+ script.push(`mkdir ${releaseDir}-backup/html`)
665
+ script.push(`cp ecosystem.config.js ${releaseDir}-backup`)
666
+ script.push(`cp /etc/nginx/sites-enabled/* ${releaseDir}-backup/sites-enabled/`)
667
+ script.push(`cp -R /var/www/html/* ${releaseDir}-backup/html/`)
668
+ script.push(`tar xf ${releaseDir}.tgz`)
669
+ script.push(`rm ${releaseDir}.tgz`)
670
+ //
671
+ script.push(`bash ${releaseDir}/boot_it.sh ${repository_dir}`)
672
+ script.push(`cp ${releaseDir}/ecosystem.config.js ./${repository_dir}`)
673
+ script.push(`pushd ${repository_dir}`)
674
+ script.push('pm2 stop all')
675
+ script.push('pm2 start ecosystem.config.js')
676
+ script.push('popd')
677
+ script.push('popd')
678
+ //
679
+ let out_script = script.join('\n')
680
+ try {
681
+ await ensureExists('./' + releaseDir)
682
+ fs.writeFileSync('./releaser.sh',out_script)
683
+ } catch(e) {
684
+ console.error(e)
685
+ }
686
+ //
687
+ }
688
+
689
+
690
+ async function output_ecosystem(micros,nginx) {
691
+ // first generate ecosystem
692
+ let releaseDir = g_releaseObject.staging.folder
693
+ fs.copyFileSync("tools/boot_it.sh",`${releaseDir}/boot_it.sh` )
694
+ //
695
+ let ecosystem = ''
696
+ let allapps = []
697
+ let nginx_prefix = micros.config_key_prefix.split('.')
698
+ let nginx_path = nginx_prefix.map(entry => {
699
+ let key = entry.trim()
700
+ if ( key[0] === '(' ) {
701
+ key = key.replace('-','.').replace('-','.').replace('-','.').replace('-','.')
702
+ key = key.substr(1,key.length-2)
703
+ }
704
+ return(key)
705
+ })
706
+ try {
707
+ await ensureExists('./' + releaseDir)
708
+ let runners = micros.runners
709
+ for ( let rnr in runners ) {
710
+ let rdef = runners[rnr]
711
+ let jsfile = micros[rdef.run]
712
+ let argvs = rdef.argv.map(arg => {
713
+ if ( arg[0] === '@' ) {
714
+ let ky_path = arg.substr(1)
715
+ //
716
+ let val = nginx
717
+ let path = nginx_path.concat([])
718
+ let accessor = path.concat(ky_path.split('.'))
719
+ accessor.forEach(fld => {
720
+ val = val[fld]
721
+ })
722
+ arg = val
723
+ }
724
+ return(arg)
725
+ })
726
+ //
727
+ let params = argvs.join(' ')
728
+ //
729
+ let appOb = {
730
+ "name" : rnr,
731
+ "cwd" : `/home/${micros.repository}`,
732
+ "script" : `node ${jsfile} ${params}`,
733
+ "watch" : true,
734
+ "env": {
735
+ "NODE_ENV": "development",
736
+ },
737
+ "env_production" : {
738
+ "NODE_ENV": "production"
739
+ }
740
+ }
741
+ allapps.push(appOb)
742
+ }
743
+
744
+ //
745
+ allapps = JSON.stringify(allapps,null,2)
746
+ ecosystem = `module.exports = { apps : ${allapps} }`
747
+ //
748
+ fs.writeFileSync(`./${releaseDir}/ecosystem.config.js`,ecosystem)
749
+ //
750
+ } catch(e) {
751
+ console.error(e)
752
+ }
753
+
754
+ }
755
+
756
+ function run_releaser() {
757
+ let rm_ctl_command = process_remote_control()
758
+ console.log(rm_ctl_command)
759
+ exec(rm_ctl_command,(err,stdout,stderr) => {
760
+ if ( err ) {
761
+ console.error(stderr)
762
+ console.error(err)
763
+ } else {
764
+ console.log(stdout)
765
+ }
766
+ })
767
+ }
768
+
769
+ //
770
+ //locate_html_directory(g_releaseObject.nginx)
771
+ //nginx_releaser(g_releaseObject.nginx)
772
+ //prepare_entry_points(g_releaseObject.micros,g_releaseObject.nginx)
773
+ stage_html()
774
+ //stage_private_files(g_releaseObject.staging)
775
+ /*stage_micros()*/
776
+ //output_ecosystem(g_releaseObject.micros,g_releaseObject.nginx)
777
+ //gen_bash_script()
778
+ //zip_release()
779
+ //upload_release()
780
+ //run_releaser()
781
+ ///
782
+ /*
783
+
784
+
785
+ npm install mime
786
+
787
+
788
+ pm2 ls
789
+ pm2 stop 0
790
+ pm2 start express-captcha.js
791
+ pm2 start express-signup.js.js
792
+ pm2 restart 0
793
+
794
+ # Start all applications
795
+ pm2 start ecosystem.config.js
796
+
797
+ # Start only the app named worker-app
798
+ pm2 start ecosystem.config.js --only worker-app
799
+
800
+ # Stop all
801
+ pm2 stop ecosystem.config.js
802
+
803
+ # Restart all
804
+ pm2 start ecosystem.config.js
805
+ ## Or
806
+ pm2 restart ecosystem.config.js
807
+
808
+ # Reload all
809
+ pm2 reload ecosystem.config.js
810
+
811
+ # Delete all
812
+ pm2 delete ecosystem.config.js
813
+
814
+ */