From 60534502586a8c76af2b2c2d87043ee5f5a48809 Mon Sep 17 00:00:00 2001 From: Pavel Vergeev Date: Wed, 14 Feb 2024 03:53:21 +0400 Subject: [PATCH 01/68] Remove Python2-related __future__ imports (#1640) Signed-off-by: Pavel Vergeev --- .github/scripts/store_benchmark.py | 1 - .github/scripts/validate_benchmark.py | 1 - example_extensions/hello_cmd/setup.py | 1 - install.py | 2 -- release-rez.py | 1 - repository/hello_world_py/1.0.0/python/hello_world.py | 3 --- repository/tbb/4.3/install.py | 2 -- setup.py | 2 -- src/build_utils/license/change_copyright | 1 - src/rez/__init__.py | 2 -- src/rez/backport/zipfile.py | 1 - src/rez/bind/PyQt.py | 1 - src/rez/bind/PySide.py | 1 - src/rez/bind/_pymodule.py | 2 -- src/rez/bind/_utils.py | 1 - src/rez/bind/arch.py | 1 - src/rez/bind/cmake.py | 1 - src/rez/bind/gcc.py | 1 - src/rez/bind/hello_world.py | 2 -- src/rez/bind/os.py | 1 - src/rez/bind/pip.py | 1 - src/rez/bind/platform.py | 1 - src/rez/bind/python.py | 1 - src/rez/bind/rez.py | 1 - src/rez/bind/rezgui.py | 1 - src/rez/bind/setuptools.py | 1 - src/rez/bind/sip.py | 1 - src/rez/build_process.py | 2 -- src/rez/cli/_main.py | 2 -- src/rez/cli/_util.py | 2 -- src/rez/cli/benchmark.py | 2 -- src/rez/cli/bind.py | 2 -- src/rez/cli/build.py | 2 -- src/rez/cli/bundle.py | 2 -- src/rez/cli/complete.py | 2 -- src/rez/cli/config.py | 2 -- src/rez/cli/context.py | 2 -- src/rez/cli/cp.py | 1 - src/rez/cli/depends.py | 1 - src/rez/cli/env.py | 1 - src/rez/cli/help.py | 1 - src/rez/cli/interpret.py | 1 - src/rez/cli/memcache.py | 1 - src/rez/cli/mv.py | 1 - src/rez/cli/pip.py | 1 - src/rez/cli/pkg-cache.py | 1 - src/rez/cli/pkg-ignore.py | 1 - src/rez/cli/plugins.py | 1 - src/rez/cli/release.py | 2 -- src/rez/cli/rm.py | 1 - src/rez/cli/search.py | 2 -- src/rez/cli/suite.py | 1 - src/rez/cli/test.py | 1 - src/rez/cli/view.py | 1 - src/rez/cli/yaml2py.py | 1 - src/rez/config.py | 1 - src/rez/data/tests/builds/packages/anti/1.0.0/build.py | 2 -- src/rez/data/tests/builds/packages/bah/2.1/build.py | 1 - src/rez/data/tests/builds/packages/build_util/1/build.py | 2 -- .../tests/builds/packages/build_util/1/build_util/__init__.py | 2 -- src/rez/data/tests/builds/packages/foo/1.0.0/build.py | 2 -- src/rez/data/tests/builds/packages/foo/1.1.0/build.py | 2 -- src/rez/data/tests/release/build.py | 2 -- src/rez/package_bind.py | 2 -- src/rez/package_help.py | 2 -- src/rez/package_serialise.py | 2 -- src/rez/pip.py | 2 -- src/rez/resolved_context.py | 2 -- src/rez/rex.py | 2 -- src/rez/solver.py | 2 -- src/rez/status.py | 2 -- src/rez/suite.py | 2 -- src/rez/tests/test_shells.py | 2 -- src/rez/tests/test_solver.py | 2 -- src/rez/tests/util.py | 2 -- src/rez/utils/colorize.py | 2 -- src/rez/utils/diff_packages.py | 2 -- src/rez/utils/filesystem.py | 2 -- src/rez/utils/formatting.py | 2 -- src/rez/utils/graph_utils.py | 2 -- src/rez/utils/installer.py | 2 -- src/rez/utils/json.py | 1 - src/rez/utils/logging_.py | 1 - src/rez/utils/memcached.py | 2 -- src/rez/utils/py_dist.py | 2 -- src/rez/utils/scope.py | 2 -- src/rez/version/_version.py | 1 - src/rez/wrapper.py | 2 -- src/rezgui/dialogs/ProcessDialog.py | 2 -- src/rezgui/objects/ResolveThread.py | 2 -- src/rezplugins/build_system/cmake.py | 2 -- src/rezplugins/release_hook/amqp.py | 2 -- src/rezplugins/release_hook/command.py | 2 -- src/rezplugins/release_hook/emailer.py | 2 -- src/rezplugins/release_vcs/git.py | 2 -- src/rezplugins/release_vcs/hg.py | 2 -- src/rezplugins/release_vcs/stub.py | 2 -- src/rezplugins/release_vcs/svn.py | 2 -- 98 files changed, 156 deletions(-) diff --git a/.github/scripts/store_benchmark.py b/.github/scripts/store_benchmark.py index d8cbb8c1e..73315ae7c 100644 --- a/.github/scripts/store_benchmark.py +++ b/.github/scripts/store_benchmark.py @@ -1,4 +1,3 @@ -from __future__ import print_function import os import os.path import json diff --git a/.github/scripts/validate_benchmark.py b/.github/scripts/validate_benchmark.py index 1db42a548..9d57e03cf 100644 --- a/.github/scripts/validate_benchmark.py +++ b/.github/scripts/validate_benchmark.py @@ -1,4 +1,3 @@ -from __future__ import print_function import os.path import sys import json diff --git a/example_extensions/hello_cmd/setup.py b/example_extensions/hello_cmd/setup.py index e890b3951..0f9617c1c 100644 --- a/example_extensions/hello_cmd/setup.py +++ b/example_extensions/hello_cmd/setup.py @@ -2,7 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function, with_statement from setuptools import setup diff --git a/install.py b/install.py index ce77b244e..78bff3550 100644 --- a/install.py +++ b/install.py @@ -6,8 +6,6 @@ This script uses venv/virtualenv to create a standalone, production-ready Rez installation in the specified directory. """ -from __future__ import print_function - import argparse import os import sys diff --git a/release-rez.py b/release-rez.py index 166083914..03ea0744c 100644 --- a/release-rez.py +++ b/release-rez.py @@ -7,7 +7,6 @@ Read RELEASE.md before using this utility. """ -from __future__ import print_function import argparse import os from datetime import date diff --git a/repository/hello_world_py/1.0.0/python/hello_world.py b/repository/hello_world_py/1.0.0/python/hello_world.py index bedf75984..e64f971eb 100644 --- a/repository/hello_world_py/1.0.0/python/hello_world.py +++ b/repository/hello_world_py/1.0.0/python/hello_world.py @@ -1,5 +1,2 @@ -from __future__ import print_function - - def hello(): print("Hello world!") diff --git a/repository/tbb/4.3/install.py b/repository/tbb/4.3/install.py index a7289c4c3..a9eb353ac 100644 --- a/repository/tbb/4.3/install.py +++ b/repository/tbb/4.3/install.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import sys import shutil import os diff --git a/setup.py b/setup.py index 5bd6d8c7d..34b9b396d 100644 --- a/setup.py +++ b/setup.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function, with_statement - import fnmatch import os import os.path diff --git a/src/build_utils/license/change_copyright b/src/build_utils/license/change_copyright index 8ce5a803e..4af68d2dc 100755 --- a/src/build_utils/license/change_copyright +++ b/src/build_utils/license/change_copyright @@ -2,7 +2,6 @@ # # dumb script to update copyright notice in a py sourcefile # -from __future__ import print_function import argparse import sys import os diff --git a/src/rez/__init__.py b/src/rez/__init__.py index f9dd5ab90..be0a91c2e 100644 --- a/src/rez/__init__.py +++ b/src/rez/__init__.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - from rez.utils._version import _rez_version import rez.deprecations import sys diff --git a/src/rez/backport/zipfile.py b/src/rez/backport/zipfile.py index 233231856..09624f902 100644 --- a/src/rez/backport/zipfile.py +++ b/src/rez/backport/zipfile.py @@ -1,2 +1 @@ -from __future__ import absolute_import from zipfile import * diff --git a/src/rez/bind/PyQt.py b/src/rez/bind/PyQt.py index dd059d466..4645bf672 100644 --- a/src/rez/bind/PyQt.py +++ b/src/rez/bind/PyQt.py @@ -5,7 +5,6 @@ """ Binds the python PyQt module as a rez package. """ -from __future__ import absolute_import from rez.bind import _pymodule from rez.bind._utils import get_version_in_python diff --git a/src/rez/bind/PySide.py b/src/rez/bind/PySide.py index 7a22ae5bc..8ccb2afc7 100644 --- a/src/rez/bind/PySide.py +++ b/src/rez/bind/PySide.py @@ -5,7 +5,6 @@ """ Binds the python PySide module as a rez package. """ -from __future__ import absolute_import from rez.bind import _pymodule diff --git a/src/rez/bind/_pymodule.py b/src/rez/bind/_pymodule.py index 0f51dc747..0c265bbdd 100644 --- a/src/rez/bind/_pymodule.py +++ b/src/rez/bind/_pymodule.py @@ -9,8 +9,6 @@ the current python interpreter - this is rez's, inside its installation virtualenv. """ -from __future__ import absolute_import, print_function - from rez.bind._utils import check_version, find_exe, make_dirs, \ get_version_in_python, run_python_command, log from rez.package_maker import make_package diff --git a/src/rez/bind/_utils.py b/src/rez/bind/_utils.py index 950c18436..395571cda 100644 --- a/src/rez/bind/_utils.py +++ b/src/rez/bind/_utils.py @@ -5,7 +5,6 @@ """ Utility functions for bind modules. """ -from __future__ import absolute_import from rez.version import Version from rez.exceptions import RezBindError from rez.config import config diff --git a/src/rez/bind/arch.py b/src/rez/bind/arch.py index 146317694..531ff2f75 100644 --- a/src/rez/bind/arch.py +++ b/src/rez/bind/arch.py @@ -5,7 +5,6 @@ """ Creates the system architecture package. """ -from __future__ import absolute_import from rez.package_maker import make_package from rez.version import Version from rez.bind._utils import check_version diff --git a/src/rez/bind/cmake.py b/src/rez/bind/cmake.py index 33ad5130c..8489a3566 100644 --- a/src/rez/bind/cmake.py +++ b/src/rez/bind/cmake.py @@ -5,7 +5,6 @@ """ Binds a cmake executable as a rez package. """ -from __future__ import absolute_import from rez.package_maker import make_package from rez.bind._utils import check_version, find_exe, extract_version, make_dirs from rez.utils.platform_ import platform_ diff --git a/src/rez/bind/gcc.py b/src/rez/bind/gcc.py index 4d99fa811..8377d7d85 100644 --- a/src/rez/bind/gcc.py +++ b/src/rez/bind/gcc.py @@ -2,7 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import absolute_import from rez.bind._utils import find_exe, extract_version, make_dirs, log from rez.package_maker import make_package from rez.utils.lint_helper import env diff --git a/src/rez/bind/hello_world.py b/src/rez/bind/hello_world.py index b973c1ee6..c98fad65b 100644 --- a/src/rez/bind/hello_world.py +++ b/src/rez/bind/hello_world.py @@ -9,8 +9,6 @@ requirement. This is not typical! This package is intended as a very simple test case, and for that reason we do not want any dependencies. """ -from __future__ import absolute_import, print_function - from rez.package_maker import make_package from rez.version import Version from rez.utils.lint_helper import env diff --git a/src/rez/bind/os.py b/src/rez/bind/os.py index 28fe9d2e0..33af3115b 100644 --- a/src/rez/bind/os.py +++ b/src/rez/bind/os.py @@ -5,7 +5,6 @@ """ Creates the operating system package. """ -from __future__ import absolute_import from rez.package_maker import make_package from rez.version import Version from rez.bind._utils import check_version diff --git a/src/rez/bind/pip.py b/src/rez/bind/pip.py index 416d20b2b..3763011d0 100644 --- a/src/rez/bind/pip.py +++ b/src/rez/bind/pip.py @@ -5,7 +5,6 @@ """ Binds the python pip module as a rez package. """ -from __future__ import absolute_import from rez.bind import _pymodule diff --git a/src/rez/bind/platform.py b/src/rez/bind/platform.py index 5aac37c7c..f998167d5 100644 --- a/src/rez/bind/platform.py +++ b/src/rez/bind/platform.py @@ -5,7 +5,6 @@ """ Creates the system platform package. """ -from __future__ import absolute_import from rez.package_maker import make_package from rez.version import Version from rez.bind._utils import check_version diff --git a/src/rez/bind/python.py b/src/rez/bind/python.py index a9338feb7..0c0f3b036 100644 --- a/src/rez/bind/python.py +++ b/src/rez/bind/python.py @@ -5,7 +5,6 @@ """ Binds a python executable as a rez package. """ -from __future__ import absolute_import from rez.bind._utils import check_version, find_exe, extract_version, \ make_dirs, log, run_python_command from rez.package_maker import make_package diff --git a/src/rez/bind/rez.py b/src/rez/bind/rez.py index 620aeda51..427d31482 100644 --- a/src/rez/bind/rez.py +++ b/src/rez/bind/rez.py @@ -5,7 +5,6 @@ """ Binds rez itself as a rez package. """ -from __future__ import absolute_import import rez from rez.package_maker import make_package from rez.bind._utils import check_version diff --git a/src/rez/bind/rezgui.py b/src/rez/bind/rezgui.py index 844c32ecc..17fa01b81 100644 --- a/src/rez/bind/rezgui.py +++ b/src/rez/bind/rezgui.py @@ -5,7 +5,6 @@ """ Binds rez-gui as a rez package. """ -from __future__ import absolute_import import rez from rez.package_maker import make_package from rez.bind._utils import check_version, make_dirs diff --git a/src/rez/bind/setuptools.py b/src/rez/bind/setuptools.py index d96df211e..61d0d5b7a 100644 --- a/src/rez/bind/setuptools.py +++ b/src/rez/bind/setuptools.py @@ -5,7 +5,6 @@ """ Binds the python setuptools module as a rez package. """ -from __future__ import absolute_import from rez.bind import _pymodule diff --git a/src/rez/bind/sip.py b/src/rez/bind/sip.py index 9e1015e38..980ba51c2 100644 --- a/src/rez/bind/sip.py +++ b/src/rez/bind/sip.py @@ -5,7 +5,6 @@ """ Binds the python PyQt module as a rez package. """ -from __future__ import absolute_import from rez.bind import _pymodule from rez.bind._utils import get_version_in_python diff --git a/src/rez/build_process.py b/src/rez/build_process.py index 42f8fb9ed..c2e006b70 100644 --- a/src/rez/build_process.py +++ b/src/rez/build_process.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - from rez.packages import iter_packages from rez.exceptions import BuildProcessError, BuildContextResolveError, \ ReleaseHookCancellingError, RezError, ReleaseError, BuildError, \ diff --git a/src/rez/cli/_main.py b/src/rez/cli/_main.py index a27de793a..a5a9744f0 100644 --- a/src/rez/cli/_main.py +++ b/src/rez/cli/_main.py @@ -5,8 +5,6 @@ """ The main command-line entry point. """ -from __future__ import print_function - import sys import importlib from argparse import _StoreTrueAction, SUPPRESS diff --git a/src/rez/cli/_util.py b/src/rez/cli/_util.py index d398c7768..917c27777 100644 --- a/src/rez/cli/_util.py +++ b/src/rez/cli/_util.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - import os import sys import signal diff --git a/src/rez/cli/benchmark.py b/src/rez/cli/benchmark.py index d2f1bfbcf..a3a568dd6 100644 --- a/src/rez/cli/benchmark.py +++ b/src/rez/cli/benchmark.py @@ -5,8 +5,6 @@ ''' Run a benchmarking suite for runtime resolves. ''' -from __future__ import print_function - import json import os import os.path diff --git a/src/rez/cli/bind.py b/src/rez/cli/bind.py index 7aca03742..a8fc5d13d 100644 --- a/src/rez/cli/bind.py +++ b/src/rez/cli/bind.py @@ -5,8 +5,6 @@ ''' Create a Rez package for existing software. ''' -from __future__ import print_function - import argparse diff --git a/src/rez/cli/build.py b/src/rez/cli/build.py index d70495a6d..208bab9a5 100644 --- a/src/rez/cli/build.py +++ b/src/rez/cli/build.py @@ -5,8 +5,6 @@ ''' Build a package from source. ''' -from __future__ import print_function - import os diff --git a/src/rez/cli/bundle.py b/src/rez/cli/bundle.py index 39e862841..962c3ab01 100644 --- a/src/rez/cli/bundle.py +++ b/src/rez/cli/bundle.py @@ -5,8 +5,6 @@ ''' Bundle a context and its packages into a relocatable dir. ''' -from __future__ import print_function - import os import os.path import sys diff --git a/src/rez/cli/complete.py b/src/rez/cli/complete.py index 98ffd4c45..7553866fa 100644 --- a/src/rez/cli/complete.py +++ b/src/rez/cli/complete.py @@ -5,8 +5,6 @@ """ Prints package completion strings. """ -from __future__ import print_function - import argparse diff --git a/src/rez/cli/config.py b/src/rez/cli/config.py index 7f7b62986..c04ce1008 100644 --- a/src/rez/cli/config.py +++ b/src/rez/cli/config.py @@ -5,8 +5,6 @@ ''' Print current rez settings. ''' -from __future__ import print_function - import json diff --git a/src/rez/cli/context.py b/src/rez/cli/context.py index 7d8de2bdb..b549c7a9a 100644 --- a/src/rez/cli/context.py +++ b/src/rez/cli/context.py @@ -5,8 +5,6 @@ ''' Print information about the current rez context, or a given context file. ''' -from __future__ import print_function - # Disable the following: # - context tracking # - package caching diff --git a/src/rez/cli/cp.py b/src/rez/cli/cp.py index 7a297c6db..7b9c14231 100644 --- a/src/rez/cli/cp.py +++ b/src/rez/cli/cp.py @@ -5,7 +5,6 @@ ''' Copy a package from one repository to another. ''' -from __future__ import print_function def setup_parser(parser, completions=False): diff --git a/src/rez/cli/depends.py b/src/rez/cli/depends.py index 166487e65..40eb00263 100644 --- a/src/rez/cli/depends.py +++ b/src/rez/cli/depends.py @@ -5,7 +5,6 @@ """ Perform a reverse package dependency lookup. """ -from __future__ import print_function def setup_parser(parser, completions=False): diff --git a/src/rez/cli/env.py b/src/rez/cli/env.py index 7b3d9c964..20cf68edf 100644 --- a/src/rez/cli/env.py +++ b/src/rez/cli/env.py @@ -5,7 +5,6 @@ ''' Open a rez-configured shell, possibly interactive. ''' -from __future__ import print_function def setup_parser(parser, completions=False): diff --git a/src/rez/cli/help.py b/src/rez/cli/help.py index 6421e287f..cc1c9771e 100644 --- a/src/rez/cli/help.py +++ b/src/rez/cli/help.py @@ -5,7 +5,6 @@ """ Utility for displaying help for the given package. """ -from __future__ import print_function def setup_parser(parser, completions=False): diff --git a/src/rez/cli/interpret.py b/src/rez/cli/interpret.py index f4302de37..6c3f4a4d1 100644 --- a/src/rez/cli/interpret.py +++ b/src/rez/cli/interpret.py @@ -5,7 +5,6 @@ ''' Execute some Rex code and print the interpreted result. ''' -from __future__ import print_function def setup_parser(parser, completions=False): diff --git a/src/rez/cli/memcache.py b/src/rez/cli/memcache.py index 42b20cd79..961e2fe6e 100644 --- a/src/rez/cli/memcache.py +++ b/src/rez/cli/memcache.py @@ -5,7 +5,6 @@ """ Manage and query memcache server(s). """ -from __future__ import print_function def setup_parser(parser, completions=False): diff --git a/src/rez/cli/mv.py b/src/rez/cli/mv.py index e02688296..803c6f280 100644 --- a/src/rez/cli/mv.py +++ b/src/rez/cli/mv.py @@ -5,7 +5,6 @@ ''' Move a package from one repository to another. ''' -from __future__ import print_function def setup_parser(parser, completions=False): diff --git a/src/rez/cli/pip.py b/src/rez/cli/pip.py index a91bee8a8..f7f916b97 100644 --- a/src/rez/cli/pip.py +++ b/src/rez/cli/pip.py @@ -5,7 +5,6 @@ """ Install a pip-compatible python package, and its dependencies, as rez packages. """ -from __future__ import print_function from argparse import REMAINDER import logging diff --git a/src/rez/cli/pkg-cache.py b/src/rez/cli/pkg-cache.py index 26a62e871..367b7a0af 100644 --- a/src/rez/cli/pkg-cache.py +++ b/src/rez/cli/pkg-cache.py @@ -5,7 +5,6 @@ ''' Manipulate a package cache. ''' -from __future__ import print_function from argparse import SUPPRESS import os.path import sys diff --git a/src/rez/cli/pkg-ignore.py b/src/rez/cli/pkg-ignore.py index 557b1ca67..0b3dd8261 100644 --- a/src/rez/cli/pkg-ignore.py +++ b/src/rez/cli/pkg-ignore.py @@ -5,7 +5,6 @@ ''' Disable a package so it is hidden from resolves. ''' -from __future__ import print_function def setup_parser(parser, completions=False): diff --git a/src/rez/cli/plugins.py b/src/rez/cli/plugins.py index 93e8265d2..4e26bbd7b 100644 --- a/src/rez/cli/plugins.py +++ b/src/rez/cli/plugins.py @@ -5,7 +5,6 @@ """ Get a list of a package's plugins. """ -from __future__ import print_function def setup_parser(parser, completions=False): diff --git a/src/rez/cli/release.py b/src/rez/cli/release.py index 870fe8b41..275f597ac 100644 --- a/src/rez/cli/release.py +++ b/src/rez/cli/release.py @@ -5,8 +5,6 @@ ''' Build a package from source and deploy it. ''' -from __future__ import print_function - import os import sys from subprocess import call diff --git a/src/rez/cli/rm.py b/src/rez/cli/rm.py index 664152437..6433f0d57 100644 --- a/src/rez/cli/rm.py +++ b/src/rez/cli/rm.py @@ -5,7 +5,6 @@ ''' Remove package(s) from a repository. ''' -from __future__ import print_function import sys diff --git a/src/rez/cli/search.py b/src/rez/cli/search.py index e5d7bf8a4..a0a180d3d 100644 --- a/src/rez/cli/search.py +++ b/src/rez/cli/search.py @@ -5,8 +5,6 @@ """ Search for packages """ -from __future__ import print_function - import os import sys diff --git a/src/rez/cli/suite.py b/src/rez/cli/suite.py index ece3a347a..02f34106b 100644 --- a/src/rez/cli/suite.py +++ b/src/rez/cli/suite.py @@ -5,7 +5,6 @@ ''' Manage a suite or print information about an existing suite. ''' -from __future__ import print_function def setup_parser(parser, completions=False): diff --git a/src/rez/cli/test.py b/src/rez/cli/test.py index b92e967f7..338269a0b 100644 --- a/src/rez/cli/test.py +++ b/src/rez/cli/test.py @@ -5,7 +5,6 @@ ''' Run tests listed in a package's definition file. ''' -from __future__ import print_function def setup_parser(parser, completions=False): diff --git a/src/rez/cli/view.py b/src/rez/cli/view.py index 4b639fb01..6e3cd5804 100644 --- a/src/rez/cli/view.py +++ b/src/rez/cli/view.py @@ -5,7 +5,6 @@ """ View the contents of a package. """ -from __future__ import print_function def setup_parser(parser, completions=False): diff --git a/src/rez/cli/yaml2py.py b/src/rez/cli/yaml2py.py index 9aa958caa..66ee206ee 100644 --- a/src/rez/cli/yaml2py.py +++ b/src/rez/cli/yaml2py.py @@ -5,7 +5,6 @@ """ Print a package.yaml file in package.py format. """ -from __future__ import print_function def setup_parser(parser, completions=False): diff --git a/src/rez/config.py b/src/rez/config.py index ae9e267dc..fe5fb2c89 100644 --- a/src/rez/config.py +++ b/src/rez/config.py @@ -2,7 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import absolute_import from rez import __version__ from rez.utils.data_utils import AttrDictWrapper, RO_AttrDictWrapper, \ convert_dicts, cached_property, cached_class_property, LazyAttributeMeta, \ diff --git a/src/rez/data/tests/builds/packages/anti/1.0.0/build.py b/src/rez/data/tests/builds/packages/anti/1.0.0/build.py index 0bffaa1ea..c636b5cff 100644 --- a/src/rez/data/tests/builds/packages/anti/1.0.0/build.py +++ b/src/rez/data/tests/builds/packages/anti/1.0.0/build.py @@ -1,5 +1,3 @@ -from __future__ import print_function - from build_util import build_directory_recurse, check_visible def build(source_path, build_path, install_path, targets): diff --git a/src/rez/data/tests/builds/packages/bah/2.1/build.py b/src/rez/data/tests/builds/packages/bah/2.1/build.py index ef57ca999..56cabebc4 100644 --- a/src/rez/data/tests/builds/packages/bah/2.1/build.py +++ b/src/rez/data/tests/builds/packages/bah/2.1/build.py @@ -1,4 +1,3 @@ -from __future__ import print_function import os from build_util import build_directory_recurse, check_visible diff --git a/src/rez/data/tests/builds/packages/build_util/1/build.py b/src/rez/data/tests/builds/packages/build_util/1/build.py index d64a1e1e5..0d51f61eb 100644 --- a/src/rez/data/tests/builds/packages/build_util/1/build.py +++ b/src/rez/data/tests/builds/packages/build_util/1/build.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import shutil import os.path diff --git a/src/rez/data/tests/builds/packages/build_util/1/build_util/__init__.py b/src/rez/data/tests/builds/packages/build_util/1/build_util/__init__.py index 6a630e625..a516190d6 100644 --- a/src/rez/data/tests/builds/packages/build_util/1/build_util/__init__.py +++ b/src/rez/data/tests/builds/packages/build_util/1/build_util/__init__.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import shutil import os.path diff --git a/src/rez/data/tests/builds/packages/foo/1.0.0/build.py b/src/rez/data/tests/builds/packages/foo/1.0.0/build.py index 6b4ffa5b8..8ec96549f 100644 --- a/src/rez/data/tests/builds/packages/foo/1.0.0/build.py +++ b/src/rez/data/tests/builds/packages/foo/1.0.0/build.py @@ -1,5 +1,3 @@ -from __future__ import print_function - from build_util import build_directory_recurse, check_visible import os.path import os diff --git a/src/rez/data/tests/builds/packages/foo/1.1.0/build.py b/src/rez/data/tests/builds/packages/foo/1.1.0/build.py index 9503672aa..93981be70 100644 --- a/src/rez/data/tests/builds/packages/foo/1.1.0/build.py +++ b/src/rez/data/tests/builds/packages/foo/1.1.0/build.py @@ -1,5 +1,3 @@ -from __future__ import print_function - from build_util import build_directory_recurse, check_visible import os.path diff --git a/src/rez/data/tests/release/build.py b/src/rez/data/tests/release/build.py index 45c09877f..966915c98 100644 --- a/src/rez/data/tests/release/build.py +++ b/src/rez/data/tests/release/build.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import shutil import os.path import os diff --git a/src/rez/package_bind.py b/src/rez/package_bind.py index d50b1c828..be51c1a52 100644 --- a/src/rez/package_bind.py +++ b/src/rez/package_bind.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - from rez.exceptions import RezBindError, _NeverError from rez import module_root_path from rez.util import get_close_pkgs diff --git a/src/rez/package_help.py b/src/rez/package_help.py index 21411721f..b036dd1ca 100644 --- a/src/rez/package_help.py +++ b/src/rez/package_help.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - from rez.packages import iter_packages from rez.config import config from rez.rex_bindings import VersionBinding diff --git a/src/rez/package_serialise.py b/src/rez/package_serialise.py index 5f905af43..c17b0c0ee 100644 --- a/src/rez/package_serialise.py +++ b/src/rez/package_serialise.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - from rez.serialise import FileFormat from rez.package_resources import help_schema, late_bound from rez.vendor.schema.schema import Schema, Optional, And, Or, Use diff --git a/src/rez/pip.py b/src/rez/pip.py index f21f44b4a..b812ef12e 100644 --- a/src/rez/pip.py +++ b/src/rez/pip.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function, absolute_import - from rez.packages import get_latest_package from rez.version import Version from rez.vendor.distlib.database import DistributionPath diff --git a/src/rez/resolved_context.py b/src/rez/resolved_context.py index 349beadea..a20fcbdf8 100644 --- a/src/rez/resolved_context.py +++ b/src/rez/resolved_context.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - from rez import __version__, module_root_path from rez.package_repository import package_repository_manager from rez.solver import SolverCallbackReturn diff --git a/src/rez/rex.py b/src/rez/rex.py index 1f5d60888..520ce4a7b 100644 --- a/src/rez/rex.py +++ b/src/rez/rex.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - import os import sys import re diff --git a/src/rez/solver.py b/src/rez/solver.py index 9990e6457..104296f99 100644 --- a/src/rez/solver.py +++ b/src/rez/solver.py @@ -11,8 +11,6 @@ See SOLVER.md for an in-depth description of how this module works. """ -from __future__ import print_function - from rez.config import config from rez.packages import iter_packages from rez.package_repository import package_repo_stats diff --git a/src/rez/status.py b/src/rez/status.py index 29949f16c..5be0b9d76 100644 --- a/src/rez/status.py +++ b/src/rez/status.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - import sys import os import os.path diff --git a/src/rez/suite.py b/src/rez/suite.py index d12818847..7b84571e8 100644 --- a/src/rez/suite.py +++ b/src/rez/suite.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - from rez.utils.execution import create_forwarding_script from rez.exceptions import SuiteError, ResolvedContextError from rez.resolved_context import ResolvedContext diff --git a/src/rez/tests/test_shells.py b/src/rez/tests/test_shells.py index 736762286..35f7de76e 100644 --- a/src/rez/tests/test_shells.py +++ b/src/rez/tests/test_shells.py @@ -5,8 +5,6 @@ """ test shell invocation """ -from __future__ import print_function - from rez.system import system from rez.shells import create_shell, get_shell_types, get_shell_class from rez.resolved_context import ResolvedContext diff --git a/src/rez/tests/test_solver.py b/src/rez/tests/test_solver.py index 1244dede5..4c9d44266 100644 --- a/src/rez/tests/test_solver.py +++ b/src/rez/tests/test_solver.py @@ -5,8 +5,6 @@ """ test dependency resolving algorithm """ -from __future__ import print_function - import rez.exceptions from rez.version import Requirement from rez.solver import Solver, Cycle, SolverStatus diff --git a/src/rez/tests/util.py b/src/rez/tests/util.py index 865cd8ec9..dc03c9aa9 100644 --- a/src/rez/tests/util.py +++ b/src/rez/tests/util.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - import unittest from rez import module_root_path from rez.config import config, _create_locked_config diff --git a/src/rez/utils/colorize.py b/src/rez/utils/colorize.py index 4fa3e8900..df0469662 100644 --- a/src/rez/utils/colorize.py +++ b/src/rez/utils/colorize.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - import sys import logging from rez.vendor import colorama diff --git a/src/rez/utils/diff_packages.py b/src/rez/utils/diff_packages.py index 6c47192b8..6e949d00a 100644 --- a/src/rez/utils/diff_packages.py +++ b/src/rez/utils/diff_packages.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - from rez.packages import iter_packages from rez.config import config from rez.plugin_managers import plugin_manager diff --git a/src/rez/utils/filesystem.py b/src/rez/utils/filesystem.py index 568ca6b9d..eb825f972 100644 --- a/src/rez/utils/filesystem.py +++ b/src/rez/utils/filesystem.py @@ -5,8 +5,6 @@ """ Filesystem-related utilities. """ -from __future__ import print_function - from threading import Lock from tempfile import mkdtemp from contextlib import contextmanager diff --git a/src/rez/utils/formatting.py b/src/rez/utils/formatting.py index 9c542339d..89f255c84 100644 --- a/src/rez/utils/formatting.py +++ b/src/rez/utils/formatting.py @@ -5,8 +5,6 @@ """ Utilities related to formatting output or translating input. """ -from __future__ import absolute_import - from string import Formatter from rez.vendor.enum import Enum from rez.version import Requirement diff --git a/src/rez/utils/graph_utils.py b/src/rez/utils/graph_utils.py index 8ff9c902b..0e040b8a1 100644 --- a/src/rez/utils/graph_utils.py +++ b/src/rez/utils/graph_utils.py @@ -5,8 +5,6 @@ """ Functions for manipulating dot-based resolve graphs. """ -from __future__ import print_function - import os.path import sys import tempfile diff --git a/src/rez/utils/installer.py b/src/rez/utils/installer.py index e1931a5fc..c09503c12 100644 --- a/src/rez/utils/installer.py +++ b/src/rez/utils/installer.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - import rez from rez.package_maker import make_package from rez.system import system diff --git a/src/rez/utils/json.py b/src/rez/utils/json.py index 26532e187..079260df1 100644 --- a/src/rez/utils/json.py +++ b/src/rez/utils/json.py @@ -2,7 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import absolute_import import json from json import dumps # noqa (forwarded) import sys diff --git a/src/rez/utils/logging_.py b/src/rez/utils/logging_.py index 201305393..63a33e131 100644 --- a/src/rez/utils/logging_.py +++ b/src/rez/utils/logging_.py @@ -2,7 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function from contextlib import contextmanager import logging import time diff --git a/src/rez/utils/memcached.py b/src/rez/utils/memcached.py index 4f27b183b..ab0945cc9 100644 --- a/src/rez/utils/memcached.py +++ b/src/rez/utils/memcached.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - from rez.config import config from rez.vendor.memcache.memcache import Client as Client_, \ SERVER_MAX_KEY_LENGTH, __version__ as memcache_client_version diff --git a/src/rez/utils/py_dist.py b/src/rez/utils/py_dist.py index 4bdc0e909..c8a96dcaa 100644 --- a/src/rez/utils/py_dist.py +++ b/src/rez/utils/py_dist.py @@ -5,8 +5,6 @@ """ Functions for converting python distributions to rez packages. """ -from __future__ import print_function - from rez.exceptions import RezSystemError import pkg_resources import shutil diff --git a/src/rez/utils/scope.py b/src/rez/utils/scope.py index b889b8a8f..fa694d198 100644 --- a/src/rez/utils/scope.py +++ b/src/rez/utils/scope.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - from rez.utils.formatting import StringFormatMixin, StringFormatType from collections import UserDict import sys diff --git a/src/rez/version/_version.py b/src/rez/version/_version.py index 8658980a2..0dc702e54 100644 --- a/src/rez/version/_version.py +++ b/src/rez/version/_version.py @@ -2,7 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function from rez.version._util import VersionError, ParseException, _Common, \ dedup from bisect import bisect_left diff --git a/src/rez/wrapper.py b/src/rez/wrapper.py index 638297700..8cf0b1f6b 100644 --- a/src/rez/wrapper.py +++ b/src/rez/wrapper.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - from rez.resolved_context import ResolvedContext from rez.utils.colorize import heading, local, critical, Printer from rez.utils.data_utils import cached_property diff --git a/src/rezgui/dialogs/ProcessDialog.py b/src/rezgui/dialogs/ProcessDialog.py index 8dd690ce8..b97ef5177 100644 --- a/src/rezgui/dialogs/ProcessDialog.py +++ b/src/rezgui/dialogs/ProcessDialog.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - from Qt import QtCore, QtWidgets from rezgui.util import create_pane from rezgui.mixins.StoreSizeMixin import StoreSizeMixin diff --git a/src/rezgui/objects/ResolveThread.py b/src/rezgui/objects/ResolveThread.py index 2d94518af..f600e4eb2 100644 --- a/src/rezgui/objects/ResolveThread.py +++ b/src/rezgui/objects/ResolveThread.py @@ -2,8 +2,6 @@ # Copyright Contributors to the Rez Project -from __future__ import print_function - from Qt import QtCore from rez.exceptions import RezError diff --git a/src/rezplugins/build_system/cmake.py b/src/rezplugins/build_system/cmake.py index fdcb55035..6a76d92de 100644 --- a/src/rezplugins/build_system/cmake.py +++ b/src/rezplugins/build_system/cmake.py @@ -5,8 +5,6 @@ """ CMake-based build system """ -from __future__ import print_function - from rez.build_system import BuildSystem from rez.build_process import BuildType from rez.resolved_context import ResolvedContext diff --git a/src/rezplugins/release_hook/amqp.py b/src/rezplugins/release_hook/amqp.py index e0fb860f9..cb3cefc3f 100644 --- a/src/rezplugins/release_hook/amqp.py +++ b/src/rezplugins/release_hook/amqp.py @@ -5,8 +5,6 @@ """ Publishes a message to the broker. """ -from __future__ import print_function - from rez.release_hook import ReleaseHook from rez.utils.logging_ import print_error, print_debug from rez.utils.amqp import publish_message diff --git a/src/rezplugins/release_hook/command.py b/src/rezplugins/release_hook/command.py index 6b2e45731..eca4c1c18 100644 --- a/src/rezplugins/release_hook/command.py +++ b/src/rezplugins/release_hook/command.py @@ -5,8 +5,6 @@ """ Executes pre- and post-release shell commands """ -from __future__ import print_function - import getpass import sys import os diff --git a/src/rezplugins/release_hook/emailer.py b/src/rezplugins/release_hook/emailer.py index e390fcd26..781151470 100644 --- a/src/rezplugins/release_hook/emailer.py +++ b/src/rezplugins/release_hook/emailer.py @@ -5,8 +5,6 @@ """ Sends a post-release email """ -from __future__ import print_function - from rez.release_hook import ReleaseHook from rez.system import system from email.mime.text import MIMEText diff --git a/src/rezplugins/release_vcs/git.py b/src/rezplugins/release_vcs/git.py index 7048b0028..5aa1a59f4 100644 --- a/src/rezplugins/release_vcs/git.py +++ b/src/rezplugins/release_vcs/git.py @@ -5,8 +5,6 @@ """ Git version control """ -from __future__ import print_function - from rez.release_vcs import ReleaseVCS from rez.utils.logging_ import print_error, print_debug from rez.exceptions import ReleaseVCSError diff --git a/src/rezplugins/release_vcs/hg.py b/src/rezplugins/release_vcs/hg.py index 13b8d08f7..ecdcb73c2 100644 --- a/src/rezplugins/release_vcs/hg.py +++ b/src/rezplugins/release_vcs/hg.py @@ -5,8 +5,6 @@ """ Mercurial version control """ -from __future__ import print_function - from rez.release_vcs import ReleaseVCS from rez.exceptions import ReleaseVCSError from rez.utils.logging_ import print_debug, print_error diff --git a/src/rezplugins/release_vcs/stub.py b/src/rezplugins/release_vcs/stub.py index 9a5d64480..41029e527 100644 --- a/src/rezplugins/release_vcs/stub.py +++ b/src/rezplugins/release_vcs/stub.py @@ -5,8 +5,6 @@ """ Stub version control system, for testing purposes """ -from __future__ import print_function - from rez.release_vcs import ReleaseVCS from rez.utils.logging_ import print_warning from rez.utils.yaml import dump_yaml diff --git a/src/rezplugins/release_vcs/svn.py b/src/rezplugins/release_vcs/svn.py index 05beb81ca..df1ab7337 100644 --- a/src/rezplugins/release_vcs/svn.py +++ b/src/rezplugins/release_vcs/svn.py @@ -5,8 +5,6 @@ """ Svn version control """ -from __future__ import print_function - from rez.release_vcs import ReleaseVCS from rez.exceptions import ReleaseVCSError import os.path From ca908037c2044b50cd6dbf79a8760c35a5404807 Mon Sep 17 00:00:00 2001 From: Pavel Vergeev Date: Wed, 14 Feb 2024 20:37:14 +0400 Subject: [PATCH 02/68] Remove the note about Python 2.7 compatibility from the docs (#1644) Signed-off-by: Pavel Vergeev --- docs/source/installation.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/source/installation.rst b/docs/source/installation.rst index a9ef7e622..2dc049f62 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -37,11 +37,6 @@ It is possible to install rez with pip, like so:: ]$ pip install rez -.. note:: - While the ``install.py`` script only supports Python 3.7+, - rez is still usable with Python 2.7 when installed via pip. In other words, the API - is fully compatible with Python 2 and 3. - However, this comes with a caveat. Rez command line tools **are not guaranteed to work correctly** once inside a rez environment (ie after using the :ref:`rez-env` command). The reasons are given in the next section. From 46720fa960f40691370be06579c830e84d4c4de6 Mon Sep 17 00:00:00 2001 From: Jose Enriquez <1145623+Pixel-Minions@users.noreply.github.com> Date: Fri, 16 Feb 2024 16:35:00 -0500 Subject: [PATCH 03/68] Add support for virtualenv in installer (#1645) * Add support for virtualenv in installer Signed-off-by: Jose Enriquez * Run workflows when install script is modified Signed-off-by: Jean-Christophe Morin --------- Signed-off-by: Jose Enriquez Signed-off-by: Jean-Christophe Morin Co-authored-by: Jean-Christophe Morin --- .github/workflows/installation.yaml | 8 ++++++ .github/workflows/tests.yaml | 8 ++++++ install.py | 44 +++++++++++++++++++++++------ 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/.github/workflows/installation.yaml b/.github/workflows/installation.yaml index 6d635d9fb..0a2425fcf 100644 --- a/.github/workflows/installation.yaml +++ b/.github/workflows/installation.yaml @@ -3,12 +3,20 @@ on: pull_request: paths: - 'src/**' + - 'install.py' + - 'setup.py' + - 'MANIFEST.in' + - 'pyproject.toml' - '.github/workflows/installation.yaml' - '!src/rez/utils/_version.py' - '!**.md' push: paths: - 'src/**' + - 'install.py' + - 'setup.py' + - 'MANIFEST.in' + - 'pyproject.toml' - '.github/workflows/installation.yaml' - '!src/rez/utils/_version.py' - '!**.md' diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index dc4fc0f0b..097c56be1 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -3,12 +3,20 @@ on: pull_request: paths: - 'src/**' + - 'install.py' + - 'setup.py' + - 'MANIFEST.in' + - 'pyproject.toml' - '.github/workflows/tests.yaml' - '!src/rez/utils/_version.py' - '!**.md' push: paths: - 'src/**' + - 'install.py' + - 'setup.py' + - 'MANIFEST.in' + - 'pyproject.toml' - '.github/workflows/tests.yaml' - '!src/rez/utils/_version.py' - '!**.md' diff --git a/install.py b/install.py index 78bff3550..43b7c81cc 100644 --- a/install.py +++ b/install.py @@ -8,10 +8,17 @@ """ import argparse import os +import platform import sys import shutil import subprocess -import venv + +USE_VIRTUALENV = False +try: + import venv +except ImportError: + USE_VIRTUALENV = True + import virtualenv source_path = os.path.dirname(os.path.realpath(__file__)) @@ -27,15 +34,36 @@ from rez.vendor.distlib.scripts import ScriptMaker # noqa: E402 -def create_virtual_environment(dest_dir): - builder = venv.EnvBuilder(with_pip=True) - builder.create(dest_dir) +def create_virtual_environment(dest_dir: str) -> None: + """Create a virtual environment in the given directory. + + Args: + dest_dir (str): Full path to the virtual environment directory. + + """ + if USE_VIRTUALENV: + try: + subprocess.run( + [sys.executable, "-m", "virtualenv", dest_dir], + check=True + ) + except subprocess.CalledProcessError as err: + print(f"Failed to create virtual environment: {err}") + sys.exit(1) + else: + builder = venv.EnvBuilder(with_pip=True) + builder.create(dest_dir) + + +def get_virtualenv_bin_dir(dest_dir: str) -> str: + """Get the bin directory of the virtual environment. + Args: + dest_dir (str): The directory of the virtual environment. -def get_virtualenv_bin_dir(dest_dir): - builder = venv.EnvBuilder() - context = builder.ensure_directories(dest_dir) - return context.bin_path + """ + bin_dir = "Scripts" if platform.system() == "Windows" else "bin" + return os.path.join(dest_dir, bin_dir) def get_virtualenv_py_executable(dest_dir): From 3ce72ac0d9cf6980d3bea64c1e249590c24aaa33 Mon Sep 17 00:00:00 2001 From: predat Date: Sat, 17 Feb 2024 15:49:03 +0000 Subject: [PATCH 04/68] Remove rez.vendor.enum (#1649) Signed-off-by: predat --- src/rez/build_process.py | 2 +- src/rez/developer_package.py | 2 +- src/rez/pip.py | 2 +- src/rez/release_hook.py | 2 +- src/rez/resolved_context.py | 2 +- src/rez/resolver.py | 2 +- src/rez/rex.py | 2 +- src/rez/serialise.py | 2 +- src/rez/solver.py | 2 +- src/rez/utils/execution.py | 2 +- src/rez/utils/formatting.py | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/rez/build_process.py b/src/rez/build_process.py index c2e006b70..a7d3e280d 100644 --- a/src/rez/build_process.py +++ b/src/rez/build_process.py @@ -12,8 +12,8 @@ from rez.release_hook import create_release_hooks from rez.resolver import ResolverStatus from rez.config import config -from rez.vendor.enum import Enum from contextlib import contextmanager +from enum import Enum from shlex import quote import getpass import os.path diff --git a/src/rez/developer_package.py b/src/rez/developer_package.py index bbb9ac516..820576f6d 100644 --- a/src/rez/developer_package.py +++ b/src/rez/developer_package.py @@ -9,8 +9,8 @@ from rez.utils.execution import add_sys_paths from rez.utils.sourcecode import SourceCode from rez.utils.logging_ import print_info, print_error -from rez.vendor.enum import Enum from inspect import isfunction +from enum import Enum import os.path import stat diff --git a/src/rez/pip.py b/src/rez/pip.py index b812ef12e..1703bb567 100644 --- a/src/rez/pip.py +++ b/src/rez/pip.py @@ -5,7 +5,6 @@ from rez.packages import get_latest_package from rez.version import Version from rez.vendor.distlib.database import DistributionPath -from rez.vendor.enum.enum import Enum from rez.vendor.packaging.version import Version as PackagingVersion from rez.vendor.packaging.specifiers import Specifier from rez.resolved_context import ResolvedContext @@ -22,6 +21,7 @@ import os from shlex import quote from pprint import pformat +from enum import Enum import re import shutil import subprocess diff --git a/src/rez/release_hook.py b/src/rez/release_hook.py index 15fbf6f09..61c3a86d6 100644 --- a/src/rez/release_hook.py +++ b/src/rez/release_hook.py @@ -4,7 +4,7 @@ from rez.utils.logging_ import print_warning, print_debug from rez.packages import get_developer_package -from rez.vendor.enum import Enum +from enum import Enum def get_release_hook_types(): diff --git a/src/rez/resolved_context.py b/src/rez/resolved_context.py index a20fcbdf8..c8cb5eff2 100644 --- a/src/rez/resolved_context.py +++ b/src/rez/resolved_context.py @@ -35,7 +35,6 @@ from rez.utils.resolve_graph import failure_detail_from_graph from rez.version import VersionRange from rez.version import Requirement -from rez.vendor.enum import Enum from rez.vendor import yaml from rez.utils import json from rez.utils.yaml import dump_yaml @@ -43,6 +42,7 @@ from contextlib import contextmanager from functools import wraps +from enum import Enum import getpass import socket import threading diff --git a/src/rez/resolver.py b/src/rez/resolver.py index 5fb999525..921871ce6 100644 --- a/src/rez/resolver.py +++ b/src/rez/resolver.py @@ -9,9 +9,9 @@ from rez.utils.memcached import memcached_client, pool_memcached_connections from rez.utils.logging_ import log_duration from rez.config import config -from rez.vendor.enum import Enum from rez.version import Requirement from contextlib import contextmanager +from enum import Enum from hashlib import sha1 diff --git a/src/rez/rex.py b/src/rez/rex.py index 520ce4a7b..6086db5b4 100644 --- a/src/rez/rex.py +++ b/src/rez/rex.py @@ -7,6 +7,7 @@ import re import traceback from fnmatch import fnmatch +from enum import Enum from contextlib import contextmanager from string import Formatter from collections.abc import MutableMapping @@ -22,7 +23,6 @@ from rez.utils.data_utils import AttrDictWrapper from rez.utils.formatting import expandvars from rez.utils.platform_ import platform_ -from rez.vendor.enum import Enum #=============================================================================== diff --git a/src/rez/serialise.py b/src/rez/serialise.py index 4fcfcf9f4..da46b78b5 100644 --- a/src/rez/serialise.py +++ b/src/rez/serialise.py @@ -6,6 +6,7 @@ Read and write data from file. File caching via a memcached server is supported. """ from contextlib import contextmanager +from enum import Enum from inspect import isfunction, ismodule import sys import stat @@ -25,7 +26,6 @@ from rez.utils import py23 from rez.config import config from rez.vendor.atomicwrites import atomic_write -from rez.vendor.enum import Enum from rez.vendor import yaml diff --git a/src/rez/solver.py b/src/rez/solver.py index 104296f99..f7652cf5d 100644 --- a/src/rez/solver.py +++ b/src/rez/solver.py @@ -23,8 +23,8 @@ PackageFamilyNotFoundError, RezSystemError from rez.version import VersionRange from rez.version import VersionedObject, Requirement, RequirementList -from rez.vendor.enum import Enum from contextlib import contextmanager +from enum import Enum from itertools import product, chain import copy import time diff --git a/src/rez/utils/execution.py b/src/rez/utils/execution.py index edf1b7c34..2ae5e8052 100644 --- a/src/rez/utils/execution.py +++ b/src/rez/utils/execution.py @@ -7,8 +7,8 @@ """ from rez.utils.yaml import dump_yaml -from rez.vendor.enum import Enum from contextlib import contextmanager +from enum import Enum import subprocess import sys import stat diff --git a/src/rez/utils/formatting.py b/src/rez/utils/formatting.py index 89f255c84..3f9c3587d 100644 --- a/src/rez/utils/formatting.py +++ b/src/rez/utils/formatting.py @@ -6,10 +6,10 @@ Utilities related to formatting output or translating input. """ from string import Formatter -from rez.vendor.enum import Enum from rez.version import Requirement from rez.exceptions import PackageRequestError from pprint import pformat +from enum import Enum import os import os.path import re From 9c8de335b55505463f74701b4da65b373c9e32ff Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> Date: Sat, 17 Feb 2024 15:32:17 -0500 Subject: [PATCH 05/68] Add clear information on how to contact project maintainers (#1659) Signed-off-by: Jean-Christophe Morin --- README.md | 12 +++++++++++- docs/source/index.rst | 9 +++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4e481622e..cd8cfc16f 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,17 @@ like any other package: * Has a package filtering feature, allowing for staged package releases such as alpha and beta packages. +## You have a problem or want to talk to us? + +If you find a bug, need help, or want to talk to the developers, here is a list of the different +ways to get in touch with us: + +* [Report an issue](https://github.com/AcademySoftwareFoundation/rez/issues) +* [Chat room](https://slack.aswf.io): Join the ``#rez`` channel +* [Start a discussion](https://github.com/AcademySoftwareFoundation/rez/discussions) +* [Mailing list](mail:main@lists.aswf.io): Note that are way less active on the mailing + list than on any other communication channel. + ## Known issues and limitations * Currently CMake builds do not function on Windows with Rez and @@ -214,4 +225,3 @@ like any other package: the roadmap. Users have successfully implemented workarounds to utilize CMake with Rez under Windows, but the goal is to provide a seamless experience on any platform in the future. For details see this [issue](/../../issues/703) - diff --git a/docs/source/index.rst b/docs/source/index.rst index 5e80eb08d..12196b605 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -79,3 +79,12 @@ Rez: Rez takes a list of package requests, and constructs the target environment, resolving all the necessary package dependencies. Any type of software package is supported - compiled, python, applications and libraries. + +If you find a bug, need help, or want to talk to the developers, here is a list of the different +ways to get in touch with us: + +* `Report an issue `_ +* `Chat room `_: Join the ``#rez`` channel +* `Start a discussion `_ +* `Mailing list `_: Note that are way less active on the mailing + list than on any other communication channel. From fb02c4aa0c7654565154e32bbdca746909cfec3d Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> Date: Tue, 20 Feb 2024 19:21:31 -0500 Subject: [PATCH 06/68] Improve install docs by mentioning how to actually download rez (#1660) Signed-off-by: Jean-Christophe Morin --- docs/source/installation.rst | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 2dc049f62..acef065ad 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -5,15 +5,20 @@ Installation Installation Script =================== -.. warning:: - The install script only supports Python 3.7+. +To install rez, you will need: + +1. Python 3.7 or above. We support 3.7, 3.8, 3.9, 3.10 and 3.11. + The python interpreter you use to run the install script will be the interpreter + used by rez itself. +2. The source code. You can get it by either cloning the `repository `_ + with git or downloading it from the `latest release `_. + If you download rez from the release page on GitHub, don't forget to unpack the downloaded archive. -To install rez, download the source. Then from the root directory, run:: +Then from the root directory, run:: ]$ python ./install.py -This installs rez to ``/opt/rez``. See ```install.py -h``` for how to install to a -different location. +This installs rez to ``/opt/rez``. Use ``install.py -h`` to see the different install options. Once the installation is complete, a message tells you how to run it:: From 8d56142e3a09a4d57e8de13138ab27406da52622 Mon Sep 17 00:00:00 2001 From: BryceGattis <36783788+BryceGattis@users.noreply.github.com> Date: Fri, 1 Mar 2024 11:45:12 -0600 Subject: [PATCH 07/68] Remove rez.backport (#1634) Signed-off-by: Bryce Gattis --- src/rez/backport/__init__.py | 1 - src/rez/backport/importlib.py | 37 ----- src/rez/backport/lru_cache.py | 136 ------------------ src/rez/backport/ordereddict.py | 1 - src/rez/backport/zipfile.py | 1 - src/rez/cli/complete.py | 2 +- src/rez/cli/forward.py | 2 +- src/rez/config.py | 2 +- src/rez/plugin_managers.py | 2 +- src/rez/utils/resources.py | 3 +- .../package_repository/filesystem.py | 2 +- 11 files changed, 7 insertions(+), 182 deletions(-) delete mode 100644 src/rez/backport/__init__.py delete mode 100644 src/rez/backport/importlib.py delete mode 100644 src/rez/backport/lru_cache.py delete mode 100644 src/rez/backport/ordereddict.py delete mode 100644 src/rez/backport/zipfile.py diff --git a/src/rez/backport/__init__.py b/src/rez/backport/__init__.py deleted file mode 100644 index 8b1378917..000000000 --- a/src/rez/backport/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/rez/backport/importlib.py b/src/rez/backport/importlib.py deleted file mode 100644 index df4abfe54..000000000 --- a/src/rez/backport/importlib.py +++ /dev/null @@ -1,37 +0,0 @@ -"""Backport of importlib.import_module from 3.x.""" -import sys - - -def _resolve_name(name, package, level): - """Return the absolute name of the module to be imported.""" - if not hasattr(package, 'rindex'): - raise ValueError("'package' not set to a string") - dot = len(package) - for x in xrange(level, 1, -1): - try: - dot = package.rindex('.', 0, dot) - except ValueError: - raise ValueError("attempted relative import beyond top-level " - "package") - return "%s.%s" % (package[:dot], name) - - -def import_module(name, package=None): - """Import a module. - - The 'package' argument is required when performing a relative import. It - specifies the package to use as the anchor point from which to resolve the - relative import to an absolute import. - - """ - if name.startswith('.'): - if not package: - raise TypeError("relative imports require the 'package' argument") - level = 0 - for character in name: - if character != '.': - break - level += 1 - name = _resolve_name(name[level:], package, level) - __import__(name) - return sys.modules[name] diff --git a/src/rez/backport/lru_cache.py b/src/rez/backport/lru_cache.py deleted file mode 100644 index 11028f638..000000000 --- a/src/rez/backport/lru_cache.py +++ /dev/null @@ -1,136 +0,0 @@ -""" -This lru cache implementation is based on the backport of the pure python lru -cache in Python 3 and found on the ActiveState website: - -http://code.activestate.com/recipes/578078-py26-and-py30-backport-of-python-33s-lru-cache/ - -It has been modified to remove the cache info (data on cache hits and misses) -and implementt a simplified _make_key method. Both of these give modest -improvements in performance, reducing the time spent in the wrapper function by -~30-40%. Both of theses changes are based on discussions in the Python bug -tracker: - -http://bugs.python.org/issue16389 -http://bugs.python.org/issue14373 -""" - - -from functools import update_wrapper -from threading import RLock - - -def _make_key(args, kwds): - return (args, frozenset(kwds.items())) - - -def lru_cache(maxsize=100): - """Least-recently-used cache decorator. - - If *maxsize* is set to None, the LRU features are disabled and the cache - can grow without bound. - - Arguments to the cached function must be hashable. - - View the cache statistics named tuple (hits, misses, maxsize, currsize) with - f.cache_info(). Clear the cache and statistics with f.cache_clear(). - Access the underlying function with f.__wrapped__. - - See: http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used - - """ - - # Users should only access the lru_cache through its public API: - # cache_info, cache_clear, and f.__wrapped__ - # The internals of the lru_cache are encapsulated for thread safety and - # to allow the implementation to change (including a possible C version). - - def decorating_function(user_function): - - cache = dict() - make_key = _make_key - cache_get = cache.get # bound method to lookup key or return None - _len = len # localize the global len() function - lock = RLock() # because linkedlist updates aren't threadsafe - root = [] # root of the circular doubly linked list - root[:] = [root, root, None, None] # initialize by pointing to self - nonlocal_root = [root] # make updateable non-locally - PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields - - if maxsize == 0: - - def wrapper(*args, **kwds): - # no caching, just do a statistics update after a successful call - result = user_function(*args, **kwds) - return result - - elif maxsize is None: - - def wrapper(*args, **kwds): - # simple caching without ordering or size limit - key = make_key(args, kwds) - result = cache_get(key, root) # root used here as a unique not-found sentinel - if result is not root: - return result - result = user_function(*args, **kwds) - cache[key] = result - return result - - else: - - def wrapper(*args, **kwds): - # size limited caching that tracks accesses by recency - key = make_key(args, kwds) - with lock: - link = cache_get(key) - if link is not None: - # record recent use of the key by moving it to the front of the list - root, = nonlocal_root - link_prev, link_next, key, result = link - link_prev[NEXT] = link_next - link_next[PREV] = link_prev - last = root[PREV] - last[NEXT] = root[PREV] = link - link[PREV] = last - link[NEXT] = root - return result - result = user_function(*args, **kwds) - with lock: - root, = nonlocal_root - if key in cache: - # getting here means that this same key was added to the - # cache while the lock was released. since the link - # update is already done, we need only return the - # computed result and update the count of misses. - pass - elif _len(cache) >= maxsize: - # use the old root to store the new key and result - oldroot = root - oldroot[KEY] = key - oldroot[RESULT] = result - # empty the oldest link and make it the new root - root = nonlocal_root[0] = oldroot[NEXT] - oldkey = root[KEY] - oldvalue = root[RESULT] - root[KEY] = root[RESULT] = None - # now update the cache dictionary for the new links - del cache[oldkey] - cache[key] = oldroot - else: - # put result in a new link at the front of the list - last = root[PREV] - link = [last, root, key, result] - last[NEXT] = root[PREV] = cache[key] = link - return result - - def cache_clear(): - """Clear the cache and cache statistics""" - with lock: - cache.clear() - root = nonlocal_root[0] - root[:] = [root, root, None, None] - - wrapper.__wrapped__ = user_function - wrapper.cache_clear = cache_clear - return update_wrapper(wrapper, user_function) - - return decorating_function diff --git a/src/rez/backport/ordereddict.py b/src/rez/backport/ordereddict.py deleted file mode 100644 index b7613b042..000000000 --- a/src/rez/backport/ordereddict.py +++ /dev/null @@ -1 +0,0 @@ -from collections import OrderedDict diff --git a/src/rez/backport/zipfile.py b/src/rez/backport/zipfile.py deleted file mode 100644 index 09624f902..000000000 --- a/src/rez/backport/zipfile.py +++ /dev/null @@ -1 +0,0 @@ -from zipfile import * diff --git a/src/rez/cli/complete.py b/src/rez/cli/complete.py index 7553866fa..8a10d4b15 100644 --- a/src/rez/cli/complete.py +++ b/src/rez/cli/complete.py @@ -81,7 +81,7 @@ def _pop_arg(l, p): comp_point += len(s) # create parser for subcommand - from rez.backport.importlib import import_module + from importlib import import_module data = subcommands[subcommand] module_name = data.get("module_name", "rez.cli.%s" % subcommand) mod = import_module(module_name) diff --git a/src/rez/cli/forward.py b/src/rez/cli/forward.py index 54c1e9160..be725b153 100644 --- a/src/rez/cli/forward.py +++ b/src/rez/cli/forward.py @@ -53,7 +53,7 @@ def command(opts, parser, extra_arg_groups=None): if isinstance(doc["module"], str): # refers to a rez module - from rez.backport.importlib import import_module + from importlib import import_module namespace = "rez.%s" % doc["module"] module = import_module(namespace) else: diff --git a/src/rez/config.py b/src/rez/config.py index fe5fb2c89..4e870cc22 100644 --- a/src/rez/config.py +++ b/src/rez/config.py @@ -15,9 +15,9 @@ from rez.vendor.schema.schema import Schema, SchemaError, And, Or, Use from rez.vendor import yaml from rez.vendor.yaml.error import YAMLError -from rez.backport.lru_cache import lru_cache import rez.deprecations from contextlib import contextmanager +from functools import lru_cache from inspect import ismodule import os import re diff --git a/src/rez/plugin_managers.py b/src/rez/plugin_managers.py index 8d647f0a6..64b1d8f09 100644 --- a/src/rez/plugin_managers.py +++ b/src/rez/plugin_managers.py @@ -110,7 +110,7 @@ def register_plugin(self, plugin_name, plugin_class, plugin_module): def load_plugins(self): import pkgutil - from rez.backport.importlib import import_module + from importlib import import_module type_module_name = 'rezplugins.' + self.type_name package = import_module(type_module_name) diff --git a/src/rez/utils/resources.py b/src/rez/utils/resources.py index 5d70d720d..372d1455f 100644 --- a/src/rez/utils/resources.py +++ b/src/rez/utils/resources.py @@ -33,11 +33,12 @@ See the 'pets' unit test in tests/test_resources.py for a complete example. """ +from functools import lru_cache + from rez.utils.data_utils import cached_property, AttributeForwardMeta, \ LazyAttributeMeta from rez.config import config from rez.exceptions import ResourceError -from rez.backport.lru_cache import lru_cache from rez.utils.logging_ import print_debug diff --git a/src/rezplugins/package_repository/filesystem.py b/src/rezplugins/package_repository/filesystem.py index 324570184..5dae0d24a 100644 --- a/src/rezplugins/package_repository/filesystem.py +++ b/src/rezplugins/package_repository/filesystem.py @@ -6,6 +6,7 @@ Filesystem-based package repository """ from contextlib import contextmanager +from functools import lru_cache import os.path import os import stat @@ -32,7 +33,6 @@ from rez.utils.platform_ import platform_ from rez.utils.yaml import load_yaml from rez.config import config -from rez.backport.lru_cache import lru_cache from rez.vendor.schema.schema import Schema, Optional, And, Use, Or from rez.version import Version, VersionRange From 91db53729019a9e2358b5ab79291ddaed692e69c Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> Date: Fri, 1 Mar 2024 16:13:51 -0500 Subject: [PATCH 08/68] Upload test coverage to Codecov (#1671) Signed-off-by: Jean-Christophe Morin --- .coveragerc | 4 +++- .github/workflows/tests.yaml | 10 +++++++++- .gitignore | 1 + .sonarcloud.properties | 3 +-- README.md | 1 + codecov.yml | 11 +++++++++++ pytest.ini | 2 -- src/rez/cli/selftest.py | 15 +++++---------- 8 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 codecov.yml delete mode 100644 pytest.ini diff --git a/.coveragerc b/.coveragerc index 33b623e81..a08a4ca56 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,6 +1,8 @@ [run] +# Relative is needed for coverage to be merged by SonarCloud +relative_files = True branch = True omit = src/rez/tests/*, src/rez/completion/*, - src/rez/vendor/* \ No newline at end of file + src/rez/vendor/* diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 097c56be1..37b23583d 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -83,6 +83,14 @@ jobs: run: rez-python -m pip install pytest-cov parameterized - name: Run tests - run: rez-selftest -v + run: rez-selftest -v -- --cov=rez --cov-report=xml:coverage.xml env: _REZ_ENSURE_TEST_SHELLS: ${{ matrix.shells }} + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v4 + with: + slug: AcademySoftwareFoundation/rez + files: 'coverage.xml' + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore index 6e77c10b4..09eebc709 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ build/ dist/ htmlcov/ .coverage +coverage.xml *~ docs/_build .DS_Store diff --git a/.sonarcloud.properties b/.sonarcloud.properties index baf07821e..9efdc32b4 100644 --- a/.sonarcloud.properties +++ b/.sonarcloud.properties @@ -25,5 +25,4 @@ sonar.projectName=rez # Source properties sonar.sources=src -sonar.exclusions=src/build_utils/**,src/rez/backport/**,src/rez/data/**,src/rez/tests/**,src/rez/vendor/** - +sonar.exclusions=src/build_utils/**,src/rez/data/**,src/rez/tests/**,src/rez/vendor/** diff --git a/README.md b/README.md index cd8cfc16f..30bfda1fb 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ [![Docs](https://readthedocs.org/projects/rez/badge/?version=stable)](https://rez.readthedocs.io/en/stable) [![PyPI](https://github.com/AcademySoftwareFoundation/rez/workflows/pypi/badge.svg)](https://github.com/AcademySoftwareFoundation/rez/actions?query=workflow%3Apypi+event%3Arelease) [![Benchmark](https://github.com/AcademySoftwareFoundation/rez/workflows/benchmark/badge.svg)](https://github.com/AcademySoftwareFoundation/rez/actions?query=workflow%3Abenchmark+event%3Arelease)
+[![Coverage](https://codecov.io/gh/AcademySoftwareFoundation/rez/graph/badge.svg?token=FLYggQOE7W)](https://codecov.io/gh/AcademySoftwareFoundation/rez) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=AcademySoftwareFoundation_rez&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=AcademySoftwareFoundation_rez) [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=AcademySoftwareFoundation_rez&metric=bugs)](https://sonarcloud.io/summary/new_code?id=AcademySoftwareFoundation_rez) [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=AcademySoftwareFoundation_rez&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=AcademySoftwareFoundation_rez) diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 000000000..90ff2e0a5 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,11 @@ +coverage: + status: + project: off + +github_checks: + annotations: false + +ignore: + - "src/rez/tests" + - "src/rez/vendor" + - "src/rez/completion" diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index d87389e84..000000000 --- a/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -addopts = --cov=src/rez --cov-report=html --cov-config=.coveragerc \ No newline at end of file diff --git a/src/rez/cli/selftest.py b/src/rez/cli/selftest.py index d99cb8d71..ec4d0e39d 100644 --- a/src/rez/cli/selftest.py +++ b/src/rez/cli/selftest.py @@ -94,14 +94,7 @@ def command(opts, parser, extra_arg_groups=None): try: if use_pytest: - cwd = os.getcwd() - os.chdir(tests_dir) - try: - run_pytest(module_tests, opts.tests, opts.verbose, - extra_arg_groups) - finally: - os.chdir(cwd) - + run_pytest(module_tests, opts.tests, opts.verbose, extra_arg_groups) else: run_unittest(module_tests, opts.tests, opts.verbose) finally: @@ -121,6 +114,8 @@ def run_unittest(module_tests, tests, verbosity): def run_pytest(module_tests, tests, verbosity, extra_arg_groups): from pytest import main + tests_dir = os.path.abspath(os.path.join(__file__, "..", "..", "tests")) + # parse test name, e.g. # "rez.tests.test_solver.TestSolver.test_01" # into @@ -133,11 +128,11 @@ def run_pytest(module_tests, tests, verbosity, extra_arg_groups): specifier += "::" + part continue if os.path.isfile(part + ".py"): - specifier = part + ".py" + specifier = os.path.join(tests_dir, f"{part}.py") if specifier: test_specifications.append(specifier) - module_tests = [("test_%s.py" % x) for x in sorted(module_tests)] + module_tests = [os.path.join(tests_dir, f"test_{x}.py") for x in sorted(module_tests)] tests = module_tests + test_specifications argv = tests[:] From 5d82dd04414dbe7776991e2328247991deefd65b Mon Sep 17 00:00:00 2001 From: BryceGattis <36783788+BryceGattis@users.noreply.github.com> Date: Mon, 4 Mar 2024 20:36:53 -0600 Subject: [PATCH 09/68] Remove Python 2 support for utils/json.py (#1673) * Delete rez/utils/json.py --------- Signed-off-by: Bryce Gattis --- src/rez/config.py | 2 +- src/rez/package_cache.py | 2 +- src/rez/resolved_context.py | 2 +- src/rez/utils/amqp.py | 2 +- src/rez/utils/json.py | 39 ------------------------------------- 5 files changed, 4 insertions(+), 43 deletions(-) delete mode 100644 src/rez/utils/json.py diff --git a/src/rez/config.py b/src/rez/config.py index 4e870cc22..e8542d1ed 100644 --- a/src/rez/config.py +++ b/src/rez/config.py @@ -112,7 +112,7 @@ def _validate(self, data): pre_formatted=True, filename=varname, ) - from rez.utils import json + import json try: return json.loads(value) diff --git a/src/rez/package_cache.py b/src/rez/package_cache.py index 5a4733309..e17b2c782 100644 --- a/src/rez/package_cache.py +++ b/src/rez/package_cache.py @@ -2,6 +2,7 @@ # Copyright Contributors to the Rez Project +import json import os import os.path import errno @@ -21,7 +22,6 @@ from rez.config import config from rez.exceptions import PackageCacheError from rez.vendor.lockfile import LockFile, NotLocked -from rez.utils import json from rez.utils.filesystem import safe_listdir, safe_makedirs, safe_remove, \ forceful_rmtree from rez.utils.colorize import ColorizedStreamHandler diff --git a/src/rez/resolved_context.py b/src/rez/resolved_context.py index c8cb5eff2..bbf68fef0 100644 --- a/src/rez/resolved_context.py +++ b/src/rez/resolved_context.py @@ -36,7 +36,6 @@ from rez.version import VersionRange from rez.version import Requirement from rez.vendor import yaml -from rez.utils import json from rez.utils.yaml import dump_yaml from rez.utils.platform_ import platform_ @@ -44,6 +43,7 @@ from functools import wraps from enum import Enum import getpass +import json import socket import threading import time diff --git a/src/rez/utils/amqp.py b/src/rez/utils/amqp.py index 0f24b1eae..c26e875f7 100644 --- a/src/rez/utils/amqp.py +++ b/src/rez/utils/amqp.py @@ -3,6 +3,7 @@ import atexit +import json import socket import time import threading @@ -10,7 +11,6 @@ import urllib.parse import queue -from rez.utils import json from rez.utils.logging_ import print_error from rez.vendor.pika.adapters.blocking_connection import BlockingConnection from rez.vendor.pika.connection import ConnectionParameters diff --git a/src/rez/utils/json.py b/src/rez/utils/json.py deleted file mode 100644 index 079260df1..000000000 --- a/src/rez/utils/json.py +++ /dev/null @@ -1,39 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright Contributors to the Rez Project - - -import json -from json import dumps # noqa (forwarded) -import sys - - -if sys.version_info.major >= 3: - - def loads(data): - return json.loads(data) - -# py2 -else: - - def loads(json_text): - """Avoids returning unicodes in py2. - - https://stackoverflow.com/questions/956867/how-to-get-string-objects-instead-of-unicode-from-json - """ - def _byteify(input, ignore_dicts=False): - if isinstance(input, list): - return [_byteify(x) for x in input] - elif isinstance(input, unicode): - try: - return str(input) - except UnicodeEncodeError: - return input - elif isinstance(input, dict) and not ignore_dicts: - return { - _byteify(k, ignore_dicts=True): _byteify(v, True) - for k, v in input.items() - } - else: - return input - - return _byteify(json.loads(json_text, object_hook=_byteify)) From 153bd87c8a983e5902b92abd3487c2f3357dbc5b Mon Sep 17 00:00:00 2001 From: BryceGattis <36783788+BryceGattis@users.noreply.github.com> Date: Tue, 5 Mar 2024 18:55:45 -0600 Subject: [PATCH 10/68] Add development environment docs (#1633) Signed-off-by: Bryce Gattis --- CONTRIBUTING.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fc1dbd542..83b5a85a1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,7 @@ # Contributing To Rez +## Guidelines + If you would like to contribute code you can do so through GitHub by forking the repository and sending a pull request. Please follow these guidelines: @@ -21,6 +23,45 @@ sending a pull request. Please follow these guidelines: document the setting. The comments in this file are extracted and turned into documentation. Pay attention to the comment formatting and follow the existing style closely. +## Development Environment + +### Prerequisites + +On Windows, make sure to set your PowerShell execution policy as shown [here](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-5.1), +otherwise the PowerShell tests will fail. + +### Setting Up + +To begin development on rez you'll first need to set up your development environment. There are many +ways you can do it, but these are the recommended approaches. + +This first approach will automatically create a virtual environment for you, patch the Rez binaries, +and copy completion scripts. All tests will be run this way. + +1. Fork the repo and clone it. +2. Create a new Git branch and check it out. +3. Install your local rez code by running `python install.py venv`. +4. Activate the virtual environment by running the `activate` file. +5. Add the `Scripts/rez` folder on Windows or the `bin/rez` folder on Mac/Linux to the `PATH` environment variable. + +There is an alternative method of setting up your development environment, that doesn't use the `install.py` +script. Please note that not all tests will be run if rez is installed this way. + +1. Fork the repo and clone it. +2. Create a new Git branch and check it out. +3. Create a virtual environment in the same directory as the repo by running `python -m venv venv`. +4. Activate the virtual environment by running the `activate` file. +5. Pip install your local rez code by running `pip install .`. + +Additionally, if you are going to run tests in the repo, you may want to install two additional optional +packages for improved test output: `pytest` and `parameterized`. You can install these by running +`pip install pytest parameterized`. + +### Running Tests + +1. Set up your development environment as shown above. +2. Run `rez selftest`. + ## CLA Rez enforces use of a Contributor License Agreement as per ASWF guidelines. You need only sign up to the EasyCLA system once, but until you do, your PRs will be automatically blocked. From dc2c77757748e87d2abf0967924ee0195aa0f11d Mon Sep 17 00:00:00 2001 From: wandth <34237282+wandth@users.noreply.github.com> Date: Fri, 8 Mar 2024 11:04:50 +0800 Subject: [PATCH 11/68] Remove rez.utils.py23 and cleanup more python 2.7 leftovers (#1678) * remove rez.utils.py23 module * remove some more __nonzero__ methods --------- Signed-off-by: wwn <1506514799@qq.com> --- src/rez/cli/forward.py | 4 +- src/rez/package_cache.py | 11 +-- src/rez/package_filter.py | 8 +-- src/rez/rex.py | 4 +- src/rez/serialise.py | 4 +- src/rez/solver.py | 4 +- .../{test_utils_py23.py => test_util.py} | 12 ++-- src/rez/util.py | 32 +++++++++ src/rez/utils/logging_.py | 4 +- src/rez/utils/memcached.py | 4 +- src/rez/utils/platform_.py | 10 --- src/rez/utils/py23.py | 71 ------------------- src/rez/utils/sourcecode.py | 4 +- src/rez/version/_version.py | 4 +- 14 files changed, 52 insertions(+), 124 deletions(-) rename src/rez/tests/{test_utils_py23.py => test_util.py} (83%) delete mode 100644 src/rez/utils/py23.py diff --git a/src/rez/cli/forward.py b/src/rez/cli/forward.py index be725b153..97b9962ae 100644 --- a/src/rez/cli/forward.py +++ b/src/rez/cli/forward.py @@ -19,7 +19,7 @@ def command(opts, parser, extra_arg_groups=None): from rez.exceptions import RezSystemError from rez.vendor import yaml from rez.vendor.yaml.error import YAMLError - from rez.utils import py23 + from rez.util import get_function_arg_names import os.path # we don't usually want warnings printed in a wrapped tool. But in cases @@ -63,7 +63,7 @@ def command(opts, parser, extra_arg_groups=None): module = plugin_manager.get_plugin_module(plugin_type, plugin_name) target_func = getattr(module, func_name) - func_args = py23.get_function_arg_names(target_func) + func_args = get_function_arg_names(target_func) if "_script" in func_args: kwargs["_script"] = yaml_file diff --git a/src/rez/package_cache.py b/src/rez/package_cache.py index e17b2c782..086000e29 100644 --- a/src/rez/package_cache.py +++ b/src/rez/package_cache.py @@ -185,16 +185,9 @@ def add_variant(self, variant, force=False): "Not cached - package is local: %s" % package.uri ) - # Package is already on same disk device as package cache. Note that - # this check is skipped on Windows + Py<3.4, as os.stat does not - # support device identification. - # - dev_stat_not_supported = ( - platform.system() == "Windows" - and sys.version_info[:2] < (3, 4) - ) + # Package is already on same disk device as package cache - if not config.package_cache_same_device and not dev_stat_not_supported: + if not config.package_cache_same_device: st_pkgcache = os.stat(self.path) st_variant = os.stat(variant_root) if st_pkgcache.st_dev == st_variant.st_dev: diff --git a/src/rez/package_filter.py b/src/rez/package_filter.py index b6b60f296..70014e400 100644 --- a/src/rez/package_filter.py +++ b/src/rez/package_filter.py @@ -157,11 +157,9 @@ def __and__(self, other): result.add_inclusion(rule) return result - def __nonzero__(self): + def __bool__(self): return bool(self._excludes) - __bool__ = __nonzero__ # py3 compat - @cached_property def cost(self): """Get the approximate cost of this filter. @@ -304,11 +302,9 @@ def to_pod(self): data.append(f.to_pod()) return data - def __nonzero__(self): + def __bool__(self): return any(self.filters) - __bool__ = __nonzero__ # py3 compat - def __str__(self): filters = sorted(self.filters, key=lambda x: (x.cost, str(x))) return str(tuple(filters)) diff --git a/src/rez/rex.py b/src/rez/rex.py index 6086db5b4..1606a12d1 100644 --- a/src/rez/rex.py +++ b/src/rez/rex.py @@ -1180,14 +1180,12 @@ def __repr__(self): return '%s(%r, %r)' % (self.__class__.__name__, self._name, self.value()) - def __nonzero__(self): + def __bool__(self): try: return bool(self.value()) except RexUndefinedVariableError: return False - __bool__ = __nonzero__ # py3 compat - def __eq__(self, value): if isinstance(value, EnvironmentVariable): value = value.value() diff --git a/src/rez/serialise.py b/src/rez/serialise.py index da46b78b5..fe82421ea 100644 --- a/src/rez/serialise.py +++ b/src/rez/serialise.py @@ -23,7 +23,7 @@ from rez.exceptions import ResourceError, InvalidPackageError from rez.utils.memcached import memcached from rez.utils.execution import add_sys_paths -from rez.utils import py23 +from rez.util import get_function_arg_names from rez.config import config from rez.vendor.atomicwrites import atomic_write from rez.vendor import yaml @@ -332,7 +332,7 @@ def _process(value): fn.__globals__.update(get_objects()) # execute the function - args = py23.get_function_arg_names(func) + args = get_function_arg_names(func) if len(args) not in (0, 1): raise ResourceError("@early decorated function must " diff --git a/src/rez/solver.py b/src/rez/solver.py index f7652cf5d..7fc8ee59a 100644 --- a/src/rez/solver.py +++ b/src/rez/solver.py @@ -134,11 +134,9 @@ def br(self): def pr(self, txt='', *args): print(txt % args, file=self.buf) - def __nonzero__(self): + def __bool__(self): return self.verbosity > 0 - __bool__ = __nonzero__ # py3 compat - class SolverState(object): """Represent the current state of the solver instance for use with a diff --git a/src/rez/tests/test_utils_py23.py b/src/rez/tests/test_util.py similarity index 83% rename from src/rez/tests/test_utils_py23.py rename to src/rez/tests/test_util.py index 96b2c04de..16391e2d9 100644 --- a/src/rez/tests/test_utils_py23.py +++ b/src/rez/tests/test_util.py @@ -3,14 +3,13 @@ """ -unit tests for 'utils.py23' module +unit tests for 'util' module """ import os -import sys import tempfile - +import sys from rez.tests.util import TestBase -from rez.utils import py23 +from rez.util import load_module_from_file class TestLoadModuleFromFile(TestBase): @@ -27,8 +26,5 @@ def test_load_module(self): with open(os.path.join(tmpdir, filename), 'w') as fd: fd.write('') - py23.load_module_from_file( - module, - os.path.join(tmpdir, filename) - ) + load_module_from_file(module, os.path.join(tmpdir, filename)) self.assertEqual(sys.modules.get(module), None, msg='Module was found in sys.modules') diff --git a/src/rez/util.py b/src/rez/util.py index 969bbf30d..cfdbe6174 100644 --- a/src/rez/util.py +++ b/src/rez/util.py @@ -11,6 +11,8 @@ import os import os.path import re +import inspect + from rez.exceptions import RezError from rez.vendor.progress.bar import Bar @@ -156,3 +158,33 @@ def is_non_string_iterable(arg): isinstance(arg, collections.abc.Iterable) and not isinstance(arg, str) ) + + +def get_function_arg_names(func): + """Get names of a function's args. + + Gives full list of positional and keyword-only args. + """ + spec = inspect.getfullargspec(func) + return spec.args + spec.kwonlyargs + + +def load_module_from_file(name, filepath): + """Load a python module from a sourcefile. + + Args: + name (str): Module name. + filepath (str): Python sourcefile. + + Returns: + `module`: Loaded module. + """ + # The below code will import the module _without_ adding it to + # sys.modules. We want this otherwise we can't import multiple + # versions of the same module + # See: https://github.com/AcademySoftwareFoundation/rez/issues/1483 + import importlib.util + spec = importlib.util.spec_from_file_location(name, filepath) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module diff --git a/src/rez/utils/logging_.py b/src/rez/utils/logging_.py index 63a33e131..76b71601b 100644 --- a/src/rez/utils/logging_.py +++ b/src/rez/utils/logging_.py @@ -62,11 +62,9 @@ def __call__(self, msg, *nargs): msg = msg % nargs self.printer_function(msg) - def __nonzero__(self): + def __bool__(self): return bool(self.printer_function) - __bool__ = __nonzero__ # py3 compat - @contextmanager def log_duration(printer, msg): diff --git a/src/rez/utils/memcached.py b/src/rez/utils/memcached.py index ab0945cc9..000d4d262 100644 --- a/src/rez/utils/memcached.py +++ b/src/rez/utils/memcached.py @@ -5,7 +5,7 @@ from rez.config import config from rez.vendor.memcache.memcache import Client as Client_, \ SERVER_MAX_KEY_LENGTH, __version__ as memcache_client_version -from rez.utils import py23 +from rez.util import get_function_arg_names from threading import local from contextlib import contextmanager from functools import update_wrapper @@ -318,7 +318,7 @@ def _listdir(path): """ def default_key(func, *nargs, **kwargs): parts = [func.__module__] - argnames = py23.get_function_arg_names(func) + argnames = get_function_arg_names(func) if argnames: if argnames[0] == "cls": diff --git a/src/rez/utils/platform_.py b/src/rez/utils/platform_.py index bf66c30c0..f0901a1ca 100644 --- a/src/rez/utils/platform_.py +++ b/src/rez/utils/platform_.py @@ -3,7 +3,6 @@ import platform -import sys import os import os.path import re @@ -465,15 +464,6 @@ def _difftool(self): class WindowsPlatform(Platform): name = "windows" - def _arch(self): - # http://stackoverflow.com/questions/7164843/in-python-how-do-you-determine-whether-the-kernel-is-running-in-32-bit-or-64-bi - if os.name == 'nt' and sys.version_info[:2] < (2, 7): - arch = os.environ.get("PROCESSOR_ARCHITEW6432", - os.environ.get('PROCESSOR_ARCHITECTURE')) - if arch: - return arch - return super(WindowsPlatform, self)._arch() - def _os(self): release, version, csd, ptype = platform.win32_ver() toks = [] diff --git a/src/rez/utils/py23.py b/src/rez/utils/py23.py deleted file mode 100644 index 8eee97f81..000000000 --- a/src/rez/utils/py23.py +++ /dev/null @@ -1,71 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright Contributors to the Rez Project - - -""" -Custom py2/3 interoperability code. - -Put any code here that deals with py2/3 interoperability, beyond simple cases -that use (for eg) the six module. -""" -import sys - -from rez.vendor.six import six - -try: - from html import escape # noqa: F401 -except ImportError: - # Python 2 - from cgi import escape # noqa: F401 - -try: - from shlex import quote # noqa: F401 -except ImportError: - # Python 2 - from pipes import quote # noqa: F401 - - -def get_function_arg_names(func): - """Get names of a function's args. - - Gives full list of positional and keyword-only (py3 only) args. - """ - import inspect - - if hasattr(inspect, "getfullargspec"): - spec = inspect.getfullargspec(func) - return spec.args + spec.kwonlyargs - else: - return inspect.getargspec(func).args - - -def load_module_from_file(name, filepath): - """Load a python module from a sourcefile. - - Args: - name (str): Module name. - filepath (str): Python sourcefile. - - Returns: - `module`: Loaded module. - """ - if six.PY2: - import imp - with open(filepath) as f: - module = imp.load_source(name, filepath, f) - # Keep the module out of sys.modules. See comment in the `else:` - # for more info - if name in sys.modules: - del sys.modules[name] - return module - - else: - # The below code will import the module _without_ adding it to - # sys.modules. We want this otherwise we can't import multiple - # versions of the same module - # See: https://github.com/AcademySoftwareFoundation/rez/issues/1483 - import importlib.util - spec = importlib.util.spec_from_file_location(name, filepath) - module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(module) - return module diff --git a/src/rez/utils/sourcecode.py b/src/rez/utils/sourcecode.py index 42c7ed63d..ff835e6ac 100644 --- a/src/rez/utils/sourcecode.py +++ b/src/rez/utils/sourcecode.py @@ -5,7 +5,7 @@ from rez.utils.formatting import indent from rez.utils.data_utils import cached_property from rez.utils.logging_ import print_debug -from rez.utils import py23 +from rez.util import load_module_from_file from inspect import getsourcelines from textwrap import dedent from glob import glob @@ -351,7 +351,7 @@ def load_module(self, name, package): if config.debug("file_loads"): print_debug("Loading include sourcefile: %s" % filepath) - module = py23.load_module_from_file(name, filepath) + module = load_module_from_file(name, filepath) self.modules[hash_str] = module return module diff --git a/src/rez/version/_version.py b/src/rez/version/_version.py index 0dc702e54..2114f5bf5 100644 --- a/src/rez/version/_version.py +++ b/src/rez/version/_version.py @@ -390,12 +390,10 @@ def __getitem__(self, index): except IndexError: raise IndexError("version token index out of range") - def __nonzero__(self): + def __bool__(self): """The empty version equates to False.""" return bool(self.tokens) - __bool__ = __nonzero__ # py3 compat - def __eq__(self, other): return isinstance(other, Version) and self.tokens == other.tokens From ee61faef2eb50d457c74050df13e21f2253caa2c Mon Sep 17 00:00:00 2001 From: brycegbrazen Date: Tue, 12 Mar 2024 11:07:28 -0500 Subject: [PATCH 12/68] Improve explicitness of help doc of --command on rez-env Signed-off-by: brycegbrazen --- src/rez/cli/env.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rez/cli/env.py b/src/rez/cli/env.py index 20cf68edf..e35c0c0c3 100644 --- a/src/rez/cli/env.py +++ b/src/rez/cli/env.py @@ -29,8 +29,8 @@ def setup_parser(parser, completions=False): help="skip loading of startup scripts") command_action = parser.add_argument( "-c", "--command", type=str, - help="read commands from string. Alternatively, list command arguments " - "after a '--'") + help="read commands from a string and exit, instead of starting an interactive shell. " + "Alternatively, list command arguments after a '--'") parser.add_argument( "-s", "--stdin", action="store_true", help="read commands from standard input") From ee4e0566e174c72c25ef4aa73af5af40ba81d969 Mon Sep 17 00:00:00 2001 From: brycegbrazen Date: Tue, 12 Mar 2024 13:18:39 -0500 Subject: [PATCH 13/68] Address notes Signed-off-by: brycegbrazen --- src/rez/cli/env.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/rez/cli/env.py b/src/rez/cli/env.py index e35c0c0c3..986c8e86b 100644 --- a/src/rez/cli/env.py +++ b/src/rez/cli/env.py @@ -29,8 +29,11 @@ def setup_parser(parser, completions=False): help="skip loading of startup scripts") command_action = parser.add_argument( "-c", "--command", type=str, - help="read commands from a string and exit, instead of starting an interactive shell. " - "Alternatively, list command arguments after a '--'") + help="execute command within rez environment and exit, instead of " + "starting an interactive shell. Alternatively, list command after a " + "'--'. The command and arguments passed to '-c' must be passed in as " + "a single shell argument, whereas the command and arguments after " + "'--' may be passed in as several shell arguments.") parser.add_argument( "-s", "--stdin", action="store_true", help="read commands from standard input") From 1d18bc267fb6e237b56e0297952be95d8e325542 Mon Sep 17 00:00:00 2001 From: Stephen Mackenzie Date: Fri, 15 Mar 2024 19:03:47 -0400 Subject: [PATCH 14/68] update sonarcloud python property (#1686) Signed-off-by: Stephen Mackenzie --- .sonarcloud.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.sonarcloud.properties b/.sonarcloud.properties index 9efdc32b4..a991abf47 100644 --- a/.sonarcloud.properties +++ b/.sonarcloud.properties @@ -26,3 +26,6 @@ sonar.projectName=rez # Source properties sonar.sources=src sonar.exclusions=src/build_utils/**,src/rez/data/**,src/rez/tests/**,src/rez/vendor/** + +# Misc properties +sonar.python.version=3.7, 3.8, 3.9, 3.10, 3.11, 3.12 From 6060663d056407656d7ab51696ad25ab8fef2df9 Mon Sep 17 00:00:00 2001 From: Stephen Mackenzie Date: Mon, 18 Mar 2024 17:28:54 -0400 Subject: [PATCH 15/68] Tick off several completed boxes in onboarding document (#1691) * Tick off several completed boxes in onboarding document Signed-off-by: Stephen Mackenzie * Update ASWF/ONBOARDING.md Signed-off-by: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> --------- Signed-off-by: Stephen Mackenzie Signed-off-by: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> Co-authored-by: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> --- ASWF/ONBOARDING.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/ASWF/ONBOARDING.md b/ASWF/ONBOARDING.md index f43382426..d9d5a7a53 100644 --- a/ASWF/ONBOARDING.md +++ b/ASWF/ONBOARDING.md @@ -7,11 +7,11 @@ https://github.com/AcademySoftwareFoundation/asfw-sample-project/blob/main/tsc/p Misc stuff not covered in the ASWF list -- [ ] Move from master to main branch [#1203](/../../issues/1203) -- [ ] Remove hardcoded references to `nerdvegas` where possible (some of these won't make sense to do until after gh migration) [#1205](/../../issues/1205) +- [X] Move from master to main branch [#1203](/../../issues/1203) +- [X] Remove hardcoded references to `nerdvegas` where possible (some of these won't make sense to do until after gh migration) [#1205](/../../issues/1205) - TODO: inline links in comments (will need a script to batch convert) - TODO: README.md -- [ ] Update Github slack integration [#1204](/../../issues/1204) +- [X] Update Github slack integration [#1204](/../../issues/1204) # ASWF Onboarding Checklist - Existing Project Governance @@ -25,11 +25,10 @@ Misc stuff not covered in the ASWF list - [X] A [CODE_OF_CONDUCT.md](../CODE_OF_CONDUCT.md) file that sets the ground rules for participants’ behavior associated and helps to facilitate a friendly, welcoming environment. By default, projects should leverage the Linux Foundation Code of Conduct unless an alternate Code of Conduct was previously approved. [#1227](/../../issues/1227) - [ ] A [RELEASE.md](process/release.md) file that provides documentation on the release methodology, cadence, criteria, etc. - (exists but requires review) - - [ ] A [GOVERNANCE.md](../GOVERNANCE.md) file that documents the project’s technical governance. [#1229](/../../issues/1229) + - [X] A [GOVERNANCE.md](../GOVERNANCE.md) file that documents the project’s technical governance. [#1229](/../../issues/1229) - [ ] A [SUPPORT.md](../SUPPORT.md) file to let users and developers know about ways to get help with your project. [#1230](/../../issues/1230) - Infrastructure/Assets - - [!] License scan completed and no issues found - - **NOTE: we need to fix: https://github.com/AcademySoftwareFoundation/rez/issues/1349** + - [X] License scan completed and no issues found - [X] Code repository imported to ASWF GitHub organization or ownership of current GitHub organization given to `thelinuxfoundation` user - [X] Developer Certificate of Origin past commit signoff done and DCO Probot enabled. - [X] Issue/feature tracker established (JIRA, GitHub issues) @@ -48,16 +47,16 @@ Misc stuff not covered in the ASWF list - New Project Goverance - [X] TSC members identified - [X] First TSC meeting held - - [ ] TSC meeting cadence set and added to project calendar - - [ ] CLA Approved ( if used ) ( [CCLA](ccla.md) and [ICLA](icla.md) ) + - [X] TSC meeting cadence set and added to project calendar + - [x] CLA Approved ( if used ) ( [CCLA](ccla.md) and [ICLA](icla.md) ) - Project charter ( [charter.md](charter.md) ) - - [ ] Approved by TSC - - [ ] Filed ( create pull request against [foundation repo](https://github.com/AcademySoftwareFoundation/foundation) ) + - [x] Approved by TSC + - [x] Filed ( create pull request against [foundation repo](https://github.com/AcademySoftwareFoundation/foundation) ) - [ ] [Core Infrastructure Initiative Best Practices Badge](https://bestpractices.coreinfrastructure.org/) achieved as the 'Passing' level. - - [ ] TAC representative appointed + - [X] TAC representative appointed - Outreach - [X] New project annoucement done ( create [issue on foundation repo](https://github.com/AcademySoftwareFoundation/foundation/issues/new) to trigger ) - - [ ] Project added to ASWF website and ASWF landscape + - [X] Project added to ASWF website and ASWF landscape - Adopted Stage graduation requirements - [ ] CII Badge achieved - [ ] Demonstrate a substantial ongoing flow of commits and merged contributions, authored by a healthy number of diverse contributors*. From d4a2daff9b148cb96fb7033d98002e31ff6a0739 Mon Sep 17 00:00:00 2001 From: Hal <13111745+loonghao@users.noreply.github.com> Date: Fri, 29 Mar 2024 22:55:06 +0800 Subject: [PATCH 16/68] Add retry mechanism when renaming folders on Windows (#1666) This will fix issues when rez-cp could fail in some situations on WIndows. Signed-off-by: loonghao --- src/rez/package_cache.py | 3 +- src/rez/tests/test_utils_filesystem.py | 88 ++++++++++++++++++++++++++ src/rez/utils/filesystem.py | 62 ++++++++++++++++-- 3 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 src/rez/tests/test_utils_filesystem.py diff --git a/src/rez/package_cache.py b/src/rez/package_cache.py index 086000e29..7ab833bdf 100644 --- a/src/rez/package_cache.py +++ b/src/rez/package_cache.py @@ -28,6 +28,7 @@ from rez.utils.logging_ import print_warning from rez.packages import get_variant from rez.system import system +from rez.utils.filesystem import rename class PackageCache(object): @@ -330,7 +331,7 @@ def remove_variant(self, variant): os.chmod(rootpath, st.st_mode | stat.S_IWUSR) # actually a mv - os.rename(rootpath, dest_rootpath) + rename(rootpath, dest_rootpath) except OSError as e: if e.errno == errno.ENOENT: diff --git a/src/rez/tests/test_utils_filesystem.py b/src/rez/tests/test_utils_filesystem.py new file mode 100644 index 000000000..cccbfe499 --- /dev/null +++ b/src/rez/tests/test_utils_filesystem.py @@ -0,0 +1,88 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright Contributors to the Rez Project + + +""" +unit tests for 'rez.utils.filesystem' module +""" +import os.path +import tempfile + +from rez.tests.util import TestBase +from rez.tests.util import TempdirMixin +from rez.utils import filesystem +from rez.utils.platform_ import platform_ +import unittest + + +class TestFileSystem(TestBase, TempdirMixin): + + def __init__(self, *nargs, **kwargs): + super().__init__(*nargs, **kwargs) + + @classmethod + def setUpClass(cls): + super().setUpClass() + TempdirMixin.setUpClass() + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + TempdirMixin.tearDownClass() + + def test_windows_rename_fallback_to_robocopy(self): + if platform_.name != 'windows': + self.skipTest('Robocopy is only available on windows.') + src = tempfile.mkdtemp(dir=self.root) + dst = tempfile.mkdtemp(dir=self.root) + with unittest.mock.patch("os.rename") as mock_rename: + mock_rename.side_effect = PermissionError("Permission denied") + filesystem.rename(src, dst) + self.assertTrue(os.path.exists(dst)) + self.assertFalse(os.path.exists(src)) + + def test_windows_robocopy_failed(self): + if platform_.name != 'windows': + self.skipTest('Robocopy is only available on windows.') + src = tempfile.mkdtemp(dir=self.root) + dst = tempfile.mkdtemp(dir=self.root) + with unittest.mock.patch("os.rename") as mock_rename: + mock_rename.side_effect = PermissionError("Permission denied") + with unittest.mock.patch("rez.utils.filesystem.Popen") as mock_subprocess: + mock_subprocess.return_value = unittest.mock.Mock(returncode=9) + with self.assertRaises(OSError) as err: + filesystem.rename(src, dst) + self.assertEqual(str(err.exception), "Rename {} to {} failed.".format(src, dst)) + + def test_rename_folder_with_permission_error_and_no_robocopy(self): + src = tempfile.mkdtemp(dir=self.root) + dst = tempfile.mkdtemp(dir=self.root) + with unittest.mock.patch("os.rename") as mock_rename: + mock_rename.side_effect = PermissionError("Permission denied") + with unittest.mock.patch("rez.utils.filesystem.which") as mock_which: + mock_which.return_value = False + with self.assertRaises(PermissionError) as err: + filesystem.rename(src, dst) + self.assertEqual(str(err.exception), "Permission denied") + + def test_rename_folder_with_permission_error_and_src_is_file(self): + src = tempfile.mktemp(dir=self.root) + dst = tempfile.mktemp(dir=self.root) + with open(src, "w") as file_: + file_.write("content.") + with unittest.mock.patch("os.rename") as mock_rename: + mock_rename.side_effect = PermissionError("Permission denied") + with self.assertRaises(PermissionError) as err: + filesystem.rename(src, dst) + self.assertEqual(str(err.exception), "Permission denied") + self.assertFalse(os.path.exists(dst)) + self.assertTrue(os.path.exists(src)) + + def test_rename_file(self): + src = tempfile.mktemp(dir=self.root) + dst = tempfile.mktemp(dir=self.root) + with open(src, "w") as file_: + file_.write("content.") + filesystem.rename(src, dst) + self.assertTrue(os.path.exists(dst)) + self.assertFalse(os.path.exists(src)) diff --git a/src/rez/utils/filesystem.py b/src/rez/utils/filesystem.py index eb825f972..fcf0db4f9 100644 --- a/src/rez/utils/filesystem.py +++ b/src/rez/utils/filesystem.py @@ -23,7 +23,8 @@ import uuid from rez.utils.platform_ import platform_ - +from rez.util import which +from rez.utils.execution import Popen is_windows = platform.system() == "Windows" @@ -213,6 +214,7 @@ def forceful_rmtree(path): * path length over 259 char (on Windows) * unicode path """ + def _on_error(func, path, exc_info): try: if is_windows: @@ -281,7 +283,7 @@ def replace_file_or_dir(dest, source): if not os.path.exists(dest): try: - os.rename(source, dest) + rename(source, dest) return except: if not os.path.exists(dest): @@ -294,8 +296,8 @@ def replace_file_or_dir(dest, source): pass with make_tmp_name(dest) as tmp_dest: - os.rename(dest, tmp_dest) - os.rename(source, dest) + rename(dest, tmp_dest) + rename(source, dest) def additive_copytree(src, dst, symlinks=False, ignore=None): @@ -690,3 +692,55 @@ def windows_long_path(dos_path): path = "\\\\?\\" + path return path + + +def rename(src, dst): + """Utility function to rename a file or folder src to dst with retrying. + + This function uses the built-in `os.rename()` function and falls back to `robocopy` tool + if `os.rename` raises a `PermissionError` exception. + + Args: + src (str): The original name (path) of the file or folder. + dst (str): The new name (path) for the file or folder. + + Raises: + OSError: If renaming fails after all attempts. + + """ + # Inspired by https://github.com/conan-io/conan/blob/2.1.0/conan/tools/files/files.py#L207 + try: + os.rename(src, dst) + except PermissionError as err: + if is_windows and which("robocopy") and os.path.isdir(src): + # https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/robocopy + args = [ + "robocopy", + # /move Moves files and directories, and deletes them from the source after they are copied. + "/move", + # /e Copies subdirectories. Note that this option includes empty directories. + "/e", + # /ndl Specifies that directory names are not to be logged. + "/ndl", + # /nfl Specifies that file names are not to be logged. + "/nfl", + # /njs Specifies that there's no job summary. + "/njs", + # /njh Specifies that there's no job header. + "/njh", + # /np Specifies that the progress of the copying operation + # (the number of files or directories copied so far) won't be displayed. + "/np", + # /ns Specifies that file sizes aren't to be logged. + "/ns", + # /nc Specifies that file classes aren't to be logged. + "/nc", + src, + dst, + ] + process = Popen(args) + process.communicate() + if process.returncode > 7: # https://ss64.com/nt/robocopy-exit.html + raise OSError("Rename {} to {} failed.".format(src, dst)) + else: + raise err From 018e449c419771d5914b572dffaeb6e861bdfec9 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> Date: Fri, 29 Mar 2024 11:02:03 -0400 Subject: [PATCH 17/68] Add -e/--editable flag to install script to create an editable install (#1672) Signed-off-by: Jean-Christophe Morin --- install.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/install.py b/install.py index 43b7c81cc..70d630dcf 100644 --- a/install.py +++ b/install.py @@ -147,19 +147,19 @@ def copy_completion_scripts(dest_dir): return None -def install(dest_dir, print_welcome=False): +def install(dest_dir, print_welcome=False, editable=False): """Install rez into the given directory. Args: dest_dir (str): Full path to the install directory. """ - print("installing rez to %s..." % dest_dir) + print("installing rez%s to %s..." % (" (editable mode)" if editable else "", dest_dir)) # create the virtualenv create_virtual_environment(dest_dir) # install rez from source - install_rez_from_source(dest_dir) + install_rez_from_source(dest_dir, editable=editable) # patch the rez binaries patch_rez_binaries(dest_dir) @@ -222,11 +222,15 @@ def install(dest_dir, print_welcome=False): print('') -def install_rez_from_source(dest_dir): +def install_rez_from_source(dest_dir, editable): _, py_executable = get_virtualenv_py_executable(dest_dir) # install via pip - run_command([py_executable, "-m", "pip", "install", "."]) + args = [py_executable, "-m", "pip", "install"] + if editable: + args.append("-e") + args.append(".") + run_command(args) def install_as_rez_package(repo_path): @@ -280,6 +284,11 @@ def install_as_rez_package(repo_path): help="Install rez as a rez package. Note that this installs the API " "only (no cli tools), and DIR is expected to be the path to a rez " "package repository (and will default to ~/packages instead).") + parser.add_argument( + "-e", "--editable", action="store_true", + help="Make the install an editable install (pip install -e). This should " + "only be used for development purposes" + ) parser.add_argument( "DIR", nargs='?', help="Destination directory. If '{version}' is present, it will be " @@ -314,4 +323,4 @@ def install_as_rez_package(repo_path): if opts.as_rez_package: install_as_rez_package(dest_dir) else: - install(dest_dir, print_welcome=True) + install(dest_dir, print_welcome=True, editable=opts.editable) From d91cde9c30bc1f94b2b101e13b6d52c219b8ddbf Mon Sep 17 00:00:00 2001 From: Ben Andersen <156872503+isohedronpipeline@users.noreply.github.com> Date: Sat, 30 Mar 2024 02:08:56 +1100 Subject: [PATCH 18/68] Apply package orderers on variants (#1684) Previously, package orderers were only applied on packages. This was an oversight. With this change, they are now applied to variants too. --------- Signed-off-by: Ben Andersen Co-authored-by: Paul Molodowitch --- .../solver/packages/pyvariants/2/package.py | 7 +- src/rez/package_order.py | 449 +++++++++++++----- src/rez/resolved_context.py | 9 +- src/rez/rezconfig.py | 15 +- src/rez/solver.py | 29 +- src/rez/tests/test_context.py | 64 +++ src/rez/tests/test_packages_order.py | 5 - src/rez/version/_version.py | 7 +- 8 files changed, 447 insertions(+), 138 deletions(-) diff --git a/src/rez/data/tests/solver/packages/pyvariants/2/package.py b/src/rez/data/tests/solver/packages/pyvariants/2/package.py index ed06df9da..0374627d3 100644 --- a/src/rez/data/tests/solver/packages/pyvariants/2/package.py +++ b/src/rez/data/tests/solver/packages/pyvariants/2/package.py @@ -1,4 +1,9 @@ name = "pyvariants" version = "2" -variants = [["python-2.7.0"], ["python-2.6.8", "nada"]] +variants = [ + ["python-2.7.0"], + ["python-2.6.8", "nada"], + ["python-2.6.8"], + ["nada"], +] diff --git a/src/rez/package_order.py b/src/rez/package_order.py index e00839fea..a71dbac02 100644 --- a/src/rez/package_order.py +++ b/src/rez/package_order.py @@ -4,10 +4,40 @@ from inspect import isclass from hashlib import sha1 +from typing import Dict, Iterable, List, Optional, Union from rez.config import config from rez.utils.data_utils import cached_class_property -from rez.version import Version +from rez.version import Version, VersionRange +from rez.version._version import _Comparable, _ReversedComparable, _LowerBound, _UpperBound, _Bound +from rez.packages import iter_packages + +ALL_PACKAGES = "*" + + +class FallbackComparable(_Comparable): + """First tries to compare objects using the main_comparable, but if that + fails, compares using the fallback_comparable object. + """ + + def __init__(self, main_comparable, fallback_comparable): + self.main_comparable = main_comparable + self.fallback_comparable = fallback_comparable + + def __eq__(self, other): + try: + return self.main_comparable == other.main_comparable + except Exception: + return self.fallback_comparable == other.fallback_comparable + + def __lt__(self, other): + try: + return self.main_comparable < other.main_comparable + except Exception: + return self.fallback_comparable < other.fallback_comparable + + def __repr__(self): + return '%s(%r, %r)' % (type(self).__name__, self.main_comparable, self.fallback_comparable) class PackageOrder(object): @@ -16,8 +46,32 @@ class PackageOrder(object): #: Orderer name name = None - def __init__(self): - pass + def __init__(self, packages: Optional[Iterable[str]] = None): + """ + Args: + packages: If not provided, PackageOrder applies to all packages. + """ + self.packages = packages + + @property + def packages(self) -> List[str]: + """Returns an iterable over the list of package family names that this + order applies to + + Returns: + (Iterable[str]) Package families that this orderer is used for + """ + return self._packages + + @packages.setter + def packages(self, packages: Union[str, Iterable[str]]): + if packages is None: + # Apply to all packages + self._packages = [ALL_PACKAGES] + elif isinstance(packages, str): + self._packages = [packages] + else: + self._packages = sorted(packages) def reorder(self, iterable, key=None): """Put packages into some order for consumption. @@ -40,11 +94,75 @@ def reorder(self, iterable, key=None): Returns: list: Reordered ``iterable`` """ + key = key or (lambda x: x) + package_name = self._get_package_name_from_iterable(iterable, key=key) + return sorted(iterable, + key=lambda x: self.sort_key(package_name, key(x).version), + reverse=True) + + @staticmethod + def _get_package_name_from_iterable(iterable, key=None): + """Utility method for getting a package from an iterable""" + try: + item = next(iter(iterable)) + except (TypeError, StopIteration): + return None + + key = key or (lambda x: x) + return key(item).name + + def sort_key(self, package_name, version_like): + """Returns a sort key usable for sorting packages within the same family + + Args: + package_name: (str) The family name of the package we are sorting + version_like: (Version|_LowerBound|_UpperBound|_Bound|VersionRange) + the version-like object you wish to generate a key for + + Returns: + Sortable object + The returned object must be sortable, which means that it must implement __lt__. + The specific return type is not important. + """ + if isinstance(version_like, VersionRange): + return tuple(self.sort_key(package_name, bound) for bound in version_like.bounds) + elif isinstance(version_like, _Bound): + return (self.sort_key(package_name, version_like.lower), + self.sort_key(package_name, version_like.upper)) + elif isinstance(version_like, _LowerBound): + inclusion_key = -2 if version_like.inclusive else -1 + return self.sort_key(package_name, version_like.version), inclusion_key + elif isinstance(version_like, _UpperBound): + inclusion_key = 2 if version_like.inclusive else 1 + return self.sort_key(package_name, version_like.version), inclusion_key + elif isinstance(version_like, Version): + # finally, the bit that we actually use the sort_key_implementation for. + return FallbackComparable( + self.sort_key_implementation(package_name, version_like), version_like) + else: + raise TypeError(version_like) + + def sort_key_implementation(self, package_name, version): + """Returns a sort key usable for sorting these packages within the + same family + Args: + package_name: (str) The family name of the package we are sorting + version: (Version) the version object you wish to generate a key for + + Returns: + Sortable object + The returned object must be sortable, which means that it must implement __lt__. + The specific return type is not important. + """ raise NotImplementedError def to_pod(self): raise NotImplementedError + @classmethod + def from_pod(cls, data): + raise NotImplementedError + @property def sha1(self): return sha1(repr(self).encode('utf-8')).hexdigest() @@ -53,7 +171,7 @@ def __str__(self): raise NotImplementedError def __eq__(self, other): - raise NotImplementedError + return type(self) == type(other) and str(self) == str(other) def __ne__(self, other): return not self == other @@ -71,8 +189,10 @@ class NullPackageOrder(PackageOrder): """ name = "no_order" - def reorder(self, iterable, key=None): - return list(iterable) + def sort_key_implementation(self, package_name, version): + # python's sort will preserve the order of items that compare equal, so + # to not change anything, we just return the same object for all... + return 0 def __str__(self): return "{}" @@ -87,12 +207,15 @@ def to_pod(self): .. code-block:: yaml type: no_order + packages: ["foo"] """ - return {} + return { + "packages": self.packages, + } @classmethod def from_pod(cls, data): - return cls() + return cls(packages=data.get("packages")) class SortedOrder(PackageOrder): @@ -100,13 +223,22 @@ class SortedOrder(PackageOrder): """ name = "sorted" - def __init__(self, descending): + def __init__(self, descending, packages=None): + super().__init__(packages) self.descending = descending - def reorder(self, iterable, key=None): - key = key or (lambda x: x) - return sorted(iterable, key=lambda x: key(x).version, - reverse=self.descending) + def sort_key_implementation(self, package_name, version): + # Note that the name "descending" can be slightly confusing - it + # indicates that the final ordering this Order gives should be + # version descending (ie, the default) - however, the sort_key itself + # returns its results in "normal" ascending order (because it needs to + # be used "alongside" normally-sorted objects like versions). + # when the key is passed to sort(), though, it is always invoked with + # reverse=True... + if self.descending: + return version + else: + return _ReversedComparable(version) def __str__(self): return str(self.descending) @@ -125,12 +257,19 @@ def to_pod(self): type: sorted descending: true + packages: ["foo"] """ - return {"descending": self.descending} + return { + "descending": self.descending, + "packages": self.packages, + } @classmethod def from_pod(cls, data): - return cls(descending=data["descending"]) + return cls( + data["descending"], + packages=data.get("packages"), + ) class PerFamilyOrder(PackageOrder): @@ -147,19 +286,16 @@ def __init__(self, order_dict, default_order=None): default_order (PackageOrder): Orderer to apply to any packages not specified in ``order_dict``. """ + super().__init__(list(order_dict)) self.order_dict = order_dict.copy() self.default_order = default_order def reorder(self, iterable, key=None): - try: - item = next(iter(iterable)) - except: + package_name = self._get_package_name_from_iterable(iterable, key) + if package_name is None: return None - key = key or (lambda x: x) - package = key(item) - - orderer = self.order_dict.get(package.name) + orderer = self.order_dict.get(package_name) if orderer is None: orderer = self.default_order if orderer is None: @@ -167,6 +303,19 @@ def reorder(self, iterable, key=None): return orderer.reorder(iterable, key) + def sort_key_implementation(self, package_name, version): + orderer = self.order_dict.get(package_name) + if orderer is None: + if self.default_order is None: + # shouldn't get here, because applies_to should protect us... + raise RuntimeError( + "package family orderer %r does not apply to package family %r", + (self, package_name)) + + orderer = self.default_order + + return orderer.sort_key_implementation(package_name, version) + def __str__(self): items = sorted((x[0], str(x[1])) for x in self.order_dict.items()) return str((items, str(self.default_order))) @@ -247,35 +396,18 @@ class VersionSplitPackageOrder(PackageOrder): """ name = "version_split" - def __init__(self, first_version): + def __init__(self, first_version, packages=None): """Create a reorderer. Args: first_version (Version): Start with versions <= this value. """ + super().__init__(packages) self.first_version = first_version - def reorder(self, iterable, key=None): - key = key or (lambda x: x) - - # sort by version descending - descending = sorted(iterable, key=lambda x: key(x).version, reverse=True) - - above = [] - below = [] - is_above = True - - for item in descending: - if is_above: - package = key(item) - is_above = (package.version > self.first_version) - - if is_above: - above.append(item) - else: - below.append(item) - - return below + above + def sort_key_implementation(self, package_name, version): + priority_key = 1 if version <= self.first_version else 0 + return priority_key, version def __str__(self): return str(self.first_version) @@ -294,12 +426,19 @@ def to_pod(self): type: version_split first_version: "3.0.0" + packages: ["foo"] """ - return dict(first_version=str(self.first_version)) + return dict( + first_version=str(self.first_version), + packages=self.packages, + ) @classmethod def from_pod(cls, data): - return cls(Version(data["first_version"])) + return cls( + Version(data["first_version"]), + packages=data.get("packages"), + ) class TimestampPackageOrder(PackageOrder): @@ -345,7 +484,7 @@ class TimestampPackageOrder(PackageOrder): """ name = "soft_timestamp" - def __init__(self, timestamp, rank=0): + def __init__(self, timestamp, rank=0, packages=None): """Create a reorderer. Args: @@ -354,73 +493,84 @@ def __init__(self, timestamp, rank=0): rank (int): If non-zero, allow version changes at this rank or above past the timestamp. """ + super().__init__(packages) self.timestamp = timestamp self.rank = rank - def reorder(self, iterable, key=None): + # dictionary mapping from package family to the first-version-after + # the given timestamp + self._cached_first_after = {} + self._cached_sort_key = {} + + def _get_first_after(self, package_family): + """Get the first package version that is after the timestamp""" + try: + first_after = self._cached_first_after[package_family] + except KeyError: + first_after = self._calc_first_after(package_family) + self._cached_first_after[package_family] = first_after + return first_after + + def _calc_first_after(self, package_family): + descending = sorted(iter_packages(package_family), + key=lambda p: p.version, + reverse=True) first_after = None - key = key or (lambda x: x) + for i, package in enumerate(descending): + if not package.timestamp: + continue + if package.timestamp > self.timestamp: + first_after = package.version + else: + break + + if not self.rank: + return first_after + + # if we have rank, then we need to then go back UP the + # versions, until we find one whose trimmed version doesn't + # match. + # Note that we COULD do this by simply iterating through + # an ascending sequence, in which case we wouldn't have to + # "switch direction" after finding the first result after + # by timestamp... but we're making the assumption that the + # timestamp break will be closer to the higher end of the + # version, and that we'll therefore have to check fewer + # timestamps this way... + trimmed_version = package.version.trim(self.rank - 1) + first_after = None + for after_package in reversed(descending[:i]): + if after_package.version.trim(self.rank - 1) != trimmed_version: + return after_package.version - # sort by version descending - descending = sorted(iterable, key=lambda x: key(x).version, reverse=True) + return first_after - for i, o in enumerate(descending): - package = key(o) - if package.timestamp: - if package.timestamp > self.timestamp: - first_after = i - else: - break + def _calc_sort_key(self, package_name, version): + first_after = self._get_first_after(package_name) + if first_after is None: + # all packages are before T + is_before = True + else: + is_before = int(version < first_after) - if first_after is None: # all packages are before T - return None + if is_before: + return is_before, version - before = descending[first_after + 1:] - after = list(reversed(descending[:first_after + 1])) - - if not self.rank: # simple case - return before + after - - # include packages after timestamp but within rank - if before and after: - package = key(before[0]) - first_prerank = package.version.trim(self.rank - 1) - found = False - - for i, o in enumerate(after): - package = key(o) - prerank = package.version.trim(self.rank - 1) - if prerank != first_prerank: - found = True - break - - if not found: - # highest version is also within rank, so result is just - # simple descending list - return descending - - if i: - before = list(reversed(after[:i])) + before - after = after[i:] - - # ascend below rank, but descend within - after_ = [] - postrank = [] - prerank = None - - for o in after: - package = key(o) - prerank_ = package.version.trim(self.rank - 1) - - if prerank_ == prerank: - postrank.append(o) - else: - after_.extend(reversed(postrank)) - postrank = [o] - prerank = prerank_ + if self.rank: + return (is_before, + _ReversedComparable(version.trim(self.rank - 1)), + version.tokens[self.rank - 1:]) + + return is_before, _ReversedComparable(version) - after_.extend(reversed(postrank)) - return before + after_ + def sort_key_implementation(self, package_name, version): + cache_key = (package_name, str(version)) + result = self._cached_sort_key.get(cache_key) + if result is None: + result = self._calc_sort_key(package_name, version) + self._cached_sort_key[cache_key] = result + + return result def __str__(self): return str((self.timestamp, self.rank)) @@ -441,23 +591,34 @@ def to_pod(self): type: soft_timestamp timestamp: 1234567 rank: 3 + packages: ["foo"] """ - return dict(timestamp=self.timestamp, - rank=self.rank) + return dict( + timestamp=self.timestamp, + rank=self.rank, + packages=self.packages, + ) @classmethod def from_pod(cls, data): - return cls(timestamp=data["timestamp"], rank=data.get("rank", 0)) + return cls( + data["timestamp"], + rank=data.get("rank", 0), + packages=data.get("packages"), + ) class PackageOrderList(list): """A list of package orderer. """ + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.by_package: Dict[str, PackageOrder] = {} + self.dirty = True + def to_pod(self): - data = [] - for f in self: - data.append(to_pod(f)) - return data + return [to_pod(f) for f in self] @classmethod def from_pod(cls, data): @@ -472,6 +633,58 @@ def singleton(cls): """Filter list as configured by rezconfig.package_filter.""" return cls.from_pod(config.package_orderers) + @staticmethod + def _to_orderer(orderer: Union[dict, PackageOrder]) -> PackageOrder: + if isinstance(orderer, dict): + orderer = from_pod(orderer) + return orderer + + def refresh(self) -> None: + """Update the internal order-by-package mapping""" + self.by_package = {} + for orderer in self: + orderer = self._to_orderer(orderer) + for package in orderer.packages: + # We allow duplicates (so we can have hierarchical configs, + # which can override each other) - earlier orderers win + if package in self.by_package: + continue + self.by_package[package] = orderer + + def append(self, *args, **kwargs): + self.dirty = True + return super().append(*args, **kwargs) + + def extend(self, *args, **kwargs): + self.dirty = True + return super().extend(*args, **kwargs) + + def pop(self, *args, **kwargs): + self.dirty = True + return super().pop(*args, **kwargs) + + def remove(self, *args, **kwargs): + self.dirty = True + return super().remove(*args, **kwargs) + + def clear(self, *args, **kwargs): + self.dirty = True + return super().clear(*args, **kwargs) + + def insert(self, *args, **kwargs): + self.dirty = True + return super().insert(*args, **kwargs) + + def get(self, key: str, default: Optional[PackageOrder] = None) -> PackageOrder: + """ + Get an orderer that sorts a package by name. + """ + if self.dirty: + self.refresh() + self.dirty = False + result = self.by_package.get(key, default) + return result + def to_pod(orderer): data = {"type": orderer.name} @@ -494,6 +707,18 @@ def from_pod(data): return cls.from_pod(data_) +def get_orderer(package_name, orderers=None): + if orderers is None: + orderers = PackageOrderList.singleton + orderer = orderers.get(package_name) + if orderer is None: + orderer = orderers.get(ALL_PACKAGES) + if orderer is None: + # default ordering is version descending + orderer = SortedOrder(descending=True) + return orderer + + def register_orderer(cls): """Register an orderer diff --git a/src/rez/resolved_context.py b/src/rez/resolved_context.py index bbf68fef0..9ef3ae09d 100644 --- a/src/rez/resolved_context.py +++ b/src/rez/resolved_context.py @@ -233,7 +233,7 @@ def __init__(self, package_requests, verbosity=0, timestamp=None, self.package_filter = (PackageFilterList.singleton if package_filter is None else package_filter) - self.package_orderers = ( + self.package_orderers = PackageOrderList( PackageOrderList.singleton if package_orderers is None else package_orderers ) @@ -1527,9 +1527,10 @@ def _add(field): data["patch_locks"] = dict((k, v.name) for k, v in self.patch_locks) if _add("package_orderers"): - package_orderers = [package_order.to_pod(x) - for x in (self.package_orderers or [])] - data["package_orderers"] = package_orderers or None + if self.package_orderers: + data["package_orderers"] = self.package_orderers.to_pod() + else: + data["package_orderers"] = None if _add("package_filter"): data["package_filter"] = self.package_filter.to_pod() diff --git a/src/rez/rezconfig.py b/src/rez/rezconfig.py index ca1f14b15..788813e50 100644 --- a/src/rez/rezconfig.py +++ b/src/rez/rezconfig.py @@ -423,7 +423,7 @@ # One or more "orderers" can be listed. # This will affect the order of version resolution. # This can be used to ensure that specific version have priority over others. -# Higher versions can still be accessed if required. +# Higher versions can still be accessed if explicitly requested. # # A common use case is to ease migration from python-2 to python-3: # @@ -452,6 +452,19 @@ # rez-env python-3 python-3.7.4 # ==================== ============= # +# +# Package orderers will also apply to variants of packages. +# Consider a package "pipeline-1.0" which has the following variants: +# ``[["python-2.7.4", "python-2.7.16", "python-3.7.4"]]`` +# +# ============================= ========================== +# Example Result +# ============================= ========================== +# rez-env pipeline pipeline-1.0 python-2.7.16 +# rez-env pipeline python-3 pipeline-1.0 python-3.7.4 +# ============================= ========================== +# +# # Here's another example, using another orderer: "soft_timestamp". # This orderer will prefer packages released before a provided timestamp. # The following example will prefer package released before 2019-09-09. diff --git a/src/rez/solver.py b/src/rez/solver.py index 7fc8ee59a..b128dbc88 100644 --- a/src/rez/solver.py +++ b/src/rez/solver.py @@ -415,6 +415,8 @@ def sort(self): here as a safety measure so that sorting is guaranteed repeatable regardless. """ + from rez.package_order import get_orderer + if self.sorted: return @@ -426,13 +428,17 @@ def key(variant): if not request.conflict: req = variant.requires_list.get(request.name) if req is not None: - requested_key.append((-i, req.range)) + orderer = get_orderer(req.name, orderers=self.solver.package_orderers or {}) + range_key = orderer.sort_key(req.name, req.range) + requested_key.append((-i, range_key)) names.add(req.name) additional_key = [] for request in variant.requires_list: if not request.conflict and request.name not in names: - additional_key.append((request.range, request.name)) + orderer = get_orderer(request.name, orderers=self.solver.package_orderers) + range_key = orderer.sort_key(request.name, request.range) + additional_key.append((range_key, request.name)) if (VariantSelectMode[config.variant_select_mode] == VariantSelectMode.version_priority): k = (requested_key, @@ -802,6 +808,7 @@ def _split(i_entry, n_variants, common_fams=None): if not fams: # trivial case, split on first variant + self.entries[0].sort() return _split(0, 1) # find split point - first variant with no dependency shared with previous @@ -831,25 +838,21 @@ def sort_versions(self): The order is typically descending, but package order functions can change this. """ + from rez.package_order import get_orderer + if self.sorted: return - for orderer in (self.solver.package_orderers or []): - entries = orderer.reorder(self.entries, key=lambda x: x.package) - if entries is not None: - self.entries = entries - self.sorted = True + orderer = get_orderer(self.package_name, orderers=self.solver.package_orderers or {}) - if self.pr: - self.pr("sorted: %s packages: %s", self.package_name, repr(orderer)) - return + def sort_key(entry): + return orderer.sort_key(entry.package.name, entry.version) - # default ordering is version descending - self.entries = sorted(self.entries, key=lambda x: x.version, reverse=True) + self.entries = sorted(self.entries, key=sort_key, reverse=True) self.sorted = True if self.pr: - self.pr("sorted: %s packages: version descending", self.package_name) + self.pr("sorted: %s packages: %s", self.package_name, repr(orderer)) def dump(self): print(self.package_name) diff --git a/src/rez/tests/test_context.py b/src/rez/tests/test_context.py index ee742a8df..65cefffbd 100644 --- a/src/rez/tests/test_context.py +++ b/src/rez/tests/test_context.py @@ -186,6 +186,70 @@ def _test_bundle(path): _test_bundle(bundle_path3) + def test_orderer_variants(self): + """Test that package orderers apply to the variants of packages, not just requires.""" + from rez.package_order import PerFamilyOrder, VersionSplitPackageOrder + from rez.version import Version + + packages_path = self.data_path("solver", "packages") + + # Verify that we get the latest python without an orderer + r = ResolvedContext( + ["pyvariants", "!nada"], + package_paths=[packages_path], + ) + resolved = [x.qualified_package_name for x in r.resolved_packages] + self.assertEqual(resolved, ['python-2.7.0', 'pyvariants-2']) + + # Now verify that we correctly get python-2.6.8 when the orderer demands it. + orderers = [PerFamilyOrder({ + "python": VersionSplitPackageOrder(Version("2.6.8")), + })] + r = ResolvedContext( + ["pyvariants", "!nada"], + package_orderers=orderers, + package_paths=[packages_path], + ) + resolved = [x.qualified_package_name for x in r.resolved_packages] + self.assertEqual(resolved, ['python-2.6.8', 'pyvariants-2']) + + def test_orderer_package_argument(self): + """Test that the packages argument to an orderer gives expected results.""" + from rez.package_order import VersionSplitPackageOrder + from rez.version import Version + + packages_path = self.data_path("solver", "packages") + + # Verify that the orderer applies to all packages. + orderers = [VersionSplitPackageOrder(Version("2.6.8"))] + r = ResolvedContext( + ["python"], + package_orderers=orderers, + package_paths=[packages_path], + ) + resolved = [x.qualified_package_name for x in r.resolved_packages] + self.assertEqual(resolved, ['python-2.6.8']) + + # Verify that the orderer applies to a specified package. + orderers = [VersionSplitPackageOrder(Version("2.6.8"), packages="python")] + r = ResolvedContext( + ["python"], + package_orderers=orderers, + package_paths=[packages_path], + ) + resolved = [x.qualified_package_name for x in r.resolved_packages] + self.assertEqual(resolved, ['python-2.6.8']) + + # Verify that the orderer does not apply to a packages that are not requested. + orderers = [VersionSplitPackageOrder(Version("2.6.8"), packages="pyfoo")] + r = ResolvedContext( + ["python"], + package_orderers=orderers, + package_paths=[packages_path], + ) + resolved = [x.qualified_package_name for x in r.resolved_packages] + self.assertEqual(resolved, ['python-2.7.0']) + if __name__ == '__main__': unittest.main() diff --git a/src/rez/tests/test_packages_order.py b/src/rez/tests/test_packages_order.py index 702963f5f..1138b86fe 100644 --- a/src/rez/tests/test_packages_order.py +++ b/src/rez/tests/test_packages_order.py @@ -53,11 +53,6 @@ def _test_pod(self, orderer): class TestAbstractPackageOrder(TestBase): """Test case for the abstract PackageOrder class""" - def test_reorder(self): - """Validate reorder is not implemented""" - with self.assertRaises(NotImplementedError): - PackageOrder().reorder([]) - def test_to_pod(self): """Validate to_pod is not implemented""" self.assertRaises(NotImplementedError, PackageOrder().to_pod) diff --git a/src/rez/version/_version.py b/src/rez/version/_version.py index 2114f5bf5..42c2caa4a 100644 --- a/src/rez/version/_version.py +++ b/src/rez/version/_version.py @@ -28,8 +28,11 @@ class _ReversedComparable(_Common): def __init__(self, value): self.value = value + def __eq__(self, other): + return self.value == other.value + def __lt__(self, other): - return not (self.value < other.value) + return self.value > other.value def __gt__(self, other): return not (self < other or self == other) @@ -41,7 +44,7 @@ def __ge__(self, other): return not self < other def __str__(self): - return "reverse(%s)" % str(self.value) + return f"reverse({self.value!r})" def __repr__(self): return "reverse(%r)" % self.value From 1624f4ff74fc23feac630ef294d051c60d98996c Mon Sep 17 00:00:00 2001 From: BryceGattis <36783788+BryceGattis@users.noreply.github.com> Date: Fri, 29 Mar 2024 11:32:04 -0500 Subject: [PATCH 19/68] Add releasing packages documentation (#1689) Signed-off-by: Bryce Gattis --- docs/README.md | 7 +++++-- docs/source/index.rst | 1 + docs/source/releasing_packages.rst | 27 +++++++++++++++++++++++++++ src/rez/rezconfig.py | 2 +- 4 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 docs/source/releasing_packages.rst diff --git a/docs/README.md b/docs/README.md index 5c94e70ae..aba4ad4da 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,9 @@ # Build instructions -To build the docs you must use Python 3.11. +To build the docs you must install the following requirements: + +- GNU Make (Linux + Mac only) +- Python 3.11 To create a build environment run the following commands: ```python @@ -9,7 +12,7 @@ source .venv/bin/activate pip install -r docs/requirements.txt cd docs -make html +make html # .\make html on Windows ``` # Example Headers diff --git a/docs/source/index.rst b/docs/source/index.rst index 12196b605..676021b0f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -15,6 +15,7 @@ Welcome to rez's documentation! getting_started basic_concepts building_packages + releasing_packages context variants guides/index diff --git a/docs/source/releasing_packages.rst b/docs/source/releasing_packages.rst new file mode 100644 index 000000000..a75ad5f1d --- /dev/null +++ b/docs/source/releasing_packages.rst @@ -0,0 +1,27 @@ +================== +Releasing packages +================== + +Rez packages can be built and deployed to the :data:`release_packages_path` +using the :ref:`rez-release` tool. This tool performs the following actions: + +* All :doc:`actions ` that the ``rez-build`` tool performs. +* Executes all configured :data:`release_hooks`. +* Executes all configured :gh-rez:`src/rezplugins/release_vcs` plugins. + +When to release vs build +============================ +Packages *can* be installed to the :data:`release_packages_path` manually +by running :option:`rez-build -i --prefix /path/to/repo `, so why would you use +``rez-release``? + +Well, here are a few benefits of ``rez-release``: + +* The package will automatically go to the configured :data:`release_packages_path`, whereas :ref:`rez-build` will go to the :data:`local_packages_path` by default. +* Tests being run by with the :ref:`rez-test` tool can run specifically prior to release, ensuring that releases pass any configured tests first. +* Automatic sanity checks to ensure local repo is ready for release. +* Automatic VCS tagging. +* Many :ref:`helpful package attributes ` are automatically added to the released package definition file. + +If you're working locally, it these additional steps and checks may slow you +down, so it may be better to stick with :ref:`rez-build`. diff --git a/src/rez/rezconfig.py b/src/rez/rezconfig.py index 788813e50..d5366e974 100644 --- a/src/rez/rezconfig.py +++ b/src/rez/rezconfig.py @@ -837,7 +837,7 @@ # a plugin listed here is not present, a warning message is printed. Note that a # release hook plugin being loaded does not mean it will run. It needs to be # listed here as well. Several built-in release hooks are available, see -# rezplugins/release_hook. +# :gh-rez:`src/rezplugins/release_hook`. release_hooks = [] # Prompt for release message using an editor. If set to False, there will be From b9eb38a075e65d857ca0c3a054b39d823e9fd730 Mon Sep 17 00:00:00 2001 From: BryceGattis <36783788+BryceGattis@users.noreply.github.com> Date: Fri, 29 Mar 2024 17:37:32 -0500 Subject: [PATCH 20/68] Improve clarify of early binding functions documentation (#1677) Improve clarify of early binding functions documentation by documenting what is accessible within an early function. Signed-off-by: Bryce Gattis --- docs/source/building_packages.rst | 2 ++ docs/source/environment.rst | 4 ++-- docs/source/package_definition.rst | 18 +++++++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/source/building_packages.rst b/docs/source/building_packages.rst index c72c76d13..0cf3414fb 100644 --- a/docs/source/building_packages.rst +++ b/docs/source/building_packages.rst @@ -23,6 +23,8 @@ package with two python-based variants might look like this: The current working directory is set to the *build path* during a build. +.. _the-build-environment: + The Build Environment ===================== diff --git a/docs/source/environment.rst b/docs/source/environment.rst index 2030aa500..7045d5586 100644 --- a/docs/source/environment.rst +++ b/docs/source/environment.rst @@ -121,8 +121,8 @@ removed**: Build Environment Variables =========================== -These are variables that rez generates within a build environment, in addition -to those listed :ref:`here `. +These are variables that rez generates within a :ref:`build environment `, in addition +to context environment variables listed :ref:`here `. .. glossary:: diff --git a/docs/source/package_definition.rst b/docs/source/package_definition.rst index 8223ccdbf..b4ad4ab3d 100644 --- a/docs/source/package_definition.rst +++ b/docs/source/package_definition.rst @@ -79,11 +79,19 @@ and *late binding* functions - and these are decorated using ``@early`` and ``@l Early Binding Functions +++++++++++++++++++++++ -Early binding functions use the ``@early`` decorator. They are evaluated at *build time*, hence the -'early' in 'early binding'. Any package attribute can be implemented as an early binding function. - -Here is an example of an :attr:`authors` attribute that is automatically set to the contributors of the -package's git project: +Early binding functions use the ``@early`` decorator. They are evaluated at +*build time*, hence the 'early' in 'early binding' and their definition persists +in the installed ``package.py``. By 'build time', it is meant that they are +evaluated before the resolve has occurred, and as such, before the +:ref:`build environment ` has been constructed. Therefore +there are some important distinctions that set early-bound functions apart from +other function attributes: + +- The :attr:`this` object only exposes package attributes. Nothing else is accessible when inside an early-bound function. +- No rez-set :doc:`environment variables ` can be accessed inside an early bound function. + +Any package attribute can be implemented as an early binding function. Here is an example of an :attr:`authors` +attribute that is automatically set to the contributors of the package's git project: .. code-block:: python From 3c75a195bda682e48088c0e910d358a45edc95cd Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> Date: Sat, 30 Mar 2024 12:11:44 -0400 Subject: [PATCH 21/68] Bump version to 3.1.0 (#1702) Signed-off-by: Jean-Christophe Morin --- .mailmap | 3 +++ CHANGELOG.md | 31 +++++++++++++++++++++++++++++++ src/rez/utils/_version.py | 2 +- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index fd16d38b8..84b550271 100644 --- a/.mailmap +++ b/.mailmap @@ -133,6 +133,9 @@ Brendan Abel <007brendan@gmail.com> Brendan Abel <007brendan@gmail.com> Brendan Abel <007brendan@gmail.com> +Bryce Gattis <36783788+BryceGattis@users.noreply.github.com> +Bryce Gattis <36783788+BryceGattis@users.noreply.github.com> <69012021+brycegbrazen@users.noreply.github.com> + David Lai davidlatwe Fabio Piparo diff --git a/CHANGELOG.md b/CHANGELOG.md index 6211ff207..895889e4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,37 @@ +## 3.1.0 (2024-03-30) +[Source](https://github.com/AcademySoftwareFoundation/rez/tree/3.1.0) | [Diff](https://github.com/AcademySoftwareFoundation/rez/compare/3.3.0...3.1.0) + +### Features + +- Add support for `virtualenv` in the installer [\#1645](https://github.com/AcademySoftwareFoundation/rez/pull/1645) ([@Pixel-Minions](https://github.com/Pixel-Minions)) +- Add `-e/--editable` flag to the installer to create an editable install [\#1672](https://github.com/AcademySoftwareFoundation/rez/pull/1672) ([@JeanChristopheMorinPerso](https://github.com/JeanChristopheMorinPerso)) + +### Fixes + +- Add retry mechanism when renaming folders on Windows [\#1666](https://github.com/AcademySoftwareFoundation/rez/pull/1666) ([@loonghao](https://github.com/loonghao)) +- Apply package orderers on variants [\#1684](https://github.com/AcademySoftwareFoundation/rez/pull/1684) ([@isohedronpipeline](https://github.com/isohedronpipeline) and [@pmolodo](https://github.com/pmolodo)) + +### Documentation + +- Remove the note about Python 2.7 compatibility from the docs [\#1644](https://github.com/AcademySoftwareFoundation/rez/pull/1644) ([@vergeev](https://github.com/vergeev)) +- Add clear information on how to contact maintainers [\#1659](https://github.com/AcademySoftwareFoundation/rez/pull/1659) ([@JeanChristopheMorinPerso](https://github.com/JeanChristopheMorinPerso)) +- Installation instructions now include how to download rez [\#1660](https://github.com/AcademySoftwareFoundation/rez/pull/1660) ([@JeanChristopheMorinPerso](https://github.com/JeanChristopheMorinPerso)) +- Add development environment docs to [CONTRIBUTING.md](./CONTRIBUTING.md) [\#1633](https://github.com/AcademySoftwareFoundation/rez/pull/1633) ([@BryceGattis](https://github.com/BryceGattis)) +- Improve clarity and expliciteness of `rez-env --command` flag help [\#1682](https://github.com/AcademySoftwareFoundation/rez/pull/1682) ([@BryceGattis](https://github.com/BryceGattis)) +- Add releasing packages documentation [\#1689](https://github.com/AcademySoftwareFoundation/rez/pull/1689) ([@BryceGattis](https://github.com/BryceGattis)) +- Improve clarify of early binding functions documentation [\#1677](https://github.com/AcademySoftwareFoundation/rez/pull/1677) ([@BryceGattis](https://github.com/BryceGattis)) + +### Miscellaneous + +- Remove Python2-related `__future__` imports [\#1640](https://github.com/AcademySoftwareFoundation/rez/pull/1640) ([@vergeev](https://github.com/vergeev)) +- Replace usages of `rez.vendor.enum` with the built-in enum module [\#1649](https://github.com/AcademySoftwareFoundation/rez/pull/1649) ([@predat](https://github.com/predat)) +- Remove `rez.backport` [\#1634](https://github.com/AcademySoftwareFoundation/rez/pull/1634) ([@BryceGattis](https://github.com/BryceGattis)) +- Remove `rez.utils.json` [\#1673](https://github.com/AcademySoftwareFoundation/rez/pull/1673) ([@BryceGattis](https://github.com/BryceGattis)) +- Remove `rez.utils.py23` and cleanup more python 2.7 leftovers [\#1678](https://github.com/AcademySoftwareFoundation/rez/pull/1678) ([@wandth](https://github.com/wandth)) + ## 3.0.0 (2024-02-08) [Source](https://github.com/AcademySoftwareFoundation/rez/tree/3.0.0) | [Diff](https://github.com/AcademySoftwareFoundation/rez/compare/2.114.1...3.0.0) diff --git a/src/rez/utils/_version.py b/src/rez/utils/_version.py index 506fb1000..ceda9738d 100644 --- a/src/rez/utils/_version.py +++ b/src/rez/utils/_version.py @@ -4,4 +4,4 @@ # Update this value to version up Rez. Do not place anything else in this file. # Using .devN allows us to run becnmarks and create proper benchmark reports on PRs. -_rez_version = "3.0.0" +_rez_version = "3.1.0" From d5c8643f127af4028179219e8a45a081adfa9938 Mon Sep 17 00:00:00 2001 From: Jer Date: Mon, 1 Apr 2024 18:09:52 +0200 Subject: [PATCH 22/68] Fix typo in "Releasing packages" docs (#1704) Signed-off-by: Jer --- docs/source/releasing_packages.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/releasing_packages.rst b/docs/source/releasing_packages.rst index a75ad5f1d..ba4377e1a 100644 --- a/docs/source/releasing_packages.rst +++ b/docs/source/releasing_packages.rst @@ -23,5 +23,5 @@ Well, here are a few benefits of ``rez-release``: * Automatic VCS tagging. * Many :ref:`helpful package attributes ` are automatically added to the released package definition file. -If you're working locally, it these additional steps and checks may slow you +If you're working locally, these additional steps and checks may slow you down, so it may be better to stick with :ref:`rez-build`. From 9610630a38e6acffa0f84989a2d82ab4ecff4528 Mon Sep 17 00:00:00 2001 From: BryceGattis <36783788+BryceGattis@users.noreply.github.com> Date: Sat, 6 Apr 2024 09:54:47 -0500 Subject: [PATCH 23/68] Remove unnecessary variable assignment in rez.deprecations (#1696) Signed-off-by: Bryce Gattis --- src/rez/deprecations.py | 4 ++-- src/rez/tests/test_config.py | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/rez/deprecations.py b/src/rez/deprecations.py index 831512563..40b3f5e31 100644 --- a/src/rez/deprecations.py +++ b/src/rez/deprecations.py @@ -7,12 +7,12 @@ def warn(message, category, pre_formatted=False, stacklevel=1, filename=None, **kwargs): """ - Wrapper around warnings.warn that allows to passa a pre-formatter + Wrapper around warnings.warn that allows to pass a pre-formatter warning message. This allows to warn about things that aren't coming from python files, like environment variables, etc. """ if not pre_formatted: - message = warnings.warn( + warnings.warn( message, category=category, stacklevel=stacklevel + 1, **kwargs ) return diff --git a/src/rez/tests/test_config.py b/src/rez/tests/test_config.py index b64b66c05..a8bf2064b 100644 --- a/src/rez/tests/test_config.py +++ b/src/rez/tests/test_config.py @@ -12,7 +12,7 @@ from rez.system import system from rez.utils.data_utils import RO_AttrDictWrapper from rez.packages import get_developer_package -from rez.deprecations import RezDeprecationWarning +from rez.deprecations import RezDeprecationWarning, warn import os import os.path import subprocess @@ -332,13 +332,13 @@ def test_deprecation_from_user_config(self): # https://docs.python.org/3.8/library/os.path.html#os.path.expanduser os.environ["USERPROFILE"] = user_home config = Config._create_main_config() - with self.assertWarns(RezDeprecationWarning) as warn: + with self.assertWarns(RezDeprecationWarning) as warning: _ = config.data # Assert just to ensure the test was set up properly. self.assertEqual(config.data["packages_path"], ["/tmp/asd"]) self.assertEqual( - str(warn.warning), + str(warning.warning), "config setting named 'packages_path' is deprecated and will be removed in 0.0.0.", ) @@ -356,13 +356,13 @@ def test_deprecation_from_env_var(self): os.environ["REZ_PACKAGES_PATH"] = "/tmp/asd2" os.environ["REZ_DISABLE_HOME_CONFIG"] = "1" config = Config._create_main_config() - with self.assertWarns(RezDeprecationWarning) as warn: + with self.assertWarns(RezDeprecationWarning) as warning: _ = config.data # Assert just to ensure the test was set up properly. self.assertEqual(config.data["packages_path"], ["/tmp/asd2"]) self.assertEqual( - str(warn.warning), + str(warning.warning), "config setting named 'packages_path' (configured through the " "REZ_PACKAGES_PATH environment variable) is deprecated and will " "be removed in 0.0.0.", @@ -373,18 +373,23 @@ def test_deprecation_from_env_var(self): os.environ["REZ_PACKAGES_PATH_JSON"] = '["/tmp/asd2"]' os.environ["REZ_DISABLE_HOME_CONFIG"] = "1" config = Config._create_main_config() - with self.assertWarns(RezDeprecationWarning) as warn: + with self.assertWarns(RezDeprecationWarning) as warning: _ = config.data # Assert just to ensure the test was set up properly. self.assertEqual(config.data["packages_path"], ["/tmp/asd2"]) self.assertEqual( - str(warn.warning), + str(warning.warning), "config setting named 'packages_path' (configured through the " "REZ_PACKAGES_PATH_JSON environment variable) is deprecated and will " "be removed in 0.0.0.", ) + def test_non_preformatted_warning(self): + with self.assertWarns(DeprecationWarning) as warning: + warn('Warning Message', DeprecationWarning, pre_formatted=False) + self.assertEqual(str(warning.warning), 'Warning Message') + if __name__ == "__main__": unittest.main() From 1b9c72a046bfe19f9267985f5714c73439d2a460 Mon Sep 17 00:00:00 2001 From: Bryce Gattis <69012021+brycegbrazen@users.noreply.github.com> Date: Sat, 13 Apr 2024 13:45:08 -0500 Subject: [PATCH 24/68] Convert all plugin rezconfig to rezconfig.py (#1692) Signed-off-by: brycegbrazen Signed-off-by: Jean-Christophe Morin Co-authored-by: Jean-Christophe Morin --- MANIFEST.in | 3 +- setup.py | 1 - src/build_utils/license/apply_copyright | 1 - src/rezplugins/build_process/rezconfig | 0 src/rezplugins/build_process/rezconfig.py | 2 + src/rezplugins/build_system/rezconfig | 21 ----- .../{rezconfig => rezconfig.py} | 20 +++-- .../release_hook/{rezconfig => rezconfig.py} | 89 ++++++++++--------- src/rezplugins/release_vcs/rezconfig | 3 - src/rezplugins/release_vcs/rezconfig.py | 8 ++ src/rezplugins/shell/rezconfig | 40 --------- src/rezplugins/shell/rezconfig.py | 45 ++++++++++ 12 files changed, 117 insertions(+), 116 deletions(-) delete mode 100644 src/rezplugins/build_process/rezconfig create mode 100644 src/rezplugins/build_process/rezconfig.py delete mode 100644 src/rezplugins/build_system/rezconfig rename src/rezplugins/package_repository/{rezconfig => rezconfig.py} (87%) rename src/rezplugins/release_hook/{rezconfig => rezconfig.py} (69%) delete mode 100644 src/rezplugins/release_vcs/rezconfig create mode 100644 src/rezplugins/release_vcs/rezconfig.py delete mode 100644 src/rezplugins/shell/rezconfig create mode 100644 src/rezplugins/shell/rezconfig.py diff --git a/MANIFEST.in b/MANIFEST.in index c646b6968..26b821f83 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,8 +1,7 @@ include src/rez/data/* -include src/rez/rezconfig include src/rez/completion/* include src/rez/vendor/distlib/*.exe include src/rezgui/rezguiconfig include src/rezgui/icons/* recursive-include src/rez README* -recursive-include src/rezplugins *.cmake Doxyfile rezconfig +recursive-include src/rezplugins *.cmake Doxyfile diff --git a/setup.py b/setup.py index 34b9b396d..ad11b1edb 100644 --- a/setup.py +++ b/setup.py @@ -76,7 +76,6 @@ def find_files(pattern, path=None, root="rez"): find_files('*', 'data') + find_files('*.exe', 'vendor/distlib'), 'rezplugins': - find_files('rezconfig', root='rezplugins') + find_files('*.cmake', 'build_system', root='rezplugins') + find_files('*', 'build_system/template_files', root='rezplugins'), 'rezgui': diff --git a/src/build_utils/license/apply_copyright b/src/build_utils/license/apply_copyright index 880cfa583..daa048eb9 100755 --- a/src/build_utils/license/apply_copyright +++ b/src/build_utils/license/apply_copyright @@ -7,7 +7,6 @@ fi # remove copyright find ./src/rez/data -name '*.py' > .lic.tmp -find ./src/rez/backport -name '*.py' >> .lic.tmp cat .lic.tmp | xargs -i ./src/build_utils/license/change_copyright -so {} # add copyright diff --git a/src/rezplugins/build_process/rezconfig b/src/rezplugins/build_process/rezconfig deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/rezplugins/build_process/rezconfig.py b/src/rezplugins/build_process/rezconfig.py new file mode 100644 index 000000000..ac31011e1 --- /dev/null +++ b/src/rezplugins/build_process/rezconfig.py @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright Contributors to the Rez Project diff --git a/src/rezplugins/build_system/rezconfig b/src/rezplugins/build_system/rezconfig deleted file mode 100644 index 18ddea371..000000000 --- a/src/rezplugins/build_system/rezconfig +++ /dev/null @@ -1,21 +0,0 @@ -# TODO remove this file in PR for https://github.com/AcademySoftwareFoundation/rez/issues/525, -# it is unused - -cmake: - # The name of the CMake build system to use, valid options are - # eclipse, make, xcode and codeblocks. - build_system: make - - # The name of the CMake build target to use, valid options are Debug, - # Release and RelWithDebInfo. - build_target: Release - - # A list of default arguments to be passed to the cmake binary. - cmake_args: - - '-DCMAKE_SKIP_RPATH=1' - - # Optionally specify an explicit cmake executable to use for building. - cmake_binary: - - # If True, install pyc files when the 'rez_install_python' macro is used. - install_pyc: true diff --git a/src/rezplugins/package_repository/rezconfig b/src/rezplugins/package_repository/rezconfig.py similarity index 87% rename from src/rezplugins/package_repository/rezconfig rename to src/rezplugins/package_repository/rezconfig.py index 811b8215d..85eba726c 100644 --- a/src/rezplugins/package_repository/rezconfig +++ b/src/rezplugins/package_repository/rezconfig.py @@ -1,15 +1,19 @@ -filesystem: +# SPDX-License-Identifier: Apache-2.0 +# Copyright Contributors to the Rez Project + + +filesystem = { # The mechanism used to create the lockfile. If set to 'default', this will # use hardlinks if the 'os.link' method is present, otherwise mkdir is used. # It can also be explicitly set to use only 'hardlink', or only 'mkdir'. # Valid options are 'default', 'mkdir', or 'hardlink' - file_lock_type: default + "file_lock_type": "default", # The timeout to use when creating file locks. This is done when a variant is # installed into an existing package, to prevent multiple file writes at # once (which could result in a variant install getting lost). The timeout # value is in seconds. A value of zero indicates no timeout. - file_lock_timeout: 10 + "file_lock_timeout": 10, # The relative directory, under the repository location, where file locks # are created. You might need to use this option when file permissions are @@ -21,13 +25,13 @@ # # Note: The directory can have any name, but we suggest '.lock' as the # standard convention. - file_lock_dir: + "file_lock_dir": None, # If True, verify that a potential package directory contains a package.py / # package.yaml file before treating it as a package. There *shouldn't* be # non-packages in these directories, and the solver is faster if this value # is False, because a lot of file stats are avoided. - check_package_definition_files: false + "check_package_definition_files": False, # A list of filenames that are expected to contain Rez definitions. # The list will be checked in top to bottom order, and the first filename @@ -39,5 +43,7 @@ # released package filename, regardless of the definition filename present # in the source. # - package_filenames: - - 'package' + "package_filenames": [ + "package" + ] +} diff --git a/src/rezplugins/release_hook/rezconfig b/src/rezplugins/release_hook/rezconfig.py similarity index 69% rename from src/rezplugins/release_hook/rezconfig rename to src/rezplugins/release_hook/rezconfig.py index 1dd9ce24d..acec27c73 100644 --- a/src/rezplugins/release_hook/rezconfig +++ b/src/rezplugins/release_hook/rezconfig.py @@ -1,18 +1,25 @@ -emailer: +# SPDX-License-Identifier: Apache-2.0 +# Copyright Contributors to the Rez Project + + +emailer = { # SMTP host. - smtp_host: '' + "smtp_host": '', # SMTP port. - smtp_port: 25 + "smtp_port": 25, # The address that post-release emails appear to come from. - sender: '{system.user}@rez-release.com' + "sender": '{system.user}@rez-release.com', # List of recipients of post-release emails; OR, path to recipients config # file (see emailer-recipients-example.yaml). If this is a string that # contains '@' and doesn't refer to a filepath, then it's treated as an # email address. - recipients: [] + "recipients": [], + + # Subject format - supports the same object formatting available in 'body' + "subject": '[rez] [release] {system.user} released {package.qualified_name}', # Message format. Available objects for formatting are: # - package: The package that is being released. @@ -25,43 +32,42 @@ # - variants: Namespace for info about the variants that were released: # - count: The number of variants that were released; # - paths: Newline-separated paths to the root of each variant. - body: | - Package '{package.qualified_name}' was released by {system.user}@{system.fqdn}. - - USER: {system.user} - PACKAGE: {package.qualified_name} - RELEASED TO: {release.path} - PREVIOUS VERSION: {release.previous_version} - REZ VERSION: {system.rez_version} + "body": """ +Package '{package.qualified_name}' was released by {system.user}@{system.fqdn}. - {variants.count} VARIANTS: - {variants.paths} +USER: {system.user} +PACKAGE: {package.qualified_name} +RELEASED TO: {release.path} +PREVIOUS VERSION: {release.previous_version} +REZ VERSION: {system.rez_version} - MESSAGE: - {release.message} +{variants.count} VARIANTS: +{variants.paths} - CHANGELOG: - {release.changelog} +MESSAGE: +{release.message} - # Subject format - supports the same object formatting available in 'body' - subject: '[rez] [release] {system.user} released {package.qualified_name}' +CHANGELOG: +{release.changelog} +""".strip() +} -command: +command = { # If true, print the commands that are being run - print_commands: true + "print_commands": True, # If true, print output of commands. - print_output: true + "print_output": True, # If true, print failed commands to stderr - print_error: true + "print_error": True, # If true, cancel the package release if a pre-* command fails. - cancel_on_error: true + "cancel_on_error": True, # If true, skip all commands after a failed command. This does not cancel # the package release. - stop_on_error: true + "stop_on_error": True, # List of commands to execute prior to build, in given order. # Each item is a dict containing: @@ -82,8 +88,7 @@ # - release: Namespace for info about the current release, contains: # - path: Installation path of release. # - # Also, any environment variables references in command arguments are - # expanded also. + # Any environment variables references in command arguments are expanded. # # Example: # pre_build_commands @@ -91,35 +96,37 @@ # args: '-a -l' # user: root # - pre_build_commands: [] + "pre_build_commands": [], # Same expected values as pre_build_commands - pre_release_commands: [] + "pre_release_commands": [], # Same expected values as pre_build_commands - post_release_commands: [] + "post_release_commands": [] +} -amqp: +amqp = { # host server, or '{host}:{port}' - host: '' + "host": '', # userid - userid: '' + "userid": '', # password - password: '' + "password": '', # connection timeout - connect_timeout: 10 + "connect_timeout": 10, # exchange name - exchange_name: '' + "exchange_name": '', # exchange routing key - exchange_routing_key: 'REZ.PACKAGE.RELEASED' + "exchange_routing_key": 'REZ.PACKAGE.RELEASED', # message delivery mode - message_delivery_mode: 1 + "message_delivery_mode": 1, # extra message attributes to be published - message_attributes: {} + "message_attributes": {} +} diff --git a/src/rezplugins/release_vcs/rezconfig b/src/rezplugins/release_vcs/rezconfig deleted file mode 100644 index a0a963d90..000000000 --- a/src/rezplugins/release_vcs/rezconfig +++ /dev/null @@ -1,3 +0,0 @@ -git: - # If false, cancel a package release if there is no upstream branch. - allow_no_upstream: false diff --git a/src/rezplugins/release_vcs/rezconfig.py b/src/rezplugins/release_vcs/rezconfig.py new file mode 100644 index 000000000..411fe38a8 --- /dev/null +++ b/src/rezplugins/release_vcs/rezconfig.py @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright Contributors to the Rez Project + + +git = { + # If false, cancel a package release if there is no upstream branch. + "allow_no_upstream": False +} diff --git a/src/rezplugins/shell/rezconfig b/src/rezplugins/shell/rezconfig deleted file mode 100644 index 392a8b655..000000000 --- a/src/rezplugins/shell/rezconfig +++ /dev/null @@ -1,40 +0,0 @@ -sh: - prompt: '>' - executable_fullpath: null - -bash: - prompt: '>' - executable_fullpath: null - -csh: - prompt: '>' - executable_fullpath: null - -tcsh: - prompt: '>' - executable_fullpath: null - -zsh: - prompt: '%' - executable_fullpath: null - -cmd: - prompt: '$G' - additional_pathext: ['.PY'] - executable_fullpath: null - -powershell: - prompt: '> $ ' - additional_pathext: ['.PY'] - executable_fullpath: null - execution_policy: null - -pwsh: - prompt: '> $ ' - additional_pathext: ['.PY'] - executable_fullpath: null - execution_policy: null - -gitbash: - prompt: '>' - executable_fullpath: null diff --git a/src/rezplugins/shell/rezconfig.py b/src/rezplugins/shell/rezconfig.py new file mode 100644 index 000000000..549cc6605 --- /dev/null +++ b/src/rezplugins/shell/rezconfig.py @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright Contributors to the Rez Project + + +sh = { + "prompt": '>', + "executable_fullpath": None +} +bash = { + "prompt": '>', + "executable_fullpath": None +} +csh = { + "prompt": '>', + "executable_fullpath": None +} +tcsh = { + "prompt": '>', + "executable_fullpath": None +} +zsh = { + "prompt": '%', + "executable_fullpath": None +} +cmd = { + "prompt": '$G', + "additional_pathext": [".PY"], + "executable_fullpath": None +} +powershell = { + "prompt": '> $ ', + "additional_pathext": [".PY"], + "executable_fullpath": None, + "execution_policy": None +} +pwsh = { + "prompt": '> $ ', + "additional_pathext": [".PY"], + "executable_fullpath": None, + "execution_policy": None +} +gitbash = { + "prompt": '>', + "executable_fullpath": None +} From cb9f1366f8fa8292b92b6a7024226ad8d4d97f58 Mon Sep 17 00:00:00 2001 From: BryceGattis <36783788+BryceGattis@users.noreply.github.com> Date: Sat, 13 Apr 2024 13:53:55 -0500 Subject: [PATCH 25/68] Add plugin documentation page (#1703) Signed-off-by: Bryce Gattis --- docs/source/index.rst | 1 + docs/source/plugins.rst | 140 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 docs/source/plugins.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index 676021b0f..405d33718 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -31,6 +31,7 @@ Welcome to rez's documentation! managing_packages caching pip + plugins .. toctree:: :maxdepth: 2 diff --git a/docs/source/plugins.rst b/docs/source/plugins.rst new file mode 100644 index 000000000..da68cf226 --- /dev/null +++ b/docs/source/plugins.rst @@ -0,0 +1,140 @@ +======= +Plugins +======= + +Rez is designed around the concept of plugins. Plugins can be used to extend rez's functionalities without modifying any of rez's source code. + +Rez comes with built-in plugins that are located at :gh-rez:`src/rezplugins`. New plugins are encouraged to be developed out-of-tree (outside rez). + +List installed plugins +====================== + +Currently installed plugins can be queried by running :option:`rez -i` + +.. code-block:: console + + $ rez -i + + Rez 2.113.0 + + PLUGIN TYPE NAME DESCRIPTION STATUS + ----------- ---- ----------- ------ + build process local Builds packages on local host loaded + build process remote Builds packages on remote hosts loaded + build system cmake CMake-based build system loaded + build system custom Package-defined build command loaded + build system make Make-based build system loaded + package repository filesystem Filesystem-based package repository loaded + package repository memory In-memory package repository loaded + release hook amqp Publishes a message to the broker. loaded + release hook command Executes pre- and post-release shell commands loaded + release hook emailer Sends a post-release email loaded + release vcs git Git version control loaded + release vcs hg Mercurial version control loaded + release vcs stub Stub version control system, for testing purposes loaded + release vcs svn FAILED: No module named 'pysvn' + shell cmd Windows Command Prompt (DOS) shell. loaded + shell gitbash Git Bash (for Windows) shell loaded + shell powershell Windows PowerShell 5 loaded + shell pwsh PowerShell Core 6+ loaded + + +Configuring plugins +=================== + +Plugins can be configured by adding a ``plugins`` key to your ``rezconfig.py`` +like this: + +.. code-block:: python + + plugins = { + "filesystem": {} + } + +Existing plugin types +===================== + +- :gh-rez:`build_process ` +- :gh-rez:`build_system ` +- :gh-rez:`command ` +- :gh-rez:`package_repository ` +- :gh-rez:`release_hook ` +- :gh-rez:`release_vcs ` +- :gh-rez:`shell ` + +Developing your own plugin +========================== + +Rez plugins require a specific folder structure as follows: + +.. code-block:: text + + /plugin_type + /__init__.py (adds plugin path to rez) + /rezconfig.py (defines configuration settings for your plugin) + /plugin_file1.py (your plugin file) + /plugin_file2.py (your plugin file) + etc. + +To make your plugin available to rez, you can install them directly under +``src/rezplugins`` (that's called a namespace package) or you can add +the path to :envvar:`REZ_PLUGIN_PATH`. + +Registering subcommands +----------------------- + +Optionally, plugins can provide new ``rez`` subcommands. + +To register a plugin and expose a new subcommand, the plugin module: + +- MUST have a module-level docstring (used as the command help) +- MUST provide a `setup_parser()` function +- MUST provide a `command()` function +- MUST provide a `register_plugin()` function +- SHOULD have a module-level attribute `command_behavior` + +For example, a plugin named 'foo' and this is the ``foo.py`` in the plugin type +root directory: + +.. code-block:: python + :caption: foo.py + + """The docstring for command help, this is required.""" + from rez.command import Command + + command_behavior = { + "hidden": False, # optional: bool + "arg_mode": None, # optional: None, "passthrough", "grouped" + } + + def setup_parser(parser, completions=False): + parser.add_argument("--hello", ...) + + def command(opts, parser=None, extra_arg_groups=None): + if opts.hello: + print("world") + + class CommandFoo(Command): + # This is where you declare the settings the plugin accepts. + schema_dict = { + "str_option": str, + "int_option": int, + ... + } + @classmethod + def name(cls): + return "foo" + + def register_plugin(): + return CommandFoo + +All new plugin types must define an ``__init__.py`` in their root directory +so that the plugin manager will find them. + +.. code-block:: python + :caption: __init__.py + + from rez.plugin_managers import extend_path + __path__ = extend_path(__path__, __name__) + + From c5b2a611f15b5eec3f1a0fa709aafcad19c7b1c5 Mon Sep 17 00:00:00 2001 From: BryceGattis <36783788+BryceGattis@users.noreply.github.com> Date: Sat, 13 Apr 2024 13:54:41 -0500 Subject: [PATCH 26/68] Make gh-rez external link dynamic in the documentation (#1707) Signed-off-by: Bryce Gattis --- docs/source/conf.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index ed9fad1cd..767e47042 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -99,8 +99,17 @@ # -- Options for extlinks extension ----------------------------------------- # https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html +blob_ref = "main" +if os.environ.get("READTHEDOCS"): + if os.environ["READTHEDOCS_VERSION_TYPE"] == "external": + blob_ref = os.environ["READTHEDOCS_GIT_COMMIT_HASH"] + else: + blob_ref = os.environ["READTHEDOCS_GIT_IDENTIFIER"] + +gh_rez_url = f"https://github.com/AcademySoftwareFoundation/rez/blob/{blob_ref}/%s" + extlinks = { - 'gh-rez': ('https://github.com/AcademySoftwareFoundation/rez/blob/master/%s', '%s'), + 'gh-rez': (gh_rez_url, '%s'), } # -- Options for todo extension --------------------------------------------- From 9b01d0b4b4c8e8e11fdc614151ad6bc6a439fef9 Mon Sep 17 00:00:00 2001 From: Robert Minsk <38872275+cfxegbert@users.noreply.github.com> Date: Sat, 13 Apr 2024 12:08:15 -0700 Subject: [PATCH 27/68] Add symlink locking for filesystems that do not support hardlinks (#1708) Signed-off-by: Robert Minsk --- src/rezplugins/package_repository/filesystem.py | 4 +++- src/rezplugins/package_repository/rezconfig.py | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/rezplugins/package_repository/filesystem.py b/src/rezplugins/package_repository/filesystem.py index 5dae0d24a..d0b793b9d 100644 --- a/src/rezplugins/package_repository/filesystem.py +++ b/src/rezplugins/package_repository/filesystem.py @@ -467,7 +467,7 @@ class FileSystemPackageRepository(PackageRepository): """ schema_dict = {"file_lock_timeout": int, "file_lock_dir": Or(None, str), - "file_lock_type": Or("default", "link", "mkdir"), + "file_lock_type": Or("default", "link", "mkdir", "symlink"), "package_filenames": [str]} building_prefix = ".building" @@ -973,6 +973,8 @@ def _lock_package(self, package_name, package_version=None): from rez.vendor.lockfile.mkdirlockfile import MkdirLockFile as LockFile elif _settings.file_lock_type == 'link': from rez.vendor.lockfile.linklockfile import LinkLockFile as LockFile + elif _settings.file_lock_type == 'symlink': + from rez.vendor.lockfile.symlinklockfile import SymlinkLockFile as LockFile path = self.location diff --git a/src/rezplugins/package_repository/rezconfig.py b/src/rezplugins/package_repository/rezconfig.py index 85eba726c..f5b39c27e 100644 --- a/src/rezplugins/package_repository/rezconfig.py +++ b/src/rezplugins/package_repository/rezconfig.py @@ -4,9 +4,8 @@ filesystem = { # The mechanism used to create the lockfile. If set to 'default', this will - # use hardlinks if the 'os.link' method is present, otherwise mkdir is used. - # It can also be explicitly set to use only 'hardlink', or only 'mkdir'. - # Valid options are 'default', 'mkdir', or 'hardlink' + # use hardlinks (link) if the 'os.link' method is present, otherwise mkdir is used. + # Valid options are 'default', 'mkdir', 'link', or 'symlink' "file_lock_type": "default", # The timeout to use when creating file locks. This is done when a variant is From 8decb45cb3ee05ea5187fec3d6912d6bbd1d39dc Mon Sep 17 00:00:00 2001 From: Hal <13111745+loonghao@users.noreply.github.com> Date: Sun, 14 Apr 2024 03:10:42 +0800 Subject: [PATCH 28/68] Fix error caused by weakly referenced package not specifying version range (#1712) Signed-off-by: loonghao --- .../2.0/package.py | 4 ++++ .../2.0/package.py | 6 +++++ src/rez/package_order.py | 22 ++++++++++++------- src/rez/tests/test_completion.py | 3 ++- src/rez/tests/test_packages.py | 4 +++- src/rez/tests/test_solver.py | 17 ++++++++++++++ 6 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 src/rez/data/tests/solver/packages/test_weakly_reference_requires/2.0/package.py create mode 100644 src/rez/data/tests/solver/packages/test_weakly_reference_variant/2.0/package.py diff --git a/src/rez/data/tests/solver/packages/test_weakly_reference_requires/2.0/package.py b/src/rez/data/tests/solver/packages/test_weakly_reference_requires/2.0/package.py new file mode 100644 index 000000000..39740bc9b --- /dev/null +++ b/src/rez/data/tests/solver/packages/test_weakly_reference_requires/2.0/package.py @@ -0,0 +1,4 @@ +name = "test_weakly_reference_requires" +version = "2.0" + +requires = ["~test_variant_split_mid1", "~test_variant_split_mid2"] diff --git a/src/rez/data/tests/solver/packages/test_weakly_reference_variant/2.0/package.py b/src/rez/data/tests/solver/packages/test_weakly_reference_variant/2.0/package.py new file mode 100644 index 000000000..92f704037 --- /dev/null +++ b/src/rez/data/tests/solver/packages/test_weakly_reference_variant/2.0/package.py @@ -0,0 +1,6 @@ +name = "test_weakly_reference_variant" +version = "2.0" + +requires = ["~pyfoo"] + +variants = [["test_variant_split_mid1", "~test_variant_split_mid2-1..3"]] diff --git a/src/rez/package_order.py b/src/rez/package_order.py index a71dbac02..e60662d77 100644 --- a/src/rez/package_order.py +++ b/src/rez/package_order.py @@ -116,8 +116,9 @@ def sort_key(self, package_name, version_like): Args: package_name: (str) The family name of the package we are sorting - version_like: (Version|_LowerBound|_UpperBound|_Bound|VersionRange) - the version-like object you wish to generate a key for + version_like: (Version|_LowerBound|_UpperBound|_Bound|VersionRange|None) + The version-like object to be used as a basis for generating a sort key. + Note that 'None' is also a supported value, which maintains the default sorting order. Returns: Sortable object @@ -126,21 +127,26 @@ def sort_key(self, package_name, version_like): """ if isinstance(version_like, VersionRange): return tuple(self.sort_key(package_name, bound) for bound in version_like.bounds) - elif isinstance(version_like, _Bound): + if isinstance(version_like, _Bound): return (self.sort_key(package_name, version_like.lower), self.sort_key(package_name, version_like.upper)) - elif isinstance(version_like, _LowerBound): + if isinstance(version_like, _LowerBound): inclusion_key = -2 if version_like.inclusive else -1 return self.sort_key(package_name, version_like.version), inclusion_key - elif isinstance(version_like, _UpperBound): + if isinstance(version_like, _UpperBound): inclusion_key = 2 if version_like.inclusive else 1 return self.sort_key(package_name, version_like.version), inclusion_key - elif isinstance(version_like, Version): + if isinstance(version_like, Version): # finally, the bit that we actually use the sort_key_implementation for. return FallbackComparable( self.sort_key_implementation(package_name, version_like), version_like) - else: - raise TypeError(version_like) + if version_like is None: + # As no version range is provided for this package, + # Python's sort preserves the order of equal elements. + # Thus, to maintain the original order, + # we return the same object for all None values. + return 0 + raise TypeError(version_like) def sort_key_implementation(self, package_name, version): """Returns a sort key usable for sorting these packages within the diff --git a/src/rez/tests/test_completion.py b/src/rez/tests/test_completion.py index ef8c390c6..f87629903 100644 --- a/src/rez/tests/test_completion.py +++ b/src/rez/tests/test_completion.py @@ -52,7 +52,8 @@ def _eq(prefix, expected_completions): _eq("", ["bahish", "nada", "nopy", "pybah", "pydad", "pyfoo", "pymum", "pyodd", "pyson", "pysplit", "python", "pyvariants", "test_variant_split_start", "test_variant_split_mid1", - "test_variant_split_mid2", "test_variant_split_end", "missing_variant_requires"]) + "test_variant_split_mid2", "test_variant_split_end", "missing_variant_requires", + "test_weakly_reference_requires", "test_weakly_reference_variant"]) _eq("py", ["pybah", "pydad", "pyfoo", "pymum", "pyodd", "pyson", "pysplit", "python", "pyvariants"]) _eq("pys", ["pyson", "pysplit"]) diff --git a/src/rez/tests/test_packages.py b/src/rez/tests/test_packages.py index 55f5254c6..5e42b0eaf 100644 --- a/src/rez/tests/test_packages.py +++ b/src/rez/tests/test_packages.py @@ -58,7 +58,9 @@ 'timestamped-1.0.5', 'timestamped-1.0.6', 'timestamped-1.1.0', 'timestamped-1.1.1', 'timestamped-1.2.0', 'timestamped-2.0.0', 'timestamped-2.1.0', 'timestamped-2.1.5', 'multi-1.0', 'multi-1.1', 'multi-1.2', 'multi-2.0', - 'missing_variant_requires-1' + 'missing_variant_requires-1', + 'test_weakly_reference_requires-2.0', + 'test_weakly_reference_variant-2.0', ]) diff --git a/src/rez/tests/test_solver.py b/src/rez/tests/test_solver.py index 4c9d44266..11c3c4ce9 100644 --- a/src/rez/tests/test_solver.py +++ b/src/rez/tests/test_solver.py @@ -256,6 +256,23 @@ def test_12_missing_variant_requires(self): config.override("error_on_missing_variant_requires", False) self._solve(["missing_variant_requires"], ["nada[]", "missing_variant_requires-1[1]"]) + def test_13_resolve_weakly_reference_requires(self): + """Test resolving a package with a weakly referenced requirement.""" + self._solve(["test_weakly_reference_requires", "test_variant_split_mid2-2"], + ['test_weakly_reference_requires-2.0[]', + 'test_variant_split_end-3.0[0]', + 'test_variant_split_mid2-2.0[1]']) + + def test_14_resolve_weakly_reference_variant(self): + """Test resolving a package with a weakly referenced variant.""" + self._solve(["test_weakly_reference_variant-2.0", "test_variant_split_mid2-2", "pyfoo"], + ['test_variant_split_end-1.0[1]', + 'test_variant_split_mid1-1.0[1]', + 'test_weakly_reference_variant-2.0[0]', + 'test_variant_split_mid2-2.0[0]', + 'python-2.6.8[]', + 'pyfoo-3.1.0[]']) + if __name__ == '__main__': unittest.main() From 36e053760932b1f0da4ea2f9584ec27faf406bb6 Mon Sep 17 00:00:00 2001 From: Stephen Mackenzie Date: Sun, 14 Apr 2024 15:15:49 -0400 Subject: [PATCH 29/68] Release 3.1.1 (#1719) Signed-off-by: Stephen Mackenzie --- .mailmap | 2 ++ CHANGELOG.md | 18 ++++++++++++++++++ src/rez/utils/_version.py | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/.mailmap b/.mailmap index 84b550271..f41c44669 100644 --- a/.mailmap +++ b/.mailmap @@ -165,6 +165,8 @@ Morné Chamberlain Paul Molodowitch +Robert Minsk cfxegbert + Sylvain Maziere predat Sylvain Maziere diff --git a/CHANGELOG.md b/CHANGELOG.md index 895889e4b..58bd4c4cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,24 @@ +## 3.1.1 (2024-04-14) +[Source](https://github.com/AcademySoftwareFoundation/rez/tree/3.1.1) | [Diff](https://github.com/AcademySoftwareFoundation/rez/compare/3.1.0...3.1.1) + +### Fixes + +- Add symlink locking for filesystems that do not support hardlinks [\#1708](https://github.com/AcademySoftwareFoundation/rez/pull/1708) ([cfxegbert](https://github.com/cfxegbert)) +- Fix error caused by weakly referenced package not specifying version ▒ [\#1712](https://github.com/AcademySoftwareFoundation/rez/pull/1712) ([loonghao](https://github.com/loonghao)) + +### Documentation + +- Add plugin documentation page [\#1703](https://github.com/AcademySoftwareFoundation/rez/pull/1703) ([BryceGattis](https://github.com/BryceGattis)) +- Make gh-rez external link dynamic [\#1707](https://github.com/AcademySoftwareFoundation/rez/pull/1707) ([BryceGattis](https://github.com/BryceGattis)) + +### Miscellaneous + +- Convert all plugin rezconfig to rezconfig.py [\#1692](https://github.com/AcademySoftwareFoundation/rez/pull/1692) ([brycegbrazen](https://github.com/brycegbrazen)) + + ## 3.1.0 (2024-03-30) [Source](https://github.com/AcademySoftwareFoundation/rez/tree/3.1.0) | [Diff](https://github.com/AcademySoftwareFoundation/rez/compare/3.3.0...3.1.0) diff --git a/src/rez/utils/_version.py b/src/rez/utils/_version.py index ceda9738d..f4fd4ec01 100644 --- a/src/rez/utils/_version.py +++ b/src/rez/utils/_version.py @@ -4,4 +4,4 @@ # Update this value to version up Rez. Do not place anything else in this file. # Using .devN allows us to run becnmarks and create proper benchmark reports on PRs. -_rez_version = "3.1.0" +_rez_version = "3.1.1" From ea18d37ef65e7ffebd9bb472335aa8c79827a21e Mon Sep 17 00:00:00 2001 From: Stephen Mackenzie Date: Wed, 17 Apr 2024 12:27:33 -0400 Subject: [PATCH 30/68] seed adopters list (#1720) * seed adopters list Signed-off-by: Stephen Mackenzie --- ADOPTERS.md | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 ADOPTERS.md diff --git a/ADOPTERS.md b/ADOPTERS.md new file mode 100644 index 000000000..1e2dcbf16 --- /dev/null +++ b/ADOPTERS.md @@ -0,0 +1,55 @@ + +# Adopters + +This document is not an official list, but is collated from a variety of +confirmed and unconfirmed sources. If your organization is erroneously present, +misspelled or miswritten in any way, please reach out to us right away and we +will amend the list. Thank you for your understanding in this regard. + +## New Adopters + +If your company, studio, or organization uses rez, please consider filing a +GitHub issue, or pull-request, asking us to add you. + +You are also encouraged to fill in and confirm or annotate any of the info in +the unofficial [rez adopters spreadsheet](https://docs.google.com/spreadsheets/d/15IUtYIePvQOtIt7W639oOPLsl5qcvB_jJhoyHelhep8/edit#gid=0). + +Thank you for helping us understand the rez ecosystem! It helps us determine how +best to grow and support usage of rez workflows everywhere. + +## The List (Alphabetical) + +Accenture Song Content +Animal Logic +AntaresImage +Apple +Brunch Studio +Company3 / Method Studios +Crafty Apes +Digital District +Dreamworks Animation +Dupe VFX +Electric Theatre Collective +Flying Bark Productions +FuseFX / Folks VFX +HouseofVFX +Iloura +Laika +Luma Pictures +Mikros Image +Milk VFX +MSG Sphere +NAD-UQAC +Paramount Animation +Pixomondo +Platige Image +Rodeo FX +Saddington Baynes +SHED Inc +Sony Pictures Imageworks +Squeeze Studio Animation +Squint Opera +Tangent Animation +Tencent Games +Toonbox Entertainment +WWFX UK From a0404e7fb653e7df1302ce052bdaa2cfe2f9daa1 Mon Sep 17 00:00:00 2001 From: Stephen Mackenzie Date: Wed, 17 Apr 2024 12:29:51 -0400 Subject: [PATCH 31/68] updates to contributing.md for support, legal, versioning (#1721) Signed-off-by: Stephen Mackenzie --- CONTRIBUTING.md | 110 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 104 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 83b5a85a1..09f26dcf6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,9 +1,61 @@ # Contributing To Rez +Thank you for your interest in contributing to rez. +This document explains our contribution process and procedures, so please review it first: + +* [Get Connected](#Get-Connected) +* [Guidelines](#Guidelines) +* [Development Environment](#Development-Environment) +* [Legal Requirements](#Legal-Requirements) +* [Reporting Bugs](#Reporting-Bugs) +* [Versioning Policy](#Versioning-Policy) + +For a description of the roles and responsibilities of the various members of the rez community, see [GOVERNANCE](GOVERNANCE.md), and +for further details, see the project's +[Technical Charter](https://github.com/AcademySoftwareFoundation/foundation/blob/main/project_charters/rez-charter.pdf). Briefly, Contributors are anyone +who submits content to the project, Committers review and approve such +submissions, and the Technical Steering Committee provides general project +oversight and maintainership. + +## Get Connected + +The first thing to do, before anything else, is talk to us! Whether you're +reporting an issue, requesting or implementing a feature, or just asking a +question; please don’t hesitate to reach out to project maintainers or the +community as a whole. This is an important first step because your issue, +feature, or the question may have been solved or discussed already, and you’ll +save yourself a lot of time by asking first. + +How do you talk to us? There are several ways to get in touch: + +* [Slack](https://slack.aswf.io): +Join the ``#rez`` channel. This channel is where the majority of rez-centric +discussion takes place, where announcements are made, where users help each +other, and other relevant community information is released. + +There are a number of other helpful channels as well, depending on your +tolerance for high-frequency information, such as: +``#rez-gh-releases``, ``#rez-gh-prs``, and ``#rez-gh-issues``. + +* [GitHub Discussions](https://github.com/AcademySoftwareFoundation/rez/discussions): +GitHub **discussions** are a great place to start a conversation! It's an +excellent place to ask both the rez maintainers as well as the general community +any questions, as well as to act as a place to facilitate complex topics such as +those related to development, rez future feature-set, or future goals of the +project! + +* [rez-discussion mailing list](https://lists.aswf.io/g/rez-discussion/): +This is a general-purpose mailing list for discussion of rez, its features, +behavior, configuration, usage patterns, and sometimes a channel for information +regarding major releases. Put simply, a slower version of our Slack channel. + +* [The monthly TSC meeting](https://www.aswf.io/meeting-calendar/): +Check the calendar for our monthly TSC meeting. Reminders often posted in Slack. + ## Guidelines -If you would like to contribute code you can do so through GitHub by forking the repository and -sending a pull request. Please follow these guidelines: +If you would like to contribute code you can do so through GitHub by forking the +repository and sending a pull request. Please follow these guidelines: 1. Always retain backwards compatibility, unless a breaking change is necessary. If it is necessary, the associated release notes must make this explicit and obvious; @@ -62,13 +114,41 @@ packages for improved test output: `pytest` and `parameterized`. You can install 1. Set up your development environment as shown above. 2. Run `rez selftest`. -## CLA +## Legal Requirements + +rez is a project hosted by the Academy Software Foundation (ASWF) and +follows the open source software best practice policies of the ASWF TAC with the +guidance from the Linux Foundation. + +### License + +rez is licensed under the [Apache 2.0 License](LICENSE). Contributions to rez +should abide by that license. + +### Contributor License Agreements + +Developers who wish to contribute code to be considered for inclusion +in rez must first complete a **Contributor License Agreement +(CLA)**. + +rez uses [EasyCLA](https://lfx.linuxfoundation.org/tools/easycla) for managing CLAs, which +automatically checks to ensure CLAs are signed by a contributor before a commit +can be merged. + +* If you are an individual writing the code on your own time and + you're SURE you are the sole owner of any intellectual property you + contribute, you can + [sign the CLA as an individual contributor](https://docs.linuxfoundation.org/lfx/easycla/contributors/individual-contributor). -Rez enforces use of a Contributor License Agreement as per ASWF guidelines. You need only sign up to the EasyCLA system once, but until you do, your PRs will be automatically blocked. +* If you are writing the code as part of your job, or if there is any + possibility that your employers might think they own any + intellectual property you create, then you should use the + [Corporate Contributor Licence Agreement](https://docs.linuxfoundation.org/lfx/easycla/contributors/corporate-contributor). -For more info see https://easycla.lfx.linuxfoundation.org/#/ +The rez CLA's are the standard forms used by Linux Foundation projects and +[recommended by the ASWF TAC](https://github.com/AcademySoftwareFoundation/tac/blob/main/process/contributing.md#contributor-license-agreement-cla). -## DCO +### DCO Commit Sign-Off Rez enforces Developer Certificate of Origin (DCO) on all commits, as per ASWF guidelines. PRs are automatically blocked until all commits within the PR are signed off. @@ -84,6 +164,15 @@ to `.gitignore`): For more info see https://github.blog/changelog/2022-06-08-admins-can-require-sign-off-on-web-based-commits/ for web-based commits, and https://probot.github.io/apps/dco/ for all others. +### Copyright Notices + +All new source files should begin with a copyright and license stating: + +``` +# SPDX-License-Identifier: Apache-2.0 +# Copyright Contributors to the Rez Project +``` + ## Reporting Bugs If you report a bug, please ensure to specify the following: @@ -92,3 +181,12 @@ If you report a bug, please ensure to specify the following: 2. Platform and operating system you were using; 3. Contextual information (what were you trying to do using Rez); 4. Simplest possible steps to reproduce. + +## Versioning Policy + +rez releases observe the [semver 2.0.0](https://semver.org/) version numbering standard. +Briefly: + +* **MAJOR** version when you make incompatible API changes +* **MINOR** version when you add functionality in a backward compatible manner +* **PATCH** version when you make backward compatible bug fixes From 6c8aafd56499b98d060b6e86eff499986de84fd5 Mon Sep 17 00:00:00 2001 From: Stephen Mackenzie Date: Wed, 17 Apr 2024 12:30:27 -0400 Subject: [PATCH 32/68] updates to release.md for release cadence and versioning used (#1722) Signed-off-by: Stephen Mackenzie --- RELEASE.md | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index 11587e4f7..9da7cbca8 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,4 +1,38 @@ -# Releasing New Rez Versions +# Release Procedures and standards for rez + +## Version nomenclature and release cadence + +### The meaning of the version parts + +rez releases observe the [semver 2.0.0](https://semver.org/) version numbering standard. +Briefly: + +* **MAJOR** version when you make incompatible API changes +* **MINOR** version when you add functionality in a backward compatible manner +* **PATCH** version when you make backward compatible bug fixes + +### Cadence of releases + +Currently, rez is not considered a component that studios feel the need to +include in the [VFX Reference Platform](https://vfxplatform.com/), although +many do use rez to help manage migrations between and amongst subsequent +iterations thereof. + +As such, rez currently releases on an as-needed basis, which is to say, at the +discretion of the TSC. For the most part that means that: + +* When there is a bugfix for a recent feature version, releasing a "patch" +bugfix version resolving the issue will be prioritized above new feature +releases. +* When there is a naturally occurring set of features or updates that are +feature-complete, well-tested, self-contained, and ready to go, those will be +released as a "minor" feature update. +* When there is a "major" breaking change, it will be deferred for as reasonably +long as possible. Strategies to make a breaking change into a non-breaking +change will also be asked-for, investigated, and preferred. rez often has +normally gone many years between breaking changes. + +## Procedures for Releasing New Rez Versions To merge a PR to the `main` branch and release a new version: From f17e88dad283826a5914e3aade4fbc9a010cdba2 Mon Sep 17 00:00:00 2001 From: Stephen Mackenzie Date: Wed, 17 Apr 2024 17:40:46 -0400 Subject: [PATCH 33/68] fix adopters list formatting (#1726) Signed-off-by: Stephen Mackenzie --- ADOPTERS.md | 68 ++++++++++++++++++++++++++--------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/ADOPTERS.md b/ADOPTERS.md index 1e2dcbf16..fb5e82a09 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -19,37 +19,37 @@ best to grow and support usage of rez workflows everywhere. ## The List (Alphabetical) -Accenture Song Content -Animal Logic -AntaresImage -Apple -Brunch Studio -Company3 / Method Studios -Crafty Apes -Digital District -Dreamworks Animation -Dupe VFX -Electric Theatre Collective -Flying Bark Productions -FuseFX / Folks VFX -HouseofVFX -Iloura -Laika -Luma Pictures -Mikros Image -Milk VFX -MSG Sphere -NAD-UQAC -Paramount Animation -Pixomondo -Platige Image -Rodeo FX -Saddington Baynes -SHED Inc -Sony Pictures Imageworks -Squeeze Studio Animation -Squint Opera -Tangent Animation -Tencent Games -Toonbox Entertainment -WWFX UK +- Accenture Song Content +- Animal Logic +- AntaresImage +- Apple +- Brunch Studio +- Company3 / Method Studios +- Crafty Apes +- Digital District +- Dreamworks Animation +- Dupe VFX +- Electric Theatre Collective +- Flying Bark Productions +- FuseFX / Folks VFX +- HouseofVFX +- Iloura +- Laika +- Luma Pictures +- Mikros Image +- Milk VFX +- MSG Sphere +- NAD-UQAC +- Paramount Animation +- Pixomondo +- Platige Image +- Rodeo FX +- Saddington Baynes +- SHED Inc +- Sony Pictures Imageworks +- Squeeze Studio Animation +- Squint Opera +- Tangent Animation +- Tencent Games +- Toonbox Entertainment +- WWFX UK From 84f184745ef210b584f172ccace744172ebeaf8f Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> Date: Sun, 28 Apr 2024 13:49:54 -0400 Subject: [PATCH 34/68] Run OpenSSF Scorecard in GitHub Actions workflow (#1730) Signed-off-by: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> --- .github/workflows/scorecard.yml | 66 +++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 .github/workflows/scorecard.yml diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 000000000..926bc3b63 --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,66 @@ +name: OpenSSF Scorecard +on: + # For Branch-Protection check. Only the default branch is supported. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection + branch_protection_rule: + # To guarantee Maintained check is occasionally updated. See + # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained + schedule: + - cron: '21 4 * * 3' + push: + branches: [ "main" ] + +# Declare default permissions as read only. +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + permissions: + # Needed to upload the results to code-scanning dashboard. + security-events: write + # Needed to publish results and get a badge (see publish_results below). + id-token: write + + steps: + - name: "Checkout code" + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 + with: + results_file: results.sarif + results_format: sarif + # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: + # - you want to enable the Branch-Protection check on a *public* repository, or + # - you are installing Scorecard on a *private* repository + # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional. + # repo_token: ${{ secrets.SCORECARD_TOKEN }} + + # Public repositories: + # - Publish results to OpenSSF REST API for easy access by consumers + # - Allows the repository to include the Scorecard badge. + # - See https://github.com/ossf/scorecard-action#publishing-results. + # For private repositories: + # - `publish_results` will always be set to `false`, regardless + # of the value entered here. + publish_results: true + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF + # format to the repository Actions tab. + - name: "Upload artifact" + uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard (optional). + # Commenting out will disable upload of results to your repo's Code Scanning dashboard + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1 + with: + sarif_file: results.sarif From eafe8f6dd76875026f796cbc87e94c7a086508dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 11:37:15 -0400 Subject: [PATCH 35/68] Bump github/codeql-action from 3.25.1 to 3.25.3 (#1738) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.1 to 3.25.3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/c7f9125735019aa87cfc361530512d50ea439c71...d39d31e687223d841ef683f52467bd88e9b21c14) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 926bc3b63..2341553eb 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -61,6 +61,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1 + uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 with: sarif_file: results.sarif From dd6de58361a269547d14f259def03d78cee679c8 Mon Sep 17 00:00:00 2001 From: BryceGattis <36783788+BryceGattis@users.noreply.github.com> Date: Wed, 1 May 2024 19:18:46 -0500 Subject: [PATCH 36/68] Add date to vendored pika (#1743) Signed-off-by: BryceGattis --- src/rez/vendor/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rez/vendor/README.md b/src/rez/vendor/README.md index 03fff75d4..dcd46e1d5 100644 --- a/src/rez/vendor/README.md +++ b/src/rez/vendor/README.md @@ -149,7 +149,7 @@ Added (July 2019) to enable PEP440 compatible versions handling. pika -1.2.0 +1.2.0 (Feb 5, 2021) BSD 3-Clause From dc761d1d3903aa73b0354688d0f8e9176a1ac2be Mon Sep 17 00:00:00 2001 From: BryceGattis <36783788+BryceGattis@users.noreply.github.com> Date: Sun, 5 May 2024 13:04:36 -0500 Subject: [PATCH 37/68] Add argcomplete vendored version to vendor README.md (#1742) Signed-off-by: BryceGattis --- src/rez/vendor/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rez/vendor/README.md b/src/rez/vendor/README.md index dcd46e1d5..b5918539f 100644 --- a/src/rez/vendor/README.md +++ b/src/rez/vendor/README.md @@ -27,12 +27,12 @@ tested. argcomplete -? +6f943d76400d6755c2152deff4f2c5c5fa4d9e7c (Jul 20, 2014) Apache 2.0 https://github.com/kislyuk/argcomplete
-Our version seems patched. +Our version is patched. From f63031e3d86b699272b144afb24adf12b1362380 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> Date: Sat, 11 May 2024 14:29:16 -0400 Subject: [PATCH 38/68] Fix CI for Python 3.7 on macOS by only running these tests on macos-13 (#1750) Signed-off-by: Jean-Christophe Morin --- .github/workflows/installation.yaml | 15 ++++++++++++++- .github/workflows/tests.yaml | 8 +++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/installation.yaml b/.github/workflows/installation.yaml index 0a2425fcf..01232c3cd 100644 --- a/.github/workflows/installation.yaml +++ b/.github/workflows/installation.yaml @@ -30,7 +30,7 @@ jobs: fail-fast: false matrix: os: ['ubuntu-latest', 'macos-latest', 'windows-latest'] - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11'] method: ['install' ,'pip'] include: @@ -52,6 +52,19 @@ jobs: method: pip REZ_SET_PATH_COMMAND: 'export PATH="$PATH:~/rez/bin" PYTHONPATH=$PYTHONPATH:$HOME/rez' REZ_INSTALL_COMMAND: pip install --target ~/rez . + # macOS + # Python 3.7 is not supported on Apple Silicon. + # macos-13 is the last macos runner image to run on Intel CPUs. + - os: macos-13 + python-version: '3.7' + method: install + REZ_SET_PATH_COMMAND: 'export PATH=${PATH}:~/rez/bin/rez' + REZ_INSTALL_COMMAND: python ./install.py ~/rez + - os: macos-13 + python-version: '3.7' + method: pip + REZ_SET_PATH_COMMAND: 'export PATH="$PATH:~/rez/bin" PYTHONPATH=$PYTHONPATH:$HOME/rez' + REZ_INSTALL_COMMAND: pip install --target ~/rez . # windows - os: windows-latest method: install diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 37b23583d..eb4222354 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -35,7 +35,7 @@ jobs: strategy: matrix: os: ['macos-latest', 'ubuntu-latest', 'windows-latest'] - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11'] include: - os: macos-latest shells: 'sh,csh,bash,tcsh,zsh,pwsh' @@ -46,6 +46,12 @@ jobs: - os: windows-latest shells: 'cmd,pwsh,gitbash' rez-path: \installdir\Scripts\rez + # Python 3.7 is not supported on Apple Silicon. + # macos-13 is the last macos runner image to run on Intel CPUs. + - os: macos-13 + shells: 'sh,csh,bash,tcsh,zsh,pwsh' + rez-path: /installdir/bin/rez + python-version: '3.7' fail-fast: false From 71d990bc63cd9314114e45c2002fa15656a778b0 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> Date: Sun, 12 May 2024 12:19:55 -0400 Subject: [PATCH 39/68] Add more logic in the shell detection code to handle a case where the parent PID is zero. This can happen when run from within a docker container with a non-interactive shel. (#1735) Signed-off-by: Jean-Christophe Morin --- src/rez/system.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/rez/system.py b/src/rez/system.py index abdc6981e..25780c1e7 100644 --- a/src/rez/system.py +++ b/src/rez/system.py @@ -79,14 +79,18 @@ def shell(self): import subprocess as sp shell = None - # check parent process via ps - try: - args = ['ps', '-o', 'args=', '-p', str(os.getppid())] - proc = sp.Popen(args, stdout=sp.PIPE) - output = proc.communicate()[0] - shell = os.path.basename(output.strip().split()[0]).replace('-', '') - except Exception: - pass + parent_pid = os.getppid() + if parent_pid != 0: + # When run from inside docker without an interactive shell, + # the parent pid will be 0, which will cause "ps" to + # print an error message: "process ID out of range". + try: + args = ['ps', '-o', 'args=', '-p', str(parent_pid)] + proc = sp.Popen(args, stdout=sp.PIPE) + output = proc.communicate()[0] + shell = os.path.basename(output.strip().split()[0]).replace('-', '') + except Exception: + pass # check $SHELL if shell not in shells: @@ -94,7 +98,7 @@ def shell(self): # traverse parent procs via /proc/(pid)/status if shell not in shells: - pid = str(os.getppid()) + pid = str(parent_pid) found = False while not found: From d46901c52c53b92f8ec53692ff5aca60f4fbd60b Mon Sep 17 00:00:00 2001 From: BryceGattis <36783788+BryceGattis@users.noreply.github.com> Date: Sun, 12 May 2024 12:05:27 -0500 Subject: [PATCH 40/68] Fix formatting sonarcloud compliance issue (#1697) Signed-off-by: Bryce Gattis --- src/rez/tests/test_utils_formatting.py | 43 ++++++++++++++++++++++++++ src/rez/utils/formatting.py | 8 +++-- 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/rez/tests/test_utils_formatting.py diff --git a/src/rez/tests/test_utils_formatting.py b/src/rez/tests/test_utils_formatting.py new file mode 100644 index 000000000..a63388f3c --- /dev/null +++ b/src/rez/tests/test_utils_formatting.py @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright Contributors to the Rez Project + + +""" +unit tests for 'utils.formatting' module +""" +from rez.tests.util import TestBase +from rez.utils import formatting + + +class TestFormatting(TestBase): + def test_readable_units(self): + readable_units = formatting._readable_units( + 0, + formatting.memory_divs + ) + self.assertEqual(readable_units, "0 bytes") + + readable_units = formatting._readable_units( + 1024, + formatting.memory_divs + ) + self.assertEqual(readable_units, "1 Kb") + + readable_units = formatting._readable_units( + 1200, + formatting.memory_divs + ) + self.assertEqual(readable_units, "1.2 Kb") + + readable_units = formatting._readable_units( + -30000, + formatting.memory_divs + ) + self.assertEqual(readable_units, "-29 Kb") + + readable_units = formatting._readable_units( + 1024, + formatting.memory_divs, + plural_aware=True + ) + self.assertEqual(readable_units, "1 K") diff --git a/src/rez/utils/formatting.py b/src/rez/utils/formatting.py index 3f9c3587d..aa8aad41c 100644 --- a/src/rez/utils/formatting.py +++ b/src/rez/utils/formatting.py @@ -10,6 +10,7 @@ from rez.exceptions import PackageRequestError from pprint import pformat from enum import Enum +import math import os import os.path import re @@ -363,7 +364,9 @@ def readable_time_duration(secs): def readable_memory_size(bytes_): - """Convert number of bytes into human readable form, eg '1.2 Kb'. + """Convert number of bytes into human-readable form. + + This method rounds to 1 decimal place eg '1.2 Kb'. """ return _readable_units(bytes_, memory_divs) @@ -382,7 +385,8 @@ def _readable_units(value, divs, plural_aware=False): rounding = 0 if f > threshold else 1 f = round(f, rounding) f = int(f * 10) / 10.0 - if plural_aware and f == 1.0: + is_one = math.isclose(f, 1.0, rel_tol=1e-09, abs_tol=1e-09) + if plural_aware and is_one: unit = unit[:-1] txt = "%g %s" % (f, unit) break From a13f7bb362cbb05e73f88e9f771c36005c1e9f4a Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> Date: Sun, 12 May 2024 16:44:08 -0400 Subject: [PATCH 41/68] Upload test coverage even if tests fail (#1751) Signed-off-by: Jean-Christophe Morin --- .github/workflows/tests.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index eb4222354..dc19ae3b6 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -89,12 +89,15 @@ jobs: run: rez-python -m pip install pytest-cov parameterized - name: Run tests + id: tests run: rez-selftest -v -- --cov=rez --cov-report=xml:coverage.xml env: _REZ_ENSURE_TEST_SHELLS: ${{ matrix.shells }} - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v4 + # Run on both success and failure, but only if coverage.xml exists. + if: ${{ hashFiles('coverage.xml') != '' && (steps.tests.outcome == 'success' || steps.tests.outcome == 'failure') }} with: slug: AcademySoftwareFoundation/rez files: 'coverage.xml' From 9094b089e4bec6048a12cf0e3d105af5935c8758 Mon Sep 17 00:00:00 2001 From: predat Date: Sat, 22 Jun 2024 17:49:28 +0200 Subject: [PATCH 42/68] Add new default_build_process setting to set the default build process (#1724) Signed-off-by: predat --- src/rez/cli/build.py | 4 +++- src/rez/config.py | 1 + src/rez/rezconfig.py | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/rez/cli/build.py b/src/rez/cli/build.py index 208bab9a5..f39057934 100644 --- a/src/rez/cli/build.py +++ b/src/rez/cli/build.py @@ -30,11 +30,13 @@ def setup_parser_common(parser): """Parser setup common to both rez-build and rez-release.""" from rez.build_process import get_build_process_types from rez.build_system import get_valid_build_systems + from rez.config import config from rez.exceptions import PackageMetadataError process_types = get_build_process_types() parser.add_argument( - "--process", type=str, choices=process_types, default="local", + "--process", type=str, choices=process_types, + default=config.default_build_process, help="the build process to use (default: %(default)s).") # add build system choices valid for this package diff --git a/src/rez/config.py b/src/rez/config.py index e8542d1ed..a6a8515f2 100644 --- a/src/rez/config.py +++ b/src/rez/config.py @@ -397,6 +397,7 @@ def _parse_env_var(self, value): "release_packages_path": Str, "dot_image_format": Str, "build_directory": Str, + "default_build_process": Str, "documentation_url": Str, "suite_visibility": SuiteVisibility_, "rez_tools_visibility": RezToolsVisibility_, diff --git a/src/rez/rezconfig.py b/src/rez/rezconfig.py index d5366e974..b63ceb56f 100644 --- a/src/rez/rezconfig.py +++ b/src/rez/rezconfig.py @@ -861,6 +861,11 @@ # leave this True. use_variant_shortlinks = True +# Default build process to use during build/release. +# Only 'local' build process is currently available, +# see :gh-rez:`src/rezplugins/build_process`. +default_build_process = "local" + ############################################################################### # Suites From 89a3b3743bddde8e208f214239fb132906818c77 Mon Sep 17 00:00:00 2001 From: Bryce Gattis <36783788+BryceGattis@users.noreply.github.com> Date: Sat, 22 Jun 2024 11:21:27 -0500 Subject: [PATCH 43/68] Migrate plugin type settings to plugin rez configs so we can more easily add plugin settings to our documentation (#1746) Signed-off-by: BryceGattis --- src/rez/rezconfig.py | 41 +------------------------ src/rezplugins/release_vcs/rezconfig.py | 39 +++++++++++++++++++++++ 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/rez/rezconfig.py b/src/rez/rezconfig.py index b63ceb56f..e9306d1bd 100644 --- a/src/rez/rezconfig.py +++ b/src/rez/rezconfig.py @@ -1217,46 +1217,7 @@ # common to all plugins of that type. plugins = { - "release_vcs": { - # Format string used to determine the VCS tag name when releasing. This - # will be formatted using the package being released - any package - # attribute can be referenced in this string, eg "{name}". - # - # It is not recommended to write only '{version}' to the tag. This will - # cause problems if you ever store multiple packages within a single - # repository - versions will clash and this will cause several problems. - "tag_name": "{qualified_name}", - - # A list of branches that a user is allowed to rez-release from. This - # can be used to block releases from development or feature branches, - # and support a workflow such as "gitflow". Each branch name should be - # a regular expression that can be used with re.match(), for example - # "^main$". - "releasable_branches": [], - - # If True, a release will be cancelled if the repository has already been - # tagged at the current package's version. Generally this is not needed, - # because Rez won't re-release over the top of an already-released - # package anyway (or more specifically, an already-released variant). - # - # However, it is useful to set this to True when packages are being - # released in a multi-site scenario. Site A may have released package - # foo-1.4, and for whatever reason this package hasn't been released at - # site B. Site B may then make some changes to the foo project, and then - # attempt to release a foo-1.4 that is now different to site A's foo-1.4. - # By setting this check to True, this situation can be avoided (assuming - # that both sites are sharing the same code repository). - # - # Bear in mind that even in the above scenario, there are still cases - # where you may NOT want to check the tag. For example, an automated - # service may be running that detects when a package is released at - # site A, which then checks out the code at site B, and performs a - # release there. In this case we know that the package is already released - # at A, but that's ok because the package hasn't changed and we just want - # to release it at B also. For this reason, you can set tag checking to - # False both in the API and via an option on the rez-release tool. - "check_tag": False - } + } diff --git a/src/rezplugins/release_vcs/rezconfig.py b/src/rezplugins/release_vcs/rezconfig.py index 411fe38a8..cdf109ade 100644 --- a/src/rezplugins/release_vcs/rezconfig.py +++ b/src/rezplugins/release_vcs/rezconfig.py @@ -2,6 +2,45 @@ # Copyright Contributors to the Rez Project +# Format string used to determine the VCS tag name when releasing. This +# will be formatted using the package being released - any package +# attribute can be referenced in this string, eg "{name}". +# +# It is not recommended to write only '{version}' to the tag. This will +# cause problems if you ever store multiple packages within a single +# repository - versions will clash and this will cause several problems. +tag_name = "{qualified_name}" + +# A list of branches that a user is allowed to rez-release from. This +# can be used to block releases from development or feature branches, +# and support a workflow such as "gitflow". Each branch name should be +# a regular expression that can be used with re.match(), for example +# "^main$". +releasable_branches = [] + +# If True, a release will be cancelled if the repository has already been +# tagged at the current package's version. Generally this is not needed, +# because Rez won't re-release over the top of an already-released +# package anyway (or more specifically, an already-released variant). +# +# However, it is useful to set this to True when packages are being +# released in a multi-site scenario. Site A may have released package +# foo-1.4, and for whatever reason this package hasn't been released at +# site B. Site B may then make some changes to the foo project, and then +# attempt to release a foo-1.4 that is now different to site A's foo-1.4. +# By setting this check to True, this situation can be avoided (assuming +# that both sites are sharing the same code repository). +# +# Bear in mind that even in the above scenario, there are still cases +# where you may NOT want to check the tag. For example, an automated +# service may be running that detects when a package is released at +# site A, which then checks out the code at site B, and performs a +# release there. In this case we know that the package is already released +# at A, but that's ok because the package hasn't changed and we just want +# to release it at B also. For this reason, you can set tag checking to +# False both in the API and via an option on the rez-release tool. +check_tag = False + git = { # If false, cancel a package release if there is no upstream branch. "allow_no_upstream": False From b9ea28166f56e41f30e79a72faa620ef6748788f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 22 Jun 2024 12:24:06 -0400 Subject: [PATCH 44/68] Bump ossf/scorecard-action from 2.3.1 to 2.3.3 (#1752) Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.3.1 to 2.3.3. - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/0864cf19026789058feabb7e87baa5f140aac736...dc50aa9510b46c811795eb24b2f1ba02a914e534) --- updated-dependencies: - dependency-name: ossf/scorecard-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 2341553eb..c94788404 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -30,7 +30,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 + uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3 with: results_file: results.sarif results_format: sarif From a63ed516457f07952945b898e02fc10fc654aaaf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 22 Jun 2024 12:24:33 -0400 Subject: [PATCH 45/68] Bump github/codeql-action from 3.25.3 to 3.25.10 (#1770) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.3 to 3.25.10. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/d39d31e687223d841ef683f52467bd88e9b21c14...23acc5c183826b7a8a97bce3cecc52db901f8251) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index c94788404..8f4ffcd1d 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -61,6 +61,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 + uses: github/codeql-action/upload-sarif@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 with: sarif_file: results.sarif From 271ba34b7e8195d22ec4a6254da51ebb501316cb Mon Sep 17 00:00:00 2001 From: Bryce Gattis <69012021+brycegbrazen@users.noreply.github.com> Date: Sat, 22 Jun 2024 11:36:02 -0500 Subject: [PATCH 46/68] Fix output so the %s is formatted with the exepath as intended (#1775) Signed-off-by: brycegbrazen --- src/rezplugins/shell/gitbash.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rezplugins/shell/gitbash.py b/src/rezplugins/shell/gitbash.py index 8d0392633..f55f09e66 100644 --- a/src/rezplugins/shell/gitbash.py +++ b/src/rezplugins/shell/gitbash.py @@ -44,7 +44,7 @@ def find_executable(cls, name, check_syspaths=False): "Git-bash executable has been detected at %s, but this is " "probably not correct (google Windows Subsystem for Linux). " "Consider adjusting your searchpath, or use rez config setting " - "plugins.shell.gitbash.executable_fullpath." + "plugins.shell.gitbash.executable_fullpath." % exepath ) return exepath From 704eb71a3c456d930d220c3f9a4bf02f50b56e62 Mon Sep 17 00:00:00 2001 From: Robert Minsk <38872275+cfxegbert@users.noreply.github.com> Date: Sat, 22 Jun 2024 11:33:06 -0700 Subject: [PATCH 47/68] Don't expand tilde in REZ_USED_IMPLICIT_PACKAGES and REZ_USED_REQUEST environment variables (#1760) Signed-off-by: Robert Minsk Signed-off-by: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> Co-authored-by: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> --- src/rez/resolved_context.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rez/resolved_context.py b/src/rez/resolved_context.py index 9ef3ae09d..45dc6e3e6 100644 --- a/src/rez/resolved_context.py +++ b/src/rez/resolved_context.py @@ -19,7 +19,7 @@ from rez.utils.memcached import pool_memcached_connections from rez.utils.logging_ import print_error, print_warning from rez.utils.which import which -from rez.rex import RexExecutor, Python, OutputStyle +from rez.rex import RexExecutor, Python, OutputStyle, literal from rez.rex_bindings import VersionBinding, VariantBinding, \ VariantsBinding, RequirementsBinding, EphemeralsBinding, intersects from rez import package_order @@ -1978,8 +1978,8 @@ def normalized(path): executor.setenv("REZ_USED_VERSION", self.rez_version) executor.setenv("REZ_USED_TIMESTAMP", str(self.timestamp)) executor.setenv("REZ_USED_REQUESTED_TIMESTAMP", req_timestamp_str) - executor.setenv("REZ_USED_REQUEST", request_str) - executor.setenv("REZ_USED_IMPLICIT_PACKAGES", implicit_str) + executor.setenv("REZ_USED_REQUEST", literal(request_str)) + executor.setenv("REZ_USED_IMPLICIT_PACKAGES", literal(implicit_str)) executor.setenv("REZ_USED_RESOLVE", resolve_str) executor.setenv("REZ_USED_PACKAGES_PATH", package_paths_str) From 671e32fcb348a4fd3feddac9302cf53f307ece5e Mon Sep 17 00:00:00 2001 From: Ben Andersen <156872503+isohedronpipeline@users.noreply.github.com> Date: Sun, 30 Jun 2024 00:31:41 +1000 Subject: [PATCH 48/68] Add ability to cache package payloads synchronously (#1679) Adds a `package_cache_async` flag which allows users to run caching synchronously (blocking) or asynchronously from the config. Also adds CLI argument `--pkg-cache-mode` to manually override the caching mode. --- Signed-off-by: ttrently <41705925+ttrently@users.noreply.github.com> Signed-off-by: Ben Andersen Signed-off-by: Jean-Christophe Morin Co-authored-by: ttrently <41705925+ttrently@users.noreply.github.com> Co-authored-by: Jean-Christophe Morin --- src/rez/cli/env.py | 15 +++- src/rez/config.py | 1 + src/rez/package_cache.py | 118 ++++++++++++++++++++++++---- src/rez/resolved_context.py | 16 +++- src/rez/rezconfig.py | 10 ++- src/rez/tests/test_package_cache.py | 60 +++++++++++++- 6 files changed, 194 insertions(+), 26 deletions(-) diff --git a/src/rez/cli/env.py b/src/rez/cli/env.py index 986c8e86b..9d8eb8aef 100644 --- a/src/rez/cli/env.py +++ b/src/rez/cli/env.py @@ -119,6 +119,11 @@ def setup_parser(parser, completions=False): parser.add_argument( "--no-pkg-cache", action="store_true", help="Disable package caching") + parser.add_argument( + "--pkg-cache-mode", choices=["sync", "async"], + help="If provided, override the rezconfig's package_cache_async key. " + "If 'sync', the process will block until packages are cached. " + "If 'async', the process will not block while packages are cached.") parser.add_argument( "--pre-command", type=str, help=SUPPRESS) PKG_action = parser.add_argument( @@ -201,6 +206,13 @@ def command(opts, parser, extra_arg_groups=None): rule = Rule.parse_rule(rule_str) package_filter.add_inclusion(rule) + if opts.pkg_cache_mode == "async": + package_cache_mode = True + elif opts.pkg_cache_mode == "sync": + package_cache_mode = False + else: + package_cache_mode = None + # perform the resolve context = ResolvedContext( package_requests=request, @@ -215,7 +227,8 @@ def command(opts, parser, extra_arg_groups=None): caching=(not opts.no_cache), suppress_passive=opts.no_passive, print_stats=opts.stats, - package_caching=(not opts.no_pkg_cache) + package_caching=(not opts.no_pkg_cache), + package_cache_async=package_cache_mode, ) success = (context.status == ResolverStatus.solved) diff --git a/src/rez/config.py b/src/rez/config.py index a6a8515f2..56b4ca3f2 100644 --- a/src/rez/config.py +++ b/src/rez/config.py @@ -454,6 +454,7 @@ def _parse_env_var(self, value): "package_cache_during_build": Bool, "package_cache_local": Bool, "package_cache_same_device": Bool, + "package_cache_async": Bool, "color_enabled": ForceOrBool, "resolve_caching": Bool, "cache_package_files": Bool, diff --git a/src/rez/package_cache.py b/src/rez/package_cache.py index 7ab833bdf..664a439b9 100644 --- a/src/rez/package_cache.py +++ b/src/rez/package_cache.py @@ -22,6 +22,7 @@ from rez.config import config from rez.exceptions import PackageCacheError from rez.vendor.lockfile import LockFile, NotLocked +from rez.vendor.progress.spinner import PixelSpinner from rez.utils.filesystem import safe_listdir, safe_makedirs, safe_remove, \ forceful_rmtree from rez.utils.colorize import ColorizedStreamHandler @@ -70,6 +71,18 @@ class PackageCache(object): VARIANT_PENDING = 5 #: Variant is pending caching VARIANT_REMOVED = 6 #: Variant was deleted + STATUS_DESCRIPTIONS = { + VARIANT_NOT_FOUND: "was not found", + VARIANT_FOUND: "was found", + VARIANT_CREATED: "was created", + VARIANT_COPYING: "payload is still being copied to this cache", + VARIANT_COPY_STALLED: "payload copy has stalled.\nSee " + "https://rez.readthedocs.io/en/stable/caching.html#cleaning-the-cache " + "for more information.", + VARIANT_PENDING: "is pending caching", + VARIANT_REMOVED: "was deleted", + } + _FILELOCK_TIMEOUT = 10 _COPYING_TIME_INC = 0.2 _COPYING_TIME_MAX = 5.0 @@ -117,7 +130,7 @@ def get_cached_root(self, variant): return rootpath - def add_variant(self, variant, force=False): + def add_variant(self, variant, force=False, wait_for_copying=False, logger=None): """Copy a variant's payload into the cache. The following steps are taken to ensure muti-thread/proc safety, and to @@ -148,6 +161,9 @@ def add_variant(self, variant, force=False): variant (Variant): The variant to copy into this cache force (bool): Copy the variant regardless. Use at your own risk (there is no guarantee the resulting variant payload will be functional). + wait_for_copying (bool): Whether the caching step should block when one of the + pending variants is marked as already copying. + logger (None | Logger): If a logger is provided, log information to it. Returns: tuple: 2-tuple: @@ -208,15 +224,40 @@ def add_variant(self, variant, force=False): % package.repository ) - no_op_statuses = ( + no_op_statuses = { self.VARIANT_FOUND, - self.VARIANT_COPYING, - self.VARIANT_COPY_STALLED - ) + self.VARIANT_COPY_STALLED, + } + if not wait_for_copying: + # Copying variants are only no-ops if we want to ignore them. + no_op_statuses.add(self.VARIANT_COPYING) # variant already exists, or is being copied to cache by another thread/proc status, rootpath = self._get_cached_root(variant) if status in no_op_statuses: + if logger: + logger.warning(f"Not caching {variant.qualified_name}. " + f"Variant {self.STATUS_DESCRIPTIONS[status]}") + return (rootpath, status) + + if wait_for_copying and status == self.VARIANT_COPYING: + spinner = PixelSpinner(f"Waiting for {variant.qualified_name} to finish copying. ") + while status == self.VARIANT_COPYING: + spinner.next() + time.sleep(self._COPYING_TIME_INC) + status, rootpath = self._get_cached_root(variant) + + # Status has changed, so report the change and return + if logger: + if status == self.VARIANT_FOUND: + # We have resolved into a satisfactory state + logger.info( + f"{variant.qualified_name} {self.STATUS_DESCRIPTIONS[status]}" + ) + else: + logger.warning( + f"{variant.qualified_name} {self.STATUS_DESCRIPTIONS[status]}" + ) return (rootpath, status) # 1. @@ -365,20 +406,39 @@ def add_variants_async(self, variants): This method is called when a context is created or sourced. Variants are then added to the cache in a separate process. + + .. deprecated:: 3.2.0 + Use :method:`add_variants` instead. """ + return self.add_variants(variants, package_cache_async=True) - # A prod install is necessary because add_variants_async works by + def add_variants(self, variants, package_cache_async=True): + """Add the given variants to the package payload cache. + """ + + # A prod install is necessary because add_variants works by # starting a rez-pkg-cache proc, and this can only be done reliably in # a prod install. On non-windows we could fork instead, but there would # remain no good solution on windows. # if not system.is_production_rez_install: raise PackageCacheError( - "PackageCache.add_variants_async is only supported in a " + "PackageCache.add_variants is only supported in a " "production rez installation." ) variants_ = [] + cachable_statuses = { + self.VARIANT_NOT_FOUND, + } + if not package_cache_async: + # We want to monitor copying variants if we're synchronous. + # We also want to report that a status has been stalled, so we'll + # hand that off to the caching function as well + cachable_statuses.update({ + self.VARIANT_COPYING, + self.VARIANT_COPY_STALLED, + }) # trim down to those variants that are cachable, and not already cached for variant in variants: @@ -386,7 +446,7 @@ def add_variants_async(self, variants): continue status, _ = self._get_cached_root(variant) - if status == self.VARIANT_NOT_FOUND: + if status in cachable_statuses: variants_.append(variant) # if there are no variants to add, and no potential cleanup to do, then exit @@ -427,6 +487,20 @@ def add_variants_async(self, variants): with open(filepath, 'w') as f: f.write(json.dumps(handle_dict)) + if package_cache_async: + self._subprocess_package_caching_daemon(self.path) + else: + # syncronous caching + self._run_caching_operation(wait_for_copying=True) + + @staticmethod + def _subprocess_package_caching_daemon(path): + """ + Run the package cache in a daemon process + + Returns: + subprocess.Popen : The package caching daemon process + """ # configure executable if platform.system() == "Windows": kwargs = { @@ -443,7 +517,7 @@ def add_variants_async(self, variants): raise RuntimeError("Did not find rez-pkg-cache executable") # start caching subproc - args = [exe, "--daemon", self.path] + args = [exe, "--daemon", path] try: with open(os.devnull, 'w') as devnull: @@ -454,8 +528,8 @@ def add_variants_async(self, variants): else: out_target = devnull - subprocess.Popen( - [exe, "--daemon", self.path], + return subprocess.Popen( + args, stdout=out_target, stderr=out_target, **kwargs @@ -558,6 +632,15 @@ def run_daemon(self): if pid > 0: sys.exit(0) + self._run_caching_operation(wait_for_copying=False) + + def _run_caching_operation(self, wait_for_copying=True): + """Copy pending variants. + + Args: + wait_for_copying (bool): Whether the caching step should block when one of the + pending variants is marked as already copying. + """ logger = self._init_logging() # somewhere for the daemon to store stateful info @@ -568,7 +651,7 @@ def run_daemon(self): # copy variants into cache try: while True: - keep_running = self._run_daemon_step(state) + keep_running = self._run_caching_step(state, wait_for_copying=wait_for_copying) if not keep_running: break except Exception: @@ -682,12 +765,13 @@ def _lock(self): except NotLocked: pass - def _run_daemon_step(self, state): + def _run_caching_step(self, state, wait_for_copying=False): logger = state["logger"] # pick a random pending variant to copy pending_filenames = set(os.listdir(self._pending_dir)) - pending_filenames -= set(state.get("copying", set())) + if not wait_for_copying: + pending_filenames -= set(state.get("copying", set())) if not pending_filenames: return False @@ -710,7 +794,11 @@ def _run_daemon_step(self, state): t = time.time() try: - rootpath, status = self.add_variant(variant) + rootpath, status = self.add_variant( + variant, + wait_for_copying=wait_for_copying, + logger=logger, + ) except PackageCacheError as e: # variant cannot be cached, so remove as a pending variant diff --git a/src/rez/resolved_context.py b/src/rez/resolved_context.py index 45dc6e3e6..7e1586b41 100644 --- a/src/rez/resolved_context.py +++ b/src/rez/resolved_context.py @@ -167,7 +167,7 @@ def __init__(self, package_requests, verbosity=0, timestamp=None, package_filter=None, package_orderers=None, max_fails=-1, add_implicit_packages=True, time_limit=-1, callback=None, package_load_callback=None, buf=None, suppress_passive=False, - print_stats=False, package_caching=None): + print_stats=False, package_caching=None, package_cache_async=None): """Perform a package resolve, and store the result. Args: @@ -205,6 +205,8 @@ def __init__(self, package_requests, verbosity=0, timestamp=None, package_caching (bool|None): If True, apply package caching settings as per the config. If None, enable as determined by config setting :data:`package_cache_during_build`. + package_cache_async (bool|None): If True, cache packages asynchronously. + If None, use the config setting :data:`package_cache_async` """ self.load_path = None @@ -246,9 +248,12 @@ def __init__(self, package_requests, verbosity=0, timestamp=None, package_caching = config.package_cache_during_build else: package_caching = True - self.package_caching = package_caching + if package_cache_async is None: + package_cache_async = config.package_cache_async + self.package_cache_async = package_cache_async + # patch settings self.default_patch_lock = PatchLock.no_lock self.patch_locks = {} @@ -1839,13 +1844,16 @@ def _update_package_cache(self): not self.success: return - # see PackageCache.add_variants_async + # see PackageCache.add_variants if not system.is_production_rez_install: return pkgcache = self._get_package_cache() if pkgcache: - pkgcache.add_variants_async(self.resolved_packages) + pkgcache.add_variants( + self.resolved_packages, + self.package_cache_async, + ) @classmethod def _init_context_tracking_payload_base(cls): diff --git a/src/rez/rezconfig.py b/src/rez/rezconfig.py index e9306d1bd..1abd59f71 100644 --- a/src/rez/rezconfig.py +++ b/src/rez/rezconfig.py @@ -278,6 +278,12 @@ # Enable package caching during a package build. package_cache_during_build = False +# Asynchronously cache packages. If this is false, resolves will block until +# all packages are cached. +# +# .. versionadded:: 3.2.0 +package_cache_async = True + # Allow caching of local packages. You would only want to set this True for # testing purposes. package_cache_local = False @@ -313,7 +319,7 @@ # This is useful as Platform.os might show different # values depending on the availability of ``lsb-release`` on the system. # The map supports regular expression, e.g. to keep versions. -# +# # .. note:: # The following examples are not necessarily recommendations. # @@ -1137,7 +1143,7 @@ # Enables/disables colorization globally. # -# .. warning:: +# .. warning:: # Turned off for Windows currently as there seems to be a problem with the colorama module. # # May also set to the string ``force``, which will make rez output color styling diff --git a/src/rez/tests/test_package_cache.py b/src/rez/tests/test_package_cache.py index c340dbfe7..01f91ff7d 100644 --- a/src/rez/tests/test_package_cache.py +++ b/src/rez/tests/test_package_cache.py @@ -134,24 +134,76 @@ def test_caching_on_resolve(self): # Creating the context will asynchronously add variants to the cache # in a separate proc. - # + # NOTE: pyfoo will not cache, because its repo is set to non-caching (see above) c = ResolvedContext([ "timestamped-1.2.0", - "pyfoo-3.1.0" # won't cache, see earlier test + "pyfoo-3.1.0" ]) + # Prove that the resolved context used async mode. + self.assertTrue(c.package_cache_async) + variant = c.get_resolved_package("timestamped") # Retry 50 times with 0.1 sec interval, 5 secs is more than enough for # the very small variant to be copied to cache. - # cached_root = None + resolve_not_always_cached = False for _ in range(50): - time.sleep(0.1) cached_root = pkgcache.get_cached_root(variant) if cached_root: break + resolve_not_always_cached = True + time.sleep(0.1) + + self.assertNotEqual(cached_root, None, + msg="Packages were expected to be cached, but were not.") + + # Test that the package is not immediately cached, since it is asynchronous + # WARNING: This is dangerous since it does open the test to a race condition and + # will fail if the cache happens faster than the resolve. + self.assertNotEqual(resolve_not_always_cached, False) + + expected_payload_file = os.path.join(cached_root, "stuff.txt") + self.assertTrue(os.path.exists(expected_payload_file)) + + # check that refs to root point to cache location in rex code + for ref in ("resolve.timestamped.root", "'{resolve.timestamped.root}'"): + proc = c.execute_rex_code( + code="info(%s)" % ref, + stdout=subprocess.PIPE, + universal_newlines=True + ) + + out, _ = proc.communicate() + root = out.strip() + + self.assertEqual( + root, cached_root, + "Reference %r should resolve to %s, but resolves to %s" + % (ref, cached_root, root) + ) + + @install_dependent() + def test_caching_on_resolve_synchronous(self): + """Test that cache is updated as expected on + resolved env using syncrhonous package caching.""" + pkgcache = self._pkgcache() + + with restore_os_environ(): + # set config settings into env so rez-pkg-cache proc sees them + os.environ.update(self.get_settings_env()) + + # Creating the context will synchronously add variants to the cache + c = ResolvedContext( + ["timestamped-1.2.0", "pyfoo-3.1.0"], + package_cache_async=False, + ) + + variant = c.get_resolved_package("timestamped") + # The first time we try to access it will be cached, because the cache is blocking + cached_root = pkgcache.get_cached_root(variant) self.assertNotEqual(cached_root, None) expected_payload_file = os.path.join(cached_root, "stuff.txt") From 57136a3f28969672cccb1280661e785f4474f6a1 Mon Sep 17 00:00:00 2001 From: Parikshit Tiwari Date: Sat, 29 Jun 2024 20:10:54 +0530 Subject: [PATCH 49/68] Fix incorrect string operations on bytes output of subprocess causing wrong shell type to be selected (#1765) Signed-off-by: Parikshit Tiwari Signed-off-by: Jean-Christophe Morin Co-authored-by: Jean-Christophe Morin --- src/rez/system.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rez/system.py b/src/rez/system.py index 25780c1e7..8486a71af 100644 --- a/src/rez/system.py +++ b/src/rez/system.py @@ -86,7 +86,7 @@ def shell(self): # print an error message: "process ID out of range". try: args = ['ps', '-o', 'args=', '-p', str(parent_pid)] - proc = sp.Popen(args, stdout=sp.PIPE) + proc = sp.Popen(args, stdout=sp.PIPE, text=True) output = proc.communicate()[0] shell = os.path.basename(output.strip().split()[0]).replace('-', '') except Exception: From 980dd0b2beb565b6a5e2f9f8c59d403231879ff8 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> Date: Sat, 29 Jun 2024 11:03:05 -0400 Subject: [PATCH 50/68] Pin GH actions to commit hash as recommended by scorecard (#1781) Signed-off-by: Jean-Christophe Morin --- .github/workflows/benchmark.yaml | 14 +++++++------- .github/workflows/copyright.yaml | 4 ++-- .github/workflows/flake8.yaml | 4 ++-- .github/workflows/installation.yaml | 4 ++-- .github/workflows/pypi.yaml | 6 +++--- .github/workflows/tests.yaml | 6 +++--- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml index 56f557d62..c8612561d 100644 --- a/.github/workflows/benchmark.yaml +++ b/.github/workflows/benchmark.yaml @@ -22,10 +22,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Setup python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: python-version: ${{ matrix.python-version }} @@ -46,7 +46,7 @@ jobs: run: | python ./.github/scripts/validate_benchmark.py - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: "benchmark-result-${{ matrix.python-version }}" path: ./out @@ -65,13 +65,13 @@ jobs: max-parallel: 1 steps: - - uses: actions/download-artifact@v4 + - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 with: name: "benchmark-result-${{ matrix.python-version }}" path: . - name: Checkout (release) - uses: actions/checkout@v4 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 if: ${{ github.event_name =='release' }} with: ref: main @@ -85,13 +85,13 @@ jobs: # token: "${{ secrets.GH_ACTION_TOKEN }}" - name: Checkout (pr) - uses: actions/checkout@v4 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 if: ${{ github.event_name !='release' }} with: path: src - name: Setup python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/copyright.yaml b/.github/workflows/copyright.yaml index 2c4d48ae4..6aac610e1 100644 --- a/.github/workflows/copyright.yaml +++ b/.github/workflows/copyright.yaml @@ -17,10 +17,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: python-version: 3 diff --git a/.github/workflows/flake8.yaml b/.github/workflows/flake8.yaml index 14221cfcb..f397a86fc 100644 --- a/.github/workflows/flake8.yaml +++ b/.github/workflows/flake8.yaml @@ -26,10 +26,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: python-version: 3.7 diff --git a/.github/workflows/installation.yaml b/.github/workflows/installation.yaml index 01232c3cd..b820be984 100644 --- a/.github/workflows/installation.yaml +++ b/.github/workflows/installation.yaml @@ -76,10 +76,10 @@ jobs: REZ_INSTALL_COMMAND: pip install --target C:\ProgramData\rez . steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Setup python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/pypi.yaml b/.github/workflows/pypi.yaml index 13566cc7b..a438aaf05 100644 --- a/.github/workflows/pypi.yaml +++ b/.github/workflows/pypi.yaml @@ -14,10 +14,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: python-version: 3.11 @@ -32,6 +32,6 @@ jobs: # Note that we don't need credentials. # We rely on https://docs.pypi.org/trusted-publishers/. - name: Upload to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@ec4db0b4ddc65acdf4bff5fa45ac92d78b56bdf0 # v1.9.0 with: packages-dir: dist diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index dc19ae3b6..31c04183b 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -57,10 +57,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Setup python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 with: python-version: ${{ matrix.python-version }} @@ -95,7 +95,7 @@ jobs: _REZ_ENSURE_TEST_SHELLS: ${{ matrix.shells }} - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0 # Run on both success and failure, but only if coverage.xml exists. if: ${{ hashFiles('coverage.xml') != '' && (steps.tests.outcome == 'success' || steps.tests.outcome == 'failure') }} with: From e215a77c7481aa0eafcbb848de18376702088bd9 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> Date: Sat, 29 Jun 2024 11:27:41 -0400 Subject: [PATCH 51/68] Restrict permissions in GHA workflows (#1782) Signed-off-by: Jean-Christophe Morin --- .github/workflows/benchmark.yaml | 3 +++ .github/workflows/copyright.yaml | 3 +++ .github/workflows/flake8.yaml | 3 +++ .github/workflows/installation.yaml | 3 +++ .github/workflows/pypi.yaml | 5 +++++ .github/workflows/release-notice.yaml | 3 +++ .github/workflows/tests.yaml | 3 +++ 7 files changed, 23 insertions(+) diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml index c8612561d..cbdec3b36 100644 --- a/.github/workflows/benchmark.yaml +++ b/.github/workflows/benchmark.yaml @@ -8,6 +8,9 @@ on: pull_request: types: [opened, synchronize, reopened, labeled] +permissions: + contents: read + jobs: run_benchmark: name: run_benchmark diff --git a/.github/workflows/copyright.yaml b/.github/workflows/copyright.yaml index 6aac610e1..641753a07 100644 --- a/.github/workflows/copyright.yaml +++ b/.github/workflows/copyright.yaml @@ -10,6 +10,9 @@ on: - '!**.md' workflow_dispatch: +permissions: + contents: read + jobs: main: name: Enforce copyright notices diff --git a/.github/workflows/flake8.yaml b/.github/workflows/flake8.yaml index f397a86fc..b0eabda88 100644 --- a/.github/workflows/flake8.yaml +++ b/.github/workflows/flake8.yaml @@ -19,6 +19,9 @@ on: - '!src/rez/vendor/**' - '!src/rez/backport/**' +permissions: + contents: read + jobs: lint: name: Run Linter diff --git a/.github/workflows/installation.yaml b/.github/workflows/installation.yaml index b820be984..577fb28b8 100644 --- a/.github/workflows/installation.yaml +++ b/.github/workflows/installation.yaml @@ -22,6 +22,9 @@ on: - '!**.md' workflow_dispatch: +permissions: + contents: read + jobs: main: name: ${{ matrix.os }} - ${{ matrix.python-version }} - ${{ matrix.method }} diff --git a/.github/workflows/pypi.yaml b/.github/workflows/pypi.yaml index a438aaf05..77593e949 100644 --- a/.github/workflows/pypi.yaml +++ b/.github/workflows/pypi.yaml @@ -3,6 +3,9 @@ on: release: types: [released] +permissions: + contents: read + jobs: publish: name: Publish to PyPI @@ -11,6 +14,8 @@ jobs: permissions: # IMPORTANT: this permission is mandatory for trusted publishing id-token: write + # Not sure if it's needed here since it's defined at the top level. + contents: read steps: - name: Checkout diff --git a/.github/workflows/release-notice.yaml b/.github/workflows/release-notice.yaml index a0184b6e3..60056a71b 100644 --- a/.github/workflows/release-notice.yaml +++ b/.github/workflows/release-notice.yaml @@ -6,6 +6,9 @@ on: # published should cover both 'released' and 'prereleased' - published +permissions: + contents: read + jobs: publish: runs-on: ubuntu-latest diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 31c04183b..3df775505 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -26,6 +26,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: + contents: read + jobs: core: name: Tests From 63879080c1029dba18807ce097e94804e41039c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 16:40:27 -0400 Subject: [PATCH 52/68] Bump actions/checkout from 4.1.1 to 4.1.7 (#1785) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 to 4.1.7. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4.1.1...692973e3d937129bcbf40652eb9f2f61becf3332) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 8f4ffcd1d..8ccf83ac6 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -25,7 +25,7 @@ jobs: steps: - name: "Checkout code" - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 with: persist-credentials: false From 670771588638458b23c32abe39bed8e94ec54cfc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 16:41:13 -0400 Subject: [PATCH 53/68] Bump actions/upload-artifact from 4.3.2 to 4.3.3 (#1784) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.2 to 4.3.3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4.3.2...65462800fd760344b1a7b4382951275a0abb4808) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 8ccf83ac6..395195041 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -52,7 +52,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2 + uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 with: name: SARIF file path: results.sarif From 6c36578ac3a7ff8da0000c2e8e6e3c8d87c1c6ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 16:42:07 -0400 Subject: [PATCH 54/68] Bump github/codeql-action from 3.25.10 to 3.25.11 (#1783) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.10 to 3.25.11. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/23acc5c183826b7a8a97bce3cecc52db901f8251...b611370bb5703a7efb587f9d136a52ea24c5c38c) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 395195041..ecefd17dd 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -61,6 +61,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10 + uses: github/codeql-action/upload-sarif@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3.25.11 with: sarif_file: results.sarif From 5e27af6c72e369e314d9629189584867fc2302ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 14:26:45 -0400 Subject: [PATCH 55/68] Bump actions/upload-artifact from 4.3.3 to 4.3.4 (#1790) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.3 to 4.3.4. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/65462800fd760344b1a7b4382951275a0abb4808...0b2256b8c012f0828dc542b3febcab082c67f72b) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yaml | 2 +- .github/workflows/scorecard.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml index cbdec3b36..dacdeb0dd 100644 --- a/.github/workflows/benchmark.yaml +++ b/.github/workflows/benchmark.yaml @@ -49,7 +49,7 @@ jobs: run: | python ./.github/scripts/validate_benchmark.py - - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + - uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 with: name: "benchmark-result-${{ matrix.python-version }}" path: ./out diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index ecefd17dd..ded84dece 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -52,7 +52,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 + uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 with: name: SARIF file path: results.sarif From 226bc37b0d0c1bc8731f0017e3d6f97977cedcea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 14:27:03 -0400 Subject: [PATCH 56/68] Bump actions/download-artifact from 4.1.7 to 4.1.8 (#1789) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4.1.7 to 4.1.8. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/65a9edc5881444af0b9093a5e628f2fe47ea3b2e...fa0a91b85d4f404e444e00e005971372dc801d16) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml index dacdeb0dd..f503d44c3 100644 --- a/.github/workflows/benchmark.yaml +++ b/.github/workflows/benchmark.yaml @@ -68,7 +68,7 @@ jobs: max-parallel: 1 steps: - - uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7 + - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 with: name: "benchmark-result-${{ matrix.python-version }}" path: . From 940e1ae63f1bef16a306b81705baababa5a5d944 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 14:49:59 -0400 Subject: [PATCH 57/68] Bump github/codeql-action from 3.25.11 to 3.25.12 (#1795) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.11 to 3.25.12. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/b611370bb5703a7efb587f9d136a52ea24c5c38c...4fa2a7953630fd2f3fb380f21be14ede0169dd4f) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index ded84dece..3d52ec4d2 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -61,6 +61,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3.25.11 + uses: github/codeql-action/upload-sarif@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3.25.12 with: sarif_file: results.sarif From 9c27f5ee667359f0dc4719ded6bbbe2b97f5462b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 14:50:30 -0400 Subject: [PATCH 58/68] Bump actions/setup-python from 5.1.0 to 5.1.1 (#1794) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.1.0 to 5.1.1. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/82c7e631bb3cdc910f68e0081d67478d79c6982d...39cd14951b08e74b54015e9e001cdefcf80e669f) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yaml | 4 ++-- .github/workflows/copyright.yaml | 2 +- .github/workflows/flake8.yaml | 2 +- .github/workflows/installation.yaml | 2 +- .github/workflows/pypi.yaml | 2 +- .github/workflows/tests.yaml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml index f503d44c3..ebc35889f 100644 --- a/.github/workflows/benchmark.yaml +++ b/.github/workflows/benchmark.yaml @@ -28,7 +28,7 @@ jobs: uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Setup python ${{ matrix.python-version }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 with: python-version: ${{ matrix.python-version }} @@ -94,7 +94,7 @@ jobs: path: src - name: Setup python ${{ matrix.python-version }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/copyright.yaml b/.github/workflows/copyright.yaml index 641753a07..9b161414b 100644 --- a/.github/workflows/copyright.yaml +++ b/.github/workflows/copyright.yaml @@ -23,7 +23,7 @@ jobs: uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 with: python-version: 3 diff --git a/.github/workflows/flake8.yaml b/.github/workflows/flake8.yaml index b0eabda88..a3043489e 100644 --- a/.github/workflows/flake8.yaml +++ b/.github/workflows/flake8.yaml @@ -32,7 +32,7 @@ jobs: uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 with: python-version: 3.7 diff --git a/.github/workflows/installation.yaml b/.github/workflows/installation.yaml index 577fb28b8..a7e7d8281 100644 --- a/.github/workflows/installation.yaml +++ b/.github/workflows/installation.yaml @@ -82,7 +82,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Setup python ${{ matrix.python-version }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/pypi.yaml b/.github/workflows/pypi.yaml index 77593e949..f70a1338f 100644 --- a/.github/workflows/pypi.yaml +++ b/.github/workflows/pypi.yaml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 with: python-version: 3.11 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 3df775505..ee0e9d850 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -63,7 +63,7 @@ jobs: uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Setup python ${{ matrix.python-version }} - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0 + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 with: python-version: ${{ matrix.python-version }} From 3d0f22489827f8def994cb2e5590d51445e55123 Mon Sep 17 00:00:00 2001 From: Ruzette Tanyag Date: Sun, 21 Jul 2024 17:41:04 -0400 Subject: [PATCH 59/68] Fix TypeError when running get_rpaths on rez.utils.elf module (#1798) Signed-off-by: Ruzette Krukkert Signed-off-by: Jean-Christophe Morin Co-authored-by: Jean-Christophe Morin --- src/rez/tests/test_utils_elf.py | 38 +++++++++++++++++++++++++++++++++ src/rez/tests/util.py | 23 +------------------- src/rez/utils/elf.py | 4 +++- 3 files changed, 42 insertions(+), 23 deletions(-) create mode 100644 src/rez/tests/test_utils_elf.py diff --git a/src/rez/tests/test_utils_elf.py b/src/rez/tests/test_utils_elf.py new file mode 100644 index 000000000..b04a906d5 --- /dev/null +++ b/src/rez/tests/test_utils_elf.py @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright Contributors to the Rez Project + + +""" +unit tests for 'rez.utils.elf' module +""" +import platform +import unittest + +from rez.tests.util import TestBase, program_dependent +from rez.utils.elf import get_rpaths, patch_rpaths + + +class TestElfUtils(TestBase): + + def __init__(self, *nargs, **kwargs): + super().__init__(*nargs, **kwargs) + + @classmethod + def setUpClass(cls): + super().setUpClass() + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + + @unittest.skipUnless(platform.system() == "Linux", "Linux only") + @program_dependent("readelf") + def test_get_rpaths_raises_runtime_exception(self): + """Tests that no TypeError from elf functions are raised.""" + with self.assertRaises(RuntimeError) as exc: + get_rpaths("/path/to/elfpath") + self.assertIn("'/path/to/elfpath': No such file", str(exc.exception)) + + with self.assertRaises(RuntimeError) as exc: + patch_rpaths("/path/to/elfpath", ["$ORIGIN", "$ORIGINTEST"]) + self.assertIn("'/path/to/elfpath': No such file", str(exc.exception)) diff --git a/src/rez/tests/util.py b/src/rez/tests/util.py index dc03c9aa9..60e2d865c 100644 --- a/src/rez/tests/util.py +++ b/src/rez/tests/util.py @@ -187,33 +187,12 @@ def find_file_in_path(to_find, path_str, pathsep=None, reverse=True): def program_dependent(program_name, *program_names): """Function decorator that skips the function if not all given programs are visible.""" - import subprocess - - program_tests = { - "cmake": ['cmake', '-h'], - "make": ['make', '-h'], - "g++": ["g++", "--help"] - } - - # test if programs all exist - def _test(name): - command = program_tests[name] - - with open(os.devnull, 'wb') as DEVNULL: - try: - subprocess.check_call(command, stdout=DEVNULL, stderr=DEVNULL) - except (OSError, IOError, subprocess.CalledProcessError): - return False - else: - return True - names = [program_name] + list(program_names) - all_exist = all(_test(x) for x in names) def decorator(func): @functools.wraps(func) def wrapper(self, *args, **kwargs): - if not all_exist: + if not all(shutil.which(x) for x in names): self.skipTest( "Requires all programs to be present and functioning: %s" % names diff --git a/src/rez/utils/elf.py b/src/rez/utils/elf.py index 87f6b2968..0916f32b6 100644 --- a/src/rez/utils/elf.py +++ b/src/rez/utils/elf.py @@ -10,6 +10,7 @@ import subprocess from rez.utils.filesystem import make_path_writable +from rez.utils.execution import Popen def get_rpaths(elfpath): @@ -54,10 +55,11 @@ def patch_rpaths(elfpath, rpaths): def _run(*nargs, **popen_kwargs): - proc = subprocess.Popen( + proc = Popen( nargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + text=True, **popen_kwargs ) From 87fed93cc1da1e2145a7e1b5fa3e9521739652e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 15:48:05 -0400 Subject: [PATCH 60/68] Bump github/codeql-action from 3.25.12 to 3.26.5 (#1816) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.12 to 3.26.5. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/4fa2a7953630fd2f3fb380f21be14ede0169dd4f...2c779ab0d087cd7fe7b826087247c2c81f27bfa6) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 3d52ec4d2..9fb7f1935 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -61,6 +61,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@4fa2a7953630fd2f3fb380f21be14ede0169dd4f # v3.25.12 + uses: github/codeql-action/upload-sarif@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 with: sarif_file: results.sarif From 34373d90257b28cb63ae42d75e8099e9413753dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 15:48:46 -0400 Subject: [PATCH 61/68] Bump actions/upload-artifact from 4.3.4 to 4.3.6 (#1814) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.4 to 4.3.6. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/0b2256b8c012f0828dc542b3febcab082c67f72b...834a144ee995460fba8ed112a2fc961b36a5ec5a) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yaml | 2 +- .github/workflows/scorecard.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml index ebc35889f..48f2e1de6 100644 --- a/.github/workflows/benchmark.yaml +++ b/.github/workflows/benchmark.yaml @@ -49,7 +49,7 @@ jobs: run: | python ./.github/scripts/validate_benchmark.py - - uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 + - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 with: name: "benchmark-result-${{ matrix.python-version }}" path: ./out diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 9fb7f1935..e65017662 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -52,7 +52,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 + uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 with: name: SARIF file path: results.sarif From 6f5bcdb355e52b830a4c61f5bd86b0f0ca9245d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 15:49:31 -0400 Subject: [PATCH 62/68] Bump ossf/scorecard-action from 2.3.3 to 2.4.0 (#1805) Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.3.3 to 2.4.0. - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/dc50aa9510b46c811795eb24b2f1ba02a914e534...62b2cac7ed8198b15735ed49ab1e5cf35480ba46) --- updated-dependencies: - dependency-name: ossf/scorecard-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index e65017662..d3beab08b 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -30,7 +30,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3 + uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 with: results_file: results.sarif results_format: sarif From 9146079ed842880257ebe2b0c209d6441e2daab0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:18:18 -0400 Subject: [PATCH 63/68] Bump github/codeql-action from 3.26.5 to 3.26.7 (#1827) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.5 to 3.26.7. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/2c779ab0d087cd7fe7b826087247c2c81f27bfa6...8214744c546c1e5c8f03dde8fab3a7353211988d) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index d3beab08b..e31ee6438 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -61,6 +61,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard (optional). # Commenting out will disable upload of results to your repo's Code Scanning dashboard - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5 + uses: github/codeql-action/upload-sarif@8214744c546c1e5c8f03dde8fab3a7353211988d # v3.26.7 with: sarif_file: results.sarif From 41fb213dc61387b97d49eb45d043161a8828c9b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:24:15 -0400 Subject: [PATCH 64/68] Bump actions/setup-python from 5.1.1 to 5.2.0 (#1820) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.1.1 to 5.2.0. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/39cd14951b08e74b54015e9e001cdefcf80e669f...f677139bbe7f9c59b41e40162b753c062f5d49a3) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yaml | 4 ++-- .github/workflows/copyright.yaml | 2 +- .github/workflows/flake8.yaml | 2 +- .github/workflows/installation.yaml | 2 +- .github/workflows/pypi.yaml | 2 +- .github/workflows/tests.yaml | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml index 48f2e1de6..40227ed4d 100644 --- a/.github/workflows/benchmark.yaml +++ b/.github/workflows/benchmark.yaml @@ -28,7 +28,7 @@ jobs: uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Setup python ${{ matrix.python-version }} - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ matrix.python-version }} @@ -94,7 +94,7 @@ jobs: path: src - name: Setup python ${{ matrix.python-version }} - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/copyright.yaml b/.github/workflows/copyright.yaml index 9b161414b..1aef5e067 100644 --- a/.github/workflows/copyright.yaml +++ b/.github/workflows/copyright.yaml @@ -23,7 +23,7 @@ jobs: uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: 3 diff --git a/.github/workflows/flake8.yaml b/.github/workflows/flake8.yaml index a3043489e..8e985b829 100644 --- a/.github/workflows/flake8.yaml +++ b/.github/workflows/flake8.yaml @@ -32,7 +32,7 @@ jobs: uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: 3.7 diff --git a/.github/workflows/installation.yaml b/.github/workflows/installation.yaml index a7e7d8281..f48332f1b 100644 --- a/.github/workflows/installation.yaml +++ b/.github/workflows/installation.yaml @@ -82,7 +82,7 @@ jobs: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Setup python ${{ matrix.python-version }} - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/pypi.yaml b/.github/workflows/pypi.yaml index f70a1338f..be31c8cd6 100644 --- a/.github/workflows/pypi.yaml +++ b/.github/workflows/pypi.yaml @@ -22,7 +22,7 @@ jobs: uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Set up Python - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: 3.11 diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index ee0e9d850..6fdb56bc5 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -63,7 +63,7 @@ jobs: uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 - name: Setup python ${{ matrix.python-version }} - uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 with: python-version: ${{ matrix.python-version }} From 02035db1128b587ec0250f81bc30efeaf4b9337f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:25:00 -0400 Subject: [PATCH 65/68] Bump actions/upload-artifact from 4.3.6 to 4.4.0 (#1819) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.6 to 4.4.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/834a144ee995460fba8ed112a2fc961b36a5ec5a...50769540e7f4bd5e21e526ee35c689e35e0d6874) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark.yaml | 2 +- .github/workflows/scorecard.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml index 40227ed4d..eede21f4a 100644 --- a/.github/workflows/benchmark.yaml +++ b/.github/workflows/benchmark.yaml @@ -49,7 +49,7 @@ jobs: run: | python ./.github/scripts/validate_benchmark.py - - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: "benchmark-result-${{ matrix.python-version }}" path: ./out diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index e31ee6438..53559ea3d 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -52,7 +52,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: SARIF file path: results.sarif From f0e40fd478e1eea2d0a0f7da2556f49a857e8dd2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:30:21 -0400 Subject: [PATCH 66/68] Update sphinx requirement from <8.0.0,>=7.0.0 to >=7.0.0,<9.0.0 in /docs (#1804) Updates the requirements on [sphinx](https://github.com/sphinx-doc/sphinx) to permit the latest version. - [Release notes](https://github.com/sphinx-doc/sphinx/releases) - [Changelog](https://github.com/sphinx-doc/sphinx/blob/master/CHANGES.rst) - [Commits](https://github.com/sphinx-doc/sphinx/compare/v7.0.0...v8.0.0) --- updated-dependencies: - dependency-name: sphinx dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 0b74fb749..1fecad963 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,3 @@ -sphinx >=7.0.0,<8.0.0 +sphinx >=7.0.0,<9.0.0 furo myst-parser From 63326f2703e5fcd05f10e6025c321ec39592bd4c Mon Sep 17 00:00:00 2001 From: Bryce Gattis <69012021+brycegbrazen@users.noreply.github.com> Date: Sun, 22 Sep 2024 13:35:39 -0500 Subject: [PATCH 67/68] Make Powershell correctly return exit codes for aliases (#1778) Fixes issue where powershell plugins were not correctly capturing exit codes when aliased commands failed (#1778) --------- Signed-off-by: brycegbrazen Co-authored-by: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> --- src/rez/tests/test_shells.py | 16 ++++++++++++++++ src/rezplugins/shell/_utils/powershell_base.py | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/rez/tests/test_shells.py b/src/rez/tests/test_shells.py index 35f7de76e..114497089 100644 --- a/src/rez/tests/test_shells.py +++ b/src/rez/tests/test_shells.py @@ -591,6 +591,22 @@ def _make_alias(ex): out, _ = p.communicate() self.assertEqual(0, p.returncode) + @per_available_shell() + def test_alias_return_code(self, shell): + """Ensure return codes are correct while using aliases.""" + config.override("default_shell", shell) + + def _make_alias(ex): + ex.alias('my_alias', 'hello_world -r 1') + + r = self._create_context(["hello_world"]) + p = r.execute_shell(command='my_alias', + actions_callback=_make_alias, + stdout=subprocess.PIPE) + + out, _ = p.communicate() + self.assertEqual(1, p.returncode) + if __name__ == '__main__': unittest.main() diff --git a/src/rezplugins/shell/_utils/powershell_base.py b/src/rezplugins/shell/_utils/powershell_base.py index f059bb248..bf9d3014d 100644 --- a/src/rezplugins/shell/_utils/powershell_base.py +++ b/src/rezplugins/shell/_utils/powershell_base.py @@ -174,7 +174,7 @@ def _record_shell(ex, files, bind_rez=True, print_msg=False): # only the bool $? var is set. # executor.command( - "if(! $?) {\n" + "if(! $? -or $LASTEXITCODE) {\n" " if ($LASTEXITCODE) {\n" " exit $LASTEXITCODE\n" " }\n" From 8476696bfe445806658c6ea8b304f72a79b093ff Mon Sep 17 00:00:00 2001 From: Nathan Rusch Date: Sun, 22 Sep 2024 11:38:32 -0700 Subject: [PATCH 68/68] Fix `package_cache_async` missing from `ResolvedContext` dict round-trip. Also bumped the serialization formation from 4.7 to 4.8 (#1810) Signed-off-by: Nathan Rusch --- src/rez/resolved_context.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/rez/resolved_context.py b/src/rez/resolved_context.py index 7e1586b41..124a1cdf6 100644 --- a/src/rez/resolved_context.py +++ b/src/rez/resolved_context.py @@ -134,7 +134,7 @@ class ResolvedContext(object): command within a configured python namespace, without spawning a child shell. """ - serialize_version = (4, 7) + serialize_version = (4, 8) tmpdir_manager = TempDirs(config.context_tmpdir, prefix="rez_context_") context_tracking_payload = None context_tracking_lock = threading.Lock() @@ -1560,6 +1560,7 @@ def _add(field): append_sys_path=self.append_sys_path, package_caching=self.package_caching, + package_cache_async=self.package_cache_async, default_patch_lock=self.default_patch_lock.name, @@ -1716,6 +1717,10 @@ def _print_version(value): req = Requirement(eph_str) r._resolved_ephemerals.append(req) + # -- SINCE SERIALIZE VERSION 4.8 + + r.package_cache_async = d.get("package_cache_async", True) + # # track context usage