lune-packaging/package/js/install.ts

103 lines
2.5 KiB
TypeScript

import * as path from "jsr:@std/path";
import { unzip } from "https://deno.land/x/nzip@v1.2.1/mod.ts";
import { fetchLuneReleases } from "./github.ts";
import consts, { BASE_PATH } from "./consts.ts";
export const LUNE_VERSION = consts.version;
export const EXE_EXTENSION = Deno.build.os == "windows" ? ".exe" : "";
async function installLune() {
let ghAuthToken: string | undefined;
try {
/*
Ideally, this would look like this:
new TextDecoder().decode(
(await new Deno.Command("gh", {
args: ["auth", "token"],
stdout: "piped",
}).output()).stdout,
);
However, dnt is yet to support Deno.command
*/
ghAuthToken = new TextDecoder().decode(
// deno-lint-ignore no-deprecated-deno-api
await Deno.run({
cmd: ["gh", "auth", "token"],
stdout: "piped",
}).output(),
);
} catch (_) {
// Don't use an auth token, be subjected to GitHub ratelimit
}
const releases = await fetchLuneReleases(ghAuthToken);
const currentRelease = releases.find((release) =>
release.tag_name === "v" + LUNE_VERSION
)!;
const platformRelease = currentRelease.assets.find((asset) =>
asset.name == `lune-${LUNE_VERSION}-${Deno.build.os}-${Deno.build.arch}.zip`
);
if (!platformRelease) {
throw new Deno.errors.NotFound(
`UnsupportedPlatform: ${Deno.build.os}-${Deno.build.arch}`,
);
}
const resp = await fetch(platformRelease.browser_download_url);
if (!resp.ok) {
throw new Deno.errors.NotFound(
`Failed to download Lune: ${resp.status}`,
);
}
const zipFile = await Deno.makeTempFile({ suffix: ".zip" });
const finalDestDir = path.join(BASE_PATH, consts.version);
const binaryBlob = resp.body!;
await binaryBlob.pipeTo(
(await Deno.open(
zipFile,
{ write: true },
)).writable,
);
const binaryPaths = await unzip(zipFile, finalDestDir, {
useWebWorkers: true,
});
if (Deno.build.os !== "windows") await Deno.chmod(binaryPaths[0], 0o777);
}
export async function checkAndInstallLune() {
const luneExePath = path.join(
BASE_PATH,
consts.version,
"lune" + EXE_EXTENSION,
);
const luneExists = await Deno.lstat(luneExePath).then(
(stat) => {
if (stat.isDirectory) {
Deno.remove(luneExePath, { recursive: true });
} else if (stat.isFile) {
return true;
}
return false;
},
(err) => {
if (err instanceof Deno.errors.NotFound) {
return false;
}
throw err;
},
);
if (!luneExists) await installLune();
}
await checkAndInstallLune();