commit:     8fba660fb08ddd468d934c7478dcfc8015330e9b
Author:     Daniel Robbins <drobbins <AT> funtoo <DOT> org>
AuthorDate: Tue Oct  3 20:29:44 2017 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Wed Oct  4 00:26:56 2017 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=8fba660f

resolver/package_tracker: new docs

Closes: https://github.com/gentoo/portage/pull/216

 pym/_emerge/resolver/package_tracker.py | 87 ++++++++++++++++++++++++++-------
 1 file changed, 69 insertions(+), 18 deletions(-)

diff --git a/pym/_emerge/resolver/package_tracker.py 
b/pym/_emerge/resolver/package_tracker.py
index 398d4cf46..06163574e 100644
--- a/pym/_emerge/resolver/package_tracker.py
+++ b/pym/_emerge/resolver/package_tracker.py
@@ -31,38 +31,89 @@ class PackageConflict(_PackageConflict):
 
 class PackageTracker(object):
        """
-       This class tracks packages which are currently
-       installed and packages which have been pulled into
-       the dependency graph.
+       **Behavior**
 
-       It automatically tracks conflicts between packages.
+       This section is intended to give you a good conceptual overview of the 
``PackageTracker`` class and its general
+       behavior -- how you can expect it to behave and how in turn expects to 
be used successfully by the programmer.
 
-       Possible conflicts:
-               1) Packages that share the same SLOT.
-               2) Packages with the same cpv.
-               Not yet implemented:
-               3) Packages that block each other.
+       This class is used to model the behavior of a real Gentoo or other 
system using Portage for package management,
+       along with the installed and to-be-installed packages. The installed 
packages are ones that are already on the
+       system and recorded in ``/var/db/pkg``, while the to-be-installed 
packages are a group of packages that Portage is
+       considering installing on the system, based on the information in 
Portage's dependency graph. Multiple roots are
+       supported, so that situations can be modeled where ROOT is set to a 
non-default value (non-``/``).
+
+       You can use the add_pkg() method to add a to-be-merged package to the 
PackageTracker, and ``add_installed_pkg()``
+       to add an already-installed package to the package tracker. Typical use 
of the package tracker involves the
+       depgraph.py code populating the package tracker with calls to 
``add_installed_pkg()`` to add all installed packages
+       on the system, and then it is initialized and ready for use. At that 
point, ``depgraph.py`` can use ``add_pkg()``
+       to add to-be-installed packages to the system.
+
+       It's worth mentioning that PackageTracker uses ``Package`` objects as 
arguments, and stores these objects
+       internally. There are parts of the code that ensure that a ``Package`` 
instance is added to the PackageTracker
+       only once.
+
+       Note that when a to-be-merged package is added to the package tracker 
via ``add_pkg()``, it will "cover up"
+       (replace) any installed package that shares the same root-catpkg-slot 
or root-catpkg-version, meaning that calling
+       the ``all_pkgs()`` or ``match()`` method will not return the installed 
package in the list. And the code does
+       support the scenario where ``add_installed_pkg(pkg2)`` is called 
*after* a call to ``add_pkg(pkg1)`` -- in this
+       case, if ``pkg1`` would 'cover up' ``pkg2``, this will be identified 
and handled correctly.
+
+       But the package tracker is designed to have an important behavior in 
this regard -- because PackageTracker has a
+       ``remove()`` method, these replaced/covered-up packages are not 
permanently removed -- so if you ``remove()`` a
+       to-be-installed package that was "replacing" an installed package, the 
installed package will "reappear". This
+       removal functionality is used by the slot conflict code in 
``depgraph.py`` to modify the list of to-be-installed
+       packages as it addresses slot conflicts.
+
+       One of the main purposes of the PackageTracker is to detect conflicts 
between packages. Conflicts are detected
+       on to-be-installed packages only.
+
+       A slot conflict is a situation where a to-be-installed package is added 
to the package tracker via ``add_pkg()``,
+       and there is already a to-be-installed package added that has the same 
root, catpkg and slot. These cannot co-exist.
+
+       A cpv conflict is a situation where a to-be-installed package is added 
to the package tracker via ``add_pkg()``, and
+       there is already a to-be-installed package add that has the same root, 
catpkg, and version+revision. These cannot
+       co-exist.
+
+       The package tracker does not prevent slot and cpv conflicts from 
occurring. Instead, it allows them to be recorded
+       and the ``conflicts()`` and ``slot_conflicts()`` method will cause the 
package tracker to look at its internal data
+       structures and generate ``PackageConflict()`` objects for each conflict 
it finds.
+
+       The ``match()`` method is used extensively by ``depgraph.py`` to find 
packages that match a particular dependency
+       atom. The code now also supports soname dependencies.
+
+       **Future Functionality**
+
+       The package tracker may be extended in the future to track additional 
useful information:
+
+       * Packages that block one another. This information is not currently 
injected into the package tracker.
+
+       * Sub-slot conflicts. It is possible to identify situations where a 
to-be-installed package is in a new sub-slot.
+         In this case, the depgraph can be queried for parents of this 
dependency, and these parents can be scheduled
+         to be rebuilt.
+
+       :ivar _cp_pkg_map: The collection of to-be-installed (not yet merged) 
packages. We care about conflicts in these
+               packages.
+       :ivar _cp_vdb_pkg_map: The collection of already-installed packages.
+       :ivar _multi_pkgs: A list of keys in ``self._cp_pkg_map`` that have 
potential slot and cpv conflicts.
+       :ivar _replacing: The mechanism by which ``PackageTracker`` records 
to-be-installed packages that 'cover up'
+               already-installed packages. ``self._replacing[cp_key] = [ 
new_pkg_that_replaced_cp_key... ]``.
+       :ivar _replaced_by: ``self.replaced_by[cp_key] == [ replaced_pkg_1, 
replaced_pkg_2 ]``
        """
 
        def __init__(self, soname_deps=False):
+
                """
-               @param soname_deps: enable soname match support
-               @type soname_deps: bool
+               :param soname_deps bool: Determines whether support for soname 
deps should be enabled or not.
                """
-               # Mapping from package keys to set of packages.
+
                self._cp_pkg_map = collections.defaultdict(list)
                self._cp_vdb_pkg_map = collections.defaultdict(list)
-               # List of package keys that may contain conflicts.
-               # The insetation order must be preserved.
                self._multi_pkgs = []
 
                # Cache for result of conflicts().
                self._conflicts_cache = None
 
-               # Records for each pulled package which installed package
-               # are replaced.
                self._replacing = collections.defaultdict(list)
-               # Records which pulled packages replace this package.
                self._replaced_by = collections.defaultdict(list)
 
                self._match_cache = collections.defaultdict(dict)
@@ -258,7 +309,7 @@ class PackageTracker(object):
                Iterates over present slot conflicts.
                This is only intended for consumers that haven't been
                updated to deal with other kinds of conflicts.
-               This funcion should be removed once all consumers are updated.
+               This function should be removed once all consumers are updated.
                """
                return (conflict for conflict in self.conflicts() \
                        if conflict.description == "slot conflict")

Reply via email to