| const http = require('http'); | const http = require('http'); | ||||
| const { Console } = require('console'); | const { Console } = require('console'); | ||||
| const { env } = require('process'); | const { env } = require('process'); | ||||
| const PATTERNAPI = require('serververse').PATTERNAPI | |||||
| // const RESTAPI = require('serververse').RESTAPI | |||||
| const RESTAPI = (function(){ | const RESTAPI = (function(){ | ||||
| // Singleton | // Singleton | ||||
| } | } | ||||
| var hasElxrSync = function(path){ return hasElxr(path, { sync :true}); } | var hasElxrSync = function(path){ return hasElxr(path, { sync :true}); } | ||||
| var uselauncdirasdefaultroot = false; | |||||
| if( ENV.NODE_ENV === 'production') uselauncdirasdefaultroot = true; | |||||
| // PB : TODO -- enable for for production. | |||||
| var thisscriptdir = path.normalize(__dirname); // PB : TODO -- Thisscriptdir could be dislocated when run as a standalone file... We need to detect this where and how | var thisscriptdir = path.normalize(__dirname); // PB : TODO -- Thisscriptdir could be dislocated when run as a standalone file... We need to detect this where and how | ||||
| var root = process.cwd() // Root need not be the launchdir... | |||||
| var root = undefined // process.cwd() // Root need not be the launchdir... | |||||
| // we typicall assume the cwd to be the root. However this should default to | |||||
| // elxr parent if the root is not recongnizable as an instance root.... | |||||
| // wd is our own environment variable probably corresponding to the root but need not be the same. | // wd is our own environment variable probably corresponding to the root but need not be the same. | ||||
| // console.log(processedArgs.root) | // console.log(processedArgs.root) | ||||
| // console.log('PWD :' + ENV.PWD) | // console.log('PWD :' + ENV.PWD) | ||||
| // console.log('cwd : ' + process.cwd()) | // console.log('cwd : ' + process.cwd()) | ||||
| // console.log('launchscriptdir : ' + path.normalize(__dirname)) | // console.log('launchscriptdir : ' + path.normalize(__dirname)) | ||||
| if(!processedArgs.root){ | |||||
| if(!process.env.wd){ | |||||
| console.log('discovery') | |||||
| // Script may exists in the same location where we were launched(PWD) but that doesn't mean we r running from elxr. | |||||
| // script could have been copied tosome random location and run from there. | |||||
| // check elxr is preinstalled in same location. If so we need to chdir to parent. Else promt for confirmation of root. | |||||
| var launchdir = /*process.env.PWD ||*/ process.cwd() // mingw + node --inspect-brk behaves differently has a PWD that windows commands cannot recognize /d instead of D:\ and process.chdir fails.. | |||||
| var parentdir = path.dirname( launchdir ) | |||||
| var parentFolderHasElxr = hasElxrSync(parentdir) | |||||
| var launchFolderHasElxr = hasElxrSync(launchdir) | |||||
| if( parentFolderHasElxr && (path.normalize(parentdir + '/elxr') === thisscriptdir)) { | |||||
| // We were run from the proper root with elxr cli in the subfolder. | |||||
| // PB : TODO -- Cleanup this should no longer be needed... selectedinstance is properly initialized... | |||||
| // instanceroot = root = selectedinstance.root; | |||||
| // instanceoptions.splice( 0, 0, detected = { root }) | |||||
| // instanceoptions.splice( 0, 0, detectfromroot(root)) | |||||
| root = ENV.wd = parentdir; // Default to the parent. | |||||
| console.log('----------------------------------------------------------------') | |||||
| console.log('BEFORE DISCOVERY') | |||||
| console.log('version : ' + getVersion()); | |||||
| console.log('process.env.wd : ' + process.env.wd) | |||||
| console.log('processedArgs.root : ' + processedArgs.root) | |||||
| console.log('----------------------------------------------------------------') | |||||
| console.log('wd :' + ENV.wd) | |||||
| console.log('PWD :' + ENV.PWD) | |||||
| console.log('cwd : ' + process.cwd()) | |||||
| console.log(`thisscriptdir = ${thisscriptdir}`) | |||||
| console.log(`root = ${root}`) | |||||
| console.log(`instanceroot = ${instanceroot}`) | |||||
| console.log('----------------------------------------------------------------') | |||||
| if(!processedArgs.root){ // There is no runtime invoke time named args override. | |||||
| console.log('discovery') | |||||
| // Script may exists in the same location where we were launched(PWD) but that doesn't mean we r running from elxr. | |||||
| // script could have been copied tosome random location and run from there. | |||||
| // check elxr is preinstalled in same location. If so we need to chdir to parent. Else promt for confirmation of root. | |||||
| var launchdir = /*process.env.PWD ||*/ process.cwd() // mingw + node --inspect-brk behaves differently has a PWD that windows commands cannot recognize /d instead of D:\ and process.chdir fails.. | |||||
| var parentdir = path.dirname( launchdir ) | |||||
| var parentFolderHasElxr = hasElxrSync(parentdir) | |||||
| var launchFolderHasElxr = hasElxrSync(launchdir) | |||||
| if( path.normalize(launchdir + '/elxr') === thisscriptdir ) { | |||||
| // launchFolderHasElxr is false -- and yet thiscriptdir is still proper. | |||||
| if(!launchFolderHasElxr) { | |||||
| console.warn('Warning : detected thisscriptdir as subfolder but did not recognize launchdir as a proper root. elxr may not autoupdate...') | |||||
| // hasElxr checks for git repo status and elxr id stamping etc. | |||||
| // exlr tool may have been acquired unconventionally and we may not be able to manage it. | |||||
| // We will run anyway though | |||||
| } | } | ||||
| else { | |||||
| if( path.normalize(parentdir + '/elxr') === thisscriptdir ) { | |||||
| // launchFolderHasElxr is false -- and yet thiscriptdir is still proper. | |||||
| // PB : TODO -- Maybe a warning / abort if for some reason thisscriptdir should not be used... | |||||
| console.error('Warning : detected thisscriptdir as elxr subfolder but not recognized as elixir. git updates might fail.') | |||||
| // instanceoptions.splice( 0, 0, detected = { root }) | |||||
| // instanceoptions.splice( 0, 0, detectfromroot(root)) | |||||
| root = ENV.wd = launchdir; | |||||
| } | |||||
| else if( path.normalize(parentdir + '/elxr') === thisscriptdir ) { | |||||
| if(!parentFolderHasElxr) { | |||||
| console.warn('Warning : detected thisscriptdir as subfolder but did not recognize parentdir as a proper root. elxr may not autoupdate...') | |||||
| } | |||||
| // PB : TODO -- Cleanup this should no longer be needed... selectedinstance is properly initialized... | |||||
| root = ENV.wd = parentdir; // Default to the parent. | |||||
| } | |||||
| else { | |||||
| if (launchdir === thisscriptdir) { | |||||
| // Same directory doesn't mean we are being run from elxr sub directory. It could be a dislocated standalone elxr script. | |||||
| // PB : TODO -- In case elxr is not full elxr we need to locate it and relaunch to switch to the full version... | |||||
| // if(!parentFolderHasElxr) console.error('Invalid run location in subfolder that looks like elxr. We should probably abort.') | |||||
| if (BUILD_VERSION.indexOf('Version: {version} - built on {date}') > -1) { | |||||
| // Confirmed we were run from an Unbuilt ( meaning non standalone ) elxr therefore we are in the elxr sub directory. | |||||
| root = ENV.wd = parentdir; // Default to the parent. | root = ENV.wd = parentdir; // Default to the parent. | ||||
| // instanceroot = root = path.normalize(selectedinstance.root + '/..'); | |||||
| // instanceoptions.splice( 0, 0, detected = { root }); | |||||
| // instanceoptions.splice( 0, 0, detectfromroot(root)); | |||||
| } | } | ||||
| else if (launchdir === thisscriptdir) { | |||||
| // Same directory doesn't mean we are being run from elxr sub directory. It could be a dislocated standalone elxr script. | |||||
| // PB : TODO -- In case elxr is not full elxr we need to locate it and relaunch to switch to the full version... | |||||
| // if(!parentFolderHasElxr) console.error('Invalid run location in subfolder that looks like elxr. We should probably abort.') | |||||
| if (BUILD_VERSION.indexOf('Version: {version} - built on {date}') > -1) { | |||||
| // Confirmed we were run from an Unbuilt ( meaning non standalone ) elxr therefore we are in the elxr sub directory. | |||||
| root = ENV.wd = parentdir; // Default to the parent. | |||||
| else if(!parentFolderHasElxr) { | |||||
| // Either case we use the launchdir. | |||||
| // if(launchFolderHasElxr) { | |||||
| // // Probably a standalone run. Lets just go with it | |||||
| // root = ENV.wd = launchdir; | |||||
| // } | |||||
| // instanceroot = root = path.normalize(selectedinstance.root + '/..'); | |||||
| // instanceoptions.splice( 0, 0, detected = { root }); | |||||
| // instanceoptions.splice( 0, 0, detectfromroot(root)); | |||||
| // In standalone build script we may or not be in the same location. | |||||
| // We could have been run from the elxr subfolder. However we cant say for sure. | |||||
| // Most likely that the built version isn't the full elxr. We assume elxr doesnt exist and create an new elxr under.. | |||||
| console.error('Warning : detected thisscriptdir as elxr subfolder but not recognized as elixir. git updates might fail.') | |||||
| root = ENV.wd = launchdir; | |||||
| } | } | ||||
| else { | else { | ||||
| // In standalone build script we may or not be in the same location. | |||||
| if(!parentFolderHasElxr) { | |||||
| // We could have been run from the elxr subfolder. However we cant say for sure. | |||||
| // Most likely that the built version isn't the full elxr. We assume elxr doesnt exist and create an new elxr under.. | |||||
| console.error('Warning : detected thisscriptdir as elxr subfolder but not recognized as elixir. git updates might fail.') | |||||
| root = ENV.wd = launchdir; | |||||
| } | |||||
| else { | |||||
| // Built version was run from the full elxr subfolder | |||||
| root = ENV.wd = parentdir; // Default to the parent. | |||||
| // instanceoptions.splice( 0, 0, detected = { root }) | |||||
| // instanceoptions.splice( 0, 0, detectfromroot(root)) | |||||
| // Assume current selectedinstance.root is a new instance and create. | |||||
| // Figure out the instnace name and environment from parent folders as an alternative option with confirmation if not provided in the arguments. | |||||
| // if(clioverrides.instanceName) { | |||||
| // if(clioverrides.node_env) { | |||||
| // instanceroot = root = path.normalize(selectedinstance.root + '/' + clioverrides.instanceName + '/' + clioverrides.node_env) | |||||
| // instanceoptions.splice( 0, 0, detected = { root, instanceName : clioverrides.instanceName, node_env : clioverrides.node_env }) | |||||
| // // instanceoptions.splice( 0, 0, detectfromroot(root)) // This can be an option but is unnecessary unless a confirmation is provided. | |||||
| // // also folder names may have no relation to the actual instanceName and instanceType coz we need to have many | |||||
| // // eg : floder name can be elixir01 but instance name is elixr | |||||
| // } | |||||
| // else { | |||||
| // instanceroot = root = path.normalize(selectedinstance.root + '/' + clioverrides.instanceName + '/' + 'development') | |||||
| // instanceoptions.splice( 0, 0, detected = { root, instanceName : clioverrides.instanceName, node_env : 'development' }) | |||||
| // instanceoptions.splice( 0, 0, detectfromroot(root)) // A recessive option only. | |||||
| // } | |||||
| // } | |||||
| // else { | |||||
| // instanceroot = root = selectedinstance.root; | |||||
| // if(clioverrides.node_env) { | |||||
| // instanceoptions.splice( 0, 0, detected = { root, node_env : clioverrides.node_env }) | |||||
| // instanceoptions.splice( 0, 0, detectfromroot(root)) | |||||
| // } | |||||
| // else { | |||||
| // // Nothing was specified... We only have one option from root. | |||||
| // instanceoptions.splice( 0, 0, detected = detectfromroot(launcpath)) | |||||
| // } | |||||
| // } | |||||
| } | |||||
| // Built version was run from the full elxr subfolder | |||||
| root = ENV.wd = parentdir; // Default to the parent. | |||||
| // instanceoptions.splice( 0, 0, detected = { root }) | |||||
| // instanceoptions.splice( 0, 0, detectfromroot(root)) | |||||
| // Assume current selectedinstance.root is a new instance and create. | |||||
| // Figure out the instnace name and environment from parent folders as an alternative option with confirmation if not provided in the arguments. | |||||
| // if(clioverrides.instanceName) { | |||||
| // if(clioverrides.node_env) { | |||||
| // instanceroot = root = path.normalize(selectedinstance.root + '/' + clioverrides.instanceName + '/' + clioverrides.node_env) | |||||
| // instanceoptions.splice( 0, 0, detected = { root, instanceName : clioverrides.instanceName, node_env : clioverrides.node_env }) | |||||
| // // instanceoptions.splice( 0, 0, detectfromroot(root)) // This can be an option but is unnecessary unless a confirmation is provided. | |||||
| // // also folder names may have no relation to the actual instanceName and instanceType coz we need to have many | |||||
| // // eg : floder name can be elixir01 but instance name is elixr | |||||
| // } | |||||
| // else { | |||||
| // instanceroot = root = path.normalize(selectedinstance.root + '/' + clioverrides.instanceName + '/' + 'development') | |||||
| // instanceoptions.splice( 0, 0, detected = { root, instanceName : clioverrides.instanceName, node_env : 'development' }) | |||||
| // instanceoptions.splice( 0, 0, detectfromroot(root)) // A recessive option only. | |||||
| // } | |||||
| // } | |||||
| // else { | |||||
| // instanceroot = root = selectedinstance.root; | |||||
| // if(clioverrides.node_env) { | |||||
| // instanceoptions.splice( 0, 0, detected = { root, node_env : clioverrides.node_env }) | |||||
| // instanceoptions.splice( 0, 0, detectfromroot(root)) | |||||
| // } | |||||
| // else { | |||||
| // // Nothing was specified... We only have one option from root. | |||||
| // instanceoptions.splice( 0, 0, detected = detectfromroot(launcpath)) | |||||
| // } | |||||
| // } | |||||
| } | } | ||||
| } | |||||
| else if(launchFolderHasElxr) { | |||||
| root = ENV.wd = launchdir; | |||||
| // instanceoptions.splice( 0, 0, detected = { root }) | |||||
| // instanceoptions.splice( 0, 0, detectfromroot(root)) | |||||
| } | |||||
| else { | |||||
| // Ambiguous but assume script is standalone in the instanceroot. | |||||
| root = ENV.wd = launchdir; | |||||
| } | |||||
| else if(launchFolderHasElxr) { | |||||
| root = ENV.wd = launchdir; | |||||
| // instanceoptions.splice( 0, 0, detected = { root }) | |||||
| // instanceoptions.splice( 0, 0, detectfromroot(root)) | |||||
| } | |||||
| else { | |||||
| // Ambiguous but assume script is standalone in the instanceroot | |||||
| // Lets defualt to the script parent assuming there is an instanceroot there. Hoever this should probably be a prompt where possible. | |||||
| // when we r in that mode. | |||||
| if(uselauncdirasdefaultroot) { | |||||
| // must be a new install in the selectedinstance.root with script invoked from some random location. | // must be a new install in the selectedinstance.root with script invoked from some random location. | ||||
| if(!process.env.wd){ | |||||
| // Working directory as a .env variable was not passed in. | |||||
| root = ENV.wd = launchdir; | |||||
| } | |||||
| else root = ENV.wd = process.env.wd | |||||
| } | |||||
| else { | |||||
| var scriptparent = path.dirname( thisscriptdir ) | |||||
| root = ENV.wd = scriptparent; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else root = ENV.wd = process.env.wd | |||||
| } | } | ||||
| else { | else { | ||||
| if(process.env.wd && process.env.wd !== processedArgs.root) throw 'wd and root must match.' | if(process.env.wd && process.env.wd !== processedArgs.root) throw 'wd and root must match.' | ||||
| ENV.NODE_ENV = processedArgs.node_env || (ENV.NODE_ENV && ENV.NODE_ENV.trim()) || 'development' | ENV.NODE_ENV = processedArgs.node_env || (ENV.NODE_ENV && ENV.NODE_ENV.trim()) || 'development' | ||||
| console.log('----------------------------------------------------------------') | console.log('----------------------------------------------------------------') | ||||
| console.log('AFTER DISCOVERY') | |||||
| console.log('version : ' + getVersion()); | console.log('version : ' + getVersion()); | ||||
| console.log('process.env.wd : ' + process.env.wd) | console.log('process.env.wd : ' + process.env.wd) | ||||
| console.log('processedArgs.root : ' + processedArgs.root) | console.log('processedArgs.root : ' + processedArgs.root) | ||||
| console.log('PWD :' + ENV.PWD) | console.log('PWD :' + ENV.PWD) | ||||
| console.log('cwd : ' + process.cwd()) | console.log('cwd : ' + process.cwd()) | ||||
| console.log(`thisscriptdir = ${thisscriptdir}`) | console.log(`thisscriptdir = ${thisscriptdir}`) | ||||
| console.log(`root = ${root}`) | |||||
| console.log(`instanceroot = ${instanceroot}`) | |||||
| console.log('----------------------------------------------------------------') | console.log('----------------------------------------------------------------') | ||||
| var cli = require('./cliverse') | var cli = require('./cliverse') | ||||
| , exludeMergeRepos : { } | , exludeMergeRepos : { } | ||||
| }; // PB : TODO -- Use initialized instance instead of __default everywhere. | }; // PB : TODO -- Use initialized instance instead of __default everywhere. | ||||
| var regexreplaceall = function(content, ps){ | |||||
| var repmatches | |||||
| var replaced = content; | |||||
| while (repmatches = ps.strOrregexp.exec(content)) { | |||||
| if(content.length > 0) { | |||||
| var replacement = repmatches[0] | |||||
| for(var m = 1; m < repmatches.length; m++) { | |||||
| replacement = replacement.replace(repmatches[m], ps.substitutes[m-1]) | |||||
| } | |||||
| replaced = replaced.replace( repmatches[0], replacement ) | |||||
| } | |||||
| } | |||||
| return replaced | |||||
| } | |||||
| var cmds = { | var cmds = { | ||||
| remote : { | |||||
| sqlpreprocess : { | |||||
| noprerequisites : true | |||||
| , cmdFn : function(args){ | |||||
| var sqlquery = fs.readFileSync(args._[1], { encoding: 'utf8'}) | |||||
| sqlquery = PATTERNAPI.includesql(sqlquery, path.dirname(args._[1])) | |||||
| fs.writeFileSync(args._[1] + '.d.sql', sqlquery, { encoding: 'utf8'}) | |||||
| return sqlquery | |||||
| // // PB : TODO -- move to dsql preprocesor | |||||
| // // var sqlquery = 'SET @dsql = @dsql + ' + "'" + ('' + fs.readFileSync(args._[1])).replace(/\'/g,"''") + "'" | |||||
| // var sqlquery = fs.readFileSync(args._[1], { encoding: 'utf8'}) | |||||
| // var regExp = /\-\-\s{{INCLUDE(.*?) ([\s\S]*?)}}\s\-\-/gm; | |||||
| // var options = {} | |||||
| // sqlquery = replacepatterns(sqlquery, regExp, (matches, sqlquery)=>{ | |||||
| // if (matches[1] === 'ASDSQL') options.dsql = true | |||||
| // var replacement = { | |||||
| // distinctpatterntoreplace : new RegExp("\\-\\-\\s{{INCLUDE\\s" + matches[2] + "}}\\s\\-\\-","gm") | |||||
| // , detectedvaluepattern : matches[2] | |||||
| // // escaped dsql... //'SET @dsql = @dsql + ' + "'" + ('' + fs.readFileSync(args._[1])).replace(/\'/g,"''") + "'" | |||||
| // } | |||||
| // if(options.dsql) replacement.substituedvalue = ('SET @dsql = @dsql + ' + "'" + ('' + fs.readFileSync(path.dirname(args._[1]) + '/' + matches[2])).replace(/\'/g,"''") + "'") | |||||
| // else replacement.substituedvalue = fs.readFileSync(path.dirname(args._[1]) + '/' + matches[2]) | |||||
| // sqlquery = sqlquery.replace(replacement.distinctpatterntoreplace, replacement.substituedvalue); | |||||
| // regExp.lastIndex = 0; | |||||
| // }) | |||||
| // // console.log(replaced) | |||||
| // fs.writeFileSync(args._[1] + '.d.sql', sqlquery, { encoding: 'utf8'}) | |||||
| } | |||||
| , toArgs : function( o ){ return o } | |||||
| , interpret() { return { cmd : processedArgs._.slice(0, 1) } } | |||||
| } | |||||
| , remote : { | |||||
| interpret() { return utils.assign_core( { keycase: true, arraymergetype : utils.assign_core.DISTINCT_UNION } | interpret() { return utils.assign_core( { keycase: true, arraymergetype : utils.assign_core.DISTINCT_UNION } | ||||
| , { cmd : processedArgs._.slice(0, 2).join(' '), runchoice : 'c' }) } | , { cmd : processedArgs._.slice(0, 2).join(' '), runchoice : 'c' }) } | ||||
| , noprerequisites : true | , noprerequisites : true | ||||
| , { cmd : 'start', runchoice : 'c' | , { cmd : 'start', runchoice : 'c' | ||||
| , node_env : ENV.NODE_ENV, root : ENV.wd, instanceType : ENV.NODE_ENV | , node_env : ENV.NODE_ENV, root : ENV.wd, instanceType : ENV.NODE_ENV | ||||
| })} | })} | ||||
| , toArgs : function( o ){ | |||||
| return o | |||||
| } | |||||
| } | } | ||||
| , 'remote refresh' : { | , 'remote refresh' : { | ||||
| // return a interpreted set of arguments for this cmd run context. | // return a interpreted set of arguments for this cmd run context. | ||||
| // } | // } | ||||
| // } | // } | ||||
| var regexreplaceall = function(content, ps){ | |||||
| var repmatches | |||||
| var replaced = content; | |||||
| while (repmatches = ps.strOrregexp.exec(content)) { | |||||
| if(content.length > 0) { | |||||
| var replacement = repmatches[0] | |||||
| for(var m = 1; m < repmatches.length; m++) { | |||||
| replacement = replacement.replace(repmatches[m], ps.substitutes[m-1]) | |||||
| } | |||||
| replaced = replaced.replace( repmatches[0], replacement ) | |||||
| } | |||||
| } | |||||
| return replaced | |||||
| } | |||||
| // filesystem walk | // filesystem walk | ||||
| const fswalk = async (pathToWalk, options, actions) => { | const fswalk = async (pathToWalk, options, actions) => { | ||||
| // options = options || { depthfirst : true } | // options = options || { depthfirst : true } |