Bug #124041 - Make emerge show an informative warning message when one
authorZac Medico <zmedico@gentoo.org>
Mon, 26 Nov 2007 01:05:35 +0000 (01:05 -0000)
committerZac Medico <zmedico@gentoo.org>
Mon, 26 Nov 2007 01:05:35 +0000 (01:05 -0000)
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
pym/portage/__init__.py
pym/portage/eclass_cache.py

index de142a41496c918634543b004b1449bee505179a..bfb306634345332b884cdd93e15e71f7039dbee6 100644 (file)
@@ -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 """
index c496b32cfd1de1bd5d73e9ad513acffe721ea497..b739a4cfcc85e223586cb616d661a2b587ec89fb 100644 (file)
@@ -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" % \
index 806505757fecce36be01d3142ff3a0c89ef81bf0..de20d307c27b1c2b34393e5ae6fe746f3d281b9d 100644 (file)
@@ -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