1 |
Author: grobian |
2 |
Date: 2008-05-25 17:51:33 +0000 (Sun, 25 May 2008) |
3 |
New Revision: 10417 |
4 |
|
5 |
Modified: |
6 |
main/branches/prefix/bin/repoman |
7 |
main/branches/prefix/pym/_emerge/__init__.py |
8 |
main/branches/prefix/pym/portage/__init__.py |
9 |
main/branches/prefix/pym/portage/dbapi/__init__.py |
10 |
main/branches/prefix/pym/portage/dbapi/porttree.py |
11 |
main/branches/prefix/pym/portage/dbapi/vartree.py |
12 |
main/branches/prefix/pym/portage/dep.py |
13 |
main/branches/prefix/pym/portage/sets/files.py |
14 |
Log: |
15 |
Merged from trunk 10382:10393 |
16 |
|
17 |
| 10383 | Raise an error if the named repository doesn't exist | |
18 |
| genone | | |
19 |
|
20 |
| 10387 | Bug #2272 - Extend dependency atom sytax to specify enabled | |
21 |
| zmedico | or disabled states of USE flags. Matching with the new | |
22 |
| | syntax is currently only supported in the dbapi classes and | |
23 |
| | dependency resolver (use matching does not work yet in | |
24 |
| | config files such as package.mask). | |
25 |
|
26 |
| 10388 | Bug #220671 - Fix 'RuntimeError: Set changed size during | |
27 |
| zmedico | iteration' error. | |
28 |
|
29 |
| 10389 | Bug #223417 - use floating point mtime for finer grained | |
30 |
| zmedico | validation in cachedir(). | |
31 |
|
32 |
| 10390 | Bug #223417 - Make the vardbapi.cpv_all() use_cache | |
33 |
| zmedico | parameter useful for forcing direct os.listdir() calls. This | |
34 |
| | is more of an issue now that these listdir() calls are | |
35 |
| | frequently triggered when merging packages (due to things | |
36 |
| | like blocker and preserve-libs handling). | |
37 |
|
38 |
| 10391 | Fix use_reduce() so that it appropriately raises an | |
39 |
| zmedico | InvalidDependString instead of an IndexError in some cases | |
40 |
| | (avoid IndexError by using slice notation). | |
41 |
|
42 |
| 10392 | Fix paren_reduce() so that it appropriately raises an | |
43 |
| zmedico | InvalidDependString() in some cases, instead of a nonsense | |
44 |
| | AttributeError. | |
45 |
|
46 |
| 10393 | Fix paren_reduce() so that it appropriately raises an | |
47 |
| zmedico | InvalidDependString() in some cases, instead of a nonsense | |
48 |
| | ValueError. | |
49 |
|
50 |
|
51 |
Modified: main/branches/prefix/bin/repoman |
52 |
=================================================================== |
53 |
--- main/branches/prefix/bin/repoman 2008-05-25 09:01:18 UTC (rev 10416) |
54 |
+++ main/branches/prefix/bin/repoman 2008-05-25 17:51:33 UTC (rev 10417) |
55 |
@@ -507,7 +507,7 @@ |
56 |
portdb.mysettings = repoman_settings |
57 |
# We really only need to cache the metadata that's necessary for visibility |
58 |
# filtering. Anything else can be discarded to reduce memory consumption. |
59 |
-for k in ("DEPEND", "IUSE", "LICENCE", "PDEPEND", |
60 |
+for k in ("DEPEND", "LICENCE", "PDEPEND", |
61 |
"PROVIDE", "RDEPEND", "RESTRICT", "repository"): |
62 |
portdb._aux_cache_keys.discard(k) |
63 |
# dep_zapdeps looks at the vardbapi, but it shouldn't for repoman. |
64 |
@@ -1256,6 +1256,7 @@ |
65 |
is_blocker = atom.startswith("!") |
66 |
if is_blocker: |
67 |
atom = token.lstrip("!") |
68 |
+ atom = portage.dep.Atom(atom) |
69 |
if mytype == "DEPEND" and \ |
70 |
not is_blocker and \ |
71 |
not inherited_java_eclass and \ |
72 |
@@ -1275,6 +1276,12 @@ |
73 |
(relative_path + ": %s slot dependency" + \ |
74 |
" not supported with EAPI='%s':" + \ |
75 |
" '%s'") % (mytype, eapi, atom)) |
76 |
+ if atom.use and eapi in ("0", "1"): |
77 |
+ stats['EAPI.incompatible'] += 1 |
78 |
+ fails['EAPI.incompatible'].append( |
79 |
+ (relative_path + ": %s use dependency" + \ |
80 |
+ " not supported with EAPI='%s':" + \ |
81 |
+ " '%s'") % (mytype, eapi, atom)) |
82 |
|
83 |
type_list.extend([mytype] * (len(badsyntax) - len(type_list))) |
84 |
|
85 |
|
86 |
Modified: main/branches/prefix/pym/_emerge/__init__.py |
87 |
=================================================================== |
88 |
--- main/branches/prefix/pym/_emerge/__init__.py 2008-05-25 09:01:18 UTC (rev 10416) |
89 |
+++ main/branches/prefix/pym/_emerge/__init__.py 2008-05-25 17:51:33 UTC (rev 10417) |
90 |
@@ -1013,7 +1013,7 @@ |
91 |
vdb_lock = portage.locks.lockdir(vdb_path) |
92 |
real_dbapi = real_vartree.dbapi |
93 |
slot_counters = {} |
94 |
- for cpv in real_dbapi.cpv_all(): |
95 |
+ for cpv in real_dbapi.cpv_all(use_cache=0): |
96 |
cache_key = ("installed", self.root, cpv, "nomerge") |
97 |
pkg = self._pkg_cache.get(cache_key) |
98 |
if pkg is not None: |
99 |
@@ -2841,6 +2841,13 @@ |
100 |
return selected_atoms |
101 |
|
102 |
def _show_unsatisfied_dep(self, root, atom, myparent=None, arg=None): |
103 |
+ atom = portage.dep.Atom(atom) |
104 |
+ atom_without_use = atom |
105 |
+ if atom.use: |
106 |
+ atom_without_use = portage.dep.remove_slot(atom) |
107 |
+ if atom.slot: |
108 |
+ atom_without_use += ":" + atom.slot |
109 |
+ atom_without_use = portage.dep.Atom(atom_without_use) |
110 |
xinfo = '"%s"' % atom |
111 |
if arg: |
112 |
xinfo='"%s"' % arg |
113 |
@@ -2851,9 +2858,11 @@ |
114 |
green('"%s"' % myparent[2]) + \ |
115 |
red(' [%s]' % myparent[0]) + ')' |
116 |
masked_packages = [] |
117 |
+ missing_use = [] |
118 |
missing_licenses = [] |
119 |
have_eapi_mask = False |
120 |
pkgsettings = self.pkgsettings[root] |
121 |
+ implicit_iuse = pkgsettings._get_implicit_iuse() |
122 |
root_config = self.roots[root] |
123 |
portdb = self.roots[root].trees["porttree"].dbapi |
124 |
dbs = self._filtered_trees[root]["dbs"] |
125 |
@@ -2862,18 +2871,61 @@ |
126 |
continue |
127 |
match = db.match |
128 |
if hasattr(db, "xmatch"): |
129 |
- cpv_list = db.xmatch("match-all", atom) |
130 |
+ cpv_list = db.xmatch("match-all", atom_without_use) |
131 |
else: |
132 |
- cpv_list = db.match(atom) |
133 |
+ cpv_list = db.match(atom_without_use) |
134 |
# descending order |
135 |
cpv_list.reverse() |
136 |
for cpv in cpv_list: |
137 |
metadata, mreasons = get_mask_info(root_config, cpv, |
138 |
pkgsettings, db, pkg_type, built, installed, db_keys) |
139 |
- masked_packages.append( |
140 |
- (root_config, pkgsettings, cpv, metadata, mreasons)) |
141 |
+ if atom.use and not mreasons: |
142 |
+ missing_use.append(Package(built=built, cpv=cpv, |
143 |
+ installed=installed, metadata=metadata, root=root)) |
144 |
+ else: |
145 |
+ masked_packages.append( |
146 |
+ (root_config, pkgsettings, cpv, metadata, mreasons)) |
147 |
|
148 |
- if masked_packages: |
149 |
+ missing_use_reasons = [] |
150 |
+ missing_iuse_reasons = [] |
151 |
+ for pkg in missing_use: |
152 |
+ use = pkg.metadata["USE"].split() |
153 |
+ iuse = implicit_iuse.union(x.lstrip("+-") \ |
154 |
+ for x in pkg.metadata["IUSE"].split()) |
155 |
+ iuse_re = re.compile("^(%s)$" % "|".join(iuse)) |
156 |
+ missing_iuse = [] |
157 |
+ for x in atom.use.required: |
158 |
+ if iuse_re.match(x) is None: |
159 |
+ missing_iuse.append(x) |
160 |
+ mreasons = [] |
161 |
+ if missing_iuse: |
162 |
+ mreasons.append("Missing IUSE: %s" % " ".join(missing_iuse)) |
163 |
+ missing_iuse_reasons.append((pkg, mreasons)) |
164 |
+ else: |
165 |
+ need_enable = sorted(atom.use.enabled.difference(use)) |
166 |
+ need_disable = sorted(atom.use.disabled.intersection(use)) |
167 |
+ if need_enable or need_disable: |
168 |
+ changes = [] |
169 |
+ changes.extend(colorize("red", "+" + x) \ |
170 |
+ for x in need_enable) |
171 |
+ changes.extend(colorize("blue", "-" + x) \ |
172 |
+ for x in need_disable) |
173 |
+ mreasons.append("Change USE: %s" % " ".join(changes)) |
174 |
+ missing_use_reasons.append((pkg, mreasons)) |
175 |
+ |
176 |
+ if missing_iuse_reasons and not missing_use_reasons: |
177 |
+ missing_use_reasons = missing_iuse_reasons |
178 |
+ elif missing_use_reasons: |
179 |
+ # Only show the latest version. |
180 |
+ del missing_use_reasons[1:] |
181 |
+ |
182 |
+ if missing_use_reasons: |
183 |
+ print "\nemerge: there are no ebuilds built with USE flags to satisfy "+green(xinfo)+"." |
184 |
+ print "!!! One of the following packages is required to complete your request:" |
185 |
+ for pkg, mreasons in missing_use_reasons: |
186 |
+ print "- "+pkg.cpv+" ("+", ".join(mreasons)+")" |
187 |
+ |
188 |
+ elif masked_packages: |
189 |
print "\n!!! "+red("All ebuilds that could satisfy ")+green(xinfo)+red(" have been masked.") |
190 |
print "!!! One of the following masked packages is required to complete your request:" |
191 |
have_eapi_mask = show_masked_packages(masked_packages) |
192 |
@@ -2923,7 +2975,8 @@ |
193 |
# List of acceptable packages, ordered by type preference. |
194 |
matched_packages = [] |
195 |
highest_version = None |
196 |
- atom_cp = portage.dep_getkey(atom) |
197 |
+ atom = portage.dep.Atom(atom) |
198 |
+ atom_cp = atom.cp |
199 |
existing_node = None |
200 |
myeb = None |
201 |
usepkgonly = "--usepkgonly" in self.myopts |
202 |
@@ -3055,11 +3108,17 @@ |
203 |
# it's not the same version. |
204 |
continue |
205 |
|
206 |
- if not built and not calculated_use: |
207 |
+ if not pkg.built and not calculated_use: |
208 |
# This is avoided whenever possible because |
209 |
# it's expensive. |
210 |
pkgsettings.setcpv(cpv, mydb=pkg.metadata) |
211 |
pkg.metadata["USE"] = pkgsettings["PORTAGE_USE"] |
212 |
+ if atom.use and not pkg.built: |
213 |
+ use = pkg.metadata["USE"].split() |
214 |
+ if atom.use.enabled.difference(use): |
215 |
+ continue |
216 |
+ if atom.use.disabled.intersection(use): |
217 |
+ continue |
218 |
if pkg.cp == atom_cp: |
219 |
if highest_version is None: |
220 |
highest_version = pkg |
221 |
|
222 |
Modified: main/branches/prefix/pym/portage/__init__.py |
223 |
=================================================================== |
224 |
--- main/branches/prefix/pym/portage/__init__.py 2008-05-25 09:01:18 UTC (rev 10416) |
225 |
+++ main/branches/prefix/pym/portage/__init__.py 2008-05-25 17:51:33 UTC (rev 10417) |
226 |
@@ -203,7 +203,7 @@ |
227 |
try: |
228 |
pathstat = os.stat(mypath) |
229 |
if stat.S_ISDIR(pathstat[stat.ST_MODE]): |
230 |
- mtime = pathstat[stat.ST_MTIME] |
231 |
+ mtime = pathstat.st_mtime |
232 |
else: |
233 |
raise portage.exception.DirectoryNotFound(mypath) |
234 |
except EnvironmentError, e: |
235 |
@@ -2050,57 +2050,14 @@ |
236 |
|
237 |
# Filter out USE flags that aren't part of IUSE. This has to |
238 |
# be done for every setcpv() call since practically every |
239 |
- # package has different IUSE. Some flags are considered to |
240 |
- # be implicit members of IUSE: |
241 |
- # |
242 |
- # * Flags derived from ARCH |
243 |
- # * Flags derived from USE_EXPAND_HIDDEN variables |
244 |
- # * Masked flags, such as those from {,package}use.mask |
245 |
- # * Forced flags, such as those from {,package}use.force |
246 |
- # * build and bootstrap flags used by bootstrap.sh |
247 |
- |
248 |
+ # package has different IUSE. |
249 |
use = set(self["USE"].split()) |
250 |
- iuse_implicit = set(x.lstrip("+-") for x in iuse.split()) |
251 |
+ iuse_implicit = self._get_implicit_iuse() |
252 |
+ iuse_implicit.update(x.lstrip("+-") for x in iuse.split()) |
253 |
|
254 |
- # Flags derived from ARCH. |
255 |
- arch = self.configdict["defaults"].get("ARCH") |
256 |
- if arch: |
257 |
- iuse_implicit.add(arch) |
258 |
- iuse_implicit.update(self.get("PORTAGE_ARCHLIST", "").split()) |
259 |
+ self.configdict["pkg"]["PORTAGE_IUSE"] = \ |
260 |
+ "^(%s)$" % "|".join(sorted(iuse_implicit)) |
261 |
|
262 |
- # Flags derived from USE_EXPAND_HIDDEN variables |
263 |
- # such as ELIBC, KERNEL, and USERLAND. |
264 |
- use_expand_hidden = self.get("USE_EXPAND_HIDDEN", "").split() |
265 |
- use_expand_hidden_raw = use_expand_hidden |
266 |
- if use_expand_hidden: |
267 |
- use_expand_hidden = re.compile("^(%s)_.*" % \ |
268 |
- ("|".join(x.lower() for x in use_expand_hidden))) |
269 |
- for x in use: |
270 |
- if use_expand_hidden.match(x): |
271 |
- iuse_implicit.add(x) |
272 |
- |
273 |
- # Flags that have been masked or forced. |
274 |
- iuse_implicit.update(self.usemask) |
275 |
- iuse_implicit.update(self.useforce) |
276 |
- |
277 |
- # build and bootstrap flags used by bootstrap.sh |
278 |
- iuse_implicit.add("build") |
279 |
- iuse_implicit.add("bootstrap") |
280 |
- |
281 |
- # prefix flag is used in Prefix |
282 |
- iuse_implicit.add("prefix") |
283 |
- |
284 |
- if ebuild_phase: |
285 |
- iuse_grep = iuse_implicit.copy() |
286 |
- if use_expand_hidden_raw: |
287 |
- for x in use_expand_hidden_raw: |
288 |
- iuse_grep.add(x.lower() + "_.*") |
289 |
- if iuse_grep: |
290 |
- iuse_grep = "^(%s)$" % "|".join(sorted(iuse_grep)) |
291 |
- else: |
292 |
- iuse_grep = "" |
293 |
- self.configdict["pkg"]["PORTAGE_IUSE"] = iuse_grep |
294 |
- |
295 |
ebuild_force_test = self.get("EBUILD_FORCE_TEST") == "1" |
296 |
if ebuild_force_test and ebuild_phase and \ |
297 |
not hasattr(self, "_ebuild_force_test_msg_shown"): |
298 |
@@ -2193,6 +2150,42 @@ |
299 |
x for x in use if \ |
300 |
x in iuse_implicit)) |
301 |
|
302 |
+ def _get_implicit_iuse(self): |
303 |
+ """ |
304 |
+ Some flags are considered to |
305 |
+ be implicit members of IUSE: |
306 |
+ * Flags derived from ARCH |
307 |
+ * Flags derived from USE_EXPAND_HIDDEN variables |
308 |
+ * Masked flags, such as those from {,package}use.mask |
309 |
+ * Forced flags, such as those from {,package}use.force |
310 |
+ * build and bootstrap flags used by bootstrap.sh |
311 |
+ """ |
312 |
+ iuse_implicit = set() |
313 |
+ # Flags derived from ARCH. |
314 |
+ arch = self.configdict["defaults"].get("ARCH") |
315 |
+ if arch: |
316 |
+ iuse_implicit.add(arch) |
317 |
+ iuse_implicit.update(self.get("PORTAGE_ARCHLIST", "").split()) |
318 |
+ |
319 |
+ # Flags derived from USE_EXPAND_HIDDEN variables |
320 |
+ # such as ELIBC, KERNEL, and USERLAND. |
321 |
+ use_expand_hidden = self.get("USE_EXPAND_HIDDEN", "").split() |
322 |
+ for x in use_expand_hidden: |
323 |
+ iuse_implicit.add(x.lower() + "_.*") |
324 |
+ |
325 |
+ # Flags that have been masked or forced. |
326 |
+ iuse_implicit.update(self.usemask) |
327 |
+ iuse_implicit.update(self.useforce) |
328 |
+ |
329 |
+ # build and bootstrap flags used by bootstrap.sh |
330 |
+ iuse_implicit.add("build") |
331 |
+ iuse_implicit.add("bootstrap") |
332 |
+ |
333 |
+ # prefix flag is used in Prefix |
334 |
+ iuse_implicit.add("prefix") |
335 |
+ |
336 |
+ return iuse_implicit |
337 |
+ |
338 |
def getMaskAtom(self, cpv, metadata): |
339 |
""" |
340 |
Take a package and return a matching package.mask atom, or None if no |
341 |
@@ -5775,8 +5768,8 @@ |
342 |
myindex = orig_dep.index(mydep) |
343 |
prefix = orig_dep[:myindex] |
344 |
postfix = orig_dep[myindex+len(mydep):] |
345 |
- return prefix + cpv_expand( |
346 |
- mydep, mydb=mydb, use_cache=use_cache, settings=settings) + postfix |
347 |
+ return portage.dep.Atom(prefix + cpv_expand( |
348 |
+ mydep, mydb=mydb, use_cache=use_cache, settings=settings) + postfix) |
349 |
|
350 |
def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, myuse=None, |
351 |
use_cache=1, use_binaries=0, myroot="/", trees=None): |
352 |
|
353 |
Modified: main/branches/prefix/pym/portage/dbapi/__init__.py |
354 |
=================================================================== |
355 |
--- main/branches/prefix/pym/portage/dbapi/__init__.py 2008-05-25 09:01:18 UTC (rev 10416) |
356 |
+++ main/branches/prefix/pym/portage/dbapi/__init__.py 2008-05-25 17:51:33 UTC (rev 10417) |
357 |
@@ -4,7 +4,8 @@ |
358 |
|
359 |
import os |
360 |
import re |
361 |
-from portage.dep import dep_getslot, dep_getkey, match_from_list |
362 |
+from portage.dep import Atom, dep_getslot, dep_getkey, \ |
363 |
+ dep_getusedeps, match_from_list |
364 |
from portage.locks import unlockfile |
365 |
from portage.output import red |
366 |
from portage.util import writemsg |
367 |
@@ -16,6 +17,8 @@ |
368 |
_category_re = re.compile(r'^\w[-.+\w]*$') |
369 |
_pkg_dir_name_re = re.compile(r'^\w[-+\w]*$') |
370 |
_categories = None |
371 |
+ _iuse_implicit = None |
372 |
+ _use_mutable = False |
373 |
_known_keys = frozenset(x for x in auxdbkeys |
374 |
if not x.startswith("UNUSED_0")) |
375 |
def __init__(self): |
376 |
@@ -119,14 +122,49 @@ |
377 |
a list of packages that match origdep |
378 |
""" |
379 |
mydep = dep_expand(origdep, mydb=self, settings=self.settings) |
380 |
- mykey = dep_getkey(mydep) |
381 |
- mylist = match_from_list(mydep, self.cp_list(mykey, use_cache=use_cache)) |
382 |
- myslot = dep_getslot(mydep) |
383 |
- if myslot is not None: |
384 |
- mylist = [cpv for cpv in mylist \ |
385 |
- if self.aux_get(cpv, ["SLOT"])[0] == myslot] |
386 |
- return mylist |
387 |
+ return list(self._iter_match(mydep, |
388 |
+ self.cp_list(mydep.cp, use_cache=use_cache))) |
389 |
|
390 |
+ def _iter_match(self, atom, cpv_iter): |
391 |
+ cpv_iter = match_from_list(atom, cpv_iter) |
392 |
+ if atom.slot: |
393 |
+ cpv_iter = self._iter_match_slot(atom, cpv_iter) |
394 |
+ if atom.use: |
395 |
+ cpv_iter = self._iter_match_use(atom, cpv_iter) |
396 |
+ return cpv_iter |
397 |
+ |
398 |
+ def _iter_match_slot(self, atom, cpv_iter): |
399 |
+ for cpv in cpv_iter: |
400 |
+ if self.aux_get(cpv, ["SLOT"])[0] == atom.slot: |
401 |
+ yield cpv |
402 |
+ |
403 |
+ def _iter_match_use(self, atom, cpv_iter): |
404 |
+ """ |
405 |
+ 1) Check for required IUSE intersection (need implicit IUSE here). |
406 |
+ 2) Check enabled/disabled flag states. |
407 |
+ """ |
408 |
+ if self._iuse_implicit is None: |
409 |
+ self._iuse_implicit = self.settings._get_implicit_iuse() |
410 |
+ for cpv in cpv_iter: |
411 |
+ iuse, use = self.aux_get(cpv, ["IUSE", "USE"]) |
412 |
+ use = use.split() |
413 |
+ iuse = self._iuse_implicit.union( |
414 |
+ x.lstrip("+-") for x in iuse.split()) |
415 |
+ iuse_re = re.compile("^(%s)$" % "|".join(iuse)) |
416 |
+ missing_iuse = False |
417 |
+ for x in atom.use.required: |
418 |
+ if iuse_re.match(x) is None: |
419 |
+ missing_iuse = True |
420 |
+ break |
421 |
+ if missing_iuse: |
422 |
+ continue |
423 |
+ if not self._use_mutable: |
424 |
+ if atom.use.enabled.difference(use): |
425 |
+ continue |
426 |
+ if atom.use.disabled.intersection(use): |
427 |
+ continue |
428 |
+ yield cpv |
429 |
+ |
430 |
def invalidentry(self, mypath): |
431 |
if mypath.endswith('portage_lockfile'): |
432 |
if not os.environ.has_key("PORTAGE_MASTER_PID"): |
433 |
|
434 |
Modified: main/branches/prefix/pym/portage/dbapi/porttree.py |
435 |
=================================================================== |
436 |
--- main/branches/prefix/pym/portage/dbapi/porttree.py 2008-05-25 09:01:18 UTC (rev 10416) |
437 |
+++ main/branches/prefix/pym/portage/dbapi/porttree.py 2008-05-25 17:51:33 UTC (rev 10417) |
438 |
@@ -27,6 +27,7 @@ |
439 |
class portdbapi(dbapi): |
440 |
"""this tree will scan a portage directory located at root (passed to init)""" |
441 |
portdbapi_instances = [] |
442 |
+ _use_mutable = True |
443 |
def __init__(self, porttree_root, mysettings=None): |
444 |
portdbapi.portdbapi_instances.append(self) |
445 |
|
446 |
@@ -36,6 +37,7 @@ |
447 |
else: |
448 |
from portage import settings |
449 |
self.mysettings = config(clone=settings) |
450 |
+ self._iuse_implicit = self.mysettings._get_implicit_iuse() |
451 |
self._categories = set(self.mysettings.categories) |
452 |
# This is strictly for use in aux_get() doebuild calls when metadata |
453 |
# is generated by the depend phase. It's safest to use a clone for |
454 |
@@ -615,22 +617,14 @@ |
455 |
# Find the minimum matching version. This is optimized to |
456 |
# minimize the number of metadata accesses (improves performance |
457 |
# especially in cases where metadata needs to be generated). |
458 |
- if mydep == mykey: |
459 |
- mylist = self.cp_list(mykey) |
460 |
- else: |
461 |
- mylist = match_from_list(mydep, self.cp_list(mykey)) |
462 |
+ cpv_iter = iter(self.cp_list(mykey)) |
463 |
+ if mydep != mykey: |
464 |
+ cpv_iter = self._iter_match(mydep, cpv_iter) |
465 |
myval = "" |
466 |
- if mylist: |
467 |
- if myslot is None: |
468 |
- myval = mylist[0] |
469 |
- else: |
470 |
- for cpv in mylist: |
471 |
- try: |
472 |
- if self.aux_get(cpv, ["SLOT"])[0] == myslot: |
473 |
- myval = cpv |
474 |
- break |
475 |
- except KeyError: |
476 |
- pass # ebuild masked by corruption |
477 |
+ for cpv in cpv_iter: |
478 |
+ myval = cpv |
479 |
+ break |
480 |
+ |
481 |
elif level in ("minimum-visible", "bestmatch-visible"): |
482 |
# Find the minimum matching visible version. This is optimized to |
483 |
# minimize the number of metadata accesses (improves performance |
484 |
@@ -674,29 +668,35 @@ |
485 |
continue |
486 |
except InvalidDependString: |
487 |
continue |
488 |
+ if mydep.use: |
489 |
+ has_iuse = False |
490 |
+ for has_iuse in self._iter_match_use(mydep, [cpv]): |
491 |
+ break |
492 |
+ if not has_iuse: |
493 |
+ continue |
494 |
myval = cpv |
495 |
break |
496 |
elif level == "bestmatch-list": |
497 |
#dep match -- find best match but restrict search to sublist |
498 |
#no point in calling xmatch again since we're not caching list deps |
499 |
|
500 |
- myval = best(match_from_list(mydep, mylist)) |
501 |
+ myval = best(list(self._iter_match(mydep, mylist))) |
502 |
elif level == "match-list": |
503 |
#dep match -- find all matches but restrict search to sublist (used in 2nd half of visible()) |
504 |
|
505 |
- myval = match_from_list(mydep, mylist) |
506 |
+ myval = list(self._iter_match(mydep, mylist)) |
507 |
elif level == "match-visible": |
508 |
#dep match -- find all visible matches |
509 |
#get all visible packages, then get the matching ones |
510 |
|
511 |
- myval = match_from_list(mydep, |
512 |
- self.xmatch("list-visible", mykey, mydep=mykey, mykey=mykey)) |
513 |
+ myval = list(self._iter_match(mydep, |
514 |
+ self.xmatch("list-visible", mykey, mydep=mykey, mykey=mykey))) |
515 |
elif level == "match-all": |
516 |
#match *all* visible *and* masked packages |
517 |
if mydep == mykey: |
518 |
myval = self.cp_list(mykey) |
519 |
else: |
520 |
- myval = match_from_list(mydep, self.cp_list(mykey)) |
521 |
+ myval = list(self._iter_match(mydep, self.cp_list(mykey))) |
522 |
else: |
523 |
print "ERROR: xmatch doesn't handle", level, "query!" |
524 |
raise KeyError |
525 |
|
526 |
Modified: main/branches/prefix/pym/portage/dbapi/vartree.py |
527 |
=================================================================== |
528 |
--- main/branches/prefix/pym/portage/dbapi/vartree.py 2008-05-25 09:01:18 UTC (rev 10416) |
529 |
+++ main/branches/prefix/pym/portage/dbapi/vartree.py 2008-05-25 17:51:33 UTC (rev 10417) |
530 |
@@ -136,7 +136,7 @@ |
531 |
libs = {} |
532 |
obj_properties = {} |
533 |
lines = [] |
534 |
- for cpv in self._dbapi.cpv_all(): |
535 |
+ for cpv in self._dbapi.cpv_all(use_cache=0): |
536 |
lines += self._dbapi.aux_get(cpv, ["NEEDED.ELF.2"])[0].split('\n') |
537 |
# Cache NEEDED.* files avoid doing excessive IO for every rebuild. |
538 |
self._dbapi.flush_cache() |
539 |
@@ -558,8 +558,25 @@ |
540 |
return returnme |
541 |
|
542 |
def cpv_all(self, use_cache=1): |
543 |
+ """ |
544 |
+ Set use_cache=0 to bypass the portage.cachedir() cache in cases |
545 |
+ when the accuracy of mtime staleness checks should not be trusted |
546 |
+ (generally this is only necessary in critical sections that |
547 |
+ involve merge or unmerge of packages). |
548 |
+ """ |
549 |
returnme = [] |
550 |
basepath = os.path.join(self.root, VDB_PATH) + os.path.sep |
551 |
+ |
552 |
+ if use_cache: |
553 |
+ from portage import listdir |
554 |
+ else: |
555 |
+ def listdir(p, **kwargs): |
556 |
+ try: |
557 |
+ return [x for x in os.listdir(p) \ |
558 |
+ if os.path.isdir(os.path.join(p, x))] |
559 |
+ except EnvironmentError: |
560 |
+ return [] |
561 |
+ |
562 |
for x in listdir(basepath, EmptyOnError=1, ignorecvs=1, dirsonly=1): |
563 |
if self._excluded_dirs.match(x) is not None: |
564 |
continue |
565 |
@@ -610,13 +627,8 @@ |
566 |
if self.matchcache.has_key(mycat): |
567 |
del self.mtdircache[mycat] |
568 |
del self.matchcache[mycat] |
569 |
- mymatch = match_from_list(mydep, |
570 |
- self.cp_list(mykey, use_cache=use_cache)) |
571 |
- myslot = dep_getslot(mydep) |
572 |
- if myslot is not None: |
573 |
- mymatch = [cpv for cpv in mymatch \ |
574 |
- if self.aux_get(cpv, ["SLOT"])[0] == myslot] |
575 |
- return mymatch |
576 |
+ return list(self._iter_match(mydep, |
577 |
+ self.cp_list(mydep.cp, use_cache=use_cache))) |
578 |
try: |
579 |
curmtime = os.stat(self.root+VDB_PATH+"/"+mycat)[stat.ST_MTIME] |
580 |
except (IOError, OSError): |
581 |
@@ -627,11 +639,8 @@ |
582 |
self.mtdircache[mycat] = curmtime |
583 |
self.matchcache[mycat] = {} |
584 |
if not self.matchcache[mycat].has_key(mydep): |
585 |
- mymatch = match_from_list(mydep, self.cp_list(mykey, use_cache=use_cache)) |
586 |
- myslot = dep_getslot(mydep) |
587 |
- if myslot is not None: |
588 |
- mymatch = [cpv for cpv in mymatch \ |
589 |
- if self.aux_get(cpv, ["SLOT"])[0] == myslot] |
590 |
+ mymatch = list(self._iter_match(mydep, |
591 |
+ self.cp_list(mydep.cp, use_cache=use_cache))) |
592 |
self.matchcache[mycat][mydep] = mymatch |
593 |
return self.matchcache[mycat][mydep][:] |
594 |
|
595 |
@@ -1893,7 +1902,9 @@ |
596 |
# inject files that should be preserved into our image dir |
597 |
import shutil |
598 |
missing_paths = [] |
599 |
- for x in candidates: |
600 |
+ candidates_stack = list(candidates) |
601 |
+ while candidates_stack: |
602 |
+ x = candidates_stack.pop() |
603 |
# skip existing files so the 'new' libs aren't overwritten |
604 |
if os.path.exists(os.path.join(srcroot, x.lstrip(os.sep))): |
605 |
missing_paths.append(x) |
606 |
@@ -1916,6 +1927,7 @@ |
607 |
if linktarget[0] != os.sep: |
608 |
linktarget = os.path.join(os.path.dirname(x), linktarget) |
609 |
candidates.add(linktarget) |
610 |
+ candidates_stack.append(linktarget) |
611 |
else: |
612 |
shutil.copy2(os.path.join(destroot, x.lstrip(os.sep)), |
613 |
os.path.join(srcroot, x.lstrip(os.sep))) |
614 |
|
615 |
Modified: main/branches/prefix/pym/portage/dep.py |
616 |
=================================================================== |
617 |
--- main/branches/prefix/pym/portage/dep.py 2008-05-25 09:01:18 UTC (rev 10416) |
618 |
+++ main/branches/prefix/pym/portage/dep.py 2008-05-25 17:51:33 UTC (rev 10417) |
619 |
@@ -108,13 +108,20 @@ |
620 |
"missing right parenthesis: '%s'" % mystr) |
621 |
elif has_left_paren and left_paren < right_paren: |
622 |
freesec,subsec = mystr.split("(",1) |
623 |
- subsec,tail = paren_reduce(subsec,tokenize) |
624 |
+ sublist = paren_reduce(subsec, tokenize=tokenize) |
625 |
+ if len(sublist) != 2: |
626 |
+ raise portage.exception.InvalidDependString( |
627 |
+ "malformed syntax: '%s'" % mystr) |
628 |
+ subsec, tail = sublist |
629 |
else: |
630 |
subsec,tail = mystr.split(")",1) |
631 |
if tokenize: |
632 |
subsec = strip_empty(subsec.split(" ")) |
633 |
return [mylist+subsec,tail] |
634 |
return mylist+[subsec],tail |
635 |
+ if not isinstance(tail, basestring): |
636 |
+ raise portage.exception.InvalidDependString( |
637 |
+ "malformed syntax: '%s'" % mystr) |
638 |
mystr = tail |
639 |
if freesec: |
640 |
if tokenize: |
641 |
@@ -230,7 +237,7 @@ |
642 |
rlist.append([]) |
643 |
|
644 |
else: |
645 |
- if head[-1] == "?": # Use reduce next group on fail. |
646 |
+ if head[-1:] == "?": # Use reduce next group on fail. |
647 |
# Pull any other use conditions and the following atom or list into a separate array |
648 |
newdeparray = [head] |
649 |
while isinstance(newdeparray[-1], str) and newdeparray[-1][-1] == "?": |
650 |
@@ -329,6 +336,37 @@ |
651 |
x += 1 |
652 |
return retlist |
653 |
|
654 |
+class _use_dep(object): |
655 |
+ def __init__(self, use): |
656 |
+ enabled_flags = [] |
657 |
+ disabled_flags = [] |
658 |
+ for x in use: |
659 |
+ if "-" == x[:1]: |
660 |
+ disabled_flags.append(x[1:]) |
661 |
+ else: |
662 |
+ enabled_flags.append(x) |
663 |
+ self.enabled = frozenset(enabled_flags) |
664 |
+ self.disabled = frozenset(disabled_flags) |
665 |
+ self.required = self.enabled.union(self.disabled) |
666 |
+ |
667 |
+class Atom(str): |
668 |
+ |
669 |
+ def __init__(self, s): |
670 |
+ str.__init__(self, s) |
671 |
+ if not isvalidatom(s, allow_blockers=True): |
672 |
+ raise InvalidAtom(s) |
673 |
+ self.blocker = "!" == s[:1] |
674 |
+ if self.blocker: |
675 |
+ s = s[1:] |
676 |
+ self.cp = dep_getkey(s) |
677 |
+ self.cpv = dep_getcpv(s) |
678 |
+ self.slot = dep_getslot(s) |
679 |
+ self.operator = get_operator(s) |
680 |
+ #self.repo = self._get_repo(s) |
681 |
+ self.use = dep_getusedeps(s) |
682 |
+ if self.use: |
683 |
+ self.use = _use_dep(self.use) |
684 |
+ |
685 |
def get_operator(mydep): |
686 |
""" |
687 |
Return the operator used in a depstring. |
688 |
@@ -344,6 +382,9 @@ |
689 |
@return: The operator. One of: |
690 |
'~', '=', '>', '<', '=*', '>=', or '<=' |
691 |
""" |
692 |
+ operator = getattr(mydep, "operator", None) |
693 |
+ if operator is not None: |
694 |
+ return operator |
695 |
if mydep: |
696 |
mydep = remove_slot(mydep) |
697 |
if not mydep: |
698 |
@@ -380,6 +421,9 @@ |
699 |
@rtype: String |
700 |
@return: The depstring with the operator removed |
701 |
""" |
702 |
+ cpv = getattr(mydep, "cpv", None) |
703 |
+ if cpv is not None: |
704 |
+ return cpv |
705 |
global _dep_getcpv_cache |
706 |
retval = _dep_getcpv_cache.get(mydep, None) |
707 |
if retval is not None: |
708 |
@@ -413,15 +457,32 @@ |
709 |
@rtype: String |
710 |
@return: The slot |
711 |
""" |
712 |
- colon = mydep.rfind(":") |
713 |
+ slot = getattr(mydep, "slot", None) |
714 |
+ if slot is not None: |
715 |
+ return slot |
716 |
+ colon = mydep.find(":") |
717 |
if colon != -1: |
718 |
- return mydep[colon+1:] |
719 |
+ bracket = mydep.find("[", colon) |
720 |
+ if bracket == -1: |
721 |
+ return mydep[colon+1:] |
722 |
+ else: |
723 |
+ return mydep[colon+1:bracket] |
724 |
return None |
725 |
|
726 |
def remove_slot(mydep): |
727 |
- colon = mydep.rfind(":") |
728 |
+ """ |
729 |
+ Removes dep components from the right side of an atom: |
730 |
+ * slot |
731 |
+ * use |
732 |
+ * repo |
733 |
+ """ |
734 |
+ colon = mydep.find(":") |
735 |
if colon != -1: |
736 |
mydep = mydep[:colon] |
737 |
+ else: |
738 |
+ bracket = mydep.find("[") |
739 |
+ if bracket != -1: |
740 |
+ mydep = mydep[:bracket] |
741 |
return mydep |
742 |
|
743 |
def dep_getusedeps( depend ): |
744 |
@@ -437,6 +498,9 @@ |
745 |
@rtype: List |
746 |
@return: List of use flags ( or [] if no flags exist ) |
747 |
""" |
748 |
+ use = getattr(depend, "use", None) |
749 |
+ if use is not None: |
750 |
+ return use |
751 |
use_list = [] |
752 |
open_bracket = depend.find('[') |
753 |
# -1 = failure (think c++ string::npos) |
754 |
@@ -452,7 +516,7 @@ |
755 |
raise InvalidAtom("USE Dependency with no use flag ([]): %s" % depend ) |
756 |
# Find next use flag |
757 |
open_bracket = depend.find( '[', open_bracket+1 ) |
758 |
- return use_list |
759 |
+ return tuple(use_list) |
760 |
|
761 |
_invalid_atom_chars_regexp = re.compile("[()|?@]") |
762 |
|
763 |
@@ -473,6 +537,10 @@ |
764 |
1) 0 if the atom is invalid |
765 |
2) 1 if the atom is valid |
766 |
""" |
767 |
+ if isinstance(atom, Atom): |
768 |
+ if atom.blocker and not allow_blockers: |
769 |
+ return 0 |
770 |
+ return 1 |
771 |
global _invalid_atom_chars_regexp |
772 |
if _invalid_atom_chars_regexp.search(atom): |
773 |
return 0 |
774 |
@@ -571,6 +639,9 @@ |
775 |
@rtype: String |
776 |
@return: The package category/package-version |
777 |
""" |
778 |
+ cp = getattr(mydep, "cp", None) |
779 |
+ if cp is not None: |
780 |
+ return cp |
781 |
mydep = dep_getcpv(mydep) |
782 |
if mydep and isspecific(mydep): |
783 |
mysplit = catpkgsplit(mydep) |
784 |
@@ -646,8 +717,10 @@ |
785 |
""" |
786 |
|
787 |
from portage.util import writemsg |
788 |
- if mydep[0] == "!": |
789 |
+ if "!" == mydep[:1]: |
790 |
mydep = mydep[1:] |
791 |
+ if not isinstance(mydep, Atom): |
792 |
+ mydep = Atom(mydep) |
793 |
|
794 |
mycpv = dep_getcpv(mydep) |
795 |
mycpv_cps = catpkgsplit(mycpv) # Can be None if not specific |
796 |
|
797 |
Modified: main/branches/prefix/pym/portage/sets/files.py |
798 |
=================================================================== |
799 |
--- main/branches/prefix/pym/portage/sets/files.py 2008-05-25 09:01:18 UTC (rev 10416) |
800 |
+++ main/branches/prefix/pym/portage/sets/files.py 2008-05-25 17:51:33 UTC (rev 10417) |
801 |
@@ -100,7 +100,10 @@ |
802 |
# look for repository path variables |
803 |
match = self._repopath_match.match(filename) |
804 |
if match: |
805 |
- filename = self._repopath_sub.sub(trees["porttree"].dbapi.treemap[match.groupdict()["reponame"]], filename) |
806 |
+ try: |
807 |
+ filename = self._repopath_sub.sub(trees["porttree"].dbapi.treemap[match.groupdict()["reponame"]], filename) |
808 |
+ except KeyError: |
809 |
+ raise SetConfigError("Could not find repository '%s'" % match.groupdict()["reponame"]) |
810 |
return StaticFileSet(filename, greedy=greedy, dbapi=trees["vartree"].dbapi) |
811 |
singleBuilder = classmethod(singleBuilder) |
812 |
|
813 |
@@ -114,7 +117,10 @@ |
814 |
# look for repository path variables |
815 |
match = self._repopath_match.match(directory) |
816 |
if match: |
817 |
- directory = self._repopath_sub.sub(trees["porttree"].dbapi.treemap[match.groupdict()["reponame"]], directory) |
818 |
+ try: |
819 |
+ directory = self._repopath_sub.sub(trees["porttree"].dbapi.treemap[match.groupdict()["reponame"]], directory) |
820 |
+ except KeyError: |
821 |
+ raise SetConfigError("Could not find repository '%s'" % match.groupdict()["reponame"]) |
822 |
if os.path.isdir(directory): |
823 |
for filename in os.listdir(directory): |
824 |
if filename.endswith(".metadata"): |
825 |
|
826 |
-- |
827 |
gentoo-commits@l.g.o mailing list |