Gentoo Archives: gentoo-commits

From: "Fabian Groffen (grobian)" <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r10904 - in main/branches/prefix/pym: . _emerge portage
Date: Thu, 03 Jul 2008 06:49:56
Message-Id: E1KEIdZ-00031e-Kl@stork.gentoo.org
1 Author: grobian
2 Date: 2008-07-03 06:49:48 +0000 (Thu, 03 Jul 2008)
3 New Revision: 10904
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/output.py
9 main/branches/prefix/pym/portage_compat_namespace.py
10 Log:
11 Merged from trunk 10893:10903
12
13 | 10894 | Handle missing select.poll on interix by using select() to |
14 | zmedico | emulate a poll object. |
15
16 | 10895 | Fix EbuildBuildDir so that it works properly with binary |
17 | zmedico | packages. |
18
19 | 10896 | Fix broken except statement. Thanks to hawking. |
20 | zmedico | |
21
22 | 10897 | Use stdout.write() instead of "print", for py3k compat. |
23 | zmedico | |
24
25 | 10898 | Split out a SpawnProcess base class out of |
26 | zmedico | EbuildFetcherAsync. |
27
28 | 10899 | Move post ebuild phase code (originally from spawnebuild) |
29 | zmedico | from EbuildExecuter.execute() to |
30 | | EbuildPhase._set_returncode(). |
31
32 | 10900 | Add missing BinpkgFetcherAsync.registered attribute. |
33 | zmedico | |
34
35 | 10901 | Make BinpkgFetcherAsync inherit from SpawnProcess. |
36 | zmedico | |
37
38 | 10902 | Implement asynchronous binary package extraction, so that |
39 | zmedico | the scheduler can run while a package is extracting in the |
40 | | background. |
41
42 | 10903 | Split out a new _check_manifests() method from |
43 | zmedico | Scheduler._merge() since this method is not useful for |
44 | | parallel scheduling and any useful code needs to be |
45 | | relocated. |
46
47
48 Modified: main/branches/prefix/pym/_emerge/__init__.py
49 ===================================================================
50 --- main/branches/prefix/pym/_emerge/__init__.py 2008-07-03 06:39:20 UTC (rev 10903)
51 +++ main/branches/prefix/pym/_emerge/__init__.py 2008-07-03 06:49:48 UTC (rev 10904)
52 @@ -24,6 +24,7 @@
53 import fcntl
54 import select
55 import shlex
56 +import shutil
57 import urlparse
58 import weakref
59 import gc
60 @@ -1522,13 +1523,22 @@
61
62 self.returncode = retval
63
64 -class EbuildFetcherAsync(SubProcess):
65 +class SpawnProcess(SubProcess):
66
67 - __slots__ = ("log_file", "fd_pipes", "pkg",
68 - "register", "unregister",
69 - "files")
70 + """
71 + Constructor keyword args are passed into portage.process.spawn().
72 + The required "args" keyword argument will be passed as the first
73 + spawn() argument.
74 + """
75
76 - _file_names = ("fetcher", "out")
77 + _spawn_kwarg_names = ("env", "opt_name", "fd_pipes",
78 + "uid", "gid", "groups", "umask", "logfile",
79 + "path_lookup", "pre_exec")
80 +
81 + __slots__ = ("args", "files", "register", "unregister", "registered") + \
82 + _spawn_kwarg_names
83 +
84 + _file_names = ("process", "out")
85 _files_dict = slot_dict_class(_file_names, prefix="")
86 _bufsize = 4096
87
88 @@ -1546,27 +1556,26 @@
89 2 : sys.stderr.fileno(),
90 }
91
92 - log_file = self.log_file
93 + logfile = self.logfile
94 self.files = self._files_dict()
95 files = self.files
96
97 - if log_file is not None:
98 - files.out = open(log_file, "a")
99 - portage.util.apply_secpass_permissions(log_file,
100 + if logfile is not None:
101 + files.out = open(logfile, "a")
102 + portage.util.apply_secpass_permissions(logfile,
103 uid=portage.portage_uid, gid=portage.portage_gid,
104 mode=0660)
105 else:
106 + fd_pipes.setdefault(1, sys.stdout.fileno())
107 for fd in fd_pipes.itervalues():
108 if fd == sys.stdout.fileno():
109 sys.stdout.flush()
110 if fd == sys.stderr.fileno():
111 sys.stderr.flush()
112 -
113 files.out = os.fdopen(os.dup(fd_pipes[1]), 'w')
114
115 master_fd, slave_fd = os.pipe()
116
117 - import fcntl
118 fcntl.fcntl(master_fd, fcntl.F_SETFL,
119 fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK)
120
121 @@ -1576,52 +1585,74 @@
122 fd_pipes[1] = slave_fd
123 fd_pipes[2] = slave_fd
124
125 - root_config = self.pkg.root_config
126 - portdb = root_config.trees["porttree"].dbapi
127 - ebuild_path = portdb.findname(self.pkg.cpv)
128 - settings = root_config.settings
129 + kwargs = {}
130 + for k in self._spawn_kwarg_names:
131 + v = getattr(self, k)
132 + if v is not None:
133 + kwargs[k] = v
134
135 - fetch_env = dict((k, settings[k]) for k in settings)
136 - fetch_env["FEATURES"] = fetch_env.get("FEATURES", "") + " -cvs"
137 - fetch_env["PORTAGE_NICENESS"] = "0"
138 - fetch_env["PORTAGE_PARALLEL_FETCHONLY"] = "1"
139 + kwargs["fd_pipes"] = fd_pipes
140 + kwargs["returnpid"] = True
141 + kwargs.pop("logfile", None)
142
143 - ebuild_binary = os.path.join(
144 - settings["EBUILD_BIN_PATH"], "ebuild")
145 + retval = portage.process.spawn(self.args, **kwargs)
146
147 - fetch_args = [ebuild_binary, ebuild_path, "fetch"]
148 - debug = settings.get("PORTAGE_DEBUG") == "1"
149 - if debug:
150 - fetch_args.append("--debug")
151 -
152 - retval = portage.process.spawn(fetch_args, env=fetch_env,
153 - fd_pipes=fd_pipes, returnpid=True)
154 -
155 self.pid = retval[0]
156
157 os.close(slave_fd)
158 - files.fetcher = os.fdopen(master_fd, 'r')
159 - self.register(files.fetcher.fileno(),
160 + files.process = os.fdopen(master_fd, 'r')
161 + self.registered = True
162 + self.register(files.process.fileno(),
163 select.POLLIN, self._output_handler)
164
165 def _output_handler(self, fd, event):
166 files = self.files
167 buf = array.array('B')
168 try:
169 - buf.fromfile(files.fetcher, self._bufsize)
170 + buf.fromfile(files.process, self._bufsize)
171 except EOFError:
172 pass
173 if buf:
174 buf.tofile(files.out)
175 files.out.flush()
176 else:
177 - self.unregister(files.fetcher.fileno())
178 + fd = files.process.fileno()
179 for f in files.values():
180 + f.flush()
181 f.close()
182 + self.registered = False
183 + self.unregister(fd)
184
185 +class EbuildFetcherAsync(SpawnProcess):
186 +
187 + __slots__ = ("pkg",)
188 +
189 + def start(self):
190 +
191 + root_config = self.pkg.root_config
192 + portdb = root_config.trees["porttree"].dbapi
193 + ebuild_path = portdb.findname(self.pkg.cpv)
194 + settings = root_config.settings
195 +
196 + fetch_env = settings.environ()
197 + fetch_env["PORTAGE_NICENESS"] = "0"
198 + fetch_env["PORTAGE_PARALLEL_FETCHONLY"] = "1"
199 +
200 + ebuild_binary = os.path.join(
201 + settings["EBUILD_BIN_PATH"], "ebuild")
202 +
203 + fetch_args = [ebuild_binary, ebuild_path, "fetch"]
204 + debug = settings.get("PORTAGE_DEBUG") == "1"
205 + if debug:
206 + fetch_args.append("--debug")
207 +
208 + self.args = fetch_args
209 + self.env = fetch_env
210 + SpawnProcess.start(self)
211 +
212 class EbuildBuildDir(SlotObject):
213
214 - __slots__ = ("pkg", "settings",
215 + __slots__ = ("dir_path", "pkg", "settings",
216 "locked", "_catdir", "_lock_obj")
217
218 def __init__(self, **kwargs):
219 @@ -1638,17 +1669,21 @@
220 if self._lock_obj is not None:
221 raise self.AlreadyLocked((self._lock_obj,))
222
223 - root_config = self.pkg.root_config
224 - portdb = root_config.trees["porttree"].dbapi
225 - ebuild_path = portdb.findname(self.pkg.cpv)
226 - settings = self.settings
227 - debug = settings.get("PORTAGE_DEBUG") == "1"
228 - use_cache = 1 # always true
229 + dir_path = self.dir_path
230 + if dir_path is None:
231 + root_config = self.pkg.root_config
232 + portdb = root_config.trees["porttree"].dbapi
233 + ebuild_path = portdb.findname(self.pkg.cpv)
234 + settings = self.settings
235 + debug = settings.get("PORTAGE_DEBUG") == "1"
236 + use_cache = 1 # always true
237 + portage.doebuild_environment(ebuild_path, "setup", root_config.root,
238 + self.settings, debug, use_cache, portdb)
239 + dir_path = self.settings["PORTAGE_BUILDDIR"]
240
241 - portage.doebuild_environment(ebuild_path, "setup", root_config.root,
242 - self.settings, debug, use_cache, portdb)
243 - catdir = os.path.dirname(settings["PORTAGE_BUILDDIR"])
244 + catdir = os.path.dirname(dir_path)
245 self._catdir = catdir
246 +
247 portage.util.ensure_dirs(os.path.dirname(catdir),
248 uid=portage.portage_uid, gid=portage.portage_gid,
249 mode=070, mask=0)
250 @@ -1658,8 +1693,7 @@
251 portage.util.ensure_dirs(catdir,
252 gid=portage.portage_gid,
253 mode=070, mask=0)
254 - self._lock_obj = portage.locks.lockdir(
255 - self.settings["PORTAGE_BUILDDIR"])
256 + self._lock_obj = portage.locks.lockdir(dir_path)
257 finally:
258 self.locked = self._lock_obj is not None
259 if catdir_lock is not None:
260 @@ -1857,12 +1891,6 @@
261 self.schedule()
262 retval = ebuild_phase.poll()
263
264 - portage._post_phase_userpriv_perms(settings)
265 - if mydo == "install":
266 - portage._check_build_log(settings)
267 - if retval == os.EX_OK:
268 - retval = portage._post_src_install_checks(settings)
269 -
270 if retval != os.EX_OK:
271 return retval
272
273 @@ -1872,7 +1900,7 @@
274
275 __slots__ = ("fd_pipes", "phase", "pkg",
276 "register", "settings", "unregister",
277 - "files")
278 + "files", "registered")
279
280 _file_names = ("log", "stdout", "ebuild")
281 _files_dict = slot_dict_class(_file_names, prefix="")
282 @@ -1953,6 +1981,7 @@
283 files.log = open(logfile, 'a')
284 files.stdout = os.fdopen(os.dup(fd_pipes_orig[1]), 'w')
285 files.ebuild = os.fdopen(master_fd, 'r')
286 + self.registered = True
287 self.register(files.ebuild.fileno(),
288 select.POLLIN, self._output_handler)
289
290 @@ -1969,9 +1998,11 @@
291 buf.tofile(files.log)
292 files.log.flush()
293 else:
294 - self.unregister(files.ebuild.fileno())
295 + fd = files.ebuild.fileno()
296 for f in files.values():
297 f.close()
298 + self.registered = False
299 + self.unregister(fd)
300
301 def _set_returncode(self, wait_retval):
302 SubProcess._set_returncode(self, wait_retval)
303 @@ -1984,6 +2015,14 @@
304 for l in wrap(msg, 72):
305 eerror(l, phase=self.phase, key=self.pkg.cpv)
306
307 + returncode = self.returncode
308 + settings = self.settings
309 + portage._post_phase_userpriv_perms(settings)
310 + if self.phase == "install":
311 + portage._check_build_log(settings)
312 + if returncode == os.EX_OK:
313 + returncode = portage._post_src_install_checks(settings)
314 +
315 class EbuildBinpkg(Task):
316 """
317 This assumes that src_install() has successfully completed.
318 @@ -2093,6 +2132,8 @@
319 pkg_count = self.pkg_count
320 scheduler = self.scheduler
321 settings = self.settings
322 + settings.setcpv(pkg)
323 + debug = settings.get("PORTAGE_DEBUG") == "1"
324
325 # The prefetcher has already completed or it
326 # could be running now. If it's running now,
327 @@ -2152,16 +2193,126 @@
328 (pkg_count.curval, pkg_count.maxval, pkg.cpv)
329 logger.log(msg, short_msg=short_msg)
330
331 - build_dir = EbuildBuildDir(pkg=pkg, settings=settings)
332 + dir_path = os.path.join(settings["PORTAGE_TMPDIR"],
333 + "portage", pkg.category, pkg.pf)
334 + build_dir = EbuildBuildDir(dir_path=dir_path,
335 + pkg=pkg, settings=settings)
336 + image_dir = os.path.join(dir_path, "image")
337 + infloc = os.path.join(dir_path, "build-info")
338 +
339 + fd_pipes = {
340 + 0 : sys.stdin.fileno(),
341 + 1 : sys.stdout.fileno(),
342 + 2 : sys.stderr.fileno(),
343 + }
344 +
345 try:
346 build_dir.lock()
347 - merge = BinpkgMerge(find_blockers=find_blockers,
348 - ldpath_mtimes=ldpath_mtimes, pkg=pkg, pretend=opts.pretend,
349 - pkg_path=pkg_path, settings=settings)
350 +
351 + root_config = self.pkg.root_config
352 + ebuild_path = os.path.join(infloc, pkg.pf + ".ebuild")
353 + cleanup = 1
354 + tree = "bintree"
355 + mydbapi = root_config.trees[tree].dbapi
356 +
357 + retval = portage.doebuild(ebuild_path, "clean",
358 + root_config.root, settings, debug, cleanup=cleanup,
359 + mydbapi=mydbapi, tree=tree)
360 + if retval != os.EX_OK:
361 + return retval
362 +
363 + try:
364 + shutil.rmtree(dir_path)
365 + except (IOError, OSError), e:
366 + if e.errno != errno.ENOENT:
367 + raise
368 + del e
369 +
370 + # This initializes PORTAGE_LOG_FILE.
371 + portage.prepare_build_dirs(root_config.root, settings, cleanup)
372 +
373 + dir_mode = 0755
374 + for mydir in (dir_path, image_dir, infloc):
375 + portage.util.ensure_dirs(mydir, uid=portage.data.portage_uid,
376 + gid=portage.data.portage_gid, mode=dir_mode)
377 +
378 + portage.writemsg_stdout(">>> Extracting info\n")
379 +
380 + pkg_xpak = portage.xpak.tbz2(pkg_path)
381 + check_missing_metadata = ("CATEGORY", "PF")
382 + missing_metadata = set()
383 + for k in check_missing_metadata:
384 + v = pkg_xpak.getfile(k)
385 + if not v:
386 + missing_metadata.add(k)
387 +
388 + pkg_xpak.unpackinfo(infloc)
389 + for k in missing_metadata:
390 + if k == "CATEGORY":
391 + v = pkg.category
392 + elif k == "PF":
393 + v = pkg.pf
394 + else:
395 + continue
396 +
397 + f = open(os.path.join(infloc, k), 'wb')
398 + try:
399 + f.write(v + "\n")
400 + finally:
401 + f.close()
402 +
403 + # Store the md5sum in the vdb.
404 + f = open(os.path.join(infloc, "BINPKGMD5"), "w")
405 + try:
406 + f.write(str(portage.checksum.perform_md5(pkg_path)) + "\n")
407 + finally:
408 + f.close()
409 +
410 + # This gives bashrc users an opportunity to do various things
411 + # such as remove binary packages after they're installed.
412 + settings["PORTAGE_BINPKG_FILE"] = pkg_path
413 + settings.backup_changes("PORTAGE_BINPKG_FILE")
414 +
415 + phase = "setup"
416 + ebuild_phase = EbuildPhase(fd_pipes=fd_pipes,
417 + pkg=pkg, phase=phase, register=scheduler.register,
418 + settings=settings, unregister=scheduler.unregister)
419 +
420 + ebuild_phase.start()
421 + retval = None
422 + while retval is None:
423 + scheduler.schedule()
424 + retval = ebuild_phase.poll()
425 +
426 + if retval != os.EX_OK:
427 + return retval
428 +
429 + extractor = BinpkgExtractorAsync(image_dir=image_dir,
430 + pkg=pkg, pkg_path=pkg_path, register=scheduler.register,
431 + unregister=scheduler.unregister)
432 + portage.writemsg_stdout(">>> Extracting %s\n" % pkg.cpv)
433 + extractor.start()
434 + retval = None
435 + while retval is None:
436 + scheduler.schedule()
437 + retval = extractor.poll()
438 +
439 + if retval != os.EX_OK:
440 + writemsg("!!! Error Extracting '%s'\n" % pkg_path,
441 + noiselevel=-1)
442 + return retval
443 +
444 + merge = EbuildMerge(
445 + find_blockers=find_blockers,
446 + ldpath_mtimes=ldpath_mtimes,
447 + pkg=pkg, settings=settings)
448 +
449 retval = merge.execute()
450 if retval != os.EX_OK:
451 return retval
452 +
453 finally:
454 + settings.pop("PORTAGE_BINPKG_FILE", None)
455 build_dir.unlock()
456 return os.EX_OK
457
458 @@ -2224,16 +2375,11 @@
459 rval = 1
460 return rval
461
462 -class BinpkgFetcherAsync(SubProcess):
463 +class BinpkgFetcherAsync(SpawnProcess):
464
465 - __slots__ = ("log_file", "fd_pipes", "pkg",
466 - "register", "unregister",
467 - "locked", "files", "pkg_path", "_lock_obj")
468 + __slots__ = ("pkg",
469 + "locked", "pkg_path", "_lock_obj")
470
471 - _file_names = ("fetcher", "out")
472 - _files_dict = slot_dict_class(_file_names, prefix="")
473 - _bufsize = 4096
474 -
475 def __init__(self, **kwargs):
476 SubProcess.__init__(self, **kwargs)
477 pkg = self.pkg
478 @@ -2244,43 +2390,6 @@
479 if self.cancelled:
480 return
481
482 - fd_pipes = self.fd_pipes
483 - if fd_pipes is None:
484 - fd_pipes = {
485 - 0 : sys.stdin.fileno(),
486 - 1 : sys.stdout.fileno(),
487 - 2 : sys.stderr.fileno(),
488 - }
489 -
490 - log_file = self.log_file
491 - self.files = self._files_dict()
492 - files = self.files
493 -
494 - if log_file is not None:
495 - files.out = open(log_file, "a")
496 - portage.util.apply_secpass_permissions(log_file,
497 - uid=portage.portage_uid, gid=portage.portage_gid,
498 - mode=0660)
499 - else:
500 - # flush any pending output
501 - for fd in fd_pipes.itervalues():
502 - if fd == sys.stdout.fileno():
503 - sys.stdout.flush()
504 - if fd == sys.stderr.fileno():
505 - sys.stderr.flush()
506 -
507 - files.out = os.fdopen(os.dup(fd_pipes[1]), 'w')
508 -
509 - master_fd, slave_fd = os.pipe()
510 - fcntl.fcntl(master_fd, fcntl.F_SETFL,
511 - fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK)
512 -
513 - fd_pipes.setdefault(0, sys.stdin.fileno())
514 - fd_pipes_orig = fd_pipes.copy()
515 - fd_pipes[0] = fd_pipes_orig[0]
516 - fd_pipes[1] = slave_fd
517 - fd_pipes[2] = slave_fd
518 -
519 pkg = self.pkg
520 bintree = pkg.root_config.trees["bintree"]
521 settings = bintree.settings
522 @@ -2322,33 +2431,15 @@
523 if use_locks:
524 self.lock()
525
526 - retval = portage.process.spawn(fetch_args, env=fetch_env,
527 - fd_pipes=fd_pipes, returnpid=True)
528 + self.args = fetch_args
529 + self.env = fetch_env
530 + SpawnProcess.start(self)
531
532 - self.pid = retval[0]
533 + def _set_returncode(self, wait_retval):
534 + SpawnProcess._set_returncode(self, wait_retval)
535 + if self.locked:
536 + self.unlock()
537
538 - os.close(slave_fd)
539 - files.fetcher = os.fdopen(master_fd, 'r')
540 - self.register(files.fetcher.fileno(),
541 - select.POLLIN, self._output_handler)
542 -
543 - def _output_handler(self, fd, event):
544 - files = self.files
545 - buf = array.array('B')
546 - try:
547 - buf.fromfile(files.fetcher, self._bufsize)
548 - except EOFError:
549 - pass
550 - if buf:
551 - buf.tofile(files.out)
552 - files.out.flush()
553 - else:
554 - self.unregister(files.fetcher.fileno())
555 - for f in files.values():
556 - f.close()
557 - if self.locked:
558 - self.unlock()
559 -
560 def lock(self):
561 """
562 This raises an AlreadyLocked exception if lock() is called
563 @@ -2373,6 +2464,21 @@
564 self._lock_obj = None
565 self.locked = False
566
567 +class BinpkgExtractorAsync(SpawnProcess):
568 +
569 + __slots__ = ("image_dir", "pkg", "pkg_path")
570 +
571 + _shell_binary = portage.const.BASH_BINARY
572 +
573 + def start(self):
574 + self.args = [self._shell_binary, "-c",
575 + "bzip2 -dqc -- %s | tar -xp -C %s -f -" % \
576 + (portage._shell_quote(self.pkg_path),
577 + portage._shell_quote(self.image_dir))]
578 +
579 + self.env = self.pkg.root_config.settings.environ()
580 + SpawnProcess.start(self)
581 +
582 class BinpkgMerge(Task):
583
584 __slots__ = ("find_blockers", "ldpath_mtimes",
585 @@ -6854,6 +6960,61 @@
586 (self.blocks - self.blocks_satisfied))
587 return "".join(myoutput)
588
589 +class PollSelectFallback(object):
590 +
591 + """
592 + Use select to emulate a poll object, for
593 + systems that don't support poll().
594 + """
595 +
596 + def __init__(self):
597 + self._registered = {}
598 + self._select_args = [[], [], []]
599 +
600 + def register(self, fd, *args):
601 + """
602 + Only select.POLLIN is currently supported!
603 + """
604 + if len(args) > 1:
605 + raise TypeError(
606 + "register expected at most 2 arguments, got " + \
607 + repr(1 + len(args)))
608 +
609 + eventmask = select.POLLIN | select.POLLPRI | select.POLLOUT
610 + if args:
611 + eventmask = args[0]
612 +
613 + self._registered[fd] = eventmask
614 + self._select_args = None
615 +
616 + def unregister(self, fd):
617 + self._select_args = None
618 + del self._registered[fd]
619 +
620 + def poll(self, *args):
621 + if len(args) > 1:
622 + raise TypeError(
623 + "poll expected at most 2 arguments, got " + \
624 + repr(1 + len(args)))
625 +
626 + timeout = None
627 + if args:
628 + timeout = args[0]
629 +
630 + select_args = self._select_args
631 + if select_args is None:
632 + select_args = [self._registered.keys(), [], []]
633 +
634 + if timeout is not None:
635 + select_args = select_args[:]
636 + select_args.append(timeout)
637 +
638 + select_events = select.select(*select_args)
639 + poll_events = []
640 + for fd in select_events[0]:
641 + poll_events.append((fd, select.POLLIN))
642 + return poll_events
643 +
644 class Scheduler(object):
645
646 _opts_ignore_blockers = \
647 @@ -6914,7 +7075,12 @@
648 register=self._register, schedule=self._schedule,
649 unregister=self._unregister)
650 self._poll_event_handlers = {}
651 - self._poll = select.poll()
652 +
653 + try:
654 + self._poll = select.poll()
655 + except AttributeError:
656 + self._poll = PollSelectFallback()
657 +
658 from collections import deque
659 self._task_queue = deque()
660 self._running_tasks = set()
661 @@ -6994,12 +7160,67 @@
662
663 return blocker_dblinks
664
665 + def _check_manifests(self):
666 + # Verify all the manifests now so that the user is notified of failure
667 + # as soon as possible.
668 + if "strict" not in self.settings.features or \
669 + "--fetchonly" in self.myopts or \
670 + "--fetch-all-uri" in self.myopts:
671 + return os.EX_OK
672 +
673 + shown_verifying_msg = False
674 + quiet_settings = {}
675 + for myroot, pkgsettings in self.pkgsettings.iteritems():
676 + quiet_config = portage.config(clone=pkgsettings)
677 + quiet_config["PORTAGE_QUIET"] = "1"
678 + quiet_config.backup_changes("PORTAGE_QUIET")
679 + quiet_settings[myroot] = quiet_config
680 + del quiet_config
681 +
682 + for x in self._mergelist:
683 + if x.type_name != "ebuild":
684 + continue
685 +
686 + if not shown_verifying_msg:
687 + shown_verifying_msg = True
688 + print ">>> Verifying ebuild Manifests..."
689 +
690 + root_config = x.root_config
691 + portdb = root_config.trees["porttree"].dbapi
692 + quiet_config = quiet_settings[root_config.root]
693 + quiet_config["O"] = os.path.dirname(portdb.findname(x.cpv))
694 + if not portage.digestcheck([], quiet_config, strict=True):
695 + return 1
696 +
697 + return os.EX_OK
698 +
699 def merge(self):
700
701 + if "--resume" in self.myopts:
702 + # We're resuming.
703 + portage.writemsg_stdout(
704 + colorize("GOOD", "*** Resuming merge...\n"), noiselevel=-1)
705 + self._logger.log(" *** Resuming merge...")
706 +
707 + rval = self._check_manifests()
708 + if rval != os.EX_OK:
709 + return rval
710 +
711 keep_going = "--keep-going" in self.myopts
712 running_tasks = self._running_tasks
713 + mtimedb = self._mtimedb
714
715 while True:
716 +
717 + # Do this before verifying the ebuild Manifests since it might
718 + # be possible for the user to use --resume --skipfirst get past
719 + # a non-essential package with a broken digest.
720 + mtimedb["resume"]["mergelist"] = [list(x) \
721 + for x in self._mergelist \
722 + if isinstance(x, Package) and x.operation == "merge"]
723 +
724 + mtimedb.commit()
725 +
726 try:
727 rval = self._merge()
728 finally:
729 @@ -7011,7 +7232,6 @@
730
731 if rval == os.EX_OK or not keep_going:
732 break
733 - mtimedb = self._mtimedb
734 if "resume" not in mtimedb:
735 break
736 mergelist = self._mtimedb["resume"].get("mergelist")
737 @@ -7120,7 +7340,7 @@
738 state_changed = False
739
740 for task in list(running_tasks):
741 - if task.poll() is not None:
742 + if not task.registered and task.poll() is not None:
743 running_tasks.remove(task)
744 state_changed = True
745
746 @@ -7148,18 +7368,6 @@
747 ldpath_mtimes = mtimedb["ldpath"]
748 logger = self._logger
749
750 - if "--resume" in self.myopts:
751 - # We're resuming.
752 - print colorize("GOOD", "*** Resuming merge...")
753 - self._logger.log(" *** Resuming merge...")
754 -
755 - # Do this before verifying the ebuild Manifests since it might
756 - # be possible for the user to use --resume --skipfirst get past
757 - # a non-essential package with a broken digest.
758 - mtimedb["resume"]["mergelist"] = [list(x) for x in mylist \
759 - if isinstance(x, Package) and x.operation == "merge"]
760 - mtimedb.commit()
761 -
762 prefetchers = weakref.WeakValueDictionary()
763 getbinpkg = "--getbinpkg" in self.myopts
764
765 @@ -7170,47 +7378,19 @@
766 continue
767 if pkg.type_name == "ebuild":
768 self._add_task(EbuildFetcherAsync(
769 - log_file=self._fetch_log,
770 + logfile=self._fetch_log,
771 pkg=pkg, register=self._register,
772 unregister=self._unregister))
773 elif pkg.type_name == "binary" and getbinpkg and \
774 pkg.root_config.trees["bintree"].isremote(pkg.cpv):
775 prefetcher = BinpkgFetcherAsync(
776 - log_file=self._fetch_log,
777 + logfile=self._fetch_log,
778 pkg=pkg, register=self._register,
779 unregister=self._unregister)
780 prefetchers[pkg] = prefetcher
781 self._add_task(prefetcher)
782 del prefetcher
783
784 - # Verify all the manifests now so that the user is notified of failure
785 - # as soon as possible.
786 - if "--fetchonly" not in self.myopts and \
787 - "--fetch-all-uri" not in self.myopts and \
788 - "strict" in self.settings.features:
789 - shown_verifying_msg = False
790 - quiet_settings = {}
791 - for myroot, pkgsettings in self.pkgsettings.iteritems():
792 - quiet_config = portage.config(clone=pkgsettings)
793 - quiet_config["PORTAGE_QUIET"] = "1"
794 - quiet_config.backup_changes("PORTAGE_QUIET")
795 - quiet_settings[myroot] = quiet_config
796 - del quiet_config
797 - for x in mylist:
798 - if x[0] != "ebuild" or x[-1] == "nomerge":
799 - continue
800 - if not shown_verifying_msg:
801 - shown_verifying_msg = True
802 - print ">>> Verifying ebuild Manifests..."
803 - mytype, myroot, mycpv, mystatus = x
804 - portdb = self.trees[myroot]["porttree"].dbapi
805 - quiet_config = quiet_settings[myroot]
806 - quiet_config["O"] = os.path.dirname(portdb.findname(mycpv))
807 - if not portage.digestcheck([], quiet_config, strict=True):
808 - return 1
809 - del x, mytype, myroot, mycpv, mystatus, quiet_config
810 - del shown_verifying_msg, quiet_settings
811 -
812 root_config = self.trees[self.target_root]["root_config"]
813 mymergelist = mylist
814 myfeat = self.settings.features[:]
815
816 Modified: main/branches/prefix/pym/portage/__init__.py
817 ===================================================================
818 --- main/branches/prefix/pym/portage/__init__.py 2008-07-03 06:39:20 UTC (rev 10903)
819 +++ main/branches/prefix/pym/portage/__init__.py 2008-07-03 06:49:48 UTC (rev 10904)
820 @@ -4923,6 +4923,7 @@
821 noauto = "noauto" in features
822 from portage.data import secpass
823
824 + clean_phases = ("clean", "cleanrm")
825 validcommands = ["help","clean","prerm","postrm","cleanrm","preinst","postinst",
826 "config","info","setup","depend","fetch","digest",
827 "unpack","compile","test","install","rpm","qmerge","merge",
828 @@ -4939,7 +4940,7 @@
829 writemsg("\n", noiselevel=-1)
830 return 1
831
832 - if not os.path.exists(myebuild):
833 + if mydo not in clean_phases and not os.path.exists(myebuild):
834 writemsg("!!! doebuild: %s not found for %s\n" % (myebuild, mydo),
835 noiselevel=-1)
836 return 1
837 @@ -5036,7 +5037,6 @@
838 doebuild_environment(myebuild, mydo, myroot, mysettings, debug,
839 use_cache, mydbapi)
840
841 - clean_phases = ("clean", "cleanrm")
842 if mydo in clean_phases:
843 retval = spawn(_shell_quote(ebuild_sh_binary) + " clean",
844 mysettings, debug=debug, free=1, logfile=None)
845
846 Modified: main/branches/prefix/pym/portage/output.py
847 ===================================================================
848 --- main/branches/prefix/pym/portage/output.py 2008-07-03 06:39:20 UTC (rev 10903)
849 +++ main/branches/prefix/pym/portage/output.py 2008-07-03 06:49:48 UTC (rev 10904)
850 @@ -461,8 +461,10 @@
851 self.ewarn(msg[0])
852 if self.__last_e_cmd != "ebegin":
853 self.__last_e_len = 0
854 - print "%*s%s" % ((self.term_columns - self.__last_e_len - 6), "", status_brackets)
855 - sys.stdout.flush()
856 + out = sys.stdout
857 + out.write("%*s%s\n" % \
858 + ((self.term_columns - self.__last_e_len - 6), "", status_brackets))
859 + out.flush()
860
861 def ebegin(self, msg):
862 """
863 @@ -501,10 +503,12 @@
864 @param msg: A very brief (shorter than one line) error message.
865 @type msg: StringType
866 """
867 + out = sys.stdout
868 if not self.quiet:
869 - if self.__last_e_cmd == "ebegin": print
870 - print colorize("BAD", " * ") + msg
871 - sys.stdout.flush()
872 + if self.__last_e_cmd == "ebegin":
873 + out.write("\n")
874 + out.write(colorize("BAD", " * ") + msg + "\n")
875 + out.flush()
876 self.__last_e_cmd = "eerror"
877
878 def einfo(self, msg):
879 @@ -514,10 +518,12 @@
880 @param msg: A very brief (shorter than one line) informative message.
881 @type msg: StringType
882 """
883 + out = sys.stdout
884 if not self.quiet:
885 - if self.__last_e_cmd == "ebegin": print
886 - print colorize("GOOD", " * ") + msg
887 - sys.stdout.flush()
888 + if self.__last_e_cmd == "ebegin":
889 + out.write("\n")
890 + out.write(colorize("GOOD", " * ") + msg + "\n")
891 + out.flush()
892 self.__last_e_cmd = "einfo"
893
894 def einfon(self, msg):
895 @@ -527,10 +533,12 @@
896 @param msg: A very brief (shorter than one line) informative message.
897 @type msg: StringType
898 """
899 + out = sys.stdout
900 if not self.quiet:
901 - if self.__last_e_cmd == "ebegin": print
902 - print colorize("GOOD", " * ") + msg ,
903 - sys.stdout.flush()
904 + if self.__last_e_cmd == "ebegin":
905 + out.write("\n")
906 + out.write(colorize("GOOD", " * ") + msg)
907 + out.flush()
908 self.__last_e_cmd = "einfon"
909
910 def ewarn(self, msg):
911 @@ -540,10 +548,12 @@
912 @param msg: A very brief (shorter than one line) warning message.
913 @type msg: StringType
914 """
915 + out = sys.stdout
916 if not self.quiet:
917 - if self.__last_e_cmd == "ebegin": print
918 - print colorize("WARN", " * ") + msg
919 - sys.stdout.flush()
920 + if self.__last_e_cmd == "ebegin":
921 + out.write("\n")
922 + out.write(colorize("WARN", " * ") + msg + "\n")
923 + out.flush()
924 self.__last_e_cmd = "ewarn"
925
926 def ewend(self, errno, *msg):
927
928 Modified: main/branches/prefix/pym/portage_compat_namespace.py
929 ===================================================================
930 --- main/branches/prefix/pym/portage_compat_namespace.py 2008-07-03 06:39:20 UTC (rev 10903)
931 +++ main/branches/prefix/pym/portage_compat_namespace.py 2008-07-03 06:49:48 UTC (rev 10904)
932 @@ -28,7 +28,7 @@
933 try:
934 __package = __import__(__newname, globals(), locals())
935 __realmodule = getattr(__package, __newname[8:])
936 -except ImportError, AttributeError:
937 +except (ImportError, AttributeError):
938 raise ImportError("No module named %s" % __oldname)
939
940 def _formatwarning(message, category, filename, lineno):
941
942 --
943 gentoo-commits@l.g.o mailing list