mirror of https://github.com/aminya/setup-cpp.git
fix: detect externally managed pythons
This commit is contained in:
parent
9a2e61232c
commit
1158c50fa0
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
|
|
@ -1,7 +1,6 @@
|
|||
import assert from "assert"
|
||||
import { homedir } from "os"
|
||||
import { dirname, join, parse as pathParse } from "path"
|
||||
import { getExecOutput } from "@actions/exec"
|
||||
import ciInfo from "ci-info"
|
||||
const { GITHUB_ACTIONS } = ciInfo
|
||||
import { endGroup, startGroup } from "@actions/core"
|
||||
|
|
@ -9,7 +8,6 @@ import { info, notice, warning } from "ci-log"
|
|||
import { addPath } from "envosman"
|
||||
import { execa } from "execa"
|
||||
import { readdir } from "fs/promises"
|
||||
import memoize from "memoizee"
|
||||
import { pathExists } from "path-exists"
|
||||
import { addExeExt } from "patha"
|
||||
import { hasApk, installApkPackage } from "setup-alpine"
|
||||
|
|
@ -27,11 +25,11 @@ import { setupPacmanPack } from "../utils/setup/setupPacmanPack.js"
|
|||
import {
|
||||
hasPipxBinary,
|
||||
hasPipxModule,
|
||||
isExternallyManaged,
|
||||
setupPipPackSystem,
|
||||
setupPipPackWithPython,
|
||||
} from "../utils/setup/setupPipPack.js"
|
||||
import { isBinUptoDate } from "../utils/setup/version.js"
|
||||
import { unique } from "../utils/std/index.js"
|
||||
import { getVersionDefault, isMinVersion } from "../versions/versions.js"
|
||||
|
||||
export async function setupPython(
|
||||
|
|
@ -356,6 +354,11 @@ async function setupPip(foundPython: string) {
|
|||
}
|
||||
|
||||
async function ensurePipUpgrade(foundPython: string) {
|
||||
if (await isExternallyManaged(foundPython)) {
|
||||
// let system tools handle pip
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
await execa(foundPython, ["-m", "ensurepip", "-U", "--upgrade"], { stdio: "inherit" })
|
||||
return true
|
||||
|
|
@ -373,29 +376,3 @@ async function ensurePipUpgrade(foundPython: string) {
|
|||
// all methods failed
|
||||
return false
|
||||
}
|
||||
|
||||
async function addPythonBaseExecPrefix_(python: string) {
|
||||
const dirs: string[] = []
|
||||
|
||||
// detection based on the platform
|
||||
if (process.platform === "linux") {
|
||||
dirs.push("/home/runner/.local/bin/")
|
||||
} else if (process.platform === "darwin") {
|
||||
dirs.push("/usr/local/bin/")
|
||||
}
|
||||
|
||||
// detection using python.sys
|
||||
const base_exec_prefix = (await getExecOutput(`${python} -c "import sys;print(sys.base_exec_prefix);"`)).stdout.trim()
|
||||
// any of these are possible depending on the operating system!
|
||||
dirs.push(join(base_exec_prefix, "Scripts"), join(base_exec_prefix, "Scripts", "bin"), join(base_exec_prefix, "bin"))
|
||||
|
||||
// remove duplicates
|
||||
return unique(dirs)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the base exec prefix to the PATH. This is required for Conan, Meson, etc. to work properly.
|
||||
*
|
||||
* The answer is cached for subsequent calls
|
||||
*/
|
||||
export const addPythonBaseExecPrefix = memoize(addPythonBaseExecPrefix_, { promise: true })
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { dirname, join } from "path"
|
||||
import { info } from "@actions/core"
|
||||
import { getExecOutput } from "@actions/exec"
|
||||
import { warning } from "ci-log"
|
||||
import { addPath } from "envosman"
|
||||
import { execa, execaSync } from "execa"
|
||||
import memoize from "memoizee"
|
||||
|
|
@ -12,15 +14,17 @@ import { installBrewPack } from "setup-brew"
|
|||
import { untildifyUser } from "untildify-user"
|
||||
import which from "which"
|
||||
import { rcOptions } from "../../cli-options.js"
|
||||
import { addPythonBaseExecPrefix, setupPython } from "../../python/python.js"
|
||||
import { setupPython } from "../../python/python.js"
|
||||
import { getVersion } from "../../versions/versions.js"
|
||||
import { hasDnf } from "../env/hasDnf.js"
|
||||
import { isArch } from "../env/isArch.js"
|
||||
import { isUbuntu } from "../env/isUbuntu.js"
|
||||
import { ubuntuVersion } from "../env/ubuntu_version.js"
|
||||
import { unique } from "../std/index.js"
|
||||
import type { InstallationInfo } from "./setupBin.js"
|
||||
import { setupDnfPack } from "./setupDnfPack.js"
|
||||
import { setupPacmanPack } from "./setupPacmanPack.js"
|
||||
import { getBinVersion } from "./version.js"
|
||||
|
||||
export type SetupPipPackOptions = {
|
||||
/** Whether to use pipx instead of pip */
|
||||
|
|
@ -301,3 +305,70 @@ export async function setupPipPackSystem(name: string, givenAddPythonPrefix?: bo
|
|||
}
|
||||
return null
|
||||
}
|
||||
|
||||
async function addPythonBaseExecPrefix_(python: string) {
|
||||
const dirs: string[] = []
|
||||
|
||||
// detection based on the platform
|
||||
if (process.platform === "linux") {
|
||||
dirs.push("/home/runner/.local/bin/")
|
||||
} else if (process.platform === "darwin") {
|
||||
dirs.push("/usr/local/bin/")
|
||||
}
|
||||
|
||||
// detection using python.sys
|
||||
const base_exec_prefix = await getPythonBaseExecPrefix(python)
|
||||
// any of these are possible depending on the operating system!
|
||||
dirs.push(join(base_exec_prefix, "Scripts"), join(base_exec_prefix, "Scripts", "bin"), join(base_exec_prefix, "bin"))
|
||||
|
||||
// remove duplicates
|
||||
return unique(dirs)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the base exec prefix to the PATH. This is required for Conan, Meson, etc. to work properly.
|
||||
*
|
||||
* The answer is cached for subsequent calls
|
||||
*/
|
||||
export const addPythonBaseExecPrefix = memoize(addPythonBaseExecPrefix_, { promise: true })
|
||||
|
||||
async function getPythonBaseExecPrefix_(python: string) {
|
||||
return (await getExecOutput(`${python} -c "import sys;print(sys.base_exec_prefix);"`)).stdout.trim()
|
||||
}
|
||||
/**
|
||||
* Get the base exec prefix of a Python installation
|
||||
* This is the directory where the Python interpreter is installed
|
||||
* and where the standard library is located
|
||||
*/
|
||||
export const getPythonBaseExecPrefix = memoize(getPythonBaseExecPrefix_, { promise: true })
|
||||
|
||||
async function isExternallyManaged_(python: string) {
|
||||
try {
|
||||
const base_exec_prefix = await getPythonBaseExecPrefix(python)
|
||||
|
||||
const pythonVersion = await getBinVersion(python)
|
||||
if (pythonVersion === undefined) {
|
||||
warning(`Failed to get the version of ${python}`)
|
||||
return false
|
||||
}
|
||||
|
||||
const externallyManagedPath = join(
|
||||
base_exec_prefix,
|
||||
"lib",
|
||||
`python${pythonVersion.major}.${pythonVersion.minor}`,
|
||||
"EXTERNALLY-MANAGED",
|
||||
)
|
||||
return pathExists(externallyManagedPath)
|
||||
} catch (err) {
|
||||
warning(`Failed to check if ${python} is externally managed: ${err}`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given Python installation is externally managed
|
||||
* This is required for Conan, Meson, etc. to work properly
|
||||
*
|
||||
* The answer is cached for subsequent calls
|
||||
*/
|
||||
export const isExternallyManaged = memoize(isExternallyManaged_, { promise: true })
|
||||
|
|
|
|||
Loading…
Reference in New Issue