Skip to content

Commit b86c009

Browse files
authored
Merge pull request #255 from aminya/skip-apt [skip ci]
2 parents 3774e9b + 41e84d8 commit b86c009

File tree

10 files changed

+171
-115
lines changed

10 files changed

+171
-115
lines changed

dist/actions/setup-cpp.js

Lines changed: 27 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/actions/setup-cpp.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/legacy/setup-cpp.js

Lines changed: 27 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/legacy/setup-cpp.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/modern/setup-cpp.js

Lines changed: 27 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/modern/setup-cpp.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
"build.packages": "pnpm run -r build",
3232
"build.parcel": "cross-env NODE_ENV=production parcel build && run-s build.babel && shx cp -r ./dist/actions/* ./dist/modern",
3333
"build.babel": "babel ./dist --out-dir dist --plugins @upleveled/babel-plugin-remove-node-prefix --plugins @babel/plugin-transform-private-methods --compact --no-babelrc --source-maps true",
34-
"bump": "ncu -u -x numerous,execa,prettier,@types/node,eslint,@types/eslint && pnpm update && pnpx typesync",
35-
"clean": "shx rm -rf ./dist ./exe ./packages/*/dist/ ./.parcel-cache && shx mkdir -p ./dist/legacy ./dist/actions ./dist/modern ",
34+
"bump": "ncu -u -x numerous,execa,prettier,@types/node,eslint,@types/eslint && pnpm update && pnpx typesync && pnpm run clean",
35+
"clean": "shx rm -rf ./dist ./exe ./packages/*/dist/ && shx mkdir -p ./dist/legacy ./dist/actions ./dist/modern ",
3636
"copy.matchers": "run-p copy.matchers.legacy copy.matchers.actions",
3737
"copy.matchers.legacy": "shx cp ./src/gcc/gcc_matcher.json ./dist/legacy/ && shx cp ./src/msvc/msvc_matcher.json ./dist/legacy/ && shx cp ./src/python/python_matcher.json ./dist/legacy/ && shx cp ./src/llvm/llvm_matcher.json ./dist/legacy/",
3838
"copy.matchers.actions": "shx cp ./src/gcc/gcc_matcher.json ./dist/actions/ && shx cp ./src/msvc/msvc_matcher.json ./dist/actions/ && shx cp ./src/python/python_matcher.json ./dist/actions/ && shx cp ./src/llvm/llvm_matcher.json ./dist/actions/",

src/llvm/llvm_installer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { execa } from "execa"
44
import { chmod, readFile, writeFile } from "fs/promises"
55
import { DEFAULT_TIMEOUT } from "../installTool"
66
import { addPath } from "../utils/env/addEnv"
7-
import { hasNala, isPackageInstalled, setupAptPack } from "../utils/setup/setupAptPack"
7+
import { hasNala, isPackageRegexInstalled, setupAptPack } from "../utils/setup/setupAptPack"
88
import type { InstallationInfo } from "../utils/setup/setupBin"
99

