From e621a168841742de463940f6bd2c65c9aa0fcc45 Mon Sep 17 00:00:00 2001 From: mayeut Date: Sat, 5 Mar 2022 13:06:37 +0100 Subject: [PATCH] Create missing `pypyX.Y` symlinks `pypyX.Y.exe` executables are missing from PyPy archives on Windows before v7.3.9 (X.Y < 3.9) `pypy2.7` symlinks are also missing from macOS/Linux PyPy archives before v7.3.9 relates to #346 --- .github/workflows/test-pypy.yml | 14 ++++++++++++++ dist/setup/index.js | 18 ++++++++++++++++++ src/find-pypy.ts | 26 +++++++++++++++++++++++++- src/install-pypy.ts | 9 +++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-pypy.yml b/.github/workflows/test-pypy.yml index 2bd044106..f6362069a 100644 --- a/.github/workflows/test-pypy.yml +++ b/.github/workflows/test-pypy.yml @@ -44,3 +44,17 @@ jobs: - name: Run simple code run: python -c 'import math; print(math.factorial(5))' + + - name: Assert PyPy is running + run: | + import platform + assert platform.python_implementation().lower() == "pypy" + shell: python + + - name: Assert expected binaries (or symlinks) are present + run: | + EXECUTABLE=${{ matrix.pypy }} + EXECUTABLE=${EXECUTABLE/-/} # remove the first '-' in "pypy-X.Y" -> "pypyX.Y" to match executable name + EXECUTABLE=${EXECUTABLE%%-*} # remove any -* suffixe + ${EXECUTABLE} --version + shell: bash diff --git a/dist/setup/index.js b/dist/setup/index.js index ae0ab4045..4563d7330 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -2064,6 +2064,19 @@ const utils_1 = __webpack_require__(163); const semver = __importStar(__webpack_require__(876)); const core = __importStar(__webpack_require__(470)); const tc = __importStar(__webpack_require__(533)); +// TODO remove the following function once v7.3.9 is in tool cache +function createPyPySymlink(pypyBinaryPath, pythonVersion) { + return __awaiter(this, void 0, void 0, function* () { + const version = semver.coerce(pythonVersion); + const pythonBinaryPostfix = semver.major(version); + const pythonMinor = semver.minor(version); + const pypyBinaryPostfix = pythonBinaryPostfix === 2 ? '' : '3'; + const pypyMajorMinorBinaryPostfix = `${pythonBinaryPostfix}.${pythonMinor}`; + let binaryExtension = utils_1.IS_WINDOWS ? '.exe' : ''; + core.info('Creating symlinks...'); + utils_1.createSymlinkInFolder(pypyBinaryPath, `pypy${pypyBinaryPostfix}${binaryExtension}`, `pypy${pypyMajorMinorBinaryPostfix}${binaryExtension}`, true); + }); +} function findPyPyVersion(versionSpec, architecture) { return __awaiter(this, void 0, void 0, function* () { let resolvedPyPyVersion = ''; @@ -2081,6 +2094,8 @@ function findPyPyVersion(versionSpec, architecture) { const pipDir = utils_1.IS_WINDOWS ? 'Scripts' : 'bin'; const _binDir = path.join(installDir, pipDir); const pythonLocation = pypyInstall.getPyPyBinaryPath(installDir); + // TODO remove the following line once v7.3.9 is in tool cache + yield createPyPySymlink(pythonLocation, resolvedPythonVersion); core.exportVariable('pythonLocation', pythonLocation); core.addPath(pythonLocation); core.addPath(_binDir); @@ -10605,11 +10620,14 @@ function createPyPySymlink(pypyBinaryPath, pythonVersion) { return __awaiter(this, void 0, void 0, function* () { const version = semver.coerce(pythonVersion); const pythonBinaryPostfix = semver.major(version); + const pythonMinor = semver.minor(version); const pypyBinaryPostfix = pythonBinaryPostfix === 2 ? '' : '3'; + const pypyMajorMinorBinaryPostfix = `${pythonBinaryPostfix}.${pythonMinor}`; let binaryExtension = utils_1.IS_WINDOWS ? '.exe' : ''; core.info('Creating symlinks...'); utils_1.createSymlinkInFolder(pypyBinaryPath, `pypy${pypyBinaryPostfix}${binaryExtension}`, `python${pythonBinaryPostfix}${binaryExtension}`, true); utils_1.createSymlinkInFolder(pypyBinaryPath, `pypy${pypyBinaryPostfix}${binaryExtension}`, `python${binaryExtension}`, true); + utils_1.createSymlinkInFolder(pypyBinaryPath, `pypy${pypyBinaryPostfix}${binaryExtension}`, `pypy${pypyMajorMinorBinaryPostfix}${binaryExtension}`, true); }); } function installPip(pythonLocation) { diff --git a/src/find-pypy.ts b/src/find-pypy.ts index eb8dfac65..0894ab64c 100644 --- a/src/find-pypy.ts +++ b/src/find-pypy.ts @@ -6,7 +6,8 @@ import { validateVersion, getPyPyVersionFromPath, readExactPyPyVersionFile, - validatePythonVersionFormatForPyPy + validatePythonVersionFormatForPyPy, + createSymlinkInFolder } from './utils'; import * as semver from 'semver'; @@ -18,6 +19,27 @@ interface IPyPyVersionSpec { pythonVersion: string; } +// TODO remove the following function once v7.3.9 is in tool cache +async function createPyPySymlink( + pypyBinaryPath: string, + pythonVersion: string +) { + const version = semver.coerce(pythonVersion)!; + const pythonBinaryPostfix = semver.major(version); + const pythonMinor = semver.minor(version); + const pypyBinaryPostfix = pythonBinaryPostfix === 2 ? '' : '3'; + const pypyMajorMinorBinaryPostfix = `${pythonBinaryPostfix}.${pythonMinor}`; + let binaryExtension = IS_WINDOWS ? '.exe' : ''; + + core.info('Creating symlinks...'); + createSymlinkInFolder( + pypyBinaryPath, + `pypy${pypyBinaryPostfix}${binaryExtension}`, + `pypy${pypyMajorMinorBinaryPostfix}${binaryExtension}`, + true + ); +} + export async function findPyPyVersion( versionSpec: string, architecture: string @@ -49,6 +71,8 @@ export async function findPyPyVersion( const pipDir = IS_WINDOWS ? 'Scripts' : 'bin'; const _binDir = path.join(installDir, pipDir); const pythonLocation = pypyInstall.getPyPyBinaryPath(installDir); + // TODO remove the following line once v7.3.9 is in tool cache + await createPyPySymlink(pythonLocation, resolvedPythonVersion); core.exportVariable('pythonLocation', pythonLocation); core.addPath(pythonLocation); core.addPath(_binDir); diff --git a/src/install-pypy.ts b/src/install-pypy.ts index 402525ab3..c3718b792 100644 --- a/src/install-pypy.ts +++ b/src/install-pypy.ts @@ -98,7 +98,9 @@ async function createPyPySymlink( ) { const version = semver.coerce(pythonVersion)!; const pythonBinaryPostfix = semver.major(version); + const pythonMinor = semver.minor(version); const pypyBinaryPostfix = pythonBinaryPostfix === 2 ? '' : '3'; + const pypyMajorMinorBinaryPostfix = `${pythonBinaryPostfix}.${pythonMinor}`; let binaryExtension = IS_WINDOWS ? '.exe' : ''; core.info('Creating symlinks...'); @@ -115,6 +117,13 @@ async function createPyPySymlink( `python${binaryExtension}`, true ); + + createSymlinkInFolder( + pypyBinaryPath, + `pypy${pypyBinaryPostfix}${binaryExtension}`, + `pypy${pypyMajorMinorBinaryPostfix}${binaryExtension}`, + true + ); } async function installPip(pythonLocation: string) {