fix: fix checking of a pip package existence

This commit is contained in:
Amin Yahyaabadi 2024-09-18 16:27:12 -07:00
parent d316735ce5
commit 4ebcbc18f2
No known key found for this signature in database
GPG Key ID: F52AF77F636088F0
6 changed files with 93 additions and 80 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

View File

@ -68,6 +68,7 @@ const retryErrors = [
* ``` * ```
*/ */
export async function installAptPack(packages: AptPackage[], update = false): Promise<InstallationInfo> { export async function installAptPack(packages: AptPackage[], update = false): Promise<InstallationInfo> {
try {
const apt: string = getApt() const apt: string = getApt()
for (const { name, version } of packages) { for (const { name, version } of packages) {
@ -117,6 +118,10 @@ export async function installAptPack(packages: AptPackage[], update = false): Pr
} }
return { binDir: "/usr/bin/" } return { binDir: "/usr/bin/" }
} catch (err) {
const msg = err instanceof Error ? `${err.message}\n${err.stack}` : String(err)
throw new Error(`Failed to install apt packages: ${msg}`)
}
} }
async function addRepositories(apt: string, packages: AptPackage[]) { async function addRepositories(apt: string, packages: AptPackage[]) {

View File

@ -55,14 +55,16 @@ export async function setupPipPackWithPython(
// if upgrade is not requested, check if the package is already installed, and return if it is // if upgrade is not requested, check if the package is already installed, and return if it is
if (!upgrade) { if (!upgrade) {
const installed = await pipPackageIsInstalled(givenPython, pip, name) const installed = isPipx
? await pipxPackageInstalled(givenPython, name)
: await pipPackageIsInstalled(givenPython, name)
if (installed) { if (installed) {
const binDir = await finishPipPackageInstall(givenPython, name) const binDir = await finishPipPackageInstall(givenPython, name)
return { binDir } return { binDir }
} }
} }
const hasPackage = await pipHasPackage(givenPython, pip, name) const hasPackage = await pipHasPackage(givenPython, name)
if (hasPackage) { if (hasPackage) {
try { try {
info(`Installing ${name} ${version ?? ""} via ${pip}`) info(`Installing ${name} ${version ?? ""} via ${pip}`)
@ -84,7 +86,8 @@ export async function setupPipPackWithPython(
env, env,
}) })
} catch (err) { } catch (err) {
info(`Failed to install ${name} via ${pip}: ${err}.`) const msg = err instanceof Error ? `${err.message}\n${err.stack}` : String(err)
info(`Failed to install ${name} via ${pip}: ${msg}`)
if ((await setupPipPackSystem(name)) === null) { if ((await setupPipPackSystem(name)) === null) {
throw new Error(`Failed to install ${name} via ${pip}: ${err}.`) throw new Error(`Failed to install ${name} via ${pip}: ${err}.`)
} }
@ -168,6 +171,18 @@ async function getPython(): Promise<string> {
return pythonBin return pythonBin
} }
async function pipPackageIsInstalled(python: string, name: string) {
try {
const result = await execa(python, ["-m", "pip", "-qq", "show", name], {
stdio: "ignore",
reject: false,
})
return result.exitCode === 0
} catch {
return false
}
}
type PipxShowType = { type PipxShowType = {
venvs: Record<string, { venvs: Record<string, {
metadata: { metadata: {
@ -180,10 +195,9 @@ type PipxShowType = {
}> }>
} }
async function pipPackageIsInstalled(python: string, pip: string, name: string) { async function pipxPackageInstalled(python: string, name: string) {
try { try {
if (pip === "pipx") { const result = await execa(python, ["-m", "pipx", "list", "--json"], {
const result = await execa(python, ["-m", pip, "list", "--json"], {
stdio: "ignore", stdio: "ignore",
reject: false, reject: false,
}) })
@ -191,7 +205,7 @@ async function pipPackageIsInstalled(python: string, pip: string, name: string)
return false return false
} }
const pipxOut = JSON.parse(result.stdout as unknown as string) as PipxShowType const pipxOut = JSON.parse(result.stdout) as PipxShowType
// search among the venvs // search among the venvs
if (name in pipxOut.venvs) { if (name in pipxOut.venvs) {
return true return true
@ -202,20 +216,14 @@ async function pipPackageIsInstalled(python: string, pip: string, name: string)
return true return true
} }
} }
}
const result = await execa(python, ["-m", pip, "-qq", "show", name], {
stdio: "ignore",
reject: false,
})
return result.exitCode === 0
} catch { } catch {
return false // ignore
} }
return false
} }
async function pipHasPackage(python: string, pip: string, name: string) { async function pipHasPackage(python: string, name: string) {
const result = await execa(python, ["-m", pip, "-qq", "index", "versions", name], { const result = await execa(python, ["-m", "pip", "-qq", "index", "versions", name], {
stdio: "ignore", stdio: "ignore",
reject: false, reject: false,
}) })