Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix PyPy installation on Windows to adopt new parameters format #201

Merged
merged 11 commits into from Apr 12, 2021
3 changes: 2 additions & 1 deletion .github/workflows/test-pypy.yml
Expand Up @@ -18,7 +18,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-20.04]
os: [macos-latest, windows-latest, ubuntu-18.04, ubuntu-latest]
pypy:
- 'pypy-2.7'
- 'pypy-3.6'
Expand All @@ -30,6 +30,7 @@ jobs:
- 'pypy-3.7-v7.x'
- 'pypy-3.6-v7.3.3rc1'
- 'pypy-3.7-nightly'
- 'pypy-2.7-v7.3.4rc1'
AlenaSviridenko marked this conversation as resolved.
Show resolved Hide resolved

steps:
- name: Checkout
Expand Down
39 changes: 39 additions & 0 deletions __tests__/data/pypy.json
Expand Up @@ -89,6 +89,45 @@
}
]
},
{
"pypy_version": "7.3.4rc1",
"python_version": "2.7.18",
"stable": false,
"latest_pypy": false,
"date": "2021-03-19",
"files": [
{
"filename": "pypy2.7-v7.3.4rc1-aarch64.tar.bz2",
"arch": "aarch64",
"platform": "linux",
"download_url": "https://test.downloads.python.org/pypy/pypy2.7-v7.3.4rc1-aarch64.tar.bz2"
},
{
"filename": "pypy2.7-v7.3.4rc1-linux32.tar.bz2",
"arch": "i686",
"platform": "linux",
"download_url": "https://test.downloads.python.org/pypy/pypy2.7-v7.3.4rc1-linux32.tar.bz2"
},
{
"filename": "pypy2.7-v7.3.4rc1-linux64.tar.bz2",
"arch": "x64",
"platform": "linux",
"download_url": "https://test.downloads.python.org/pypy/pypy2.7-v7.3.4rc1-linux64.tar.bz2"
},
{
"filename": "pypy2.7-v7.3.4rc1-osx64.tar.bz2",
"arch": "x64",
"platform": "darwin",
"download_url": "https://test.downloads.python.org/pypy/pypy2.7-v7.3.4rc1-osx64.tar.bz2"
},
{
"filename": "pypy2.7-v7.3.4rc1-win64.zip",
"arch": "x64",
"platform": "win64",
"download_url": "https://test.downloads.python.org/pypy/pypy2.7-v7.3.4rc1-win64.zip"
}
]
},
{
"pypy_version": "7.3.3rc2",
"python_version": "3.7.7",
Expand Down
38 changes: 35 additions & 3 deletions dist/index.js
Expand Up @@ -1133,7 +1133,9 @@ exports.findPyPyVersion = findPyPyVersion;
function findPyPyToolCache(pythonVersion, pypyVersion, architecture) {
let resolvedPyPyVersion = '';
let resolvedPythonVersion = '';
let installDir = tc.find('PyPy', pythonVersion, architecture);
let installDir = utils_1.IS_WINDOWS
? findPyPyInstallDirForWindows(pythonVersion)
: tc.find('PyPy', pythonVersion, architecture);
if (installDir) {
// 'tc.find' finds tool based on Python version but we also need to check
// whether PyPy version satisfies requested version.
Expand Down Expand Up @@ -1177,6 +1179,12 @@ function parsePyPyVersion(versionSpec) {
};
}
exports.parsePyPyVersion = parsePyPyVersion;
function findPyPyInstallDirForWindows(pythonVersion) {
let installDir = '';
utils_1.WINDOWS_ARCHS.forEach(architecture => (installDir = installDir || tc.find('PyPy', pythonVersion, architecture)));
return installDir;
}
exports.findPyPyInstallDirForWindows = findPyPyInstallDirForWindows;


/***/ }),
Expand Down Expand Up @@ -2327,6 +2335,8 @@ const path = __importStar(__webpack_require__(622));
const semver = __importStar(__webpack_require__(876));
exports.IS_WINDOWS = process.platform === 'win32';
exports.IS_LINUX = process.platform === 'linux';
exports.WINDOWS_ARCHS = ['x86', 'x64'];
exports.WINDOWS_PLATFORMS = ['win32', 'win64'];
const PYPY_VERSION_FILE = 'PYPY_VERSION';
/** create Symlinks for downloaded PyPy
* It should be executed only for downloaded versions in runtime, because
Expand Down Expand Up @@ -2893,7 +2903,9 @@ function findRelease(releases, pythonVersion, pypyVersion, architecture) {
const isPyPyVersionSatisfied = isPyPyNightly ||
semver.satisfies(pypyVersionToSemantic(item.pypy_version), pypyVersion);
const isArchPresent = item.files &&
item.files.some(file => file.arch === architecture && file.platform === process.platform);
(utils_1.IS_WINDOWS
? isArchPresentForWindows(item)
: isArchPresentForMacOrLinux(item, architecture, process.platform));
return isPythonVersionSatisfied && isPyPyVersionSatisfied && isArchPresent;
});
if (filterReleases.length === 0) {
Expand All @@ -2904,7 +2916,9 @@ function findRelease(releases, pythonVersion, pypyVersion, architecture) {
semver.compare(semver.coerce(current.python_version), semver.coerce(previous.python_version)));
});
const foundRelease = sortedReleases[0];
const foundAsset = foundRelease.files.find(item => item.arch === architecture && item.platform === process.platform);
const foundAsset = utils_1.IS_WINDOWS
? findAssetForWindows(foundRelease)
: findAssetForMacOrLinux(foundRelease, architecture, process.platform);
return {
foundAsset,
resolvedPythonVersion: foundRelease.python_version,
Expand All @@ -2926,6 +2940,24 @@ function pypyVersionToSemantic(versionSpec) {
return versionSpec.replace(prereleaseVersion, '$1-$2.$3');
}
exports.pypyVersionToSemantic = pypyVersionToSemantic;
function isArchPresentForWindows(item) {
return item.files.some((file) => utils_1.WINDOWS_ARCHS.includes(file.arch) &&
utils_1.WINDOWS_PLATFORMS.includes(file.platform));
}
exports.isArchPresentForWindows = isArchPresentForWindows;
function isArchPresentForMacOrLinux(item, architecture, platform) {
return item.files.some((file) => file.arch === architecture && file.platform === platform);
}
exports.isArchPresentForMacOrLinux = isArchPresentForMacOrLinux;
function findAssetForWindows(releases) {
return releases.files.find((item) => utils_1.WINDOWS_ARCHS.includes(item.arch) &&
utils_1.WINDOWS_PLATFORMS.includes(item.platform));
}
exports.findAssetForWindows = findAssetForWindows;
function findAssetForMacOrLinux(releases, architecture, platform) {
return releases.files.find((item) => item.arch === architecture && item.platform === platform);
}
exports.findAssetForMacOrLinux = findAssetForMacOrLinux;


/***/ }),
Expand Down
16 changes: 15 additions & 1 deletion src/find-pypy.ts
Expand Up @@ -2,6 +2,7 @@ import * as path from 'path';
import * as pypyInstall from './install-pypy';
import {
IS_WINDOWS,
WINDOWS_ARCHS,
validateVersion,
getPyPyVersionFromPath,
readExactPyPyVersionFile,
Expand Down Expand Up @@ -67,7 +68,9 @@ export function findPyPyToolCache(
) {
let resolvedPyPyVersion = '';
let resolvedPythonVersion = '';
let installDir: string | null = tc.find('PyPy', pythonVersion, architecture);
let installDir: string | null = IS_WINDOWS
? findPyPyInstallDirForWindows(pythonVersion)
: tc.find('PyPy', pythonVersion, architecture);

if (installDir) {
// 'tc.find' finds tool based on Python version but we also need to check
Expand Down Expand Up @@ -129,3 +132,14 @@ export function parsePyPyVersion(versionSpec: string): IPyPyVersionSpec {
pythonVersion: pythonVersion
};
}

export function findPyPyInstallDirForWindows(pythonVersion: string): string {
let installDir = '';

WINDOWS_ARCHS.forEach(
architecture =>
(installDir = installDir || tc.find('PyPy', pythonVersion, architecture))
);

return installDir;
}
50 changes: 44 additions & 6 deletions src/install-pypy.ts
Expand Up @@ -8,6 +8,8 @@ import fs from 'fs';

import {
IS_WINDOWS,
WINDOWS_ARCHS,
WINDOWS_PLATFORMS,
IPyPyManifestRelease,
createSymlinkInFolder,
isNightlyKeyword,
Expand Down Expand Up @@ -143,9 +145,9 @@ export function findRelease(
semver.satisfies(pypyVersionToSemantic(item.pypy_version), pypyVersion);
const isArchPresent =
item.files &&
item.files.some(
file => file.arch === architecture && file.platform === process.platform
);
(IS_WINDOWS
? isArchPresentForWindows(item)
: isArchPresentForMacOrLinux(item, architecture, process.platform));
return isPythonVersionSatisfied && isPyPyVersionSatisfied && isArchPresent;
});

Expand All @@ -167,9 +169,9 @@ export function findRelease(
});

const foundRelease = sortedReleases[0];
const foundAsset = foundRelease.files.find(
item => item.arch === architecture && item.platform === process.platform
);
const foundAsset = IS_WINDOWS
? findAssetForWindows(foundRelease)
: findAssetForMacOrLinux(foundRelease, architecture, process.platform);

return {
foundAsset,
Expand All @@ -191,3 +193,39 @@ export function pypyVersionToSemantic(versionSpec: string) {
const prereleaseVersion = /(\d+\.\d+\.\d+)((?:a|b|rc))(\d*)/g;
return versionSpec.replace(prereleaseVersion, '$1-$2.$3');
}

export function isArchPresentForWindows(item: any) {
return item.files.some(
(file: any) =>
WINDOWS_ARCHS.includes(file.arch) &&
WINDOWS_PLATFORMS.includes(file.platform)
);
}

export function isArchPresentForMacOrLinux(
item: any,
architecture: string,
platform: string
) {
return item.files.some(
(file: any) => file.arch === architecture && file.platform === platform
);
}

export function findAssetForWindows(releases: any) {
return releases.files.find(
(item: any) =>
WINDOWS_ARCHS.includes(item.arch) &&
WINDOWS_PLATFORMS.includes(item.platform)
);
}

export function findAssetForMacOrLinux(
releases: any,
architecture: string,
platform: string
) {
return releases.files.find(
(item: any) => item.arch === architecture && item.platform === platform
);
}
2 changes: 2 additions & 0 deletions src/utils.ts
Expand Up @@ -4,6 +4,8 @@ import * as semver from 'semver';

export const IS_WINDOWS = process.platform === 'win32';
export const IS_LINUX = process.platform === 'linux';
export const WINDOWS_ARCHS = ['x86', 'x64'];
export const WINDOWS_PLATFORMS = ['win32', 'win64'];
const PYPY_VERSION_FILE = 'PYPY_VERSION';

export interface IPyPyManifestAsset {
Expand Down