Browse Source

Merge branch 'master' of http://git.bbh/chess/elxr

master^2
pb 3 years ago
parent
commit
079dc7b7b4
6 changed files with 200 additions and 354 deletions
  1. 0
    240
      cliargs.js
  2. 173
    113
      index.js
  3. BIN
      jdk-12.0.2.zip
  4. 2
    1
      package.json
  5. 22
    0
      repolog.js
  6. 3
    0
      windowselevate.hta

+ 0
- 240
cliargs.js View File

@@ -1,240 +0,0 @@
// -------------------------------
// Command line option parsing
// -------------------------------
function cliargs(args, opts) {
if (!opts) opts = {};
var flags = { bools : {}, strings : {}, unknownFn: null };

if (typeof opts['unknown'] === 'function') {
flags.unknownFn = opts['unknown'];
}

if (typeof opts['boolean'] === 'boolean' && opts['boolean']) {
flags.allBools = true;
} else {
[].concat(opts['boolean']).filter(Boolean).forEach(function (key) {
flags.bools[key] = true;
});
}
var aliases = {};
Object.keys(opts.alias || {}).forEach(function (key) {
aliases[key] = [].concat(opts.alias[key]);
aliases[key].forEach(function (x) {
aliases[x] = [key].concat(aliases[key].filter(function (y) {
return x !== y;
}));
});
});

[].concat(opts.string).filter(Boolean).forEach(function (key) {
flags.strings[key] = true;
if (aliases[key]) {
flags.strings[aliases[key]] = true;
}
});

var defaults = opts['default'] || {};
var argv = { _ : [] };
Object.keys(flags.bools).forEach(function (key) {
setArg(key, defaults[key] === undefined ? false : defaults[key]);
});
var notFlags = [];

if (args.indexOf('--') !== -1) {
notFlags = args.slice(args.indexOf('--')+1);
args = args.slice(0, args.indexOf('--'));
}

function argDefined(key, arg) {
return (flags.allBools && /^--[^=]+$/.test(arg)) ||
flags.strings[key] || flags.bools[key] || aliases[key];
}

function setArg (key, val, arg) {
if (arg && flags.unknownFn && !argDefined(key, arg)) {
if (flags.unknownFn(arg) === false) return;
}

var value = !flags.strings[key] && isNumber(val)
? Number(val) : val
;
setKey(argv, key.split('.'), value);
(aliases[key] || []).forEach(function (x) {
setKey(argv, x.split('.'), value);
});
}

function setKey (obj, keys, value) {
var o = obj;
keys.slice(0,-1).forEach(function (key) {
if (o[key] === undefined) o[key] = {};
o = o[key];
});

var key = keys[keys.length - 1];
if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') {
o[key] = value;
}
else if (Array.isArray(o[key])) {
o[key].push(value);
}
else {
o[key] = [ o[key], value ];
}
}
function aliasIsBoolean(key) {
return aliases[key].some(function (x) {
return flags.bools[x];
});
}

