fix: memoize apt update/init via micromemoize

This commit is contained in:
Amin Yahyaabadi 2024-08-28 15:29:31 -07:00
parent 0dbc7a0d00
commit 9a295dea76
No known key found for this signature in database
GPG Key ID: F52AF77F636088F0
13 changed files with 121 additions and 109 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

@ -26,7 +26,8 @@
"which": "4.0.0", "which": "4.0.0",
"execa": "^7.2.0", "execa": "^7.2.0",
"escape-string-regexp": "^5.0.0", "escape-string-regexp": "^5.0.0",
"node-downloader-helper": "2.1.9" "node-downloader-helper": "2.1.9",
"micro-memoize": "^4.1.2"
}, },
"engines": { "engines": {
"node": ">=12" "node": ">=12"

View File

@ -2,13 +2,19 @@ import { defaultExecOptions, execRootSync } from "admina"
import { getAptEnv } from "./apt-env.js" import { getAptEnv } from "./apt-env.js"
import { aptTimeout } from "./apt-timeout.js" import { aptTimeout } from "./apt-timeout.js"
import { getApt } from "./get-apt.js" import { getApt } from "./get-apt.js"
import { initAptMemoized } from "./init-apt.js"
import { isAptPackInstalled } from "./is-installed.js" import { isAptPackInstalled } from "./is-installed.js"
import { updateAptRepos } from "./update.js" import { updateAptReposMemoized } from "./update.js"
export async function addAptRepository(repo: string, apt = getApt()) { export async function addAptRepository(repo: string, apt = getApt()) {
await initAptMemoized(apt)
await installAddAptRepo(apt) await installAddAptRepo(apt)
execRootSync("add-apt-repository", ["-y", "--no-update", repo], { ...defaultExecOptions, env: getAptEnv(apt) }) execRootSync("add-apt-repository", ["-y", "--no-update", repo], { ...defaultExecOptions, env: getAptEnv(apt) })
updateAptRepos(apt)
// clear the cache
updateAptReposMemoized.cache.keys = []
updateAptReposMemoized.cache.values = []
updateAptReposMemoized(apt)
} }
export async function installAddAptRepo(apt: string) { export async function installAddAptRepo(apt: string) {

View File

@ -1,13 +1,14 @@
import { defaultExecOptions, execRootSync } from "admina" import { defaultExecOptions, execRootSync } from "admina"
import memoize from "micro-memoize"
import { getAptEnv } from "./apt-env.js" import { getAptEnv } from "./apt-env.js"
import { aptTimeout } from "./apt-timeout.js" import { aptTimeout } from "./apt-timeout.js"
import { filterAndQualifyAptPackages } from "./qualify-install.js" import { filterAndQualifyAptPackages } from "./qualify-install.js"
import { updateAptRepos } from "./update.js" import { updateAptReposMemoized } from "./update.js"
/** Install gnupg and certificates (usually missing from docker containers) */ /** Install gnupg and certificates (usually missing from docker containers) */
export async function initApt(apt: string) { export async function initApt(apt: string) {
// Update the repos // Update the repos
updateAptRepos(apt) updateAptReposMemoized(apt)
const toInstall = await filterAndQualifyAptPackages(apt, [ const toInstall = await filterAndQualifyAptPackages(apt, [
{ name: "ca-certificates" }, { name: "ca-certificates" },
@ -22,3 +23,6 @@ export async function initApt(apt: string) {
}) })
} }
} }
/** Install gnupg and certificates (usually missing from docker containers) (memoized) */
export const initAptMemoized = memoize(initApt, { isPromise: true })

View File

@ -6,9 +6,9 @@ import { type AddAptKeyOptions, addAptKey } from "./apt-key.js"
import { addAptRepository } from "./apt-repository.js" import { addAptRepository } from "./apt-repository.js"
import { aptTimeout } from "./apt-timeout.js" import { aptTimeout } from "./apt-timeout.js"
import { getApt } from "./get-apt.js" import { getApt } from "./get-apt.js"
import { initApt } from "./init-apt.js" import { initAptMemoized } from "./init-apt.js"
import { filterAndQualifyAptPackages } from "./qualify-install.js" import { filterAndQualifyAptPackages } from "./qualify-install.js"
import { updateAptRepos } from "./update.js" import { updateAptReposMemoized } from "./update.js"
/** /**
* The information about an installation result * The information about an installation result
@ -22,10 +22,6 @@ export type InstallationInfo = {
bin?: string bin?: string
} }
/* eslint-disable require-atomic-updates */
export let didUpdate: boolean = false
let didInit: boolean = false
/** /**
* The information about an apt package * The information about an apt package
*/ */
@ -80,8 +76,7 @@ export async function installAptPack(packages: AptPackage[], update = false): Pr
// Update the repos if needed // Update the repos if needed
if (update) { if (update) {
updateAptRepos(apt) updateAptReposMemoized(apt)
didUpdate = true
} }
// Add the repos if needed // Add the repos if needed
@ -95,10 +90,7 @@ export async function installAptPack(packages: AptPackage[], update = false): Pr
} }
// Initialize apt if needed // Initialize apt if needed
if (!didInit) { await initAptMemoized(apt)
await initApt(apt)
didInit = true
}
try { try {
// Add the keys if needed // Add the keys if needed

View File

@ -2,10 +2,9 @@ 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, didUpdate } from "./install.js"
import { isAptPackInstalled } from "./is-installed.js" import { isAptPackInstalled } from "./is-installed.js"
import { updateAptRepos } from "./update.js" import { updateAptReposMemoized } from "./update.js"
/** /**
* The type of apt package to install * The type of apt package to install
@ -65,8 +64,8 @@ async function aptPackageType(apt: string, name: string, version: string | undef
} }
// If apt-cache fails, update the repos and try again // If apt-cache fails, update the repos and try again
if (!didUpdate) { if (!updateAptReposMemoized.cache.keys.includes([apt])) {
updateAptRepos(getApt()) updateAptReposMemoized(apt)
return aptPackageType(apt, name, version) return aptPackageType(apt, name, version)
} }

View File

@ -1,4 +1,5 @@
import { defaultExecOptions, execRootSync } from "admina" import { defaultExecOptions, execRootSync } from "admina"
import memoize from "micro-memoize"
import { getAptEnv } from "./apt-env.js" import { getAptEnv } from "./apt-env.js"
import { aptTimeout } from "./apt-timeout.js" import { aptTimeout } from "./apt-timeout.js"
import { getApt } from "./get-apt.js" import { getApt } from "./get-apt.js"
@ -14,3 +15,9 @@ export function updateAptRepos(apt: string = getApt()) {
{ ...defaultExecOptions, env: getAptEnv(apt) }, { ...defaultExecOptions, env: getAptEnv(apt) },
) )
} }
/**
* Update the apt repositories (memoized)
* @param apt The apt command to use (optional)
*/
export const updateAptReposMemoized = memoize(updateAptRepos)

View File

@ -312,6 +312,9 @@ importers:
execa: execa:
specifier: ^7.2.0 specifier: ^7.2.0
version: 7.2.0 version: 7.2.0
micro-memoize:
specifier: ^4.1.2
version: 4.1.2
node-downloader-helper: node-downloader-helper:
specifier: 2.1.9 specifier: 2.1.9
version: 2.1.9 version: 2.1.9