Re: [gentoo-portage-dev] [PATCH] portageq: fix eroot parameter (bug #529200)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 On 14/11/14 18:36, Zac Medico wrote: > That won't work, because you can't reference eprefix on the right > hand side of the assignment, and the whole right hand side must > evaluate before the eprefix reference is initialized. Oh right. My python-fu isn't as strong as it used to be. Thanks. - -- Alexander berna...@gentoo.org https://secure.plaimi.net/~alexander -BEGIN PGP SIGNATURE- Version: GnuPG v2 Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iF4EAREIAAYFAlRpqxUACgkQRtClrXBQc7V+iAEAmJtBB4yZRAmb0i6HHHG+V2zh COJ58I6Q5iuPGjrVimkA/0qQVYGC66czxZ6JP4lOC+NWf5n6EMOpi2jS7kOZzxcv =84lS -END PGP SIGNATURE-
Re: [gentoo-portage-dev] [PATCH] unprivileged mode: use first_existing helper func
-BEGIN PGP SIGNED MESSAGE- Hash: SHA256 Looks OK. Go ahead... - -- Alexander berna...@gentoo.org https://secure.plaimi.net/~alexander -BEGIN PGP SIGNATURE- Version: GnuPG v2 Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iF4EAREIAAYFAlRprgYACgkQRtClrXBQc7WKYQD8DmeatGuSom5fxqXgR4VSzPve +JMFmYlp/RNZ3Ya6YHgA/37BZ+Hoo4BfrHY9Owp98y4O6EACN3YVz6psmB/uJn5u =Cfxl -END PGP SIGNATURE-
Re: [gentoo-portage-dev] Binpackages
On Fri, 14 Nov 2014 10:21:14 -0800 Zac Medico wrote: > On 11/14/2014 03:29 AM, ma...@nucleus.it wrote: > > Hi all, > > i think the answer is "you can't" but i wan to try :) . > > > > I setup a builder ( FEATURES="buildpkg" ) server to deploy bin > > packages for other servers ( FEATURES="getbinpkg" ) ? > > > > For example: > > mail-mta/postfix with USE="mysql" > > mail-mta/postfix without mysql > > > > Sometimes can be useful to have a binpackage with different use > > flags to deploy to different servers without have two binhosts > > repository or more. > > > > Is it possible to have this situation ? > > > > Thanks Marco > > > > We have a feature request bug filed for that here: > > https://bugs.gentoo.org/show_bug.cgi?id=150031 > Thanks for the link , i hope this feature will be implemented soon :) Marco
[gentoo-portage-dev] [PATCH] unprivileged mode: fix cross-prefix support
In commit 1364fcd89384c9f60e6d72d7057dc00d8caba175, EROOT calculation in portage.data did not account from cross-prefix support. This is fixed by using new _target_root and _target_eprefix functions to perform the calculation. The _target_eprefix function is also useful in portageq, where the target EPREFIX needs to be known before portage.settings is instantiated. Fixes 1364fcd89384 ("Support unprivileged mode for bug #433453.") --- bin/portageq| 4 +--- pym/portage/data.py | 35 +++ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/bin/portageq b/bin/portageq index ef565d1..6a42bfd 100755 --- a/bin/portageq +++ b/bin/portageq @@ -1397,9 +1397,7 @@ def main(argv): # portage.settings["EPREFIX"] here, but that would force # instantiation of portage.settings, which we don't want to do # until after we've calculated ROOT (see bug #529200). - eprefix = os.environ.get("EPREFIX", portage.const.EPREFIX) - if eprefix: - eprefix = portage.util.normalize_path(eprefix) + eprefix = portage.data._target_eprefix() eroot = portage.util.normalize_path(argv[2]) if eprefix: diff --git a/pym/portage/data.py b/pym/portage/data.py index d9b36ee..2fd287d 100644 --- a/pym/portage/data.py +++ b/pym/portage/data.py @@ -35,6 +35,35 @@ if not lchown: lchown = portage._unicode_func_wrapper(lchown) +def _target_eprefix(): + """ + Calculate the target EPREFIX, which may be different from + portage.const.EPREFIX due to cross-prefix support. The result + is equivalent to portage.settings["EPREFIX"], but the calculation + is done without the expense of instantiating portage.settings. + @rtype: str + @return: the target EPREFIX + """ + eprefix = os.environ.get("EPREFIX", portage.const.EPREFIX) + if eprefix: + eprefix = portage.util.normalize_path(eprefix) + return eprefix + +def _target_root(): + """ + Calculate the target ROOT. The result is equivalent to + portage.settings["ROOT"], but the calculation + is done without the expense of instantiating portage.settings. + @rtype: str + @return: the target ROOT (always ends with a slash) + """ + root = os.environ.get("ROOT") + if not root: + # Handle either empty or unset ROOT. + root = os.sep + root = portage.util.normalize_path(root) + return root.rstrip(os.sep) + os.sep + def portage_group_warning(): warn_prefix = colorize("BAD", "*** WARNING *** ") mylines = [ @@ -96,8 +125,7 @@ def _get_global(k): # The config class has equivalent code, but we also need to # do it here if _disable_legacy_globals() has been called. eroot_or_parent = first_existing(os.path.join( - os.environ.get('ROOT', os.sep), - portage.const.EPREFIX.lstrip(os.sep))) + _target_root(), _target_eprefix().lstrip(os.sep))) try: eroot_st = os.stat(eroot_or_parent) except OSError: @@ -210,8 +238,7 @@ def _get_global(k): # The config class has equivalent code, but we also need to # do it here if _disable_legacy_globals() has been called. eroot_or_parent = first_existing(os.path.join( - os.environ.get('ROOT', os.sep), - portage.const.EPREFIX.lstrip(os.sep))) + _target_root(), _target_eprefix().lstrip(os.sep))) try: eroot_st = os.stat(eroot_or_parent) except OSError: -- 2.0.4
Re: [gentoo-portage-dev] [PATCH] unprivileged mode: fix cross-prefix support
On Mon, 17 Nov 2014 09:02:45 -0800 Zac Medico wrote: > In commit 1364fcd89384c9f60e6d72d7057dc00d8caba175, EROOT calculation > in portage.data did not account from cross-prefix support. This is ^ for > fixed by using new _target_root and _target_eprefix functions to > perform the calculation. The _target_eprefix function is also useful > in portageq, where the target EPREFIX needs to be known before > portage.settings is instantiated. > > Fixes 1364fcd89384 ("Support unprivileged mode for bug #433453.") > --- Just a wrong word in the commit message, otherwise looks good -- Brian Dolbec
[gentoo-portage-dev] [PATCH v3 1/2] dblink: case insensitive support for bug #524236
This adds a dblink._contents attribute with methods that provide an interface for contents operations with "implicit" case handling. The new methods are implemented in a separate ContentsCaseSensitivityManager class, in order to avoid adding more bloat to vartree.py. X-Gentoo-Bug: 524236 X-Gentoo-Url: https://bugs.gentoo.org/show_bug.cgi?id=524236 --- .../dbapi/_ContentsCaseSensitivityManager.py | 93 ++ pym/portage/dbapi/vartree.py | 3 + 2 files changed, 96 insertions(+) create mode 100644 pym/portage/dbapi/_ContentsCaseSensitivityManager.py diff --git a/pym/portage/dbapi/_ContentsCaseSensitivityManager.py b/pym/portage/dbapi/_ContentsCaseSensitivityManager.py new file mode 100644 index 000..c479ec9 --- /dev/null +++ b/pym/portage/dbapi/_ContentsCaseSensitivityManager.py @@ -0,0 +1,93 @@ +# Copyright 2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +class ContentsCaseSensitivityManager(object): + """ + Implicitly handles case transformations that are needed for + case-insensitive support. + """ + + def __init__(self, db): + """ + @param db: A dblink instance + @type db: vartree.dblink + """ + self.getcontents = db.getcontents + + if "case-insensitive-fs" in db.settings.features: + self.unmap_key = self._unmap_key_case_insensitive + self.contains = self._contains_case_insensitive + self.keys = self._keys_case_insensitive + + self._contents_insensitive = None + self._reverse_key_map = None + + def clear_cache(self): + """ + Clear all cached contents data. + """ + self._contents_insensitive = None + self._reverse_key_map = None + + def keys(self): + """ + Iterate over all contents keys, which are transformed to + lowercase when appropriate, for use in case-insensitive + comparisons. + @rtype: iterator + @return: An iterator over all the contents keys + """ + return iter(self.getcontents()) + + def contains(self, key): + """ + Check if the given key is contained in the contents, using + case-insensitive comparison when appropriate. + @param key: A filesystem path (including ROOT and EPREFIX) + @type key: str + @rtype: bool + @return: True if the given key is contained in the contents, + False otherwise + """ + return key in self.getcontents() + + def unmap_key(self, key): + """ + Map a key (from the keys method) back to its case-preserved + form. + @param key: A filesystem path (including ROOT and EPREFIX) + @type key: str + @rtype: str + @return: The case-preserved form of key + """ + return key + + def _case_insensitive_init(self): + """ + Initialize data structures for case-insensitive support. + """ + self._contents_insensitive = dict( + (k.lower(), v) for k, v in self.getcontents().items()) + self._reverse_key_map = dict( + (k.lower(), k) for k in self.getcontents()) + + def _keys_case_insensitive(self): + if self._contents_insensitive is None: + self._case_insensitive_init() + return iter(self._contents_insensitive) + + _keys_case_insensitive.__doc__ = keys.__doc__ + + def _contains_case_insensitive(self, key): + if self._contents_insensitive is None: + self._case_insensitive_init() + return key.lower() in self._contents_insensitive + + _contains_case_insensitive.__doc__ = contains.__doc__ + + def _unmap_key_case_insensitive(self, key): + if self._reverse_key_map is None: + self._case_insensitive_init() + return self._reverse_key_map[key] + + _unmap_key_case_insensitive.__doc__ = unmap_key.__doc__ diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index 8b06f4c..81059b1 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -69,6 +69,7 @@ from _emerge.EbuildPhase import EbuildPhase from _emerge.emergelog import emergelog from _emerge.MiscFunctionsProcess import MiscFunctionsProcess from _emerge.SpawnProcess import SpawnProcess +from ._ContentsCaseSensitivityManager import ContentsCaseSensitivityManager import errno import fnmatch @@ -1525,6 +1526,7 @@ class dblink(object):
[gentoo-portage-dev] [PATCH v3 2/2] FEATURES=case-insensitive-fs for bug #524236
When case-insensitive-fs is enabled in FEATURES, the dblink.isowner method, _owners_db class, and ConfigProtect class will be case-insensitive. This causes the collision-protect and unmerge code to behave correctly for a case-insensitive file system. If the file system is case-insensitive but case-preserving, then case is preserved in the CONTENTS data of installed packages. X-Gentoo-Bug: 524236 X-Gentoo-Url: https://bugs.gentoo.org/show_bug.cgi?id=524236 --- bin/dispatch-conf | 8 - bin/etc-update | 10 -- bin/portageq | 7 +++-- bin/quickpkg | 4 ++- man/make.conf.5| 6 pym/_emerge/depgraph.py| 4 ++- pym/portage/_global_updates.py | 4 ++- pym/portage/const.py | 1 + pym/portage/dbapi/vartree.py | 71 +++--- pym/portage/update.py | 6 ++-- pym/portage/util/__init__.py | 8 - 11 files changed, 92 insertions(+), 37 deletions(-) diff --git a/bin/dispatch-conf b/bin/dispatch-conf index 8058d6f..b679910 100755 --- a/bin/dispatch-conf +++ b/bin/dispatch-conf @@ -35,6 +35,10 @@ from portage.process import find_binary, spawn FIND_EXTANT_CONFIGS = "find '%s' %s -name '._cfg_%s' ! -name '.*~' ! -iname '.*.bak' -print" DIFF_CONTENTS= "diff -Nu '%s' '%s'" +if "case-insensitive-fs" in portage.settings.features: +FIND_EXTANT_CONFIGS = FIND_EXTANT_CONFIGS.replace( +"-name '._cfg", "-iname '._cfg") + # We need a secure scratch dir and python does silly verbose errors on the use of tempnam oldmask = os.umask(0o077) SCRATCH_DIR = None @@ -152,7 +156,9 @@ class dispatch: protect_obj = portage.util.ConfigProtect( config_root, config_paths, portage.util.shlex_split( -portage.settings.get('CONFIG_PROTECT_MASK', ''))) +portage.settings.get('CONFIG_PROTECT_MASK', '')), +case_insensitive=("case-insensitive-fs" +in portage.settings.features)) # # Remove new configs identical to current diff --git a/bin/etc-update b/bin/etc-update index 0307688..e0f7224 100755 --- a/bin/etc-update +++ b/bin/etc-update @@ -113,12 +113,15 @@ scan() { [[ -d ${path%/*} ]] || continue local name_opt=$(get_basename_find_opt "${path##*/}") path="${path%/*}" - find_opts=( -maxdepth 1 -name "$name_opt" ) + find_opts=( -maxdepth 1 ) else # Do not traverse hidden directories such as .svn or .git. local name_opt=$(get_basename_find_opt '*') - find_opts=( -name '.*' -type d -prune -o -name "$name_opt" ) + find_opts=( -name '.*' -type d -prune -o ) fi + ${case_insensitive} && \ + find_opts+=( -iname ) || find_opts+=( -name ) + find_opts+=( "$name_opt" ) find_opts+=( ! -name '.*~' ! -iname '.*.bak' -print ) if [ ! -w "${path}" ] ; then @@ -743,6 +746,7 @@ fi portage_vars=( CONFIG_PROTECT{,_MASK} + FEATURES PORTAGE_CONFIGROOT PORTAGE_INST_{G,U}ID PORTAGE_TMPDIR @@ -759,6 +763,8 @@ fi export PORTAGE_TMPDIR SCAN_PATHS=${*:-${CONFIG_PROTECT}} +[[ " ${FEATURES} " == *" case-insensitive-fs "* ]] && \ + case_insensitive=true || case_insensitive=false TMP="${PORTAGE_TMPDIR}/etc-update-$$" trap "die terminated" SIGTERM diff --git a/bin/portageq b/bin/portageq index 6a42bfd..2c4f548 100755 --- a/bin/portageq +++ b/bin/portageq @@ -379,8 +379,8 @@ def is_protected(argv): protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", "")) protect_mask = portage.util.shlex_split( settings.get("CONFIG_PROTECT_MASK", "")) - protect_obj = ConfigProtect(root, protect, protect_mask) - + protect_obj = ConfigProtect(root, protect, protect_mask, + case_insensitive=("case-insensitive-fs" in settings.features)) if protect_obj.isprotected(f): return 0 return 1 @@ -414,7 +414,8 @@ def filter_protected(argv): protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", "")) protect_mask = portage.util.shlex_split( settings.get("CONFIG_PROTECT_MASK", "")) - protect_obj = ConfigProtect(root, protect, protect_mask) + protect_obj = ConfigProtect(root, protect, protect_mask, + case_insensitive=("case-insensitive-fs" in settings.features)) errors = 0 diff --git a/bin/quickpkg b/bin/quickpkg index cf75791..2c69a69 100755 --- a/bin/quickpkg +++ b/bin/quickpkg @@ -102,7 +102,9 @@ def quickpkg_atom(options, infos, arg, eout): if not include_config: confprot = ConfigProtect(eroot,
Re: [gentoo-portage-dev] [PATCH v3 1/2] dblink: case insensitive support for bug #524236
On Mon, 17 Nov 2014 12:29:37 -0800 Zac Medico wrote: > This adds a dblink._contents attribute with methods that provide > an interface for contents operations with "implicit" case handling. > The new methods are implemented in a separate > ContentsCaseSensitivityManager class, in order to avoid adding more > bloat to vartree.py. > > X-Gentoo-Bug: 524236 > X-Gentoo-Url: https://bugs.gentoo.org/show_bug.cgi?id=524236 > --- ... > +class ContentsCaseSensitivityManager(object): > + """ > + Implicitly handles case transformations that are needed for > + case-insensitive support. > + """ > + > + def __init__(self, db): > + """ > + @param db: A dblink instance > + @type db: vartree.dblink > + """ Thank you :) looks much better now ;) Both 1/2, 2/2 look good now. Clear to merge :) > + self.getcontents = db.getcontents > + > + if "case-insensitive-fs" in db.settings.features: > + self.unmap_key = > self._unmap_key_case_insensitive > + self.contains = > self._contains_case_insensitive > + self.keys = self._keys_case_insensitive > + > + self._contents_insensitive = None > + self._reverse_key_map = None > + > + def clear_cache(self): > + """ > + Clear all cached contents data. > + """ > + self._contents_insensitive = None > + self._reverse_key_map = None > + > + def keys(self): > + """ > + Iterate over all contents keys, which are > transformed to > + lowercase when appropriate, for use in > case-insensitive > + comparisons. > + @rtype: iterator > + @return: An iterator over all the contents keys > + """ > + return iter(self.getcontents()) > + > + def contains(self, key): > + """ > + Check if the given key is contained in the contents, > using > + case-insensitive comparison when appropriate. > + @param key: A filesystem path (including ROOT and > EPREFIX) > + @type key: str > + @rtype: bool > + @return: True if the given key is contained in the > contents, > + False otherwise > + """ > + return key in self.getcontents() > + > + def unmap_key(self, key): > + """ > + Map a key (from the keys method) back to its > case-preserved > + form. > + @param key: A filesystem path (including ROOT and > EPREFIX) > + @type key: str > + @rtype: str > + @return: The case-preserved form of key > + """ > + return key > + > + def _case_insensitive_init(self): > + """ > + Initialize data structures for case-insensitive > support. > + """ > + self._contents_insensitive = dict( > + (k.lower(), v) for k, v in > self.getcontents().items()) > + self._reverse_key_map = dict( > + (k.lower(), k) for k in self.getcontents()) > + > + def _keys_case_insensitive(self): > + if self._contents_insensitive is None: > + self._case_insensitive_init() > + return iter(self._contents_insensitive) > + > + _keys_case_insensitive.__doc__ = keys.__doc__ > + > + def _contains_case_insensitive(self, key): > + if self._contents_insensitive is None: > + self._case_insensitive_init() > + return key.lower() in self._contents_insensitive > + > + _contains_case_insensitive.__doc__ = contains.__doc__ > + > + def _unmap_key_case_insensitive(self, key): > + if self._reverse_key_map is None: > + self._case_insensitive_init() > + return self._reverse_key_map[key] > + > + _unmap_key_case_insensitive.__doc__ = unmap_key.__doc__ > diff --git a/pym/portage/dbapi/vartree.py > b/pym/portage/dbapi/vartree.py index 8b06f4c..81059b1 100644 > --- a/pym/portage/dbapi/vartree.py > +++ b/pym/portage/dbapi/vartree.py > @@ -69,6 +69,7 @@ from _emerge.EbuildPhase import EbuildPhase > from _emerge.emergelog import emergelog > from _emerge.MiscFunctionsProcess import MiscFunctionsProcess > from _emerge.SpawnProcess import SpawnProcess > +from ._ContentsCaseSensitivityManager import > ContentsCaseSensitivityManager > import errno > import fnmatch > @@ -1525,6 +1526,7 @@ class dblink(object): > # When necessary, this attribute is modified for > # compliance with RESTRICT=preserve-libs. > self._preserve_libs = "preserve-libs" in > mysettings.features > + self._contents = ContentsCaseSensitivityManager(self) > > def __hash__(self): > return hash(self._hash_key) > @@ -1612,6 +16
Re: [gentoo-portage-dev] [PATCH v2] NewsManager.getUnreadItems: handle EROFS (490732)
On Fri, 14 Nov 2014 20:45:11 -0800 Zac Medico wrote: > When getUnreadItems tries to lock the news.unread file, it's safe to > ignore EROFS. This is handled with a ReadOnlyFileSystem exception > raised from the portage.locks.lockfile function. > > X-Gentoo-Bug: 490732 > X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=490732 > --- > This updated patch fixes the typo spotted by Brian Dolbec. > LGTM, go for it. but for future reference... use brackets to group multiline imports instead of line continuations. - from portage.exception import InvalidLocation, OperationNotPermitted, \ - PermissionDenied + from portage.exception import (InvalidLocation, OperationNotPermitted, + PermissionDenied, ReadOnlyFileSystem) -- Brian Dolbec
[gentoo-portage-dev] Time for another meeting
It's that time again to hold another meeting to discuss some patches submitted, decide which to include in the next release,... Also, discuss the repoman re-write in progress. Please add any items to the agenda in the wiki page if you are able or reply to this email with them. Alexander (bernalex) will reset the meeting scheduler with some days to fill in with your availability. Some patches/branches up for review/inclusion, plugin-sync, new indexed search for emerge, qa checks patches, EAPI 6, ... -- Brian Dolbec
[gentoo-portage-dev] Re: [PATCH] dep_zapdeps: avoid use.mask/force changes (515584)
On 11/11/2014 05:55 PM, Zac Medico wrote: > This patch causes dep_zapdeps to check which USE flags cause a match > to fail, and uses that information to prioritize choices that do not > require changes to use.mask or use.force. > > X-Gentoo-Bug: 515584 > X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=515584 Any issues with this? I think this one is good to merge. -- Thanks, Zac
Re: [gentoo-portage-dev] Re: [PATCH] dep_zapdeps: avoid use.mask/force changes (515584)
On Mon, 17 Nov 2014 21:09:42 -0800 Zac Medico wrote: > On 11/11/2014 05:55 PM, Zac Medico wrote: > > This patch causes dep_zapdeps to check which USE flags cause a match > > to fail, and uses that information to prioritize choices that do not > > require changes to use.mask or use.force. > > > > X-Gentoo-Bug: 515584 > > X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=515584 > > Any issues with this? I think this one is good to merge. I thought this was merged already... I'll recheck in the morning -- Brian Dolbec
Re: [gentoo-portage-dev] Re: [PATCH] dep_zapdeps: avoid use.mask/force changes (515584)
On Mon, 17 Nov 2014 22:06:41 -0800 Brian Dolbec wrote: > On Mon, 17 Nov 2014 21:09:42 -0800 > Zac Medico wrote: > > > On 11/11/2014 05:55 PM, Zac Medico wrote: > > > This patch causes dep_zapdeps to check which USE flags cause a > > > match to fail, and uses that information to prioritize choices > > > that do not require changes to use.mask or use.force. > > > > > > X-Gentoo-Bug: 515584 > > > X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=515584 > > > > Any issues with this? I think this one is good to merge. > > > I thought this was merged already... I'll recheck in the morning > ok, I was confusing it with: dep_zapdeps: handle circular deps with --onlydeps I looked it over, looks fine, I don't know all the reasoning why ;) but your the expert in that area of code :) merge approved :) /me needs to loose a few projects to spend more time on portage... -- Brian Dolbec
[gentoo-portage-dev] [PATCH] _slot_operator_update_probe: memoize use_reduce (529660)
Memoize the results of use_reduce calls inside _slot_operator_update_probe, in order to improve performance. With memoization, 'emerge -puvDN @world' on one of my computers takes 22.4% less time, and results in 13.5% fewer use_reduce calls. X-Gentoo-Bug: 529660 X-Gentoo-Url: https://bugs.gentoo.org/show_bug.cgi?id=529660 --- pym/_emerge/depgraph.py | 65 ++--- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 6f1910d..3f4a097 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -399,6 +399,7 @@ class _dynamic_depgraph_config(object): self._initially_unsatisfied_deps = [] self._ignored_deps = [] self._highest_pkg_cache = {} + self._flatten_atoms_cache = {} # Binary packages that have been rejected because their USE # didn't match the user's config. It maps packages to a set @@ -1719,26 +1720,10 @@ class depgraph(object): selected_atoms = None - atoms = set() - invalid_metadata = False - for dep_key in ("DEPEND", "HDEPEND", "RDEPEND", "PDEPEND"): - dep_string = replacement_parent._metadata[dep_key] - if not dep_string: - continue - - try: - dep_string = portage.dep.use_reduce(dep_string, - uselist=self._pkg_use_enabled(replacement_parent), - is_valid_flag=replacement_parent.iuse.is_valid_flag, - flat=True, token_class=Atom, - eapi=replacement_parent.eapi) - except portage.exception.InvalidDependString: - invalid_metadata = True - break - - atoms.update(token for token in dep_string if isinstance(token, Atom)) - - if invalid_metadata: + try: + atoms = self._flatten_atoms(replacement_parent, + self._pkg_use_enabled(replacement_parent)) + except InvalidDependString: continue # List of list of child,atom pairs for each atom. @@ -2005,6 +1990,46 @@ class depgraph(object): return frozenset(x.unevaluated_atom for x in selected_atoms) + def _flatten_atoms(self, pkg, use): + """ + Evaluate all dependency atoms of the given package, and return + them as a frozenset. For performance, results are cached. + + @param pkg: a Package instance + @type pkg: Package + @param pkg: set of enabled USE flags + @type pkg: frozenset + @rtype: frozenset + @return: set of evaluated atoms + """ + + cache_key = (pkg, use) + + try: + return self._dynamic_config._flatten_atoms_cache[cache_key] + except KeyError: + pass + + atoms = [] + + for dep_key in pkg._dep_keys: + dep_string = pkg._metadata[dep_key] + if not dep_string: + continue + + dep_string = portage.dep.use_reduce( + dep_string, uselist=use, + is_valid_flag=pkg.iuse.is_valid_flag, + flat=True, token_class=Atom, eapi=pkg.eapi) + + atoms.extend(token for token in dep_string + if isinstance(token, Atom)) + + atoms = frozenset(atoms) + + self._dynamic_config._flatten_atoms_cache[cache_key] = atoms + return atoms + def _iter_similar_available(self, graph_pkg, atom, autounmask_level=None): """ Given a package that's in the graph, do a rough check to -- 2.0.4