@makano/rew 1.4.6 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/rew/cli/cli.js +4 -0
- package/lib/rew/cli/helpers.js +5 -1
- package/lib/rew/cli/utils.js +144 -3
- package/lib/rew/functions/exec.js +1 -1
- package/lib/rew/functions/stdout.js +76 -0
- package/lib/rew/functions/types.js +32 -2
- package/lib/rew/modules/context.js +1 -1
- package/lib/rew/pkgs/conf.js +3 -0
- package/lib/rew/pkgs/modules/threads/worker.js +1 -1
- package/lib/rew/pkgs/threads.js +3 -3
- package/package.json +4 -2
package/lib/rew/cli/cli.js
CHANGED
|
@@ -302,6 +302,10 @@ yargs(hideBin(process.argv))
|
|
|
302
302
|
alias: 'u',
|
|
303
303
|
describe: 'Update the app',
|
|
304
304
|
type: 'boolean',
|
|
305
|
+
}).option('clean', {
|
|
306
|
+
alias: 'c',
|
|
307
|
+
describe: 'Clean intall the app',
|
|
308
|
+
type: 'boolean',
|
|
305
309
|
}).option('yes', {
|
|
306
310
|
alias: 'y',
|
|
307
311
|
describe: 'Auto yes',
|
package/lib/rew/cli/helpers.js
CHANGED
|
@@ -9,6 +9,9 @@ const logspath = path.join(conf({}).create('').root, '.logs');
|
|
|
9
9
|
const cachepath = path.join(conf({}).create('').root, '.cache');
|
|
10
10
|
const localBinPath = path.join(binpath, '../../../', 'bin');
|
|
11
11
|
|
|
12
|
+
const FILE_DL_EXTRACT_REGEX = /^file\+sha\(([^)]+)\)\+([a-zA-Z0-9_-]+)(\([^\)]*\))?:(.*)$|^file\+([a-zA-Z0-9_-]+)(\([^\)]*\))?:(.*)$/;
|
|
13
|
+
|
|
14
|
+
|
|
12
15
|
if (!fs.existsSync(CONFIG_PATH) || !fs.existsSync(CONFIG_PATH + '/repos.yaml')) {
|
|
13
16
|
fs.mkdirSync(CONFIG_PATH, { recursive: true });
|
|
14
17
|
log('First time init');
|
|
@@ -66,5 +69,6 @@ module.exports = {
|
|
|
66
69
|
localBinPath,
|
|
67
70
|
npm_package_name,
|
|
68
71
|
getAllPipeInput,
|
|
69
|
-
hashTags
|
|
72
|
+
hashTags,
|
|
73
|
+
FILE_DL_EXTRACT_REGEX
|
|
70
74
|
}
|
package/lib/rew/cli/utils.js
CHANGED
|
@@ -21,10 +21,13 @@ const {
|
|
|
21
21
|
logspath,
|
|
22
22
|
cachepath,
|
|
23
23
|
localBinPath,
|
|
24
|
-
hashTags
|
|
24
|
+
hashTags,
|
|
25
|
+
FILE_DL_EXTRACT_REGEX
|
|
25
26
|
} = require('./helpers');
|
|
26
27
|
const { input } = require('../functions/stdout');
|
|
27
28
|
|
|
29
|
+
|
|
30
|
+
|
|
28
31
|
module.exports = {
|
|
29
32
|
conf(command, fullPath, key, value) {
|
|
30
33
|
const con = conf({});
|
|
@@ -399,8 +402,8 @@ module.exports = {
|
|
|
399
402
|
if(command == 'list'){
|
|
400
403
|
console.log(fs.readdirSync(cachepath).join('\n').trim());
|
|
401
404
|
} else if(command == 'clear'){
|
|
402
|
-
if(file) fs.rmSync(path.join(cachepath, file), { recursive: true });
|
|
403
|
-
else if(file == 'all') fs.readdirSync(cachepath).forEach(file => fs.rmSync(path.join(cachepath, file), { recursive: true }));
|
|
405
|
+
if(file && file !== 'all') fs.rmSync(path.join(cachepath, file), { recursive: true });
|
|
406
|
+
else if(file == 'all' || !file) fs.readdirSync(cachepath).forEach(file => fs.rmSync(path.join(cachepath, file), { recursive: true }));
|
|
404
407
|
} else if(command == 'install'){
|
|
405
408
|
if(!file) return process.exit(1);
|
|
406
409
|
this.installApp(path.join(cachepath, file, 'clone'), {
|
|
@@ -496,8 +499,146 @@ module.exports = {
|
|
|
496
499
|
const repos = conf({}).create('').optionCenter('repos');
|
|
497
500
|
return repos.get(repo);
|
|
498
501
|
},
|
|
502
|
+
isCommandAvailable(command) {
|
|
503
|
+
try {
|
|
504
|
+
execSync(`command -v ${command}`, { stdio: 'ignore' });
|
|
505
|
+
return true;
|
|
506
|
+
} catch (e) {
|
|
507
|
+
return false;
|
|
508
|
+
}
|
|
509
|
+
},
|
|
510
|
+
downloadFileFromUrl(url, dest, sha, opts) {
|
|
511
|
+
const isCurlAvailable = this.isCommandAvailable('curl');
|
|
512
|
+
const isWgetAvailable = this.isCommandAvailable('wget');
|
|
513
|
+
|
|
514
|
+
if (!isCurlAvailable && !isWgetAvailable) {
|
|
515
|
+
log(` Failed to download: Nither curl nor wget command were found.`.red.bold, ':end');
|
|
516
|
+
return false;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
if(opts.c || opts.clean){
|
|
520
|
+
if(fs.existsSync(dest)) fs.rmSync(dest);
|
|
521
|
+
}
|
|
522
|
+
let tries = 0;
|
|
523
|
+
|
|
524
|
+
const checkSha = (throwErr) => {
|
|
525
|
+
if(sha){
|
|
526
|
+
const thisSha = execSync(`sha256sum "${dest}"`).toString().split(' ')[0];
|
|
527
|
+
if(thisSha === sha){
|
|
528
|
+
return true;
|
|
529
|
+
} else {
|
|
530
|
+
if(throwErr) {
|
|
531
|
+
log(` Failed to verify file checksum, ${tries == 0 ? 'trying again...' : 'try again.'}`.red.bold, ':end');
|
|
532
|
+
fs.rmSync(dest);
|
|
533
|
+
tries++;
|
|
534
|
+
if(tries < 2) return tryDl();
|
|
535
|
+
}
|
|
536
|
+
return false;
|
|
537
|
+
}
|
|
538
|
+
} else return true;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
const downloadCommand = isCurlAvailable
|
|
542
|
+
? `curl -L -o "${dest}" "${url}"`
|
|
543
|
+
: `wget -O "${dest}" "${url}"`;
|
|
544
|
+
|
|
545
|
+
const tryDl = () => {
|
|
546
|
+
try {
|
|
547
|
+
if(fs.existsSync(dest)){
|
|
548
|
+
return checkSha(true);
|
|
549
|
+
} else {
|
|
550
|
+
execSync(downloadCommand, { stdio: opts.verbose ? 'inherit' : 'ignore' });
|
|
551
|
+
return checkSha(true);
|
|
552
|
+
}
|
|
553
|
+
} catch(e){
|
|
554
|
+
log(` Failed to download ${url}: ${e.name}: ${e.message}.`.red.bold, ':end');
|
|
555
|
+
return false;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
return tryDl();
|
|
560
|
+
},
|
|
561
|
+
downloadFile(fullPath, opts){
|
|
562
|
+
const pathToDownloadInto = path.join(cachepath, 'rew-file-download-'+gen_key(fullPath).substring(0, 12));
|
|
563
|
+
|
|
564
|
+
const commandMatch = fullPath.match(FILE_DL_EXTRACT_REGEX);
|
|
565
|
+
|
|
566
|
+
let shaHash = null;
|
|
567
|
+
let command = null;
|
|
568
|
+
let args = [];
|
|
569
|
+
let url = null;
|
|
570
|
+
|
|
571
|
+
if (commandMatch) {
|
|
572
|
+
// If sha() is present in the format file+sha(SHA-AAAA)+command(args):URL
|
|
573
|
+
if (commandMatch[1]) {
|
|
574
|
+
shaHash = commandMatch[1];
|
|
575
|
+
command = commandMatch[2];
|
|
576
|
+
args = commandMatch[3] ? commandMatch[3].slice(1, -1).split(' ') : [];
|
|
577
|
+
url = commandMatch[4];
|
|
578
|
+
} else {
|
|
579
|
+
command = commandMatch[5];
|
|
580
|
+
args = commandMatch[6] ? commandMatch[6].slice(1, -1).split(' ') : [];
|
|
581
|
+
url = commandMatch[7];
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
fs.mkdirSync(pathToDownloadInto, { recursive: true });
|
|
585
|
+
} else {
|
|
586
|
+
log(` Format not correct`.red.bold, ':end');
|
|
587
|
+
process.exit(1);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
const fileName = path.basename(url);
|
|
591
|
+
const filePath = path.join(pathToDownloadInto, fileName);
|
|
592
|
+
|
|
593
|
+
const extractPath = path.join(pathToDownloadInto, 'extract');
|
|
594
|
+
if(opts.c || opts.clean || opts.u){
|
|
595
|
+
if(fs.existsSync(extractPath)) execSync(`rm -rf ${extractPath}`);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
const fixedArgs = args.join(' ')
|
|
599
|
+
.replaceAll('$path', extractPath)
|
|
600
|
+
.replaceAll('$file', filePath) || (
|
|
601
|
+
command == 'unzip' ?
|
|
602
|
+
`${filePath} -d ${extractPath}` :
|
|
603
|
+
`${filePath} ${extractPath}`
|
|
604
|
+
);
|
|
605
|
+
|
|
606
|
+
if(opts.verbose){
|
|
607
|
+
log('Download started for'.cyan, url.yellow, 'at'.cyan, filePath.yellow, shaHash ? 'with sha'.cyan : '', shaHash ? shaHash.yellow : '');
|
|
608
|
+
} else {
|
|
609
|
+
log(`Downloading`.cyan, fileName.yellow);
|
|
610
|
+
}
|
|
611
|
+
const downloaded = fs.existsSync(extractPath) ? true : this.downloadFileFromUrl(url, filePath, shaHash, opts);
|
|
612
|
+
if(downloaded){
|
|
613
|
+
log(`Download Complete for`.cyan, fileName.yellow);
|
|
614
|
+
log('Extracting'.cyan, fileName.yellow);
|
|
615
|
+
if(opts.verbose){
|
|
616
|
+
log('Running command:'.cyan, command.green.bold, 'for'.cyan, filePath.yellow, 'at'.cyan, extractPath.yellow);
|
|
617
|
+
}
|
|
618
|
+
if(this.isCommandAvailable(command)){
|
|
619
|
+
try{
|
|
620
|
+
if(fs.existsSync(extractPath)) {
|
|
621
|
+
log('Found Extracted Directory'.cyan);
|
|
622
|
+
} else execSync(`${command} ${fixedArgs}`, {
|
|
623
|
+
stdio: opts.verbose ? 'inherit' : 'ignore'
|
|
624
|
+
});
|
|
625
|
+
} catch(e){
|
|
626
|
+
log(` Failed to extract`.red.bold, ':end');
|
|
627
|
+
return null;
|
|
628
|
+
}
|
|
629
|
+
} else {
|
|
630
|
+
log(` Command "${command}" not found.`.red.bold, ':end');
|
|
631
|
+
return null;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
return extractPath;
|
|
635
|
+
} else {
|
|
636
|
+
return null;
|
|
637
|
+
}
|
|
638
|
+
},
|
|
499
639
|
async installAppFrom(path, opts) {
|
|
500
640
|
if (path.startsWith('github:')) this.installApp(await this.cloneGit(path, opts), opts, true);
|
|
641
|
+
if (path.match(FILE_DL_EXTRACT_REGEX)) this.installApp(this.downloadFile(path, opts), opts, true);
|
|
501
642
|
else if (path.startsWith('@')) this.fromRepo(path, opts);
|
|
502
643
|
else this.installApp(path, opts, null, null);
|
|
503
644
|
},
|
|
@@ -1,10 +1,86 @@
|
|
|
1
1
|
const { spawnSync } = require('child_process');
|
|
2
|
+
const r = require('colors')
|
|
3
|
+
|
|
4
|
+
const baseAnsii = '\x1b';
|
|
5
|
+
const fg = {
|
|
6
|
+
o: ["30", '39'],
|
|
7
|
+
r: ["31", '39'],
|
|
8
|
+
g: ["32", '39'],
|
|
9
|
+
y: ["33", '39'],
|
|
10
|
+
b: ["34", '39'],
|
|
11
|
+
m: ["35", '39'],
|
|
12
|
+
c: ["36", '39'],
|
|
13
|
+
w: ["37", '39'],
|
|
14
|
+
a: ["90", '39']
|
|
15
|
+
}
|
|
16
|
+
const bg = {
|
|
17
|
+
O: ["40", '49'],
|
|
18
|
+
R: ["41", '49'],
|
|
19
|
+
G: ["42", '49'],
|
|
20
|
+
Y: ["43", '49'],
|
|
21
|
+
B: ["44", '49'],
|
|
22
|
+
M: ["45", '49'],
|
|
23
|
+
C: ["46", '49'],
|
|
24
|
+
W: ["47", '49'],
|
|
25
|
+
A: ["48", '49']
|
|
26
|
+
}
|
|
27
|
+
const styles = {
|
|
28
|
+
"!": ["1", '22'], // bold
|
|
29
|
+
"'": ["2", '22'], // dim
|
|
30
|
+
"/": ["3", '23'], // italic
|
|
31
|
+
"_": ["4", '24'], // underline
|
|
32
|
+
"i": ["7", '27'],
|
|
33
|
+
"h": ["8", '28'],
|
|
34
|
+
"-": ["9", '29'],
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const findStyle = (name) => {
|
|
38
|
+
return styles[name] || bg[name] || fg[name];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const addColorize = (applied) => {
|
|
42
|
+
return `${baseAnsii}[${applied.fg}m${applied.bg ? `${baseAnsii}[${applied.bg}m` : ''}${applied.style ? `${baseAnsii}[${applied.style}m` : ''}`
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const colorize = (baseString = '') => {
|
|
46
|
+
const applied = {
|
|
47
|
+
style: '',
|
|
48
|
+
fg: "39",
|
|
49
|
+
bg: "49",
|
|
50
|
+
};
|
|
51
|
+
const stringParts = baseString.replace(/%([orgybmcwaORGYBMCWA!'\/_ih-])/gmi, (_, col) => {
|
|
52
|
+
const val = findStyle(col);
|
|
53
|
+
if(!val) return _;
|
|
54
|
+
const tag = col in styles ? 'style' :
|
|
55
|
+
col in fg ? 'fg' : 'bg';
|
|
56
|
+
if(applied[tag] == val[0]){
|
|
57
|
+
applied[tag] = val[1];
|
|
58
|
+
} else {
|
|
59
|
+
applied[tag] = val[0];
|
|
60
|
+
}
|
|
61
|
+
return addColorize(applied);
|
|
62
|
+
});
|
|
63
|
+
return stringParts + addColorize({
|
|
64
|
+
style: '',
|
|
65
|
+
fg: "39",
|
|
66
|
+
bg: "49",
|
|
67
|
+
});
|
|
68
|
+
}
|
|
2
69
|
|
|
3
70
|
(module.exports.print = function print(...args) {
|
|
71
|
+
if(!args.some(i => typeof i !== "string")){
|
|
72
|
+
args = [args.join(' ')]
|
|
73
|
+
}
|
|
74
|
+
if(typeof args[0] === "string" && args[0].startsWith('%c')){
|
|
75
|
+
args[0] = colorize(args[0]);
|
|
76
|
+
}
|
|
4
77
|
return console.log(...args);
|
|
5
78
|
});
|
|
6
79
|
|
|
7
80
|
module.exports.printf = function printf(buffer, cb) {
|
|
81
|
+
if(typeof buffer === "string" && buffer.startsWith('%c')){
|
|
82
|
+
buffer = colorize(buffer);
|
|
83
|
+
}
|
|
8
84
|
return process.stdout.write(buffer, cb);
|
|
9
85
|
};
|
|
10
86
|
|
|
@@ -41,7 +41,7 @@ function typedef(value, strict = false) {
|
|
|
41
41
|
});
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function typef(fn, returnType) {
|
|
44
|
+
function typef(fn, returnType, argumentsTypes) {
|
|
45
45
|
if(typeof returnType == "function"){
|
|
46
46
|
const ref = fn;
|
|
47
47
|
fn = returnType;
|
|
@@ -51,7 +51,17 @@ function typef(fn, returnType) {
|
|
|
51
51
|
throw new Error('First argument must be a function');
|
|
52
52
|
}
|
|
53
53
|
if (typeof returnType == 'function' && returnType.type instanceof Type) returnType = returnType.type;
|
|
54
|
+
const requiredArguments = Array.isArray(argumentsTypes) ? argumentsTypes.filter(i => Array.isArray(i) ? !i.includes(null) : true) : [];
|
|
54
55
|
const wrappedFn = function(...args){
|
|
56
|
+
if(argumentsTypes && Array.isArray(argumentsTypes)){
|
|
57
|
+
if(args.length !== requiredArguments.length && args.length !== argumentsTypes.length){
|
|
58
|
+
throw new TypeError(`Function ${fn.name || '<anonymous>'} takes exactly ${requiredArguments.length} parameters`)
|
|
59
|
+
}
|
|
60
|
+
const argumentsTyped = typeAre(args, argumentsTypes);
|
|
61
|
+
if(argumentsTyped !== false){
|
|
62
|
+
throw new TypeError(`Function ${fn.name || '<anonymous>'} call error: Parameter at index ${argumentsTyped} is of the wrong type`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
55
65
|
const result = fn.call(this, ...args);
|
|
56
66
|
if(!typeis(result, wrappedFn.returnType)){
|
|
57
67
|
throw new TypeError(`Function ${fn.name || '<anonymous>'} does not return it's own return type.`);
|
|
@@ -60,13 +70,32 @@ function typef(fn, returnType) {
|
|
|
60
70
|
}
|
|
61
71
|
wrappedFn.returnType = returnType;
|
|
62
72
|
wrappedFn.type = returnType;
|
|
73
|
+
wrappedFn.argumentsTypes = argumentsTypes;
|
|
63
74
|
return wrappedFn;
|
|
64
75
|
}
|
|
65
|
-
typef.is = function(func, returnType){
|
|
76
|
+
typef.is = function(func, returnType, argumentsTypes){
|
|
66
77
|
return typeis(func.returnType.defaultValue, returnType);
|
|
67
78
|
}
|
|
68
79
|
|
|
80
|
+
const typeAre = (values, types) => {
|
|
81
|
+
const verified = values.map((t, i) => Array.isArray(types[i]) ? (types[i].map((t2) => typeis(t, t2)).includes(true)) : typeis(t, types[i]));
|
|
82
|
+
const hasWrong = verified.indexOf(false);
|
|
83
|
+
return hasWrong > -1 ? hasWrong : false;
|
|
84
|
+
}
|
|
85
|
+
|
|
69
86
|
function typeis(obj, typeDef, missingObjects = false) {
|
|
87
|
+
|
|
88
|
+
if(obj == null && typeDef === null) return true;
|
|
89
|
+
else if(obj == null) return false;
|
|
90
|
+
if(obj == undefined && typeDef === undefined) return true;
|
|
91
|
+
else if(obj == undefined) return false;
|
|
92
|
+
|
|
93
|
+
if(typeDef == null && obj === null) return true;
|
|
94
|
+
else if(typeDef == null) return false;
|
|
95
|
+
|
|
96
|
+
if(typeDef == undefined && obj === undefined) return true;
|
|
97
|
+
else if(typeDef == undefined) return false;
|
|
98
|
+
|
|
70
99
|
// Resolve Type
|
|
71
100
|
if (typeof typeDef == 'function' && typeDef.type instanceof Type) typeDef = typeDef.type;
|
|
72
101
|
|
|
@@ -123,6 +152,7 @@ function typeis(obj, typeDef, missingObjects = false) {
|
|
|
123
152
|
|
|
124
153
|
return missingObjects ? [true] : true;
|
|
125
154
|
}
|
|
155
|
+
typeis.multi = (values, types) => typeAre(values, types);
|
|
126
156
|
|
|
127
157
|
function typex(child, parent) {
|
|
128
158
|
return child.prototype instanceof parent || child === parent;
|
|
@@ -81,7 +81,7 @@ module.exports.prepareContext = function (
|
|
|
81
81
|
this['@cb'] = cb;
|
|
82
82
|
}
|
|
83
83
|
});
|
|
84
|
-
}, out: {...process.stdout, put: (...logs) => context.print(...logs), strace: (...logs) => straceLog('==> STRACE_OUT():', ...logs ), write: (logs) => context.printf(logs+'\n') }, in: {...process.stdin, read: (...args) => context.input(...args)}, define: (name, object) => {
|
|
84
|
+
}, out: {...process.stdout, cols: process.stdout.columns, rows: process.stdout.rows, put: (...logs) => context.print(...logs), strace: (...logs) => straceLog('==> STRACE_OUT():', ...logs ), write: (logs) => context.printf(logs+'\n') }, in: {...process.stdin, read: (...args) => context.input(...args)}, define: (name, object) => {
|
|
85
85
|
if(Array.isArray(name) && name.length == 2 && typeof name[0] == 'string'){
|
|
86
86
|
object = name[1];
|
|
87
87
|
name = name[0];
|
package/lib/rew/pkgs/conf.js
CHANGED
package/lib/rew/pkgs/threads.js
CHANGED
|
@@ -33,7 +33,7 @@ module.exports = (context) => ({
|
|
|
33
33
|
dataResult.resolve(data.result);
|
|
34
34
|
stop();
|
|
35
35
|
} else if (data.type === 'error') {
|
|
36
|
-
|
|
36
|
+
listener.emit('error', new Error(data.error));
|
|
37
37
|
stop();
|
|
38
38
|
} else if (data.type === 'event') {
|
|
39
39
|
listener.emit(data.event, data.data);
|
|
@@ -41,7 +41,7 @@ module.exports = (context) => ({
|
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
worker.on('error', (error) => {
|
|
44
|
-
|
|
44
|
+
listener.emit('error', error);
|
|
45
45
|
stop();
|
|
46
46
|
});
|
|
47
47
|
|
|
@@ -51,7 +51,7 @@ module.exports = (context) => ({
|
|
|
51
51
|
if (exiting) return;
|
|
52
52
|
stop();
|
|
53
53
|
if (code !== 0) {
|
|
54
|
-
|
|
54
|
+
listener.emit('error', new Error(`Worker stopped with exit code ${code}`));
|
|
55
55
|
}
|
|
56
56
|
});
|
|
57
57
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@makano/rew",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "A simple coffescript runtime and app manager",
|
|
5
5
|
"main": "main.js",
|
|
6
6
|
"directories": {
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"url": "git+https://github.com/kevinj045/rew.git"
|
|
24
24
|
},
|
|
25
25
|
"keywords": [
|
|
26
|
-
"
|
|
26
|
+
"coffeescript",
|
|
27
|
+
"coffee",
|
|
28
|
+
"compiler",
|
|
27
29
|
"rew",
|
|
28
30
|
"runtime"
|
|
29
31
|
],
|