From fff15a21cc8b16191cb1249f621fa3a55b9005b8 Mon Sep 17 00:00:00 2001 From: Matthieu Darbois Date: Wed, 18 May 2022 15:20:53 +0200 Subject: [PATCH] Use pypyX.Y for PyPy python-version input (#349) This versioning scheme is consistent with other tools in the python ecosystem so it feels more natural and allows better interaction with other tools. fixes #346 --- .github/workflows/test-pypy.yml | 4 +++- README.md | 28 ++++++++++++++-------------- __tests__/find-pypy.test.ts | 30 ++++++++++++++++++++++++------ dist/setup/index.js | 8 ++++++-- src/find-pypy.ts | 7 ++++++- src/setup-python.ts | 2 +- 6 files changed, 54 insertions(+), 25 deletions(-) diff --git a/.github/workflows/test-pypy.yml b/.github/workflows/test-pypy.yml index f636206..0eb06c3 100644 --- a/.github/workflows/test-pypy.yml +++ b/.github/workflows/test-pypy.yml @@ -22,6 +22,7 @@ jobs: pypy: - 'pypy-2.7' - 'pypy-3.7' + - 'pypy3.9' - 'pypy-2.7-v7.3.4' - 'pypy-3.7-v7.3.5' - 'pypy-3.7-v7.3.4' @@ -29,6 +30,7 @@ jobs: - 'pypy-3.7-v7.x' - 'pypy-2.7-v7.3.4rc1' - 'pypy-3.7-nightly' + - 'pypy3.8-v7.3.7' steps: - name: Checkout @@ -54,7 +56,7 @@ jobs: - 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/pypy-/pypy} # 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/README.md b/README.md index e06082a..2ace1f7 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ '2.x', '3.x', 'pypy-2.7', 'pypy-3.7', 'pypy-3.8' ] + python-version: [ '2.x', '3.x', 'pypy2.7', 'pypy3.7', 'pypy3.8' ] name: Python ${{ matrix.python-version }} sample steps: - uses: actions/checkout@v3 @@ -63,7 +63,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ['2.7', '3.7', '3.8', '3.9', '3.10', 'pypy-2.7', 'pypy-3.8'] + python-version: ['2.7', '3.7', '3.8', '3.9', '3.10', 'pypy2.7', 'pypy3.8'] exclude: - os: macos-latest python-version: '3.8' @@ -125,9 +125,9 @@ jobs: strategy: matrix: python-version: - - 'pypy-3.7' # the latest available version of PyPy that supports Python 3.7 - - 'pypy-3.7-v7.3.3' # Python 3.7 and PyPy 7.3.3 - - 'pypy-3.8' # the latest available version of PyPy that supports Python 3.8 + - 'pypy3.7' # the latest available version of PyPy that supports Python 3.7 + - 'pypy3.7-v7.3.3' # Python 3.7 and PyPy 7.3.3 + - 'pypy3.8' # the latest available version of PyPy that supports Python 3.8 steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v3 @@ -164,7 +164,7 @@ Check out our detailed guide on using [Python with GitHub Actions](https://help. - Preinstalled versions of PyPy in the tools cache on GitHub-hosted runners - For detailed information regarding the available versions of PyPy that are installed, see [Supported software](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-software). - For the latest PyPy release, all versions of Python are cached. - - Cache is updated with a 1-2 week delay. If you specify the PyPy version as `pypy-3.7`, the cached version will be used although a newer version is available. If you need to start using the recently released version right after release, you should specify the exact PyPy version using `pypy-3.7-v7.3.3`. + - Cache is updated with a 1-2 week delay. If you specify the PyPy version as `pypy3.7` or `pypy-3.7`, the cached version will be used although a newer version is available. If you need to start using the recently released version right after release, you should specify the exact PyPy version using `pypy3.7-v7.3.3` or `pypy-3.7-v7.3.3`. - Downloadable PyPy versions from the [official PyPy site](https://downloads.python.org/pypy/). - All available versions that we can download are listed in [versions.json](https://downloads.python.org/pypy/versions.json) file. @@ -197,17 +197,17 @@ You should specify only a major and minor version if you are okay with the most - Using the most recent patch version will result in a very quick setup since no downloads will be required since a locally installed version Python on the runner will be used. # Specifying a PyPy version -The version of PyPy should be specified in the format `pypy-[-v]`. +The version of PyPy should be specified in the format `pypy[-v]` or `pypy-[-v]`. The `` parameter is optional and can be skipped. The latest version will be used in this case. ``` -pypy-3.7 # the latest available version of PyPy that supports Python 3.7 -pypy-3.8 # the latest available version of PyPy that supports Python 3.8 -pypy-2.7 # the latest available version of PyPy that supports Python 2.7 -pypy-3.7-v7.3.3 # Python 3.7 and PyPy 7.3.3 -pypy-3.7-v7.x # Python 3.7 and the latest available PyPy 7.x -pypy-3.7-v7.3.3rc1 # Python 3.7 and preview version of PyPy -pypy-3.7-nightly # Python 3.7 and nightly PyPy +pypy3.7 or pypy-3.7 # the latest available version of PyPy that supports Python 3.7 +pypy3.8 or pypy-3.8 # the latest available version of PyPy that supports Python 3.8 +pypy2.7 or pypy-2.7 # the latest available version of PyPy that supports Python 2.7 +pypy3.7-v7.3.3 or pypy-3.7-v7.3.3 # Python 3.7 and PyPy 7.3.3 +pypy3.7-v7.x or pypy-3.7-v7.x # Python 3.7 and the latest available PyPy 7.x +pypy3.7-v7.3.3rc1 or pypy-3.7-v7.3.3rc1 # Python 3.7 and preview version of PyPy +pypy3.7-nightly or pypy-3.7-nightly # Python 3.7 and nightly PyPy ``` # Caching packages dependencies diff --git a/__tests__/find-pypy.test.ts b/__tests__/find-pypy.test.ts index ddf7ebc..8cb3250 100644 --- a/__tests__/find-pypy.test.ts +++ b/__tests__/find-pypy.test.ts @@ -37,16 +37,34 @@ describe('parsePyPyVersion', () => { ['pypy-3.6-v7.x', {pythonVersion: '3.6', pypyVersion: 'v7.x'}], ['pypy-3.6', {pythonVersion: '3.6', pypyVersion: 'x'}], ['pypy-3.6-nightly', {pythonVersion: '3.6', pypyVersion: 'nightly'}], - ['pypy-3.6-v7.3.3rc1', {pythonVersion: '3.6', pypyVersion: 'v7.3.3-rc.1'}] + ['pypy-3.6-v7.3.3rc1', {pythonVersion: '3.6', pypyVersion: 'v7.3.3-rc.1'}], + ['pypy3.8-v7.3.7', {pythonVersion: '3.8', pypyVersion: 'v7.3.7'}], + ['pypy3.8-v7.3.x', {pythonVersion: '3.8', pypyVersion: 'v7.3.x'}], + ['pypy3.8-v7.x', {pythonVersion: '3.8', pypyVersion: 'v7.x'}], + ['pypy3.8', {pythonVersion: '3.8', pypyVersion: 'x'}], + ['pypy3.9-nightly', {pythonVersion: '3.9', pypyVersion: 'nightly'}], + ['pypy3.9-v7.3.8rc1', {pythonVersion: '3.9', pypyVersion: 'v7.3.8-rc.1'}] ])('%s -> %s', (input, expected) => { expect(finder.parsePyPyVersion(input)).toEqual(expected); }); - it('throw on invalid input', () => { - expect(() => finder.parsePyPyVersion('pypy-')).toThrowError( - "Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy-'. See README for examples and documentation." - ); - }); + it.each(['', 'pypy-', 'pypy', 'p', 'notpypy-'])( + 'throw on invalid input "%s"', + input => { + expect(() => finder.parsePyPyVersion(input)).toThrowError( + "Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy' or 'pypy-'. See README for examples and documentation." + ); + } + ); + + it.each(['pypy-2', 'pypy-3', 'pypy2', 'pypy3', 'pypy3.x', 'pypy3.8.10'])( + 'throw on invalid input "%s"', + input => { + expect(() => finder.parsePyPyVersion(input)).toThrowError( + "Invalid format of Python version for PyPy. Python version should be specified in format 'x.y'. See README for examples and documentation." + ); + } + ); }); describe('getPyPyVersionFromPath', () => { diff --git a/dist/setup/index.js b/dist/setup/index.js index 3298e22..bf07395 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -6073,7 +6073,7 @@ const os = __importStar(__webpack_require__(87)); const cache_factory_1 = __webpack_require__(633); const utils_1 = __webpack_require__(163); function isPyPyVersion(versionSpec) { - return versionSpec.startsWith('pypy-'); + return versionSpec.startsWith('pypy'); } function cacheDependencies(cache, pythonVersion) { return __awaiter(this, void 0, void 0, function* () { @@ -52411,8 +52411,12 @@ function findPyPyToolCache(pythonVersion, pypyVersion, architecture) { exports.findPyPyToolCache = findPyPyToolCache; function parsePyPyVersion(versionSpec) { const versions = versionSpec.split('-').filter(item => !!item); + if (/^(pypy)(.+)/.test(versions[0])) { + let pythonVersion = versions[0].replace('pypy', ''); + versions.splice(0, 1, 'pypy', pythonVersion); + } if (versions.length < 2 || versions[0] != 'pypy') { - throw new Error("Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy-'. See README for examples and documentation."); + throw new Error("Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy' or 'pypy-'. See README for examples and documentation."); } const pythonVersion = versions[1]; let pypyVersion; diff --git a/src/find-pypy.ts b/src/find-pypy.ts index fd27382..5342c64 100644 --- a/src/find-pypy.ts +++ b/src/find-pypy.ts @@ -98,9 +98,14 @@ export function findPyPyToolCache( export function parsePyPyVersion(versionSpec: string): IPyPyVersionSpec { const versions = versionSpec.split('-').filter(item => !!item); + if (/^(pypy)(.+)/.test(versions[0])) { + let pythonVersion = versions[0].replace('pypy', ''); + versions.splice(0, 1, 'pypy', pythonVersion); + } + if (versions.length < 2 || versions[0] != 'pypy') { throw new Error( - "Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy-'. See README for examples and documentation." + "Invalid 'version' property for PyPy. PyPy version should be specified as 'pypy' or 'pypy-'. See README for examples and documentation." ); } diff --git a/src/setup-python.ts b/src/setup-python.ts index 82a9207..e8789de 100644 --- a/src/setup-python.ts +++ b/src/setup-python.ts @@ -7,7 +7,7 @@ import {getCacheDistributor} from './cache-distributions/cache-factory'; import {isCacheFeatureAvailable} from './utils'; function isPyPyVersion(versionSpec: string) { - return versionSpec.startsWith('pypy-'); + return versionSpec.startsWith('pypy'); } async function cacheDependencies(cache: string, pythonVersion: string) {