Merge pull request #178 from aminya/python-is-python3 [skip ci]

This commit is contained in:
Amin Yahyaabadi 2023-07-04 13:16:59 -07:00 committed by GitHub
commit 0ef456cf00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 81 additions and 64 deletions

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

View File

@ -3,7 +3,7 @@ import { getExecOutput } from "@actions/exec"
import assert from "assert" import assert from "assert"
import { GITHUB_ACTIONS } from "ci-info" import { GITHUB_ACTIONS } from "ci-info"
import { info, warning } from "ci-log" import { info, warning } from "ci-log"
import { execaSync } from "execa" import { execa } from "execa"
import memoize from "micro-memoize" import memoize from "micro-memoize"
import { addExeExt, dirname, join } from "patha" import { addExeExt, dirname, join } from "patha"
import which from "which" import which from "which"
@ -21,6 +21,7 @@ import { isBinUptoDate } from "../utils/setup/version"
import { unique } from "../utils/std" import { unique } from "../utils/std"
import { MinVersions } from "../versions/default_versions" import { MinVersions } from "../versions/default_versions"
import { pathExists } from "path-exists" import { pathExists } from "path-exists"
import { setupPipPackWithPython } from "../utils/setup/setupPipPack"
export async function setupPython(version: string, setupDir: string, arch: string): Promise<InstallationInfo> { export async function setupPython(version: string, setupDir: string, arch: string): Promise<InstallationInfo> {
const installInfo = await findOrSetupPython(version, setupDir, arch) const installInfo = await findOrSetupPython(version, setupDir, arch)
@ -33,11 +34,12 @@ export async function setupPython(version: string, setupDir: string, arch: strin
throw new Error("pip was not installed correctly") throw new Error("pip was not installed correctly")
} }
// setup wheel // setup wheel and setuptools
try { try {
setupWheel(foundPython) await setupPipPackWithPython(foundPython, "setuptools", undefined, true)
await setupPipPackWithPython(foundPython, "wheel", undefined, true)
} catch (err) { } catch (err) {
warning(`Failed to install wheels: ${(err as Error).toString()}. Ignoring...`) warning(`Failed to install setuptools or wheel: ${(err as Error).toString()}. Ignoring...`)
} }
return installInfo return installInfo
@ -99,6 +101,11 @@ async function setupPythonSystem(setupDir: string, version: string) {
} }
case "darwin": { case "darwin": {
installInfo = await setupBrewPack("python3", version) installInfo = await setupBrewPack("python3", version)
// add the python and pip binaries to the path
const brewPythonPrefix = await execa("brew", ["--prefix", "python"], { stdio: "pipe" })
const brewPythonBin = join(brewPythonPrefix.stdout, "libexec", "bin")
await addPath(brewPythonBin)
break break
} }
case "linux": { case "linux": {
@ -107,7 +114,7 @@ async function setupPythonSystem(setupDir: string, version: string) {
} else if (hasDnf()) { } else if (hasDnf()) {
installInfo = setupDnfPack("python3", version) installInfo = setupDnfPack("python3", version)
} else if (isUbuntu()) { } else if (isUbuntu()) {
installInfo = await setupAptPack([{ name: "python3", version }]) installInfo = await setupAptPack([{ name: "python3", version }, { name: "python-is-python3" }])
} else { } else {
throw new Error("Unsupported linux distributions") throw new Error("Unsupported linux distributions")
} }
@ -194,23 +201,23 @@ async function isPipUptoDate(pip: string) {
} }
async function setupPip(foundPython: string) { async function setupPip(foundPython: string) {
const upgraded = ensurePipUpgrade(foundPython) const upgraded = await ensurePipUpgrade(foundPython)
if (!upgraded) { if (!upgraded) {
await setupPipSystem() await setupPipSystem()
// upgrade pip // upgrade pip
ensurePipUpgrade(foundPython) await ensurePipUpgrade(foundPython)
} }
} }
function ensurePipUpgrade(foundPython: string) { async function ensurePipUpgrade(foundPython: string) {
try { try {
execaSync(foundPython, ["-m", "ensurepip", "-U", "--upgrade"], { stdio: "inherit" }) await execa(foundPython, ["-m", "ensurepip", "-U", "--upgrade"], { stdio: "inherit" })
return true return true
} catch (err1) { } catch (err1) {
info((err1 as Error)?.toString?.()) info((err1 as Error)?.toString?.())
try { try {
// ensure pip is disabled on Ubuntu // ensure pip is disabled on Ubuntu
execaSync(foundPython, ["-m", "pip", "install", "--upgrade", "pip"], { stdio: "inherit" }) await execa(foundPython, ["-m", "pip", "install", "--upgrade", "pip"], { stdio: "inherit" })
return true return true
} catch (err2) { } catch (err2) {
info((err2 as Error)?.toString?.()) info((err2 as Error)?.toString?.())
@ -235,11 +242,6 @@ function setupPipSystem() {
throw new Error(`Could not install pip on ${process.platform}`) throw new Error(`Could not install pip on ${process.platform}`)
} }
/** Install wheel (required for Conan, Meson, etc.) */
function setupWheel(foundPython: string) {
execaSync(foundPython, ["-m", "pip", "install", "-U", "wheel"], { stdio: "inherit" })
}
async function addPythonBaseExecPrefix_raw(python: string) { async function addPythonBaseExecPrefix_raw(python: string) {
const dirs: string[] = [] const dirs: string[] = []

View File

@ -8,23 +8,29 @@ import { addPath } from "../env/addEnv"
import { InstallationInfo } from "./setupBin" import { InstallationInfo } from "./setupBin"
import { getVersion } from "../../versions/versions" import { getVersion } from "../../versions/versions"
import { ubuntuVersion } from "../env/ubuntu_version" import { ubuntuVersion } from "../env/ubuntu_version"
import memoize from "micro-memoize"
/* eslint-disable require-atomic-updates */
let python: string | undefined
/** 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, upgrade = false): Promise<InstallationInfo> {
info(`Installing ${name} ${version ?? ""} via pip`) return setupPipPackWithPython(await getPython(), name, version, upgrade)
if (python === undefined) {
python = (await setupPython(getVersion("python", undefined, await ubuntuVersion()), "", process.arch)).bin!
} }
execaSync(python, ["-m", "pip", "install", version !== undefined && version !== "" ? `${name}==${version}` : name], { export async function setupPipPackWithPython(
givenPython: string,
name: string,
version?: string,
upgrade = false
): Promise<InstallationInfo> {
info(`Installing ${name} ${version ?? ""} via pip`)
const nameAndVersion = version !== undefined && version !== "" ? `${name}==${version}` : name
const upgradeFlag = upgrade === true ? ["--upgrade"] : []
execaSync(givenPython, ["-m", "pip", "install", ...upgradeFlag, nameAndVersion], {
stdio: "inherit", stdio: "inherit",
}) })
const execPaths = await addPythonBaseExecPrefix(python) const execPaths = await addPythonBaseExecPrefix(givenPython)
const binDir = await findBinDir(execPaths, name) const binDir = await findBinDir(execPaths, name)
await addPath(binDir) await addPath(binDir)
@ -32,6 +38,15 @@ export async function setupPipPack(name: string, version?: string): Promise<Inst
return { binDir } return { binDir }
} }
async function getPython_raw(): Promise<string> {
const pythonBin = (await setupPython(getVersion("python", undefined, await ubuntuVersion()), "", process.arch)).bin
if (pythonBin === undefined) {
throw new Error("Python binary was not found")
}
return pythonBin
}
const getPython = memoize(getPython_raw)
async function findBinDir(dirs: string[], name: string) { async function findBinDir(dirs: string[], name: string) {
const exists = await Promise.all(dirs.map((dir) => pathExists(join(dir, addExeExt(name))))) const exists = await Promise.all(dirs.map((dir) => pathExists(join(dir, addExeExt(name)))))
const dirIndex = exists.findIndex((exist) => exist) const dirIndex = exists.findIndex((exist) => exist)