Browse Source

Added commandoptions

production
guest 2 years ago
parent
commit
8b69622fd3
1 changed files with 199 additions and 179 deletions
  1. 199
    179
      index.js

+ 199
- 179
index.js View File

function getVersion() { return BUILD_VERSION; } function getVersion() { return BUILD_VERSION; }
console.log(getVersion()); console.log(getVersion());




// 'use strict'; // 'use strict';


// PB : TODO -- make sure folder context is proper coz we can now run elxr from anywhere. // PB : TODO -- make sure folder context is proper coz we can now run elxr from anywhere.
// } // }
// }) // })


var subcommandlabels = {
remote : (`remote ${processedArgs._[1] || ''}`).trim()
//

// elxr cli operations
var noprerequisites = {
add : true, 'set-url' : true, 'repo-relocate' : true
, remote : true, 'c' : true, 'h' : true
, httpget : true, getuser : true
, 'switch user' : true
, 'switch' : true
// , 'undefined' : true
} }


var interpretrun = function(){
var reconfirmcmds = { create : true }

var subcommandlabels = {
remote : (`remote ${processedArgs._[1] || ''}`).trim()
, switch : (`switch ${processedArgs._[1] || ''}`).trim()
}


var cmds = {
'remote' : function() {
var cmds = {
remote : {
// return a interpreted set of arguments for this comd run context.
interpret() {
return { cmd : subcommandlabels['remote'], runchoice : 'c' } return { cmd : subcommandlabels['remote'], runchoice : 'c' }
} }
} }
, switch : {
interpret() {
return { cmd : subcommandlabels['switch'], runchoice : 'c', username : processedArgs._[2]
, reposerver : __default.reposerver
}
}
, getPossiblePrompts(){ return { username : true, reposerver : 'http://git.bbh' } } // Requires only one argument...
}
, 'switch user' : {
interpret() {
return { cmd : subcommandlabels['switch'], runchoice : 'c', username : processedArgs._[2] }
}
, getPossiblePrompts(){ return { username : true } } // Requires only one argument...
}
}

var interpretrun = function(){


var cmd = processedArgs._[0]; var cmd = processedArgs._[0];
var clioverrides = { cmd } var clioverrides = { cmd }
: (process.env.NODE_ENV && process.env.NODE_ENV.trim()) : (process.env.NODE_ENV && process.env.NODE_ENV.trim())
? clioverrides.node_env = (process.env.NODE_ENV && process.env.NODE_ENV.trim()) : null; ? clioverrides.node_env = (process.env.NODE_ENV && process.env.NODE_ENV.trim()) : null;
return cmds[cmd] ? cmds[cmd]() : (function(){
return cmds[cmd] ? cmds[cmd].interpret() : (function(){
processedArgs._[1] ? clioverrides.instanceName = processedArgs._[1]: null; processedArgs._[1] ? clioverrides.instanceName = processedArgs._[1]: null;
return clioverrides
// return clioverrides
cmds[cmd] = {
interpret() {
return Object.assign(clioverrides, { cmd, runchoice : 'c' })
}
, getPossiblePrompts(){ return { cmd, username : true, password : true,
instanceName : true, instanceType : true, reposerver : true } }
}
return cmds[cmd].interpret()
})() })()
} }



var clioverrides = interpretrun() var clioverrides = interpretrun()
console.dir(clioverrides) console.dir(clioverrides)


var useGitPull = processedArgs.useGitPull || false; var useGitPull = processedArgs.useGitPull || false;
var configPromise = null var configPromise = null


// elxr cli operations
var noprerequisites = {
add : true, 'set-url' : true, 'repo-relocate' : true
, remote : true, 'c' : true, 'h' : true
, httpget : true, getuser : true
// , 'undefined' : true
}

var reconfirmcmds = { create : true }


