mirror of https://github.com/aminya/setup-cpp
fix: install nala via default repo or installer
This commit is contained in:
parent
61855cf251
commit
4e7c4bb64b
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
|
@ -46,6 +46,34 @@ Add the update-alternatives command to the rc file
|
||||||
|
|
||||||
**returns:** Promise<void>
|
**returns:** Promise<void>
|
||||||
|
|
||||||
|
### `getAptEnv` (function)
|
||||||
|
|
||||||
|
Get the environment variables to use for the apt command
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- apt (`string`) - The apt command to use
|
||||||
|
|
||||||
|
**returns:** ProcessEnv
|
||||||
|
|
||||||
|
### `aptTimeout` (variable)
|
||||||
|
|
||||||
|
The timeout to use for apt commands
|
||||||
|
Wait up to 300 seconds if the apt-get lock is held
|
||||||
|
|
||||||
|
### `hasNala` (function)
|
||||||
|
|
||||||
|
Check if nala is installed
|
||||||
|
|
||||||
|
**returns:** boolean
|
||||||
|
|
||||||
|
### `getApt` (function)
|
||||||
|
|
||||||
|
Get the apt command to use
|
||||||
|
If nala is installed, use that, otherwise use apt-get
|
||||||
|
|
||||||
|
**returns:** string
|
||||||
|
|
||||||
### `isAptPackInstalled` (function)
|
### `isAptPackInstalled` (function)
|
||||||
|
|
||||||
Check if a package is installed
|
Check if a package is installed
|
||||||
|
@ -66,6 +94,8 @@ Check if a package matching a regexp is installed
|
||||||
|
|
||||||
**returns:** Promise<boolean>
|
**returns:** Promise<boolean>
|
||||||
|
|
||||||
|
### `updatedRepos` (variable)
|
||||||
|
|
||||||
### `updateAptRepos` (function)
|
### `updateAptRepos` (function)
|
||||||
|
|
||||||
Update the apt repositories
|
Update the apt repositories
|
||||||
|
@ -76,15 +106,73 @@ Update the apt repositories
|
||||||
|
|
||||||
**returns:** void
|
**returns:** void
|
||||||
|
|
||||||
|
### `updateAptReposMemoized` (variable)
|
||||||
|
|
||||||
|
Update the apt repositories (memoized)
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- apt - The apt command to use (optional)
|
||||||
|
|
||||||
|
### `filterAndQualifyAptPackages` (function)
|
||||||
|
|
||||||
|
Filter out the packages that are already installed and qualify the packages into a full package name/version
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- packages (`AptPackage[]`)
|
||||||
|
- apt (`string`)
|
||||||
|
|
||||||
|
**returns:** Promise<string[]>
|
||||||
|
|
||||||
|
### `qualifiedNeededAptPackage` (function)
|
||||||
|
|
||||||
|
Qualify the package into full package name/version.
|
||||||
|
If the package is not installed, return the full package name/version.
|
||||||
|
If the package is already installed, return undefined
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- pack (`AptPackage`)
|
||||||
|
- apt (`string`)
|
||||||
|
|
||||||
|
**returns:** Promise<string>
|
||||||
|
|
||||||
|
### `initApt` (function)
|
||||||
|
|
||||||
|
Install gnupg and certificates (usually missing from docker containers)
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- apt (`string`)
|
||||||
|
|
||||||
|
**returns:** Promise<void>
|
||||||
|
|
||||||
|
### `initAptMemoized` (variable)
|
||||||
|
|
||||||
|
Install gnupg and certificates (usually missing from docker containers) (memoized)
|
||||||
|
|
||||||
|
### `addAptRepository` (function)
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- repo (`string`)
|
||||||
|
- apt (`string`)
|
||||||
|
|
||||||
|
**returns:** Promise<void>
|
||||||
|
|
||||||
|
### `installAddAptRepo` (function)
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- apt (`string`)
|
||||||
|
|
||||||
|
**returns:** Promise<void>
|
||||||
|
|
||||||
### `InstallationInfo` (type)
|
### `InstallationInfo` (type)
|
||||||
|
|
||||||
The information about an installation result
|
The information about an installation result
|
||||||
|
|
||||||
### `aptTimeout` (variable)
|
|
||||||
|
|
||||||
The timeout to use for apt commands
|
|
||||||
Wait up to 300 seconds if the apt-get lock is held
|
|
||||||
|
|
||||||
### `AptPackage` (type)
|
### `AptPackage` (type)
|
||||||
|
|
||||||
The information about an apt package
|
The information about an apt package
|
||||||
|
@ -115,29 +203,6 @@ await installAptPack([
|
||||||
])
|
])
|
||||||
```
|
```
|
||||||
|
|
||||||
### `hasNala` (function)
|
|
||||||
|
|
||||||
Check if nala is installed
|
|
||||||
|
|
||||||
**returns:** boolean
|
|
||||||
|
|
||||||
### `getApt` (function)
|
|
||||||
|
|
||||||
Get the apt command to use
|
|
||||||
If nala is installed, use that, otherwise use apt-get
|
|
||||||
|
|
||||||
**returns:** string
|
|
||||||
|
|
||||||
### `getAptEnv` (function)
|
|
||||||
|
|
||||||
Get the environment variables to use for the apt command
|
|
||||||
|
|
||||||
**Parameters:**
|
|
||||||
|
|
||||||
- apt (`string`) - The apt command to use
|
|
||||||
|
|
||||||
**returns:** ProcessEnv
|
|
||||||
|
|
||||||
### `AddAptKeyOptions` (type)
|
### `AddAptKeyOptions` (type)
|
||||||
|
|
||||||
### `addAptKey` (function)
|
### `addAptKey` (function)
|
||||||
|
@ -151,10 +216,7 @@ Add an apt key
|
||||||
**returns:** Promise<string>
|
**returns:** Promise<string>
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
await addAptKey({
|
await addAptKey({ key: "3B4FE6ACC0B21F32" fileName: "bazel-archive-keyring.gpg"})
|
||||||
key: "3B4FE6ACC0B21F32"
|
|
||||||
fileName: "bazel-archive-keyring.gpg",
|
|
||||||
})
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
|
|
@ -6,4 +6,5 @@ export * from "./get-apt.js"
|
||||||
export * from "./init-apt.js"
|
export * from "./init-apt.js"
|
||||||
export * from "./install.js"
|
export * from "./install.js"
|
||||||
export * from "./is-installed.js"
|
export * from "./is-installed.js"
|
||||||
|
export * from "./qualify-install.js"
|
||||||
export * from "./update.js"
|
export * from "./update.js"
|
||||||
|
|
|
@ -10,11 +10,11 @@ export async function initApt(apt: string) {
|
||||||
// Update the repos
|
// Update the repos
|
||||||
updateAptReposMemoized(apt)
|
updateAptReposMemoized(apt)
|
||||||
|
|
||||||
const toInstall = await filterAndQualifyAptPackages(apt, [
|
const toInstall = await filterAndQualifyAptPackages([
|
||||||
{ name: "ca-certificates" },
|
{ name: "ca-certificates" },
|
||||||
{ name: "gnupg" },
|
{ name: "gnupg" },
|
||||||
{ name: "apt-utils" },
|
{ name: "apt-utils" },
|
||||||
])
|
], apt)
|
||||||
|
|
||||||
if (toInstall.length !== 0) {
|
if (toInstall.length !== 0) {
|
||||||
execRootSync(apt, ["install", "-y", "--fix-broken", "-o", aptTimeout, ...toInstall], {
|
execRootSync(apt, ["install", "-y", "--fix-broken", "-o", aptTimeout, ...toInstall], {
|
||||||
|
|
|
@ -82,7 +82,7 @@ export async function installAptPack(packages: AptPackage[], update = false): Pr
|
||||||
// Add the repos if needed
|
// Add the repos if needed
|
||||||
await addRepositories(apt, packages)
|
await addRepositories(apt, packages)
|
||||||
|
|
||||||
const needToInstall = await filterAndQualifyAptPackages(apt, packages)
|
const needToInstall = await filterAndQualifyAptPackages(packages, apt)
|
||||||
|
|
||||||
if (needToInstall.length === 0) {
|
if (needToInstall.length === 0) {
|
||||||
info("All packages are already installed")
|
info("All packages are already installed")
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { warning } from "ci-log"
|
||||||
import escapeRegex from "escape-string-regexp"
|
import escapeRegex from "escape-string-regexp"
|
||||||
import { execa } from "execa"
|
import { execa } from "execa"
|
||||||
import { getAptEnv } from "./apt-env.js"
|
import { getAptEnv } from "./apt-env.js"
|
||||||
|
import { getApt } from "./get-apt.js"
|
||||||
import type { AptPackage } from "./install.js"
|
import type { AptPackage } from "./install.js"
|
||||||
import { isAptPackInstalled } from "./is-installed.js"
|
import { isAptPackInstalled } from "./is-installed.js"
|
||||||
import { updateAptReposMemoized, updatedRepos } from "./update.js"
|
import { updateAptReposMemoized, updatedRepos } from "./update.js"
|
||||||
|
@ -19,15 +20,20 @@ export enum AptPackageType {
|
||||||
/**
|
/**
|
||||||
* Filter out the packages that are already installed and qualify the packages into a full package name/version
|
* Filter out the packages that are already installed and qualify the packages into a full package name/version
|
||||||
*/
|
*/
|
||||||
export async function filterAndQualifyAptPackages(apt: string, packages: AptPackage[]) {
|
export async function filterAndQualifyAptPackages(packages: AptPackage[], apt: string = getApt()) {
|
||||||
return (await Promise.all(packages.map((pack) => qualifiedNeededAptPackage(apt, pack))))
|
return (await Promise.all(packages.map((pack) => qualifiedNeededAptPackage(pack, apt))))
|
||||||
.filter((pack) => pack !== undefined)
|
.filter((pack) => pack !== undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function qualifiedNeededAptPackage(apt: string, pack: AptPackage) {
|
/**
|
||||||
// Qualify the packages into full package name/version
|
* Qualify the package into full package name/version.
|
||||||
|
* If the package is not installed, return the full package name/version.
|
||||||
|
* If the package is already installed, return undefined
|
||||||
|
*/
|
||||||
|
export async function qualifiedNeededAptPackage(pack: AptPackage, apt: string = getApt()) {
|
||||||
|
// Qualify the package into full package name/version
|
||||||
const qualified = await getAptArg(apt, pack.name, pack.version)
|
const qualified = await getAptArg(apt, pack.name, pack.version)
|
||||||
// filter out the packages that are already installed
|
// filter out the package that are already installed
|
||||||
return (await isAptPackInstalled(qualified)) ? undefined : qualified
|
return (await isAptPackInstalled(qualified)) ? undefined : qualified
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
import { tmpdir } from "os"
|
||||||
import { execRootSync } from "admina"
|
import { execRootSync } from "admina"
|
||||||
import { dirname } from "patha"
|
import { readFile, writeFile } from "fs/promises"
|
||||||
import { addAptKeyViaURL, hasNala, installAptPack } from "setup-apt"
|
import { DownloaderHelper } from "node-downloader-helper"
|
||||||
|
import { dirname, join } from "patha"
|
||||||
|
import { hasNala, installAptPack, qualifiedNeededAptPackage } from "setup-apt"
|
||||||
import which from "which"
|
import which from "which"
|
||||||
import { isUbuntu } from "../utils/env/isUbuntu.js"
|
import { isUbuntu } from "../utils/env/isUbuntu.js"
|
||||||
|
|
||||||
|
@ -23,31 +26,49 @@ export async function setupNala(version: string, _setupDir: string, _arch: strin
|
||||||
|
|
||||||
await installAptPack([{ name: "python3-apt" }])
|
await installAptPack([{ name: "python3-apt" }])
|
||||||
|
|
||||||
// https://gitlab.com/volian/nala/-/wikis/Installation
|
|
||||||
const keyFileName = await addAptKeyViaURL({
|
|
||||||
fileName: "volian-archive-nala.gpg",
|
|
||||||
keyUrl: "https://deb.volian.org/volian/nala.key",
|
|
||||||
})
|
|
||||||
execRootSync("/bin/bash", [
|
|
||||||
"-c",
|
|
||||||
`echo "deb [signed-by=${keyFileName}] http://deb.volian.org/volian/ nala main" | tee /etc/apt/sources.list.d/volian-archive-nala.list`,
|
|
||||||
])
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (version !== "legacy") {
|
|
||||||
await installAptPack([{ name: "nala" }], true)
|
|
||||||
} else {
|
|
||||||
await installAptPack([{ name: "nala-legacy" }], true)
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
await installAptPack([{ name: "nala-legacy" }], true)
|
|
||||||
}
|
|
||||||
|
|
||||||
binDir = "/usr/bin" // eslint-disable-line require-atomic-updates
|
binDir = "/usr/bin" // eslint-disable-line require-atomic-updates
|
||||||
|
|
||||||
|
// If nala is available in the default repositories, install it
|
||||||
|
const nalaPack = await qualifiedNeededAptPackage({ name: "nala", version })
|
||||||
|
if (nalaPack !== undefined) {
|
||||||
|
await installAptPack([{ name: nalaPack }])
|
||||||
return { binDir }
|
return { binDir }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Nala is not available in the default repositories
|
||||||
|
// Check if the legacy version is available
|
||||||
|
const nalaLegacyPack = await qualifiedNeededAptPackage({ name: "nala-legacy" })
|
||||||
|
if (nalaLegacyPack !== undefined) {
|
||||||
|
await installAptPack([{ name: nalaLegacyPack }], true)
|
||||||
|
return { binDir }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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, ""))
|
||||||
|
|
||||||
|
execRootSync("bash", [installerPath])
|
||||||
|
}
|
||||||
|
|
||||||
export function bashWithNala(script: string) {
|
export function bashWithNala(script: string) {
|
||||||
if (hasNala()) {
|
if (hasNala()) {
|
||||||
return `apt-get() { nala $@; }; export -f apt-get; ${script}; unset -f apt-get`
|
return `apt-get() { nala $@; }; export -f apt-get; ${script}; unset -f apt-get`
|
||||||
|
|
Loading…
Reference in New Issue