Browse Source

Added remote refresh

production
chess 3 years ago
parent
commit
198d10d237
3 changed files with 140 additions and 70 deletions
  1. 4
    2
      cliverse.js
  2. 126
    56
      index.js
  3. 10
    12
      repo-manifest.js

+ 4
- 2
cliverse.js View File

child.on('close', (code) => { child.on('close', (code) => {
// console.log('Proper close was fired') // console.log('Proper close was fired')
var logEntry = { code, success } var logEntry = { code, success }
if(+code !== 0 || opts.haserrors) { success = false; logEntry = { result: `${opts.title} exited with code ${code}`, success, code }};
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(opts.stdio !== 'ignore') { if(opts.stdio !== 'ignore') {
logEntry = { result: `${opts.title} exited with code ${code}`, messages, code } logEntry = { result: `${opts.title} exited with code ${code}`, messages, code }
logEntry.success = success; logEntry.success = success;
if(opts.evaluateResult) logEntry = opts.evaluateResult(success, logEntry);
if(opts.runas){ if(opts.runas){
// success ? logEntry.success = true : null; // success ? logEntry.success = true : null;
fs.writeFileSync('run.log', ', ' + JSON.stringify(logEntry), {'flag':'a+'} ) fs.writeFileSync('run.log', ', ' + JSON.stringify(logEntry), {'flag':'a+'} )

+ 126
- 56
index.js View File

// } // }
// }) // })


var clioverrides = { }
processedArgs._[1] ? clioverrides.instanceName = processedArgs._[1]: null;
processedArgs.node_env ? clioverrides.node_env = processedArgs.node_env
: (process.env.NODE_ENV && process.env.NODE_ENV.trim())
? clioverrides.node_env = (process.env.NODE_ENV && process.env.NODE_ENV.trim()) : null;
var subcommandlabels = {
remote : (`remote ${processedArgs._[1] || ''}`).trim()
}

var interpretrun = function(){

var cmds = {
'remote' : function() {
return { cmd : subcommandlabels['remote'], runchoice : 'c' }
}
}

var cmd = processedArgs._[0];
var clioverrides = { cmd }
processedArgs.node_env ? clioverrides.node_env = processedArgs.node_env
: (process.env.NODE_ENV && process.env.NODE_ENV.trim())
? clioverrides.node_env = (process.env.NODE_ENV && process.env.NODE_ENV.trim()) : null;
return cmds[cmd] ? cmds[cmd]() : (function(){

processedArgs._[1] ? clioverrides.instanceName = processedArgs._[1]: null;
return clioverrides
})()
}


Object.keys(clioverrides).forEach( prop => { })

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

// Object.keys(clioverrides).forEach( prop => { })


var globSync = require('glob').sync; var globSync = require('glob').sync;




// Directory shallow walk and do perform on each dir. // Directory shallow walk and do perform on each dir.
const dirs = async (perform, path) => { const dirs = async (perform, path) => {
for (const dir of await readdir(path || process.cwd(), { withFileTypes: true })) {
for (const dir of await readdir(path || selectedinstance.root, { withFileTypes: true })) {
if (dir.isDirectory()) perform(dir) if (dir.isDirectory()) perform(dir)
} }
} }


var getShellTask = (command, args, options) => { var getShellTask = (command, args, options) => {
options = options || {} options = options || {}
var callshell = command === 'rm' ? callgitbashtask : callsheltask;
var callshell = command === 'rm' ? getgitbashtask : getshelltask;
return () => { return () => {
var p = callshell( [command, args, Object.assign({ var p = callshell( [command, args, Object.assign({
inherit: true, shell: true, env: ENV, title: `${command} ${args}` inherit: true, shell: true, env: ENV, title: `${command} ${args}`
} }
} }


var callsheltask = (args) => {
return args[0] === 'rm' ? callgitbashtask(args) : () => { return nodeShellExec.apply(null, args) } }
var callgitbashtask = (args) => { return () => {
var callshelltask = (args) => {
console.dir(args)
return getshelltask(args)() }

var getshelltask = (args) => {
return args[0] === 'rm' ? getgitbashtask(args) : () => { return nodeShellExec.apply(null, args) } }
var getgitbashtask = (args) => { return () => {
return nodeShellExec( `"${gitbash}"`, ['-c', `"${args[0]} ${args[1].join(' ')}"`], args[2]) } return nodeShellExec( `"${gitbash}"`, ['-c', `"${args[0]} ${args[1].join(' ')}"`], args[2]) }
} }


var parameters = ['-c', 'branch=`git rev-parse --abbrev-ref HEAD`;for i in `git remote`; do git pull $i $branch; done;'] var parameters = ['-c', 'branch=`git rev-parse --abbrev-ref HEAD`;for i in `git remote`; do git pull $i $branch; done;']
var cmd = [gitbash var cmd = [gitbash
, ['-c', 'branch=`git rev-parse --abbrev-ref HEAD`;for i in `git remote`; do git pull $i $branch; done;'] , ['-c', 'branch=`git rev-parse --abbrev-ref HEAD`;for i in `git remote`; do git pull $i $branch; done;']
, { cwd: instanceroot + '/' + repo, title: 'pull all origins for ' + repo + ' ' + parameters.join(' ') }]
, { cwd: instanceroot + '/' + repo, title: 'discoverbranch for ' + repo + ' ' + parameters.join(' ') }]
return cmd return cmd
} }
} }
var pullCmd = [] var pullCmd = []
if(!branch) { if(!branch) {
// console.warn('No branch was specified detecting from working client.') // console.warn('No branch was specified detecting from working client.')
// First check if working client exits.
// First check if working client exists.
// if (existsSync(instanceroot + '/' + repo)) { // if (existsSync(instanceroot + '/' + repo)) {
pullCmd= gitops.getdiscoverbranchcmd(repo) pullCmd= gitops.getdiscoverbranchcmd(repo)
// } // }
} }
// var pullCmd = [gitInstallDir // var pullCmd = [gitInstallDir
// , ['-c', 'branch=`git rev-parse --abbrev-ref HEAD`;for i in `git remote`; do git pull $i $branch; done;'] // , ['-c', 'branch=`git rev-parse --abbrev-ref HEAD`;for i in `git remote`; do git pull $i $branch; done;']
// , { cwd: instanceroot + '/' + repo, title: 'pull all origins for ' + repo }]
// , { cwd: instanceroot + '/' + repo, title: 'pull all remotes for ' + repo }]
if(branch) { if(branch) {
var parameters = ['-c', 'for i in `git remote`; do git pull $i ' + branch + '; done;'] var parameters = ['-c', 'for i in `git remote`; do git pull $i ' + branch + '; done;']
var pullCmd = [ gitbash var pullCmd = [ gitbash
, ['-c', 'for i in `git remote`; do git pull $i ' + branch + '; done;'] , ['-c', 'for i in `git remote`; do git pull $i ' + branch + '; done;']
, { cwd: instanceroot + '/' + repo, title : 'pull all origins for ' + branch + ' ' + repo + ' ' + parameters.join(' ') }]
, { cwd: instanceroot + '/' + repo, title : 'pull all remotes for ' + branch + ' ' + repo + ' ' + parameters.join(' ') }]
} }
// var pullCmd = ['pullall', [], { cwd : repo }] // var pullCmd = ['pullall', [], { cwd : repo }]
if (useGitPull) pullCmd = ['git', ['pull'], { if (useGitPull) pullCmd = ['git', ['pull'], {
, 'remote': (args) => { , 'remote': (args) => {
// Subcommands! // Subcommands!
// PB : TODO -- we can now pass in hypehnated args...
if(!processedArgs.v) return false; // Only -v is supported presently.. if(!processedArgs.v) return false; // Only -v is supported presently..


var serial_perform = (repo) => { var serial_perform = (repo) => {


dirs(perform_git_seturl) dirs(perform_git_seturl)
} }
, 'reset' : ()=>{
// Reset the whole installation pertaining to this elxr folder.
// , 'reset' : ()=>{
// PB : TODO -- Cant have 2 resets !!
// // Reset the whole installation pertaining to this elxr folder.
}
// }


, 'remote exists': (args) => { , 'remote exists': (args) => {
var __args = { var __args = {
, branch : args.branch || processedArgs._[4] , branch : args.branch || processedArgs._[4]
} }


var command = ['git', ['remote', '-v']]
return nodeShellExec.apply(null, command).then(result=>{
return result.messages.find( (r)=> { return r.includes( __args.remotename ) })
var options = args.repo ? { cwd: instanceroot + '/' + args.repo } : {}

// PB : TODO -- We should evaluate a whole list of remotes passed in from args instead of just one.
var commands = [
['git', ['remote', '-v'], utils.assign( {
evaluateResult : function(err, result){
return [
result.messages.find( (r)=> { return r.includes( __args.remotename ) })
, result
]
}
} , options) ]
, ['git', ['ls-remote', __args.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) ]
]
var mapped = commands.map(callshelltask).map( p => p.catch(e => e)) // Handle errors later.
return Promise.all(mapped).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.')
: allresolved[0][0] && !allresolved[1][0] ? console.log('was added as a remote but url is currently inaccessible.')
: console.log('was not added as a remote but url is currently accessible.')
return !allresolved[0][0] && !allresolved[1][0] ? [0, 0]
: 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.
}) })
} }




// use the repo manifest to create missing remotes. // use the repo manifest to create missing remotes.
function perform_remote_refresh(dir){ function perform_remote_refresh(dir){

var repo = dir.name var repo = dir.name
var dscoverbranchcmd = gitops.getdiscoverbranchcmd(repo) var dscoverbranchcmd = gitops.getdiscoverbranchcmd(repo)
var remotes = require(`${dir.name}/repo-manifest.js`)( null, { repouser : selectedinstance.repouser }).remotes;
try {
var remotes = require(`${selectedinstance.root}/${dir.name}/repo-manifest.js`)( null, selectedinstance).remotes || [];
}
catch(e){
var remotes = []
}
// console.log(`${dir.name}/repo-manifest.js` + '---------------------------')
// console.dir(remotes)


return nodeShellExec.apply(null, dscoverbranchcmd(repo)).then(__branch=>{
return nodeShellExec.apply(null, dscoverbranchcmd).then(__branch=>{
console.log('Processing : ' + dir.name)
var branch = __branch var branch = __branch
__args.repo = repo
__args.branch = __branch
var promises = [] var promises = []


remotes.foreach(remote =>{
remotes.forEach(remote =>{
Object.keys(remote).forEach(remotename => { Object.keys(remote).forEach(remotename => {
promises.push( op['remote exists'].then( exists => {
if(!exits) {
return op['remote add']( { remotename,
__args.remotename = remotename
__args.url = remote[remotename]
promises.push( op['remote exists']( __args ).then( exists => {
if(!exists[0]) {
if(!exists[1]) { console.error( `Skipping inaccessible remote url ${__args.url}` ) }
else return op['remote add']( { remotename,
// PB : TODO -- use the most accessible remote instead of the first available. // PB : TODO -- use the most accessible remote instead of the first available.
url : (utils.js.isArray(remote[remotename]) ? remote[remotename][0] : remote[remotename]), branch url : (utils.js.isArray(remote[remotename]) ? remote[remotename][0] : remote[remotename]), branch
} ) } )


return Promise.all(promises) return Promise.all(promises)
}) })
.catch((e) => { console.error(e); return { error: true, message: repo } })
.catch((e) => { console.log('Processing Error : ' + dir.name); console.error(e); return { error: true, message: repo } })
} }
dirs(perform_remote_refresh)

return dirs(perform_remote_refresh)
} }
, 'remote add': (args) => { , 'remote add': (args) => {
// PB : TODO -- set-upstream-to should be chosen and intentionally switched. Coz we can have multiple upstream remotes. // PB : TODO -- set-upstream-to should be chosen and intentionally switched. Coz we can have multiple upstream remotes.
// , ['git', ['commit', '-a', '-m', `relocate folder ${args.folder} to ${targetrepo}`], sourcerepooptions ] // , ['git', ['commit', '-a', '-m', `relocate folder ${args.folder} to ${targetrepo}`], sourcerepooptions ]
] ]


return any(cmdseq.map(callsheltask))
return any(cmdseq.map(getshelltask))
}) })
}).catch(e=>{console.error(e)}) }).catch(e=>{console.error(e)})
} }
, ['git', ['clone', `${args.remotebase}${args.targetrepo}`, `relocate-${args.targetrepo}-${args.folder}`], options] , ['git', ['clone', `${args.remotebase}${args.targetrepo}`, `relocate-${args.targetrepo}-${args.folder}`], options]
] ]
return any(cmdseq.map(callsheltask)).then(() => {
return any(cmdseq.map(getshelltask)).then(() => {
// , ['git', ['subtree', 'split', '-P', `${args.folder}`, '-b', `relocate-${args.sourcerepo}-${args.folder}`], sourcerepooptions] // , ['git', ['subtree', 'split', '-P', `${args.folder}`, '-b', `relocate-${args.sourcerepo}-${args.folder}`], sourcerepooptions]
// split doesnt retain folder structure we need to move and commit ourselves through a branch to retain history... // split doesnt retain folder structure we need to move and commit ourselves through a branch to retain history...
// , ['git', [`checkout relocate-${args.sourcerepo}-${args.folder}`], sourcerepooptions] // , ['git', [`checkout relocate-${args.sourcerepo}-${args.folder}`], sourcerepooptions]
, targetrepooptions ] , targetrepooptions ]
// , ['git', ['push', targetrepooptions ] // manual push for now.. // , ['git', ['push', targetrepooptions ] // manual push for now..
] ]
return any(cmdseq.map(callsheltask)).catch(e=>{console.error(e)})
return any(cmdseq.map(getshelltask)).catch(e=>{console.error(e)})
} }


, 'filter-repo' : function(args){ , 'filter-repo' : function(args){
// git remote add src-project ../src-project // git remote add src-project ../src-project
['git', ['filter-repo', '--path', `${args.folder}`], targetrepooptions ] ['git', ['filter-repo', '--path', `${args.folder}`], targetrepooptions ]
] ]
return any(cmdseq.map(callsheltask)).catch(e=>{console.error(e); throw 'failed' })
return any(cmdseq.map(getshelltask)).catch(e=>{console.error(e); throw 'failed' })
} }


, 'filter-branch' : function(preservefolder, repo){ , 'filter-branch' : function(preservefolder, repo){
if (!branch) { if (!branch) {
var dscoverbranchcmd = gitops.getdiscoverbranchcmd(repo) var dscoverbranchcmd = gitops.getdiscoverbranchcmd(repo)
promise = nodeShellExec.apply(null, dscoverbranchcmd(repo)).then(__branch=>{ branch = __branch})
promise = nodeShellExec.apply(null, dscoverbranchcmd).then(__branch=>{ branch = __branch})
.catch((e) => { console.error(e); return { error: true, message: repo } }) .catch((e) => { console.error(e); return { error: true, message: repo } })
} }
// Checkout is reduced to pull provided the current branch is the targetbranch // Checkout is reduced to pull provided the current branch is the targetbranch
if(branch === mergesource) performCheckout = (def) => { if(branch === mergesource) performCheckout = (def) => {
var dscoverbranchcmd = gitops.getdiscoverbranchcmd(repo) var dscoverbranchcmd = gitops.getdiscoverbranchcmd(repo)
return nodeShellExec.apply(null, dscoverbranchcmd(repo)).then(__branch=>{
return nodeShellExec.apply(null, dscoverbranchcmd).then(__branch=>{
if(branch === __branch) return performCloneAndCheckout(def) if(branch === __branch) return performCloneAndCheckout(def)
return performPullOrCloneForBranch(def) return performPullOrCloneForBranch(def)
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
`) `)
} }
, getpulltask(def){
, getpulltask(args){


// def can be an instance config // def can be an instance config
// Or an object with many repos and elevated repos // Or an object with many repos and elevated repos
// var parameters = ['-c', 'for i in `git remote`; do git pull $i ' + branch + '; done;'] // var parameters = ['-c', 'for i in `git remote`; do git pull $i ' + branch + '; done;']
// var pullCmd = [ gitbash // var pullCmd = [ gitbash
// , ['-c', 'for i in `git remote`; do git pull $i ' + branch + '; done;'] // , ['-c', 'for i in `git remote`; do git pull $i ' + branch + '; done;']
// , { cwd: instanceroot + '/' + repo, title : 'pull all origins for ' + branch + ' ' + repo + ' ' + parameters.join(' ') }]
// , { cwd: instanceroot + '/' + repo, title : 'pull all remotes for ' + branch + ' ' + repo + ' ' + parameters.join(' ') }]






def = def || {
var def = args || {
repos : selectedinstance.repos, repos : selectedinstance.repos,
elevated : selectedinstance.elevated elevated : selectedinstance.elevated
} }


// The main elxr cli process // The main elxr cli process
function elxrworker() { function elxrworker() {
var subcommandlabels = {
remote : (`remote ${processedArgs._[1] || ''}`).trim()
}


var __runcmd = function (label) { var __runcmd = function (label) {
var distinquishedlabel = subcommandlabels[label] || label var distinquishedlabel = subcommandlabels[label] || label
instanceroot = detected.root instanceroot = detected.root
__default.root = root; __default.root = root;
clioverrides.root = clioverrides.root || root; clioverrides.root = clioverrides.root || root;
// Resolves empty array when No known instances detected. // Resolves empty array when No known instances detected.
return Promise.resolve(instanceoptions) return Promise.resolve(instanceoptions)
}) })
return any([any(steps), any(prompts)]) return any([any(steps), any(prompts)])
} }
, installsteps: function () { , installsteps: function () {
return any([this.installcmd].map(callsheltask))
return any([this.installcmd].map(getshelltask))
} }
, postinstallsteps: function(){ , postinstallsteps: function(){
['git', ['config', '--global', '--add', 'user.name', `${gitUser}`]] ['git', ['config', '--global', '--add', 'user.name', `${gitUser}`]]
, ['git', ['config', '--global', '--add', 'user.email', `${gitEmail}`]] , ['git', ['config', '--global', '--add', 'user.email', `${gitEmail}`]]
] ]
return any(steps.map(callsheltask)).then(() => {
return any(steps.map(getshelltask)).then(() => {


}) })
}); });
, verifyAndInstall : function(){ , verifyAndInstall : function(){
return getTaskCheckExists(this.shellcmd, { ignorefailures: true })().then((exists) => { return getTaskCheckExists(this.shellcmd, { ignorefailures: true })().then((exists) => {
if(exists) { if(exists) {
// return any(['git', ['config', '--global', '-l']].map(callsheltask))
// return any(['git', ['config', '--global', '-l']].map(getshelltask))
return this.getUser(null, this.postinstallsteps.bind(this)) return this.getUser(null, this.postinstallsteps.bind(this))
} }
return this.install(); return this.install();
if(!repo) globalOrLocal = '--global'; if(!repo) globalOrLocal = '--global';
else globalOrLocal = '--local' else globalOrLocal = '--local'


return any([['git', ['config', globalOrLocal, '--get-all', 'user.name']]].map(callsheltask)).then((result)=>{
return any([['git', ['config', globalOrLocal, '--get-all', 'user.name']]].map(getshelltask)).then((result)=>{
// not yet configured. // not yet configured.
if(!result.success) return onNoResult() if(!result.success) return onNoResult()
else { else {
, installcmd: ['MSIEXEC.exe', ['/i' , installcmd: ['MSIEXEC.exe', ['/i'
, path.resolve(downloadsdir + '/' + 'node-v14.16.0-x64.msi') , path.resolve(downloadsdir + '/' + 'node-v14.16.0-x64.msi')
, 'ACCEPT=YES', '/passive']] , 'ACCEPT=YES', '/passive']]
, install : function() { return any([this.installcmd].map(callsheltask)).then(() => { }) }
, install : function() { return any([this.installcmd].map(getshelltask)).then(() => { }) }
} }
] ]


const retaincount = 2 const retaincount = 2
var min = runtimestamp; var min = runtimestamp;
var collect = [] var collect = []
if(noprerequisites[processedArgs._[0]]
|| skipprereqs[processedArgs._[0]]
) {
return elxrworker()
}
// if(noprerequisites[processedArgs._[0]]
// || skipprereqs[processedArgs._[0]]
// ) {
// return elxrworker()
// }


var getchoices = function(detectedinstanceoptions, promptkeys){ var getchoices = function(detectedinstanceoptions, promptkeys){


} }


return detectinstances().then((detectedinstanceoptions)=>{ return detectinstances().then((detectedinstanceoptions)=>{
detectedinstanceoptions.splice(0,0, __default) detectedinstanceoptions.splice(0,0, __default)


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



+ 10
- 12
repo-manifest.js View File

// User can always add more branches and remotes as needed. Mainifest only occupies // User can always add more branches and remotes as needed. Mainifest only occupies
// well defined namespaces // well defined namespaces
, remotes : [ , remotes : [
// these are both fetch and push remotes. Use push - remotes to overrid.
{ 'chess' : 'http://git.bbh/chess/elxr.git' }
, { 'public-baptistdev' : 'https://github.com/baptistdev/elxr.git' }
// these are both fetch and push remotes. Use push - remotes to override push.
{ 'chess' : `${options.reposerver}/chess/elxr.git` }
, { 'public-github-baptistdev' : 'https://github.com/baptistdev/elxr.git' }
// Multiple urls as an array doesn't tell us the current origin which may be different in
// different based on currently available/accessible to client.
// This is just a list of possible equivalent options.
, { 'origin' : [
`http://git.bbh/${options.repouser}/elxr.git`
, `https://git.bbh.org.in/${options.repouser}/elxr.git`
, `//172.16.0.27/repos/${options.repouser}/elxr.git`
]
}
// 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' : `${options.reposerver}/${options.repouser}/elxr.git` }
, { 'origin-public' : `https://git.bbh.org.in/${options.repouser}/elxr.git` }
, { 'origin-unc' : `//172.16.0.27/repos/${options.repouser}/elxr.git` }
] ]


, 'push-remotes' : [ , 'push-remotes' : [

Loading…
Cancel
Save