mirror of https://github.com/aminya/setup-cpp
Merge pull request #139 from aminya/python-fix [skip ci]
This commit is contained in:
commit
9c8f057dbf
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
|
@ -12,6 +12,13 @@ import { dirname, join } from "patha"
|
||||||
import { hasDnf } from "../utils/env/hasDnf"
|
import { hasDnf } from "../utils/env/hasDnf"
|
||||||
import { setupDnfPack } from "../utils/setup/setupDnfPack"
|
import { setupDnfPack } from "../utils/setup/setupDnfPack"
|
||||||
import { isUbuntu } from "../utils/env/isUbuntu"
|
import { isUbuntu } from "../utils/env/isUbuntu"
|
||||||
|
import { getExecOutput } from "@actions/exec"
|
||||||
|
import { existsSync } from "fs"
|
||||||
|
import { isBinUptoDate } from "../utils/setup/version"
|
||||||
|
import { getVersion } from "../versions/versions"
|
||||||
|
import assert from "assert"
|
||||||
|
import execa from "execa"
|
||||||
|
import { unique } from "../utils/std"
|
||||||
|
|
||||||
export async function setupPython(version: string, setupDir: string, arch: string) {
|
export async function setupPython(version: string, setupDir: string, arch: string) {
|
||||||
if (ciDetect() !== "github-actions") {
|
if (ciDetect() !== "github-actions") {
|
||||||
|
@ -48,7 +55,7 @@ export async function setupPythonViaSystem(
|
||||||
join(setupDir, "python.exe")
|
join(setupDir, "python.exe")
|
||||||
const pythonSetupDir = dirname(pythonBinPath)
|
const pythonSetupDir = dirname(pythonBinPath)
|
||||||
/** The directory which the tool is installed to */
|
/** The directory which the tool is installed to */
|
||||||
await activateWinPython(pythonSetupDir)
|
await addPath(pythonSetupDir)
|
||||||
return { installDir: pythonSetupDir, binDir: pythonSetupDir }
|
return { installDir: pythonSetupDir, binDir: pythonSetupDir }
|
||||||
}
|
}
|
||||||
case "darwin": {
|
case "darwin": {
|
||||||
|
@ -76,7 +83,67 @@ export async function setupPythonViaSystem(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function activateWinPython(binDir: string) {
|
let setupPythonAndPipTried = false
|
||||||
info(`Add ${binDir} to PATH`)
|
|
||||||
await addPath(binDir)
|
/// setup python and pip if needed
|
||||||
|
export async function setupPythonAndPip(): Promise<string> {
|
||||||
|
let foundPython: string
|
||||||
|
|
||||||
|
// install python
|
||||||
|
if (which.sync("python3", { nothrow: true }) !== null) {
|
||||||
|
foundPython = "python3"
|
||||||
|
} else if (which.sync("python", { nothrow: true }) !== null && (await isBinUptoDate("python", "3.0.0"))) {
|
||||||
|
foundPython = "python"
|
||||||
|
} else {
|
||||||
|
info("python3 was not found. Installing python")
|
||||||
|
await setupPython(getVersion("python", undefined), "", process.arch)
|
||||||
|
// try again
|
||||||
|
if (setupPythonAndPipTried) {
|
||||||
|
throw new Error("Failed to install python")
|
||||||
|
}
|
||||||
|
setupPythonAndPipTried = true
|
||||||
|
return setupPythonAndPip() // recurse
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(typeof foundPython === "string")
|
||||||
|
|
||||||
|
// install pip
|
||||||
|
if (process.platform === "win32") {
|
||||||
|
// downgrade pip on Windows
|
||||||
|
// https://github.com/pypa/pip/issues/10875#issuecomment-1030293005
|
||||||
|
execa.sync(foundPython, ["-m", "pip", "install", "-U", "pip==21.3.1"], { stdio: "inherit" })
|
||||||
|
} else if (process.platform === "linux") {
|
||||||
|
// ensure that pip is installed on Linux (happens when python is found but pip not installed)
|
||||||
|
if (isArch()) {
|
||||||
|
setupPacmanPack("python-pip")
|
||||||
|
} else if (hasDnf()) {
|
||||||
|
setupDnfPack("python3-pip")
|
||||||
|
} else if (isUbuntu()) {
|
||||||
|
await setupAptPack("python3-pip")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// install wheel (required for Conan, Meson, etc.)
|
||||||
|
execa.sync(foundPython, ["-m", "pip", "install", "-U", "wheel"], { stdio: "inherit" })
|
||||||
|
|
||||||
|
return foundPython
|
||||||
|
}
|
||||||
|
|
||||||
|
export 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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,91 +1,49 @@
|
||||||
/* eslint-disable require-atomic-updates */
|
/* eslint-disable require-atomic-updates */
|
||||||
import { getExecOutput } from "@actions/exec"
|
|
||||||
import execa from "execa"
|
import execa from "execa"
|
||||||
import which from "which"
|
|
||||||
import { info } from "@actions/core"
|
import { info } from "@actions/core"
|
||||||
import { addPath } from "../env/addEnv"
|
import { addPythonBaseExecPrefix, setupPythonAndPip } from "../../python/python"
|
||||||
import { setupPython } from "../../python/python"
|
|
||||||
import { isBinUptoDate } from "./version"
|
|
||||||
import { join } from "patha"
|
|
||||||
import { getVersion } from "../../versions/versions"
|
|
||||||
import { InstallationInfo } from "./setupBin"
|
import { InstallationInfo } from "./setupBin"
|
||||||
import { setupAptPack } from "./setupAptPack"
|
import { existsSync } from "fs"
|
||||||
import { setupPacmanPack } from "./setupPacmanPack"
|
import { addExeExt, dirname, join } from "patha"
|
||||||
import { isArch } from "../env/isArch"
|
import { addPath } from "../env/addEnv"
|
||||||
import { isUbuntu } from "../env/isUbuntu"
|
import which from "which"
|
||||||
import { hasDnf } from "../env/hasDnf"
|
|
||||||
import { setupDnfPack } from "./setupDnfPack"
|
|
||||||
|
|
||||||
let python: string | undefined
|
let python: string | undefined
|
||||||
let binDir: string | undefined
|
let binDirs: string[] | undefined
|
||||||
|
|
||||||
let tried = false
|
|
||||||
|
|
||||||
/** A function that installs a package using pip */
|
/** A function that installs a package using pip */
|
||||||
export async function setupPipPack(name: string, version?: string): Promise<InstallationInfo> {
|
export async function setupPipPack(name: string, version?: string): Promise<InstallationInfo> {
|
||||||
info(`Installing ${name} ${version ?? ""} via pip`)
|
info(`Installing ${name} ${version ?? ""} via pip`)
|
||||||
|
|
||||||
// setup python and pip if needed
|
|
||||||
if (python === undefined) {
|
if (python === undefined) {
|
||||||
if (which.sync("python3", { nothrow: true }) !== null) {
|
python = await setupPythonAndPip()
|
||||||
python = "python3"
|
|
||||||
} else if (which.sync("python", { nothrow: true }) !== null && (await isBinUptoDate("python", "3.0.0"))) {
|
|
||||||
python = "python"
|
|
||||||
} else {
|
|
||||||
info("python3 was not found. Installing python")
|
|
||||||
await setupPython(getVersion("python", undefined), "", process.arch)
|
|
||||||
// try again
|
|
||||||
if (tried) {
|
|
||||||
throw new Error("Failed to install python")
|
|
||||||
}
|
|
||||||
tried = true
|
|
||||||
return setupPipPack(name, version)
|
|
||||||
}
|
|
||||||
if (process.platform === "win32") {
|
|
||||||
// downgrade pip on Windows
|
|
||||||
// https://github.com/pypa/pip/issues/10875#issuecomment-1030293005
|
|
||||||
execa.sync(python, ["-m", "pip", "install", "-U", "pip==21.3.1"], { stdio: "inherit" })
|
|
||||||
} else if (process.platform === "linux") {
|
|
||||||
// ensure that pip is installed on Linux (happens when python is found but pip not installed)
|
|
||||||
if (isArch()) {
|
|
||||||
setupPacmanPack("python-pip")
|
|
||||||
} else if (hasDnf()) {
|
|
||||||
setupDnfPack("python3-pip")
|
|
||||||
} else if (isUbuntu()) {
|
|
||||||
await setupAptPack("python3-pip")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// install wheel (required for Conan, Meson, etc.)
|
|
||||||
execa.sync(python, ["-m", "pip", "install", "-U", "wheel"], { stdio: "inherit" })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
execa.sync(python, ["-m", "pip", "install", version !== undefined && version !== "" ? `${name}==${version}` : name], {
|
execa.sync(python, ["-m", "pip", "install", version !== undefined && version !== "" ? `${name}==${version}` : name], {
|
||||||
stdio: "inherit",
|
stdio: "inherit",
|
||||||
})
|
})
|
||||||
|
|
||||||
if (binDir === undefined) {
|
if (binDirs === undefined) {
|
||||||
if (process.platform === "linux") {
|
binDirs = await addPythonBaseExecPrefix(python)
|
||||||
binDir = "/home/runner/.local/bin/"
|
|
||||||
} else if (process.platform === "darwin") {
|
|
||||||
binDir = "/usr/local/bin/"
|
|
||||||
} else {
|
|
||||||
// windows or others
|
|
||||||
try {
|
|
||||||
binDir = join(
|
|
||||||
(await getExecOutput(`${python} -c "import sys;print(sys.base_exec_prefix);"`)).stdout.trim(),
|
|
||||||
"Scripts"
|
|
||||||
)
|
|
||||||
} catch {
|
|
||||||
binDir = join(
|
|
||||||
(await getExecOutput(`${python} -c "import sys;print(sys.base_exec_prefix);"`)).stdout.trim(),
|
|
||||||
"Scripts"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
info(`${binDir} to PATH`)
|
|
||||||
await addPath(binDir)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const binDir = findBinDir(binDirs, name)
|
||||||
|
|
||||||
|
await addPath(binDir)
|
||||||
|
|
||||||
return { binDir }
|
return { binDir }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findBinDir(dirs: string[], name: string) {
|
||||||
|
const foundDir = dirs.find((dir) => existsSync(join(dir, addExeExt(name))))
|
||||||
|
if (foundDir !== undefined) {
|
||||||
|
return foundDir
|
||||||
|
}
|
||||||
|
|
||||||
|
const whichDir = which.sync(addExeExt(name), { nothrow: true })
|
||||||
|
if (whichDir !== null) {
|
||||||
|
return dirname(whichDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
return dirs[dirs.length - 1]
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
export function unique(dirs: string[]) {
|
||||||
|
return [...new Set(dirs)]
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ export const DefaultVersions: Record<string, string> = {
|
||||||
meson: "0.63.3", // https://github.com/mesonbuild/meson/releases
|
meson: "0.63.3", // https://github.com/mesonbuild/meson/releases
|
||||||
kcov: "40", // https://github.com/SimonKagstrom/kcov/releases
|
kcov: "40", // https://github.com/SimonKagstrom/kcov/releases
|
||||||
task: "3.16.0", // https://github.com/go-task/task/releases
|
task: "3.16.0", // https://github.com/go-task/task/releases
|
||||||
doxygen: isArch() ? "1.9.3-1" : "1.9.5", // https://www.doxygen.nl/download.html // https://packages.ubuntu.com/search?suite=all&arch=any&searchon=names&keywords=doxygen // https://formulae.brew.sh/formula/doxygen // https://archlinux.org/packages/extra/x86_64/doxygen/
|
doxygen: isArch() ? "1.9.5-1" : "1.9.5", // https://www.doxygen.nl/download.html // https://packages.ubuntu.com/search?suite=all&arch=any&searchon=names&keywords=doxygen // https://formulae.brew.sh/formula/doxygen // https://archlinux.org/packages/extra/x86_64/doxygen/
|
||||||
gcc: "11", // https://github.com/brechtsanders/winlibs_mingw/releases and // https://packages.ubuntu.com/search?suite=all&arch=any&searchon=names&keywords=gcc
|
gcc: "11", // https://github.com/brechtsanders/winlibs_mingw/releases and // https://packages.ubuntu.com/search?suite=all&arch=any&searchon=names&keywords=gcc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue