From 148abc1340e37ef2b5ba84ea4df103d20dd78eba Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Mon, 26 Nov 2007 01:05:35 +0000 Subject: Bug #124041 - Make emerge show an informative warning message when one or more eclasses override eclasses from PORTDIR. The warning can be permanently disabled by setting PORTAGE_ECLASS_WARNING_ENABLE="0" in /etc/make.conf. svn path=/main/trunk/; revision=8668 --- pym/_emerge/__init__.py | 37 +++++++++++++++++++++++++++++++++---- pym/portage/__init__.py | 9 ++++++++- pym/portage/eclass_cache.py | 10 +++++++++- 3 files changed, 50 insertions(+), 6 deletions(-) (limited to 'pym') diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index de142a414..bfb306634 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -6818,10 +6818,39 @@ def emerge_main(): if "--quiet" not in myopts: portage.deprecated_profile_check() - #Freeze the portdbapi for enhanced performance: - for myroot in trees: - trees[myroot]["porttree"].dbapi.freeze() - del myroot + eclasses_overridden = {} + for mytrees in trees.itervalues(): + mydb = mytrees["porttree"].dbapi + # Freeze the portdbapi for performance (memoize all xmatch results). + mydb.freeze() + eclasses_overridden.update(mydb.eclassdb._master_eclasses_overridden) + del mytrees, mydb + + if eclasses_overridden and \ + settings.get("PORTAGE_ECLASS_WARNING_ENABLE") != "0": + prefix = bad(" * ") + if len(eclasses_overridden) == 1: + writemsg(prefix + "Overlay eclass overrides " + \ + "eclass from PORTDIR:\n", noiselevel=-1) + else: + writemsg(prefix + "Overlay eclasses override " + \ + "eclasses from PORTDIR:\n", noiselevel=-1) + writemsg(prefix + "\n", noiselevel=-1) + for eclass_name in sorted(eclasses_overridden): + writemsg(prefix + " '%s/%s.eclass'\n" % \ + (eclasses_overridden[eclass_name], eclass_name), + noiselevel=-1) + writemsg(prefix + "\n", noiselevel=-1) + msg = "It is best to avoid overridding eclasses from PORTDIR " + \ + "because it will trigger invalidation of cached ebuild metadata " + \ + "that is distributed with the portage tree. If you must " + \ + "override eclasses from PORTDIR then you are advised to run " + \ + "`emerge --regen` after each time that you run `emerge --sync`. " + \ + "Set PORTAGE_ECLASS_WARNING_ENABLE=\"0\" in /etc/make.conf if " + \ + "you would like to disable this warning." + from textwrap import wrap + for line in wrap(msg, 72): + writemsg("%s%s\n" % (prefix, line), noiselevel=-1) if "moo" in myfiles: print """ diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index c496b32cf..b739a4cfc 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -857,7 +857,11 @@ class config(object): Generally if you need data like USE flags, FEATURES, environment variables, virtuals ...etc you look in here. """ - + + # Filter selected variables in the config.environ() method so that + # they don't needlessly propagate down into the ebuild environment. + _environ_filter = frozenset(["PORTAGE_ECLASS_WARNING_ENABLE"]) + def __init__(self, clone=None, mycpv=None, config_profile_path=None, config_incrementals=None, config_root=None, target_root=None, local_config=True): @@ -2479,7 +2483,10 @@ class config(object): def environ(self): "return our locally-maintained environment" mydict={} + environ_filter = self._environ_filter for x in self: + if x in environ_filter: + continue myvalue = self[x] if not isinstance(myvalue, basestring): writemsg("!!! Non-string value in config: %s=%s\n" % \ diff --git a/pym/portage/eclass_cache.py b/pym/portage/eclass_cache.py index 806505757..de20d307c 100644 --- a/pym/portage/eclass_cache.py +++ b/pym/portage/eclass_cache.py @@ -23,6 +23,7 @@ class cache(object): self.porttrees = [self.porttree_root]+overlays self.porttrees = tuple(map(normalize_path, self.porttrees)) self._master_eclass_root = os.path.join(self.porttrees[0],"eclass") + self._master_eclasses_overridden = {} self.update_eclasses() def close_caches(self): @@ -41,6 +42,7 @@ class cache(object): def update_eclasses(self): self.eclasses = {} self._eclass_locations = {} + master_eclasses = {} eclass_len = len(".eclass") ignored_listdir_errnos = (errno.ENOENT, errno.ENOTDIR) for x in [normalize_path(os.path.join(y,"eclass")) for y in self.porttrees]: @@ -63,7 +65,13 @@ class cache(object): ys=y[:-eclass_len] self.eclasses[ys] = (x, long(mtime)) self._eclass_locations[ys] = x - + if x == self._master_eclass_root: + master_eclasses[ys] = mtime + else: + master_mtime = master_eclasses.get(ys) + if master_mtime and master_mtime != mtime: + self._master_eclasses_overridden[ys] = x + def is_eclass_data_valid(self, ec_dict): if not isinstance(ec_dict, dict): return False -- cgit v1.2.3-1-g7c22