mirror of https://github.com/aminya/setup-cpp
feat: skip installation of pip/pipx packages if already installed
This commit is contained in:
parent
67a1d8d27d
commit
99db11072d
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
|
@ -56,12 +56,20 @@ async function setupPipx(foundPython: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await execa(foundPython, ["-m", "pipx", "ensurepath"], { stdio: "inherit" })
|
await execa(foundPython, ["-m", "pipx", "ensurepath"], { stdio: "inherit" })
|
||||||
await setupPipPackWithPython(foundPython, "venv", undefined, { upgrade: false, usePipx: false })
|
await setupVenv(foundPython)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
warning(`Failed to install pipx: ${(err as Error).toString()}. Ignoring...`)
|
warning(`Failed to install pipx: ${(err as Error).toString()}. Ignoring...`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function setupVenv(foundPython: string) {
|
||||||
|
try {
|
||||||
|
await setupPipPackWithPython(foundPython, "venv", undefined, { upgrade: false, usePipx: false })
|
||||||
|
} catch (err) {
|
||||||
|
warning(`Failed to install venv: ${(err as Error).toString()}. Ignoring...`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Setup wheel and setuptools */
|
/** Setup wheel and setuptools */
|
||||||
async function setupWheel(foundPython: string) {
|
async function setupWheel(foundPython: string) {
|
||||||
try {
|
try {
|
||||||
|
@ -70,9 +78,9 @@ async function setupWheel(foundPython: string) {
|
||||||
isLibrary: true,
|
isLibrary: true,
|
||||||
usePipx: false,
|
usePipx: false,
|
||||||
})
|
})
|
||||||
await setupPipPackWithPython(foundPython, "wheel", undefined, { upgrade: true, isLibrary: true, usePipx: false })
|
await setupPipPackWithPython(foundPython, "wheel", undefined, { upgrade: false, isLibrary: true, usePipx: false })
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
warning(`Failed to install setuptools or wheel: ${(err as Error).toString()}. Ignoring...`)
|
warning(`Failed to install setuptools/wheel: ${(err as Error).toString()}. Ignoring...`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,16 @@ export async function setupPipPackWithPython(
|
||||||
const isPipx = usePipx && !isLibrary && (await hasPipx(givenPython))
|
const isPipx = usePipx && !isLibrary && (await hasPipx(givenPython))
|
||||||
const pip = isPipx ? "pipx" : "pip"
|
const pip = isPipx ? "pipx" : "pip"
|
||||||
|
|
||||||
const hasPackage = await pipHasPackage(givenPython, name)
|
// if upgrade is not requested, check if the package is already installed, and return if it is
|
||||||
|
if (!upgrade) {
|
||||||
|
const installed = await pipPackageIsInstalled(givenPython, pip, name)
|
||||||
|
if (installed) {
|
||||||
|
const binDir = await finishPipPackageInstall(givenPython, name)
|
||||||
|
return { binDir }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasPackage = await pipHasPackage(givenPython, pip, name)
|
||||||
if (hasPackage) {
|
if (hasPackage) {
|
||||||
try {
|
try {
|
||||||
info(`Installing ${name} ${version ?? ""} via ${pip}`)
|
info(`Installing ${name} ${version ?? ""} via ${pip}`)
|
||||||
|
@ -79,20 +88,21 @@ export async function setupPipPackWithPython(
|
||||||
throw new Error(`Failed to install ${name} via ${pip}: ${err}.`)
|
throw new Error(`Failed to install ${name} via ${pip}: ${err}.`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if ((await setupPipPackSystem(name)) === null) {
|
||||||
if ((await setupPipPackSystem(name)) === null) {
|
|
||||||
throw new Error(`Failed to install ${name} as it was not found via ${pip} or the system package manager`)
|
throw new Error(`Failed to install ${name} as it was not found via ${pip} or the system package manager`)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const execPaths = await addPythonBaseExecPrefix(givenPython)
|
|
||||||
const binDir = await findBinDir(execPaths, name)
|
|
||||||
|
|
||||||
await addPath(binDir, rcOptions)
|
|
||||||
|
|
||||||
|
const binDir = await finishPipPackageInstall(givenPython, name)
|
||||||
return { binDir }
|
return { binDir }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function finishPipPackageInstall(givenPython: string, name: string) {
|
||||||
|
const pythonBaseExecPrefix = await addPythonBaseExecPrefix(givenPython)
|
||||||
|
const binDir = await findBinDir(pythonBaseExecPrefix, name)
|
||||||
|
await addPath(binDir, rcOptions)
|
||||||
|
return binDir
|
||||||
|
}
|
||||||
|
|
||||||
export async function hasPipx(givenPython: string) {
|
export async function hasPipx(givenPython: string) {
|
||||||
return (await execa(givenPython, ["-m", "pipx", "--help"], { stdio: "ignore", reject: false })).exitCode === 0
|
return (await execa(givenPython, ["-m", "pipx", "--help"], { stdio: "ignore", reject: false })).exitCode === 0
|
||||||
}
|
}
|
||||||
|
@ -153,8 +163,54 @@ async function getPython_(): Promise<string> {
|
||||||
}
|
}
|
||||||
const getPython = memoize(getPython_, { promise: true })
|
const getPython = memoize(getPython_, { promise: true })
|
||||||
|
|
||||||
async function pipHasPackage(python: string, name: string) {
|
type PipxShowType = {
|
||||||
const result = await execa(python, ["-m", "pip", "-qq", "index", "versions", name], {
|
venvs: Record<string, {
|
||||||
|
metadata: {
|
||||||
|
main_package: {
|
||||||
|
package: string
|
||||||
|
package_or_url: string
|
||||||
|
apps: string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
|
||||||
|
async function pipPackageIsInstalled(python: string, pip: string, name: string) {
|
||||||
|
try {
|
||||||
|
if (pip === "pipx") {
|
||||||
|
const result = await execa(python, ["-m", pip, "list", "--json"], {
|
||||||
|
stdio: "ignore",
|
||||||
|
reject: false,
|
||||||
|
})
|
||||||
|
if (result.exitCode !== 0 || typeof result.stdout !== "string") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const pipxOut = JSON.parse(result.stdout as unknown as string) as PipxShowType
|
||||||
|
// search among the venvs
|
||||||
|
if (name in pipxOut.venvs) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// search among the urls
|
||||||
|
for (const venv of Object.values(pipxOut.venvs)) {
|
||||||
|
if (venv.metadata.main_package.package_or_url === name || venv.metadata.main_package.package === name) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await execa(python, ["-m", pip, "-qq", "show", name], {
|
||||||
|
stdio: "ignore",
|
||||||
|
reject: false,
|
||||||
|
})
|
||||||
|
return result.exitCode === 0
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function pipHasPackage(python: string, pip: string, name: string) {
|
||||||
|
const result = await execa(python, ["-m", pip, "-qq", "index", "versions", name], {
|
||||||
stdio: "ignore",
|
stdio: "ignore",
|
||||||
reject: false,
|
reject: false,
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue