Source code for rez.utils.patching

# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the Rez Project


from rez.vendor.version.requirement import Requirement


[docs]def get_patched_request(requires, patchlist): """Apply patch args to a request. For example, consider: >>> print(get_patched_request(["foo-5", "bah-8.1"], ["foo-6"])) ["foo-6", "bah-8.1"] >>> print(get_patched_request(["foo-5", "bah-8.1"], ["^bah"])) ["foo-5"] The following rules apply wrt how normal/conflict/weak patches override (note though that the new request is always added, even if it doesn't override an existing request): PATCH OVERRIDES: foo !foo ~foo ----- ---------- --- ---- ----- foo Y Y Y !foo N N N ~foo N N Y ^foo Y Y Y Args: requires (list of str or `version.Requirement`): Request. patchlist (list of str): List of patch requests. Returns: List of `version.Requirement`: Patched request. """ # rules from table in docstring above rules = { '': (True, True, True), '!': (False, False, False), '~': (False, False, True), '^': (True, True, True) } requires = [Requirement(x) if not isinstance(x, Requirement) else x for x in requires] appended = [] for patch in patchlist: if patch and patch[0] in ('!', '~', '^'): ch = patch[0] name = Requirement(patch[1:]).name else: ch = '' name = Requirement(patch).name rule = rules[ch] replaced = (ch == '^') for i, req in enumerate(requires): if req is None or req.name != name: continue if not req.conflict: replace = rule[0] # foo elif not req.weak: replace = rule[1] # !foo else: replace = rule[2] # ~foo if replace: if replaced: requires[i] = None else: requires[i] = Requirement(patch) replaced = True if not replaced: appended.append(Requirement(patch)) result = [x for x in requires if x is not None] + appended return result