sprites/tools/deploy/script.ts
2020-08-09 05:59:21 -04:00

92 lines
2.4 KiB
TypeScript

import fs from 'fs';
import nodePath from 'path';
import vm from 'vm';
import * as pathlib from './path.js';
import * as spritename from './spritename.js';
export class ActionQueue {
private queue: {src : pathlib.Path, dst : pathlib.Path}[];
constructor() {
this.queue = [];
}
copy(src : pathlib.Path, dst : pathlib.Path) {
// TODO: detect conflicts
this.queue.push({src, dst});
}
describe() : {src : pathlib.Path, dst : pathlib.Path}[] {
return this.queue;
}
print() {
for (const {src, dst} of this.queue) {
console.log(`${pathlib.format(src)} ==> ${pathlib.format(dst)}`);
}
}
run(mode : 'link' | 'copy') {
for (const {src, dst} of this.queue) {
fs.mkdirSync(dst.dir, {recursive: true});
if (mode === 'link') {
fs.linkSync(pathlib.format(src), pathlib.format(dst));
} else {
fs.copyFileSync(pathlib.format(src), pathlib.format(dst));
}
}
}
}
const ENV_PROTO = {
spritename
};
function makeEnv(srcDir : string, dstDir : string, queue: ActionQueue) {
return {
__proto__: ENV_PROTO,
list(dir : string) : pathlib.Path[] {
const result = [];
for (const filename of fs.readdirSync(nodePath.join(srcDir, dir))) {
result.push(pathlib.path(filename, {dir}));
}
return result;
},
copy(src : pathlib.PathLike, dst : pathlib.PathLike) {
const srcp = pathlib.path(src);
const dstp = pathlib.path(dst);
queue.copy(pathlib.join(srcDir, srcp), pathlib.join(dstDir, dstp));
}
}
}
export class Script {
private script : vm.Script;
constructor(code : string) {
this.script = new vm.Script(code);
}
runOnFile(src : pathlib.Path) : pathlib.Path {
const input = pathlib.update(src, {dir: ""});
const result = this.script.runInNewContext({
__proto__: ENV_PROTO,
path: input,
...input
});
if (result === undefined) {
throw new Error(`undefined output on ${pathlib.format(src)}`);
}
const output = pathlib.path(input, result);
return output;
}
run(srcDir : string, dstDir : string, queue : ActionQueue) {
this.script.runInNewContext(makeEnv(srcDir, dstDir, queue));
}
}