1 # Copyright 2007 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
5 from portage.versions import catpkgsplit, catsplit, pkgcmp
6 from portage.sets.base import PackageSet
7 from portage.sets import SetConfigError, get_boolean
9 __all__ = ["CategorySet", "EverythingSet", "InheritSet"]
11 class EverythingSet(PackageSet):
12 _operations = ["merge", "unmerge"]
13 description = "Package set which contains SLOT " + \
14 "atoms to match all installed packages"
16 def __init__(self, vdbapi):
17 super(EverythingSet, self).__init__()
22 for cp in self._db.cp_all():
23 if len(self._db.cp_list(cp)) > 1:
24 for cpv in self._db.cp_list(cp):
25 myslot = self._db.aux_get(cpv, ["SLOT"])[0]
26 myatoms.append(cp+":"+myslot)
29 self._setAtoms(myatoms)
31 def singleBuilder(self, options, settings, trees):
32 return EverythingSet(trees["vartree"].dbapi)
33 singleBuilder = classmethod(singleBuilder)
35 class OwnerSet(PackageSet):
37 _operations = ["merge", "unmerge"]
39 description = "Package set which contains all packages " + \
40 "that own one or more files."
42 def __init__(self, vardb=None, files=None):
43 super(OwnerSet, self).__init__()
47 def mapPathsToAtoms(self, paths):
50 aux_get = vardb.aux_get
52 for link, p in vardb._owners.iter_owners(paths):
53 cat, pn = catpkgsplit(link.mycpv)[:2]
54 slot, = aux_get(link.mycpv, aux_keys)
55 rValue.add("%s/%s:%s" % (cat, pn, slot))
59 self._setAtoms(self.mapPathsToAtoms(self._files))
61 def singleBuilder(cls, options, settings, trees):
62 if not "files" in options:
63 raise SetConfigError("no files given")
66 return cls(vardb=trees["vartree"].dbapi,
67 files=frozenset(shlex.split(options["files"])))
69 singleBuilder = classmethod(singleBuilder)
71 class InheritSet(PackageSet):
73 _operations = ["merge", "unmerge"]
75 description = "Package set which contains all packages " + \
76 "that inherit one or more specific eclasses."
78 def __init__(self, vardb=None, inherits=None):
79 super(InheritSet, self).__init__()
81 self._inherits = inherits
85 inherits = self._inherits
86 cp_list = self._db.cp_list
87 aux_get = self._db.aux_get
88 aux_keys = ["INHERITED", "SLOT"]
89 for cp in self._db.cp_all():
90 for cpv in cp_list(cp):
91 inherited, slot = aux_get(cpv, aux_keys)
92 inherited = inherited.split()
93 if inherits.intersection(inherited):
94 atoms.append("%s:%s" % (cp, slot))
98 def singleBuilder(cls, options, settings, trees):
99 if not "inherits" in options:
100 raise SetConfigError("no inherits given")
102 inherits = options["inherits"]
103 return cls(vardb=trees["vartree"].dbapi,
104 inherits=frozenset(inherits.split()))
106 singleBuilder = classmethod(singleBuilder)
108 class DowngradeSet(PackageSet):
110 _operations = ["merge", "unmerge"]
112 description = "Package set which contains all packages " + \
113 "for which the highest visible ebuild version is lower than " + \
114 "the currently installed version."
116 def __init__(self, portdb=None, vardb=None):
117 super(DowngradeSet, self).__init__()
118 self._portdb = portdb
123 xmatch = self._portdb.xmatch
124 xmatch_level = "bestmatch-visible"
125 cp_list = self._vardb.cp_list
126 aux_get = self._vardb.aux_get
128 for cp in self._vardb.cp_all():
129 for cpv in cp_list(cp):
130 slot, = aux_get(cpv, aux_keys)
131 slot_atom = "%s:%s" % (cp, slot)
132 ebuild = xmatch(xmatch_level, slot_atom)
133 ebuild_split = catpkgsplit(ebuild)[1:]
134 installed_split = catpkgsplit(cpv)[1:]
135 if pkgcmp(installed_split, ebuild_split) > 0:
136 atoms.append(slot_atom)
138 self._setAtoms(atoms)
140 def singleBuilder(cls, options, settings, trees):
141 return cls(portdb=trees["porttree"].dbapi,
142 vardb=trees["vartree"].dbapi)
144 singleBuilder = classmethod(singleBuilder)
146 class CategorySet(PackageSet):
147 _operations = ["merge", "unmerge"]
149 def __init__(self, category, dbapi, only_visible=True):
150 super(CategorySet, self).__init__()
152 self._category = category
153 self._check = only_visible
158 self.description = "Package set containing %s packages of category %s" % (s, self._category)
162 for cp in self._db.cp_all():
163 if catsplit(cp)[0] == self._category:
164 if (not self._check) or len(self._db.match(cp)) > 0:
166 self._setAtoms(myatoms)
168 def _builderGetRepository(cls, options, repositories):
169 repository = options.get("repository", "porttree")
170 if not repository in repositories:
171 raise SetConfigError("invalid repository class '%s'" % repository)
173 _builderGetRepository = classmethod(_builderGetRepository)
175 def _builderGetVisible(cls, options):
176 return get_boolean(options, "only_visible", True)
177 _builderGetVisible = classmethod(_builderGetVisible)
179 def singleBuilder(cls, options, settings, trees):
180 if not "category" in options:
181 raise SetConfigError("no category given")
183 category = options["category"]
184 if not category in settings.categories:
185 raise SetConfigError("invalid category name '%s'" % category)
187 repository = cls._builderGetRepository(options, trees.keys())
188 visible = cls._builderGetVisible(options)
190 return CategorySet(category, dbapi=trees[repository].dbapi, only_visible=visible)
191 singleBuilder = classmethod(singleBuilder)
193 def multiBuilder(cls, options, settings, trees):
196 if "categories" in options:
197 categories = options["categories"].split()
198 invalid = set(categories).difference(settings.categories)
200 raise SetConfigError("invalid categories: %s" % ", ".join(list(invalid)))
202 categories = settings.categories
204 repository = cls._builderGetRepository(options, trees.keys())
205 visible = cls._builderGetVisible(options)
206 name_pattern = options.get("name_pattern", "$category/*")
208 if not "$category" in name_pattern and not "${category}" in name_pattern:
209 raise SetConfigError("name_pattern doesn't include $category placeholder")
211 for cat in categories:
212 myset = CategorySet(cat, trees[repository].dbapi, only_visible=visible)
213 myname = name_pattern.replace("$category", cat)
214 myname = myname.replace("${category}", cat)
215 rValue[myname] = myset
217 multiBuilder = classmethod(multiBuilder)