for (var i = 0; i < args.length; i++) {
var arg = args[i];
if (/^--.+=/.test(arg)) {
// Using [\s\S] instead of . because js doesn't support the
// 'dotall' regex modifier. See:
// http://stackoverflow.com/a/1068308/13216
var m = arg.match(/^--([^=]+)=([\s\S]*)$/);
var key = m[1];
var value = m[2];
if (flags.bools[key]) {
value = value !== 'false';
}
setArg(key, value, arg);
}
else if (/^--no-.+/.test(arg)) {
var key = arg.match(/^--no-(.+)/)[1];
setArg(key, false, arg);
}
else if (/^--.+/.test(arg)) {
var key = arg.match(/^--(.+)/)[1];
var next = args[i + 1];
if (next !== undefined && !/^-/.test(next)
&& !flags.bools[key]
&& !flags.allBools
&& (aliases[key] ? !aliasIsBoolean(key) : true)) {
setArg(key, next, arg);
i++;
}
else if (/^(true|false)$/.test(next)) {
setArg(key, next === 'true', arg);
i++;
}
else {
setArg(key, flags.strings[key] ? '' : true, arg);
}
}
else if (/^-[^-]+/.test(arg)) {
var letters = arg.slice(1,-1).split('');
var broken = false;
for (var j = 0; j < letters.length; j++) {
var next = arg.slice(j+2);
if (next === '-') {
setArg(letters[j], next, arg)
continue;
}
if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) {
setArg(letters[j], next.split('=')[1], arg);
broken = true;
break;
}
if (/[A-Za-z]/.test(letters[j])
&& /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) {
setArg(letters[j], next, arg);
broken = true;
break;
}
if (letters[j+1] && letters[j+1].match(/\W/)) {
setArg(letters[j], arg.slice(j+2), arg);
broken = true;
break;
}
else {
setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg);
}
}
var key = arg.slice(-1)[0];
if (!broken && key !== '-') {
if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1])
&& !flags.bools[key]
&& (aliases[key] ? !aliasIsBoolean(key) : true)) {
setArg(key, args[i+1], arg);
i++;
}
else if (args[i+1] && /true|false/.test(args[i+1])) {
setArg(key, args[i+1] === 'true', arg);
i++;
}
else {
setArg(key, flags.strings[key] ? '' : true, arg);
}
}
}
else {
if (!flags.unknownFn || flags.unknownFn(arg) !== false) {
argv._.push(
flags.strings['_'] || !isNumber(arg) ? arg : Number(arg)
);
}
if (opts.stopEarly) {
argv._.push.apply(argv._, args.slice(i + 1));
break;
}
}
}
Object.keys(defaults).forEach(function (key) {
if (!hasKey(argv, key.split('.'))) {
setKey(argv, key.split('.'), defaults[key]);
(aliases[key] || []).forEach(function (x) {
setKey(argv, x.split('.'), defaults[key]);
});
}
});
if (opts['--']) {
argv['--'] = new Array();
notFlags.forEach(function(key) {
argv['--'].push(key);
});
}
else {
notFlags.forEach(function(key) {
argv._.push(key);
});
}

return argv;
};

function hasKey (obj, keys) {
var o = obj;
keys.slice(0,-1).forEach(function (key) {
o = (o[key] || {});
});

var key = keys[keys.length - 1];
return key in o;
}

function isNumber (x) {
if (typeof x === 'number') return true;
if (/^0x[0-9a-f]+$/i.test(x)) return true;
return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x);
}

module.exports = cliargs;

+ 173
- 113
index.js View File

@@ -1,4 +1,7 @@

var repolog = require('./repolog')
var path = require('path');
var utils = require('bbhverse');
var any = utils.any;
// 'use strict';

// PB : TODO -- make sure folder context is proper coz we can now run elxr from anywhere.
@@ -18,7 +21,7 @@
const { existsSync } = require('fs');
const fs = require('fs')
const { spawn, spawnSync } = require('child_process');
const cliargs = require('../elxr/cliargs'); // Use minimist...
const cliargs = utils.cliargs;
const processedArgs = cliargs(process.argv.slice(2));
console.dir(processedArgs)
var globSync = require('glob').sync;
@@ -28,8 +31,9 @@ const { isMaster } = require('cluster');

// Default Config...
var reposervers = [
'http://git.bbh'
, '//172.16.0.27/repos'
'http://git.bbh'
, 'https://git.bbh.org.in'
, '//172.16.0.27/repos'
]
var defaultRepoServer = reposervers[0]

@@ -38,84 +42,6 @@ var defaultRepoOwner = 'chess';

// PB : TODO -- If we are run from an elevated shell it never moves forward and simply exits.
// -- Currently workaround is to always run from a non-elevated shell.

