Support RESTRICT=preserve-libs, bug #364427
authorZac Medico <zmedico@gentoo.org>
Wed, 1 May 2013 23:44:18 +0000 (16:44 -0700)
committerZac Medico <zmedico@gentoo.org>
Wed, 1 May 2013 23:44:18 +0000 (16:44 -0700)
Note than when a package is merged, RESTRICT=preserve-libs applies if
*either* the new instance or the old instance sets
RESTRICT=preserve-libs.

Also note that when the user has preserve-libs enabled, the
--depclean-lib-check option may now kick in if one of the packages
selected for unmerge sets RESTRICT=preserve-libs.

bin/repoman
man/ebuild.5
man/emerge.1
pym/_emerge/actions.py
pym/portage/dbapi/vartree.py

index a8293345abea3043ab27cd6e73e0dd88e9a7d1b1..a7bcbe1d157fe19d7504764d64cd93a94397c13c 100755 (executable)
@@ -450,7 +450,7 @@ for x in missingvars:
                qawarnings.add(x)
 
 valid_restrict = frozenset(["binchecks", "bindist",
-       "fetch", "installsources", "mirror",
+       "fetch", "installsources", "mirror", "preserve-libs",
        "primaryuri", "splitdebug", "strip", "test", "userpriv"])
 
 live_eclasses = frozenset([
index 7ecb672e9a88159cd61c5ff044a49df1ab237cac..20e7b4b75b712ad081785f40103cfdf4edd2f895 100644 (file)
@@ -673,6 +673,11 @@ binaries that are not compatible with debugedit.
 .I mirror
 files in \fBSRC_URI\fR will not be downloaded from the \fBGENTOO_MIRRORS\fR.
 .TP
+.I preserve\-libs
+Disables preserve\-libs for specific packages. Note than when a package is
+merged, RESTRICT=preserve\-libs applies if either the new instance or the
+old instance sets RESTRICT=preserve\-libs.
+.TP
 .I primaryuri
 fetch from URIs in \fBSRC_URI\fR before \fBGENTOO_MIRRORS\fR.
 .TP
index 874d33380d1a5dcfdbb1306ec031955f93a617ed..15e8185fa568615148bda10c9a16c926b30c36d3 100644 (file)
@@ -429,10 +429,11 @@ required.
 .BR "\-\-depclean\-lib\-check [ y | n ]"
 Account for library link-level dependencies during
 \fB\-\-depclean\fR and \fB\-\-prune\fR actions.
-This option is enabled by default. This option is ignored
-when FEATURES="preserve\-libs" is enabled in
-\fBmake.conf\fR(5), since any libraries that have
-consumers will simply be preserved.
+This option is enabled by default. If FEATURES="preserve\-libs" is
+enabled in \fBmake.conf\fR(5), and preserve\-libs is not restricted
+for any of the packages selected for removal, then this option is
+ignored because any libraries that have consumers will simply be
+preserved.
 .TP
 .BR \-\-digest
 Prevent corruption from being noticed. The `repoman manifest` command is the
index 2c5a1b383bbad9b7ef849498e21243b30220b879..3982eb3636ccb50a5db237e0527e01ba35db8acd 100644 (file)
@@ -987,10 +987,19 @@ def calc_depclean(settings, trees, ldpath_mtimes,
        cleanlist = create_cleanlist()
        clean_set = set(cleanlist)
 
-       if cleanlist and \
-               real_vardb._linkmap is not None and \
-               myopts.get("--depclean-lib-check", _DEPCLEAN_LIB_CHECK_DEFAULT) != "n" and \
-               "preserve-libs" not in settings.features:
+       depclean_lib_check = cleanlist and real_vardb._linkmap is not None and \
+               myopts.get("--depclean-lib-check", _DEPCLEAN_LIB_CHECK_DEFAULT) != "n"
+       preserve_libs = "preserve-libs" in settings.features
+       preserve_libs_restrict = False
+
+       if depclean_lib_check and preserve_libs:
+               for pkg in cleanlist:
+                       if "preserve-libs" in pkg.restrict:
+                               preserve_libs_restrict = True
+                               break
+
+       if depclean_lib_check and \
+               (preserve_libs_restrict or not preserve_libs):
 
                # Check if any of these packages are the sole providers of libraries
                # with consumers that have not been selected for removal. If so, these
@@ -1003,6 +1012,13 @@ def calc_depclean(settings, trees, ldpath_mtimes,
                writemsg_level(">>> Checking for lib consumers...\n")
 
                for pkg in cleanlist:
+
+                       if preserve_libs and "preserve-libs" not in pkg.restrict:
+                               # Any needed libraries will be preserved
+                               # when this package is unmerged, so there's
+                               # no need to account for it here.
+                               continue
+
                        pkg_dblink = real_vardb._dblink(pkg.cpv)
                        consumers = {}
 
index 0d4a75608cb84d0eb6ef4da82024a342699efd79..c6eaabfc000cd73d01c98d3897277d07d7c7d54b 100644 (file)
@@ -1519,6 +1519,10 @@ class dblink(object):
                self._protect_obj = None
                self._pipe = pipe
 
+               # When necessary, this attribute is modified for
+               # compliance with RESTRICT=preserve-libs.
+               self._preserve_libs = "preserve-libs" in mysettings.features
+
        def __hash__(self):
                return hash(self._hash_key)
 
@@ -1895,6 +1899,10 @@ class dblink(object):
                except UnsupportedAPIException as e:
                        eapi_unsupported = e
 
+               if self._preserve_libs and "preserve-libs" in \
+                       self.settings["PORTAGE_RESTRICT"].split():
+                       self._preserve_libs = False
+
                builddir_lock = None
                scheduler = self._scheduler
                retval = os.EX_OK
@@ -2879,7 +2887,7 @@ class dblink(object):
                        self.vartree.dbapi._linkmap is None or \
                        self.vartree.dbapi._plib_registry is None or \
                        (not unmerge and self._installed_instance is None) or \
-                       "preserve-libs" not in self.settings.features:
+                       not self._preserve_libs:
                        return set()
 
                os = _os_merge
@@ -3598,26 +3606,40 @@ class dblink(object):
                cp = self.mysplit[0]
                slot_atom = "%s:%s" % (cp, slot)
 
-               # filter any old-style virtual matches
-               slot_matches = [cpv for cpv in self.vartree.dbapi.match(slot_atom) \
-                       if cpv_getkey(cpv) == cp]
-
-               if self.mycpv not in slot_matches and \
-                       self.vartree.dbapi.cpv_exists(self.mycpv):
-                       # handle multislot or unapplied slotmove
-                       slot_matches.append(self.mycpv)
-
-               others_in_slot = []
-               for cur_cpv in slot_matches:
-                       # Clone the config in case one of these has to be unmerged since
-                       # we need it to have private ${T} etc... for things like elog.
-                       settings_clone = portage.config(clone=self.settings)
-                       settings_clone.pop("PORTAGE_BUILDDIR_LOCKED", None)
-                       settings_clone.reset()
-                       others_in_slot.append(dblink(self.cat, catsplit(cur_cpv)[1],
-                               settings=settings_clone,
-                               vartree=self.vartree, treetype="vartree",
-                               scheduler=self._scheduler, pipe=self._pipe))
+               self.lockdb()
+               try:
+                       # filter any old-style virtual matches
+                       slot_matches = [cpv for cpv in self.vartree.dbapi.match(slot_atom)
+                               if cpv_getkey(cpv) == cp]
+
+                       if self.mycpv not in slot_matches and \
+                               self.vartree.dbapi.cpv_exists(self.mycpv):
+                               # handle multislot or unapplied slotmove
+                               slot_matches.append(self.mycpv)
+
+                       others_in_slot = []
+                       for cur_cpv in slot_matches:
+                               # Clone the config in case one of these has to be unmerged,
+                               # since we need it to have private ${T} etc... for things
+                               # like elog.
+                               settings_clone = portage.config(clone=self.settings)
+                               settings_clone.pop("PORTAGE_BUILDDIR_LOCKED", None)
+                               settings_clone.setcpv(cur_cpv, mydb=self.vartree.dbapi)
+                               if self._preserve_libs and "preserve-libs" in \
+                                       settings_clone["PORTAGE_RESTRICT"].split():
+                                       self._preserve_libs = False
+                               others_in_slot.append(dblink(self.cat, catsplit(cur_cpv)[1],
+                                       settings=settings_clone,
+                                       vartree=self.vartree, treetype="vartree",
+                                       scheduler=self._scheduler, pipe=self._pipe))
+               finally:
+                       self.unlockdb()
+
+               # If any instance has RESTRICT=preserve-libs, then
+               # restrict it for all instances.
+               if not self._preserve_libs:
+                       for dblnk in others_in_slot:
+                               dblnk._preserve_libs = False
 
                retval = self._security_check(others_in_slot)
                if retval: