69 lines
1.8 KiB
TypeScript
69 lines
1.8 KiB
TypeScript
import { difference, Sys } from "../deps.ts";
|
|
|
|
export class Runner {
|
|
constructor(readonly sys = Sys) {
|
|
}
|
|
|
|
// Run a tool by its name and args
|
|
async run(args: string[]) {
|
|
const app = args.shift();
|
|
if (!app) {
|
|
throw new Error("Usage: run app [args...]");
|
|
}
|
|
|
|
const flags_txt = await this.downloadText(
|
|
`https://code.thunderk.net/typescript/${app}/raw/branch/master/config/run.flags`,
|
|
);
|
|
const flags = flags_txt.split(/\s+/).filter((arg) => arg);
|
|
if (flags.some((arg) => !arg.startsWith("--"))) {
|
|
throw new Error(`Bad run flags: ${flags}`);
|
|
}
|
|
|
|
if (!await this.checkStamp(app)) {
|
|
console.log("Reloading sources...");
|
|
flags.unshift("--reload");
|
|
}
|
|
|
|
const uri =
|
|
`https://code.thunderk.net/typescript/${app}/raw/branch/master/cli.ts`;
|
|
await this.sys.run({
|
|
cmd: ["deno", "run"].concat(flags).concat([uri]).concat(args),
|
|
}).status();
|
|
}
|
|
|
|
// Download a remote text content (empty if not a 200 response)
|
|
async downloadText(uri: string): Promise<string> {
|
|
const response = await fetch(uri);
|
|
if (response.status == 200) {
|
|
const result = await response.text();
|
|
return result;
|
|
} else {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
// Check an app timestamp, returning true if it is valid
|
|
async checkStamp(app: string): Promise<boolean> {
|
|
const path = `/tmp/thunderk-run-${app}.stamp`;
|
|
try {
|
|
const stat = await this.sys.stat(path);
|
|
if (stat.isFile && stat.mtime) {
|
|
const age = difference(stat.mtime, new Date()).days ?? 0;
|
|
if (age < 1) {
|
|
return true;
|
|
}
|
|
}
|
|
} catch {
|
|
}
|
|
|
|
await this.sys.writeTextFile(path, "");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Run a remote program, by its name and args
|
|
export async function run(args: string[], sys = Sys) {
|
|
const runner = new Runner(sys);
|
|
await runner.run(args);
|
|
}
|