// Serialize a set of functions that will execute to return a promises one after the other.
// Will stop when any one fails unless continueOnFailure is true.
// All tasks in iterables can be functions or promises.
// promises as usual can return other promises or resolve to either truthy or falsy values.
// functions must return a promise
function any(iterable, continueOnFailure) {
return iterable.reduce(
(p, fn, i ,a) => {
// console.log('accumulator :');
// console.log(p);
if(Promise.resolve(p) === p ) {
return p.then((pVal) => {



// Falsy values are task failure.
if(!pVal) {
console.warn('Possible failure for result : ' + pVal)
console.warn(a[i-1])
fn ? console.error("Fn : " + fn.toString()) : null;
}

// Truthy values are failures if obj has error=true.
if(pVal && pVal.error) { console.error('Failed : ' + pVal.message + ' ' + pVal) }

if(Promise.resolve(pVal) === pVal) {
// Passed in function retured a promise. We still need to wait for it.
pVal.then((pVal)=>{

// console.log('Then --pVal = ' + pVal + ' bContinue = ' + continueOnFailure ); console.log(p);
if(!pVal && !continueOnFailure) {
console.error(`E1 : i = ${i} : pVal :` + pVal);
console.error('debugData 2 -------------------');
console.log("Cancelling remaining...");
throw 'Failed in reduce 1 '
}
if(!fn && !continueOnFailure) { console.error('Error : No task specified.'); throw false;}
else if(!fn) return false;
return (Promise.resolve(fn) === fn ) ? fn : fn() ;
})
}
else {

// We will stop on null resolved values on any one task unless continueOnFailure is true.
// console.log('Then --pVal = ' + pVal + ' bContinue = ' + continueOnFailure ); console.log(p);
if(!pVal && !continueOnFailure) {
console.error(`E2 : i = ${i} : pVal :` + pVal);
console.error('debugData 2 -------------------');
console.log("Cancelling remaining...");
throw 'Failed in reduce 2 '
}
if(!fn && !continueOnFailure) { console.error('Error : No task specified.'); throw false;}
else if(!fn) return false;
return (Promise.resolve(fn) === fn ) ? fn : fn() ;
}

}).catch((error) => {
console.error(`E3 : i = ${i} `);
fn ? console.error("Fn : " + fn.toString()) : null;
console.error('debugData 3-------------------------');

throw 'Failed in reduce 3 '
})
}
else if(!p) {
console.log("Bypass on failure");
return false;
}
}
, Promise.resolve(true)
);
}

