From ed68db64a45b0395d43e8711aa57f4841ae81953 Mon Sep 17 00:00:00 2001 From: Brian Harring Date: Tue, 16 Aug 2005 00:26:43 +0000 Subject: 1) corrections for restriction subsystem changes 2) full use deps implemented, and slot deps. 3) reverse use dep lookup, effectively "yo, turn off depends x please" resulting in figuring out how, and configuring the package appropriately 4) bug in obj caching for tracking when forced to regenerate an obj (package.conditionals) --- portage/ebuild/conditionals.py | 35 +++++++++++----- portage/ebuild/ebuild_package.py | 10 ++--- portage/ebuild/ebuild_repository.py | 4 +- portage/package/conditionals.py | 84 +++++++++++++++++++++++++++++++------ 4 files changed, 104 insertions(+), 29 deletions(-) diff --git a/portage/ebuild/conditionals.py b/portage/ebuild/conditionals.py index cef834d..25a8f8c 100644 --- a/portage/ebuild/conditionals.py +++ b/portage/ebuild/conditionals.py @@ -1,14 +1,15 @@ # Copyright: 2005 Gentoo Foundation # Author(s): Jason Stubbs (jstubbs@gentoo.org), Brian Harring (ferringb@gentoo.org) # License: GPL2 -# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/portage/ebuild/conditionals.py,v 1.5 2005/08/14 01:01:24 ferringb Exp $ +# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/portage/ebuild/conditionals.py,v 1.6 2005/08/16 00:26:43 ferringb Exp $ # TODO: move exceptions elsewhere, bind them to a base exception for portage import logging -from portage.restrictions.restriction_set import RestrictionSet, OrRestrictionSet -from portage.util.strings import iter_tokens +from portage.restrictions.packages import OrRestriction, AndRestriction from portage.package.conditionals import base as Conditional +from portage.util.lists import unique, flatten +from portage.util.strings import iter_tokens def conditional_converter(node, payload): if node[0] == "!": @@ -16,9 +17,9 @@ def conditional_converter(node, payload): return Conditional(node, payload) -class DepSet(RestrictionSet): - __slots__ = tuple(["has_conditionals", "conditional_class"] + list(RestrictionSet.__slots__)) - def __init__(self, dep_str, element_func, operators={"||":OrRestrictionSet}, \ +class DepSet(AndRestriction): + __slots__ = ("has_conditionals", "conditional_class", "node_conds") + def __init__(self, dep_str, element_func, operators={"||":OrRestriction}, \ conditional_converter=conditional_converter, conditional_class=Conditional, empty=False): """dep_str is a dep style syntax, element_func is a callable returning the obj for each element, and @@ -26,6 +27,7 @@ class DepSet(RestrictionSet): super(DepSet, self).__init__() self.conditional_class = conditional_class + self.node_conds = {} if empty: return @@ -34,7 +36,7 @@ class DepSet(RestrictionSet): # ~harring conditionals, depsets, has_conditionals = [], [self], [False] - + raw_conditionals = [] words = iter_tokens(dep_str) try: for k in words: @@ -44,11 +46,14 @@ class DepSet(RestrictionSet): if len(depsets[-1].restrictions) == 0: raise ParseError(dep_str) elif conditionals[-1].endswith('?'): + cond = raw_conditionals[:] depsets[-2].restrictions.append(conditional_converter(conditionals.pop(-1)[:-1], depsets[-1])) + raw_conditionals.pop(0) + for x in depsets[-1]: + self.node_conds.setdefault(x, []).append(cond) else: depsets[-2].restrictions.append(operators[conditionals.pop(-1)](depsets[-1])) - if not has_conditionals[-2]: - has_conditionals[-2] = has_conditionals[-1] + depsets[-1].has_conditionals = has_conditionals.pop(-1) depsets.pop(-1) @@ -66,11 +71,13 @@ class DepSet(RestrictionSet): conditionals.append(k) if k.endswith("?"): has_conditionals[-1] = True + raw_conditionals.append(k[:-1]) has_conditionals.append(False) else: # node/element. depsets[-1].restrictions.append(element_func(k)) + except IndexError: # [][-1] for a frame access, which means it was a parse error. @@ -80,7 +87,9 @@ class DepSet(RestrictionSet): if len(depsets) != 1: raise ParseError(dep_str) self.has_conditionals = has_conditionals[0] - + for x in self.node_conds: + self.node_conds[x] = tuple(unique(flatten(self.node_conds[x]))) + def __str__(self): return ' '.join(map(str,self.restrictions)) def evaluate_depset(self, cond_dict): @@ -105,6 +114,12 @@ class DepSet(RestrictionSet): stack.pop(0) return flat_deps + def __iter__(self): + return iter(self.restrictions) + + def match(self, *a): + raise NotImplementedError + force_False = force_True = match class ParseError(Exception): def __init__(self, s): self.dep_str = s diff --git a/portage/ebuild/ebuild_package.py b/portage/ebuild/ebuild_package.py index 5bf7e57..02a1d24 100644 --- a/portage/ebuild/ebuild_package.py +++ b/portage/ebuild/ebuild_package.py @@ -1,7 +1,7 @@ # Copyright: 2005 Gentoo Foundation # Author(s): Brian Harring (ferringb@gentoo.org) # License: GPL2 -# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/portage/ebuild/ebuild_package.py,v 1.7 2005/08/14 01:01:24 ferringb Exp $ +# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/portage/ebuild/ebuild_package.py,v 1.8 2005/08/16 00:26:43 ferringb Exp $ import os from portage import package @@ -10,8 +10,8 @@ from portage.package.atom import atom #from portage.fetch import fetchable #from digest import parse_digest from portage.util.mappings import LazyValDict -from portage.restrictions.restriction import PackageRestriction, StrExactMatch -from portage.restrictions.restriction_set import AndRestrictionSet, OrRestrictionSet +from portage.restrictions.values import StrExactMatch +from portage.restrictions.packages import PackageRestriction class EbuildPackage(package.metadata.package): @@ -34,8 +34,8 @@ class EbuildPackage(package.metadata.package): val = DepSet(self.data[key.upper()[:-1]], atom) elif key == "fetchables": val = DepSet(self.data["SRC_URI"], str, operators={}) - elif key == "license": - val = DepSet(self.data["LICENSE"], str) + elif key in ("license", "slot"): + val = DepSet(self.data[key.upper()], str) elif key == "description": val = self.data["DESCRIPTION"] elif key == "keywords": diff --git a/portage/ebuild/ebuild_repository.py b/portage/ebuild/ebuild_repository.py index bbf0c28..61deb96 100644 --- a/portage/ebuild/ebuild_repository.py +++ b/portage/ebuild/ebuild_repository.py @@ -1,7 +1,7 @@ # Copyright: 2005 Gentoo Foundation # Author(s): Brian Harring (ferringb@gentoo.org) # License: GPL2 -# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/portage/ebuild/ebuild_repository.py,v 1.5 2005/08/14 01:01:24 ferringb Exp $ +# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/portage/ebuild/ebuild_repository.py,v 1.6 2005/08/16 00:26:43 ferringb Exp $ import os, stat from portage.repository import prototype, errors @@ -77,7 +77,7 @@ class UnconfiguredTree(prototype.tree): class ConfiguredTree(UnconfiguredTree): configured = True - l=["license","depends","rdepends","bdepends", "fetchables"] + l=["license","depends","rdepends","bdepends", "fetchables", "license", "slot"] wrappables = dict(zip(l, len(l)*[convert_depset])) def __init__(self, raw_repo, domain_settings): diff --git a/portage/package/conditionals.py b/portage/package/conditionals.py index 07cd0aa..94b11fa 100644 --- a/portage/package/conditionals.py +++ b/portage/package/conditionals.py @@ -1,10 +1,12 @@ # Copyright: 2005 Gentoo Foundation # Author(s): Brian Harring (ferringb@gentoo.org) # License: GPL2 -# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/portage/package/conditionals.py,v 1.2 2005/08/14 00:59:51 ferringb Exp $ +# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/portage/package/conditionals.py,v 1.3 2005/08/16 00:26:43 ferringb Exp $ #from metadata import package as package_base -from portage.util.mappings import LimitedChangeSet +from portage.util.mappings import LimitedChangeSet, Unchangable +from portage.util.lists import unique, flatten +import copy class base(object): """base object representing a conditional node""" @@ -39,11 +41,16 @@ class PackageWrapper(object): if configurable_attribute_name.find(".") != -1: raise ValueError("can only wrap first level attributes, 'obj.dar' fex, not '%s'" % (configurable_attribute_name)) setattr(self, configurable_attribute_name, LimitedChangeSet(initial_settings, unchangable_settings)) + self.__unchangable = unchangable_settings self.__configurable = getattr(self, configurable_attribute_name) self.__configurable_name = configurable_attribute_name self.__reuse_pt = 0 self.__cached_wrapped = {} + def __copy__(self): + return self.__class__(self.__wrapped_pkg, self.__configurable_name, initial_settings=set(self.__configurable), + unchangable_settings=self.__unchangable, attributes_to_wrap=self.__wrapped_attr) + def rollback(self, point=0): self.__configurable.rollback(point) # yes, nuking objs isn't necessarily required. easier this way though. @@ -52,20 +59,64 @@ class PackageWrapper(object): def commit(self): self.__configurable.commit() + self.__reuse_pt = 0 def changes_count(self): return self.__configurable.changes_count() - def push_add(self, key): - if key not in self.__configurable: - self.__configurable.add(key) - self.__reuse_pt += 1 - - def push_remove(self, key): - if key in self.__configurable: - self.__configurable.remove(key) - self.__reuse_pt += 1 - + def request_enable(self, attr, *vals): + if attr not in self.__wrapped_attr: + if attr == self.__configurable_name: + entry_point = self.changes_count() + try: + map(self.__configurable.add, vals) + self.__reuse_pt += 1 + return True + except Unchangable: + self.rollback_changes(entry_point) + return False + entry_point = self.changes_count() + a = getattr(self.__wrapped_pkg, attr) + try: + for x in vals: + if x in a.node_conds: + map(self.__configurable.add, a.node_conds[x]) + else: + if x not in a: + self.rollback(entry_point) + return False + except Unchangable: + self.rollback(entry_point) + return False + self.__reuse_pt += 1 + return True + + def request_disable(self, attr, *vals): + if attr not in self.__wrapped_attr: + if attr == self.__configurable_name: + entry_point = self.changes_count() + try: + map(self.__configurable.remove, vals) + return True + except Unchangable: + self.rollback_changes(entry_point) + return False + entry_point = self.changes_count() + a = getattr(self.__wrapped_pkg, attr) + try: + for x in vals: + if x in a.node_conds: + map(self.__configurable.remove, a.node_conds[x]) + else: + if x in a: + self.rollback(entry_point) + return False + except Unchangable: + self.rollback(entry_point) + return False + self.__reuse_pt += 1 + return True + def __getattr__(self, attr): if attr in self.__wrapped_attr: if attr in self.__cached_wrapped: @@ -80,3 +131,12 @@ class PackageWrapper(object): def __str__(self): return "config wrapper: %s, configurable('%s'):%s" % (self.__wrapped_pkg, self.__configurable_name, self.__configurable) + + def freeze(self): + o = copy.copy(self) + o.lock() + return o + + def lock(self): + self.commit() + self.__configurable = list(self.__configurable) -- cgit v1.2.3-65-gdbad