var op = { var op = {
'h': () => { console.log(elxr.help()); return '-h' } 'h': () => { console.log(elxr.help()); return '-h' }
//Switch to target branch //Switch to target branch
.then( () => { .then( () => {
if(!mergesource || branch === mergesource ) return Promise.resolve(true) if(!mergesource || branch === mergesource ) return Promise.resolve(true)
return any(elevatedRunasRepos.map((repodef) => performCheckout({ repo : repodef.repo, branch})))
return any(gitRepos.map((repodef) => performCheckout({ repo : repodef.repo, branch})))
}) })
.then( //Merge source branch to target branch .then( //Merge source branch to target branch
() => { () => {
return createInstance(selectedinstance) } return createInstance(selectedinstance) }


, 'httpget' : () => { , 'httpget' : () => {
// HTTPAPI.get({
// RESTAPI.get({
// hostname: 'git.bbh', // hostname: 'git.bbh',
// // port: 443, // // port: 443,
// protocol : 'http:', // protocol : 'http:',
, 'getuser' : ()=>{ , 'getuser' : ()=>{
return prerequisites.git.getuser().then(u=>{ console.log(u)}) return prerequisites.git.getuser().then(u=>{ console.log(u)})
} }

, 'switch user' : (tousername)=>{
return GIT['switch user'](tousername)
}
} }


var util = require('util'); var util = require('util');
} }
else { var reconfirm = {}; } else { var reconfirm = {}; }


var shouldPrompt = function(k, mustPrompt, target){
return ((mustPrompt[k] !== undefined && mustPrompt[k] !== null) && target[k] !== mustPrompt[k]
|| (mustPrompt[k] === undefined || mustPrompt[k] === null) && (target[k] === undefined || target[k] === null)
var shouldPrompt = function(k, possiblePrompts, target){
return ((possiblePrompts[k] !== undefined && possiblePrompts[k] !== null) && target[k] !== possiblePrompts[k]
|| (possiblePrompts[k] === undefined || possiblePrompts[k] === null) && (target[k] === undefined || target[k] === null)
|| reconfirm[k]) || reconfirm[k])
} }


var getBoundEachPrompt = function(target, mustPrompt, promptables, choices, promptsfilter) {
var getBoundEachPrompt = function(target, possiblePrompts, promptables, choices, promptsfilter) {
return function(prompts, k, i, a){ return function(prompts, k, i, a){
// No local instances config found. We use a default initialized instance available in selectedinstance // No local instances config found. We use a default initialized instance available in selectedinstance
// Confirm those that were not supplied as user choices in runtime args and proceed to reattempt. // Confirm those that were not supplied as user choices in runtime args and proceed to reattempt.
// PB : TODO -- selectedinstance === __default check to prompt everything... // PB : TODO -- selectedinstance === __default check to prompt everything...
if( shouldPrompt(k, mustPrompt, target) ) {
if( shouldPrompt(k, possiblePrompts, target) ) {
delete reconfirm[k]; delete reconfirm[k];
// console.log(k) // console.log(k)
// console.dir(mustPrompt); //console.dir(target)
// console.dir(possiblePrompts); //console.dir(target)
prompts.push(async ()=>{ prompts.push(async ()=>{
// PB : NOTE -- Important in async cases when this needs to be in the same state as when it was invoked. // PB : NOTE -- Important in async cases when this needs to be in the same state as when it was invoked.
// We take a snapshot... Shallow.. !! If required deep should be used based on use case. // We take a snapshot... Shallow.. !! If required deep should be used based on use case.
return await target[k] return await target[k]
}) })
} }
delete mustPrompt[k]
delete possiblePrompts[k] // PB : TODO We should keep this around instead of deleting so we can do a second pass if required.
return prompts return prompts
} }
} }
var selectedinstance = null; var selectedinstance = null;
var chessinstances = { current_run : {} }; var chessinstances = { current_run : {} };
var promptkeys = { var promptkeys = {
cmd : processedArgs._[0]
cmd : processedArgs._[0] || 'pull'
// Try not to prompt anything unless absolutely necessary or reconfirm is forced. // Try not to prompt anything unless absolutely necessary or reconfirm is forced.
// 'instanceName' : true // 'instanceName' : true
// , 'node_env' : true // , 'node_env' : true
, username : ''
// , username : ''
// , runchoice : 'c'
} }
promptkeys.runchoice = promptkeys.cmd ? 'c' : undefined
// promptkeys.runchoice = promptkeys.cmd ? 'c' : undefined


function createChessInsance( cfg ){ function createChessInsance( cfg ){
var inst = {}; var inst = {};
, username : ['guest', 'chessdemo', 'demo'] , username : ['guest', 'chessdemo', 'demo']
} }


var getInteractionPoints = function(detectedinstanceoptions, promptkeys, promptsfilter){
var getInteractionPoints = function(detectedinstanceoptions, possiblePrompts, promptsfilter){


var instances = [] var instances = []
var reposervers = []; var reposervers = [];
var instnaceNames = []
var instanceNames = []
var instanceTypes = ['development', 'production']; var instanceTypes = ['development', 'production'];
Object.keys( chessinstances).forEach(instanceName => { Object.keys( chessinstances).forEach(instanceName => {
if(instanceName === 'current_run') return; if(instanceName === 'current_run') return;
if(instance.reposerver) reposervers.push(instance.reposerver) if(instance.reposerver) reposervers.push(instance.reposerver)
instances.push(instance) instances.push(instance)
instanceTypes.push(instance.node_env) instanceTypes.push(instance.node_env)
instnaceNames.push(instance.instanceName)
instanceNames.push(instance.instanceName)
}) })
}) })
instances = instances.concat(detectedinstanceoptions) instances = instances.concat(detectedinstanceoptions)