1010
export enum LLVMPackages {
@@ -87,7 +87,7 @@ async function removeConflictingPackages(givenScript: string) {
8787
await Promise.all(
8888
conflictingPackages.map(async (pack) => {
8989
const installingPack = pack.replace("$LLVM_VERSION", "*")
90-
if (await isPackageInstalled(installingPack)) {
90+
if (await isPackageRegexInstalled(installingPack)) {
9191
info(`Removing conflicting package ${installingPack}`)
9292
script = script.replace(pack, "")
9393
}

src/nala/nala.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export async function setupNala(version: string, _setupDir: string, _arch: strin
2121
return { binDir }
2222
}
2323

24+
await setupAptPack([{ name: "python3-apt" }])
25+
2426
// https://gitlab.com/volian/nala/-/wikis/Installation
2527
const keyFileName = await addAptKeyViaDownload(
2628
"volian-archive-nala.gpg",

src/utils/setup/setupAptPack.ts

Lines changed: 81 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -35,36 +35,41 @@ export async function setupAptPack(packages: AptPackage[], update = false): Prom
3535

3636
process.env.DEBIAN_FRONTEND = "noninteractive"
3737

38-
if (!didUpdate || update) {
38+
// Update the repos if needed
39+
if (update) {
3940
updateRepos(apt)
4041
didUpdate = true
4142
}
4243

43-
if (!didInit) {
44-
await initApt(apt)
45-
didInit = true
46-
}
44+
// Add the repos if needed
45+
await addRepositories(apt, packages)
4746

48-
const allRepositories = [...new Set(packages.flatMap((pack) => pack.repositories ?? []))]
47+
// Qualify the packages into full package name/version
48+
let qualifiedPacks = await Promise.all(packages.map((pack) => getAptArg(pack.name, pack.version)))
4949

50-
if (allRepositories.length !== 0) {
51-
for (const repo of allRepositories) {
52-
// eslint-disable-next-line no-await-in-loop
53-
execRootSync("add-apt-repository", ["-y", repo])
54-
}
50+
// find the packages that are not installed
51+
qualifiedPacks = await Promise.all(qualifiedPacks.filter(async (pack) => !(await isPackageInstalled(pack))))
5552

56-
updateRepos(apt)
53+
if (qualifiedPacks.length === 0) {
54+
info("All packages are already installed")
55+
return { binDir: "/usr/bin/" }
56+
}
57+
58+
// Initialize apt if needed
59+
if (!didInit) {
60+
await initApt(apt)
61+
didInit = true
5762
}
5863

59-
const aptArgs = await Promise.all(packages.map((pack) => getAptArg(pack.name, pack.version)))
64+
// Install
6065
try {
61-
execRootSync(apt, ["install", "--fix-broken", "-y", ...aptArgs])
66+
execRootSync(apt, ["install", "--fix-broken", "-y", ...qualifiedPacks])
6267
} catch (err) {
6368
if ("stderr" in (err as ExecaError)) {
6469
const stderr = (err as ExecaError).stderr
6570
if (retryErrors.some((error) => stderr.includes(error))) {
66-
warning(`Failed to install packages ${aptArgs}. Retrying...`)
67-
execRootSync(apt, ["install", "--fix-broken", "-y", ...aptArgs])
71+
warning(`Failed to install packages ${qualifiedPacks}. Retrying...`)
72+
execRootSync(apt, ["install", "--fix-broken", "-y", ...qualifiedPacks])
6873
}
6974
} else {
7075
throw err
@@ -81,6 +86,23 @@ export enum AptPackageType {
8186
None = 3,
8287
}
8388

89+
async function addRepositories(apt: string, packages: AptPackage[]) {
90+
const allRepositories = [...new Set(packages.flatMap((pack) => pack.repositories ?? []))]
91+
if (allRepositories.length !== 0) {
92+
if (!didInit) {
93+
await initApt(apt)
94+
didInit = true
95+
}
96+
await installAddAptRepo()
97+
for (const repo of allRepositories) {
98+
// eslint-disable-next-line no-await-in-loop
99+
execRootSync("add-apt-repository", ["-y", repo])
100+
}
101+
updateRepos(apt)
102+
didUpdate = true
103+
}
104+
}
105+
84106
export async function aptPackageType(name: string, version: string | undefined): Promise<AptPackageType> {
85107
if (version !== undefined && version !== "") {
86108
const { stdout } = await execa("apt-cache", [
@@ -113,6 +135,13 @@ export async function aptPackageType(name: string, version: string | undefined):
113135
// ignore
114136
}
115137

138+
// If apt-cache fails, update the repos and try again
139+
if (!didUpdate) {
140+
updateRepos(getApt())
141+
didUpdate = true
142+
return aptPackageType(name, version)
143+
}
144+
116145
return AptPackageType.None
117146
}
118147

@@ -148,17 +177,27 @@ function updateRepos(apt: string) {
148177
execRootSync(apt, apt !== "nala" ? ["update", "-y"] : ["update"])
149178
}
150179

151-
/** Install apt utils and certificates (usually missing from docker containers) */
180+
async function installAddAptRepo() {
181+
if (await isPackageInstalled("software-properties-common")) {
182+
return
183+
}
184+
execRootSync("apt-get", ["install", "-y", "--fix-broken", "software-properties-common"])
185+
}
186+
187+
/** Install gnupg and certificates (usually missing from docker containers) */
152188
async function initApt(apt: string) {
153-
execRootSync(apt, [
154-
"install",
155-
"--fix-broken",
156-
"-y",
157-
"software-properties-common",
158-
"apt-utils",
159-
"ca-certificates",
160-
"gnupg",
161-
])
189+
// Update the repos if needed
190+
if (!didUpdate) {
191+
updateRepos(apt)
192+
didUpdate = true
193+
}
194+
195+
const toInstall = ["ca-certificates", "gnupg", "apt-utils"].filter(async (pack) => !(await isPackageInstalled(pack)))
196+
197+
if (toInstall.length !== 0) {
198+
execRootSync(apt, ["install", "-y", "--fix-broken", ...toInstall])
199+
}
200+
162201
const promises: Promise<string | void>[] = [
163202
addAptKeyViaServer(["3B4FE6ACC0B21F32", "40976EAF437D05B5"], "setup-cpp-ubuntu-archive.gpg"),
164203
addAptKeyViaServer(["1E9377A2BA9EF27F"], "launchpad-toolchain.gpg"),
@@ -229,7 +268,22 @@ export async function updateAptAlternatives(name: string, path: string, priority
229268
}
230269
}
231270

232-
export async function isPackageInstalled(regexp: string) {
271+
export async function isPackageInstalled(pack: string) {
272+
try {
273+
// check if a package is installed
274+
const { stdout } = await execa("dpkg", ["-s", pack])
275+
if (typeof stdout !== "string") {
276+
return false
277+
}
278+
const lines = stdout.split("\n")
279+
// check if the output contains a line that starts with "Status: install ok installed"
280+
return lines.some((line) => line.startsWith("Status: install ok installed"))
281+
} catch {
282+
return false
283+
}
284+
}
285+
286+
export async function isPackageRegexInstalled(regexp: string) {
233287
try {
234288
// check if a package matching the regexp is installed
235289
const { stdout } = await execa("dpkg", ["-l", regexp])

0 commit comments

Comments
 (0)