fix: skip apt installation calls if package already installed

This commit is contained in:
Amin Yahyaabadi 2024-08-08 15:21:23 -07:00
parent 3774e9b3ac
commit 9ab878fa33
No known key found for this signature in database
GPG Key ID: F52AF77F636088F0
8 changed files with 124 additions and 101 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@ import { execa } from "execa"
import { chmod, readFile, writeFile } from "fs/promises"
import { DEFAULT_TIMEOUT } from "../installTool"
import { addPath } from "../utils/env/addEnv"
import { hasNala, isPackageInstalled, setupAptPack } from "../utils/setup/setupAptPack"
import { hasNala, isPackageRegexInstalled, setupAptPack } from "../utils/setup/setupAptPack"
import type { InstallationInfo } from "../utils/setup/setupBin"
export enum LLVMPackages {
@ -87,7 +87,7 @@ async function removeConflictingPackages(givenScript: string) {
await Promise.all(
conflictingPackages.map(async (pack) => {
const installingPack = pack.replace("$LLVM_VERSION", "*")
if (await isPackageInstalled(installingPack)) {
if (await isPackageRegexInstalled(installingPack)) {
info(`Removing conflicting package ${installingPack}`)
script = script.replace(pack, "")
}

View File

@ -35,16 +35,6 @@ export async function setupAptPack(packages: AptPackage[], update = false): Prom
process.env.DEBIAN_FRONTEND = "noninteractive"
if (!didUpdate || update) {
updateRepos(apt)
didUpdate = true
}
if (!didInit) {
await initApt(apt)
didInit = true
}
const allRepositories = [...new Set(packages.flatMap((pack) => pack.repositories ?? []))]
if (allRepositories.length !== 0) {
@ -56,15 +46,33 @@ export async function setupAptPack(packages: AptPackage[], update = false): Prom
updateRepos(apt)
}
const aptArgs = await Promise.all(packages.map((pack) => getAptArg(pack.name, pack.version)))
let qualifiedPacks = await Promise.all(packages.map((pack) => getAptArg(pack.name, pack.version)))
// find the packages that are not installed
qualifiedPacks = await Promise.all(qualifiedPacks.filter(async (pack) => !(await isPackageInstalled(pack))))
if (qualifiedPacks.length === 0) {
return { binDir: "/usr/bin/" }
}
if (!didUpdate || update) {
updateRepos(apt)
didUpdate = true
}
if (!didInit) {
await initApt(apt)
didInit = true
}
try {
execRootSync(apt, ["install", "--fix-broken", "-y", ...aptArgs])
execRootSync(apt, ["install", "--fix-broken", "-y", ...qualifiedPacks])
} catch (err) {
if ("stderr" in (err as ExecaError)) {
const stderr = (err as ExecaError).stderr
if (retryErrors.some((error) => stderr.includes(error))) {
warning(`Failed to install packages ${aptArgs}. Retrying...`)
execRootSync(apt, ["install", "--fix-broken", "-y", ...aptArgs])
warning(`Failed to install packages ${qualifiedPacks}. Retrying...`)
execRootSync(apt, ["install", "--fix-broken", "-y", ...qualifiedPacks])
}
} else {
throw err
@ -229,7 +237,22 @@ export async function updateAptAlternatives(name: string, path: string, priority
}
}
export async function isPackageInstalled(regexp: string) {
export async function isPackageInstalled(pack: string) {
try {
// check if a package is installed
const { stdout } = await execa("dpkg", ["-s", pack])
if (typeof stdout !== "string") {
return false
}
const lines = stdout.split("\n")
// check if the output contains a line that starts with "Status: install ok installed"
return lines.some((line) => line.startsWith("Status: install ok installed"))
} catch {
return false
}
}
export async function isPackageRegexInstalled(regexp: string) {
try {
// check if a package matching the regexp is installed
const { stdout } = await execa("dpkg", ["-l", regexp])