jostraca 0.0.9 → 0.1.2
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/LICENSE +1 -1
- package/README.md +0 -10
- package/dist/jostraca.d.ts +16 -0
- package/dist/jostraca.js +189 -0
- package/dist/jostraca.js.map +1 -0
- package/package.json +31 -76
- package/src/jostraca.ts +261 -0
- package/src/tsconfig.json +16 -0
- package/bin/jostraca-exec.js +0 -10
- package/bin/run +0 -5
- package/bin/run.cmd +0 -3
- package/jostraca.js +0 -15
- package/jostraca.ts +0 -19
- package/lib/commands/generate.d.ts +0 -12
- package/lib/commands/generate.js +0 -41
- package/lib/commands/goodbye.d.ts +0 -13
- package/lib/commands/goodbye.js +0 -26
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -4
- package/lib/util/repo.d.ts +0 -55
- package/lib/util/repo.js +0 -231
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,12 +1,2 @@
|
|
|
1
1
|
# jostraca
|
|
2
|
-
Jostraca
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
## Development
|
|
6
|
-
|
|
7
|
-
* Watch: `npm run tsc:w`
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
## Templating
|
|
11
|
-
|
|
12
|
-
* The `<%=slots.foo%>` injection *currently* should always be placed at the start of a line to avoid adding indentation on each generation - whitespace handling needs to be smarter.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
type JostracaOptions = {
|
|
2
|
+
folder: string;
|
|
3
|
+
fs: any;
|
|
4
|
+
};
|
|
5
|
+
type Component = (props: any, children?: any) => void;
|
|
6
|
+
declare function Jostraca(): {
|
|
7
|
+
cmp: (component: Function) => Component;
|
|
8
|
+
each: (subject: any, apply?: any) => any;
|
|
9
|
+
generate: (opts: JostracaOptions, root: Function) => void;
|
|
10
|
+
Project: Component;
|
|
11
|
+
Code: Component;
|
|
12
|
+
File: Component;
|
|
13
|
+
Folder: Component;
|
|
14
|
+
};
|
|
15
|
+
export type { JostracaOptions, Component, };
|
|
16
|
+
export { Jostraca, };
|
package/dist/jostraca.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (c) 2024 Richard Rodger, MIT License */
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
20
|
+
if (mod && mod.__esModule) return mod;
|
|
21
|
+
var result = {};
|
|
22
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
23
|
+
__setModuleDefault(result, mod);
|
|
24
|
+
return result;
|
|
25
|
+
};
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.Jostraca = Jostraca;
|
|
28
|
+
const Fs = __importStar(require("node:fs"));
|
|
29
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
30
|
+
function Jostraca() {
|
|
31
|
+
const GLOBAL = global;
|
|
32
|
+
GLOBAL.jostraca = new node_async_hooks_1.AsyncLocalStorage();
|
|
33
|
+
function generate(opts, root) {
|
|
34
|
+
const fs = opts.fs || Fs;
|
|
35
|
+
GLOBAL.jostraca.run({
|
|
36
|
+
content: null,
|
|
37
|
+
}, () => {
|
|
38
|
+
root();
|
|
39
|
+
const ctx$ = GLOBAL.jostraca.getStore();
|
|
40
|
+
const node = ctx$.node;
|
|
41
|
+
build(node, {
|
|
42
|
+
fs,
|
|
43
|
+
current: {
|
|
44
|
+
folder: {
|
|
45
|
+
parent: opts.folder
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function cmp(component) {
|
|
52
|
+
const cf = (props, children) => {
|
|
53
|
+
props = props || {};
|
|
54
|
+
if (null == props || 'object' !== typeof props) {
|
|
55
|
+
props = { arg: props };
|
|
56
|
+
}
|
|
57
|
+
props.ctx$ = GLOBAL.jostraca.getStore();
|
|
58
|
+
children = 'function' === typeof children ? [children] : children;
|
|
59
|
+
let node = {
|
|
60
|
+
kind: 'content',
|
|
61
|
+
children: []
|
|
62
|
+
};
|
|
63
|
+
const parent = props.ctx$.node = (props.ctx$.node || node);
|
|
64
|
+
const siblings = props.ctx$.children = (props.ctx$.children || []);
|
|
65
|
+
siblings.push(node);
|
|
66
|
+
props.ctx$.children = node.children;
|
|
67
|
+
props.ctx$.node = node;
|
|
68
|
+
let out = component(props, children);
|
|
69
|
+
props.ctx$.children = siblings;
|
|
70
|
+
props.ctx$.node = parent;
|
|
71
|
+
return out;
|
|
72
|
+
};
|
|
73
|
+
Object.defineProperty(cf, 'name', { value: component.name });
|
|
74
|
+
return cf;
|
|
75
|
+
}
|
|
76
|
+
function each(subject, apply) {
|
|
77
|
+
if (null == apply) {
|
|
78
|
+
if (Array.isArray(subject)) {
|
|
79
|
+
for (let fn of subject) {
|
|
80
|
+
fn();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
if (Array.isArray(subject)) {
|
|
86
|
+
return subject.map(apply);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
const entries = Object.entries(subject);
|
|
90
|
+
if (entries[0] && entries[0][1] && 'string' === typeof entries[0][1].name) {
|
|
91
|
+
entries.sort((a, b) => a.name < b.name ? 1 : b.name < a.name ? -1 : 0);
|
|
92
|
+
}
|
|
93
|
+
return entries.map((n, ...args) => apply(n[1], [0], ...args));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function build(topnode, ctx) {
|
|
98
|
+
// console.dir(topnode, { depth: null })
|
|
99
|
+
step(topnode, ctx);
|
|
100
|
+
}
|
|
101
|
+
function step(node, ctx) {
|
|
102
|
+
const op = opmap[node.kind];
|
|
103
|
+
if (null == op) {
|
|
104
|
+
throw new Error('missing op: ' + node.kind);
|
|
105
|
+
}
|
|
106
|
+
op.before(node, ctx);
|
|
107
|
+
if (node.children) {
|
|
108
|
+
for (let childnode of node.children) {
|
|
109
|
+
step(childnode, ctx);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
op.after(node, ctx);
|
|
113
|
+
}
|
|
114
|
+
const opmap = {
|
|
115
|
+
project: {
|
|
116
|
+
before(node, ctx) {
|
|
117
|
+
const cproject = ctx.current.project = (ctx.current.project || {});
|
|
118
|
+
cproject.node = node;
|
|
119
|
+
},
|
|
120
|
+
after(_node, _ctx) {
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
folder: {
|
|
124
|
+
before(node, ctx) {
|
|
125
|
+
const cfolder = ctx.current.folder = (ctx.current.folder || {});
|
|
126
|
+
cfolder.node = node;
|
|
127
|
+
cfolder.path = (cfolder.path || [ctx.current.folder.parent]);
|
|
128
|
+
cfolder.path.push(node.name);
|
|
129
|
+
let fullpath = cfolder.path.join('/');
|
|
130
|
+
ctx.fs.mkdirSync(fullpath, { recursive: true });
|
|
131
|
+
},
|
|
132
|
+
after(_node, ctx) {
|
|
133
|
+
const cfolder = ctx.current.folder;
|
|
134
|
+
cfolder.path.length = cfolder.path.length - 1;
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
file: {
|
|
138
|
+
before(node, ctx) {
|
|
139
|
+
const cfile = ctx.current.file = node;
|
|
140
|
+
cfile.path = ctx.current.folder.path.join('/') + '/' + node.name;
|
|
141
|
+
cfile.content = [];
|
|
142
|
+
},
|
|
143
|
+
after(_node, ctx) {
|
|
144
|
+
const cfile = ctx.current.file;
|
|
145
|
+
const content = cfile.content.join('');
|
|
146
|
+
ctx.fs.writeFileSync(cfile.path, content);
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
content: {
|
|
150
|
+
before(node, ctx) {
|
|
151
|
+
const ccontent = ctx.current.content = node;
|
|
152
|
+
ctx.current.file.content.push(ccontent.content);
|
|
153
|
+
},
|
|
154
|
+
after(_node, _ctx) {
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
const Code = cmp(function Code(props) {
|
|
159
|
+
let src = props.arg;
|
|
160
|
+
props.ctx$.node.content = src;
|
|
161
|
+
});
|
|
162
|
+
const File = cmp(function File(props, children) {
|
|
163
|
+
props.ctx$.node.kind = 'file';
|
|
164
|
+
props.ctx$.node.name = props.name;
|
|
165
|
+
// Code('// FILE START: ' + props.name + '\n')
|
|
166
|
+
each(children);
|
|
167
|
+
// Code('// FILE END: ' + props.name + '\n')
|
|
168
|
+
});
|
|
169
|
+
const Project = cmp(function Project(props, children) {
|
|
170
|
+
props.ctx$.node.kind = 'project';
|
|
171
|
+
props.ctx$.node.name = props.name;
|
|
172
|
+
each(children);
|
|
173
|
+
});
|
|
174
|
+
const Folder = cmp(function Folder(props, children) {
|
|
175
|
+
props.ctx$.node.kind = 'folder';
|
|
176
|
+
props.ctx$.node.name = props.name;
|
|
177
|
+
each(children);
|
|
178
|
+
});
|
|
179
|
+
return {
|
|
180
|
+
cmp,
|
|
181
|
+
each,
|
|
182
|
+
generate,
|
|
183
|
+
Project,
|
|
184
|
+
Code,
|
|
185
|
+
File,
|
|
186
|
+
Folder,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=jostraca.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jostraca.js","sourceRoot":"","sources":["../src/jostraca.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,87 +1,42 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jostraca",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"main": "dist/jostraca.js",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"types": "dist/jostraca.d.ts",
|
|
7
|
+
"description": "Jostraca Jostraca.",
|
|
8
|
+
"homepage": "https://github.com/jostraca/jostraca",
|
|
9
|
+
"keywords": [
|
|
10
|
+
"jostraca",
|
|
11
|
+
"jostraca"
|
|
12
|
+
],
|
|
13
|
+
"author": "Richard Rodger (http://richardrodger.com)",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git://github.com/jostraca/jostraca.git"
|
|
8
17
|
},
|
|
9
18
|
"scripts": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"test-nyc": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"",
|
|
15
|
-
"version": "oclif-dev readme && git add README.md",
|
|
16
|
-
"compile": "tsc jostraca.ts",
|
|
17
|
-
"test": "lab --sourcemaps --transform node_modules/lab-transform-typescript -P lab-test -v -t 50",
|
|
18
|
-
"prettier": "prettier --write --no-semi --single-quote *.ts *.js src/**/*.ts test/**/*.ts test/**/*.js",
|
|
19
|
-
"tsc:w": "tsc -w -d --noEmitOnError",
|
|
20
|
-
"tsc": "tsc -d --noEmitOnError",
|
|
21
|
-
"coveralls": "lab -s -P test -r lcov | coveralls",
|
|
22
|
-
"reset": "npm run clean && npm i && npm run test",
|
|
19
|
+
"test": "node --enable-source-maps --test dist-test",
|
|
20
|
+
"test-some": "node --enable-source-maps --test-name-pattern=\"$npm_config_pattern\" --test dist-test",
|
|
21
|
+
"watch": "tsc --build src test -w",
|
|
22
|
+
"build": "tsc --build src test",
|
|
23
23
|
"clean": "rm -rf node_modules yarn.lock package-lock.json",
|
|
24
|
+
"reset": "npm run clean && npm i && npm run build && npm test",
|
|
24
25
|
"repo-tag": "REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;",
|
|
25
|
-
"repo-publish": "npm run clean && npm i
|
|
26
|
-
"repo-publish-quick": "npm run
|
|
26
|
+
"repo-publish": "npm run clean && npm i && npm run repo-publish-quick",
|
|
27
|
+
"repo-publish-quick": "npm run build && npm run test && npm run repo-tag && npm publish --registry https://registry.npmjs.org --access=public"
|
|
27
28
|
},
|
|
29
|
+
"license": "MIT",
|
|
28
30
|
"files": [
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"jostraca.ts",
|
|
33
|
-
"lib",
|
|
34
|
-
"bin"
|
|
31
|
+
"src",
|
|
32
|
+
"dist",
|
|
33
|
+
"LICENSE"
|
|
35
34
|
],
|
|
36
|
-
"repository": {
|
|
37
|
-
"type": "git",
|
|
38
|
-
"url": "git+https://github.com/jostraca/jostraca.git"
|
|
39
|
-
},
|
|
40
|
-
"keywords": [
|
|
41
|
-
"jostraca"
|
|
42
|
-
],
|
|
43
|
-
"author": "Richard Rodger",
|
|
44
|
-
"license": "MIT",
|
|
45
|
-
"bugs": {
|
|
46
|
-
"url": "https://github.com/jostraca/jostraca/issues"
|
|
47
|
-
},
|
|
48
|
-
"homepage": "https://github.com/jostraca/jostraca#readme",
|
|
49
|
-
"dependencies": {
|
|
50
|
-
"@oclif/command": "^1.6.1",
|
|
51
|
-
"@oclif/config": "^1.15.1",
|
|
52
|
-
"@oclif/plugin-help": "^3.0.1",
|
|
53
|
-
"ejs": "^3.1.3",
|
|
54
|
-
"jsonic": "^0.3.1",
|
|
55
|
-
"lodash.defaultsdeep": "^4.6.1",
|
|
56
|
-
"tslib": "^2.0.0"
|
|
57
|
-
},
|
|
58
35
|
"devDependencies": {
|
|
59
|
-
"@hapi/code": "^
|
|
60
|
-
"@
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
|
|
65
|
-
"@types/mocha": "^7.0.2",
|
|
66
|
-
"@types/node": "^14.0.9",
|
|
67
|
-
"chai": "^4.2.0",
|
|
68
|
-
"globby": "^11.0.1",
|
|
69
|
-
"lab-transform-typescript": "^3.0.1",
|
|
70
|
-
"mocha": "^7.2.0",
|
|
71
|
-
"mock-fs": "^4.12.0",
|
|
72
|
-
"nyc": "^15.1.0",
|
|
73
|
-
"prettier": "^2.0.5",
|
|
74
|
-
"ts-node": "^8.10.2",
|
|
75
|
-
"tslint": "^6.1.2",
|
|
76
|
-
"tslint-config-prettier": "^1.18.0",
|
|
77
|
-
"typescript": "^3.9.3"
|
|
78
|
-
},
|
|
79
|
-
"oclif": {
|
|
80
|
-
"commands": "./lib/commands",
|
|
81
|
-
"bin": "jostraca",
|
|
82
|
-
"plugins": [
|
|
83
|
-
"@oclif/plugin-help"
|
|
84
|
-
]
|
|
85
|
-
},
|
|
86
|
-
"types": "lib/index.d.ts"
|
|
36
|
+
"@hapi/code": "^9.0.3",
|
|
37
|
+
"@types/node": "22.0.0",
|
|
38
|
+
"esbuild": "^0.23.0",
|
|
39
|
+
"memfs": "^4.11.1",
|
|
40
|
+
"typescript": "^5.5.4"
|
|
41
|
+
}
|
|
87
42
|
}
|
package/src/jostraca.ts
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/* Copyright (c) 2024 Richard Rodger, MIT License */
|
|
2
|
+
|
|
3
|
+
import * as Fs from 'node:fs'
|
|
4
|
+
|
|
5
|
+
import { AsyncLocalStorage } from 'node:async_hooks'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
type JostracaOptions = {
|
|
9
|
+
folder: string
|
|
10
|
+
fs: any
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
type Node = {
|
|
15
|
+
kind: string
|
|
16
|
+
children?: Node[]
|
|
17
|
+
name?: string
|
|
18
|
+
path?: string
|
|
19
|
+
content?: any[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
type Component = (props: any, children?: any) => void
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
function Jostraca() {
|
|
27
|
+
|
|
28
|
+
const GLOBAL = (global as any)
|
|
29
|
+
GLOBAL.jostraca = new AsyncLocalStorage()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
function generate(opts: JostracaOptions, root: Function) {
|
|
33
|
+
const fs = opts.fs || Fs
|
|
34
|
+
GLOBAL.jostraca.run({
|
|
35
|
+
content: null,
|
|
36
|
+
}, () => {
|
|
37
|
+
root()
|
|
38
|
+
|
|
39
|
+
const ctx$ = GLOBAL.jostraca.getStore()
|
|
40
|
+
const node = ctx$.node
|
|
41
|
+
|
|
42
|
+
build(
|
|
43
|
+
node,
|
|
44
|
+
{
|
|
45
|
+
fs,
|
|
46
|
+
current: {
|
|
47
|
+
folder: {
|
|
48
|
+
parent: opts.folder
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
function cmp(component: Function): Component {
|
|
57
|
+
const cf = (props: any, children?: any) => {
|
|
58
|
+
props = props || {}
|
|
59
|
+
if (null == props || 'object' !== typeof props) {
|
|
60
|
+
props = { arg: props }
|
|
61
|
+
}
|
|
62
|
+
props.ctx$ = GLOBAL.jostraca.getStore()
|
|
63
|
+
children = 'function' === typeof children ? [children] : children
|
|
64
|
+
|
|
65
|
+
let node = {
|
|
66
|
+
kind: 'content',
|
|
67
|
+
children: []
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const parent = props.ctx$.node = (props.ctx$.node || node)
|
|
71
|
+
const siblings = props.ctx$.children = (props.ctx$.children || [])
|
|
72
|
+
siblings.push(node)
|
|
73
|
+
|
|
74
|
+
props.ctx$.children = node.children
|
|
75
|
+
props.ctx$.node = node
|
|
76
|
+
|
|
77
|
+
let out = component(props, children)
|
|
78
|
+
|
|
79
|
+
props.ctx$.children = siblings
|
|
80
|
+
props.ctx$.node = parent
|
|
81
|
+
|
|
82
|
+
return out
|
|
83
|
+
}
|
|
84
|
+
Object.defineProperty(cf, 'name', { value: component.name })
|
|
85
|
+
return cf
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
function each(subject: any, apply?: any) {
|
|
90
|
+
if (null == apply) {
|
|
91
|
+
if (Array.isArray(subject)) {
|
|
92
|
+
for (let fn of subject) {
|
|
93
|
+
fn()
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
if (Array.isArray(subject)) {
|
|
99
|
+
return subject.map(apply)
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
const entries: any = Object.entries(subject)
|
|
103
|
+
if (entries[0] && entries[0][1] && 'string' === typeof entries[0][1].name) {
|
|
104
|
+
entries.sort((a: any, b: any) => a.name < b.name ? 1 : b.name < a.name ? -1 : 0)
|
|
105
|
+
}
|
|
106
|
+
return entries.map((n: any, ...args: any[]) =>
|
|
107
|
+
apply(n[1], [0], ...args))
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
function build(topnode: Node, ctx: any) {
|
|
114
|
+
// console.dir(topnode, { depth: null })
|
|
115
|
+
step(topnode, ctx)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
function step(node: Node, ctx: any) {
|
|
120
|
+
const op = opmap[node.kind]
|
|
121
|
+
if (null == op) {
|
|
122
|
+
throw new Error('missing op: ' + node.kind)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
op.before(node, ctx)
|
|
126
|
+
|
|
127
|
+
if (node.children) {
|
|
128
|
+
for (let childnode of node.children) {
|
|
129
|
+
step(childnode, ctx)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
op.after(node, ctx)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
const opmap: any = {
|
|
139
|
+
|
|
140
|
+
project: {
|
|
141
|
+
before(node: Node, ctx: any) {
|
|
142
|
+
const cproject: any = ctx.current.project = (ctx.current.project || {})
|
|
143
|
+
cproject.node = node
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
after(_node: Node, _ctx: any) {
|
|
147
|
+
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
folder: {
|
|
153
|
+
before(node: Node, ctx: any) {
|
|
154
|
+
const cfolder = ctx.current.folder = (ctx.current.folder || {})
|
|
155
|
+
|
|
156
|
+
cfolder.node = node
|
|
157
|
+
cfolder.path = (cfolder.path || [ctx.current.folder.parent])
|
|
158
|
+
cfolder.path.push(node.name)
|
|
159
|
+
|
|
160
|
+
let fullpath = cfolder.path.join('/')
|
|
161
|
+
ctx.fs.mkdirSync(fullpath, { recursive: true })
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
after(_node: Node, ctx: any) {
|
|
166
|
+
const cfolder = ctx.current.folder
|
|
167
|
+
cfolder.path.length = cfolder.path.length - 1
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
file: {
|
|
173
|
+
before(node: Node, ctx: any) {
|
|
174
|
+
const cfile = ctx.current.file = node
|
|
175
|
+
cfile.path = ctx.current.folder.path.join('/') + '/' + node.name
|
|
176
|
+
cfile.content = []
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
after(_node: Node, ctx: any) {
|
|
180
|
+
const cfile = ctx.current.file
|
|
181
|
+
const content = cfile.content.join('')
|
|
182
|
+
ctx.fs.writeFileSync(cfile.path, content)
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
content: {
|
|
188
|
+
before(node: Node, ctx: any) {
|
|
189
|
+
const ccontent = ctx.current.content = node
|
|
190
|
+
ctx.current.file.content.push(ccontent.content)
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
after(_node: Node, _ctx: any) {
|
|
194
|
+
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
const Code = cmp(function Code(props: any) {
|
|
204
|
+
let src = props.arg
|
|
205
|
+
props.ctx$.node.content = src
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
const File = cmp(function File(props: any, children: any) {
|
|
210
|
+
props.ctx$.node.kind = 'file'
|
|
211
|
+
props.ctx$.node.name = props.name
|
|
212
|
+
|
|
213
|
+
// Code('// FILE START: ' + props.name + '\n')
|
|
214
|
+
|
|
215
|
+
each(children)
|
|
216
|
+
|
|
217
|
+
// Code('// FILE END: ' + props.name + '\n')
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
const Project: Component = cmp(function Project(props: any, children: any) {
|
|
222
|
+
props.ctx$.node.kind = 'project'
|
|
223
|
+
props.ctx$.node.name = props.name
|
|
224
|
+
|
|
225
|
+
each(children)
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
const Folder = cmp(function Folder(props: any, children: any) {
|
|
230
|
+
props.ctx$.node.kind = 'folder'
|
|
231
|
+
props.ctx$.node.name = props.name
|
|
232
|
+
|
|
233
|
+
each(children)
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
cmp,
|
|
240
|
+
each,
|
|
241
|
+
generate,
|
|
242
|
+
|
|
243
|
+
Project,
|
|
244
|
+
Code,
|
|
245
|
+
File,
|
|
246
|
+
Folder,
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
export type {
|
|
254
|
+
JostracaOptions,
|
|
255
|
+
Component,
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
export {
|
|
260
|
+
Jostraca,
|
|
261
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"esModuleInterop": true,
|
|
4
|
+
"module": "nodenext",
|
|
5
|
+
"noEmitOnError": true,
|
|
6
|
+
"outDir":"../dist",
|
|
7
|
+
"rootDir":".",
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"sourceMap": true,
|
|
10
|
+
"strict": true,
|
|
11
|
+
"target": "es2021",
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"declarationDir": "../dist"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
package/bin/jostraca-exec.js
DELETED
package/bin/run
DELETED
package/bin/run.cmd
DELETED
package/jostraca.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/* Copyright © 2019 Richard Rodger and other contributors, MIT License. */
|
|
2
|
-
var Pkg = require('./package.json')
|
|
3
|
-
var Seneca = require('seneca')
|
|
4
|
-
module.exports = make_jostraca
|
|
5
|
-
function make_jostraca() {
|
|
6
|
-
return Jostraca()
|
|
7
|
-
}
|
|
8
|
-
function Jostraca() {
|
|
9
|
-
var self = {}
|
|
10
|
-
self.toString = function () {
|
|
11
|
-
return 'jostraca@' + Pkg.version
|
|
12
|
-
}
|
|
13
|
-
self['seneca'] = Seneca()
|
|
14
|
-
return self
|
|
15
|
-
}
|
package/jostraca.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/* Copyright © 2019 Richard Rodger and other contributors, MIT License. */
|
|
2
|
-
|
|
3
|
-
const Pkg = require('./package.json')
|
|
4
|
-
|
|
5
|
-
module.exports = make_jostraca
|
|
6
|
-
|
|
7
|
-
function make_jostraca() {
|
|
8
|
-
return Jostraca()
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function Jostraca() {
|
|
12
|
-
var self = {}
|
|
13
|
-
|
|
14
|
-
self.toString = function () {
|
|
15
|
-
return 'jostraca@' + Pkg.version
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return self
|
|
19
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Command, flags } from '@oclif/command';
|
|
2
|
-
export default class Generate extends Command {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static flags: {
|
|
6
|
-
config: flags.IOptionFlag<string | undefined>;
|
|
7
|
-
};
|
|
8
|
-
static args: {
|
|
9
|
-
name: string;
|
|
10
|
-
}[];
|
|
11
|
-
run(): Promise<void>;
|
|
12
|
-
}
|
package/lib/commands/generate.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const Path = require("path");
|
|
4
|
-
const command_1 = require("@oclif/command");
|
|
5
|
-
const repo_1 = require("../util/repo");
|
|
6
|
-
// TODO: better resolver needed
|
|
7
|
-
let config = {
|
|
8
|
-
basefolder: process.cwd() + '/jostraca',
|
|
9
|
-
};
|
|
10
|
-
let Generate = /** @class */ (() => {
|
|
11
|
-
class Generate extends command_1.Command {
|
|
12
|
-
async run() {
|
|
13
|
-
const { args, flags } = this.parse(Generate);
|
|
14
|
-
const group = args.group || 'all';
|
|
15
|
-
const repo = args.repo || '';
|
|
16
|
-
const basefolder = Path.resolve(flags.config || config.basefolder);
|
|
17
|
-
const systemfolder = Path.dirname(basefolder);
|
|
18
|
-
const repofolder = Path.dirname(systemfolder);
|
|
19
|
-
const spec = {
|
|
20
|
-
group,
|
|
21
|
-
repo,
|
|
22
|
-
basefolder,
|
|
23
|
-
repofolder,
|
|
24
|
-
};
|
|
25
|
-
// console.log('JOSTRACA GENERATE', spec)
|
|
26
|
-
repo_1.generate(spec);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
Generate.description = 'Generate repo files';
|
|
30
|
-
Generate.examples = [
|
|
31
|
-
`$ jostraca generate`,
|
|
32
|
-
`$ jostraca generate [group]`,
|
|
33
|
-
`$ jostraca generate [group] [repo]`,
|
|
34
|
-
];
|
|
35
|
-
Generate.flags = {
|
|
36
|
-
config: command_1.flags.string({ char: 'c', description: 'config folder' }),
|
|
37
|
-
};
|
|
38
|
-
Generate.args = [{ name: 'group' }, { name: 'repo' }];
|
|
39
|
-
return Generate;
|
|
40
|
-
})();
|
|
41
|
-
exports.default = Generate;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Command, flags } from '@oclif/command';
|
|
2
|
-
export default class Goodbye extends Command {
|
|
3
|
-
static description: string;
|
|
4
|
-
static flags: {
|
|
5
|
-
help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
|
|
6
|
-
name: flags.IOptionFlag<string | undefined>;
|
|
7
|
-
force: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
|
|
8
|
-
};
|
|
9
|
-
static args: {
|
|
10
|
-
name: string;
|
|
11
|
-
}[];
|
|
12
|
-
run(): Promise<void>;
|
|
13
|
-
}
|
package/lib/commands/goodbye.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const command_1 = require("@oclif/command");
|
|
4
|
-
let Goodbye = /** @class */ (() => {
|
|
5
|
-
class Goodbye extends command_1.Command {
|
|
6
|
-
async run() {
|
|
7
|
-
const { args, flags } = this.parse(Goodbye);
|
|
8
|
-
const name = flags.name || 'world';
|
|
9
|
-
this.log(`hello ${name} from /root/cli/tmp/examples/example-multi-ts/src/commands/goodbye.ts`);
|
|
10
|
-
if (args.file && flags.force) {
|
|
11
|
-
this.log(`you input --force and --file: ${args.file}`);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
Goodbye.description = 'describe the command here';
|
|
16
|
-
Goodbye.flags = {
|
|
17
|
-
help: command_1.flags.help({ char: 'h' }),
|
|
18
|
-
// flag with a value (-n, --name=VALUE)
|
|
19
|
-
name: command_1.flags.string({ char: 'n', description: 'name to print' }),
|
|
20
|
-
// flag with no value (-f, --force)
|
|
21
|
-
force: command_1.flags.boolean({ char: 'f' }),
|
|
22
|
-
};
|
|
23
|
-
Goodbye.args = [{ name: 'file' }];
|
|
24
|
-
return Goodbye;
|
|
25
|
-
})();
|
|
26
|
-
exports.default = Goodbye;
|
package/lib/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { run } from '@oclif/command';
|
package/lib/index.js
DELETED
package/lib/util/repo.d.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
interface Repo {
|
|
2
|
-
name: string;
|
|
3
|
-
order: number;
|
|
4
|
-
props: object;
|
|
5
|
-
}
|
|
6
|
-
declare type MapRepo = Repo[] & {
|
|
7
|
-
[key: string]: Repo;
|
|
8
|
-
};
|
|
9
|
-
interface Template {
|
|
10
|
-
name: string;
|
|
11
|
-
path: string;
|
|
12
|
-
parent_folders: string[];
|
|
13
|
-
text: string;
|
|
14
|
-
kind: string;
|
|
15
|
-
render?: (ctxt: any) => any;
|
|
16
|
-
}
|
|
17
|
-
interface TemplateContext {
|
|
18
|
-
name: string;
|
|
19
|
-
version: string;
|
|
20
|
-
year: number;
|
|
21
|
-
prefix: string;
|
|
22
|
-
suffix: string;
|
|
23
|
-
parent_folders: string[];
|
|
24
|
-
props: object;
|
|
25
|
-
slots?: {
|
|
26
|
-
[key: string]: string;
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
interface GenerateSpec {
|
|
30
|
-
group: string;
|
|
31
|
-
repo: string;
|
|
32
|
-
basefolder: string;
|
|
33
|
-
repofolder: string;
|
|
34
|
-
}
|
|
35
|
-
interface GroupSpec {
|
|
36
|
-
name: string;
|
|
37
|
-
repos: MapRepo;
|
|
38
|
-
}
|
|
39
|
-
interface RepoSpec {
|
|
40
|
-
version: string;
|
|
41
|
-
}
|
|
42
|
-
declare const intern: {
|
|
43
|
-
generate(spec: GenerateSpec): void;
|
|
44
|
-
render_template(tm: Template, ctxt: TemplateContext, text: string): any;
|
|
45
|
-
load_templates(folder: string): Template[];
|
|
46
|
-
parse_templates(templates: Template[]): void;
|
|
47
|
-
load_repo_spec(spec: GenerateSpec, repo: Repo): RepoSpec;
|
|
48
|
-
load_repo_groups(folder: string): {
|
|
49
|
-
[group: string]: GroupSpec;
|
|
50
|
-
};
|
|
51
|
-
parse_repo_list(text: string): Repo[];
|
|
52
|
-
deep(...rest: any[]): any;
|
|
53
|
-
};
|
|
54
|
-
declare function generate(spec: GenerateSpec): void;
|
|
55
|
-
export { generate, intern };
|
package/lib/util/repo.js
DELETED
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// Copyright © 2019 Richard Rodger and other contributors, MIT License.
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.intern = exports.generate = void 0;
|
|
5
|
-
const Fs = require("fs");
|
|
6
|
-
const Path = require("path");
|
|
7
|
-
//import { Jsonic } from 'jsonic'
|
|
8
|
-
const Jsonic = require('jsonic');
|
|
9
|
-
const Ejs = require('ejs');
|
|
10
|
-
const LodashDefaultsDeep = require('lodash.defaultsdeep');
|
|
11
|
-
const intern = {
|
|
12
|
-
generate(spec) {
|
|
13
|
-
let groups = intern.load_repo_groups(spec.basefolder + '/repos');
|
|
14
|
-
let all_group = groups.all;
|
|
15
|
-
let group = groups[spec.group];
|
|
16
|
-
let template_folder = spec.basefolder + '/templates';
|
|
17
|
-
let templates = intern.load_templates(template_folder);
|
|
18
|
-
let repos = group.repos.filter((repo) => {
|
|
19
|
-
return '' === spec.repo || repo.name === spec.repo;
|
|
20
|
-
});
|
|
21
|
-
for (let rI = 0; rI < repos.length; rI++) {
|
|
22
|
-
let repo = repos[rI];
|
|
23
|
-
let repospec = intern.load_repo_spec(spec, repo);
|
|
24
|
-
// inherit props from 'all' group
|
|
25
|
-
let all_repo = all_group.repos[repo.name] || {};
|
|
26
|
-
let props = intern.deep(all_repo.props, repo.props);
|
|
27
|
-
let skip = false;
|
|
28
|
-
for (let template of templates) {
|
|
29
|
-
skip = false;
|
|
30
|
-
let path = spec.repofolder +
|
|
31
|
-
'/' +
|
|
32
|
-
repo.name +
|
|
33
|
-
'/' +
|
|
34
|
-
template.path.substring(template_folder.length + 1);
|
|
35
|
-
while (path !== (path = path.replace('%NAME%', repo.name))) { }
|
|
36
|
-
let excludes = ('string' === typeof props.exclude$
|
|
37
|
-
? [props.exclude$]
|
|
38
|
-
: props.exclude$) || [];
|
|
39
|
-
for (let exclude of excludes) {
|
|
40
|
-
skip = skip || -1 !== path.indexOf(exclude);
|
|
41
|
-
}
|
|
42
|
-
if (!skip) {
|
|
43
|
-
let text = '';
|
|
44
|
-
if (Fs.existsSync(path)) {
|
|
45
|
-
text = Fs.readFileSync(path).toString();
|
|
46
|
-
}
|
|
47
|
-
let repo_name_prefix = '';
|
|
48
|
-
let repo_name_suffix = '';
|
|
49
|
-
let m = repo.name.match(/^(.*)-([^-]*?)$/);
|
|
50
|
-
if (m) {
|
|
51
|
-
repo_name_prefix = m[1];
|
|
52
|
-
repo_name_suffix = m[2];
|
|
53
|
-
}
|
|
54
|
-
let ctxt = {
|
|
55
|
-
name: repo.name,
|
|
56
|
-
version: repospec.version,
|
|
57
|
-
prefix: repo_name_prefix,
|
|
58
|
-
suffix: repo_name_suffix,
|
|
59
|
-
year: new Date().getFullYear(),
|
|
60
|
-
parent_folders: template.parent_folders,
|
|
61
|
-
props,
|
|
62
|
-
};
|
|
63
|
-
let out = intern.render_template(template, ctxt, text);
|
|
64
|
-
let folder_part = Path.dirname(path);
|
|
65
|
-
Fs.mkdirSync(folder_part, { recursive: true });
|
|
66
|
-
Fs.writeFileSync(path, out);
|
|
67
|
-
console_log('SAVE: ' + path);
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
console_log('skip: ' + path);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
render_template(tm, ctxt, text) {
|
|
76
|
-
text = text || '';
|
|
77
|
-
ctxt.slots = {};
|
|
78
|
-
// NOTE: slot *MUST* have newline prefix and suffix
|
|
79
|
-
// This supports syntax comments in source code
|
|
80
|
-
let jostraca_slot_re = /[^\r\n]*?JOSTRACA-SLOT-START:([\S]+)[^\r\n]*[\r\n]?([\s\S]*?)[\r\n]?[^\r\n]*JOSTRACA-SLOT-END:\1[^\r\n]*/;
|
|
81
|
-
let m = null;
|
|
82
|
-
let last = 0;
|
|
83
|
-
let index;
|
|
84
|
-
while ((m = jostraca_slot_re.exec(text.substring(last)))) {
|
|
85
|
-
//console.log(m)
|
|
86
|
-
let slot_full = m[0];
|
|
87
|
-
let slot_name = m[1];
|
|
88
|
-
// Need to preserve slot markers on re-insert
|
|
89
|
-
ctxt.slots[slot_name] = slot_full;
|
|
90
|
-
index = m.index;
|
|
91
|
-
// keep looking from end of last match
|
|
92
|
-
last = last + index + slot_full.length;
|
|
93
|
-
}
|
|
94
|
-
let render_text = tm.render(ctxt);
|
|
95
|
-
let out = render_text;
|
|
96
|
-
let jostraca_inject_re = /(.*?JOSTRACA-INJECT-START.*?)([\r\n])[\s\S]*?([^\r\n]*JOSTRACA-INJECT-END.*)/;
|
|
97
|
-
m = jostraca_inject_re.exec(text);
|
|
98
|
-
//console.log('INJECT MATCH',m)
|
|
99
|
-
if (m) {
|
|
100
|
-
out = text.replace(m[0], m[1] + m[2] + render_text + m[3]);
|
|
101
|
-
}
|
|
102
|
-
return out;
|
|
103
|
-
},
|
|
104
|
-
load_templates(folder) {
|
|
105
|
-
let found = [];
|
|
106
|
-
walk(folder, [], found);
|
|
107
|
-
intern.parse_templates(found);
|
|
108
|
-
return found;
|
|
109
|
-
function walk(folder, parent_folders, found) {
|
|
110
|
-
let files = Fs.readdirSync(folder).filter((file_name) => {
|
|
111
|
-
return !file_name.endsWith('~');
|
|
112
|
-
});
|
|
113
|
-
for (let file of files) {
|
|
114
|
-
let path = folder + '/' + file;
|
|
115
|
-
let entrystat = Fs.lstatSync(path);
|
|
116
|
-
if (entrystat.isFile()) {
|
|
117
|
-
let m = file.match(/\.([^.]+)$/);
|
|
118
|
-
let kind = (m ? m[1] : '').toLowerCase();
|
|
119
|
-
found.push({
|
|
120
|
-
path,
|
|
121
|
-
parent_folders,
|
|
122
|
-
kind,
|
|
123
|
-
name: file,
|
|
124
|
-
text: Fs.readFileSync(path).toString(),
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
// NOTE: parent folders ordered by ancestor ascending,
|
|
129
|
-
// and thus opposite to folder path order. This is more
|
|
130
|
-
// useful for immediate parent folder name conventions
|
|
131
|
-
let child_parents = [file].concat(parent_folders);
|
|
132
|
-
walk(path, child_parents, found);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
parse_templates(templates) {
|
|
138
|
-
for (let template of templates) {
|
|
139
|
-
let ejs_render = Ejs.compile(template.text, {});
|
|
140
|
-
template.render = function (ctxt) {
|
|
141
|
-
return ejs_render(ctxt);
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
},
|
|
145
|
-
load_repo_spec(spec, repo) {
|
|
146
|
-
let version = '';
|
|
147
|
-
let pkg_path = spec.repofolder + '/' + repo.name + '/package.json';
|
|
148
|
-
if (Fs.existsSync(pkg_path)) {
|
|
149
|
-
let pkg = require(pkg_path);
|
|
150
|
-
version = pkg.version;
|
|
151
|
-
}
|
|
152
|
-
let repospec = {
|
|
153
|
-
version,
|
|
154
|
-
};
|
|
155
|
-
return repospec;
|
|
156
|
-
},
|
|
157
|
-
load_repo_groups(folder) {
|
|
158
|
-
let files = Fs.readdirSync(folder);
|
|
159
|
-
files = files.filter((entry) => {
|
|
160
|
-
// let entrystat = Fs.lstatSync(folder + '/' + entry)
|
|
161
|
-
return (
|
|
162
|
-
// entrystat.isFile() &&
|
|
163
|
-
!entry.startsWith('.') && !entry.endsWith('~'));
|
|
164
|
-
});
|
|
165
|
-
let groups = {};
|
|
166
|
-
for (let groupname of files) {
|
|
167
|
-
let group_def_loc = folder + '/' + groupname;
|
|
168
|
-
let is_folder = Fs.lstatSync(group_def_loc).isDirectory();
|
|
169
|
-
let grouptext = '';
|
|
170
|
-
// location is a folder, expect groupname.list file
|
|
171
|
-
if (is_folder) {
|
|
172
|
-
let groupfile = group_def_loc + '/' + groupname + '.list';
|
|
173
|
-
if (Fs.existsSync(groupfile)) {
|
|
174
|
-
grouptext = Fs.readFileSync(groupfile).toString();
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
// location is a file
|
|
178
|
-
else if (Fs.existsSync(group_def_loc)) {
|
|
179
|
-
grouptext = Fs.readFileSync(group_def_loc).toString();
|
|
180
|
-
}
|
|
181
|
-
// try .list suffix
|
|
182
|
-
else {
|
|
183
|
-
grouptext = Fs.readFileSync(group_def_loc + '.list').toString();
|
|
184
|
-
}
|
|
185
|
-
let repolist = intern.parse_repo_list(grouptext);
|
|
186
|
-
// index by repo name also
|
|
187
|
-
repolist.forEach((repo) => {
|
|
188
|
-
repolist[repo.name] = repo;
|
|
189
|
-
});
|
|
190
|
-
groups[groupname] = {
|
|
191
|
-
repos: repolist,
|
|
192
|
-
name: groupname,
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
return groups;
|
|
196
|
-
},
|
|
197
|
-
parse_repo_list(text) {
|
|
198
|
-
let repo_lines = text.split('\n').filter((line) => '' !== line);
|
|
199
|
-
let order = 0;
|
|
200
|
-
let repos = repo_lines
|
|
201
|
-
.map((line) => {
|
|
202
|
-
let m = line.match(/^([^#\.\s][^\s]*)(\s+.*)?$/);
|
|
203
|
-
let name = null;
|
|
204
|
-
let props_str = null;
|
|
205
|
-
let props = null;
|
|
206
|
-
if (m) {
|
|
207
|
-
name = m[1];
|
|
208
|
-
props_str = m[2];
|
|
209
|
-
props = props_str ? Jsonic(props_str.substring(1)) : {};
|
|
210
|
-
return { name, order: order++, props };
|
|
211
|
-
}
|
|
212
|
-
return null;
|
|
213
|
-
})
|
|
214
|
-
.filter((repo) => null !== repo);
|
|
215
|
-
return repos;
|
|
216
|
-
},
|
|
217
|
-
// NOTE: treats arrays as if objects where indexes are keys - this is desired
|
|
218
|
-
deep(...rest) {
|
|
219
|
-
rest = rest.reverse();
|
|
220
|
-
rest.unshift({});
|
|
221
|
-
return LodashDefaultsDeep.apply(null, rest);
|
|
222
|
-
},
|
|
223
|
-
};
|
|
224
|
-
exports.intern = intern;
|
|
225
|
-
function console_log(...rest) {
|
|
226
|
-
console.log(...rest);
|
|
227
|
-
}
|
|
228
|
-
function generate(spec) {
|
|
229
|
-
return intern.generate(spec);
|
|
230
|
-
}
|
|
231
|
-
exports.generate = generate;
|