diff --git a/.github/scripts/create_python_package.py b/.github/scripts/create_python_package.py new file mode 100644 index 0000000000..107b9d3b71 --- /dev/null +++ b/.github/scripts/create_python_package.py @@ -0,0 +1,64 @@ +import os +import zipfile +import argparse +import platform +import tempfile +import subprocess +import urllib.request + +import rez.packages +import rez.package_maker + + +parser = argparse.ArgumentParser() +parser.add_argument("version", help="Python version") +parser.add_argument("repository", help="Repository path") + +args = parser.parse_args() + + +def make_root(variant: rez.packages.Variant, path: str): + dest = os.path.join(path, "python") + + if platform.system() == "Windows": + with tempfile.TemporaryDirectory() as tmpdir: + archive_path = os.path.join(tmpdir, "python.nupkg") + + url = f"https://globalcdn.nuget.org/packages/python.{variant.version}.nupkg" + + print(f"Downloading {url!r}") + with urllib.request.urlopen(url) as archive: + with open(archive_path, "wb") as targetFile: + targetFile.write(archive.read()) + + with zipfile.ZipFile(archive_path) as archive: + print(f"Extracting {archive_path!r} to {dest!r}") + archive.extractall(path=dest) + else: + cmd = [ + "conda", + "create", + "--prefix", + dest, + f"python={args.version}", + "pip", + "--yes", + ] + print(f"Running {' '.join(cmd)!r}") + subprocess.check_call(cmd) + + +with rez.package_maker.make_package( + "python", os.path.expanduser(args.repository), make_root=make_root +) as package: + package.version = args.version + commands = [ + "env.PATH.prepend('{root}/python/bin')", + ] + if platform.system() == "Windows": + commands = [ + "env.PATH.prepend('{root}/python/tools')", + "env.PATH.prepend('{root}/python/tools/DLLs')", + ] + + package.commands = "\n".join(commands) diff --git a/.github/workflows/wheel.yaml b/.github/workflows/wheel.yaml index 4f6779a6e6..9a9a8c49f0 100644 --- a/.github/workflows/wheel.yaml +++ b/.github/workflows/wheel.yaml @@ -119,6 +119,8 @@ jobs: CURRENT_PLATFORM: ${{ matrix.os }} steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v4 with: python-version: 3.11 @@ -156,8 +158,46 @@ jobs: echo 'Running jctest with REZ_LAUNCHER_DEBUG=1' export REZ_LAUNCHER_DEBUG=1 - jctest + _rez-install-test rez --help rez --version rez-env --help + + - name: Integration test + shell: bash + run: | + set -e + + if [[ "${CURRENT_PLATFORM}" != "windows-latest" ]]; then + eval "$(conda shell.bash hook)" + conda activate base + fi + + set -x + + interpreter_path="" + export REZ_PACKAGES_PATH="~/rez_packages" + if [[ "${CURRENT_PLATFORM}" == "windows-latest" ]]; then + interpreter_path='.venv/Scripts/python.exe' + export PATH=$(pwd)/.venv/Scripts/rez:$PATH + else + interpreter_path=.'venv/bin/python' + export PATH=$(pwd)/.venv/bin/rez:$PATH + fi + "${interpreter_path}" .github/scripts/create_python_package.py 3.7.9 $REZ_PACKAGES_PATH + + # First, test that the "python" package is found and is the right version. + test "$(rez-env python -- python --version)" = 'Python 3.7.9' + + # Now test that the -E flag is used. This manifest with sys.flags.ignore_environment=1 + test $(rez-env python -- _rez-install-test | jq '.sysflags.ignore_environment' -r) -eq 1 + + # Now test that the executable used for runnin the rez command is the one from the rez + # install, not the rez package. + expected_path="$(pwd)/${interpreter_path}" + if [[ "${CURRENT_PLATFORM}" == "windows-latest" ]]; then + # Convert unix path to windows path + expected_path=$(cygpath -w "${expected_path}") + fi + test $(rez-env python -- _rez-install-test | jq '.executable' -r) = "${expected_path}" diff --git a/src/rez/cli/_entry_points.py b/src/rez/cli/_entry_points.py index 695a3c8d5f..2de7101708 100644 --- a/src/rez/cli/_entry_points.py +++ b/src/rez/cli/_entry_points.py @@ -8,6 +8,7 @@ import os import os.path import sys +import json ### Utility functions @@ -62,14 +63,6 @@ def check_production_install(): ### Entry points -@register("jctest") -def run_jctest(): - print("argv:", sys.argv) - print("executable:", sys.executable) - print("sys.flags:", sys.flags) - return 0 - - @register("rez") def run_rez(): check_production_install() @@ -322,3 +315,19 @@ def run_rez_rm(): check_production_install() from rez.cli._main import run return run("rm") + + +@register("_rez-install-test") +def run_rez_install_test(): + data = { + "argv": sys.argv, + "executable": sys.executable, + "sysflags": { + attr: getattr(sys.flags, attr) + for attr in dir(sys.flags) + if not attr.startswith("_") and not callable(getattr(sys.flags, attr)) + } + } + + print(json.dumps(data, indent=4)) + return 0