fix: avoid needing rcFile for nala lang settings

This commit is contained in:
Amin Yahyaabadi 2024-08-15 17:40:00 -07:00
parent efbc01e1b5
commit 429d0724fa
No known key found for this signature in database
GPG Key ID: F52AF77F636088F0
18 changed files with 143 additions and 130 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

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

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

@ -119,7 +119,7 @@
"time-delta": "github:aminya/time-delta#69d91a41cef28e569be9a2991129f5f7d1f0d00e", "time-delta": "github:aminya/time-delta#69d91a41cef28e569be9a2991129f5f7d1f0d00e",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"ts-readme": "^1.1.3", "ts-readme": "^1.1.3",
"turbo": "2.0.5", "turbo": "2.0.14",
"typescript": "^5.5.4", "typescript": "^5.5.4",
"ubuntu-version": "^2.0.0", "ubuntu-version": "^2.0.0",
"untildify-user": "workspace:*", "untildify-user": "workspace:*",

View File

@ -195,8 +195,8 @@ importers:
specifier: ^1.1.3 specifier: ^1.1.3
version: 1.1.3(typescript@5.5.4) version: 1.1.3(typescript@5.5.4)
turbo: turbo:
specifier: 2.0.5 specifier: 2.0.14
version: 2.0.5 version: 2.0.14
typescript: typescript:
specifier: ^5.5.4 specifier: ^5.5.4
version: 5.5.4 version: 5.5.4
@ -4965,38 +4965,38 @@ packages:
resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==}
engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'}
turbo-darwin-64@2.0.5: turbo-darwin-64@2.0.14:
resolution: {integrity: sha512-t/9XpWYIjOhIHUdwiR47SYBGYHkR1zWLxTkTNKZwCSn8BN0cfjPZ1BR6kcwYGxLGBhtl5GBf6A29nq2K7iwAjg==} resolution: {integrity: sha512-kwfDmjNwlNfvtrvT29+ZBg5n1Wvxl891bFHchMJyzMoR0HOE9N1NSNdSZb9wG3e7sYNIu4uDkNk+VBEqJW0HzQ==}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
turbo-darwin-arm64@2.0.5: turbo-darwin-arm64@2.0.14:
resolution: {integrity: sha512-//5y4RJvnal8CttOLBwlaBqblcQb1qTlIxLN+I8O3E3rPuvHOupNKB9ZJxYIQ8oWf8ns8Ec8cxQ0GSBLTJIMtA==} resolution: {integrity: sha512-m3LXYEshCx3wc4ZClM6gb01KYpFmtjQ9IBF3A7ofjb6ahux3xlYZJZ3uFCLAGHuvGLuJ3htfiPbwlDPTdknqqw==}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
turbo-linux-64@2.0.5: turbo-linux-64@2.0.14:
resolution: {integrity: sha512-LDtEDU2Gm8p3lKu//aHXZFRKUCVu68BNF9LQ+HmiCKFpNyK7khpMTxIAAUhDqt+AzlrbxtrxcCpCJaWg1JDjHg==} resolution: {integrity: sha512-7vBzCPdoTtR92SNn2JMgj1FlMmyonGmpMaQdgAB1OVYtuQ6NVGoh7/lODfaILqXjpvmFSVbpBIDrKOT6EvcprQ==}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
turbo-linux-arm64@2.0.5: turbo-linux-arm64@2.0.14:
resolution: {integrity: sha512-84wdrzntErBNxkHcwHxiTZdaginQAxGPnwLTyZj8lpUYI7okPoxy3jKpUeMHN3adm3iDedl/x0mYSIvVVkmOiA==} resolution: {integrity: sha512-jwH+c0bfjpBf26K/tdEFatmnYyXwGROjbr6bZmNcL8R+IkGAc/cglL+OToqJnQZTgZvH7uDGbeSyUo7IsHyjuA==}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
turbo-windows-64@2.0.5: turbo-windows-64@2.0.14:
resolution: {integrity: sha512-SgaFZ0VW6kHCJogLNuLEleAauAJx2Y48wazZGVRmBpgSUS2AylXesaBMhJaEScYqLz7mIRn6KOgwM8D4wTxI9g==} resolution: {integrity: sha512-w9/XwkHSzvLjmioo6cl3S1yRfI6swxsV1j1eJwtl66JM4/pn0H2rBa855R0n7hZnmI6H5ywLt/nLt6Ae8RTDmw==}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
turbo-windows-arm64@2.0.5: turbo-windows-arm64@2.0.14:
resolution: {integrity: sha512-foUxLOZoru0IRNIxm53fkfM4ubas9P0nTFjIcHtd+E8YHeogt8GqTweNre2e6ri1EHDo71emmuQgpuoFCOXZMg==} resolution: {integrity: sha512-XaQlyYk+Rf4xS5XWCo8XCMIpssgGGy8blzLfolN6YBp4baElIWMlkLZHDbGyiFmCbNf9I9gJI64XGRG+LVyyjA==}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
turbo@2.0.5: turbo@2.0.14:
resolution: {integrity: sha512-+6+hcWr4nwuESlKqUc626HMOTd3QT8hUOc9QM45PP1d4nErGkNOgExm4Pcov3in7LTuadMnB0gcd/BuzkEDIPw==} resolution: {integrity: sha512-00JjdCMD/cpsjP0Izkjcm8Oaor5yUCfDwODtaLb+WyblyadkaDEisGhy3Dbd5az9n+5iLSPiUgf+WjPbns6MRg==}
hasBin: true hasBin: true
type-check@0.4.0: type-check@0.4.0:
@ -8618,7 +8618,7 @@ snapshots:
doctrine: 2.1.0 doctrine: 2.1.0
eslint: 8.57.0 eslint: 8.57.0
has: 1.0.4 has: 1.0.4
jsx-ast-utils: 3.3.5 jsx-ast-utils: 2.4.1
minimatch: 3.1.2 minimatch: 3.1.2
object.entries: 1.1.8 object.entries: 1.1.8
object.fromentries: 2.0.8 object.fromentries: 2.0.8
@ -11174,32 +11174,32 @@ snapshots:
tunnel@0.0.6: {} tunnel@0.0.6: {}
turbo-darwin-64@2.0.5: turbo-darwin-64@2.0.14:
optional: true optional: true
turbo-darwin-arm64@2.0.5: turbo-darwin-arm64@2.0.14:
optional: true optional: true
turbo-linux-64@2.0.5: turbo-linux-64@2.0.14:
optional: true optional: true
turbo-linux-arm64@2.0.5: turbo-linux-arm64@2.0.14:
optional: true optional: true
turbo-windows-64@2.0.5: turbo-windows-64@2.0.14:
optional: true optional: true
turbo-windows-arm64@2.0.5: turbo-windows-arm64@2.0.14:
optional: true optional: true
turbo@2.0.5: turbo@2.0.14:
optionalDependencies: optionalDependencies:
turbo-darwin-64: 2.0.5 turbo-darwin-64: 2.0.14
turbo-darwin-arm64: 2.0.5 turbo-darwin-arm64: 2.0.14
turbo-linux-64: 2.0.5 turbo-linux-64: 2.0.14
turbo-linux-arm64: 2.0.5 turbo-linux-arm64: 2.0.14
turbo-windows-64: 2.0.5 turbo-windows-64: 2.0.14
turbo-windows-arm64: 2.0.5 turbo-windows-arm64: 2.0.14
type-check@0.4.0: type-check@0.4.0:
dependencies: dependencies:

View File

@ -1,10 +1,11 @@
import { execRoot, execRootSync } from "admina" import { defaultExecOptions, execRoot, execRootSync } from "admina"
import { GITHUB_ACTIONS } from "ci-info" import { GITHUB_ACTIONS } from "ci-info"
import { info, warning } from "ci-log" import { info, warning } from "ci-log"
import escapeRegex from "escape-string-regexp" import escapeRegex from "escape-string-regexp"
import { type ExecaError, execa } from "execa" import { type ExecaError, execa } from "execa"
import { appendFile } from "fs/promises" import { appendFile } from "fs/promises"
import { addEnv, sourceRC } from "os-env" import memoize from "micro-memoize"
import { sourceRC } from "os-env"
import { pathExists } from "path-exists" import { pathExists } from "path-exists"
import which from "which" import which from "which"
import { rcOptions } from "../../cli-options.js" import { rcOptions } from "../../cli-options.js"
@ -37,8 +38,6 @@ export async function setupAptPack(packages: AptPackage[], update = false): Prom
info(`Installing ${name} ${version ?? ""} via ${apt}`) info(`Installing ${name} ${version ?? ""} via ${apt}`)
} }
process.env.DEBIAN_FRONTEND = "noninteractive"
// Update the repos if needed // Update the repos if needed
if (update) { if (update) {
updateRepos(apt) updateRepos(apt)
@ -63,13 +62,13 @@ export async function setupAptPack(packages: AptPackage[], update = false): Prom
// Install // Install
try { try {
execRootSync(apt, ["install", "--fix-broken", "-y", ...needToInstall]) execRootSync(apt, ["install", "--fix-broken", "-y", ...needToInstall], getAptExecOptions(apt))
} catch (err) { } catch (err) {
if ("stderr" in (err as ExecaError)) { if ("stderr" in (err as ExecaError)) {
const stderr = (err as ExecaError).stderr const stderr = (err as ExecaError).stderr
if (retryErrors.some((error) => stderr.includes(error))) { if (retryErrors.some((error) => stderr.includes(error))) {
warning(`Failed to install packages ${needToInstall}. Retrying...`) warning(`Failed to install packages ${needToInstall}. Retrying...`)
execRootSync(apt, ["install", "--fix-broken", "-y", "-o", aptTimeout, ...needToInstall]) execRootSync(apt, ["install", "--fix-broken", "-y", "-o", aptTimeout, ...needToInstall], getAptExecOptions(apt))
} }
} else { } else {
throw err throw err
@ -79,6 +78,42 @@ export async function setupAptPack(packages: AptPackage[], update = false): Prom
return { binDir: "/usr/bin/" } return { binDir: "/usr/bin/" }
} }
export function hasNala() {
return which.sync("nala", { nothrow: true }) !== null
}
export function getApt() {
let apt: string
if (hasNala()) {
apt = "nala"
} else {
apt = "apt-get"
}
return apt
}
function getEnv(apt: string) {
const env: NodeJS.ProcessEnv = { ...process.env, DEBIAN_FRONTEND: "noninteractive" }
if (apt === "nala") {
// if LANG/LC_ALL is not set, enable utf8 otherwise nala fails because of ASCII encoding
if (env.LANG === undefined) {
env.LANG = "C.UTF-8"
}
if (env.LC_ALL === undefined) {
env.LC_ALL = "C.UTF-8"
}
}
return env
}
function getAptExecOptionsRaw(apt: string = "apt-get") {
return { env: getEnv(apt), ...defaultExecOptions }
}
const getAptExecOptions = memoize(getAptExecOptionsRaw)
export enum AptPackageType { export enum AptPackageType {
NameDashVersion = 0, NameDashVersion = 0,
NameEqualsVersion = 1, NameEqualsVersion = 1,
@ -111,7 +146,7 @@ async function addRepositories(apt: string, packages: AptPackage[]) {
await installAddAptRepo(apt) await installAddAptRepo(apt)
for (const repo of allRepositories) { for (const repo of allRepositories) {
// eslint-disable-next-line no-await-in-loop // eslint-disable-next-line no-await-in-loop
execRootSync("add-apt-repository", ["-y", "--no-update", repo]) execRootSync("add-apt-repository", ["-y", "--no-update", repo], getAptExecOptions())
} }
updateRepos(apt) updateRepos(apt)
didUpdate = true didUpdate = true
@ -124,7 +159,7 @@ export async function aptPackageType(name: string, version: string | undefined):
"search", "search",
"--names-only", "--names-only",
`^${escapeRegex(name)}-${escapeRegex(version)}$`, `^${escapeRegex(name)}-${escapeRegex(version)}$`,
]) ], getAptExecOptions())
if (stdout.trim() !== "") { if (stdout.trim() !== "") {
return AptPackageType.NameDashVersion return AptPackageType.NameDashVersion
} }
@ -132,7 +167,7 @@ export async function aptPackageType(name: string, version: string | undefined):
try { try {
// check if apt-get show can find the version // check if apt-get show can find the version
// eslint-disable-next-line @typescript-eslint/no-shadow // eslint-disable-next-line @typescript-eslint/no-shadow
const { stdout } = await execa("apt-cache", ["show", `${name}=${version}`]) const { stdout } = await execa("apt-cache", ["show", `${name}=${version}`], getAptExecOptions())
if (stdout.trim() === "") { if (stdout.trim() === "") {
return AptPackageType.NameEqualsVersion return AptPackageType.NameEqualsVersion
} }
@ -142,7 +177,7 @@ export async function aptPackageType(name: string, version: string | undefined):
} }
try { try {
const { stdout: showStdout } = await execa("apt-cache", ["show", name]) const { stdout: showStdout } = await execa("apt-cache", ["show", name], getAptExecOptions())
if (showStdout.trim() !== "") { if (showStdout.trim() !== "") {
return AptPackageType.Name return AptPackageType.Name
} }
@ -174,29 +209,23 @@ async function getAptArg(name: string, version: string | undefined) {
} }
} }
export function hasNala() {
return which.sync("nala", { nothrow: true }) !== null
}
export function getApt() {
let apt: string
if (hasNala()) {
apt = "nala"
} else {
apt = "apt-get"
}
return apt
}
function updateRepos(apt: string) { function updateRepos(apt: string) {
execRootSync(apt, apt !== "nala" ? ["update", "-y", "-o", aptTimeout] : ["update", "-o", aptTimeout]) execRootSync(
apt,
apt !== "nala" ? ["update", "-y", "-o", aptTimeout] : ["update", "-o", aptTimeout],
getAptExecOptions(apt),
)
} }
async function installAddAptRepo(apt: string) { async function installAddAptRepo(apt: string) {
if (await isPackageInstalled("software-properties-common")) { if (await isPackageInstalled("software-properties-common")) {
return return
} }
execRootSync(apt, ["install", "-y", "--fix-broken", "-o", aptTimeout, "software-properties-common"]) execRootSync(
apt,
["install", "-y", "--fix-broken", "-o", aptTimeout, "software-properties-common"],
getAptExecOptions(apt),
)
} }
/** Install gnupg and certificates (usually missing from docker containers) */ /** Install gnupg and certificates (usually missing from docker containers) */
@ -214,20 +243,13 @@ async function initApt(apt: string) {
]) ])
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], getAptExecOptions(apt))
} }
const promises: Promise<string | void>[] = [ const promises: Promise<string | void>[] = [
addAptKeyViaServer(["3B4FE6ACC0B21F32", "40976EAF437D05B5"], "setup-cpp-ubuntu-archive.gpg"), addAptKeyViaServer(["3B4FE6ACC0B21F32", "40976EAF437D05B5"], "setup-cpp-ubuntu-archive.gpg"),
addAptKeyViaServer(["1E9377A2BA9EF27F"], "launchpad-toolchain.gpg"), addAptKeyViaServer(["1E9377A2BA9EF27F"], "launchpad-toolchain.gpg"),
] ]
if (apt === "nala") {
// If LANGE/LC_ALL is not set, enable utf8 otherwise nala fails because of ASCII encoding
promises.push(
addEnv("LANG", "C.UTF-8", { overwrite: false, ...rcOptions }),
addEnv("LC_ALL", "C.UTF-8", { overwrite: false, ...rcOptions }),
)
}
await Promise.all(promises) await Promise.all(promises)
} }
@ -290,7 +312,7 @@ export async function updateAptAlternatives(name: string, path: string, rcPath:
export async function isPackageInstalled(pack: string) { export async function isPackageInstalled(pack: string) {
try { try {
// check if a package is installed // check if a package is installed
const { stdout } = await execa("dpkg", ["-s", pack]) const { stdout } = await execa("dpkg", ["-s", pack], getAptExecOptions())
if (typeof stdout !== "string") { if (typeof stdout !== "string") {
return false return false
} }
@ -305,7 +327,7 @@ export async function isPackageInstalled(pack: string) {
export async function isPackageRegexInstalled(regexp: string) { export async function isPackageRegexInstalled(regexp: string) {
try { try {
// check if a package matching the regexp is installed // check if a package matching the regexp is installed
const { stdout } = await execa("dpkg", ["-l", regexp]) const { stdout } = await execa("dpkg", ["-l", regexp], getAptExecOptions())
if (typeof stdout !== "string") { if (typeof stdout !== "string") {
return false return false
} }