@genesis-agent/cli 0.5.9 → 0.5.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/install.js +56 -0
- package/package.json +1 -1
package/install.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
const fs = require("fs");
|
|
6
6
|
const path = require("path");
|
|
7
7
|
const https = require("https");
|
|
8
|
+
const crypto = require("crypto");
|
|
8
9
|
const { execSync } = require("child_process");
|
|
9
10
|
|
|
10
11
|
const VERSION = require("./package.json").version;
|
|
@@ -42,6 +43,60 @@ function getDownloadUrl(binaryName) {
|
|
|
42
43
|
return `https://github.com/${REPO}/releases/download/v${VERSION}/${binaryName}`;
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
function getChecksumUrl() {
|
|
47
|
+
return `https://github.com/${REPO}/releases/download/v${VERSION}/sha256sums.txt`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function fetchText(url) {
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
const follow = (url, redirects) => {
|
|
53
|
+
if (redirects > 5) return reject(new Error("Too many redirects"));
|
|
54
|
+
|
|
55
|
+
https
|
|
56
|
+
.get(url, (res) => {
|
|
57
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
58
|
+
return follow(res.headers.location, redirects + 1);
|
|
59
|
+
}
|
|
60
|
+
if (res.statusCode !== 200) {
|
|
61
|
+
return reject(new Error(`Download failed: HTTP ${res.statusCode}`));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
res.setEncoding("utf8");
|
|
65
|
+
let body = "";
|
|
66
|
+
res.on("data", (chunk) => {
|
|
67
|
+
body += chunk;
|
|
68
|
+
});
|
|
69
|
+
res.on("end", () => resolve(body));
|
|
70
|
+
})
|
|
71
|
+
.on("error", reject);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
follow(url, 0);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function checksumFor(text, binaryName) {
|
|
79
|
+
for (const line of text.split(/\r?\n/)) {
|
|
80
|
+
const fields = line.trim().split(/\s+/);
|
|
81
|
+
if (fields.length >= 2 && fields[1] === binaryName) return fields[0].toLowerCase();
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function sha256File(filePath) {
|
|
87
|
+
const hash = crypto.createHash("sha256");
|
|
88
|
+
hash.update(fs.readFileSync(filePath));
|
|
89
|
+
return hash.digest("hex");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function verifyChecksum(binaryName, dest) {
|
|
93
|
+
const sums = await fetchText(getChecksumUrl());
|
|
94
|
+
const expected = checksumFor(sums, binaryName);
|
|
95
|
+
if (!expected) throw new Error(`Missing checksum for ${binaryName}`);
|
|
96
|
+
const actual = sha256File(dest);
|
|
97
|
+
if (actual !== expected) throw new Error(`Checksum mismatch for ${binaryName}`);
|
|
98
|
+
}
|
|
99
|
+
|
|
45
100
|
function download(url, dest) {
|
|
46
101
|
return new Promise((resolve, reject) => {
|
|
47
102
|
const follow = (url, redirects) => {
|
|
@@ -100,6 +155,7 @@ async function main() {
|
|
|
100
155
|
|
|
101
156
|
try {
|
|
102
157
|
await download(url, dest);
|
|
158
|
+
await verifyChecksum(binaryName, dest);
|
|
103
159
|
if (process.platform !== "win32") {
|
|
104
160
|
fs.chmodSync(dest, 0o755);
|
|
105
161
|
}
|