-
Notifications
You must be signed in to change notification settings - Fork 17
/
update.ts
93 lines (78 loc) · 2.51 KB
/
update.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import { decode, encode } from "./deps.ts";
import { importUrls } from "./search.ts";
import { versioned, Versioned } from "./versioned.ts";
// FIXME we should catch ctrl-c etc. and write back the original deps.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> {
// first we test the thunk works prior to updatng...
if (await this.test()) {
console.error("Tests failed prior to update");
Deno.exit(1);
}
const content: string = await this.content(); // decode(await Deno.readFile(filename));
const urls: string[] = importUrls(content);
// from a url we need to extract the current version
for (const u of urls) {
const v = versioned(u);
if (v !== undefined) {
await this.updateOne(v!);
}
}
// TODO count the imports that were updated
}
async updateOne(
url: Versioned
): Promise<void> {
// now we look up the available versions
const versions = await url.all();
console.log("current version:", url.current());
console.log("available versions:", versions);
// TODO: options: try latest, semver compat, or input
// pick a new version (should be in for loop?)
// i.e. rety or skip if fails
// for now, let's pick the most recent!
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));
}
}