Browse Source

Remote Add implementation

master
guest 2 years ago
parent
commit
7c2878ce31
4 changed files with 435 additions and 269 deletions
  1. 6
    3
      cliverse.js
  2. 317
    224
      index.js
  3. 1
    1
      lin_verse.js
  4. 111
    41
      repo-manifest.js

+ 6
- 3
cliverse.js View File

@@ -110,13 +110,16 @@ var prompt = function(choices, label, defaultchoice, selectedchoice){
++ci; var choice_label = isNaN(+choice) ? `${ci}) (${choice})` : ci + ')';
return ` ${choice_label} ${choices[choice]} `
}).join('\n')
+ `\n default ( <= ${ defaultchoice || choices[0]} ) : `
+ `\n d) default ( <= ${ defaultchoice || choices[0]} ) : `
+ `\n selected ( <= ${ selectedchoice || defaultchoice || choices[0]} ) : `
).then(choice => {
// propName = promptable.interpret(propValue)
if(!choice) return selectedchoice;
if(!choice && selectedchoice) return selectedchoice;
if(!choice) return defaultchoice || choices[0];
if(choice && isNaN(+choice)) return choice;
if(choice && isNaN(+choice)) {
if(choice === 'd') return defaultchoice || choices[0];
return choice;
}
return choices[(+choice) - 1];
})
}

+ 317
- 224
index.js View File

@@ -297,7 +297,10 @@ var callshelltask = (args) => {
var getCmdString = function(args){ return `"${args[0]} ${args[1].join(' ')}"` }

var getshelltask = (args) => {
return args[0] === 'rm' ? getgitbashtask(args) : () => { return nodeShellExec.apply(null, 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} })
}
}
var getgitbashtask = (args, onEachError) => { return () => {
return nodeShellExec( `"${gitbash}"`, ['-c', getCmdString(args)], args[2]).catch( onEachError || function(e){ console.error(e) }) }
}
@@ -324,10 +327,10 @@ var gitops = {
}
}

