ScuttleBot

scuttlebot / sdk / npm / scuttlectl / bin / scuttlectl.js
Blame History Raw 94 lines
1
#!/usr/bin/env node
2
/**
3
* scuttlectl npm wrapper.
4
* Downloads the appropriate scuttlectl binary for the current platform
5
* and executes it, passing all arguments through.
6
*/
7
"use strict";
8
9
const { execFileSync } = require("child_process");
10
const { createWriteStream, existsSync, mkdirSync, chmodSync } = require("fs");
11
const { get } = require("https");
12
const { join } = require("path");
13
const { createGunzip } = require("zlib");
14
const { Extract } = require("tar");
15
16
const REPO = "ConflictHQ/scuttlebot";
17
const BIN_DIR = join(__dirname, "..", "dist");
18
const BIN_PATH = join(BIN_DIR, process.platform === "win32" ? "scuttlectl.exe" : "scuttlectl");
19
20
function platformSuffix() {
21
const os = process.platform === "darwin" ? "darwin" : "linux";
22
const arch = process.arch === "arm64" ? "arm64" : "x86_64";
23
return `${os}-${arch}`;
24
}
25
26
async function fetchLatestVersion() {
27
return new Promise((resolve, reject) => {
28
get(
29
`https://api.github.com/repos/${REPO}/releases/latest`,
30
{ headers: { "User-Agent": "scuttlectl-npm" } },
31
(res) => {
32
let data = "";
33
res.on("data", (c) => (data += c));
34
res.on("end", () => {
35
try {
36
resolve(JSON.parse(data).tag_name);
37
} catch (e) {
38
reject(e);
39
}
40
});
41
}
42
).on("error", reject);
43
});
44
}
45
46
async function download(url, dest) {
47
return new Promise((resolve, reject) => {
48
get(url, { headers: { "User-Agent": "scuttlectl-npm" } }, (res) => {
49
if (res.statusCode === 302 || res.statusCode === 301) {
50
return download(res.headers.location, dest).then(resolve).catch(reject);
51
}
52
mkdirSync(BIN_DIR, { recursive: true });
53
const out = createWriteStream(dest);
54
res.pipe(out);
55
out.on("finish", resolve);
56
out.on("error", reject);
57
}).on("error", reject);
58
});
59
}
60
61
async function ensureBinary() {
62
if (existsSync(BIN_PATH)) return;
63
64
const version = await fetchLatestVersion();
65
const suffix = platformSuffix();
66
const asset = `scuttlectl-${version}-${suffix}.tar.gz`;
67
const url = `https://github.com/${REPO}/releases/download/${version}/${asset}`;
68
const tarPath = join(BIN_DIR, asset);
69
70
process.stderr.write(`Downloading scuttlectl ${version}...\n`);
71
await download(url, tarPath);
72
73
await new Promise((resolve, reject) => {
74
require("fs")
75
.createReadStream(tarPath)
76
.pipe(createGunzip())
77
.pipe(Extract({ cwd: BIN_DIR, strip: 0 }))
78
.on("finish", resolve)
79
.on("error", reject);
80
});
81
82
chmodSync(BIN_PATH, 0o755);
83
require("fs").unlinkSync(tarPath);
84
}
85
86
ensureBinary()
87
.then(() => {
88
execFileSync(BIN_PATH, process.argv.slice(2), { stdio: "inherit" });
89
})
90
.catch((err) => {
91
process.stderr.write(`scuttlectl: ${err.message}\n`);
92
process.exit(1);
93
});
94

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button