Gentoo Archives: gentoo-commits

From: "Michał Górny" <mgorny@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:master commit in: pym/portage/_sets/, cnf/sets/
Date: Thu, 28 Aug 2014 08:59:30
Message-Id: 1409216343.3553e8bc274ae5b736a47ed8f1acc4bf472a7af4.mgorny@gentoo
1 commit: 3553e8bc274ae5b736a47ed8f1acc4bf472a7af4
2 Author: Michał Górny <mgorny <AT> gentoo <DOT> org>
3 AuthorDate: Thu Jul 24 22:20:16 2014 +0000
4 Commit: Michał Górny <mgorny <AT> gentoo <DOT> org>
5 CommitDate: Thu Aug 28 08:59:03 2014 +0000
6 URL: http://sources.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=3553e8bc
7
8 sets: Introduce @changed-deps to update packages which need dep changes
9
10 The @changed-deps set compares the RDEPEND and PDEPEND entries of
11 installed packages with the metadata of matching ebuilds, triggering
12 rebuilds whenever a difference in dependencies is detected.
13
14 This set can be used to force installed package metadata updates when
15 ebuild dependencies are changed in-place. In particular, it can be used
16 to restore dependency tree integrity after disabling --dynamic-deps.
17
18 Acked-by: Alexander Berntsen <bernalex <AT> gentoo.org>
19 Acked-by: Brian Dolbec <dolsen <AT> gentoo.org>
20
21 ---
22 cnf/sets/portage.conf | 5 +++
23 pym/portage/_sets/dbapi.py | 81 ++++++++++++++++++++++++++++++++++++++++++++--
24 2 files changed, 84 insertions(+), 2 deletions(-)
25
26 diff --git a/cnf/sets/portage.conf b/cnf/sets/portage.conf
27 index b73afb1..fd2c387 100644
28 --- a/cnf/sets/portage.conf
29 +++ b/cnf/sets/portage.conf
30 @@ -84,3 +84,8 @@ class = portage.sets.dbapi.UnavailableSet
31 # are not available.
32 [unavailable-binaries]
33 class = portage.sets.dbapi.UnavailableBinaries
34 +
35 +# Installed packages for which vdb *DEPEND entries are outdated compared
36 +# to the matching portdb entry.
37 +[changed-deps]
38 +class = portage.sets.dbapi.ChangedDepsSet
39
40 diff --git a/pym/portage/_sets/dbapi.py b/pym/portage/_sets/dbapi.py
41 index 817bcd7..299cb81 100644
42 --- a/pym/portage/_sets/dbapi.py
43 +++ b/pym/portage/_sets/dbapi.py
44 @@ -3,17 +3,19 @@
45
46 from __future__ import division
47
48 +import re
49 import time
50
51 from portage import os
52 from portage.versions import best, catsplit, vercmp
53 -from portage.dep import Atom
54 +from portage.dep import Atom, use_reduce
55 +from portage.exception import InvalidAtom
56 from portage.localization import _
57 from portage._sets.base import PackageSet
58 from portage._sets import SetConfigError, get_boolean
59 import portage
60
61 -__all__ = ["CategorySet", "DowngradeSet",
62 +__all__ = ["CategorySet", "ChangedDepsSet", "DowngradeSet",
63 "EverythingSet", "OwnerSet", "VariableSet"]
64
65 class EverythingSet(PackageSet):
66 @@ -458,3 +460,78 @@ class RebuiltBinaries(EverythingSet):
67 bindb=trees["bintree"].dbapi)
68
69 singleBuilder = classmethod(singleBuilder)
70 +
71 +class ChangedDepsSet(PackageSet):
72 +
73 + _operations = ["merge", "unmerge"]
74 +
75 + description = "Package set which contains all installed " + \
76 + "packages for which the vdb *DEPEND entries are outdated " + \
77 + "compared to corresponding portdb entries."
78 +
79 + def __init__(self, portdb=None, vardb=None):
80 + super(ChangedDepsSet, self).__init__()
81 + self._portdb = portdb
82 + self._vardb = vardb
83 +
84 + def load(self):
85 + depvars = ('RDEPEND', 'PDEPEND')
86 +
87 + # regexp used to match atoms using subslot operator :=
88 + subslot_repl_re = re.compile(r':[^[]*=')
89 +
90 + atoms = []
91 + for cpv in self._vardb.cpv_all():
92 + # no ebuild, no update :).
93 + if not self._portdb.cpv_exists(cpv):
94 + continue
95 +
96 + # USE flags used to build the ebuild and EAPI
97 + # (needed for Atom & use_reduce())
98 + use, eapi = self._vardb.aux_get(cpv, ('USE', 'EAPI'))
99 + usel = use.split()
100 +
101 + # function used to recursively process atoms in nested lists.
102 + def clean_subslots(depatom, usel=None):
103 + if isinstance(depatom, list):
104 + # process the nested list.
105 + return [clean_subslots(x, usel) for x in depatom]
106 + else:
107 + try:
108 + # this can be either an atom or some special operator.
109 + # in the latter case, we get InvalidAtom and pass it as-is.
110 + a = Atom(depatom)
111 + except InvalidAtom:
112 + return depatom
113 + else:
114 + # if we're processing portdb, we need to evaluate USE flag
115 + # dependency conditionals to make them match vdb. this
116 + # requires passing the list of USE flags, so we reuse it
117 + # as conditional for the operation as well.
118 + if usel is not None:
119 + a = a.evaluate_conditionals(usel)
120 +
121 + # replace slot operator := dependencies with plain :=
122 + # since we can't properly compare expanded slots
123 + # in vardb to abstract slots in portdb.
124 + return subslot_repl_re.sub(':=', a)
125 +
126 + # get all *DEPEND variables from vdb & portdb and compare them.
127 + # we need to do some cleaning up & expansion to make matching
128 + # meaningful since vdb dependencies are conditional-free.
129 + vdbvars = [clean_subslots(use_reduce(x, uselist=usel, eapi=eapi))
130 + for x in self._vardb.aux_get(cpv, depvars)]
131 + pdbvars = [clean_subslots(use_reduce(x, uselist=usel, eapi=eapi), usel)
132 + for x in self._portdb.aux_get(cpv, depvars)]
133 +
134 + # if dependencies don't match, trigger the rebuild.
135 + if vdbvars != pdbvars:
136 + atoms.append('=%s' % cpv)
137 +
138 + self._setAtoms(atoms)
139 +
140 + def singleBuilder(cls, options, settings, trees):
141 + return cls(portdb=trees["porttree"].dbapi,
142 + vardb=trees["vartree"].dbapi)
143 +
144 + singleBuilder = classmethod(singleBuilder)