1 |
Author: grobian |
2 |
Date: 2009-10-28 18:36:02 +0000 (Wed, 28 Oct 2009) |
3 |
New Revision: 14743 |
4 |
|
5 |
Modified: |
6 |
main/branches/prefix/bin/ebuild.sh |
7 |
main/branches/prefix/bin/repoman |
8 |
main/branches/prefix/man/emerge.1 |
9 |
main/branches/prefix/pym/_emerge/JobStatusDisplay.py |
10 |
main/branches/prefix/pym/_emerge/help.py |
11 |
main/branches/prefix/pym/_emerge/main.py |
12 |
main/branches/prefix/pym/portage/__init__.py |
13 |
main/branches/prefix/pym/portage/dbapi/vartree.py |
14 |
main/branches/prefix/pym/portage/elog/messages.py |
15 |
main/branches/prefix/pym/portage/output.py |
16 |
main/branches/prefix/pym/portage/util.py |
17 |
Log: |
18 |
Merged from trunk -r14724:14735 |
19 |
|
20 |
| 14725 | Don't set mtime on downloaded metadata.dtd when using | |
21 |
| zmedico | python3, since the rfc822.parsedate() function is not | |
22 |
| | available. Thanks to Arfrever for reporting. | |
23 |
|
24 |
| 14728 | Use calendar.timegm instead of time.mktime, for correct | |
25 |
| zmedico | timezone handling. | |
26 |
|
27 |
| 14729 | Add a parsedate() function which emulates | |
28 |
| zmedico | rfc822.parsedate(), since python3 doesn't have it. | |
29 |
|
30 |
| 14730 | Add -R as a shortcut for --depclean. Thanks to Jonathan | |
31 |
| zmedico | Callen <abcd@g.o> for the suggestion. | |
32 |
|
33 |
| 14731 | Take the -c option and make it mean --depclean instead of | |
34 |
| zmedico | --clean, since --clean is pretty useless anyway. | |
35 |
|
36 |
| 14732 | Add a reference to bug #141118 inside | |
37 |
| zmedico | _expand_new_virtuals(). | |
38 |
|
39 |
| 14733 | Revert the workaround for bug #288863. This will require a | |
40 |
| zmedico | dependency on >=sys-apps/sandbox-2.2. | |
41 |
|
42 |
| 14734 | Bug #290625 - Manually encode output to stdout in python3, | |
43 |
| zmedico | in order to avoid potential UnicodeEncodeError exceptions. | |
44 |
|
45 |
| 14735 | Bug #290428 - Update mtime of /var/db/pkg and category | |
46 |
| zmedico | subdirectories when stuff inside is modified, so that | |
47 |
| | consumers can use directory mtimes to validate caches. | |
48 |
|
49 |
|
50 |
Modified: main/branches/prefix/bin/ebuild.sh |
51 |
=================================================================== |
52 |
--- main/branches/prefix/bin/ebuild.sh 2009-10-27 22:56:07 UTC (rev 14742) |
53 |
+++ main/branches/prefix/bin/ebuild.sh 2009-10-28 18:36:02 UTC (rev 14743) |
54 |
@@ -6,12 +6,6 @@ |
55 |
PORTAGE_BIN_PATH="${PORTAGE_BIN_PATH:-@PORTAGE_BASE@/bin}" |
56 |
PORTAGE_PYM_PATH="${PORTAGE_PYM_PATH:-@PORTAGE_BASE@/pym}" |
57 |
|
58 |
-# Ensure that /dev/std* streams have appropriate sandbox permission for |
59 |
-# bug #288863. This can be removed after sandbox is fixed and portage |
60 |
-# depends on the fixed version. |
61 |
-export SANDBOX_WRITE="${SANDBOX_WRITE:+${SANDBOX_WRITE}:}/dev/stdout:/dev/stderr" |
62 |
-export SANDBOX_READ="${SANDBOX_READ:+${SANDBOX_READ}:}/dev/stdin" |
63 |
- |
64 |
# Don't use sandbox's BASH_ENV for new shells because it does |
65 |
# 'source /etc/profile' which can interfere with the build |
66 |
# environment by modifying our PATH. |
67 |
|
68 |
Modified: main/branches/prefix/bin/repoman |
69 |
=================================================================== |
70 |
--- main/branches/prefix/bin/repoman 2009-10-27 22:56:07 UTC (rev 14742) |
71 |
+++ main/branches/prefix/bin/repoman 2009-10-28 18:36:02 UTC (rev 14743) |
72 |
@@ -9,6 +9,7 @@ |
73 |
|
74 |
from __future__ import print_function |
75 |
|
76 |
+import calendar |
77 |
import codecs |
78 |
try: |
79 |
from subprocess import getstatusoutput as subprocess_getstatusoutput |
80 |
@@ -25,8 +26,12 @@ |
81 |
import tempfile |
82 |
import time |
83 |
import platform |
84 |
-import urllib |
85 |
|
86 |
+try: |
87 |
+ from urllib.request import urlopen as urllib_request_urlopen |
88 |
+except ImportError: |
89 |
+ from urllib import urlopen as urllib_request_urlopen |
90 |
+ |
91 |
from io import StringIO |
92 |
from itertools import chain |
93 |
from stat import S_ISDIR, ST_CTIME |
94 |
@@ -774,6 +779,33 @@ |
95 |
xmllint_capable = False |
96 |
metadata_dtd = os.path.join(repoman_settings["DISTDIR"], 'metadata.dtd') |
97 |
|
98 |
+def parsedate(s): |
99 |
+ """Parse a RFC 822 date and time string. |
100 |
+ This is required for python3 compatibility, since the |
101 |
+ rfc822.parsedate() function is not available.""" |
102 |
+ |
103 |
+ s_split = [] |
104 |
+ for x in s.upper().split(): |
105 |
+ for y in x.split(','): |
106 |
+ if y: |
107 |
+ s_split.append(y) |
108 |
+ |
109 |
+ if len(s_split) != 6: |
110 |
+ return None |
111 |
+ |
112 |
+ # %a, %d %b %Y %H:%M:%S %Z |
113 |
+ a, d, b, Y, H_M_S, Z = s_split |
114 |
+ |
115 |
+ # Convert month to integer, since strptime %w is locale-dependent. |
116 |
+ month_map = {'JAN':1, 'FEB':2, 'MAR':3, 'APR':4, 'MAY':5, 'JUN':6, |
117 |
+ 'JUL':7, 'AUG':8, 'SEP':9, 'OCT':10, 'NOV':11, 'DEC':12} |
118 |
+ m = month_map.get(b) |
119 |
+ if m is None: |
120 |
+ return None |
121 |
+ m = str(m).rjust(2, '0') |
122 |
+ |
123 |
+ return time.strptime(':'.join((Y, m, d, H_M_S)), '%Y:%m:%d:%H:%M:%S') |
124 |
+ |
125 |
def fetch_metadata_dtd(): |
126 |
""" |
127 |
Fetch metadata.dtd if it doesn't exist or the ctime is older than |
128 |
@@ -803,10 +835,13 @@ |
129 |
"needs to be refetched, doing that now") |
130 |
print() |
131 |
try: |
132 |
- url_f = urllib.urlopen(metadata_dtd_uri) |
133 |
- last_modified = url_f.info().getdate('last-modified') |
134 |
+ url_f = urllib_request_urlopen(metadata_dtd_uri) |
135 |
+ msg_info = url_f.info() |
136 |
+ last_modified = msg_info.get('last-modified') |
137 |
if last_modified is not None: |
138 |
- last_modified = time.mktime(last_modified) |
139 |
+ last_modified = parsedate(last_modified) |
140 |
+ if last_modified is not None: |
141 |
+ last_modified = calendar.timegm(last_modified) |
142 |
|
143 |
metadata_dtd_tmp = "%s.%s" % (metadata_dtd, os.getpid()) |
144 |
try: |
145 |
|
146 |
Modified: main/branches/prefix/man/emerge.1 |
147 |
=================================================================== |
148 |
--- main/branches/prefix/man/emerge.1 2009-10-27 22:56:07 UTC (rev 14742) |
149 |
+++ main/branches/prefix/man/emerge.1 2009-10-28 18:36:02 UTC (rev 14743) |
150 |
@@ -93,7 +93,7 @@ |
151 |
to the \fBworld\fR file at the end, so that they are considered for |
152 |
later updating. |
153 |
.TP |
154 |
-.BR "\-\-clean " (\fB\-c\fR) |
155 |
+.BR \-\-clean |
156 |
Cleans up the system by examining the installed packages and removing older |
157 |
packages. This is accomplished by looking at each installed package and separating |
158 |
the installed versions by \fBslot\fR. Clean will \fBremove all but the most recently |
159 |
@@ -105,7 +105,7 @@ |
160 |
has completed. This usually entails configuration file setup or other similar |
161 |
setups that the user may wish to run. |
162 |
.TP |
163 |
-.BR \-\-depclean |
164 |
+.BR "\-\-depclean (-c)" |
165 |
Cleans the system by removing packages that are not associated |
166 |
with explicitly merged packages. Depclean works by creating the |
167 |
full dependency tree from the @world set, |
168 |
|
169 |
Modified: main/branches/prefix/pym/_emerge/JobStatusDisplay.py |
170 |
=================================================================== |
171 |
--- main/branches/prefix/pym/_emerge/JobStatusDisplay.py 2009-10-27 22:56:07 UTC (rev 14742) |
172 |
+++ main/branches/prefix/pym/_emerge/JobStatusDisplay.py 2009-10-28 18:36:02 UTC (rev 14743) |
173 |
@@ -17,6 +17,7 @@ |
174 |
from portage import os |
175 |
from portage import _encodings |
176 |
from portage import _unicode_decode |
177 |
+from portage import _unicode_encode |
178 |
from portage.output import xtermTitle |
179 |
|
180 |
from _emerge.getloadavg import getloadavg |
181 |
@@ -75,11 +76,14 @@ |
182 |
return sys.stdout |
183 |
|
184 |
def _write(self, s): |
185 |
- if sys.hexversion < 0x3000000 and isinstance(s, unicode): |
186 |
- # avoid potential UnicodeEncodeError |
187 |
- s = s.encode(_encodings['stdio'], 'backslashreplace') |
188 |
- self.out.write(s) |
189 |
- self.out.flush() |
190 |
+ # avoid potential UnicodeEncodeError |
191 |
+ s = _unicode_encode(s, |
192 |
+ encoding=_encodings['stdio'], errors='backslashreplace') |
193 |
+ out = self.out |
194 |
+ if sys.hexversion >= 0x3000000: |
195 |
+ out = out.buffer |
196 |
+ out.write(s) |
197 |
+ out.flush() |
198 |
|
199 |
def _init_term(self): |
200 |
""" |
201 |
|
202 |
Modified: main/branches/prefix/pym/_emerge/help.py |
203 |
=================================================================== |
204 |
--- main/branches/prefix/pym/_emerge/help.py 2009-10-27 22:56:07 UTC (rev 14742) |
205 |
+++ main/branches/prefix/pym/_emerge/help.py 2009-10-28 18:36:02 UTC (rev 14743) |
206 |
@@ -42,7 +42,7 @@ |
207 |
print(" emerge to display detailed help.") |
208 |
print() |
209 |
print(turquoise("Actions:")) |
210 |
- print(" "+green("--clean")+" ("+green("-c")+" short option)") |
211 |
+ print(" "+green("--clean")) |
212 |
print(" Cleans the system by removing outdated packages which will not") |
213 |
print(" remove functionalities or prevent your system from working.") |
214 |
print(" The arguments can be in several different formats :") |
215 |
@@ -66,7 +66,7 @@ |
216 |
print(" emerge process has completed. This usually entails configuration") |
217 |
print(" file setup or other similar setups that the user may wish to run.") |
218 |
print() |
219 |
- print(" "+green("--depclean")) |
220 |
+ print(" "+green("--depclean")+" ("+green("-c")+" short option)") |
221 |
|
222 |
paragraph = "Cleans the system by removing packages that are " + \ |
223 |
"not associated with explicitly merged packages. Depclean works " + \ |
224 |
|
225 |
Modified: main/branches/prefix/pym/_emerge/main.py |
226 |
=================================================================== |
227 |
--- main/branches/prefix/pym/_emerge/main.py 2009-10-27 22:56:07 UTC (rev 14742) |
228 |
+++ main/branches/prefix/pym/_emerge/main.py 2009-10-28 18:36:02 UTC (rev 14743) |
229 |
@@ -77,7 +77,8 @@ |
230 |
"1":"--oneshot", |
231 |
"a":"--ask", |
232 |
"b":"--buildpkg", "B":"--buildpkgonly", |
233 |
-"c":"--clean", "C":"--unmerge", |
234 |
+"c":"--depclean", |
235 |
+"C":"--unmerge", |
236 |
"d":"--debug", |
237 |
"e":"--emptytree", |
238 |
"f":"--fetchonly", "F":"--fetch-all-uri", |
239 |
|
240 |
Modified: main/branches/prefix/pym/portage/__init__.py |
241 |
=================================================================== |
242 |
--- main/branches/prefix/pym/portage/__init__.py 2009-10-27 22:56:07 UTC (rev 14742) |
243 |
+++ main/branches/prefix/pym/portage/__init__.py 2009-10-28 18:36:02 UTC (rev 14743) |
244 |
@@ -7671,8 +7671,10 @@ |
245 |
|
246 |
def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", |
247 |
trees=None, use_mask=None, use_force=None, **kwargs): |
248 |
- """Recursively expand new-style virtuals so as to collapse one or more |
249 |
- levels of indirection. In dep_zapdeps, new-style virtuals will be assigned |
250 |
+ """ |
251 |
+ In order to solve bug #141118, recursively expand new-style virtuals so |
252 |
+ as to collapse one or more levels of indirection, generating an expanded |
253 |
+ search space. In dep_zapdeps, new-style virtuals will be assigned |
254 |
zero cost regardless of whether or not they are currently installed. Virtual |
255 |
blockers are supported but only when the virtual expands to a single |
256 |
atom because it wouldn't necessarily make sense to block all the components |
257 |
|
258 |
Modified: main/branches/prefix/pym/portage/dbapi/vartree.py |
259 |
=================================================================== |
260 |
--- main/branches/prefix/pym/portage/dbapi/vartree.py 2009-10-27 22:56:07 UTC (rev 14742) |
261 |
+++ main/branches/prefix/pym/portage/dbapi/vartree.py 2009-10-28 18:36:02 UTC (rev 14743) |
262 |
@@ -53,6 +53,7 @@ |
263 |
import logging |
264 |
import os as _os |
265 |
import sys |
266 |
+import time |
267 |
import warnings |
268 |
|
269 |
try: |
270 |
@@ -1565,6 +1566,19 @@ |
271 |
rValue = _os.path.join(rValue, filename) |
272 |
return rValue |
273 |
|
274 |
+ def _bump_mtime(self, cpv): |
275 |
+ """ |
276 |
+ This is called before an after any modifications, so that consumers |
277 |
+ can use directory mtimes to validate caches. See bug #290428. |
278 |
+ """ |
279 |
+ base = self.root + _os.sep + VDB_PATH |
280 |
+ cat = catsplit(cpv)[0] |
281 |
+ catdir = base + _os.sep + cat |
282 |
+ t = time.time() |
283 |
+ t = (t, t) |
284 |
+ for x in (catdir, base): |
285 |
+ os.utime(x, t) |
286 |
+ |
287 |
def cpv_exists(self, mykey): |
288 |
"Tells us whether an actual ebuild exists on disk (no masking)" |
289 |
return os.path.exists(self.getpath(mykey)) |
290 |
@@ -2017,6 +2031,7 @@ |
291 |
return results |
292 |
|
293 |
def aux_update(self, cpv, values): |
294 |
+ self._bump_mtime(cpv) |
295 |
cat, pkg = catsplit(cpv) |
296 |
mylink = dblink(cat, pkg, self.root, self.settings, |
297 |
treetype="vartree", vartree=self.vartree) |
298 |
@@ -2030,6 +2045,7 @@ |
299 |
os.unlink(os.path.join(self.getpath(cpv), k)) |
300 |
except EnvironmentError: |
301 |
pass |
302 |
+ self._bump_mtime(cpv) |
303 |
|
304 |
def counter_tick(self, myroot, mycpv=None): |
305 |
return self.counter_tick_core(myroot, incrementing=1, mycpv=mycpv) |
306 |
@@ -2151,9 +2167,11 @@ |
307 |
removed += 1 |
308 |
|
309 |
if removed: |
310 |
+ self._bump_mtime(pkg.mycpv) |
311 |
f = atomic_ofstream(os.path.join(pkg.dbdir, "CONTENTS")) |
312 |
write_contents(new_contents, root, f) |
313 |
f.close() |
314 |
+ self._bump_mtime(pkg.mycpv) |
315 |
pkg._clear_contents_cache() |
316 |
|
317 |
class _owners_cache(object): |
318 |
@@ -2783,6 +2801,7 @@ |
319 |
The caller must ensure that lockdb() and unlockdb() are called |
320 |
before and after this method. |
321 |
""" |
322 |
+ self.vartree.dbapi._bump_mtime(self.mycpv) |
323 |
showMessage = self._display_merge |
324 |
if self.vartree.dbapi._categories is not None: |
325 |
self.vartree.dbapi._categories = None |
326 |
@@ -2924,6 +2943,7 @@ |
327 |
self.vartree.dbapi.plib_registry.pruneNonExisting() |
328 |
|
329 |
finally: |
330 |
+ self.vartree.dbapi._bump_mtime(self.mycpv) |
331 |
if builddir_lock: |
332 |
try: |
333 |
if myebuildpath: |
334 |
@@ -5066,6 +5086,7 @@ |
335 |
mydbapi=None, prev_mtimes=None): |
336 |
retval = -1 |
337 |
self.lockdb() |
338 |
+ self.vartree.dbapi._bump_mtime(self.mycpv) |
339 |
try: |
340 |
self.vartree.dbapi.plib_registry.load() |
341 |
self.vartree.dbapi.plib_registry.pruneNonExisting() |
342 |
@@ -5091,6 +5112,7 @@ |
343 |
finally: |
344 |
self.vartree.dbapi.linkmap._clear_cache() |
345 |
self.unlockdb() |
346 |
+ self.vartree.dbapi._bump_mtime(self.mycpv) |
347 |
return retval |
348 |
|
349 |
def getstring(self,name): |
350 |
|
351 |
Modified: main/branches/prefix/pym/portage/elog/messages.py |
352 |
=================================================================== |
353 |
--- main/branches/prefix/pym/portage/elog/messages.py 2009-10-27 22:56:07 UTC (rev 14742) |
354 |
+++ main/branches/prefix/pym/portage/elog/messages.py 2009-10-28 18:36:02 UTC (rev 14743) |
355 |
@@ -96,11 +96,12 @@ |
356 |
|
357 |
formatted_msg = colorize(color, " * ") + msg + "\n" |
358 |
|
359 |
- if sys.hexversion < 0x3000000 and \ |
360 |
- out in (sys.stdout, sys.stderr) and isinstance(formatted_msg, unicode): |
361 |
- # avoid potential UnicodeEncodeError |
362 |
- formatted_msg = formatted_msg.encode( |
363 |
- _encodings['stdio'], 'backslashreplace') |
364 |
+ # avoid potential UnicodeEncodeError |
365 |
+ if out in (sys.stdout, sys.stderr): |
366 |
+ formatted_msg = _unicode_encode(formatted_msg, |
367 |
+ encoding=_encodings['stdio'], errors='backslashreplace') |
368 |
+ if sys.hexversion >= 0x3000000: |
369 |
+ out = out.buffer |
370 |
|
371 |
out.write(formatted_msg) |
372 |
|
373 |
|
374 |
Modified: main/branches/prefix/pym/portage/output.py |
375 |
=================================================================== |
376 |
--- main/branches/prefix/pym/portage/output.py 2009-10-27 22:56:07 UTC (rev 14742) |
377 |
+++ main/branches/prefix/pym/portage/output.py 2009-10-28 18:36:02 UTC (rev 14743) |
378 |
@@ -251,12 +251,16 @@ |
379 |
mystr = mystr[:_max_xtermTitle_len] |
380 |
if not raw: |
381 |
mystr = '\x1b]0;%s\x07' % mystr |
382 |
- if sys.hexversion < 0x3000000 and isinstance(mystr, unicode): |
383 |
- # avoid potential UnicodeEncodeError |
384 |
- mystr = mystr.encode(_encodings['stdio'], 'backslashreplace') |
385 |
- sys.stderr.write(mystr) |
386 |
- sys.stderr.flush() |
387 |
|
388 |
+ # avoid potential UnicodeEncodeError |
389 |
+ mystr = _unicode_encode(mystr, |
390 |
+ encoding=_encodings['stdio'], errors='backslashreplace') |
391 |
+ f = sys.stderr |
392 |
+ if sys.hexversion >= 0x3000000: |
393 |
+ f = f.buffer |
394 |
+ f.write(mystr) |
395 |
+ f.flush() |
396 |
+ |
397 |
default_xterm_title = None |
398 |
|
399 |
def xtermTitleReset(): |
400 |
@@ -374,11 +378,12 @@ |
401 |
self._write(self.write_listener, s) |
402 |
|
403 |
def _write(self, f, s): |
404 |
- if sys.hexversion < 0x3000000 and \ |
405 |
- isinstance(s, unicode) and \ |
406 |
- f in (sys.stdout, sys.stderr): |
407 |
- # avoid potential UnicodeEncodeError |
408 |
- s = s.encode(_encodings['stdio'], 'backslashreplace') |
409 |
+ # avoid potential UnicodeEncodeError |
410 |
+ if f in (sys.stdout, sys.stderr): |
411 |
+ s = _unicode_encode(s, |
412 |
+ encoding=_encodings['stdio'], errors='backslashreplace') |
413 |
+ if sys.hexversion >= 0x3000000: |
414 |
+ f = f.buffer |
415 |
f.write(s) |
416 |
|
417 |
def writelines(self, lines): |
418 |
@@ -484,9 +489,12 @@ |
419 |
sys.stderr.flush() |
420 |
|
421 |
def _write(self, f, s): |
422 |
- if sys.hexversion < 0x3000000 and isinstance(s, unicode): |
423 |
- # avoid potential UnicodeEncodeError |
424 |
- s = s.encode(_encodings['stdio'], 'backslashreplace') |
425 |
+ # avoid potential UnicodeEncodeError |
426 |
+ s = _unicode_encode(s, |
427 |
+ encoding=_encodings['stdio'], errors='backslashreplace') |
428 |
+ f = sys.stderr |
429 |
+ if sys.hexversion >= 0x3000000: |
430 |
+ f = f.buffer |
431 |
f.write(s) |
432 |
f.flush() |
433 |
|
434 |
|
435 |
Modified: main/branches/prefix/pym/portage/util.py |
436 |
=================================================================== |
437 |
--- main/branches/prefix/pym/portage/util.py 2009-10-27 22:56:07 UTC (rev 14742) |
438 |
+++ main/branches/prefix/pym/portage/util.py 2009-10-28 18:36:02 UTC (rev 14743) |
439 |
@@ -68,10 +68,11 @@ |
440 |
if fd is None: |
441 |
fd = sys.stderr |
442 |
if noiselevel <= noiselimit: |
443 |
- if sys.hexversion < 0x3000000: |
444 |
- # avoid potential UnicodeEncodeError |
445 |
- mystr = _unicode_encode(mystr, |
446 |
- encoding=_encodings['stdio'], errors='backslashreplace') |
447 |
+ # avoid potential UnicodeEncodeError |
448 |
+ mystr = _unicode_encode(mystr, |
449 |
+ encoding=_encodings['stdio'], errors='backslashreplace') |
450 |
+ if sys.hexversion >= 0x3000000: |
451 |
+ fd = fd.buffer |
452 |
fd.write(mystr) |
453 |
fd.flush() |