summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Mauch <genone@gentoo.org>2008-09-25 16:37:06 +0000
committerMarius Mauch <genone@gentoo.org>2008-09-25 16:37:06 +0000
commit404898e1027b73d4cde03acddec69065ebba9727 (patch)
tree45daad5f2cf0a845cb38fc40e8d891f800e5291e
parentmove set expansion code into its own function (diff)
downloadportage-404898e1027b73d4cde03acddec69065ebba9727.tar.gz
portage-404898e1027b73d4cde03acddec69065ebba9727.tar.bz2
portage-404898e1027b73d4cde03acddec69065ebba9727.zip
implement simple expression logic for apckage sets to generate unions, intersections and differences of two or more package sets
svn path=/main/trunk/; revision=11543
-rw-r--r--pym/_emerge/__init__.py76
1 files changed, 58 insertions, 18 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py
index 09aa403a5..afc3f58e8 100644
--- a/pym/_emerge/__init__.py
+++ b/pym/_emerge/__init__.py
@@ -13390,26 +13390,66 @@ def expand_set_arguments(myfiles, myaction, root_config):
myfiles = newargs
del newargs
newargs = []
+
+ IS_OPERATOR = "/"
+ DIFF_OPERATOR = "-"
+ UNION_OPERATOR = "+"
for a in myfiles:
if a.startswith(SETPREFIX):
- s = a[len(SETPREFIX):]
- if s not in sets:
- display_missing_pkg_set(root_config, s)
- return (None, 1)
- setconfig.active.append(s)
- if myaction in unmerge_actions and \
- not sets[s].supportsOperation("unmerge"):
- sys.stderr.write("emerge: the given set '%s' does " % s + \
- "not support unmerge operations\n")
- retval = 1
- elif not setconfig.getSetAtoms(s):
- print "emerge: '%s' is an empty set" % s
- elif myaction not in do_not_expand:
- newargs.extend(setconfig.getSetAtoms(s))
- else:
- newargs.append(SETPREFIX+s)
- for e in sets[s].errors:
- print e
+ # support simple set operations (intersection, difference and union)
+ # on the commandline. Expressions are evaluated strictly left-to-right
+ if IS_OPERATOR in a or DIFF_OPERATOR in a or UNION_OPERATOR in a:
+ expression = a[len(SETPREFIX):]
+ expr_sets = []
+ expr_ops = []
+ while IS_OPERATOR in expression or DIFF_OPERATOR in expression or UNION_OPERATOR in expression:
+ is_pos = expression.rfind(IS_OPERATOR)
+ diff_pos = expression.rfind(DIFF_OPERATOR)
+ union_pos = expression.rfind(UNION_OPERATOR)
+ s1 = expression[:max(is_pos, diff_pos, union_pos)]
+ s2 = expression[max(is_pos, diff_pos, union_pos)+1:]
+ op = expression[max(is_pos, diff_pos, union_pos)]
+ if not s2 in sets:
+ display_missing_pkg_set(root_config, s2)
+ return (None, 1)
+ expr_sets.insert(0, s2)
+ expr_ops.insert(0, op)
+ expression = s1
+ if not expression in sets:
+ display_missing_pkg_set(root_config, expression)
+ return (None, 1)
+ expr_sets.insert(0, expression)
+ result = set(setconfig.getSetAtoms(expression))
+ for i in range(0, len(expr_ops)):
+ s2 = setconfig.getSetAtoms(expr_sets[i+1])
+ if expr_ops[i] == IS_OPERATOR:
+ result.intersection_update(s2)
+ elif expr_ops[i] == DIFF_OPERATOR:
+ result.difference_update(s2)
+ elif expr_ops[i] == UNION_OPERATOR:
+ result.update(s2)
+ else:
+ raise NotImplementedError("unknown set operator %s" % expr_ops[i])
+ newargs.extend(result)
+ else:
+ s = a[len(SETPREFIX):]
+ if s not in sets:
+ display_missing_pkg_set(root_config, s)
+ return (None, 1)
+ setconfig.active.append(s)
+ if myaction in unmerge_actions and \
+ not sets[s].supportsOperation("unmerge"):
+ sys.stderr.write("emerge: the given set '%s' does " % s + \
+ "not support unmerge operations\n")
+ retval = 1
+ elif not setconfig.getSetAtoms(s):
+ print "emerge: '%s' is an empty set" % s
+ elif myaction not in do_not_expand:
+ newargs.extend(setconfig.getSetAtoms(s))
+ else:
+ newargs.append(SETPREFIX+s)
+ for e in sets[s].errors:
+ print e
else:
newargs.append(a)
return (newargs, retval)