var getPullCmd = (repo, branch) => {
var getPullCmd = (repodef, branch) => {
// console.log(useGitPull)var getPullCmd = (repo, branch) => {
// console.log(useGitPull)
var repo = repodef.repo
var pullCmd = []
if(!branch) {
// console.warn('No branch was specified detecting from working client.')
@@ -403,12 +406,41 @@ 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 branchprint = branch ? ' branch :' + branch : '';
var task = ()=>{
console.log('pulling ' + instanceroot + '/' + repo + branchprint )
return nodeShellExec.apply(null, getPullCmd(repo, branch)).then(() => {
return true;
})
return any(tasks).then( ()=>{
return nodeShellExec.apply(null, getPullCmd(repodef, branch)).then(() => {
return true;
})
})
}
initTask(task)

@@ -490,6 +522,10 @@ var dbForLabel = function (label) {
return dbsForLabel[label] || 'mysql'
}

// Maps an environment to a branch. Not required if the branch is appropriately named.
var checkoutMap = { 'development': 'master' }


// SAM : TODO Use nodeshellexec where to detect git installation dir
var gitbash = shell_verse.getbash()
// var gitbash = "G:\\Installed\\Git\\bin\\sh.exe"
@@ -627,6 +663,7 @@ var op = {
// git push origin master

var repo = processedArgs._[1];
var remote = 'origin'

var sequentialTaskShellCommands = [];
if (!existsSync(`Z:/${repo}.git`)) {
@@ -648,10 +685,10 @@ var op = {
, env: process.env
}]
// PB : TODO -- Do this conditionally only...
, ['git', ['remote', 'rename', 'origin', 'githubclone'], { cwd: `${instanceroot + '/' + repo}` }, (err) => {
console.log('Ignoring origin rename error : ' + err); return true; //return true to continue.
, ['git', ['remote', 'rename', remote, 'githubclone'], { cwd: `${instanceroot + '/' + repo}` }, (err) => {
console.log(`Ignoring ${remote} rename error : ` + err); return true; //return true to continue.
}] // PB ; Todo -- new repositories created locally will not have origin. Handle this failure.
, ['git', ['remote', 'add', 'origin', `${selectedinstance.reposerver}/${repo}.git`], { cwd: `${instanceroot + '/' + repo}` }]
, ['git', ['remote', 'add', remote, `${selectedinstance.reposerver}/${repo}.git`], { cwd: `${instanceroot + '/' + repo}` }]
// PB : TODO -- If threre is a gitbubclone origin
// Set the master to pull from the local repo.
]
@@ -665,7 +702,7 @@ var op = {
}
}

sequentialTaskShellCommands.push(['git', ['push', 'origin', 'master'], { cwd: `${instanceroot + '/' + repo}` }])
sequentialTaskShellCommands.push(['git', ['push', remote, 'master'], { cwd: `${instanceroot + '/' + repo}` }])
// console.dir(sequentialTaskShellCommands);

var tasks = [];
@@ -795,50 +832,66 @@ var op = {
var commands = [
// git remote -v| while read remote; do "${remote#origin/}" "$remote"; done
// ['git', ['remote', '-v', '| while read remote; do "${remote#origin/}" "$remote"; done'], utils.assign( {
['git', ['remote', '-v'], utils.assign( {
evaluateResult : function(err, result){
// var found = result.messages.find( (r)=> { return r.includes( __args.remotename ) })
var remotes = []
var found = false;
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
]
}
} , options) ]
[
// 'git', ['remote', '-v']
'git', ['config', `remote.${__args.remotename}.url`]
, utils.assign_core( { arraymergetype : utils.assign_core.DISTINCT_UNION }
, {
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
]
}
} , 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( {
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) ])()
}
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]]
})
}
]
var mapped = commands.map(callshelltask) //.map( p => p.catch(e => e)) // Handle errors later.
return any(mapped).then( allresolved =>{
return any(mapped, true).then( allresolved =>{
console.dir(allresolved)
!allresolved[0][0] && !allresolved[1][0] ? console.log('was not added as a remote and url is currently inaccessible.')
: allresolved[0][0] && allresolved[1][0] ? console.log('was added as a remote and url is accessible.')
@@ -849,6 +902,9 @@ var op = {
: allresolved[0][0] && allresolved[1][0] ? [1, 1] // => was added as a remote and url is accessible.
: allresolved[0][0] && !allresolved[1][0] ? [1, 0] // => was added as a remote but url is currently inaccessible.
: [0, 1] // => was not added and remote and url is accessible.
}).catch(e => {
console.log(e)
return [0, 0]
})
}

@@ -883,6 +939,8 @@ var op = {
Object.keys(remote).forEach(remotename => {
__args.remotename = remotename
__args.url = remote[remotename]
__args.benign = true
__args.ignorefailures = true
promises.push( op['remote exists']( __args ).then( exists => {
if(!exists[0]) {
if(!exists[1]) { console.error( `Skipping inaccessible remote url ${__args.url}` ) }
@@ -918,9 +976,10 @@ var op = {
// alias pullall='for i in `git remote`; do git pull $i; done;'
// args === processedArgs ? args = {} : null;
var __args = {
remotename : args.remotename|| processedArgs._[2]
remotename : args.remotename|| processedArgs._[2]
, url : args.url || processedArgs._[3]
, branch : args.branch || processedArgs._[4]
, 'set-upstream' : args['set-upstream'] || processedArgs._[5]
}
var remotename = __args.remotename
@@ -934,22 +993,23 @@ var op = {
var options = { cwd: instanceroot + '/' + repo }
// console.log(repo)
if (pushable) {
return [
var gacmds = [
['git', ['remote', 'add', remotename, url + '/' + repo], { cwd: instanceroot + '/' + repo }]
, ['git', ['pull', remotename, branch], { cwd: instanceroot + '/' + repo }]
, ['git', ['branch', `--set-upstream-to=${remotename}/${branch}`, branch], { cwd: instanceroot + '/' + repo }]
// , ['git', ['branch', `--set-upstream-to=${remotename}/${branch}`, branch], { cwd: instanceroot + '/' + repo }]
]
}
else {

return [
var gacmds = [
['git', ['remote', 'add', remotename, url + '/' + repo], { cwd: instanceroot + '/' + repo }]
, ['git', ['remote', `set-url`, '--push', remotename, 'no-pushing'], { cwd: instanceroot + '/' + repo }]
, ['git', ['pull', remotename, branch], { cwd: instanceroot + '/' + repo }]
, ['git', ['branch', `--set-upstream-to=${remotename}/${branch}`, branch], { cwd: instanceroot + '/' + repo }]
// When we add a remote it should not automatically become the upstream. The upstream should be a chosen remote else we do not change
// , ['git', ['branch', `--set-upstream-to=${remotename}/${branch}`, branch], { cwd: instanceroot + '/' + repo }]
]
}
if(args['set-upstream']) gacmds.push(['git', ['branch', `--set-upstream-to=${remotename}/${branch}`, branch], { cwd: instanceroot + '/' + repo }])
}
var x = (args) => {
return () => {
@@ -1027,9 +1087,9 @@ var op = {
var options = { cwd: instanceroot + '/' + repo }
// console.log(repo)
return [
['git', ['remote', 'add', 'chess', `${selectedinstance.reposerver}/${user}/${repo}.git`], { cwd: instanceroot + '/' + repo }]
['git', ['remote', 'add', 'chess', `${selectedinstance.reposerver}/${user}/${repo}.git`], { cwd: instanceroot + '/' + repo }]
, ['git', ['remote', 'set-url', '--push', 'chess', 'no-pushing'], { cwd: instanceroot + '/' + repo }]
, ['git', ['remote', 'set-url', 'origin', `${selectedinstance.reposerver}/${user}/${repo}.git`], { cwd: instanceroot + '/' + repo }]
, ['git', ['remote', 'set-url', 'userfork', `${selectedinstance.reposerver}/${user}/${repo}.git`], { cwd: instanceroot + '/' + repo }]
]
}
var x = (args) => {
@@ -1602,8 +1662,6 @@ var op = {
4) Iterates all repos and checkout to the ENV specified. 'git', ['checkout', checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV]
5) Iterates all repos and merge from source configured in mergesource. 'git', ['merge', mergesource],
*/
var runconfig = { NODE_ENV: selectedinstance.node_env }
try { runconfig = Object.assign(runconfig, require(instanceroot + '/run.js')) } catch (e) { }
// We no longer need to check ruans.. ??? if we were initiated from self invoked privileged shell ?
if (( /*processedArgs.runas && processedArgs.runas !== 'self' &&*/ !processedArgs.force) &&
runconfig.NODE_ENV && runconfig.NODE_ENV === (selectedinstance.node_env || runconfig.NODE_ENV) &&
@@ -1651,9 +1709,6 @@ var op = {
// console.log(process.env.cwd)
fs.writeFileSync(instanceroot + '/run.js', 'module.exports = ' + JSON.stringify(runconfig))

// Maps an environment to a branch. Not required if the branch is appropriately named.
var checkoutMap = { 'development': 'master' }

var branch = checkoutMap[runconfig.NODE_ENV] || runconfig.NODE_ENV
var performPullOrCloneForBranch = (def)=>{
@@ -2173,7 +2228,8 @@ var elxrcmd = (function(){
// console.log(o)
subs.forEach(sub=>elxrcmd.create( cmds[subcommandlabelFor(o.cmd, sub)] ))
var created = utils.assign_strict({}, __cmd, cmds[o.cmd], o)
var created = utils.assign_core( { keycase: true, arraymergetype : utils.assign_core.DISTINCT_UNION }
, {}, __cmd, cmds[o.cmd], o)
cmds[o.cmd] = created;
op[o.cmd] = created.cmdFn;
noprerequisites[o.cmd] = created.noprerequisites
@@ -2549,7 +2605,8 @@ var mergeObjByKey = function(arrOfObjs, keyName) {
if(o) (keyedDistinct[o[keyName]] || (keyedDistinct[o[keyName]] = []) ).push(o)
})
Object.keys(keyedDistinct).forEach(key => {
distinctArrOfObjs.push( utils.assign( ...keyedDistinct[key] ) ) // PB : TODO -- Shallow use utils.assign
distinctArrOfObjs.push( utils.assign_core( { arraymergetype : utils.assign_core.DISTINCT_UNION }
, ...keyedDistinct[key] ) ) // PB : TODO -- Shallow use utils.assign
})

return distinctArrOfObjs;
@@ -2563,22 +2620,35 @@ var cacheWriteInstanceConfig = function(chessinstances){
fs.writeFileSync(instanceroot + '/chessinstances.js', 'module.exports = ' + JSON.stringify(chessinstances, null, 2) + '', { 'flag': 'w' })
}


var os = require("os");
var hostname = os.hostname();
var clustername = null; // PB : TODO -- Prompt to acquire.
var configs = (function(){
return {
clusterNodeInstance(selected) { var clusternodename = 'node01'
return __acquireConfig(selected, selected.username, clusternodename
// We need to discover and use the most specialized config available.
// Two passes are required as the config currently cloned may be switched by the discovery.
// If the repo name is the same but has different remotes the newly acquired config from multiple remotes may
// iteself redefine the remotes, repos and servers for the config which we need to honor..
return {
ownerClusterNodeConfig(selected) {
// Hostname and therefore clusternodename can be anything and can participate in many clusters.
// Also many cluster node instance can be running as a set of services on the same host on the same port with ( specific domain names )
var clusternodename = hostname || `CHESS0001${selected.username}`; // Cluster node names need to be unique accross all clusters to avoid collitions.
clustername = clustername || `${selected.username}-CHESS-${selected.node_env}`;
return __acquireConfig(selected, { remote : 'userfork' } // PB : TODO -- accessiblity state should switch to public etc..
, selected.instanceName + '-config-' + 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.');
return e; }
)
}
, ownerInstnace(selected) { return __acquireConfig(selected, selected.username, null, null
, ownerInstnace(selected) { return __acquireConfig(selected, { remote : 'userfork' }
, selected.instanceName + '-config-' + selected.node_env
, function(e){ console.info('Customized user level config not found. This is not an Error. Will attempt global common instance config.');
return e }
)
}
// 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
, 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.') }
) }
, genericChessInstance(selected) { return __acquireConfig(selected) }
@@ -2592,7 +2662,7 @@ var eNotImplemented = function(){

// PB : TODO -- accept additional arg - an array specifying custom configPriority.
var acquireConfig = function(slections){
var configPriority = [ 'clusterNodeInstance', 'ownerInstnace', 'commonInstance' /*, 'genericChessInstance'*/ ]
var configPriority = [ 'ownerClusterNodeConfig', 'ownerInstnace', 'commonInstance' /*, 'genericChessInstance'*/ ]
return any(configPriority.map(cfg => { return function() { return configs[cfg](slections) } } ), true, true).then(()=>{
return acquireData(slections)
})
@@ -2600,21 +2670,24 @@ var acquireConfig = function(slections){

var instanceData = (function(){
return {
clusterNodeInstance(selected) { var clusternodename = 'node01'
return __acquireData(selected, selected.username, clusternodename
ownerClusterNodeData(selected) {
var clusternodename = hostname || `CHESS0001${selected.username}`; // Cluster node names need to be unique accross all clusters to avoid collitions.
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.');
return e; }
)
}
, ownerInstnace(selected) { return __acquireData(selected, selected.username, null
, 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.');
return e }
)
}
// 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 __acquireData(selected, defaultRepoOwner
, commonInstance(selected) { return __acquireData(selected, { defaultRepoOwner }
// , function(e){ console.info('This is probably an error unless the user is asking to create a new instance with this name.') }
) }
, genericChessInstance(selected) { return __acquireData(selected) }
@@ -2622,7 +2695,7 @@ var instanceData = (function(){
})()

var acquireData = function(slections){
var configPriority = [ 'clusterNodeInstance', 'ownerInstnace', 'commonInstance' /*, 'genericChessInstance'*/ ]
var configPriority = [ 'ownerClusterNodeData', 'ownerInstnace', 'commonInstance' /*, 'genericChessInstance'*/ ]
return any(configPriority.map(cfg => { return function() { return instanceData[cfg](slections) } } ), true, true)
}

@@ -2716,12 +2789,12 @@ var execserial = function(tasklist, task, shellT){
var execonce = function(taskArgs, task){ return any([task[1].push.apply(task[1], taskArgs)].map(createTasq)) }


var __acquireConfig = function (selected, owner, clusternodename, configrepo, errHandler) {
var __acquireConfig = function (selected, options, configrepo, errHandler) {

configrepo = configrepo || selected.instanceName + '-config-' + selected.node_env;

var errorHandler = (e) => {
if(e.messages.join(' ').match(new RegExp (`fatal: unable to access '${selectedinstance.reposerver}/${owner}/${configrepo}.git/': Failed to connect to .*? port .*? after .*? ms: Timed out`))){
if(e.messages.join(' ').match(new RegExp (`fatal: unable to access '${selectedinstance.reposerver}/${selected.username || options.defaultRepoOwner}/${configrepo}.git/': Failed to connect to .*? port .*? after .*? ms: Timed out`))){
// console.error('Could not connect to repo server. Timed Out')
return cli.prompt( ['(y)es', '(n)o', '(r)etry'], 'Could not connect to repo server. Timed Out. Would you like to switch server ? (y/n) ', 'y' ).then(propValue => {
@@ -2736,14 +2809,15 @@ var __acquireConfig = function (selected, owner, clusternodename, configrepo, er
})
}

if(e.messages.join(' ').match(new RegExp (`fatal: repository '${selectedinstance.reposerver}/${owner}/${configrepo}.git/' not found`))){
if(e.messages.join(' ').match(new RegExp (`fatal: repository '${selectedinstance.reposerver}/${selected.username || options.defaultRepoOwner}/${configrepo}.git/' not found`))){
var choices = {
t : `install a new temporary local instance with this name ( will not persist ).
Use your own username for additional options. You can request for a username at chess@bbh.org.in )`
, e : 'exit' }

if(selectedinstance.username !== 'guest' && selectedinstance.username !== 'demo') {
choices = utils.assign({
choices = utils.assign_core( { arraymergetype : utils.assign_core.DISTINCT_UNION }
, {
i : 'create a new instance with this name => will fork the default config under your username'
, f : 'fork a new instance with this name for yourself for this node from another instance'
, o : 'fork a new instance with this name for your organization from another instance' // prompt organization name...
@@ -2775,7 +2849,8 @@ var __acquireConfig = function (selected, owner, clusternodename, configrepo, er
var successHandler = () => {

var manifestpath = path.normalize(selected.root + '/' + selected.instanceName + '-config-' + selected.node_env + '/repo-manifest');
utils.assign_strict(selectedinstance, require(manifestpath)( null, selectedinstance))
utils.assign_core( { keycase : true, arraymergetype : utils.assign_core.DISTINCT_UNION }
, selectedinstance, require(manifestpath)( null, selectedinstance))
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...
@@ -2787,14 +2862,20 @@ var __acquireConfig = function (selected, owner, clusternodename, configrepo, er
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(selected, selectedinstance)
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;
}

return performPull({repo : configrepo}, null, owner, errHandler || errorHandler || ((e)=>{ throw e })).then( successHandler )
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 || {} ) }
, null, selected.username || options.defaultRepoOwner, errHandler || errorHandler || ((e)=>{ throw e })).then( successHandler )
.catch( (e)=>{
// if(e){
if(Promise.resolve(e) === e) return e;
@@ -2805,12 +2886,12 @@ var __acquireConfig = function (selected, owner, clusternodename, configrepo, er
})
}

var __acquireData = function (selected, owner, clusternodename, datarepo, errHandler) {
var __acquireData = function (selected, options, datarepo, errHandler) {

datarepo = datarepo || selected.instanceName + '-data';

var errorHandler = (e) => {
if(e.messages.join(' ').match(new RegExp (`fatal: unable to access '${selectedinstance.reposerver}/${owner}/${datarepo}.git/': Failed to connect to .*? port .*? after .*? ms: Timed out`))){
if(e.messages.join(' ').match(new RegExp (`fatal: unable to access '${selectedinstance.reposerver}/${selected.username || options.defaultRepoOwner}/${datarepo}.git/': Failed to connect to .*? port .*? after .*? ms: Timed out`))){
// console.error('Could not connect to repo server. Timed Out')
return cli.prompt( ['(y)es', '(n)o', '(r)etry'], 'Could not connect to repo server. Timed Out. Would you like to switch server ? (y/n) ', 'y' ).then(propValue => {
@@ -2825,14 +2906,15 @@ var __acquireData = function (selected, owner, clusternodename, datarepo, errHan
})
}

if(e.messages.join(' ').match(new RegExp (`fatal: repository '${selectedinstance.reposerver}/${owner}/${datarepo}.git/' not found`))){
if(e.messages.join(' ').match(new RegExp (`fatal: repository '${selectedinstance.reposerver}/${selected.username || options.defaultRepoOwner}/${datarepo}.git/' not found`))){
var choices = {
t : `install a temporary local data folder.
For more options. Request and use a personal username at chess@bbh.org.in )`
, e : 'exit' }

if(selectedinstance.username !== 'guest' && selectedinstance.username !== 'demo') {
choices = utils.assign({
choices = utils.assign_core( { arraymergetype : utils.assign_core.DISTINCT_UNION }
, {
i : 'create a new instance with this name => will fork the default config under your username'
, f : 'fork a new instance with this name for yourself for this node from another instance'
, o : 'fork a new instance with this name for your organization from another instance' // prompt organization name...
@@ -2865,7 +2947,13 @@ var __acquireData = function (selected, owner, clusternodename, datarepo, errHan

}

return performPull({ repo : datarepo }, null, owner, errHandler || errorHandler || ((e)=>{ throw e })).then( successHandler )
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 || {} ) }
, null, selected.username || options.defaultRepoOwner, errHandler || errorHandler || ((e)=>{ throw e })).then( successHandler )
.catch( (e)=>{
// if(e){
if(Promise.resolve(e) === e) return e;
@@ -2911,118 +2999,9 @@ var detectInstanceRoot = any(instancediscoverytasks, true, true).then( ir => {
instanceroot = path.normalize(thisscriptdir) === path.normalize(launchpath) ? path.normalize(thisscriptdir + '/..') : launchpath ;
})


// PB : TODO -- Embed this in the build instead of inlining it.
// Also attepmt to load from ../chess-config/...
var __default = ((name, options)=>{

// Default set of users in main repos.
var users = [
{ username : `${options.username}`, password : `${options.password}` }
, { username : `chess` }
// , { username : `baptistdev`, password : 'encrypted' }
// , { username : `guest`, password : 'encrypted' }
]

// ${options.reposerver} should be used to lookup current config.

// User can always add more branches and remotes as needed. Mainifest only occupies
// well defined namespaces
var remotes = {
// these are both fetch and push remotes. Use push - remotes to override push.
'chess' : {
server : `${options.reposerver}`, user : 'chess', path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
, push : 'no-pushing' }
, 'baptistdev-public' : {
server : `https://github.com`, user : 'baptistdev', path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
, push : 'no-pushing' }

// Multiple urls dont tell us the current origin which may be
// different based on currently available/accessible based on device and client.
// We just treat them as different remotes and merge as needed.
//
, 'origin' : {
server : `${options.reposerver}`, user : '${options.username}', path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
}
, 'origin-public' : {
// export GIT_SSL_NO_VERIFY=true
server : `https://git.bbh.org.in`, user : 'chess', path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
, push : {
server : `${options.reposerver}`, user : `${options.username}`, path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`}
}
}
, 'origin-unc' : {
server : `//172.16.0.27/repos`, user : '${options.username}', path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
}
// , { `${options.username}` : `https://git.bbh.org.in/${options.username}/elxr.git` }
}

// , 'fetch-remotes' : [] // Multiple fetch remotes are not supported by git.
// We therefore need to use
// - a pullall
// - or branch alias for multiple remote branch tracking branch strategy.
// -- This is however limited to corresponding branch names

// tracking branches.
// We at least need one branch for each remote that we wish to track.
// , 'tracking-branches' : [
// { master : ['origin/master', 'chess/master'] }
// ]

var reposerverinstances = {
'http://git.bbh' : { users, remotes }
, 'https://git.bbh.org.in' : { users, remotes, external : true }
, '//172.16.0.27/repos' : { users, remotes }
, 'https://github.com' : {
// We host a miniaml set of repositories in github.
get users() { return [{ username : `${this.username}` }]}, username : `baptistdev`
, remotes : {
'baptistdev-public' : {
server : `https://github.com`, user : 'baptistdev', path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
, push : 'no-pushing' }
// , Add other remotes here.
}
, external : true, public : true
}
}
return {
reposervers : Object.keys(reposerverinstances)
, reposerverinstances

// Common baseline repos for all chess instances.
, 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' }
]
// Requires elevation only in windows
, elevated : [ { repo : 'chess-server-lib', requiresElevation : true } ]
, exludeMergeRepos : { }
}

})(
'__default' // name
, { username : 'guest', instanceName : 'chess', node_env : 'development', reposerver : 'https://git.bbh.org.in' } // options
)
// We first load the default and then override with a runconfig if it exists else we override with the interactive prompts.
// Then acquire and reload and replace this default.


var hasElxr = function(path, options, cb) {
// PB : TOOD -- Navigate up the folder chain to discover the relevant .elxr directory.
options = options || {};
@@ -3184,12 +3163,12 @@ var shouldPrompt = function(k, possiblePrompts, target){

var getBoundEachPrompt = function(target, possiblePrompts, promptables, choices, promptsfilter) {
return function(prompts, k, i, a){
// Reducer for all prompts on targets.
// 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, possiblePrompts, target) ) {
if( shouldPrompt(k, possiblePrompts, target) ) {
delete reconfirm[k];
// console.log(k)
// console.dir(possiblePrompts); //console.dir(target)
@@ -3283,13 +3262,70 @@ var __interactive_prompts = function( target, choices, promptsfilter ){
}
, instanceType : { label : `Enter Instance Type ( <= ${target.instanceType || 'development'} ) : `
, choices : choices['instanceType'], defaultchoice : 'development'
, selectedchoice : target.instanceType
, selectedchoice : target.instanceType || 'development'
}
, reposerver : { label : `Enter Repo Url ( <= ${target.reposerver || 'https://git.bbh.org.in'} ) : `
, choices : choices['reposerver'], defaultchoice : 'https://git.bbh.org.in'
, reposerver : { label : `Enter Repo Server Base Url ( <= ${target.reposerver || 'https://git.bbh.org.in'} ) : `
, get choices() {
choices['reposerver'].forEach( rs => {
var __rs = new URL(rs);
__rs.hostname = __rs.host;
__rs.path = '/'
__rs.method = 'GET'
RESTAPI.get(__rs, function(data){ rs.accessibility = 'unaccessible' }
, function(error){ rs.accessibility = 'unaccessible' } )
})
return choices['reposerver']
}
, defaultchoice : 'https://git.bbh.org.in'
, selectedchoice : target.reposerver
}
, 'upstream-remote' : { label : `Enter Remote Name ( <= ${target['upstream-remote'] || 'chess'} ) : `
, get choices() {
var reposerver = target['reposerver']
var remotes = []
target.reposervers.forEach(rs => {
if(rs.server === reposerver){
remotes.push(remote)
// PB : TODO -- Sort and display highest priority target.remotes.sort( )
}
})
return remotes
}
, defaultchoice : 'userfork'
, selectedchoice : target['upstream-remote'] || 'userfork'
// 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)
// PB : TODO -- Sort and display highest priority target.remotes.sort( )
}
})
// PB : TODO -- Need to generate all possible permuted choices nP( 1 -> n )
// Currenty handles all combinations without any priority order.
var _remotechoices = [] // Array of arrays of choices.
remotenames.forEach( r => {
var __rcs = []
_remotechoices.forEach(rc => {
__rcs.push( rc.concat(r) )
})
Array.prototype.push.apply( _remotechoices, __rcs)
_remotechoices.push(r)
})

return _remotechoices
}
, defaultchoice : ['userfork-public', 'chess-public']
, selectedchoice : target['selectedremotes'] || ['userfork-public', 'chess-public']
// , defaultchoice : { 'userfork-public' : target.remotes['userfork-public'] , 'chess-public' : target.remotes['chess-public'] }
// , selectedchoice : target['selectedremotes'] || { 'userfork-public' : target.remotes['userfork-public'] , 'chess-public' : target.remotes['chess-public'] }
// Info : Just using getters resolves dependencies..., dependencies : [ ()=>{ return target['reposerver'] } ]
}
, get username() { return { label : `Enter User Id for ${target.reposerver} ( <= ${target.username || 'chess'} ) : `
, choices : choices['username'], defaultchoice : 'chess', selectedchoice : target.username } }
, get password() { return { label : `Enter Password for ${target.username} @ ${target.reposerver} ( <= ${target.password || ''} ) : `
@@ -3484,25 +3520,29 @@ function verifyAndInstallPrerequisites() {
var getPromptableAsyncPropDescriptor = function(propName, promptable){
return {
get (){
return cli.prompt( promptable.choices, promptable.label, promptable.defaultchoice, promptable.selectedchoice ).then(propValue => {
var asyncprop = Promise.resolve(propValue)
if(promptable.interpret){
asyncprop = promptable.interpret(propValue)
}
return any( promptable.dependencies || [] ).then(()=>{

return asyncprop.then(
()=>{
Object.defineProperty(this, propName, {
value: propValue,
writable: true,
configurable : true,
enumerable : true
});
return propValue
return cli.prompt( promptable.choices, promptable.label, promptable.defaultchoice, promptable.selectedchoice ).then(propValue => {
var asyncprop = Promise.resolve(propValue)
if(promptable.interpret){
asyncprop = promptable.interpret(propValue)
}
)
})
return asyncprop.then(
()=>{
Object.defineProperty(this, propName, {
value: propValue,
writable: true,
configurable : true,
enumerable : true
});
return propValue
}
)
})
} )

}
// , set (propValue){
// Object.defineProperty(this, propName, {
@@ -3522,8 +3562,9 @@ var getPromptableAsyncPropDescriptor = function(propName, promptable){


function acquirelocalinstances(selected){
// utils.assign is used to cleanup duplicates...
var chessinstances = utils.assign(require(path.normalize(selected.root + '/chessinstances.js')));
// utils.assign is used to cleanup duplicates... assuming chessinstances.js is probably not clean.
var chessinstances = utils.assign_core( { arraymergetype : utils.assign_core.DISTINCT_UNION }
, require(path.normalize(selected.root + '/chessinstances.js')));
return chessinstances
}

@@ -3559,6 +3600,8 @@ function findlocalinstances(chessinstances, instanceoptions){

// function updateselection(selected) { selectedinstance = utils.assign(selectedinstance, selected) }
var selectedinstance = { root : process.env.wd };
var runconfig = null;

var chessinstances = { current_run : {} };
var promptkeys = {
cmd : processedArgs._[0] || 'pull'
@@ -3578,9 +3621,11 @@ function createLocalChessInstance( cfg ){
inst[cfg.node_env] = __new; return inst;
}


var choices = {
'instanceName' : []
, 'reposerver' : []
, 'upstream-remote' : []
, 'instanceType' : []
, username : ['guest', 'chessdemo', 'demo']
}
@@ -3589,6 +3634,7 @@ var getInteractionPoints = function(detectedinstanceoptions, possiblePrompts, pr

var instances = []
var reposervers = [];
var remotes = [];
var instanceNames = []
var instanceTypes = ['development', 'production'];
Object.keys( chessinstances).forEach(instanceName => {
@@ -3600,6 +3646,7 @@ var getInteractionPoints = function(detectedinstanceoptions, possiblePrompts, pr
instances.push(instance)
instanceTypes.push(instance.node_env)
instanceNames.push(instance.instanceName)
Array.prototype.push.apply(remotes, Object.keys(instance.reposerverinstances[instance.reposerver].remotes))
})
})
instances = instances.concat(detectedinstanceoptions)
@@ -3610,6 +3657,7 @@ var getInteractionPoints = function(detectedinstanceoptions, possiblePrompts, pr
choices['instanceName'] = Array.from( new Set(instanceNames.concat(choices['instanceName'])) )
choices['reposerver'] = Array.from( new Set(reposervers.concat(choices['reposerver'])) )
// choices['upstream-remote'] = Array.from( new Set(remotes.concat(choices['upstream-remote'])) )
choices['instanceType'] = Array.from( new Set(instanceTypes.concat(choices['instanceType'])) )

return __interactive_prompts(selectedinstance, choices, promptsfilter)
@@ -3622,6 +3670,7 @@ var detection_state = {
const https = require('https')
const http = require('http');
const { resolve } = require('path');
const { Console } = require('console');
const RESTAPI = (function(){

// Singleton
@@ -3959,10 +4008,12 @@ function initinstances(selected_overrides) {
// __default, chessinstances[current_run], instanceName-config-development, cliargs, interactve_promts
// PB : TODO -- Undefined keys are overriding and deleting values. We should not allow that.
// This is ordinary utils.assign behavior. The key should not exist as undefined in the override.
// PB : TODO -- We now have options that can be passed into assign_core to control this behavior.
if(selected_overrides.node_env === undefined) delete selected_overrides.node_env
selectedinstance = utils.assign(
chessinstances[instanceName][node_env]
selectedinstance = utils.assign_core( { arraymergetype : utils.assign_core.DISTINCT_UNION }
, __default
, chessinstances[instanceName][node_env]
, clioverrides
, selected_overrides
// , __interactive_prompts -- Cant just override. Also need selectedinstance to be ready...
@@ -4166,7 +4217,8 @@ var startElxr = function() {
var cmdprompts = cmdinstance.getPossiblePrompts()
selectedinstance.node_env ? selectedinstance.node_env : selectedinstance.node_env = clioverrides.node_env
// 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_core( { arraymergetype : utils.assign_core.DISTINCT_UNION }
, ...detectedinstanceoptions.slice(-2), promptkeys )
// promptkeys = utils.assign(promptkeys, clioverrides)

if(cmdprompts.instanceName) {
@@ -4220,7 +4272,8 @@ var startElxr = function() {
else return Promise.resolve(true)
})
.then(()=>{

runconfig = { NODE_ENV: selectedinstance.node_env }
try { runconfig = Object.assign(runconfig, require(instanceroot + '/run.js')) } catch (e) { }
generateDependencies();
if(noprerequisites[processedArgs._[0]]
|| skipprereqs[processedArgs._[0]]
@@ -4269,10 +4322,50 @@ var startElxr = function() {
})
}

var __default = null; // 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) {

+ 1
- 1
lin_verse.js View File

@@ -90,7 +90,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 => runElevated ))
return any(batchToRun.map( t => shell_verse.runElevated ))
}

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

+ 111
- 41
repo-manifest.js View File

@@ -1,46 +1,97 @@
module.exports = ((name, options)=>{

options = options || { username : ``, reposerver : `https://git.bbh.org.in` }
utils = options.utils

// Default set of users in main repos.
var users = [
{ username : `${options.username}`, password : `${options.password}` }
, { username : `chess` }
, { username : `guest`}
// , { username : `baptistdev`, password : 'encrypted' }
// , { username : `guest`, password : 'encrypted' }
]

// ${options.reposerver} should be used to lookup current config.

// User can always add more branches and remotes as needed. Mainifest only occupies
// well defined namespaces
var remotes = {
// these are both fetch and push remotes. Use push - remotes to override push.
'chess' : {
server : `${options.reposerver}`, user : 'chess', path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
, push : 'no-pushing' }
, 'baptistdev-public' : {
server : `https://github.com`, user : 'baptistdev', path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
, push : 'no-pushing' }
// User can always add more branches and remotes as needed. Mainifest defines and occupies
// a dictionary of well defined remote names
var remotes = { // these are both fetch and push remotes. Use push - remotes to override push.
'chess' : {
priority : 0,
// PB : TODO -- Handle cases where a repository url can be accessed by multiple users...
server : `${options.reposerver}`, user : options.username || '', path : ``
, get url(){ return `${this.server}/chess/${this.path}`} // fetch
, push : 'no-pushing'
, title : 'chess'
}
, 'chess-public' : { priority : 1,
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']
, push : 'no-pushing'
}
// PB : TODO -- Load private repositories from private config...
, 'chess-private' : { priority : 2,
server : `http://git.bbh`, user : options.username || '', path : ``
, get url(){ return `${this.server}/chess/${this.path}`}
, title : 'chess-private'
, accessibility : ['private', 'internal']
, 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']
, push : 'no-pushing' //, external : true, public : true
}
}
// Multiple urls dont tell us the current origin which may be
// different based on currently available/accessible based on device and client.
// We just treat them as different remotes and merge as needed.
//
, 'origin' : {
server : `${options.reposerver}`, user : '${options.username}', path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
}
, 'origin-public' : {
server : `https://git.bbh.org.in`, user : 'chess', path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
, push : {
server : `${options.reposerver}`, user : `${options.username}`, path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`}

if(options.username) {
utils.assign_core( { arraymergetype : utils.assign_core.DISTINCT_UNION }
, remotes
, { 'userfork' : {
priority : 1,
server : `${options.reposerver}`, user : `${options.username}`, path : ``
, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
, title : 'userfork'
}
, 'userfork-public' : {
priority : 1,
server : `https://git.bbh.org.in`, user : `${options.username}`, path : ``
, 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 */
}
// 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']
}
, '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']
// , unc : true, private : true
}
}
}
, 'origin-unc' : {
server : `//172.16.0.27/repos`, user : '${options.username}', path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
}
// , { `${options.username}` : `https://git.bbh.org.in/${options.username}/elxr.git` }
)
}
// , { `${options.username}` : `https://git.bbh.org.in/${options.username}/elxr.git` }

// PB : TODO --
// , 'fetch-remotes' : [] // Multiple fetch remotes are not supported by git.
// We therefore need to use
// - a pullall
@@ -53,25 +104,44 @@ module.exports = ((name, options)=>{
// { master : ['origin/master', 'chess/master'] }
// ]

// This is a list of all known repositories.
var reposerverinstances = {
'http://git.bbh' : { users, remotes }
, 'https://git.bbh.org.in' : { users, remotes, external : true }
, '//172.16.0.27/repos' : { users, remotes }
, 'https://github.com' : {
// We host a miniaml set of repositories in github.
get users() { return [{ username : `${this.username}` }]}, username : `baptistdev`
, remotes : {
'baptistdev-public' : {
server : `https://github.com`, user : 'baptistdev', path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
, push : 'no-pushing' }
// , Add other remotes here.
}
, external : true, public : true
}
// 'http://git.bbh' : { users, remotes }
// , 'https://git.bbh.org.in' : { users, remotes, external : true }
// , '//172.16.0.27/repos' : { users, remotes }
// , 'https://github.com' : {
// // We host a miniaml set of repositories in github.
// get users() { return [{ username : `${this.username}` }]}, username : `baptistdev`
// , remotes : {
// 'baptistdev-public' : {
// server : `https://github.com`, user : 'bAptistdev', path : ``, get url(){ return `${this.server}/${this.user}/${this.path}`} // fetch
// , push : 'no-pushing' }
// // , Add other remotes here.
// }
// , external : true, public : true
// }
}

Object.keys(remotes).forEach(
(k) => {
var v = remotes[k]
// var reposerverinstances = {}
reposerverinstances[v.server] = reposerverinstances[v.server] || { users : [], remotes : {} };
utils.assign_core( { arraymergetype : utils.assign_core.DISTINCT_UNION }
, reposerverinstances[v.server].users, v.users || [v.user] )
// if(v.server === options.reposerver) v.upstream = true;
reposerverinstances[v.server].remotes[k] = v; // Assign ??
}
)

return {
reposervers : Object.keys(reposerverinstances)
, reposerverinstances
// We need currently active ( as preferred by client ) repositories and remotes...
//
reposervers : Object.keys(reposerverinstances)
, reposerverinstances
, remotes

, repos : [
{ repo : 'elxr' }

Loading…
Cancel
Save