Browse Source

Added addremotes option for pull

production
guest 2 years ago
parent
commit
730fc82177
4 changed files with 366 additions and 206 deletions
  1. 13
    3
      cliverse.js
  2. 336
    190
      index.js
  3. 2
    3
      lin_verse.js
  4. 15
    10
      repo-manifest.js

+ 13
- 3
cliverse.js View File

@@ -41,6 +41,9 @@ function nodeShellExec() {
// D:\chess\instances\elixir_01\elxr/.elxr/run-1630002739610/download.bat https://github.com/git-for-windows/git/releases/download/v2.33.0.windows.2/Git-2.33.0.2-64-bit.exe D:\\chess\\instances\\elixir_01\\elxr/Downloads/Git-2.33.0.2-64-bit.exe
// D:\\chess\\instances\\elixir_01\\elxr/.elxr/run-1630002923584/download.bat https://github.com/git-for-windows/git/releases/download/v2.33.0.windows.2/Git-2.33.0.2-64-bit.exe D:\\chess\\instances\\elixir_01\\elxr/Downloads/Git-2.33.0.2-64-bit.exe
console.dir(args[2])
console.dir(`${args[0]} ${args[1].join(' ') }`)

const child = spawn(...args);
var p = new Promise(function(resolve, reject){
// console.log(...args)
@@ -68,8 +71,8 @@ function nodeShellExec() {
child.on('close', (code) => {
// console.log('Proper close was fired')
var logEntry = { code, success }
if(+code !== 0 || opts.haserrors) { success = false; logEntry = { messages, result: `${opts.title} exited with code ${code}`, success, code }
if(opts.evaluateResult) logEntry = opts.evaluateResult(false, logEntry);
if(+code !== 0 || opts.haserrors) {
success = false; logEntry = { messages, result: `${opts.title} exited with code ${code}`, success, code }
};
if(opts.stdio !== 'ignore') {
logEntry = { result: `${opts.title} exited with code ${code}`, messages, code }
@@ -84,8 +87,15 @@ function nodeShellExec() {
process.stdout.write( messages.join('') )
}
}
else if(opts.evaluateResult) {
try { logEntry = opts.evaluateResult(false, logEntry); }
catch(e){ reject(e) }
}
// clearInterval(interval)
if(code !== 0 || opts.haserrors) return reject(logEntry)
if(code !== 0 || opts.haserrors) {
args[2].benign || args[2].ignorefailures ? (logEntry.benign = true, logEntry.ignorefailures = true) : null
return reject(logEntry)
}
resolve(logEntry)
});
}

+ 336
- 190
index.js View File

@@ -298,13 +298,20 @@ var getCmdString = function(args){ return `"${args[0]} ${args[1].join(' ')}"` }

var getshelltask = (args) => {
return args[0] === 'rm' ? getgitbashtask(args) : () => {
return nodeShellExec.apply(null, args).catch(function(e){ e.benign = args[2].benign; if(!e.benign) {console.error(e); throw e} })
return nodeShellExec.apply(null, args).catch(function(e){
e.benign = args[2].benign;
if(!e.benign) { console.error(e); }
throw e
})
}
}
var getgitbashtask = (args, onEachError) => { return () => {
return nodeShellExec( `"${gitbash}"`, ['-c', getCmdString(args)], args[2]).catch( onEachError || function(e){ console.error(e) }) }
}

var getnodeshellexectask = (args) => { return () => { return nodeShellExec.apply(null, args) }}
var perform = function( serailtasks, taskvector ){ return any( serailtasks(taskvector).map(getnodeshellexectask)) }

var getTaskCheckExists = shell_verse.getTaskCheckExists
// var getTaskWithElevation = function(tasdef){ return shell_verse.getElevatedTask( tasdef.elevatedpulltasks ) }

@@ -380,6 +387,9 @@ var getPullTask = (repodef, branch, repoowner, errHandler, elevatedBatch, regula
elevatedBatch = elevatedBatch || [];
regularBatch = regularBatch || [];
try{
// PB : TODO -- local repo folder named the same as the remote repository name is not enough to establish existence.
// This remote repo and branch may have been or may need to be added as a local tracking branch
// to any other local repo folder (with a different name)
var exists = existsSync(instanceroot + '/' + repo)
}
catch(e){
@@ -395,7 +405,9 @@ var getPullTask = (repodef, branch, repoowner, errHandler, elevatedBatch, regula
etask.selectedinstance = selectedinstance
etask.runtimestamp = runtimestamp
etask.ENV = ENV
}

function initElevatedBatch(){
elevatedBatch.info = { repo }
elevatedBatch.errHandler = errHandler
elevatedBatch.statuslog = statuslog
@@ -407,57 +419,102 @@ var getPullTask = (repodef, branch, repoowner, errHandler, elevatedBatch, regula

if (exists) {
// Add the remotes
var tasks = []
var selectedremotes = Array.from( new Set(selectedinstance.selectedremotes.concat(Object.keys(repodef.remotes || {}))));
var repoRemotes = Object.assign( {}, selectedinstance.remotes, repodef.remotes );
selectedremotes.forEach((remotename)=>{
var ai_RemoteAddNeeded = (info)=>{ return true }; // ai prefix for all apis that require an answer if choice is needed.
tasks.push(
()=>{

return op['remote exists']({
remotename, repo, benign : true, ignorefailures : true
, url : repoRemotes[remotename].url || processedArgs._[3]
, branch : processedArgs._[4]
}).then( (r) => {
if(!r[1]) return false; // PB : TODO -- Not accessible skip for now probably should remove.
else if(r[0]) return true; // Already added nothing to do
else if(ai_RemoteAddNeeded()) return op['remote add']( { remotename,
'set-upstream' : remotename === selectedinstance['upstream-remote'] //remote.upstream ??? when url accessible... in order of highest priority
, url : remote.url, branch : checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV
})
// else skipped as remote is not relevant for this repo...
var tasks = [];
return (()=>{
// PB : TODO -- We need a non cacheable set of properties that need to default to something but then need to escplicitly specified in each run.
if(selectedinstance.addremotes) {
return op['get-remotes']({repo}).then(( remotes )=>{
return op['get-upstream']({repo, remotes}).then(( upstream ) => {
return __addremotesandpull({ upstream, remotes})
})
}
)
})

var branchprint = branch ? ' branch :' + branch : '';
var task = ()=>{
console.log('pulling ' + instanceroot + '/' + repo + branchprint )
return any(tasks).then( ()=>{
return nodeShellExec.apply(null, getPullCmd(repodef, branch)).then(() => {
return true;
})
})
}
initTask(task)
}
else return __pull();
})()

if(repodef.requiresElevation) {
elevatedBatch.push(shell_verse.getElevatedTaskInBatch( task ));
if(elevatedBatch.length === 1) { initTask(elevatedBatch[0]) } // PB : TDOO -- Make sure first task also has run context. May need to be moved to win_verse
return elevatedBatch[elevatedBatch.length-1]
function __pull(){
var branchprint = branch ? ' branch :' + branch : '';
var task = ()=>{
console.log('pulling ' + instanceroot + '/' + repo + branchprint )
return any(tasks).then( ()=>{
return nodeShellExec.apply(null, getPullCmd(repodef, branch)).then(() => {
return true;
})
})
}
initTask(task)
if(repodef.requiresElevation) {
elevatedBatch.push(shell_verse.getElevatedTaskInBatch( task ));
if(elevatedBatch.length === 1) { initElevatedBatch(); initTask(elevatedBatch[0]) } // PB : TDOO -- Make sure first task also has run context. May need to be moved to win_verse
else initTask(elevatedBatch[elevatedBatch.length-1])
return elevatedBatch[elevatedBatch.length-1]
}
else {
regularBatch.push(shell_verse.getNonElevatedTask( task ))
return regularBatch[regularBatch.length-1]
}
}
else {
regularBatch.push(shell_verse.getNonElevatedTask( task ))
return regularBatch[regularBatch.length-1]
function __addremotesandpull(options){
// Add the remotes
var tasks = []
// selectedinstance.selectedremotes are optional and need not be enforced to be chosen. The selection for hte selected remotes
// could also be derived from a crossfilter of remote-type selected for this run and the current chosen and operating reposervers.
var selectedremotes = Array.from( new Set(selectedinstance.selectedremotes.concat(Object.keys(repodef.remotes || {}))));
if(selectedremotes.length > 0) var selectedremoteFilter = function(rs) { return selectedremotes.find( rs.server ) }
else var selectedremoteFilter = function(){ return true }
var repoRemotes = Object.assign( {}, selectedinstance.remotes, options.remotes, options.upstream, repodef.remotes );
// We need a most permissive filtered list to use as an efficient starting point to further reduce to whats actually needed.
// However if such a cached list is not available we need to build it by scaning and apply all the filters anyway on the whole world.

Object.keys(repoRemotes).forEach((remotename)=>{
// PB : TODO -- ai prefix for all apis that require an answer amongst many choices.
var ai_RemoteAddNeeded = (r)=>{
if(r.server === reposerver && selectedremoteFilter() && r.accessibility.find( selectedinstance[ 'remote-type' ] )){ // currently chosen remotetype...
var exists = false;
if(exists = (options.remotes[r.remotename] || Object.keys(options.remotes).find( lrn => {
var exists = options.remotes[lrn].server === r.server && !options.remotes[r.remotename]
if(exists) console.warn('Found duplicate remote with a different name for the same server...')
return exists
} )) ) {
return false // Already a remote not required.
}
return true // PB : TODO -- Sort and display highest priority target.remotes.sort( )
}
return false
};
tasks.push(
()=>{
return op['remote exists']({
remotename, repo, benign : true, ignorefailures : true
, url : repoRemotes[remotename].url + repo
, branch : checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV
}).then( (r) => {
if(!r[1]) return false; // PB : TODO -- Not accessible skip for now probably should remove.
else if(r[0]) return true; // Already added nothing to do
else if(ai_RemoteAddNeeded( repoRemotes[remotename] )) return op['remote add']( { remotename,
'set-upstream' : remotename === selectedinstance['upstream-remote'] //remote.upstream ??? when url accessible... in order of highest priority
, repo
, url : repoRemotes[remotename].url , branch : checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV
})
// else skipped as remote is not relevant for this repo...
})
}
)
})
__pull()
}
}
else {
// PB : TODO -- detect if a clonable repo exists within the context of currentGitAuthUser on remote reposerver...
console.log('cloning ' + repo)
// PB : TODO -- detect if a clonable repo exists in currentGitAuthUser
// PB : TODO -- add additional remotes after cloning and pull again...
var task = ()=>{
return nodeShellExec('git', ['clone', '-c', 'core.symlinks=true', selectedinstance.reposerver + `/${repoowner || defaultRepoOwner}/` + repo + '.git'],
{
@@ -489,7 +546,7 @@ var getPullTask = (repodef, branch, repoowner, errHandler, elevatedBatch, regula
return regularBatch[regularBatch.length-1]
}
})
}
}
initTask(task)
if(repodef.requiresElevation) {
@@ -509,8 +566,6 @@ var elevatedRunasRepos = null
var gitRepos = null

// grep -qxF 'alias elxr="node elxr/index.js"' ~/.bash_profile || echo 'alias elxr="node elxr/index.js"' >> ~/.bash_profile


// nodeShellExec('echo', ['elxr'], { inherit : true}) //, {stdio: "inherit"}

var dbForLabel = function (label) {
@@ -839,58 +894,37 @@ var op = {
, {
benign : args.benign, ignorefailures : args.ignorefailures,
evaluateResult : function(err, result){
// var found = result.messages.find( (r)=> { return r.includes( __args.remotename ) })
console.log(__args.remotename)
var remotes = []
var found = false;
if(+result.code === 0) found = true;
// console.dir(result.messages)
// console.log(result + '---------------')
// result.messages.forEach( (line)=> {
// console.log(line + '$$$$$$$$$$$$$$$$$$$$')
// var matches = line.match(/(.*)?\s\s([^\(]*)?\s?\(?([^\)]*)\)?/);
// if(matches) {
// var remote = {};
// remote[matches[1]] = matches[2];
// if( (!matches[3].trim() || matches[3].trim() === 'fetch') && matches[1].trim() === remotename.trim()) {
// found = true;
// result.url = remote[remotename];
// }
// }
// })
console.dir(remotes)
return [
found
+result.code === 0
, result
]
}
} , options) ]
, function(prevserialtaskresult) {
if(!prevserialtaskresult) return [[ false, null], [ false, null]]

if(!prevserialtaskresult) return [[ false, null], [ false, null]]
console.log('================================')
var url = __args || prevserialtaskresult.url;
console.dir(prevserialtaskresult)
return getshelltask(['git', ['ls-remote', url], utils.assign_core( { arraymergetype : utils.assign_core.DISTINCT_UNION }
, {
benign : args.benign,
evaluateResult : function(err, result){
// fatal: unable to access '${__args.url}/': Failed to connect to git.bbh port 80 after 21025 ms: Timed out
// `fatal: repository '${__args.url}/' not found`
var hasfailed = /^fatal: .*/.test(result.messages.join(' '))
return [
!hasfailed, result
]
}
} , options) ])().catch( e => {
console.error(e)
return [[ false, null], [ false, null]]
})
}
} , options) ]
]
var mapped = commands.map(callshelltask) //.map( p => p.catch(e => e)) // Handle errors later.
return any(mapped, true).then( allresolved =>{
var mapped = commands.map(getshelltask) //.map( p => p.catch(e => e)) // Handle errors later.
mapped.push( function(prevserialtaskresult) {
var pt = [false , null]
if(prevserialtaskresult.error) {
// Previous task has failed.
pt[1] = prevserialtaskresult.error[1]
}
else pt = prevserialtaskresult;

console.dir(prevserialtaskresult)
return getshelltask(['git', ['ls-remote', `${__args.url}`], utils.assign_core( { arraymergetype : utils.assign_core.DISTINCT_UNION }
, {
benign : args.benign, ignorefailures : args.ignorefailures,
evaluateResult : function(err, result){
if(+result.code !== 0) return [pt, [ false, result]]
// var hasfailed = /^fatal: .*/.test(result.messages.join(' '))
return [pt, [true, result] ]
}
} , options) ])().catch( e => {
console.error(e)
return [pt, [ false, null]]
})
})
return any(mapped, true, false, { accumulatedresults : [] }).then( allresolved => {
console.dir(allresolved)
!allresolved[0][0] && !allresolved[1][0] ? console.log('was not added as a remote and url is currently inaccessible.')
@@ -920,7 +954,11 @@ var op = {
var repo = dir.name
var dscoverbranchcmd = gitops.getdiscoverbranchcmd(repo)
try {
var remotes = require(`${selectedinstance.root}/${dir.name}/repo-manifest.js`)( null, selectedinstance).remotes || [];
var remotes = require(`${selectedinstance.root}/${dir.name}/repo-manifest.js`)( null
, { utils, username : selectedinstance.username, instanceName : selectedinstance.instanceName
, node_env : selectedinstance.node_env, reposerver : 'https://git.bbh.org.in' } // options
).remotes || [];
}
catch(e){
var remotes = []
@@ -977,6 +1015,7 @@ var op = {
// args === processedArgs ? args = {} : null;
var __args = {
remotename : args.remotename|| processedArgs._[2]
, repo : args.repo
, url : args.url || processedArgs._[3]
, branch : args.branch || processedArgs._[4]
, 'set-upstream' : args['set-upstream'] || processedArgs._[5]
@@ -988,7 +1027,6 @@ var op = {

var pushable = processedArgs.pushable || false;


var serial_perform_git_add = (repo) => {
var options = { cwd: instanceroot + '/' + repo }
// console.log(repo)
@@ -1010,14 +1048,10 @@ var op = {
]
}
if(args['set-upstream']) gacmds.push(['git', ['branch', `--set-upstream-to=${remotename}/${branch}`, branch], { cwd: instanceroot + '/' + repo }])
return gacmds
}
var x = (args) => {
return () => {
// console.log(args)
return nodeShellExec.apply(null, args)
}
// return Promise.resolve(true)
}
// PB : TODO -- Accumulate using yield... and finally return a set of tasks or promises...
var perform_git_add = (dir) => {
op['is-git-repo'](dir).then((logEntry) => {
// console.log(code)
@@ -1026,18 +1060,17 @@ var op = {
console.log('skipped : ' + dir.name + ', reason : A remote with same name already exists.')
})
.catch((e) => {
any(serial_perform_git_add(dir.name).map(x))
perform( serial_perform_git_add, dir.name )
})
}
// else console.log('Skipped : Not a Git Repo : ' + dir.name)
// else console.log('Skipped : Not a Git Repo : ' + dir.name)
}).catch((e) => {
console.log('Failed : ' + dir.name)
})
}

const { readdir } = require("fs").promises
dirs(perform_git_add)
if(args.repo) { perform_git_add( { name : args.repo} ) }
else return dirs(perform_git_add)
}
, 'remote remove': (args) => {
@@ -1052,19 +1085,13 @@ var op = {
['git', ['remote', 'remove', remotename], { cwd: instanceroot + '/' + repo }]
]
}
var x = (args) => {
return () => {
// console.log(args)
return nodeShellExec.apply(null, args)
}
// return Promise.resolve(true)
}
var perform_git_remove = (dir) => {
op['is-git-repo'](dir).then((logEntry) => {
// console.log(code)
if (logEntry.success) {
nodeShellExec('git', ['remote', 'get-url', remotename], { cwd: dir.name, stdio: 'ignore' }).then(() => {
any(serial_perform_git_remove(dir.name).map(x))
any(serial_perform_git_remove(dir.name).map(getnodeshellexectask))
})
.catch((e) => {
console.log('skipped : ' + dir.name + `, reason : No remote named ${remotename}`)
@@ -1080,6 +1107,94 @@ var op = {

dirs(perform_git_remove)
}
, 'get-remotes' : (args) => {
// var __args = {
// repo : args?.repo || processedArgs._[1]
// }

var repo = args.repo

var serial_perform = (repo) => {
return [
['git', ['remote', '-vvvv'], { cwd: instanceroot + '/' + repo,
evaluateResult : function( issuccess, result){
if(!issuccess || +result.code !== 0) throw Object.assign( new Error('git branch -vvvv crashed'), result);
var lines = result.messages.join('').split('\n')
var remotes = {}
lines.forEach(line => {
// pattern = origin https://git.bbh.org.in/chess/elxr (fetch)
var match = new RegExp(`(\\S+)\\s(\\S+)/${repo}.git\\s\\((\\S+)\\)`).exec(line)
if(match) {
var r = remotes[match[1]] || (remotes[match[1]] = { title : match[1] })
if(match[3] === 'push') { r.push = match[2] }
else r.url = match[2]
}
})
return remotes
}}]
]
}

return perform( serial_perform, repo )
}
, 'get-remote' : (upstream) => {
// var __args = {
// repo : args?.repo || processedArgs._[1]
// }

var repo = upstream.repo

var serial_perform = (repo) => {
return [
['git', ['remote', '-vvvv'], { cwd: instanceroot + '/' + repo,
evaluateResult : function( issuccess, result){
if(!issuccess || +result.code !== 0) throw Object.assign( new Error('git branch -vvvv crashed'), result);
// origin https://git.bbh.org.in/chess/elxr (fetch)
var match = new RegExp(`${upstream.remotename}\\\s(\\S+)/${repo}.git\\s\\(fetch\\)`).exec(result.messages.join(' '))
if(match) { upstream.url = match[1] }
else throw Object.assign( new Error('No upstream found for active branch'), result)
return upstream
}}]
]
}

return perform( serial_perform, repo )
}
, 'get-upstream' : (args) => {

var __args = {
repo : args?.repo || processedArgs._[1]
}

var repo = __args.repo

var serial_perform = (repo) => {
return [
['git', ['branch', '-vvvv'], { cwd: instanceroot + '/' + repo,
evaluateResult : function( issuccess, result){
if(!issuccess || +result.code !== 0) throw Object.assign( new Error('git branch -vvvv crashed'), result);
var match = /\*\s(\S+)\s\S+\s\[(\S+)\/(\S+).*?\].*?/.exec(result.messages.join(' '))
if(match) { var upstream = { remotename : match[2], branch : match[1], remotebranch : match[3] } }
else throw Object.assign( new Error('No upstream found for active branch'), result)
if(args?.remotes) {
var r = args.remotes[upstream.remotename];
if(!r) return op['get-remote'](upstream)
r.branch = upstream.branch
r.remotebranch = upstream.remotebranch
return r
}
return op['get-remote'](upstream)
}}]
]
}

return perform( serial_perform, repo )
}
, 'init-gitea': (user) => {
user = user || processedArgs._[1]
if (!user) throw 'User name required'
@@ -1092,13 +1207,7 @@ var op = {
, ['git', ['remote', 'set-url', 'userfork', `${selectedinstance.reposerver}/${user}/${repo}.git`], { cwd: instanceroot + '/' + repo }]
]
}
var x = (args) => {
return () => {
// console.log(args)
return nodeShellExec.apply(null, args)
}
// return Promise.resolve(true)
}
var perform_init_gitea = (dir) => {
op['is-git-repo'](dir).then((logEntry) => {
// console.log(code)
@@ -1106,9 +1215,9 @@ var op = {
nodeShellExec('git', ['remote', 'get-url', 'chess'], { cwd: dir.name, stdio: 'ignore' }).then(() => {
console.log('skipped : ' + dir.name + ', reason : Already has remote chess ')
})
.catch((e) => {
any(serial_perform_init_gitea(dir.name).map(x))
})
.catch((e) => {
perform( serial_perform_init_gitea, dir.name )
})
}
// else console.log('Skipped : Not a Git Repo : ' + dir.name)
}).catch((e) => {
@@ -1116,8 +1225,6 @@ var op = {
})
}

const { readdir } = require("fs").promises

dirs(perform_init_gitea)
}
, 'syncmaster': (label) => {
@@ -2140,6 +2247,14 @@ var cmds = {
, cmd : 'users list'
, noprerequisites : true
}
, 'get-upstream' :{
cmdFn : op['get-upstream'] // default
, cmd : 'get-upstream'
, noprerequisites : true
, independentcmd : true
, interpret() { return { cmd : 'get-upstream' } }
, getPossiblePrompts(){ return {} }
}
, 'g' : {
cmdFn : op['g'] // default
, cmd : 'g'
@@ -2595,6 +2710,8 @@ function elxrworker() {
// // })
// }


// PB : TODO -- Move this to utils assign... as an array merge option.
var mergeObjByKey = function(arrOfObjs, keyName) {

var keyedDistinct = {}
@@ -2614,8 +2731,9 @@ var mergeObjByKey = function(arrOfObjs, keyName) {
var cacheWriteInstanceConfig = function(chessinstances){
var instanceName = chessinstances['current_run'].instanceName;
var node_env = chessinstances['current_run'].node_env;
chessinstances[instanceName][node_env].repos = mergeObjByKey(chessinstances[instanceName][node_env].repos, 'repo') ;
chessinstances[instanceName][node_env].elevated = mergeObjByKey(chessinstances[instanceName][node_env].elevated, 'repo') ;
// PB : TODO -- We should be able to do simply merge at a higher level using assign
chessinstances[instanceName][node_env].repos = mergeObjByKey(chessinstances[instanceName][node_env].repos || [], 'repo') ;
chessinstances[instanceName][node_env].elevated = mergeObjByKey(chessinstances[instanceName][node_env].elevated || [], 'repo') ;
fs.writeFileSync(instanceroot + '/chessinstances.js', 'module.exports = ' + JSON.stringify(chessinstances, null, 2) + '', { 'flag': 'w' })
}

@@ -2648,9 +2766,35 @@ var configs = (function(){
}
// PB : TODO -- Use the ORG level instance before falling back to common Instance coz common instance may not exist for certain orgs.
, commonInstance(selected) { return __acquireConfig(selected, { defaultRepoOwner }
// , function(e){ console.info('This is probably an error unless the user is asking to create a new instance with this name.') }
, undefined
, function(e){
// PB : TODO -- console.info('This is probably an error unless the user is asking to create a new instance with this name.')
statuslog.statuslog(e, e)
var manifestpath = path.normalize(selected.root + '/' + selected.instanceName + '-config-' + selected.node_env + '/repo-manifest');
utils.assign_core( { keycase : true, arraymergetype : utils.assign_core.DISTINCT_UNION }
, selectedinstance, require(manifestpath)( null, { utils, username : selectedinstance.username, instanceName : selectedinstance.instanceName
, node_env : selectedinstance.node_env, reposerver : 'https://git.bbh.org.in' } ))
console.dir(selectedinstance.repos)
// Config from server always override merges into selection except for the current selection.
// PB : TODO -- utils.assign Array merges are non-distinct...
if(selectedinstance?.repos && !selectedinstance.repos[0].repo) {
console.warn('repo manifest has obsolete format. Attempting upgrade.')
selectedinstance.repos = selectedinstance.repos.map(function(repo){ return { repo } })
}
if(selectedinstance?.elevated && !selectedinstance.elevated[0]?.repo) {
console.warn('elevated repo manifest has obsolete format. Attempting upgrade.')
selectedinstance.elevated = selectedinstance.elevated.map(function(repo){ return { repo } })
}
chessinstances[selected.instanceName][selected.node_env] = selectedinstance = utils.assign_core( { arraymergetype : utils.assign_core.DISTINCT_UNION }
, selected, selectedinstance)
chessinstances[selected.instanceName][selected.node_env].reposervers = Array.from(new Set(chessinstances[selected.instanceName][selected.node_env].reposervers))
selectedinstance.reposerver = selectedinstance.reposerver || selectedinstance.reposervers[0] // PB : TODO -- Attempt first one that is available and online...
cacheWriteInstanceConfig(chessinstances)
// ENV.NODE_ENV = selectedinstance.node_env;
throw e
}
) }
, genericChessInstance(selected) { return __acquireConfig(selected) }
// , genericChessInstance(selected) { return __acquireConfig(selected) }
}
})()

@@ -2674,13 +2818,13 @@ var instanceData = (function(){
clustername = clustername || `${selected.username}-CHESS-${selected.node_env}`;
return __acquireData(selected, { remote : 'userfork' }
, selected.instanceName + '-data-' + selected.node_env + `-${clusternodename}`
, function(e){ console.info('Customized node level config not found. This is not an Error. Will attempt with owner level config.');
, function(e){ console.info('Customized node level data not found. This is not an Error. Will attempt with owner level config.');
return e; }
)
}
, ownerInstnace(selected) { return __acquireData(selected, { remote : 'userfork' }
, selected.instanceName + '-data-' + selected.node_env
, function(e){ console.info('Customized user level config not found. This is not an Error. Will attempt global common instance config.');
, function(e){ console.info('Customized user level data not found. This is not an Error. Will attempt global common instance config.');
return e }
)
}
@@ -2849,7 +2993,8 @@ var __acquireConfig = function (selected, options, configrepo, errHandler) {

var manifestpath = path.normalize(selected.root + '/' + selected.instanceName + '-config-' + selected.node_env + '/repo-manifest');
utils.assign_core( { keycase : true, arraymergetype : utils.assign_core.DISTINCT_UNION }
, selectedinstance, require(manifestpath)( null, selectedinstance))
, selectedinstance, require(manifestpath)( null, { utils, username : selectedinstance.username, instanceName : selectedinstance.instanceName
, node_env : selectedinstance.node_env, reposerver : 'https://git.bbh.org.in' }))
console.dir(selectedinstance.repos)
// Config from server always override merges into selection except for the current selection.
// PB : TODO -- utils.assign Array merges are non-distinct...
@@ -2869,11 +3014,7 @@ var __acquireConfig = function (selected, options, configrepo, errHandler) {
ENV.NODE_ENV = selectedinstance.node_env;
}

var selectedremotes = {};
if(options.remote) selectedremotes[options.remote] = selected.reposerverinstances[selected.reposerver].remotes[options.remote];
// else known remotes preselected from UI pref.
return performPull({repo : configrepo, remotes : Object.assign(selectedremotes
, selected.repos[configrepo]?.remotes || {} ) }
return performPull( selected.reposindexed[configrepo] || { repo : configrepo }
, null, selected.username || options.defaultRepoOwner, errHandler || errorHandler || ((e)=>{ throw e })).then( successHandler )
.catch( (e)=>{
// if(e){
@@ -2946,12 +3087,7 @@ var __acquireData = function (selected, options, datarepo, errHandler) {

}

var selectedremotes = {};
if(options.remote) selectedremotes[options.remote] = selected.reposerverinstances[selected.reposerver].remotes[options.remote]
// else ...
return performPull({ repo : datarepo
, remotes : Object.assign(selectedremotes
, selected.repos[datarepo]?.remotes || {} ) }
return performPull( selected.reposindexed[datarepo] || { repo : datarepo }
, null, selected.username || options.defaultRepoOwner, errHandler || errorHandler || ((e)=>{ throw e })).then( successHandler )
.catch( (e)=>{
// if(e){
@@ -3294,12 +3430,20 @@ var __interactive_prompts = function( target, choices, promptsfilter ){
, selectedchoice : target['upstream-remote'] || 'userfork'
// Just using getters resolves dependencies..., dependencies : [ ()=>{ return target['reposerver'] } ]
}
, 'remote-type' : { label : `Enter Remote Type ( <= ${target['remote-type'] || 'public'} ) : `
, get choices() {
return ['public', 'private', 'github', 'unc']
}
, defaultchoice : 'public'
, selectedchoice : target['remote-type'] || 'public'
// Just using getters resolves dependencies..., dependencies : [ ()=>{ return target['reposerver'] } ]
}
, 'selectedremotes' : { label : `Chose Remote Names ( <= ${target['selectedremotes'] || 'chess'} ) : `
, get choices() {
var reposerver = target['reposerver'] // PB : TODO -- We need options to work with multiple selected reposervers at the same time..
var remotenames = []
Object.entries(target.remotes).forEach( ([rname, r]) => {
if(r.server === reposerver){
if(r.server === reposerver && r.accessibility.find( target[ 'remote-type' ] )){
remotes.push(rname)
// PB : TODO -- Sort and display highest priority target.remotes.sort( )
}
@@ -4026,11 +4170,11 @@ function initinstances(selected_overrides) {
// selectedinstance = Object.assign( __default, selectedinstance )
// }
if(!selectedinstance.repos[0].repo) {
if(selectedinstance?.repos && !selectedinstance?.repos[0]?.repo) {
console.warn('repo manifest has obsolete format. Attempting upgrade.')
selectedinstance.repos = selectedinstance.repos.map(function(repo){ return { repo } })
}
if(selectedinstance.elevated[0] && !selectedinstance.elevated[0].repo) {
if(selectedinstance?.elevated && !selectedinstance?.elevated[0]?.repo) {
console.warn('elevated repo manifest has obsolete format. Attempting upgrade.')
selectedinstance.elevated = selectedinstance.elevated.map(function(repo){ return { repo } })
}
@@ -4270,7 +4414,48 @@ var startElxr = function() {
}
})
}
return todo
return todo.then( ()=>{
// PB : TODO -- Embed this in the build instead of inlining it.
// Also attepmt to load from ../chess-config/...
var __repo_manifest = (require(path.normalize(instanceroot + '/elxr/repo-manifest.js')))(
'defaultmanifest' // name
, { utils, username : selectedinstance.username, instanceName : selectedinstance.instanceName
, node_env : selectedinstance.node_env, reposerver : 'https://git.bbh.org.in' } // options
)

__default = Object.assign(__default, __repo_manifest, {
// Common baseline repos for all chess instances.
repos : (()=> {
var __repos = [
{ repo : 'ember-masonry-grid' /*, branch : master*/ } // Default need not be specified.
, { repo : 'bbhverse' }
, { repo : 'clientverse' }
, { repo : 'serververse' }
, { repo : 'elxr' }
, { repo : 'ember-searchable-select' }
, { repo : 'loopback-component-jsonapi' }
, { repo : 'loopback-jsonapi-model-serializer' }
, { repo : 'loopback-connector-mysql' }
, { repo : 'loopback-connector-ds' }
, { repo : 'ember-service-worker' }
, { repo : 'ember-service-worker-asset-cache' }
, { repo : 'ember-service-worker-cache-fallback' }
, { repo : 'ember-service-worker-index' }
, { repo : 'ember-sw-client-route' }
, { repo : 'global-this' }
]
Array.prototype.push.apply( __repos, __repo_manifest.repos)
return __repos;
})()
// Requires elevation only in windows
, elevated : [ { repo : 'chess-server-lib', requiresElevation : true } ]
, exludeMergeRepos : { }
})
initinstances(selectedinstance)
return selectedinstance
})
}
else return Promise.resolve(true)
})
@@ -4325,50 +4510,11 @@ var startElxr = function() {
})
}

var __default = null; // PB : TODO -- Use initialized instance instead of default everywhere.
var __default = {}; // PB : TODO -- Use initialized instance instead of default everywhere.
// PB : TODO -- In windows if we are run from an elevated shell we never move forward and simply exits !?.
// -- Currently workaround in windows is to always run from a non-elevated shell.
shell_verse.acquireElevationState().then((elevationstate) => {
return detectInstanceRoot.then(()=>{

// PB : TODO -- Embed this in the build instead of inlining it.
// Also attepmt to load from ../chess-config/...
var __repo_manifest = (require(path.normalize(instanceroot + '/elxr/repo-manifest.js')))(
'__default' // name
, { utils, username : 'guest', instanceName : 'chess', node_env : 'development', reposerver : 'https://git.bbh.org.in' } // options
)

__default = Object.assign(__repo_manifest, {
// Common baseline repos for all chess instances.
repos : (()=> {
var __repos = [
{ repo : 'ember-masonry-grid' /*, branch : master*/ } // Default need not be specified.
, { repo : 'bbhverse' }
, { repo : 'clientverse' }
, { repo : 'serververse' }
, { repo : 'elxr' }
, { repo : 'ember-searchable-select' }
, { repo : 'loopback-component-jsonapi' }
, { repo : 'loopback-jsonapi-model-serializer' }
, { repo : 'loopback-connector-mysql' }
, { repo : 'loopback-connector-ds' }
, { repo : 'ember-service-worker' }
, { repo : 'ember-service-worker-asset-cache' }
, { repo : 'ember-service-worker-cache-fallback' }
, { repo : 'ember-service-worker-index' }
, { repo : 'ember-sw-client-route' }
, { repo : 'global-this' }
]
Array.prototype.push.apply( __repos, __repo_manifest.repos)
return __repos;
})()
// Requires elevation only in windows
, elevated : [ { repo : 'chess-server-lib', requiresElevation : true } ]
, exludeMergeRepos : { }
})


var cmdobj = cmds[clioverrides.cmd]
return Promise.all((cmdobj.requires || []).map( (r) => utils.promisify(null, r) ) ).then(()=>{
if(cmdobj.independentcmd) {

+ 2
- 3
lin_verse.js View File

@@ -81,8 +81,7 @@ var shell_verse = {

if(taskToRun.processedArgs.skipelevated) return Promise.resolve({ skipped : true });


if (__isElevated) {
if(__isElevated) {
return shell_verse.elevatedRunner(taskToRun)
}
else {
@@ -95,7 +94,7 @@ var shell_verse = {
, runElevatedBatch( batchToRun ){
// In windows we don't need to run each task. We hand over to another shell which in elevated state rebuilds the whole batch and runs.
// Irrespective of the batch we just call runElevated once.
return any(batchToRun.map( t => shell_verse.runElevated ))
return any(batchToRun.map(shell_verse.runElevated))
}

, getNonElevatedTask : function( taskToRun ){ return ()=>{ return shell_verse.runNonElevated(taskToRun) } }

+ 15
- 10
repo-manifest.js View File

@@ -28,7 +28,7 @@ module.exports = ((name, options)=>{
server : `https://git.bbh.org.in`, user : options.username || '', path : ``
, get url(){ return `${this.server}/chess/${this.path}`}
, title : 'chess-public' // PB : TODO -- rename...
, accessibility : ['external', 'public']
, accessibility : ['public']
, push : 'no-pushing'
}
// PB : TODO -- Load private repositories from private config...
@@ -36,14 +36,14 @@ module.exports = ((name, options)=>{
server : `http://git.bbh`, user : options.username || '', path : ``
, get url(){ return `${this.server}/chess/${this.path}`}
, title : 'chess-private'
, accessibility : ['private', 'internal']
, accessibility : ['private']
, push : 'no-pushing', private : true
}
, 'chess-github' : { priority : 3,
server : `https://github.com`, user : 'baptistdev', path : ``
, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
, title : 'chess-github'
, accessibility : ['external', 'public']
, accessibility : ['public']
, push : 'no-pushing' //, external : true, public : true
}
}
@@ -68,21 +68,21 @@ module.exports = ((name, options)=>{
, get url(){ return `${this.server}/${this.user}/${this.path}`}
// PB : TODO - Other users may have access to this users repo. However that needs to be defined as a new remote
, title : 'userfork-public'
, accessibility : ['public', 'external'] /*public : true, external: true */
, accessibility : ['public'] /*public : true, external: true */
}
// PB : TODO -- Load private repositories from private config...
, 'userfork-private' : { priority : 2,
server : `http://git.bbh`, user : options.username || '', path : ``
, get url(){ return `${this.server}/${options.username}/${this.path}`}
, title : 'userfork-private'
, accessibility : ['private', 'interanl']
, accessibility : ['private']
}
, 'userfork-unc' : {
priority : 3,
server : `//172.16.0.27/repos`, user : `${options.username}`, path : ``
, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
, title : 'userfork-unc'
, accessibility : ['private', 'unc']
, accessibility : ['unc']
// , unc : true, private : true
}
}
@@ -142,9 +142,14 @@ module.exports = ((name, options)=>{
reposervers : Object.keys(reposerverinstances)
, reposerverinstances
, remotes

, repos : [
{ repo : 'elxr' }
]
, get reposindexed(){
// PB : TODO -- Implement -- One time gettor and then cached...
var indexed = {}
this.repos.forEach(r => { indexed[r.repo] = r })
return indexed;
}
, repos : [
{ repo : 'elxr' }
]
}
})

Loading…
Cancel
Save