Merge pull request #190 from aminya/pipx [skip ci]

This commit is contained in:
Amin Yahyaabadi 2023-09-01 09:58:08 -07:00 committed by GitHub
commit 2ab6e8f154
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 122 additions and 61 deletions

View File

@ -32,6 +32,7 @@ words:
- DCMAKE
- deps
- devel
- DVCPKG
- dyld
- eabi
- esmodule
@ -67,6 +68,7 @@ words:
- OSSDK
- papm
- patha
- pipx
- pnpm
- pwsh
- pygments
@ -74,6 +76,7 @@ words:
- Sccache
- setupcpp
- setx
- SYSROOT
- Syuu
- terserrc
- Trofimovich
@ -83,16 +86,15 @@ words:
- upleveled
- vbatts
- vcpkg
- VCPKG
- vcvarsall
- venv
- visualc
- visualcpp
- vsversion
- whatwg
- xcrun
- Yahyaabadi
- VCPKG
- DVCPKG
- SYSROOT
ignoreWords: []
import: []
dictionaryDefinitions: []

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,6 @@
import { setupPipPack } from "../utils/setup/setupPipPack"
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export async function setupConan(version: string | undefined, _setupDir: string, _arch: string) {
await setupPipPack("setuptools", "")
export function setupConan(version: string | undefined, _setupDir: string, _arch: string) {
return setupPipPack("conan", version)
}

View File

@ -21,7 +21,7 @@ import { isBinUptoDate } from "../utils/setup/version"
import { unique } from "../utils/std"
import { MinVersions } from "../versions/default_versions"
import { pathExists } from "path-exists"
import { setupPipPackWithPython } from "../utils/setup/setupPipPack"
import { hasPipx, setupPipPackSystem, setupPipPackWithPython } from "../utils/setup/setupPipPack"
export async function setupPython(version: string, setupDir: string, arch: string): Promise<InstallationInfo> {
const installInfo = await findOrSetupPython(version, setupDir, arch)
@ -34,15 +34,37 @@ export async function setupPython(version: string, setupDir: string, arch: strin
throw new Error("pip was not installed correctly")
}
// setup wheel and setuptools
await setupPipx(foundPython)
await setupWheel(foundPython)
return installInfo
}
async function setupPipx(foundPython: string) {
try {
await setupPipPackWithPython(foundPython, "setuptools", undefined, true)
await setupPipPackWithPython(foundPython, "wheel", undefined, true)
if (!(await hasPipx(foundPython))) {
await setupPipPackWithPython(foundPython, "pipx", undefined, { upgrade: true, usePipx: false })
}
await execa(foundPython, ["-m", "pipx", "ensurepath"], { stdio: "inherit" })
await setupPipPackWithPython(foundPython, "venv", undefined, { upgrade: false, usePipx: false })
} catch (err) {
warning(`Failed to install pipx: ${(err as Error).toString()}. Ignoring...`)
}
}
/** Setup wheel and setuptools */
async function setupWheel(foundPython: string) {
try {
await setupPipPackWithPython(foundPython, "setuptools", undefined, {
upgrade: true,
isLibrary: true,
usePipx: false,
})
await setupPipPackWithPython(foundPython, "wheel", undefined, { upgrade: true, isLibrary: true, usePipx: false })
} catch (err) {
warning(`Failed to install setuptools or wheel: ${(err as Error).toString()}. Ignoring...`)
}
return installInfo
}
async function findOrSetupPython(version: string, setupDir: string, arch: string) {
@ -203,7 +225,9 @@ async function isPipUptoDate(pip: string) {
async function setupPip(foundPython: string) {
const upgraded = await ensurePipUpgrade(foundPython)
if (!upgraded) {
await setupPipSystem()
// ensure that pip is installed on Linux (happens when python is found but pip not installed)
await setupPipPackSystem("pip")
// upgrade pip
await ensurePipUpgrade(foundPython)
}
@ -228,20 +252,6 @@ async function ensurePipUpgrade(foundPython: string) {
return false
}
function setupPipSystem() {
if (process.platform === "linux") {
// ensure that pip is installed on Linux (happens when python is found but pip not installed)
if (isArch()) {
return setupPacmanPack("python-pip")
} else if (hasDnf()) {
return setupDnfPack([{ name: "python3-pip" }])
} else if (isUbuntu()) {
return setupAptPack([{ name: "python3-pip" }])
}
}
throw new Error(`Could not install pip on ${process.platform}`)
}
async function addPythonBaseExecPrefix_raw(python: string) {
const dirs: string[] = []

View File

@ -1,5 +1,5 @@
import { info } from "@actions/core"
import { execaSync } from "execa"
import { execa, execaSync } from "execa"
import { pathExists } from "path-exists"
import { addExeExt, dirname, join } from "patha"
import which from "which"
@ -9,26 +9,59 @@ import { InstallationInfo } from "./setupBin"
import { getVersion } from "../../versions/versions"
import { ubuntuVersion } from "../env/ubuntu_version"
import memoize from "micro-memoize"
import { isArch } from "../env/isArch"
import { setupPacmanPack } from "./setupPacmanPack"
import { hasDnf } from "../env/hasDnf"
import { setupDnfPack } from "./setupDnfPack"
import { isUbuntu } from "../env/isUbuntu"
import { setupAptPack } from "./setupAptPack"
export type SetupPipPackOptions = {
/** Whether to use pipx instead of pip */
usePipx?: boolean
/** Whether to install the package as a user */
user?: boolean
/** Whether to upgrade the package */
upgrade?: boolean
/** Whether the package is a library */
isLibrary?: boolean
}
/** A function that installs a package using pip */
export async function setupPipPack(name: string, version?: string, upgrade = false): Promise<InstallationInfo> {
return setupPipPackWithPython(await getPython(), name, version, upgrade)
export async function setupPipPack(
name: string,
version?: string,
options: SetupPipPackOptions = {},
): Promise<InstallationInfo> {
return setupPipPackWithPython(await getPython(), name, version, options)
}
export async function setupPipPackWithPython(
givenPython: string,
name: string,
version?: string,
upgrade = false,
options: SetupPipPackOptions = {},
): Promise<InstallationInfo> {
info(`Installing ${name} ${version ?? ""} via pip`)
const { usePipx = true, user = true, upgrade = false, isLibrary = false } = options
const isPipx = usePipx && !isLibrary && (await hasPipx(givenPython))
const pip = isPipx ? "pipx" : "pip"
info(`Installing ${name} ${version ?? ""} via ${pip}`)
try {
const nameAndVersion = version !== undefined && version !== "" ? `${name}==${version}` : name
const upgradeFlag = upgrade === true ? ["--upgrade"] : []
const upgradeFlag = upgrade ? (isPipx ? ["upgrade"] : ["install", "--upgrade"]) : ["install"]
const userFlag = !isPipx && user ? ["--user"] : []
execaSync(givenPython, ["-m", "pip", "install", ...upgradeFlag, nameAndVersion], {
execaSync(givenPython, ["-m", pip, ...upgradeFlag, ...userFlag, nameAndVersion], {
stdio: "inherit",
})
} catch (err) {
if ((await setupPipPackSystem(name)) === null) {
throw new Error(`Failed to install ${name} via ${pip} ${err}`)
}
}
const execPaths = await addPythonBaseExecPrefix(givenPython)
const binDir = await findBinDir(execPaths, name)
@ -38,6 +71,10 @@ export async function setupPipPackWithPython(
return { binDir }
}
export async function hasPipx(givenPython: string) {
return (await execa(givenPython, ["-m", "pipx", "--help"], { stdio: "ignore", reject: false })).exitCode === 0
}
async function getPython_raw(): Promise<string> {
const pythonBin = (await setupPython(getVersion("python", undefined, await ubuntuVersion()), "", process.arch)).bin
if (pythonBin === undefined) {
@ -62,3 +99,16 @@ async function findBinDir(dirs: string[], name: string) {
return dirs[dirs.length - 1]
}
export function setupPipPackSystem(name: string) {
if (process.platform === "linux") {
if (isArch()) {
return setupPacmanPack(`python-${name}`)
} else if (hasDnf()) {
return setupDnfPack([{ name: `python3-${name}` }])
} else if (isUbuntu()) {
return setupAptPack([{ name: `python3-${name}` }])
}
}
return null
}