Skip to content

Commit 9c8f057

Browse files
authored
Merge pull request #139 from aminya/python-fix [skip ci]
2 parents d2f3163 + 04867b9 commit 9c8f057

File tree

8 files changed

+106
-78
lines changed

8 files changed

+106
-78
lines changed

dist/node12/setup_cpp.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/node12/setup_cpp.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/node16/setup_cpp.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/node16/setup_cpp.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/python/python.ts

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ import { dirname, join } from "patha"
1212
import { hasDnf } from "../utils/env/hasDnf"
1313
import { setupDnfPack } from "../utils/setup/setupDnfPack"
1414
import { isUbuntu } from "../utils/env/isUbuntu"
15+
import { getExecOutput } from "@actions/exec"
16+
import { existsSync } from "fs"
17+
import { isBinUptoDate } from "../utils/setup/version"
18+
import { getVersion } from "../versions/versions"
19+
import assert from "assert"
20+
import execa from "execa"
21+
import { unique } from "../utils/std"
1522

1623
export async function setupPython(version: string, setupDir: string, arch: string) {
1724
if (ciDetect() !== "github-actions") {
@@ -48,7 +55,7 @@ export async function setupPythonViaSystem(
4855
join(setupDir, "python.exe")
4956
const pythonSetupDir = dirname(pythonBinPath)
5057
/** The directory which the tool is installed to */
51-
await activateWinPython(pythonSetupDir)
58+
await addPath(pythonSetupDir)
5259
return { installDir: pythonSetupDir, binDir: pythonSetupDir }
5360
}
5461
case "darwin": {
@@ -76,7 +83,67 @@ export async function setupPythonViaSystem(
7683
}
7784
}
7885

79-
async function activateWinPython(binDir: string) {
80-
info(`Add ${binDir} to PATH`)
81-
await addPath(binDir)
86+
let setupPythonAndPipTried = false
87+
88+
/// setup python and pip if needed
89+
export async function setupPythonAndPip(): Promise<string> {
90+
let foundPython: string
91+
92+
// install python
93+
if (which.sync("python3", { nothrow: true }) !== null) {
94+
foundPython = "python3"
95+
} else if (which.sync("python", { nothrow: true }) !== null && (await isBinUptoDate("python", "3.0.0"))) {
96+
foundPython = "python"
97+
} else {
98+
info("python3 was not found. Installing python")
99+
await setupPython(getVersion("python", undefined), "", process.arch)
100+
// try again
101+
if (setupPythonAndPipTried) {
102+
throw new Error("Failed to install python")
103+
}
104+
setupPythonAndPipTried = true
105+
return setupPythonAndPip() // recurse
106+
}
107+
108+
assert(typeof foundPython === "string")
109+
110+
// install pip
111+
if (process.platform === "win32") {
112+
// downgrade pip on Windows
113+
// https://github.com/pypa/pip/issues/10875#issuecomment-1030293005
114+
execa.sync(foundPython, ["-m", "pip", "install", "-U", "pip==21.3.1"], { stdio: "inherit" })
115+
} else if (process.platform === "linux") {
116+
// ensure that pip is installed on Linux (happens when python is found but pip not installed)
117+
if (isArch()) {
118+
setupPacmanPack("python-pip")
119+
} else if (hasDnf()) {
120+
setupDnfPack("python3-pip")
121+
} else if (isUbuntu()) {
122+
await setupAptPack("python3-pip")
123+
}
124+
}
125+
126+
// install wheel (required for Conan, Meson, etc.)
127+
execa.sync(foundPython, ["-m", "pip", "install", "-U", "wheel"], { stdio: "inherit" })
128+
129+
return foundPython
130+
}
131+
132+
export async function addPythonBaseExecPrefix(python: string) {
133+
const dirs: string[] = []
134+
135+
// detection based on the platform
136+
if (process.platform === "linux") {
137+
dirs.push("/home/runner/.local/bin/")
138+
} else if (process.platform === "darwin") {
139+
dirs.push("/usr/local/bin/")
140+
}
141+
142+
// detection using python.sys
143+
const base_exec_prefix = (await getExecOutput(`${python} -c "import sys;print(sys.base_exec_prefix);"`)).stdout.trim()
144+
// any of these are possible depending on the operating system!
145+
dirs.push(join(base_exec_prefix, "Scripts"), join(base_exec_prefix, "Scripts", "bin"), join(base_exec_prefix, "bin"))
146+
147+
// remove duplicates
148+
return unique(dirs)
82149
}

src/utils/setup/setupPipPack.ts

Lines changed: 27 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,49 @@
11
/* eslint-disable require-atomic-updates */
2-
import { getExecOutput } from "@actions/exec"
32
import execa from "execa"
4-
import which from "which"
53
import { info } from "@actions/core"
6-
import { addPath } from "../env/addEnv"
7-
import { setupPython } from "../../python/python"
8-
import { isBinUptoDate } from "./version"
9-
import { join } from "patha"
10-
import { getVersion } from "../../versions/versions"
4+
import { addPythonBaseExecPrefix, setupPythonAndPip } from "../../python/python"
115
import { InstallationInfo } from "./setupBin"
12-
import { setupAptPack } from "./setupAptPack"
13-
import { setupPacmanPack } from "./setupPacmanPack"
14-
import { isArch } from "../env/isArch"
15-
import { isUbuntu } from "../env/isUbuntu"
16-
import { hasDnf } from "../env/hasDnf"
17-
import { setupDnfPack } from "./setupDnfPack"
6+
import { existsSync } from "fs"
7+
import { addExeExt, dirname, join } from "patha"
8+
import { addPath } from "../env/addEnv"
9+
import which from "which"
1810

1911
let python: string | undefined
20-
let binDir: string | undefined
21-
22-
let tried = false
12+
let binDirs: string[] | undefined
2313

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

28-
// setup python and pip if needed
2918
if (python === undefined) {
30-
if (which.sync("python3", { nothrow: true }) !== null) {
31-
python = "python3"
32-
} else if (which.sync("python", { nothrow: true }) !== null && (await isBinUptoDate("python", "3.0.0"))) {
33-
python = "python"
34-
} else {
35-
info("python3 was not found. Installing python")
36-
await setupPython(getVersion("python", undefined), "", process.arch)
37-
// try again
38-
if (tried) {
39-
throw new Error("Failed to install python")
40-
}
41-
tried = true
42-
return setupPipPack(name, version)
43-
}
44-
if (process.platform === "win32") {
45-
// downgrade pip on Windows
46-
// https://github.com/pypa/pip/issues/10875#issuecomment-1030293005
47-
execa.sync(python, ["-m", "pip", "install", "-U", "pip==21.3.1"], { stdio: "inherit" })
48-
} else if (process.platform === "linux") {
49-
// ensure that pip is installed on Linux (happens when python is found but pip not installed)
50-
if (isArch()) {
51-
setupPacmanPack("python-pip")
52-
} else if (hasDnf()) {
53-
setupDnfPack("python3-pip")
54-
} else if (isUbuntu()) {
55-
await setupAptPack("python3-pip")
56-
}
57-
}
58-
59-
// install wheel (required for Conan, Meson, etc.)
60-
execa.sync(python, ["-m", "pip", "install", "-U", "wheel"], { stdio: "inherit" })
19+
python = await setupPythonAndPip()
6120
}
6221

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

67-
if (binDir === undefined) {
68-
if (process.platform === "linux") {
69-
binDir = "/home/runner/.local/bin/"
70-
} else if (process.platform === "darwin") {
71-
binDir = "/usr/local/bin/"
72-
} else {
73-
// windows or others
74-
try {
75-
binDir = join(
76-
(await getExecOutput(`${python} -c "import sys;print(sys.base_exec_prefix);"`)).stdout.trim(),
77-
"Scripts"
78-
)
79-
} catch {
80-
binDir = join(
81-
(await getExecOutput(`${python} -c "import sys;print(sys.base_exec_prefix);"`)).stdout.trim(),
82-
"Scripts"
83-
)
84-
}
85-
}
86-
info(`${binDir} to PATH`)
87-
await addPath(binDir)
26+
if (binDirs === undefined) {
27+
binDirs = await addPythonBaseExecPrefix(python)
8828
}
8929

30+
const binDir = findBinDir(binDirs, name)
31+
32+
await addPath(binDir)
33+
9034
return { binDir }
9135
}
36+
37+
function findBinDir(dirs: string[], name: string) {
38+
const foundDir = dirs.find((dir) => existsSync(join(dir, addExeExt(name))))
39+
if (foundDir !== undefined) {
40+
return foundDir
41+
}
42+
43+
const whichDir = which.sync(addExeExt(name), { nothrow: true })
44+
if (whichDir !== null) {
45+
return dirname(whichDir)
46+
}
47+
48+
return dirs[dirs.length - 1]
49+
}

src/utils/std/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function unique(dirs: string[]) {
2+
return [...new Set(dirs)]
3+
}

src/versions/default_versions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const DefaultVersions: Record<string, string> = {
1414
meson: "0.63.3", // https://github.com/mesonbuild/meson/releases
1515
kcov: "40", // https://github.com/SimonKagstrom/kcov/releases
1616
task: "3.16.0", // https://github.com/go-task/task/releases
17-
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/
17+
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/
1818
gcc: "11", // https://github.com/brechtsanders/winlibs_mingw/releases and // https://packages.ubuntu.com/search?suite=all&arch=any&searchon=names&keywords=gcc
1919
}
2020

0 commit comments

Comments
 (0)