Skip to content

Commit

Permalink
Merge pull request #139 from aminya/python-fix [skip ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
aminya authored Nov 5, 2022
2 parents d2f3163 + 04867b9 commit 9c8f057
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 78 deletions.
2 changes: 1 addition & 1 deletion dist/node12/setup_cpp.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/node12/setup_cpp.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/node16/setup_cpp.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/node16/setup_cpp.js.map

Large diffs are not rendered by default.

75 changes: 71 additions & 4 deletions src/python/python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ import { dirname, join } from "patha"
import { hasDnf } from "../utils/env/hasDnf"
import { setupDnfPack } from "../utils/setup/setupDnfPack"
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) {
if (ciDetect() !== "github-actions") {
Expand Down Expand Up @@ -48,7 +55,7 @@ export async function setupPythonViaSystem(
join(setupDir, "python.exe")
const pythonSetupDir = dirname(pythonBinPath)
/** The directory which the tool is installed to */
await activateWinPython(pythonSetupDir)
await addPath(pythonSetupDir)
return { installDir: pythonSetupDir, binDir: pythonSetupDir }
}
case "darwin": {
Expand Down Expand Up @@ -76,7 +83,67 @@ export async function setupPythonViaSystem(
}
}

async function activateWinPython(binDir: string) {
info(`Add ${binDir} to PATH`)
await addPath(binDir)
let setupPythonAndPipTried = false

/// 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)
}
96 changes: 27 additions & 69 deletions src/utils/setup/setupPipPack.ts
Original file line number Diff line number Diff line change
@@ -1,91 +1,49 @@
/* eslint-disable require-atomic-updates */
import { getExecOutput } from "@actions/exec"
import execa from "execa"
import which from "which"
import { info } from "@actions/core"
import { addPath } from "../env/addEnv"
import { setupPython } from "../../python/python"
import { isBinUptoDate } from "./version"
import { join } from "patha"
import { getVersion } from "../../versions/versions"
import { addPythonBaseExecPrefix, setupPythonAndPip } from "../../python/python"
import { InstallationInfo } from "./setupBin"
import { setupAptPack } from "./setupAptPack"
import { setupPacmanPack } from "./setupPacmanPack"
import { isArch } from "../env/isArch"
import { isUbuntu } from "../env/isUbuntu"
import { hasDnf } from "../env/hasDnf"
import { setupDnfPack } from "./setupDnfPack"
import { existsSync } from "fs"
import { addExeExt, dirname, join } from "patha"
import { addPath } from "../env/addEnv"
import which from "which"

let python: string | undefined
let binDir: string | undefined

let tried = false
let binDirs: string[] | undefined

/** A function that installs a package using pip */
export async function setupPipPack(name: string, version?: string): Promise<InstallationInfo> {
info(`Installing ${name} ${version ?? ""} via pip`)

// setup python and pip if needed
if (python === undefined) {
if (which.sync("python3", { nothrow: true }) !== null) {
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" })
python = await setupPythonAndPip()
}

execa.sync(python, ["-m", "pip", "install", version !== undefined && version !== "" ? `${name}==${version}` : name], {
stdio: "inherit",
})

if (binDir === undefined) {
if (process.platform === "linux") {
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)
if (binDirs === undefined) {
binDirs = await addPythonBaseExecPrefix(python)
}

const binDir = findBinDir(binDirs, name)

await addPath(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]
}
3 changes: 3 additions & 0 deletions src/utils/std/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function unique(dirs: string[]) {
return [...new Set(dirs)]
}
2 changes: 1 addition & 1 deletion src/versions/default_versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const DefaultVersions: Record<string, string> = {
meson: "0.63.3", // https://github.com/mesonbuild/meson/releases
kcov: "40", // https://github.com/SimonKagstrom/kcov/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
}

Expand Down

0 comments on commit 9c8f057

Please sign in to comment.