diff --git a/.github/workflows/test-pypy.yml b/.github/workflows/test-pypy.yml index f6362069a..0eb06c393 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 689566459..efb85adea 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 @@ -163,7 +163,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`, 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`. - 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. @@ -196,17 +196,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 # the latest available version of PyPy that supports Python 3.7 +pypy3.8 # the latest available version of PyPy that supports Python 3.8 +pypy2.7 # the latest available version of PyPy that supports Python 2.7 +pypy3.7-v7.3.3 # Python 3.7 and PyPy 7.3.3 +pypy3.7-v7.x # Python 3.7 and the latest available PyPy 7.x +pypy3.7-v7.3.3rc1 # Python 3.7 and preview version of PyPy +pypy3.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 ddf7ebcf4..8cb32509f 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 7c47a470c..362b9eecb 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* () { @@ -52406,14 +52406,24 @@ function findPyPyToolCache(pythonVersion, pypyVersion, architecture) { } exports.findPyPyToolCache = findPyPyToolCache; function parsePyPyVersion(versionSpec) { - const versions = versionSpec.split('-').filter(item => !!item); - 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."); + let versionsString; + if (versionSpec.length > 4 && versionSpec[4] == '-') { + versionsString = versionSpec.slice(5); } - const pythonVersion = versions[1]; + else if (versionSpec.length > 3) { + versionsString = versionSpec.slice(4); + } + else { + versionsString = ''; + } + const versions = versionsString.split('-').filter(item => !!item); + if (!versionSpec.startsWith('pypy') || versions.length == 0) { + 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[0]; let pypyVersion; - if (versions.length > 2) { - pypyVersion = pypyInstall.pypyVersionToSemantic(versions[2]); + if (versions.length > 1) { + pypyVersion = pypyInstall.pypyVersionToSemantic(versions[1]); } else { pypyVersion = 'x'; diff --git a/src/find-pypy.ts b/src/find-pypy.ts index 75b6abb03..4580b2f4f 100644 --- a/src/find-pypy.ts +++ b/src/find-pypy.ts @@ -95,18 +95,27 @@ export function findPyPyToolCache( } export function parsePyPyVersion(versionSpec: string): IPyPyVersionSpec { - const versions = versionSpec.split('-').filter(item => !!item); + let versionsString: string; + if (versionSpec.length > 4 && versionSpec[4] == '-') { + versionsString = versionSpec.slice(5); + } else if (versionSpec.length > 3) { + versionsString = versionSpec.slice(4); + } else { + versionsString = ''; + } + + const versions = versionsString.split('-').filter(item => !!item); - if (versions.length < 2 || versions[0] != 'pypy') { + if (!versionSpec.startsWith('pypy') || versions.length == 0) { 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." ); } - const pythonVersion = versions[1]; + const pythonVersion = versions[0]; let pypyVersion: string; - if (versions.length > 2) { - pypyVersion = pypyInstall.pypyVersionToSemantic(versions[2]); + if (versions.length > 1) { + pypyVersion = pypyInstall.pypyVersionToSemantic(versions[1]); } else { pypyVersion = 'x'; } diff --git a/src/setup-python.ts b/src/setup-python.ts index 62c76dba9..b9247d357 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) {