if(selectedinstance['instanceName']) instnaceNames.push(selectedinstance['instanceName'])
if(promptkeys['instanceName']) instnaceNames.push(promptkeys['instanceName'])
if(selectedinstance['instanceName']) instanceNames.push(selectedinstance['instanceName'])
if(possiblePrompts['instanceName']) instanceNames.push(possiblePrompts['instanceName'])
if(selectedinstance['reposervers']) reposervers = reposervers.concat(selectedinstance['reposervers']) if(selectedinstance['reposervers']) reposervers = reposervers.concat(selectedinstance['reposervers'])
choices['instanceName'] = Array.from( new Set(instnaceNames.concat(choices['instanceName'])) )
choices['instanceName'] = Array.from( new Set(instanceNames.concat(choices['instanceName'])) )
choices['reposerver'] = Array.from( new Set(reposervers.concat(choices['reposerver'])) ) choices['reposerver'] = Array.from( new Set(reposervers.concat(choices['reposerver'])) )
choices['instanceType'] = Array.from( new Set(instanceTypes.concat(choices['instanceType'])) ) choices['instanceType'] = Array.from( new Set(instanceTypes.concat(choices['instanceType'])) )




const https = require('https') const https = require('https')
const http = require('http') const http = require('http')
const HTTPAPI = (function(){
const RESTAPI = (function(){


// Singleton // Singleton
function HTTPAPI(){}
// HTTPAPI.create = HTTPAPI; // Returns the one singe instance which is the class itself

HTTPAPI.post = function(options, jsonpostpayload, resolve, reject){

var _post = function(options, jsonpostpayload, resolve, reject) {

console.dir(options)
console.dir(jsonpostpayload)
const data = new TextEncoder().encode(
JSON.stringify(jsonpostpayload)
)
options.headers = options.headers || {
'Content-Type': 'application/json',
'Content-Length': data.length
function RESTAPI(){}
// RESTAPI.create = RESTAPI; // Returns the one singe instance which is the class itself
// const options = {
// hostname: 'whatever.com',
// port: 443,
// path: '/todos',
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// 'Content-Length': data.length
// }
// }
RESTAPI.method = function(options, resolve, reject){
var __method = function() {
options.headers = options.headers || { 'Content-Type': 'application/json' }
if(options.payload) {
const data = new TextEncoder().encode( JSON.stringify(options.payload) )
options.headers = options.headers || {
'Content-Type': 'application/json',
'Content-Length': data.length
}
} }
if(!options.authenticatepost) options.headers.Authorization = `token ${usertokens[options.username]}` if(!options.authenticatepost) options.headers.Authorization = `token ${usertokens[options.username]}`
// const options = {
// hostname: 'whatever.com',
// port: 443,
// path: '/todos',
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// 'Content-Length': data.length
// }
// }
var acquirer = getHTTP_S(options)

var acquirer = getHTTPorS(options)
const req = acquirer.request(options, res => { const req = acquirer.request(options, res => {
if (res.statusCode < 200 || res.statusCode >= 300) { if (res.statusCode < 200 || res.statusCode >= 300) {
return reject(new Error('statusCode=' + res.statusCode)); return reject(new Error('statusCode=' + res.statusCode));
} }
var body = []; var body = [];
// res.setEncoding('utf8');
res.on('data', function(chunk) { res.on('data', function(chunk) {
body.push(chunk); body.push(chunk);
}); });
reject(error) reject(error)
}) })
req.write(data)
if(options.payload) req.write(data)
req.end() req.end()
} }


if(!options.authenticatepost && !usertokens[options.username]) { if(!options.authenticatepost && !usertokens[options.username]) {
HTTPAPI.authenticate(options, function(tokenresp){
RESTAPI.authenticate(options, function(tokenresp){
usertokens[options.username] = tokenresp.sha1 usertokens[options.username] = tokenresp.sha1
_post(options, jsonpostpayload, resolve, reject)
__method(options, resolve, reject)
}, },
function(err){ throw err} function(err){ throw err}
) )
} }
else _post(options, jsonpostpayload, resolve, reject)

else __method(options, resolve, reject)
} }


RESTAPI.post = RESTAPI.method

var usertokens = {} var usertokens = {}


HTTPAPI.authenticate = function(options, resolve, reject){
RESTAPI.authenticate = function(options, resolve, reject){
options.headers = options.headers || { 'Content-Type': 'application/json' } options.headers = options.headers || { 'Content-Type': 'application/json' }



if(!usertokens[options.username]) { if(!usertokens[options.username]) {
// Authenticate and acquire token. // Authenticate and acquire token.
// https://git.bbh/api/v1/users/<username>/tokens // https://git.bbh/api/v1/users/<username>/tokens
var postoptions = { name : _options.username } var postoptions = { name : _options.username }
delete _options.username delete _options.username
delete _options.password delete _options.password
HTTPAPI.post( _options, postoptions, function(tokenresp){
_options.payload = postoptions
RESTAPI.post( _options, function(tokenresp){
// tokenresp = JSON.parse(tokenresp) // tokenresp = JSON.parse(tokenresp)
usertokens[options.username] = tokenresp.sha1 usertokens[options.username] = tokenresp.sha1
resolve(tokenresp) resolve(tokenresp)
else resolve(tokenresp.sha1) else resolve(tokenresp.sha1)
} }
HTTPAPI.get = function(options, resolve, reject){
options.headers = options.headers || { 'Content-Type': 'application/json' }
if(!usertokens[options.username]) {
HTTPAPI.authenticate(options, function(tokenresp){
usertokens[options.username] = tokenresp.sha1
_get(options, resolve, reject)
},
function(err){ throw err}
)
}
else _get(options, resolve, reject)
var _get = function() {
options.headers.Authorization = `token ${usertokens[options.username]}`
// const options = {
// hostname: 'whatever.com',
// port: 443,
// path: '/todos',
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// 'Content-Length': data.length
// }
// }
var acquirer = getHTTP_S(options)
const req = acquirer.request(options, res => {
if (res.statusCode < 200 || res.statusCode >= 300) {
return reject(new Error('statusCode=' + res.statusCode));
}
var body = [];
res.setEncoding('utf8');
res.on('data', function(chunk) {
body.push(chunk);
});
res.on('end', function() {
try {
body = JSON.parse(Buffer.concat(body).toString());
} catch(e) {
reject(e);
}
resolve(body);
});
});
req.on('error', error => {
console.error(error)
reject(error)
})
req.end()
}
}
RESTAPI.get = RESTAPI.post = RESTAPI.method


return HTTPAPI
return RESTAPI
})(); })();


var getHTTP_S = function(options){ return options.protocol.startsWith('https') ? https : http; }
var getHTTPorS = function(options){ return options.protocol.startsWith('https') ? https : http; }


const GITEA = (function(){ const GITEA = (function(){


// http://try.gitea.io/api/v1/repos/{owner}/{repo}/forks // http://try.gitea.io/api/v1/repos/{owner}/{repo}/forks
httpoptions.path = `/api/v1/repos/${cmdoptions.owner}/${cmdoptions.repo}/forks` httpoptions.path = `/api/v1/repos/${cmdoptions.owner}/${cmdoptions.repo}/forks`
httpoptions.method = 'POST' httpoptions.method = 'POST'
return HTTPAPI.post(httpoptions, giteaoptions, resolve || function(){}, reject || function(){} )
httpoptions.payload = giteaoptions;
return RESTAPI.post(httpoptions, resolve || function(){}, reject || function(){} )
} }
, updateattributes( httpoptions, cmdoptions, giteaoptions, resolve, reject ){ , updateattributes( httpoptions, cmdoptions, giteaoptions, resolve, reject ){
httpoptions.path = `/api/v1/repos/${cmdoptions.owner}/${cmdoptions.repo}` httpoptions.path = `/api/v1/repos/${cmdoptions.owner}/${cmdoptions.repo}`
httpoptions.method = 'PATCH' httpoptions.method = 'PATCH'
return HTTPAPI.post(httpoptions, giteaoptions, resolve || function(){}, reject || function(){} )
httpoptions.payload = giteaoptions;
return RESTAPI.post(httpoptions, resolve || function(){}, reject || function(){} )
} }
} }


GITEA.user = {
getuser( httpoptions, cmdoptions, giteaoptions, resolve, reject ){
// ​/users​/{username} // Get a user
httpoptions.path = `/api/v1/users/${httpoptions.username}`
httpoptions.method = 'GET'
return RESTAPI.get(httpoptions, giteaoptions, resolve || function(){}, reject || function(){} )
}
}


return GITEA return GITEA
})(); })();


// Wrapper for Git shell operations. Some meta operations will map to a bunch of GIT commands.
const GIT = (function(){
function GIT(){}

Object.assign(GIT, {
'switch user'(username){
var server = new URL(selectedinstance.reposerver);
return GITEA.user.getuser({ hostname : server.host, protocol : server.protocol
, username : selectedinstance.username, password : selectedinstance.password
}).then(()=>{
return nodeShellExec('git', ['config', '--replace-all', 'user.name', username],
{
inherit: true, shell: true,
env: process.env
, cwd: instanceroot + '/' + repo
, runas: processedArgs.runas
, title: `git core.symlinks --replace-all true for ${selectedinstance.reposerver + `/${defaultRepoOwner}/` + repo + '.git'}`
})
}
)
.catch(e => {
console.error(e + 'Could not switch. Probably no such user.')
})

}
})

return GIT
})();

function createInstance(selectedinstance) { function createInstance(selectedinstance) {


// http://try.gitea.io/api/v1/org/{org}/repos // http://try.gitea.io/api/v1/org/{org}/repos
detectedinstanceoptions.splice(0,0, __default) detectedinstanceoptions.splice(0,0, __default)

var cmdinstance = cmds[clioverrides.cmd]
var cmdprompts = cmdinstance.getPossiblePrompts()
// PB : TODO -- Most recent should be at the tip ! at index 0 so utils.reverseassign is required !!! // PB : TODO -- Most recent should be at the tip ! at index 0 so utils.reverseassign is required !!!
selectedinstance = utils.assign( ...detectedinstanceoptions.slice(-2), promptkeys ) selectedinstance = utils.assign( ...detectedinstanceoptions.slice(-2), promptkeys )
// promptkeys = utils.assign(promptkeys, clioverrides) // promptkeys = utils.assign(promptkeys, clioverrides)
console.dir(selectedinstance)
try {

chessinstances = acquirelocalinstances(selectedinstance);
findlocalinstances(chessinstances, detectedinstanceoptions)
initinstances(selectedinstance) // use the local instances for defaults if at all possible.
var todo = any( getInteractionPoints(detectedinstanceoptions, promptkeys) ).then(()=>{
var inst = initinstances(selectedinstance)
detection_state.didWeFindInstance = true;
return inst;
})
}
catch (e) {
// PB : TODO -- verbose mode warning.. console.warn(e) // Missing chessinstances is not an error...
var todo = any( getInteractionPoints(detectedinstanceoptions, promptkeys) ).then(()=>{
return initinstances(selectedinstance)
})


// if(!processedArgs._[0] || !selectedinstance.node_env || !selectedinstance.instanceName){
// // Weve not been told what to do.
// todo = todo.then(() => { return acquireChoices(selectedinstance) })
// }
if(cmdprompts.instanceName) {
// not an instanceless cmd.
console.dir(selectedinstance)
try {
todo = todo.then(() => {
try {
chessinstances = acquirelocalinstances(selectedinstance)
findlocalinstances(chessinstances, detectedinstanceoptions)
detectedinstanceoptions.splice(0,0, __default)
initinstances(selectedinstance)
chessinstances = acquirelocalinstances(selectedinstance);
findlocalinstances(chessinstances, detectedinstanceoptions)
initinstances(selectedinstance) // use the local instances for defaults if at all possible.
var todo = any( getInteractionPoints(detectedinstanceoptions, promptkeys) ).then(()=>{
var inst = initinstances(selectedinstance)
detection_state.didWeFindInstance = true; detection_state.didWeFindInstance = true;
}
catch (e) {
// console.error(e)
console.log('No local instances config found in current root = ' + selectedinstance.root);
console.log('A config will be createed with the instance and environment chosen...')
// return (async ()=>{return await __default.reposerver})().then(()=>{
// // selectedinstance = Object.assign(detectedInstance, clioverrides);
// return selectedinstance = Object.assign(__default, selectedinstance);
// })
detection_state.didWeFindInstance = false;
return selectedinstance
}
})
return inst;
})
}
catch (e) {
// PB : TODO -- verbose mode warning.. console.warn(e) // Missing chessinstances is not an error...
var todo = any( getInteractionPoints(detectedinstanceoptions, promptkeys) ).then(()=>{
return initinstances(selectedinstance)
})
// if(!processedArgs._[0] || !selectedinstance.node_env || !selectedinstance.instanceName){
// // Weve not been told what to do.
// todo = todo.then(() => { return acquireChoices(selectedinstance) })
// }
todo = todo.then(() => {
try {
chessinstances = acquirelocalinstances(selectedinstance)
findlocalinstances(chessinstances, detectedinstanceoptions)
detectedinstanceoptions.splice(0,0, __default)
initinstances(selectedinstance)
detection_state.didWeFindInstance = true;
}
catch (e) {
// console.error(e)
console.log('No local instances config found in current root = ' + selectedinstance.root);
console.log('A config will be createed with the instance and environment chosen...')
// return (async ()=>{return await __default.reposerver})().then(()=>{
// // selectedinstance = Object.assign(detectedInstance, clioverrides);
// return selectedinstance = Object.assign(__default, selectedinstance);
// })
detection_state.didWeFindInstance = false;
return selectedinstance
}
})
}
return todo
} }


return todo
else return Promise.resolve(true)
}) })
.then(()=>{ .then(()=>{



Loading…
Cancel
Save