mirror of https://github.com/theacodes/nox.git


7 changed files with 320 additions and 10 deletions
@ -0,0 +1,74 @@
|
||||
import sys |
||||
|
||||
|
||||
def filter_version(version: str) -> str: |
||||
"""return python 'major.minor'""" |
||||
|
||||
# remove interpreter prefix |
||||
if version.startswith("pypy-"): |
||||
version_ = version[5:] |
||||
elif version.startswith("pypy"): |
||||
version_ = version[4:] |
||||
else: |
||||
version_ = version |
||||
|
||||
# remove extra specifier e.g. "3.11-dev" => "3.11" |
||||
version_ = version_.split("-")[0] |
||||
|
||||
version_parts = version_.split(".") |
||||
if len(version_parts) < 2: |
||||
raise ValueError(f"invalid version: {version}") |
||||
if not version_parts[0].isdigit(): |
||||
raise ValueError(f"invalid major python version: {version}") |
||||
if not version_parts[1].isdigit(): |
||||
raise ValueError(f"invalid minor python version: {version}") |
||||
return ".".join(version_parts[:2]) |
||||
|
||||
|
||||
def setup_action(input_: str) -> None: |
||||
versions = [version.strip() for version in input_.split(",") if version.strip()] |
||||
|
||||
pypy_versions = [version for version in versions if version.startswith("pypy")] |
||||
pypy_versions_filtered = [filter_version(version) for version in pypy_versions] |
||||
if len(pypy_versions) != len(set(pypy_versions_filtered)): |
||||
raise ValueError( |
||||
"multiple versions specified for the same 'major.minor' PyPy interpreter:" |
||||
f" {pypy_versions}" |
||||
) |
||||
|
||||
cpython_versions = [version for version in versions if version not in pypy_versions] |
||||
cpython_versions_filtered = [ |
||||
filter_version(version) for version in cpython_versions |
||||
] |
||||
if len(cpython_versions) != len(set(cpython_versions_filtered)): |
||||
raise ValueError( |
||||
"multiple versions specified for the same 'major.minor' CPython" |
||||
f" interpreter: {cpython_versions}" |
||||
) |
||||
|
||||
# cpython shall be installed last because |
||||
# other interpreters also define pythonX.Y symlinks. |
||||
versions = pypy_versions + cpython_versions |
||||
|
||||
# we want to install python 3.10 last to ease nox set-up |
||||
if "3.10" in cpython_versions_filtered: |
||||
index = cpython_versions_filtered.index("3.10") |
||||
index = versions.index(cpython_versions[index]) |
||||
cpython_310 = versions.pop(index) |
||||
versions.append(cpython_310) |
||||
else: |
||||
# add this to install nox |
||||
versions.append("3.10") |
||||
|
||||
if len(versions) > 20: |
||||
raise ValueError(f"too many interpreters to install: {len(versions)} > 20") |
||||
|
||||
print(f"::set-output name=interpreter_count::{len(versions)}") |
||||
for i, version in enumerate(versions): |
||||
print(f"::set-output name=interpreter_{i}::{version}") |
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
if len(sys.argv) != 2: |
||||
raise AssertionError(f"invalid arguments: {sys.argv}") |
||||
setup_action(sys.argv[1]) |
@ -0,0 +1,117 @@
|
||||
from __future__ import annotations |
||||
|
||||
import sys |
||||
from pathlib import Path |
||||
|
||||
import pytest |
||||
|
||||
GITHUB_FOLDER = Path(__file__).resolve().parent.parent / ".github" |
||||
sys.path.insert(0, str(GITHUB_FOLDER)) |
||||
from action_helper import filter_version, setup_action # noqa: E402 |
||||
|
||||
VALID_VERSIONS = { |
||||
"2.7.18": "2.7", |
||||
"3.9-dev": "3.9", |
||||
"3.10": "3.10", |
||||
"3.11.0.beta1": "3.11", |
||||
"pypy-3.7": "3.7", |
||||
"pypy-3.8-v7.3.9": "3.8", |
||||
"pypy-3.9": "3.9", |
||||
"pypy3.10": "3.10", |
||||
} |
||||
|
||||
|
||||
@pytest.mark.parametrize("version", VALID_VERSIONS.keys()) |
||||
def test_filter_version(version): |
||||
assert filter_version(version) == VALID_VERSIONS[version] |
||||
|
||||
|
||||
def test_filter_version_invalid(): |
||||
with pytest.raises(ValueError, match=r"invalid version: 3"): |
||||
filter_version("3") |
||||
|
||||
|
||||
def test_filter_version_invalid_major(): |
||||
with pytest.raises(ValueError, match=r"invalid major python version: x.0"): |
||||
filter_version("x.0") |
||||
|
||||
|
||||
def test_filter_version_invalid_minor(): |
||||
with pytest.raises(ValueError, match=r"invalid minor python version: 3.x"): |
||||
filter_version("3.x") |
||||
|
||||
|
||||
VALID_VERSION_LISTS = { |
||||
"3.7, 3.8, 3.9, 3.10, pypy-3.7, pypy-3.8, pypy-3.9": [ |
||||
"::set-output name=interpreter_count::7", |
||||
"::set-output name=interpreter_0::pypy-3.7", |
||||
"::set-output name=interpreter_1::pypy-3.8", |
||||
"::set-output name=interpreter_2::pypy-3.9", |
||||
"::set-output name=interpreter_3::3.7", |
||||
"::set-output name=interpreter_4::3.8", |
||||
"::set-output name=interpreter_5::3.9", |
||||
"::set-output name=interpreter_6::3.10", |
||||
], |
||||
"": [ |
||||
"::set-output name=interpreter_count::1", |
||||
"::set-output name=interpreter_0::3.10", |
||||
], |
||||
"3.10.4": [ |
||||
"::set-output name=interpreter_count::1", |
||||
"::set-output name=interpreter_0::3.10.4", |
||||
], |
||||
"3.9-dev,pypy3.9-nightly": [ |
||||
"::set-output name=interpreter_count::3", |
||||
"::set-output name=interpreter_0::pypy3.9-nightly", |
||||
"::set-output name=interpreter_1::3.9-dev", |
||||
"::set-output name=interpreter_2::3.10", |
||||
], |
||||
"3.10, 3.9, 3.8": [ |
||||
"::set-output name=interpreter_count::3", |
||||
"::set-output name=interpreter_0::3.9", |
||||
"::set-output name=interpreter_1::3.8", |
||||
"::set-output name=interpreter_2::3.10", |
||||
], |
||||
",".join(f"3.{minor}" for minor in range(20)): [ |
||||
"::set-output name=interpreter_count::20" |
||||
] |
||||
+ [ |
||||
f"::set-output name=interpreter_{i}::3.{minor}" |
||||
for i, minor in enumerate(minor_ for minor_ in range(20) if minor_ != 10) |
||||
] |
||||
+ ["::set-output name=interpreter_19::3.10"], |
||||
} |
||||
|
||||
|
||||
@pytest.mark.parametrize("version_list", VALID_VERSION_LISTS.keys()) |
||||
def test_setup_action(capsys, version_list): |
||||
setup_action(version_list) |
||||
captured = capsys.readouterr() |
||||
lines = captured.out.splitlines() |
||||
assert lines == VALID_VERSION_LISTS[version_list] |
||||
|
||||
|
||||
def test_setup_action_multiple_pypy(): |
||||
with pytest.raises( |
||||
ValueError, |
||||
match=( |
||||
r"multiple versions specified for the same 'major.minor' PyPy interpreter" |
||||
), |
||||
): |
||||
setup_action("pypy3.9, pypy-3.9-v7.3.9") |
||||
|
||||
|
||||
def test_setup_action_multiple_cpython(): |
||||
with pytest.raises( |
||||
ValueError, |
||||
match=( |
||||
r"multiple versions specified for the same 'major.minor' CPython" |
||||
r" interpreter" |
||||
), |
||||
): |
||||
setup_action("3.10, 3.10.4") |
||||
|
||||
|
||||
def test_setup_action_too_many_interpreters(): |
||||
with pytest.raises(ValueError, match=r"too many interpreters to install: 21 > 20"): |
||||
setup_action(",".join(f"3.{minor}" for minor in range(21))) |
Loading…
Reference in new issue