var __isElevated = null;
var isRunningElevated = ()=>{
if(__isElevated === null) {
@@ -173,7 +99,7 @@ var gitRepos = [
, 'loopback-jsonapi-model-serializer'
, 'elixir-config-development'
, 'elixir-config-test'
, 'cihsr-config'
, 'cihsr-config-development'
, 'cihsr-data'
, 'elixir-data'
, 'loopback-connector-ds'
@@ -209,7 +135,7 @@ var exludeMergeRepos = {
var productionRepos = [
'elixir-config-production'
]
var productionIsAllowed = true;
var productionIsAllowed = (process.env.NODE_ENV === 'production');
if(productionIsAllowed) gitRepos = gitRepos.concat(productionRepos)

var env = Object.assign({}, process.env); // Shallow clone it.
@@ -456,6 +382,48 @@ var __runcmd = function(label){
, 'is-git-repo' : (dir)=>{
return nodeShellExec('git', ['-C', dir.name, 'rev-parse'], { stdio : 'ignore'})
}
, 'set-url' : (remotename, url) => {
var pushable = processedArgs.pushable || false;
remotename = remotename || processedArgs._[1]
url = url || processedArgs._[2]
var serial_perform_git_seturl = (repo)=>{
var options = { cwd : repo }
// console.log(repo)
if(pushable) {
return [
['git', ['remote', 'set-url', remotename, url + '/' + repo], { cwd : repo }]
]
}
else {
console.error('not supported for non-pushable')
}

}
var x = (args)=>{
return ()=>{
// console.log(args)
return nodeShellExec.apply(null, args)
}
// return Promise.resolve(true)
}
var perform_git_seturl = (dir)=>{
op['is-git-repo'](dir).then((code)=>{
any( serial_perform_git_seturl(dir.name).map(x) )
}).catch((e)=>{
// console.log('Failed : ' + dir.name)
})
}

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

const dirs = async (perform, path) => {
for (const dir of await readdir(path || process.cwd(), { withFileTypes: true })) {
if (dir.isDirectory()) perform(dir)
}
}

dirs( perform_git_seturl)
}
, 'add' : (remotename, url, branch) => {
var pushable = processedArgs.pushable || false;
remotename = remotename || processedArgs._[1]
@@ -566,9 +534,9 @@ var __runcmd = function(label){
var options = { cwd : repo }
// console.log(repo)
return [
['git', ['remote', 'add', 'chess', 'http://git.bbh/chess/elxr.git'], { cwd : repo }]
['git', ['remote', 'add', 'chess', `${defaultRepoServer}/${user}/${repo}.git`], { cwd : repo }]
, ['git', ['remote', 'set-url', '--push', 'chess', 'no-pushing'], { cwd : repo }]
, ['git', ['remote', 'set-url', 'origin', `http://git.bbh/${user}/${repo}.git`], { cwd : repo }]
, ['git', ['remote', 'set-url', 'origin', `${defaultRepoServer}/${user}/${repo}.git`], { cwd : repo }]
]}
var x = (args)=>{
return ()=>{
@@ -722,20 +690,24 @@ var __runcmd = function(label){
return pullCmd
}

var errors = [];
var performPull = (repo) => {
if(existsSync(repo)) {
console.log('pulling ' + repo)
return nodeShellExec.apply(null, getPullCmd(repo)).catch((e)=>{ console.error(e) })
return nodeShellExec.apply(null, getPullCmd(repo)).then((srepo)=>{
repolog.statuslog(null, srepo)}).catch((e)=>{ console.error(e) })
}
else {
console.log('cloning ' + repo)
// PB : TODO -- detect if a clonable repo exists in currentGitAuthUser
return nodeShellExec('git', ['clone', '-c', 'core.symlinks=true', defaultRepoServer + `/${defaultRepoOwner}/` + repo + '.git'],
{
inherit : true, shell: true,
env: process.env
, runas : processedArgs.runas
}).catch((e)=>{ console.error(e) }).then(()=>{
}).catch((e)=>{
errors.push({ repo , e})
console.error(e)
}).then(()=>{

return nodeShellExec('git', ['config', '--replace-all' , 'core.symlinks', true],
{
@@ -749,7 +721,15 @@ var __runcmd = function(label){
}
}

if(!processedArgs.runas) gitRepos.forEach(performPull)
if(!processedArgs.runas) {
var pendingpulls = [];
gitRepos.forEach( (r)=>{
pendingpulls.push(performPull(r))
} )
Promise.all(pendingpulls).then(results =>{
console.log(repolog.log.SUCCESS)
})
}
return isRunningElevated().then(
(isElevated) => {
if(isElevated) {
@@ -775,6 +755,33 @@ var __runcmd = function(label){
}
, 'npmi' : ()=>{
var tasks = [];
var bowerRepos = ['client']

var npmbuildrepos = ['loopback-jsonapi-model-serializer']
npmbuildrepos.forEach(repo => {
tasks.push(()=>{
var p = nodeShellExec('npm', ['run build'], {
inherit : true, shell: true
, cwd : repo
, env: process.env
, title : `bower i for ${repo}`
}).catch((e)=>{ console.error(e) })
return p;
})
})
bowerRepos.forEach(repo => {
tasks.push(()=>{
var p = nodeShellExec('bower', ['install'], {
inherit : true, shell: true
, cwd : repo
, env: process.env
, title : `bower i for ${repo}`
}).catch((e)=>{ console.error(e) })
return p;
})
})
gitRepos = gitRepos.concat(elevatedRunasRepos);
gitRepos.push('client/server');
gitRepos.forEach(repo => {
console.log('npm i for ' + repo)
@@ -790,15 +797,18 @@ var __runcmd = function(label){
, env: process.env
, title : `rm 'package-lock.json' for ${repo}`
}).catch((e)=>{ console.error(e) })
tasks.push(()=>{
var p = nodeShellExec('npm', ['i'], {
inherit : true, shell: true
, cwd : repo
, env: process.env
, title : `npm i for ${repo}`
}).catch((e)=>{ console.error(e) })
return p;
})

if( npmbuildrepos.indexOf(repo) != -1) {
tasks.push(()=>{
var p = nodeShellExec('npm', ['i --force'], {
inherit : true, shell: true
, cwd : repo
, env: process.env
, title : `npm i for ${repo}`
}).catch((e)=>{ console.error(e) })
return p;
})
}
})
any(tasks);
@@ -1116,7 +1126,9 @@ var __runcmd = function(label){
if(0){
// PB : TODO -- Special google chrome profile for tests etc.
nodeShellExec('pwd', { inherit : true});
//$ "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --profile-directory="Profile 1" http://localhost:4200/tests/index.html?grep=loopback
// /c/Program\ Files\ \(x86\)/Google/Chrome/Application/chrome.exe --user-data-dir=/c/chess/instances/elixir_01/data/Google/Chrome/User\ Data --profile-directory="chess"
// "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --user-data-dir="C:\chess\instances\elixir_01\data\Google\Chrome\User Data" --profile-directory="chess" http://localhost:4200/admin/crud/create/item
// "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --user-data-dir="C:\chess\instances\elixir_01\data\Google\Chrome\User Data" --profile-directory="chess" http://localhost:4200/tests/index.html?grep=loopback
nodeShellExec("C:/Program Files (x86)/Google/Chrome/Application/chrome.exe", [
"--profile-directory=Profile 1"
, 'http://localhost:4200/tests/index.html?grep=model convert ember to loopback' + '&filter=none' /*+ '&filter=model convert ember to loopback'*/]);
@@ -1126,19 +1138,68 @@ var __runcmd = function(label){
// nodeShellExec('npm', ['init', '-y'], options);
// })

var g = {
'client' : ()=>{
console.info('Creating new ember client named : ' + processedArgs._[2] ) ;
var step1 = nodeShellExec('cmd', ['/c', 'ember', 'new', processedArgs._[2]], {
stdio: ['pipe', process.stdout, process.stderr],
inherit : true,
shell: true,
cwd : path.dirname(__dirname),
env: env
})
}
var g = {
'client' : ()=>{
console.info('Creating new ember client named : ' + processedArgs._[2] ) ;
var step1 = nodeShellExec('cmd', ['/c', 'ember', 'new', processedArgs._[2]], {
stdio: ['pipe', process.stdout, process.stderr],
inherit : true,
shell: true,
cwd : path.dirname(__dirname),
env: env
})
},

'modelr' : ()=>{
var tasks = [
()=>{
var p = nodeShellExec('"ember"', [
'g'
, 'modelr'
, processedArgs._[2]], {
inherit : true, shell: true, env: process.env
}).then(()=>{
console.log('Blueprint generation complete for : ' + processedArgs._[2])
return true;
}).catch((e)=>{ console.error(e) })
return p;
},
()=>{
var chromePrefsFile = "C:\\chess\\instances\\elixir_01\\data\\Google\\Chrome\\User Data\\chess\\Preferences";
var chromeprefs = fs.readFileSync(chromePrefsFile, { encoding: 'utf8' })
chromeprefs = JSON.parse(chromeprefs)
var previous = chromeprefs.download.default_directory;
var parentDir = path.dirname(__dirname);
chromeprefs.download.default_directory = parentDir + "\\client\\app\\templates\\components\\resource";
fs.writeFileSync(chromePrefsFile, JSON.stringify(chromeprefs))
// PB : TODO -- detect where chrome is installed.
// PB : TODO -- set the download dir to the place where files are needed.
var p = nodeShellExec('"C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"', [
'--user-data-dir="C:\\chess\\instances\\elixir_01\\data\\Google\\Chrome\\User Data"'
, '--profile-directory="chess"'
, 'http://localhost:4200/admin/crud/create/' + processedArgs._[2]], {
inherit : true, shell: true
, env: process.env
}).then(()=>{
chromeprefs.download.default_directory = previous;
fs.writeFileSync(chromePrefsFile, JSON.stringify(chromeprefs))
return true;
}).catch((e)=>{ console.error(e) })
return p;
}
,
()=>{
console.log('Browser process should have closed here....')
return true;
}
]
any(tasks)
}
g[processedArgs._[1]]();

}

g[processedArgs._[1]]();
}
}
return op[label] ? op[label]() : null;
@@ -1204,4 +1265,3 @@ function nodeShellExec() {
p.process = child;
return p;
}


BIN
jdk-12.0.2.zip View File


+ 2
- 1
package.json View File

@@ -11,7 +11,8 @@
"license": "ISC",
"dependencies": {
"tree-kill": "^1.2.2",
"glob": "^7.1.2"
"glob": "^7.1.2",
"bbhverse": "file:../bbhverse"
},
"bin": {
"elxr": "bin/elxr"

+ 22
- 0
repolog.js View File

@@ -0,0 +1,22 @@
var log = {
SUCCESS : []
, ERROR : []
, FAIL : []
}

var statuslog = function (err, data){
if(err)
{
log.ERROR.push(data)
}
else
{
log.SUCCESS.push(data)
}
}

module.exports = {
'log' : log
, 'statuslog' : statuslog
}

+ 3
- 0
windowselevate.hta View File

@@ -38,7 +38,10 @@
var cargs = (processedArgs.debug ? '--inspect-brk=9228' : '') + ' elxr ' + processedArgs._.join(' ') + ' ' + namedArgs.join(' ');
// alert(cargs)
var shell = new ActiveXObject('shell.application');
// alert('launching node privilged. ' + processedArgs['nodepath'])
// shell.ShellExecute('where', 'node', '', '', 10);
shell.ShellExecute('node', cargs, '', 'runas', 1);
// shell.ShellExecute(processedArgs['nodepath'], cargs, '', 'runas', 1);
var fso = new ActiveXObject('Scripting.FileSystemObject');
window.onload = function() {

Loading…
Cancel
Save