setup-cpp/src/nala/nala.ts

96 lines
2.7 KiB
TypeScript

import { tmpdir } from "os"
import { execRootSync } from "admina"
import { error, info } from "ci-log"
import { readFile, writeFile } from "fs/promises"
import { DownloaderHelper } from "node-downloader-helper"
import { dirname, join } from "patha"
import { hasNala, installAptPack, qualifiedNeededAptPackage } from "setup-apt"
import which from "which"
import { isUbuntu } from "../utils/env/isUbuntu.js"
let binDir: string | undefined
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export async function setupNala(version: string, _setupDir: string, _arch: string) {
if (!isUbuntu()) {
return undefined
}
if (typeof binDir === "string") {
return { binDir }
}
const maybeBinDir = which.sync("nala", { nothrow: true })
if (maybeBinDir !== null) {
binDir = dirname(maybeBinDir)
return { binDir }
}
await installAptPack([{ name: "python3-apt" }])
binDir = "/usr/bin" // eslint-disable-line require-atomic-updates
// If nala is available in the default repositories, install it
try {
const nalaPack = await qualifiedNeededAptPackage({ name: "nala", version })
if (nalaPack !== undefined) {
await installAptPack([{ name: nalaPack }])
return { binDir }
}
} catch (err) {
// ignore
info(`Failed to install nala: ${err}`)
}
// Nala is not available in the default repositories
// Check if the legacy version is available
try {
const nalaLegacyPack = await qualifiedNeededAptPackage({ name: "nala-legacy" })
if (nalaLegacyPack !== undefined) {
await installAptPack([{ name: nalaLegacyPack }], true)
return { binDir }
}
} catch (err) {
// ignore
info(`Failed to install nala-legacy: ${err}`)
}
// Install via the installer script
await setupNalaViaInstaller()
return { binDir }
}
async function setupNalaViaInstaller() {
const installer = new DownloaderHelper(
"https://gitlab.com/volian/volian-archive/-/raw/main/install-nala.sh",
tmpdir(),
{ fileName: "install-nala.sh" },
)
installer.on("error", (err) => {
throw new Error(`Failed to download install-nala.sh: ${err}`)
})
await installer.start()
const installerPath = join(tmpdir(), "install-nala.sh")
// Patch the installer script to not use sudo explicitly
const script = await readFile(installerPath, "utf8")
await writeFile(installerPath, script.replace(/sudo/g, ""))
await installAptPack([{ name: "wget" }])
try {
execRootSync("bash", [installerPath])
} catch (err) {
error(`Failed to install nala via installer: ${err}`)
execRootSync("apt", ["install", "-y", "-t", "nala", "nala"])
}
}
export function bashWithNala(script: string) {
if (hasNala()) {
return `apt-get() { nala $@; }; export -f apt-get; ${script}; unset -f apt-get`
}
return script
}