Merge pull request #43 from Enlik/nonregex-dep-rewrite
Simpler dependency rewrite syntax
This commit is contained in:
@@ -10,6 +10,8 @@
|
||||
# AND or OR operators: ( app-foo/bar & foo-app/rab ) | app-nice/woot
|
||||
# Please take this into consideration when writing dep rewrites.
|
||||
|
||||
# 1. Regex-based dependency rewrite syntax.
|
||||
|
||||
# LINE CONSTRUCTION:
|
||||
# <::pkg::> <::dep_pattern::> <::dep_replace_1::> [<::dep_replace_2::> ...]
|
||||
# ::pkg:: = package containing dependency to match, or * for catch-all
|
||||
@@ -59,3 +61,25 @@
|
||||
# Apply a dep_rewrite rule to any package being added:
|
||||
# * <::dep_pattern::> <::dep_replace_1::> [<::dep_replace_2::> ...]
|
||||
# In other words, set <::pkg::> to *
|
||||
|
||||
|
||||
# 2. Token-based dependency rewrite syntax.
|
||||
|
||||
# This syntax supports only modification to dependencies, not addition nor removal.
|
||||
# rewrite <::pkg::> <::rule::>
|
||||
# where <::pkg::> is matched the same was as explained above,
|
||||
# and <::rule::> is:
|
||||
# <from-dep=::dep_atom::> <to-dep=::new_dep_atom::>
|
||||
# [<if-dep-has-use=::use_to_match::>] [<drop-use=::use_to_remove::>]
|
||||
# (order does not matter).
|
||||
#
|
||||
# To a dependency to be rewritten, ::dep_atom:: must match and ::use_to_match:: if present.
|
||||
# Dependency will be rewritten as ::new_dep_atom::.
|
||||
# If present in rule, ::use_to_remove:: will be removed if dependency contains it.
|
||||
#
|
||||
# ::dep_atom:: and ::new_dep_atom:: are category/package names, without version, slot etc.
|
||||
# ::use_to_remove:: can be an asterisk (*) which means to remove all USE flags.
|
||||
#
|
||||
# EXAMPLE
|
||||
# rewrite foo/bar from-dep=app-crypt/pinentry to-dep=app-crypt/pinentry-gtk2 if-dep-has-use=gtk drop-use=gtk
|
||||
# will change foo/bar's dependency "app-crypt/pinentry[gtk,qt5]" to "app-crypt/pinentry-gtk2[qt5]".
|
||||
|
||||
+139
-1
@@ -3,8 +3,9 @@
|
||||
"""
|
||||
|
||||
@author: Fabio Erculiani <lxnay@sabayon.org>
|
||||
@author: Slawomir Nizio <slawomir.nizio@sabayon.org>
|
||||
@contact: lxnay@sabayon.org
|
||||
@copyright: Fabio Erculiani
|
||||
@copyright: Fabio Erculiani, Slawomir Nizio
|
||||
@license: GPL-2
|
||||
|
||||
B{Entropy dependency functions module}.
|
||||
@@ -1241,3 +1242,140 @@ def expand_dependencies(dependencies, entropy_repository_list,
|
||||
pkg_deps.append((dep, dep_type))
|
||||
|
||||
return pkg_deps
|
||||
|
||||
class WrongRewriteRuleError(Exception):
|
||||
"""
|
||||
Exception thrown when the new dep_rewrite mechanism encounters a badly
|
||||
formatted rule.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class DependencyRewriter(object):
|
||||
"""
|
||||
Class that implements the new dependency rewrite schema.
|
||||
It is simpler to use but less powerful than the regex based one, so the two
|
||||
are complementary.
|
||||
"""
|
||||
_use_in_depstring_re = re.compile(r"\[([^\]]+)\]")
|
||||
|
||||
def __init__(self, deps, rule):
|
||||
self.deps = deps
|
||||
self._rule = rule
|
||||
self._rule_dict = self._get_rewrite_rules_dict(rule)
|
||||
self.matched = None
|
||||
self.changed = None
|
||||
|
||||
self._dep_has_use, self._modify_use = self._setup_default_funcs()
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _get_rewrite_rules_dict(rule):
|
||||
known_rule_keys = set(["if-dep-has-use", "from-dep", "to-dep", "drop-use"])
|
||||
mandatory_keys = set(["from-dep", "to-dep"])
|
||||
|
||||
rule_dict = {}
|
||||
for rule_word in rule.split():
|
||||
try:
|
||||
op, arg = rule_word.split("=", 1)
|
||||
except ValueError:
|
||||
raise WrongRewriteRuleError("Badly formatted line with '%s'" % (rule_word,))
|
||||
rule_dict[op] = arg
|
||||
|
||||
if op not in known_rule_keys:
|
||||
raise WrongRewriteRuleError("Bad key '%s'" % (op,))
|
||||
|
||||
missing_keys = mandatory_keys - set(rule_dict.keys())
|
||||
if missing_keys:
|
||||
raise WrongRewriteRuleError("Incomplete rewrite rule")
|
||||
|
||||
return rule_dict
|
||||
|
||||
|
||||
def _setup_default_funcs(self):
|
||||
if 'if-dep-has-use' in self._rule_dict:
|
||||
dep_has_use_func = lambda deps_: self._rule_dict['if-dep-has-use'] in deps_
|
||||
else:
|
||||
dep_has_use_func = lambda _: True
|
||||
|
||||
if 'drop-use' in self._rule_dict:
|
||||
if self._rule_dict['drop-use'] == "*":
|
||||
modify_use_func = lambda dep_postfix, use_flags_list, clean_use_flags_list: \
|
||||
DependencyRewriter._use_in_depstring_re.sub(
|
||||
"",
|
||||
dep_postfix,
|
||||
count=1)
|
||||
else:
|
||||
modify_use_func = lambda dep_postfix, use_flags_list, clean_use_flags_list: \
|
||||
DependencyRewriter._use_in_depstring_re.sub(
|
||||
self._filter_use(use_flags_list, clean_use_flags_list, self._rule_dict['drop-use']),
|
||||
dep_postfix,
|
||||
count=1)
|
||||
else:
|
||||
modify_use_func = lambda dep_postfix, _1, _2: dep_postfix
|
||||
|
||||
return dep_has_use_func, modify_use_func
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _filter_use(use_list, clean_use_list, use_to_remove):
|
||||
filtered_use = []
|
||||
for orig_use, clean_use in zip(use_list, clean_use_list):
|
||||
if clean_use != use_to_remove:
|
||||
filtered_use.append(orig_use)
|
||||
|
||||
if filtered_use:
|
||||
result = "[%s]" % (",".join(filtered_use),)
|
||||
else:
|
||||
result = ""
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def rewrite(self):
|
||||
"""
|
||||
Do a rewrite of dependencies and set attributes: self.deps (rewritten
|
||||
dependencies), self.matched (any dependency matched its prerequisites)
|
||||
and self.changed (at least one dependency was modifed).
|
||||
|
||||
Value of these attributes is not defined before executing this method.
|
||||
"""
|
||||
matched = False
|
||||
changed = False
|
||||
|
||||
new_deps = []
|
||||
for dep in self.deps:
|
||||
clean_dep = dep_getkey(dep)
|
||||
dep_prefix, dep_postfix = dep.split(clean_dep, 1)
|
||||
|
||||
use_flags_list, clean_use_flags_list = self._use_flags_from_dep(dep_postfix)
|
||||
|
||||
if self._rule_dict['from-dep'] == clean_dep and self._dep_has_use(clean_use_flags_list):
|
||||
new_dep = dep_prefix + self._rule_dict['to-dep'] + self._modify_use(dep_postfix, use_flags_list, clean_use_flags_list)
|
||||
new_deps.append(new_dep)
|
||||
matched = True
|
||||
if dep != new_dep:
|
||||
changed = True
|
||||
else:
|
||||
new_deps.append(dep)
|
||||
|
||||
self.matched = matched
|
||||
self.changed = changed
|
||||
self.deps = new_deps
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _use_flags_from_dep(depstring):
|
||||
dep_use_match = DependencyRewriter._use_in_depstring_re.search(depstring)
|
||||
usestring = dep_use_match.group(1) if dep_use_match else ""
|
||||
dep_use = usestring.split(",")
|
||||
clean_dep_use = []
|
||||
use_postfixes_to_strip = ("?", "(-)", "(+)")
|
||||
for raw_dep in dep_use:
|
||||
for use_postfix_to_strip in use_postfixes_to_strip:
|
||||
if raw_dep.endswith(use_postfix_to_strip):
|
||||
raw_dep = raw_dep[:-len(use_postfix_to_strip)]
|
||||
clean_dep_use += [raw_dep]
|
||||
|
||||
assert len(dep_use) == len(clean_dep_use)
|
||||
return dep_use, clean_dep_use
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
"""
|
||||
|
||||
@author: Fabio Erculiani <lxnay@sabayon.org>
|
||||
@author: Slawomir Nizio <slawomir.nizio@sabayon.org>
|
||||
@contact: lxnay@sabayon.org
|
||||
@copyright: Fabio Erculiani
|
||||
@copyright: Fabio Erculiani, Slawomir Nizio
|
||||
@license: GPL-2
|
||||
|
||||
B{Entropy Package Manager Server Main Interfaces}.
|
||||
@@ -984,16 +985,83 @@ class ServerSystemSettingsPlugin(SystemSettingsPlugin):
|
||||
if cached is not None:
|
||||
return cached
|
||||
|
||||
data = {}
|
||||
data = []
|
||||
rewrite_file = Server._get_conf_dep_rewrite_file()
|
||||
if not os.path.isfile(rewrite_file):
|
||||
return data
|
||||
rewrite_content = self.__generic_parser(rewrite_file)
|
||||
|
||||
def add_dep_handler(dep_pattern):
|
||||
metadata = {'dep_pattern_str': dep_pattern,
|
||||
'replaces_str': _("added"),
|
||||
'action': "add",
|
||||
'add_what': dep_pattern}
|
||||
return metadata
|
||||
|
||||
def remove_dep_handler(dep_pattern, compiled_pattern):
|
||||
metadata = {'dep_pattern_str': dep_pattern,
|
||||
'replaces_str': _("removed"),
|
||||
'action': "remove",
|
||||
'does_dep_match_func': lambda dep_string: compiled_pattern.match(dep_string) is not None,
|
||||
'replaces': []}
|
||||
return metadata
|
||||
|
||||
def replace_dep_handler(dep_pattern, compiled_pattern, replaces):
|
||||
def _do(replace, dep_string):
|
||||
new_dep_string, number_of_subs_made = \
|
||||
compiled_pattern.subn(replace, dep_string)
|
||||
return new_dep_string, bool(number_of_subs_made)
|
||||
|
||||
metadata = {'dep_pattern_str': dep_pattern,
|
||||
'replaces_str': "=> " + ', '.join(replaces),
|
||||
'action': "replace",
|
||||
'does_dep_match_func': lambda dep_string: compiled_pattern.match(dep_string) is not None,
|
||||
'replaces': replaces,
|
||||
'do_func': _do}
|
||||
return metadata
|
||||
|
||||
def new_replace_dep_handler(rule):
|
||||
def _do(_unused, dep_string):
|
||||
try:
|
||||
# Should not actually happen as it's tested with does_dep_match_func.
|
||||
rewriter = entropy.dep.DependencyRewriter([dep_string], rule)
|
||||
except entropy.dep.WrongRewriteRuleError:
|
||||
return dep_string, False
|
||||
|
||||
rewriter.rewrite()
|
||||
return rewriter.deps[0], rewriter.changed
|
||||
|
||||
def _does_dep_match(dep_string):
|
||||
try:
|
||||
rewriter = entropy.dep.DependencyRewriter([dep_string], rule)
|
||||
except entropy.dep.WrongRewriteRuleError:
|
||||
return False
|
||||
|
||||
rewriter.rewrite()
|
||||
return rewriter.matched
|
||||
|
||||
metadata = {'dep_pattern_str': "rewrite",
|
||||
# not translated to match the keyword in configuration
|
||||
'replaces_str': "~> %s" % (rule,),
|
||||
'action': "replace",
|
||||
'does_dep_match_func': _does_dep_match,
|
||||
'replaces': [rule],
|
||||
'do_func': _do}
|
||||
return metadata
|
||||
|
||||
for line in rewrite_content:
|
||||
params = line.split()
|
||||
if len(params) < 2:
|
||||
continue
|
||||
|
||||
if params[0] == "rewrite":
|
||||
if len(params) < 3:
|
||||
continue
|
||||
_unused, pkg_match, rule = line.split(None, 2)
|
||||
metadata = new_replace_dep_handler(rule)
|
||||
data.append((pkg_match, metadata))
|
||||
continue
|
||||
|
||||
pkg_match, pattern, replaces = params[0], params[1], params[2:]
|
||||
if pattern.startswith("++"):
|
||||
compiled_pattern = None
|
||||
@@ -1007,8 +1075,18 @@ class ServerSystemSettingsPlugin(SystemSettingsPlugin):
|
||||
except re.error:
|
||||
# invalid pattern
|
||||
continue
|
||||
|
||||
if compiled_pattern is None:
|
||||
# this means that user is asking to add dep_pattern
|
||||
# as a dependency to package
|
||||
metadata = add_dep_handler(pattern)
|
||||
elif not replaces:
|
||||
# this means that user is asking to remove dep_pattern
|
||||
metadata = remove_dep_handler(pattern, compiled_pattern)
|
||||
else:
|
||||
metadata = replace_dep_handler(pattern, compiled_pattern, replaces)
|
||||
# use this key to make sure to not overwrite similar entries
|
||||
data[(pkg_match, pattern)] = (compiled_pattern, replaces)
|
||||
data.append((pkg_match, metadata))
|
||||
|
||||
self._mod_rewrite_data = data
|
||||
return data
|
||||
@@ -7357,7 +7435,7 @@ class Server(Client):
|
||||
|
||||
rewrites_enabled = []
|
||||
wildcard_rewrite = False
|
||||
for dep_string_rewrite, dep_pattern in dep_rewrite:
|
||||
for dep_string_rewrite, handler in dep_rewrite:
|
||||
# magic catch-all support
|
||||
if dep_string_rewrite == "*":
|
||||
pkg_id, rc = None, 0
|
||||
@@ -7366,7 +7444,7 @@ class Server(Client):
|
||||
wildcard_rewrite = False
|
||||
pkg_id, rc = tmp_repo.atomMatch(dep_string_rewrite)
|
||||
if rc == 0:
|
||||
rewrites_enabled.append((dep_string_rewrite, dep_pattern))
|
||||
rewrites_enabled.append((dep_string_rewrite, handler))
|
||||
tmp_repo.close()
|
||||
|
||||
if not rewrites_enabled:
|
||||
@@ -7384,22 +7462,11 @@ class Server(Client):
|
||||
level = "info",
|
||||
header = brown(" @@ ")
|
||||
)
|
||||
for dep_string_rewrite, dep_pattern in rewrites_enabled:
|
||||
compiled_pattern, replaces = \
|
||||
dep_rewrite[(dep_string_rewrite, dep_pattern)]
|
||||
if compiled_pattern is None:
|
||||
# this means that user is asking to add dep_pattern
|
||||
# as a dependency to package
|
||||
replaces_str = _("added")
|
||||
elif not replaces:
|
||||
# this means that user is asking to remove dep_pattern
|
||||
replaces_str = _("removed")
|
||||
else:
|
||||
replaces_str = "=> " + ', '.join(replaces)
|
||||
for dep_string_rewrite, handler in rewrites_enabled:
|
||||
self.output(
|
||||
"%s %s" % (
|
||||
purple(dep_pattern),
|
||||
replaces_str,
|
||||
purple(handler['dep_pattern_str']),
|
||||
handler['replaces_str'],
|
||||
),
|
||||
importance = 1,
|
||||
level = "info",
|
||||
@@ -7457,17 +7524,19 @@ class Server(Client):
|
||||
|
||||
for dep_string, dep_value, is_conflict in pkg_deps:
|
||||
|
||||
dep_string_matched = False
|
||||
dep_changed = False
|
||||
matched_pattern = False
|
||||
|
||||
for key in rewrites_enabled:
|
||||
for dep_string_rewrite, handler in rewrites_enabled:
|
||||
|
||||
dep_string_rewrite, dep_pattern = key
|
||||
compiled_pattern, replaces = dep_rewrite[key]
|
||||
if compiled_pattern is None:
|
||||
# user is asking to add dep_pattern to dependency list
|
||||
action = handler['action']
|
||||
|
||||
assert action in ("add", "remove", "replace")
|
||||
|
||||
if action == "add":
|
||||
# user is asking to add a dependency to dependency list
|
||||
dep_pattern_string, dep_pattern_type, conflict = \
|
||||
_extract_dep_add_from_dep_pattern(dep_pattern)
|
||||
_extract_dep_add_from_dep_pattern(handler['add_what'])
|
||||
if conflict:
|
||||
conflicts.add(dep_pattern_string)
|
||||
else:
|
||||
@@ -7475,20 +7544,19 @@ class Server(Client):
|
||||
(dep_pattern_string, dep_pattern_type))
|
||||
continue
|
||||
|
||||
if not compiled_pattern.match(dep_string):
|
||||
if not handler['does_dep_match_func'](dep_string):
|
||||
# dep_string not matched, skipping
|
||||
continue
|
||||
matched_pattern = True
|
||||
|
||||
if not replaces:
|
||||
# then it's a removal
|
||||
dep_string_matched = True
|
||||
if action == "remove":
|
||||
dep_changed = True
|
||||
|
||||
for replace in replaces:
|
||||
new_dep_string, number_of_subs_made = \
|
||||
compiled_pattern.subn(replace, dep_string)
|
||||
if number_of_subs_made:
|
||||
dep_string_matched = True
|
||||
for replace in handler['replaces']:
|
||||
new_dep_string, subst_made = \
|
||||
handler['do_func'](replace, dep_string)
|
||||
if subst_made:
|
||||
dep_changed = True
|
||||
if new_dep_string and (new_dep_string != "-"):
|
||||
|
||||
if is_conflict:
|
||||
@@ -7529,13 +7597,13 @@ class Server(Client):
|
||||
header = darkred(" !!! ")
|
||||
)
|
||||
|
||||
if dep_string_matched:
|
||||
if dep_changed:
|
||||
if is_conflict:
|
||||
remove_conflicts.add(dep_string)
|
||||
else:
|
||||
remove_dependencies.add(dep_string)
|
||||
|
||||
elif (not dep_string_matched) and matched_pattern:
|
||||
elif (not dep_changed) and matched_pattern:
|
||||
self.output(
|
||||
"%s: %s :: %s" % (
|
||||
darkred(_("No dependency rewrite made for")),
|
||||
|
||||
@@ -7,6 +7,7 @@ import unittest
|
||||
from entropy.const import const_convert_to_rawstring, const_convert_to_unicode
|
||||
from entropy.output import print_generic
|
||||
import tests._misc as _misc
|
||||
import itertools
|
||||
import tempfile
|
||||
import subprocess
|
||||
import shutil
|
||||
@@ -285,6 +286,255 @@ class DepTest(unittest.TestCase):
|
||||
outcome = et.get_entropy_package_sha1(name)
|
||||
self.assertEqual(outcome, expected_outcome)
|
||||
|
||||
|
||||
class DepsRewriteTestsMixin:
|
||||
def _validate(self):
|
||||
rewriter = et.DependencyRewriter(self._deps, self._rule)
|
||||
rewriter.rewrite()
|
||||
self.assertEqual(rewriter.deps, self._expected_deps)
|
||||
|
||||
|
||||
class MatchedChangedTestsMixin:
|
||||
def _validate(self):
|
||||
rewriter = et.DependencyRewriter(self._deps, self._rule)
|
||||
rewriter.rewrite()
|
||||
self.assertEqual(rewriter.matched, self._expected_matched)
|
||||
self.assertEqual(rewriter.changed, self._expected_changed)
|
||||
|
||||
|
||||
class DependencyRewriterTests(unittest.TestCase, DepsRewriteTestsMixin):
|
||||
# Test for the new rewrite rules without regexes.
|
||||
def test_dep_changed(self):
|
||||
# inspired by:
|
||||
# foo/bar (.*)app-text/poppler(.*)(\[.*\]) \1app-text/poppler-glib\2
|
||||
self._rule = "from-dep=app-text/poppler to-dep=app-text/poppler-glib"
|
||||
self._deps = ["app-text/poppler"]
|
||||
self._expected_deps = ["app-text/poppler-glib"]
|
||||
self._validate()
|
||||
|
||||
def _test_dep_changed_pkg_data_stays(self, dep_matches):
|
||||
prefixes = ("", "=", ">=", "<", "~")
|
||||
postfixes = ("", ":3", "[some]", "[some,use]", ":4[use]")
|
||||
rule = "from-dep=app-text/poppler to-dep=app-text/poppler-glib"
|
||||
|
||||
if dep_matches:
|
||||
dep_base = "app-text/poppler"
|
||||
expected_base = "app-text/poppler-glib"
|
||||
else:
|
||||
dep_base = "foobar"
|
||||
expected_base = dep_base
|
||||
|
||||
for prefix, postfix in itertools.product(prefixes, postfixes):
|
||||
self._rule = rule
|
||||
self._deps = [prefix + dep_base + postfix]
|
||||
self._expected_deps = [prefix + expected_base + postfix]
|
||||
self._validate()
|
||||
|
||||
def test_dep_changed_pkg_data_stays(self):
|
||||
self._test_dep_changed_pkg_data_stays(dep_matches=True)
|
||||
|
||||
def test_dep_with_pkg_data_dep_not_matched(self):
|
||||
self._test_dep_changed_pkg_data_stays(dep_matches=False)
|
||||
|
||||
def test_dep_changed_version_stays(self):
|
||||
self._rule = "from-dep=app-text/poppler to-dep=app-text/poppler-glib"
|
||||
self._deps = ["=app-text/poppler-10"]
|
||||
self._expected_deps = ["=app-text/poppler-glib-10"]
|
||||
self._validate()
|
||||
|
||||
def test_version_dep_not_matched(self):
|
||||
self._rule = "from-dep=app-text/poppler to-dep=app-text/poppler-glib"
|
||||
self._deps = ["=app-text/not-poppler-10"]
|
||||
self._expected_deps = ["=app-text/not-poppler-10"]
|
||||
self._validate()
|
||||
|
||||
def test_version_and_data_matches(self):
|
||||
self._rule = "from-dep=app-text/poppler to-dep=app-text/poppler-glib"
|
||||
self._deps = ["=app-text/poppler-10:3[use]"]
|
||||
self._expected_deps = ["=app-text/poppler-glib-10:3[use]"]
|
||||
self._validate()
|
||||
|
||||
def test_version_and_data_not_matches(self):
|
||||
self._rule = "from-dep=app-text/poppler to-dep=app-text/poppler-glib"
|
||||
self._deps = ["=app-text/not-poppler-10:3[use]"]
|
||||
self._expected_deps = ["=app-text/not-poppler-10:3[use]"]
|
||||
self._validate()
|
||||
|
||||
def test_more_deps_one_changed(self):
|
||||
self._rule = "from-dep=app-text/poppler to-dep=app-text/poppler-glib"
|
||||
self._deps = ["d1", "app-text/poppler", "d2"]
|
||||
self._expected_deps = ["d1", "app-text/poppler-glib", "d2"]
|
||||
self._validate()
|
||||
|
||||
def test_dep_not_changed_dep_not_matched(self):
|
||||
self._rule = "from-dep=app-text/poppler-not to-dep=app-text/poppler-glib"
|
||||
self._deps = ["app-text/poppler"]
|
||||
self._expected_deps = ["app-text/poppler"]
|
||||
self._validate()
|
||||
|
||||
def test_more_deps_none_changed_dep_not_matched(self):
|
||||
self._rule = "from-dep=app-text/poppler-not to-dep=app-text/poppler-glib"
|
||||
self._deps = ["d1", "app-text/poppler", "d2"]
|
||||
self._expected_deps = ["d1", "app-text/poppler", "d2"]
|
||||
self._validate()
|
||||
|
||||
def _test_with_if_has_use(self, dep_use, rule_use, dep_use_matches):
|
||||
assert dep_use.startswith("[") or not dep_use
|
||||
if dep_use_matches:
|
||||
expected_dep_base = "x11-misc/lightdm-qt4"
|
||||
else:
|
||||
expected_dep_base = "x11-misc/lightdm"
|
||||
|
||||
self._rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm-qt4 if-dep-has-use=%s" % (rule_use,)
|
||||
self._deps = ["x11-misc/lightdm"+dep_use]
|
||||
self._expected_deps = [expected_dep_base+dep_use]
|
||||
self._validate()
|
||||
|
||||
def test_with_if_has_use_matched(self):
|
||||
self._test_with_if_has_use(dep_use="[qt4]", rule_use="qt4", dep_use_matches=True)
|
||||
|
||||
def test_with_if_has_use_matched_complex(self):
|
||||
use_list = ("[qt4,qt5]", "[qt4?,qt5]", "[qt4(-)]", "[qt4(+)]")
|
||||
for use in use_list:
|
||||
self._test_with_if_has_use(dep_use=use, rule_use="qt4", dep_use_matches=True)
|
||||
|
||||
def test_with_if_has_use_not_matched_no_use(self):
|
||||
self._test_with_if_has_use(dep_use="", rule_use="qt4", dep_use_matches=False)
|
||||
|
||||
def test_with_if_has_use_not_matched_different_use(self):
|
||||
self._test_with_if_has_use(dep_use="[not-qt4]", rule_use="qt4", dep_use_matches=False)
|
||||
|
||||
def test_with_if_has_use_not_matched_different_use_complex(self):
|
||||
self._test_with_if_has_use(dep_use="[qt4]", rule_use="not-qt4", dep_use_matches=False)
|
||||
# There is no necessity to handle [-use(-)].
|
||||
self._test_with_if_has_use(dep_use="[-qt4]", rule_use="qt4", dep_use_matches=False)
|
||||
use_list = ("[qt4,qt5]", "[qt4?,qt5]", "[qt4(-)]", "[qt4(+)]")
|
||||
for use in use_list:
|
||||
self._test_with_if_has_use(dep_use=use, rule_use="not-qt4", dep_use_matches=False)
|
||||
|
||||
def test_with_if_has_use_and_drop_use(self):
|
||||
self._rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm-qt4 if-dep-has-use=qt4 drop-use=qt4"
|
||||
self._deps = ["x11-misc/lightdm[qt4]"]
|
||||
self._expected_deps = ["x11-misc/lightdm-qt4"]
|
||||
self._validate()
|
||||
|
||||
def test_with_if_has_use_and_drop_use_more_deps(self):
|
||||
self._rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm-qt4 if-dep-has-use=qt4 drop-use=qt4"
|
||||
self._deps = ["x11-misc/lightdm[qt4,something-else]"]
|
||||
self._expected_deps = ["x11-misc/lightdm-qt4[something-else]"]
|
||||
self._validate()
|
||||
|
||||
def test_with_if_has_use_and_drop_use_complex(self):
|
||||
self._rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm-qt4 if-dep-has-use=qt4 drop-use=qt4"
|
||||
self._deps = ["x11-misc/lightdm[qt4(-),something-else(+)]"]
|
||||
self._expected_deps = ["x11-misc/lightdm-qt4[something-else(+)]"]
|
||||
self._validate()
|
||||
|
||||
def test_with_if_has_use_and_drop_use_no_dropped_use_match(self):
|
||||
self._rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm-qt4 if-dep-has-use=qt4 drop-use=something"
|
||||
self._deps = ["x11-misc/lightdm[qt4]"]
|
||||
self._expected_deps = ["x11-misc/lightdm-qt4[qt4]"]
|
||||
self._validate()
|
||||
|
||||
def test_without_if_has_use_but_with_drop_use(self):
|
||||
self._rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm-qt5 drop-use=qt4"
|
||||
self._deps = ["x11-misc/lightdm[qt4]"]
|
||||
self._expected_deps = ["x11-misc/lightdm-qt5"]
|
||||
self._validate()
|
||||
|
||||
def test_with_drop_use_asterisk(self):
|
||||
self._rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm-qt5 drop-use=*"
|
||||
self._deps = ["x11-misc/lightdm[qt4?,qt5]"]
|
||||
self._expected_deps = ["x11-misc/lightdm-qt5"]
|
||||
self._validate()
|
||||
|
||||
def test_with_drop_use_asterisk_and_no_use_in_dep(self):
|
||||
self._rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm-qt5 drop-use=*"
|
||||
self._deps = ["x11-misc/lightdm"]
|
||||
self._expected_deps = ["x11-misc/lightdm-qt5"]
|
||||
self._validate()
|
||||
|
||||
def test_raises_on_unknown_key(self):
|
||||
rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm-qt4 haha=true"
|
||||
deps = ["x11-misc/lightdm"]
|
||||
|
||||
with self.assertRaisesRegexp(et.WrongRewriteRuleError, r"^Bad key 'haha'"):
|
||||
et.DependencyRewriter(deps, rule)
|
||||
|
||||
def test_raises_on_missing_key(self):
|
||||
rule_parts = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm-qt4".split()
|
||||
deps = []
|
||||
for rule in rule_parts:
|
||||
with self.assertRaisesRegexp(et.WrongRewriteRuleError, r"Incomplete rewrite rule"):
|
||||
et.DependencyRewriter(deps, rule)
|
||||
|
||||
def test_raises_on_key_with_no_assignment(self):
|
||||
wrong_values = ("if-has-use", "drop-use", "haha")
|
||||
for value in wrong_values:
|
||||
rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm-qt4 %s" % (value,)
|
||||
deps = ["x11-misc/lightdm"]
|
||||
with self.assertRaisesRegexp(et.WrongRewriteRuleError,
|
||||
r"^Badly formatted line with '%s'" % (value,)):
|
||||
et.DependencyRewriter(deps, rule)
|
||||
|
||||
def test_with_empty_deps(self):
|
||||
self._rule = "from-dep=app-text/poppler to-dep=app-text/poppler-glib"
|
||||
self._deps = []
|
||||
self._expected_deps = []
|
||||
self._validate()
|
||||
|
||||
|
||||
class DependencyRewriterBasicAttrsTests(unittest.TestCase, MatchedChangedTestsMixin):
|
||||
def test_matched_and_changed(self):
|
||||
self._rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm-qt5 drop-use=qt4"
|
||||
self._deps = ["x11-misc/lightdm[qt4]"]
|
||||
self._expected_matched = True
|
||||
self._expected_changed = True
|
||||
self._validate()
|
||||
|
||||
def test_not_matched_and_not_changed_dep_mismatch(self):
|
||||
self._rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm-qt5 drop-use=qt4"
|
||||
self._deps = ["something-else/lightdm[qt4]"]
|
||||
self._expected_matched = False
|
||||
self._expected_changed = False
|
||||
self._validate()
|
||||
|
||||
def test_not_matched_and_not_changed_use_mismatch(self):
|
||||
self._rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm-qt5 if-dep-has-use=qt4"
|
||||
self._deps = ["x11-misc/lightdm[not-qt4]"]
|
||||
self._expected_matched = False
|
||||
self._expected_changed = False
|
||||
self._validate()
|
||||
|
||||
def test_matched_and_not_changed(self):
|
||||
self._rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm if-dep-has-use=qt4"
|
||||
self._deps = ["x11-misc/lightdm[qt4]"]
|
||||
self._expected_matched = True
|
||||
self._expected_changed = False
|
||||
self._validate()
|
||||
|
||||
def test_with_empty_deps(self):
|
||||
self._rule = "from-dep=app-text/poppler to-dep=app-text/poppler-glib"
|
||||
self._deps = []
|
||||
self._expected_matched = False
|
||||
self._expected_changed = False
|
||||
self._validate()
|
||||
|
||||
def test_matched_and_changed_with_use_asterisk(self):
|
||||
self._rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm drop-use=*"
|
||||
self._deps = ["x11-misc/lightdm[gtk]"]
|
||||
self._expected_matched = True
|
||||
self._expected_changed = True
|
||||
self._validate()
|
||||
|
||||
def test_matched_and_not_changed_with_use_asterisk(self):
|
||||
self._rule = "from-dep=x11-misc/lightdm to-dep=x11-misc/lightdm drop-use=*"
|
||||
self._deps = ["x11-misc/lightdm"]
|
||||
self._expected_matched = True
|
||||
self._expected_changed = False
|
||||
self._validate()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
raise SystemExit(0)
|
||||
|
||||
Reference in New Issue
Block a user