Explorar el Código

Added commandoptions

production
guest hace 3 años
padre
commit
8b69622fd3
Se han modificado 1 ficheros con 199 adiciones y 179 borrados
  1. 199
    179
      index.js

+ 199
- 179
index.js Ver fichero

@@ -16,8 +16,6 @@ const runtimestamp = (new Date()).getTime();
function getVersion() { return BUILD_VERSION; }
console.log(getVersion());



// 'use strict';

// PB : TODO -- make sure folder context is proper coz we can now run elxr from anywhere.
@@ -65,17 +63,49 @@ console.dir(processedArgs)
// }
// })

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' }
}
}
, 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 clioverrides = { cmd }
@@ -83,14 +113,21 @@ var interpretrun = function(){
: (process.env.NODE_ENV && process.env.NODE_ENV.trim())
? 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;
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()
console.dir(clioverrides)

@@ -351,15 +388,6 @@ var exludeMergeRepos = [];
var useGitPull = processedArgs.useGitPull || false;
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 = {
'h': () => { console.log(elxr.help()); return '-h' }
@@ -1668,7 +1696,7 @@ var op = {
//Switch to target branch
.then( () => {
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
() => {
@@ -1859,7 +1887,7 @@ var op = {
return createInstance(selectedinstance) }

, 'httpget' : () => {
// HTTPAPI.get({
// RESTAPI.get({
// hostname: 'git.bbh',
// // port: 443,
// protocol : 'http:',
@@ -1872,6 +1900,10 @@ var op = {
, 'getuser' : ()=>{
return prerequisites.git.getuser().then(u=>{ console.log(u)})
}

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

var util = require('util');
@@ -2490,23 +2522,23 @@ if(clioverrides.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])
}

var getBoundEachPrompt = function(target, mustPrompt, promptables, choices, promptsfilter) {
var getBoundEachPrompt = function(target, possiblePrompts, promptables, choices, promptsfilter) {
return function(prompts, k, i, a){
// 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.
// PB : TODO -- selectedinstance === __default check to prompt everything...
if( shouldPrompt(k, mustPrompt, target) ) {
if( shouldPrompt(k, possiblePrompts, target) ) {
delete reconfirm[k];
// console.log(k)
// console.dir(mustPrompt); //console.dir(target)
// console.dir(possiblePrompts); //console.dir(target)
prompts.push(async ()=>{
// 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.
@@ -2517,7 +2549,7 @@ var getBoundEachPrompt = function(target, mustPrompt, promptables, choices, prom
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
}
}
@@ -2947,13 +2979,14 @@ function findlocalinstances(chessinstances, instanceoptions){
var selectedinstance = null;
var chessinstances = { current_run : {} };
var promptkeys = {
cmd : processedArgs._[0]
cmd : processedArgs._[0] || 'pull'
// Try not to prompt anything unless absolutely necessary or reconfirm is forced.
// 'instanceName' : true
// , 'node_env' : true
, username : ''
// , username : ''
// , runchoice : 'c'
}
promptkeys.runchoice = promptkeys.cmd ? 'c' : undefined
// promptkeys.runchoice = promptkeys.cmd ? 'c' : undefined

function createChessInsance( cfg ){
var inst = {};
@@ -2968,11 +3001,11 @@ var choices = {
, username : ['guest', 'chessdemo', 'demo']
}

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

var instances = []
var reposervers = [];
var instnaceNames = []
var instanceNames = []
var instanceTypes = ['development', 'production'];
Object.keys( chessinstances).forEach(instanceName => {
if(instanceName === 'current_run') return;
@@ -2982,16 +3015,16 @@ var getInteractionPoints = function(detectedinstanceoptions, promptkeys, prompts
if(instance.reposerver) reposervers.push(instance.reposerver)
instances.push(instance)
instanceTypes.push(instance.node_env)
instnaceNames.push(instance.instanceName)
instanceNames.push(instance.instanceName)
})
})
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'])
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['instanceType'] = Array.from( new Set(instanceTypes.concat(choices['instanceType'])) )

@@ -3004,44 +3037,40 @@ var detection_state = {

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

// 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]}`
// 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 => {
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);
});
@@ -3060,29 +3089,28 @@ const HTTPAPI = (function(){
reject(error)
})
req.write(data)
if(options.payload) req.write(data)
req.end()
}

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

else __method(options, resolve, reject)
}

RESTAPI.post = RESTAPI.method

var usertokens = {}

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


if(!usertokens[options.username]) {
// Authenticate and acquire token.
// https://git.bbh/api/v1/users/<username>/tokens
@@ -3098,7 +3126,8 @@ const HTTPAPI = (function(){
var postoptions = { name : _options.username }
delete _options.username
delete _options.password
HTTPAPI.post( _options, postoptions, function(tokenresp){
_options.payload = postoptions
RESTAPI.post( _options, function(tokenresp){
// tokenresp = JSON.parse(tokenresp)
usertokens[options.username] = tokenresp.sha1
resolve(tokenresp)
@@ -3109,66 +3138,12 @@ const HTTPAPI = (function(){
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(){

@@ -3183,19 +3158,60 @@ const GITEA = (function(){
// http://try.gitea.io/api/v1/repos/{owner}/{repo}/forks
httpoptions.path = `/api/v1/repos/${cmdoptions.owner}/${cmdoptions.repo}/forks`
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 ){
httpoptions.path = `/api/v1/repos/${cmdoptions.owner}/${cmdoptions.repo}`
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
})();

// 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) {

// http://try.gitea.io/api/v1/org/{org}/repos
@@ -3359,57 +3375,61 @@ acquireElevationState().then(() => {
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 !!!
selectedinstance = utils.assign( ...detectedinstanceoptions.slice(-2), promptkeys )
// 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;
}
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(()=>{


Cargando…
Cancelar
Guardar