import { decode, encode } from "./deps.ts";import { importUrls } from "./search.ts";import { versioned, Versioned } from "./versioned.ts";
export async function update( filename: string, test: () => Promise<boolean>): Promise<void> { const u = new Update(filename, test); await u.update();}
export class Update { private filename: string; private test: () => Promise<boolean>;
constructor(filename: string, test: () => Promise<boolean>) { this.filename = filename; this.test = test; }
async update(): Promise<void> { if (await this.test()) { console.error("Tests failed prior to update"); Deno.exit(1); }
const content: string = await this.content();
const urls: string[] = importUrls(content);
for (const u of urls) { const v = versioned(u); if (v !== undefined) { await this.updateOne(v!); } } }
async updateOne( url: Versioned ): Promise<void> { const versions = await url.all(); console.log("current version:", url.current()); console.log("available versions:", versions);
const newVersion = versions[0]; if (url.current() === newVersion) { return; } const fails: boolean = await this.updateIfTestPasses(url, newVersion); }
async updateIfTestPasses( url: Versioned, newVersion: string ): Promise<boolean> { const newUrl = url.at(newVersion); console.log("Updating to", newUrl.url); await this.replace(url, newUrl);
console.log("Running tests..."); if (await this.test()) { console.log("Test failed, reverting."); await this.replace(newUrl, url); return true; } else { console.log("Test passed."); return false; } }
async content(): Promise<string> { return decode(await Deno.readFile(this.filename)); }
async replace(url: Versioned, newUrl: Versioned) { const content = await this.content(); const newContent = content.split(url.url).join(newUrl.url); await Deno.writeFile(this.filename, encode(newContent)); }}