roll-right 0.0.1 → 0.1.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.
- package/README.md +55 -10
- package/bin/breakup.js +56 -0
- package/bin/index.js +107 -4
- package/index.js +1 -1
- package/lib/mod_utils.js +79 -0
- package/lib/phase1.js +445 -0
- package/lib/phase2.js +77 -0
- package/lib/rr_utils.js +128 -8
- package/lib/to_export.js +39 -0
- package/lib/utils.js +97 -0
- package/package.json +11 -2
- package/tools/affiliates.js +132 -0
- package/tools/allgen.sh +20 -0
- package/tools/charwindow.js +17 -0
- package/tools/filter_requires.js +60 -0
- package/tools/genpage.js +141 -0
- package/tools/npm_much.sh +57 -0
- package/tools/prep_body_insert_only.js +28 -0
- package/tools/releasepages.js +814 -0
- package/tools/rungen.sh +6 -0
- package/tools/rungen_dashboard.sh +5 -0
- package/tools/rungen_header_shell.sh +5 -0
- package/tools/rungen_paramed_shell.sh +12 -0
- package/tools/rungen_profile.sh +5 -0
- package/tools/web_files.js +149 -0
- package/transform.js +490 -0
- package/roll_right.js +0 -96
|
@@ -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
|
+
*/
|