# Copyright 2011 Corentin Chary # Copyright 2020-2023 src_prepare group # Distributed under the terms of the GNU General Public License v2 import re import euscan.handlers def apply_mangling_rule(mangle, string): # convert regex from perl format to python format # there are some regex in this format: s/pattern/replacement/ m = re.match(r"s/(.*[^\\])/(.*)/", mangle) if not m: # or in this format s|pattern|replacement| m = re.match(r"s\|(.*[^\\])\|(.*)\|", mangle) if not m: # Not a known regex format return string pattern, repl = m.groups() repl = re.sub(r"\$(\d+)", r"\\\1", repl) return re.sub(pattern, repl, string) def apply_mangling_rules(kind, rules, string): """ Apply multiple mangling rules (both sed-like and handlers) in order """ if kind not in rules: return string for rule in rules[kind]: ret = None # First try handlers rules if rule == "gentoo" and kind == "versionmangle": ret = gentoo_mangle_version(string) elif kind == "downloadurlmangle": ret = euscan.handlers.mangle_url(rule, string) elif kind == "versionmangle": ret = euscan.handlers.mangle_version(rule, string) if ret is not None: # Use return value as new string if not None string = ret else: # Apply sed like rules string = apply_mangling_rule(rule, string) return string def mangle_version(up_pv, options): # Default rule is gentoo when empty if "versionmangle" not in options or not options["versionmangle"]: options["versionmangle"] = ["gentoo"] return apply_mangling_rules("versionmangle", options, up_pv) def mangle_url(url, options): return apply_mangling_rules("downloadurlmangle", options, url) # Stolen from g-pypi def gentoo_mangle_version(up_pv): """Convert PV to MY_PV if needed :param up_pv: Upstream package version :type up_pv: string :returns: pv :rtype: string Can't determine PV from upstream's version. Do our best with some well-known versioning schemes: * 1.0a1 (1.0_alpha1) * 1.0-a1 (1.0_alpha1) * 1.0b1 (1.0_beta1) * 1.0-b1 (1.0_beta1) * 1.0-r1234 (1.0_pre1234) * 1.0dev-r1234 (1.0_pre1234) * 1.0.dev-r1234 (1.0_pre1234) * 1.0dev-20091118 (1.0_pre20091118) Regex match.groups(): * pkgfoo-1.0.dev-r1234 * group 1 pv major (1.0) * group 2 replace this with portage suffix (.dev-r) * group 3 suffix version (1234) The order of the regexes is significant. For instance if you have .dev-r123, dev-r123 and -r123 you should order your regex's in that order. The chronological portage release versions are: * _alpha * _beta * _pre * _rc * release * _p **Example:** >>> gentoo_mangle_version('1.0b2') '1.0_beta2' .. note:: The number of regex's could have been reduced, but we use four number of match.groups every time to simplify the code """ bad_suffixes = re.compile(r"((?:[._-]*)(?:dev|devel|final|stable|snapshot)$)", re.I) revision_suffixes = re.compile(r"(.*?)([\._-]*(?:r|patch|p)[\._-]*)([0-9]*)$", re.I) suf_matches = { "_pre": [ r"(.*?)([\._-]*dev[\._-]*r?)([0-9]+)$", r"(.*?)([\._-]*(?:pre|preview)[\._-]*)([0-9]*)$", ], "_alpha": [ r"(.*?)([\._-]*(?:alpha|test)[\._-]*)([0-9]*)$", r"(.*?)([\._-]*a[\._-]*)([0-9]*)$", r"(.*[^a-z])(a)([0-9]*)$", ], "_beta": [ r"(.*?)([\._-]*beta[\._-]*)([0-9]*)$", r"(.*?)([\._-]*b)([0-9]*)$", r"(.*[^a-z])(b)([0-9]*)$", ], "_rc": [ r"(.*?)([\._-]*rc[\._-]*)([0-9]*)$", r"(.*?)([\._-]*c[\._-]*)([0-9]*)$", r"(.*[^a-z])(c[\._-]*)([0-9]+)$", ], } rs_match = None pv = up_pv additional_version = "" rev_match = revision_suffixes.search(up_pv) if rev_match: pv = up_pv = rev_match.group(1) # replace_me = rev_match.group(2) rev = rev_match.group(3) additional_version = "_p" + rev for this_suf in list(suf_matches.keys()): if rs_match: break for regex in suf_matches[this_suf]: rsuffix_regex = re.compile(regex, re.I) rs_match = rsuffix_regex.match(up_pv) if rs_match: portage_suffix = this_suf break if rs_match: # e.g. 1.0.dev-r1234 major_ver = rs_match.group(1) # 1.0 # replace_me = rs_match.group(2) # .dev-r rev = rs_match.group(3) # 1234 pv = major_ver + portage_suffix + rev else: # Single suffixes with no numeric component are simply removed. match = bad_suffixes.search(up_pv) if match: suffix = match.groups()[0] pv = up_pv[: -(len(suffix))] pv = pv + additional_version return pv