mirror of
https://github.com/smogon/sprites.git
synced 2026-03-22 01:45:27 -05:00
107 lines
2.8 KiB
TypeScript
107 lines
2.8 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 : string, dst : string}[];
|
|
|
|
constructor() {
|
|
this.queue = [];
|
|
}
|
|
|
|
copy(src : string, dst : string) {
|
|
// TODO: detect conflicts
|
|
this.queue.push({src, dst});
|
|
}
|
|
|
|
describe() : {src : string, dst : string}[] {
|
|
return this.queue;
|
|
}
|
|
|
|
join(dir : string) {
|
|
for (const pair of this.queue) {
|
|
pair.dst = nodePath.join(dir, pair.dst);
|
|
}
|
|
}
|
|
|
|
print() {
|
|
for (const {src, dst} of this.queue) {
|
|
console.log(`${src} ==> ${dst}`);
|
|
}
|
|
}
|
|
|
|
run(mode : 'link' | 'copy') {
|
|
for (const {src, dst} of this.queue) {
|
|
fs.mkdirSync(nodePath.dirname(dst), {recursive: true});
|
|
if (mode === 'link') {
|
|
fs.linkSync(src, dst);
|
|
} else {
|
|
fs.copyFileSync(src, dst);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export class Script extends vm.Script {
|
|
public readonly filename : string | null;
|
|
|
|
constructor(x : string, type : 'file' | 'expr') {
|
|
let code : string;
|
|
let filename : string | null = null;
|
|
if (type === 'expr') {
|
|
// Force expression parsing
|
|
code = `(${x})`;
|
|
} else {
|
|
code = fs.readFileSync(x, 'utf8');
|
|
filename = x;
|
|
}
|
|
super(code, filename !== null ? {filename} : undefined);
|
|
this.filename = filename;
|
|
}
|
|
}
|
|
|
|
const ENV_PROTO = {
|
|
spritename
|
|
};
|
|
|
|
function makeEnv(srcDir : 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.format(pathlib.join(srcDir, srcp)), pathlib.format(dstp));
|
|
}
|
|
}
|
|
}
|
|
|
|
export function runOnFile(scr : Script, src : pathlib.Path) : pathlib.Path {
|
|
const input = pathlib.update(src, {dir: ""});
|
|
const result = scr.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;
|
|
}
|
|
|
|
export function run(scr : Script, srcDir : string, queue : ActionQueue) {
|
|
scr.runInNewContext(makeEnv(srcDir, queue));
|
|
}
|