1 |
Author: grobian |
2 |
Date: 2008-11-22 11:34:13 +0000 (Sat, 22 Nov 2008) |
3 |
New Revision: 12038 |
4 |
|
5 |
Modified: |
6 |
main/branches/prefix/pym/_emerge/__init__.py |
7 |
main/branches/prefix/pym/portage/__init__.py |
8 |
main/branches/prefix/pym/portage/cache/metadata.py |
9 |
main/branches/prefix/pym/portage/cache/sqlite.py |
10 |
Log: |
11 |
Merged from trunk -r12004:12020 |
12 |
|
13 |
| 12006 | Bug #247370 - Use a private PORTAGE_TMPDIR for --fetchonly | |
14 |
| zmedico | mode in order do avoid locking the normal build dir location | |
15 |
| | (similar to bug #245231). The EbuildFetchPretend class is | |
16 |
| | renamed to EbuildFetchonly and it's used for --fetchonly | |
17 |
| | mode regardless of whether --pretend is enabled. Also, fix | |
18 |
| | stdout/stderr flushing in JobStatusDisplay.displayMessage() | |
19 |
| | and portage.spawn() to ensure output always occurs in the | |
20 |
| | correct order when displaying pkg_nofetch() output in | |
21 |
| | --fetchonly mode. | |
22 |
|
23 |
| 12008 | Inside _parse_data(), don't rely on the magic 22 line count | |
24 |
| zmedico | for the flat_list format, since it doesn't make a | |
25 |
| | significant performance difference and it places an | |
26 |
| | artificial limit on the number of keys that can be stored. | |
27 |
|
28 |
| 12010 | Remove inappropriate backslash escaping inside | |
29 |
| zmedico | _db_escape_string(). | |
30 |
|
31 |
| 12012 | When given an ambiguous ebuild name to install, format the | |
32 |
| zmedico | list of choices in emerge --search format if --quiet mode is | |
33 |
| | not enabled, otherwise just show a brief list. Thanks to | |
34 |
| | Markus Meier <maekke@g.o> for the suggestion. | |
35 |
|
36 |
| 12014 | In JobStatusDisplay, always flush the output stream after | |
37 |
| zmedico | writing to it. | |
38 |
|
39 |
| 12016 | In EbuildProcess._start(), don't open the log file during | |
40 |
| zmedico | the clean phase since the open file can result in an nfs | |
41 |
| | lock on $T/build.log which prevents the clean phase from | |
42 |
| | removing $T. Thanks to Jeremy Olexa <darkside@g.o> for | |
43 |
| | reporting. | |
44 |
|
45 |
| 12018 | Bug #248059 - In action_depclean(), ignore invalid atoms in | |
46 |
| zmedico | deps of packages to be uninstalled. | |
47 |
|
48 |
| 12020 | Bug #248059 - Make --depclean more tolerant of invalid atoms | |
49 |
| zmedico | in dependencies of packages that will be uninstalled anyway. | |
50 |
|
51 |
|
52 |
Modified: main/branches/prefix/pym/_emerge/__init__.py |
53 |
=================================================================== |
54 |
--- main/branches/prefix/pym/_emerge/__init__.py 2008-11-22 11:31:14 UTC (rev 12037) |
55 |
+++ main/branches/prefix/pym/_emerge/__init__.py 2008-11-22 11:34:13 UTC (rev 12038) |
56 |
@@ -441,6 +441,8 @@ |
57 |
self.searchdesc = searchdesc |
58 |
self.root_config = root_config |
59 |
self.setconfig = root_config.setconfig |
60 |
+ self.matches = {"pkg" : []} |
61 |
+ self.mlen = 0 |
62 |
|
63 |
def fake_portdb(): |
64 |
pass |
65 |
@@ -557,7 +559,7 @@ |
66 |
if not result or cpv == portage.best([cpv, result]): |
67 |
result = cpv |
68 |
else: |
69 |
- db_keys = list(db._aux_cache_keys) |
70 |
+ db_keys = Package.metadata_keys |
71 |
# break out of this loop with highest visible |
72 |
# match, checked in descending order |
73 |
for cpv in reversed(db.match(atom)): |
74 |
@@ -650,6 +652,15 @@ |
75 |
self.matches[mtype].sort() |
76 |
self.mlen += len(self.matches[mtype]) |
77 |
|
78 |
+ def addCP(self, cp): |
79 |
+ if not self.portdb.xmatch("match-all", cp): |
80 |
+ return |
81 |
+ masked = 0 |
82 |
+ if not self.portdb.xmatch("bestmatch-visible", cp): |
83 |
+ masked = 1 |
84 |
+ self.matches["pkg"].append([cp, masked]) |
85 |
+ self.mlen += 1 |
86 |
+ |
87 |
def output(self): |
88 |
"""Outputs the results of the search.""" |
89 |
print "\b\b \n[ Results for search key : "+white(self.searchkey)+" ]" |
90 |
@@ -744,7 +755,6 @@ |
91 |
print " ", darkgreen("Description:")+" ",desc |
92 |
print " ", darkgreen("License:")+" ",license |
93 |
print |
94 |
- print |
95 |
# |
96 |
# private interface |
97 |
# |
98 |
@@ -1610,9 +1620,9 @@ |
99 |
v = 0 |
100 |
self._pkg.mtime = v |
101 |
|
102 |
-class EbuildFetchPretend(SlotObject): |
103 |
+class EbuildFetchonly(SlotObject): |
104 |
|
105 |
- __slots__ = ("fetch_all", "pkg", "settings") |
106 |
+ __slots__ = ("fetch_all", "pkg", "pretend", "settings") |
107 |
|
108 |
def execute(self): |
109 |
# To spawn pkg_nofetch requires PORTAGE_BUILDDIR for |
110 |
@@ -1648,9 +1658,13 @@ |
111 |
|
112 |
retval = portage.doebuild(ebuild_path, "fetch", |
113 |
self.settings["ROOT"], self.settings, debug=debug, |
114 |
- listonly=1, fetchonly=1, fetchall=self.fetch_all, |
115 |
+ listonly=self.pretend, fetchonly=1, fetchall=self.fetch_all, |
116 |
mydbapi=portdb, tree="porttree") |
117 |
|
118 |
+ if retval != os.EX_OK: |
119 |
+ msg = "Fetch failed for '%s'" % (pkg.cpv,) |
120 |
+ eerror(msg, phase="unpack", key=pkg.cpv) |
121 |
+ |
122 |
portage.elog.elog_process(self.pkg.cpv, self.settings) |
123 |
return retval |
124 |
|
125 |
@@ -2520,10 +2534,11 @@ |
126 |
pkg = self.pkg |
127 |
settings = self.settings |
128 |
|
129 |
- if opts.fetchonly and opts.pretend: |
130 |
- fetcher = EbuildFetchPretend( |
131 |
+ if opts.fetchonly: |
132 |
+ fetcher = EbuildFetchonly( |
133 |
fetch_all=opts.fetch_all_uri, |
134 |
- pkg=pkg, settings=settings) |
135 |
+ pkg=pkg, pretend=opts.pretend, |
136 |
+ settings=settings) |
137 |
retval = fetcher.execute() |
138 |
self.returncode = retval |
139 |
self.wait() |
140 |
@@ -2897,7 +2912,11 @@ |
141 |
__slots__ = ("phase", "pkg", "settings", "tree") |
142 |
|
143 |
def _start(self): |
144 |
- self.logfile = self.settings.get("PORTAGE_LOG_FILE") |
145 |
+ # Don't open the log file during the clean phase since the |
146 |
+ # open file can result in an nfs lock on $T/build.log which |
147 |
+ # prevents the clean phase from removing $T. |
148 |
+ if self.phase not in ("clean", "cleanrm"): |
149 |
+ self.logfile = self.settings.get("PORTAGE_LOG_FILE") |
150 |
SpawnProcess._start(self) |
151 |
|
152 |
def _pipe(self, fd_pipes): |
153 |
@@ -5045,13 +5064,10 @@ |
154 |
if portage.dep_getkey(atom) == installed_cp] |
155 |
|
156 |
if len(expanded_atoms) > 1: |
157 |
- print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous. Please specify" |
158 |
- print "!!! one of the following fully-qualified ebuild names instead:\n" |
159 |
- expanded_atoms = set(portage.dep_getkey(atom) \ |
160 |
- for atom in expanded_atoms) |
161 |
- for i in sorted(expanded_atoms): |
162 |
- print " " + green(i) |
163 |
print |
164 |
+ print |
165 |
+ ambiguous_package_name(x, expanded_atoms, root_config, |
166 |
+ self.spinner, self.myopts) |
167 |
return False, myfavorites |
168 |
if expanded_atoms: |
169 |
atom = expanded_atoms[0] |
170 |
@@ -8930,10 +8946,12 @@ |
171 |
self.out.write( |
172 |
self._term_codes['carriage_return'] + \ |
173 |
self._term_codes['clr_eol']) |
174 |
+ self.out.flush() |
175 |
self._displayed = False |
176 |
|
177 |
def _display(self, line): |
178 |
self.out.write(line) |
179 |
+ self.out.flush() |
180 |
self._displayed = True |
181 |
|
182 |
def _update(self, msg): |
183 |
@@ -8941,6 +8959,7 @@ |
184 |
out = self.out |
185 |
if not self._isatty: |
186 |
out.write(self._format_msg(msg) + self._term_codes['newline']) |
187 |
+ self.out.flush() |
188 |
self._displayed = True |
189 |
return |
190 |
|
191 |
@@ -8957,6 +8976,7 @@ |
192 |
self._erase() |
193 |
|
194 |
self.out.write(self._format_msg(msg) + self._term_codes['newline']) |
195 |
+ self.out.flush() |
196 |
self._displayed = False |
197 |
|
198 |
if was_displayed: |
199 |
@@ -8971,6 +8991,7 @@ |
200 |
|
201 |
if self._displayed: |
202 |
self.out.write(self._term_codes['newline']) |
203 |
+ self.out.flush() |
204 |
self._displayed = False |
205 |
|
206 |
def __setattr__(self, name, value): |
207 |
@@ -12845,15 +12866,17 @@ |
208 |
finally: |
209 |
portage.dep._dep_check_strict = True |
210 |
if not success: |
211 |
- show_invalid_depstring_notice( |
212 |
- ("installed", myroot, node, "nomerge"), |
213 |
- depstr, atoms) |
214 |
- return |
215 |
- |
216 |
+ # Ignore invalid deps of packages that will |
217 |
+ # be uninstalled anyway. |
218 |
+ continue |
219 |
+ |
220 |
priority = priority_map[dep_type] |
221 |
for atom in atoms: |
222 |
- if atom.startswith("!"): |
223 |
+ if not isinstance(atom, portage.dep.Atom): |
224 |
+ # Ignore invalid atoms returned from dep_check(). |
225 |
continue |
226 |
+ if atom.blocker: |
227 |
+ continue |
228 |
matches = vardb.match_pkgs(atom) |
229 |
if not matches: |
230 |
continue |
231 |
@@ -13955,6 +13978,28 @@ |
232 |
|
233 |
return bool(missing_repo_names) |
234 |
|
235 |
+def ambiguous_package_name(arg, atoms, root_config, spinner, myopts): |
236 |
+ |
237 |
+ if "--quiet" in myopts: |
238 |
+ print "!!! The short ebuild name \"%s\" is ambiguous. Please specify" % arg |
239 |
+ print "!!! one of the following fully-qualified ebuild names instead:\n" |
240 |
+ for cp in sorted(set(portage.dep_getkey(atom) for atom in atoms)): |
241 |
+ print " " + colorize("INFORM", cp) |
242 |
+ return |
243 |
+ |
244 |
+ s = search(root_config, spinner, "--searchdesc" in myopts, |
245 |
+ "--quiet" not in myopts, "--usepkg" in myopts, |
246 |
+ "--usepkgonly" in myopts) |
247 |
+ null_cp = portage.dep_getkey(insert_category_into_atom( |
248 |
+ arg, "null")) |
249 |
+ cat, atom_pn = portage.catsplit(null_cp) |
250 |
+ s.searchkey = atom_pn |
251 |
+ for cp in sorted(set(portage.dep_getkey(atom) for atom in atoms)): |
252 |
+ s.addCP(cp) |
253 |
+ s.output() |
254 |
+ print "!!! The short ebuild name \"%s\" is ambiguous. Please specify" % arg |
255 |
+ print "!!! one of the above fully-qualified ebuild names instead.\n" |
256 |
+ |
257 |
def emerge_main(): |
258 |
global portage # NFC why this is necessary now - genone |
259 |
portage._disable_legacy_globals() |
260 |
|
261 |
Modified: main/branches/prefix/pym/portage/__init__.py |
262 |
=================================================================== |
263 |
--- main/branches/prefix/pym/portage/__init__.py 2008-11-22 11:31:14 UTC (rev 12037) |
264 |
+++ main/branches/prefix/pym/portage/__init__.py 2008-11-22 11:34:13 UTC (rev 12038) |
265 |
@@ -3076,11 +3076,12 @@ |
266 |
# In some cases the above print statements don't flush stdout, so |
267 |
# it needs to be flushed before allowing a child process to use it |
268 |
# so that output always shows in the correct order. |
269 |
+ stdout_filenos = (sys.stdout.fileno(), sys.stderr.fileno()) |
270 |
for fd in fd_pipes.itervalues(): |
271 |
- if fd == sys.stdout.fileno(): |
272 |
+ if fd in stdout_filenos: |
273 |
sys.stdout.flush() |
274 |
- if fd == sys.stderr.fileno(): |
275 |
sys.stderr.flush() |
276 |
+ break |
277 |
|
278 |
# The default policy for the sesandbox domain only allows entry (via exec) |
279 |
# from shells and from binaries that belong to portage (the number of entry |
280 |
@@ -6661,8 +6662,16 @@ |
281 |
writemsg("mysplit: %s\n" % (mysplit), 1) |
282 |
writemsg("mysplit2: %s\n" % (mysplit2), 1) |
283 |
|
284 |
- myzaps = dep_zapdeps(mysplit, mysplit2, myroot, |
285 |
- use_binaries=use_binaries, trees=trees) |
286 |
+ try: |
287 |
+ myzaps = dep_zapdeps(mysplit, mysplit2, myroot, |
288 |
+ use_binaries=use_binaries, trees=trees) |
289 |
+ except portage.exception.InvalidAtom, e: |
290 |
+ if portage.dep._dep_check_strict: |
291 |
+ raise # This shouldn't happen. |
292 |
+ # dbapi.match() failed due to an invalid atom in |
293 |
+ # the dependencies of an installed package. |
294 |
+ return [0, "Invalid atom: '%s'" % (e,)] |
295 |
+ |
296 |
mylist = flatten(myzaps) |
297 |
writemsg("myzaps: %s\n" % (myzaps), 1) |
298 |
writemsg("mylist: %s\n" % (mylist), 1) |
299 |
|
300 |
Modified: main/branches/prefix/pym/portage/cache/metadata.py |
301 |
=================================================================== |
302 |
--- main/branches/prefix/pym/portage/cache/metadata.py 2008-11-22 11:31:14 UTC (rev 12037) |
303 |
+++ main/branches/prefix/pym/portage/cache/metadata.py 2008-11-22 11:34:13 UTC (rev 12038) |
304 |
@@ -3,7 +3,7 @@ |
305 |
# License: GPL2 |
306 |
# $Id$ |
307 |
|
308 |
-import os, stat |
309 |
+import os, re, stat, types |
310 |
from portage.cache import flat_hash |
311 |
import portage.eclass_cache |
312 |
from portage.cache.template import reconstruct_eclasses |
313 |
@@ -22,6 +22,8 @@ |
314 |
|
315 |
autocommits = True |
316 |
|
317 |
+ _hashed_re = re.compile('^(\\w+)=([^\n]*)') |
318 |
+ |
319 |
def __init__(self, location, *args, **config): |
320 |
loc = location |
321 |
super(database, self).__init__(location, *args, **config) |
322 |
@@ -33,35 +35,24 @@ |
323 |
|
324 |
|
325 |
def _parse_data(self, data, cpv): |
326 |
- # easy attempt first. |
327 |
+ _hashed_re_match = self._hashed_re.match |
328 |
data = list(data) |
329 |
- if len(data) != magic_line_count: |
330 |
- d = flat_hash.database._parse_data(self, data, cpv) |
331 |
- else: |
332 |
- # this one's interesting. |
333 |
- d = {} |
334 |
+ d = {} |
335 |
|
336 |
- for line in data: |
337 |
- # yes, meant to iterate over a string. |
338 |
- hashed = False |
339 |
- # poor mans enumerate. replace when python 2.3 is required |
340 |
- for idx, c in zip(range(len(line)), line): |
341 |
- if not c.isalpha(): |
342 |
- if c == "=" and idx > 0: |
343 |
- hashed = True |
344 |
- d[line[:idx]] = line[idx + 1:].rstrip("\n") |
345 |
- elif c == "_" or c.isdigit(): |
346 |
- continue |
347 |
- break |
348 |
+ for line in data: |
349 |
+ hashed = False |
350 |
+ hashed_match = _hashed_re_match(line) |
351 |
+ if hashed_match is None: |
352 |
+ d.clear() |
353 |
+ try: |
354 |
+ for i, key in enumerate(self.auxdbkey_order): |
355 |
+ d[key] = data[i].rstrip("\n") |
356 |
+ except IndexError: |
357 |
+ pass |
358 |
+ break |
359 |
+ else: |
360 |
+ d[hashed_match.group(1)] = hashed_match.group(2) |
361 |
|
362 |
- if not hashed: |
363 |
- # non hashed. |
364 |
- d.clear() |
365 |
- # poor mans enumerate. replace when python 2.3 is required |
366 |
- for idx, key in zip(range(len(self.auxdbkey_order)), self.auxdbkey_order): |
367 |
- d[key] = data[idx].strip() |
368 |
- break |
369 |
- |
370 |
if "_eclasses_" not in d: |
371 |
if "INHERITED" in d: |
372 |
d["_eclasses_"] = self.ec.get_eclass_data(d["INHERITED"].split(), from_master_only=True) |
373 |
|
374 |
Modified: main/branches/prefix/pym/portage/cache/sqlite.py |
375 |
=================================================================== |
376 |
--- main/branches/prefix/pym/portage/cache/sqlite.py 2008-11-22 11:31:14 UTC (rev 12037) |
377 |
+++ main/branches/prefix/pym/portage/cache/sqlite.py 2008-11-22 11:34:13 UTC (rev 12038) |
378 |
@@ -46,7 +46,8 @@ |
379 |
|
380 |
def _db_escape_string(self, s): |
381 |
"""meta escaping, returns quoted string for use in sql statements""" |
382 |
- return "'%s'" % str(s).replace("\\","\\\\").replace("'","''") |
383 |
+ # This is equivalent to the _quote function from pysqlite 1.1. |
384 |
+ return "'%s'" % str(s).replace("'","''") |
385 |
|
386 |
def _db_init_connection(self, config): |
387 |
self._dbpath = self.location + ".sqlite" |