This repository has been archived by the owner on Apr 3, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 51
/
Copy pathupdater.d
81 lines (61 loc) · 2.65 KB
/
updater.d
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
module updater;
import std.process: Config, spawnShell;
import std.json: JSONValue, parseJSON;
import std.net.curl: get, download;
import std.range: zip, popFront;
import std.file: thisExePath;
import std.algorithm: sort;
import std.stdio: writeln;
import std.string: split;
import std.path: dirName;
import std.conv: to;
import core.stdc.stdlib: exit;
import common: formatString;
debug import std.stdio: writeln;
void startInstallUpdate(const string downloadUrl, const string installerFile, const bool silent = false) {
// Download the installer to the temporary path created above.
download(downloadUrl, installerFile);
auto launchArgs = `"{{installerFile}}" {{otherArgs}} /components="main, updater" /dir="{{installPath}}"`
.formatString(["installerFile"
: installerFile, "installPath" : thisExePath().dirName(), "otherArgs" : silent ? "/verysilent" : ""]);
debug writeln(launchArgs);
// This executable should already be running as admin so no verb should be necessary.
spawnShell(launchArgs, null, Config.detached | Config.suppressConsole);
exit(0);
}
/// Iterate through a release's assets and return the one that matches the filename given.
JSONValue getReleaseAsset(const JSONValue release, const string filename) {
foreach (asset; release["assets"].array)
if (asset["name"].str == filename)
return asset;
assert(false);
}
/// Return the latest release according to semantic versioning.
JSONValue getLatestRelease(const string author, const string repository) {
const string apiReleases = "https://api.github.com/repos/" ~ author ~ "/" ~ repository ~ "/releases";
JSONValue releasesJson = get(apiReleases).parseJSON();
releasesJson.array.sort!((a, b) => compareVersions(a["tag_name"].str, b["tag_name"].str))();
return releasesJson.array[0];
}
/// Compare two semantic versions, returning true if the first version is newer, false otherwise.
public bool compareVersions(const string firstVer, const string secondVer) {
ushort[] firstVerParts = firstVer.split('.').to!(ushort[]);
ushort[] secondVerParts = secondVer.split('.').to!(ushort[]);
while (firstVerParts.length > secondVerParts.length) {
if (firstVerParts[0] != 0)
return true;
firstVerParts.popFront();
}
while (secondVerParts.length > firstVerParts.length) {
if (secondVerParts[0] != 0)
return false;
secondVerParts.popFront();
}
foreach (verParts; zip(firstVerParts, secondVerParts)) {
if (verParts[0] > verParts[1])
return true;
else if (verParts[1] > verParts[0])
return false;
}
return false;
}