|
|
@@ -412,13 +412,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 ) } |
|
|
|
|
|
|
@@ -494,6 +501,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){ |
|
|
@@ -509,7 +519,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 |
|
|
@@ -521,57 +533,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'], |
|
|
|
{ |
|
|
@@ -603,7 +660,7 @@ var getPullTask = (repodef, branch, repoowner, errHandler, elevatedBatch, regula |
|
|
|
return regularBatch[regularBatch.length-1] |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
initTask(task) |
|
|
|
if(repodef.requiresElevation) { |
|
|
@@ -623,8 +680,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) { |
|
|
@@ -953,58 +1008,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.') |
|
|
@@ -1034,7 +1068,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 = [] |
|
|
@@ -1091,6 +1129,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] |
|
|
@@ -1102,7 +1141,6 @@ var op = { |
|
|
|
|
|
|
|
var pushable = processedArgs.pushable || false; |
|
|
|
|
|
|
|
|
|
|
|
var serial_perform_git_add = (repo) => { |
|
|
|
var options = { cwd: instanceroot + '/' + repo } |
|
|
|
// console.log(repo) |
|
|
@@ -1124,14 +1162,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) |
|
|
@@ -1140,18 +1174,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) => { |
|
|
|
|
|
|
@@ -1166,19 +1199,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}`) |
|
|
@@ -1194,6 +1221,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' |
|
|
@@ -1206,13 +1321,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) |
|
|
@@ -1220,9 +1329,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) => { |
|
|
@@ -1230,8 +1339,6 @@ var op = { |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
const { readdir } = require("fs").promises |
|
|
|
|
|
|
|
dirs(perform_init_gitea) |
|
|
|
} |
|
|
|
, 'syncmaster': (label) => { |
|
|
@@ -2282,6 +2389,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' |
|
|
@@ -2737,6 +2852,8 @@ function elxrworker() { |
|
|
|
// // }) |
|
|
|
// } |
|
|
|
|
|
|
|
|
|
|
|
// PB : TODO -- Move this to utils assign... as an array merge option. |
|
|
|
var mergeObjByKey = function(arrOfObjs, keyName) { |
|
|
|
|
|
|
|
var keyedDistinct = {} |
|
|
@@ -2756,8 +2873,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' }) |
|
|
|
} |
|
|
|
|
|
|
@@ -2790,9 +2908,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) } |
|
|
|
} |
|
|
|
})() |
|
|
|
|
|
|
@@ -2816,13 +2960,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 } |
|
|
|
) |
|
|
|
} |
|
|
@@ -2991,7 +3135,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... |
|
|
@@ -3011,11 +3156,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){ |
|
|
@@ -3088,12 +3229,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){ |
|
|
@@ -3436,13 +3572,21 @@ 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){ |
|
|
|
// remotes.push(rname) |
|
|
|
if(r.server === reposerver && r.accessibility.find( target[ 'remote-type' ] )){ |
|
|
|
remotes.push(rname) |
|
|
|
// PB : TODO -- Sort and display highest priority target.remotes.sort( ) |
|
|
|
} |
|
|
|
}) |
|
|
@@ -4168,11 +4312,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 } }) |
|
|
|
} |
|
|
@@ -4412,7 +4556,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) |
|
|
|
}) |
|
|
@@ -4467,50 +4652,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) { |