Gentoo Archives: gentoo-commits

From: "Fabian Groffen (grobian)" <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] portage r11694 - in main/branches/prefix: bin pym/_emerge pym/portage pym/portage/dbapi pym/portage/elog
Date: Wed, 15 Oct 2008 20:33:30
Message-Id: E1KqD3b-0000AE-6I@stork.gentoo.org
1 Author: grobian
2 Date: 2008-10-15 20:33:21 +0000 (Wed, 15 Oct 2008)
3 New Revision: 11694
4
5 Modified:
6 main/branches/prefix/bin/ebuild.sh
7 main/branches/prefix/bin/repoman
8 main/branches/prefix/pym/_emerge/__init__.py
9 main/branches/prefix/pym/portage/__init__.py
10 main/branches/prefix/pym/portage/dbapi/bintree.py
11 main/branches/prefix/pym/portage/dbapi/porttree.py
12 main/branches/prefix/pym/portage/dbapi/vartree.py
13 main/branches/prefix/pym/portage/elog/__init__.py
14 Log:
15 Merged from trunk -r11675:11692
16
17 | 11676 | Bug #241204 - Fix dbapi.invalidentry() calls inside |
18 | zmedico | vardbapi.cpv_all() to correctly join the path via |
19 | | self.getpath(). |
20
21 | 11677 | When warning about package categories that haven't been |
22 | zmedico | configured via /etc/portage/categories, join the path with |
23 | | PORTAGE_CONFIGROOT. Thanks to Ned Ludd <solar@g.o> for |
24 | | reporting. |
25
26 | 11678 | In EbuildFetcher._start(), in order to ensure that a new log |
27 | zmedico | is created when appropriate, clean up PORTAGE_BUILDDIR if |
28 | | appropriate. |
29
30 | 11679 | Make the Scheduler class treat failed fetches the same as |
31 | zmedico | other failed packages, and don't bail out due to a failure |
32 | | when in --fetchonly mode. This fixes an issue with |
33 | | --fetchonly bailing out instead of continuing to fetch. |
34
35 | 11680 | Buge #241100 - Make EbuildFetcher use a pty when |
36 | zmedico | appropriate, so that fetcher progress bars, like wget has, |
37 | | will work properly. |
38
39 | 11681 | Remove the prefetch logic in EbuildFetcher._pipe() since |
40 | zmedico | prefetchers are always in the background anyway. |
41
42 | 11682 | Now that only prefetch (parallel-fetch) output goes to the |
43 | zmedico | global fetch log, update code to remove inappropriate |
44 | | references to this log. |
45
46 | 11683 | Inside fetch(), don't call pkg_nofetch when in |
47 | zmedico | parallel-fetch mode since it will get call again later |
48 | | anyway. |
49
50 | 11684 | Add an explicit note about bug #239560 in the relevant code. |
51 | zmedico | |
52
53 | 11685 | Bug #241118 - Re-enable pkg_nofetch for emerge --pretend |
54 | zmedico | --fetch, but direct output to stderr. This requires |
55 | | PORTAGE_BUILDDIR locking for bug #239560 and also for elog |
56 | | message storage. |
57
58 | 11686 | Bug #234301 - When fetch fails, include the path of the log |
59 | zmedico | file in the eerror message that's generated. This way it's |
60 | | easy for the user to find the output from the fetcher or |
61 | | from the pkg_nofetch phase. |
62
63 | 11687 | Don't return from fetch() due to fetch restriction when in |
64 | zmedico | "listonly" mode. |
65
66 | 11688 | Make fetch() fetch as many files as possible, even if some |
67 | zmedico | fail, when in fetchonly mode. |
68
69 | 11689 | Make sure the pkg_nofetch phase is only called once when in |
70 | zmedico | fetchonly mode. |
71
72 | 11690 | When emerge --keep-going bails due to missing dependencies, |
73 | zmedico | show the error message after the mod_echo output since |
74 | | otherwise the mod_echo output can sweep the error message |
75 | | out of view. Thanks to Donnie Berkholz <dberkholz@g.o> for |
76 | | reporting. |
77
78 | 11691 | Bug #241366 - Only suggest to run `emaint --check world` |
79 | zmedico | when the atom is a direct member of the world set (rather |
80 | | than from a nested set). |
81
82 | 11692 | Bug #229033 - When a Manifest is added automatically by |
83 | zmedico | repoman, it's in the "mynew" list, so move manifest paths |
84 | | from that list to the "mymanifests" list when necessary. |
85
86
87 Modified: main/branches/prefix/bin/ebuild.sh
88 ===================================================================
89 --- main/branches/prefix/bin/ebuild.sh 2008-10-15 19:39:42 UTC (rev 11693)
90 +++ main/branches/prefix/bin/ebuild.sh 2008-10-15 20:33:21 UTC (rev 11694)
91 @@ -272,7 +272,9 @@
92 export EBUILD_DEATH_HOOKS="${EBUILD_DEATH_HOOKS} $*"
93 }
94
95 -# Ensure that $PWD is sane whenever possible.
96 +# Ensure that $PWD is sane whenever possible, to protect against
97 +# exploitation of insecure search path for python -c in ebuilds.
98 +# See bug #239560.
99 if ! hasq "$EBUILD_PHASE" clean depend help ; then
100 cd "$PORTAGE_BUILDDIR" || \
101 die "PORTAGE_BUILDDIR does not exist: '$PORTAGE_BUILDDIR'"
102
103 Modified: main/branches/prefix/bin/repoman
104 ===================================================================
105 --- main/branches/prefix/bin/repoman 2008-10-15 19:39:42 UTC (rev 11693)
106 +++ main/branches/prefix/bin/repoman 2008-10-15 20:33:21 UTC (rev 11694)
107 @@ -1738,8 +1738,23 @@
108
109 # Manifests need to be regenerated after all other commits, so don't commit
110 # them now even if they have changed.
111 - mymanifests = [f for f in mychanged if "Manifest" == os.path.basename(f)]
112 - mychanged = [f for f in mychanged if "Manifest" != os.path.basename(f)]
113 + mymanifests = set()
114 + changed_set = set()
115 + new_set = set()
116 + for f in mychanged:
117 + if "Manifest" == os.path.basename(f):
118 + mymanifests.add(f)
119 + else:
120 + changed_set.add(f)
121 + for f in mynew:
122 + if "Manifest" == os.path.basename(f):
123 + mymanifests.add(f)
124 + else:
125 + new_set.add(f)
126 + mychanged = list(changed_set)
127 + mynew = list(new_set)
128 + mymanifests = list(mymanifests)
129 + del changed_set, new_set
130 myupdates = mychanged + mynew
131 myheaders = []
132 mydirty = []
133
134 Modified: main/branches/prefix/pym/_emerge/__init__.py
135 ===================================================================
136 --- main/branches/prefix/pym/_emerge/__init__.py 2008-10-15 19:39:42 UTC (rev 11693)
137 +++ main/branches/prefix/pym/_emerge/__init__.py 2008-10-15 20:33:21 UTC (rev 11694)
138 @@ -1615,6 +1615,13 @@
139 __slots__ = ("fetch_all", "pkg", "settings")
140
141 def execute(self):
142 + # To spawn pkg_nofetch requires PORTAGE_BUILDDIR for
143 + # ensuring sane $PWD (bug #239560) and storing elog
144 + # messages.
145 + build_dir = EbuildBuildDir(pkg=self.pkg, settings=self.settings)
146 + build_dir.lock()
147 + build_dir.clean()
148 + portage.prepare_build_dirs(self.pkg.root, self.settings, 0)
149 portdb = self.pkg.root_config.trees["porttree"].dbapi
150 ebuild_path = portdb.findname(self.pkg.cpv)
151 debug = self.settings.get("PORTAGE_DEBUG") == "1"
152 @@ -1623,6 +1630,10 @@
153 self.settings["ROOT"], self.settings, debug=debug,
154 listonly=1, fetchonly=1, fetchall=self.fetch_all,
155 mydbapi=portdb, tree="porttree")
156 +
157 + portage.elog.elog_process(self.pkg.cpv, self.settings)
158 + build_dir.clean()
159 + build_dir.unlock()
160 return retval
161
162 class AsynchronousTask(SlotObject):
163 @@ -2275,6 +2286,8 @@
164 settings = self.config_pool.allocate()
165 self._build_dir = EbuildBuildDir(pkg=self.pkg, settings=settings)
166 self._build_dir.lock()
167 + self._build_dir.clean()
168 + portage.prepare_build_dirs(self.pkg.root, self._build_dir.settings, 0)
169 if self.logfile is None:
170 self.logfile = settings.get("PORTAGE_LOG_FILE")
171
172 @@ -2304,6 +2317,18 @@
173 self.env = fetch_env
174 SpawnProcess._start(self)
175
176 + def _pipe(self, fd_pipes):
177 + """When appropriate, use a pty so that fetcher progress bars,
178 + like wget has, will work properly."""
179 + if self.background or not sys.stdout.isatty():
180 + # When the output only goes to a log file,
181 + # there's no point in creating a pty.
182 + return os.pipe()
183 + stdout_pipe = fd_pipes.get(1)
184 + got_pty, master_fd, slave_fd = \
185 + portage._create_pty_or_pipe(copy_term_size=stdout_pipe)
186 + return (master_fd, slave_fd)
187 +
188 def _set_returncode(self, wait_retval):
189 SpawnProcess._set_returncode(self, wait_retval)
190 # Collect elog messages that might have been
191 @@ -2315,21 +2340,20 @@
192 if self.logfile is not None:
193 if self.background:
194 elog_out = open(self.logfile, 'a')
195 - eerror("Fetch failed for '%s'" % self.pkg.cpv,
196 - phase="unpack", key=self.pkg.cpv, out=elog_out)
197 + msg = "Fetch failed for '%s'" % (self.pkg.cpv,)
198 + if self.logfile is not None:
199 + msg += ", Log file:"
200 + eerror(msg, phase="unpack", key=self.pkg.cpv, out=elog_out)
201 + if self.logfile is not None:
202 + eerror(" '%s'" % (self.logfile,),
203 + phase="unpack", key=self.pkg.cpv, out=elog_out)
204 if elog_out is not None:
205 elog_out.close()
206 if not self.prefetch:
207 portage.elog.elog_process(self.pkg.cpv, self._build_dir.settings)
208 features = self._build_dir.settings.features
209 - if (self.fetchonly or self.returncode == os.EX_OK) and \
210 - not ("keepwork" in features or "keeptemp" in features):
211 - try:
212 - shutil.rmtree(self._build_dir.settings["PORTAGE_BUILDDIR"])
213 - except EnvironmentError, e:
214 - if e.errno != errno.ENOENT:
215 - raise
216 - del e
217 + if self.returncode == os.EX_OK:
218 + self._build_dir.clean()
219 self._build_dir.unlock()
220 self.config_pool.deallocate(self._build_dir.settings)
221 self._build_dir = None
222 @@ -2365,7 +2389,6 @@
223 portage.doebuild_environment(ebuild_path, "setup", root_config.root,
224 self.settings, debug, use_cache, portdb)
225 dir_path = self.settings["PORTAGE_BUILDDIR"]
226 - portage.prepare_build_dirs(self.pkg.root, self.settings, 0)
227
228 catdir = os.path.dirname(dir_path)
229 self._catdir = catdir
230 @@ -2385,6 +2408,19 @@
231 if catdir_lock is not None:
232 portage.locks.unlockdir(catdir_lock)
233
234 + def clean(self):
235 + """Uses shutil.rmtree() rather than spawning a 'clean' phase. Disabled
236 + by keepwork or keeptemp in FEATURES."""
237 + settings = self.settings
238 + features = settings.features
239 + if not ("keepwork" in features or "keeptemp" in features):
240 + try:
241 + shutil.rmtree(settings["PORTAGE_BUILDDIR"])
242 + except EnvironmentError, e:
243 + if e.errno != errno.ENOENT:
244 + raise
245 + del e
246 +
247 def unlock(self):
248 if self._lock_obj is None:
249 return
250 @@ -3504,7 +3540,7 @@
251
252 __slots__ = ("args_set",
253 "binpkg_opts", "build_opts", "config_pool", "emerge_opts",
254 - "failed_fetches", "find_blockers", "logger", "mtimedb", "pkg",
255 + "find_blockers", "logger", "mtimedb", "pkg",
256 "pkg_count", "pkg_to_replace", "prefetcher",
257 "settings", "statusMessage", "world_atom") + \
258 ("_install_task",)
259 @@ -3564,7 +3600,7 @@
260 settings=settings, world_atom=world_atom)
261
262 self._install_task = build
263 - self._start_task(build, self._ebuild_exit)
264 + self._start_task(build, self._default_final_exit)
265 return
266
267 elif pkg.type_name == "binary":
268 @@ -3580,12 +3616,6 @@
269 self._start_task(binpkg, self._default_final_exit)
270 return
271
272 - def _ebuild_exit(self, build):
273 - if self._final_exit(build) != os.EX_OK:
274 - if self.build_opts.fetchonly:
275 - self.failed_fetches.append(self.pkg.cpv)
276 - self.wait()
277 -
278 def _poll(self):
279 self._install_task.poll()
280 return self.returncode
281 @@ -3598,7 +3628,6 @@
282
283 pkg = self.pkg
284 build_opts = self.build_opts
285 - failed_fetches = self.failed_fetches
286 find_blockers = self.find_blockers
287 logger = self.logger
288 mtimedb = self.mtimedb
289 @@ -7567,8 +7596,11 @@
290 if self._missing_args:
291 world_problems = False
292 if "world" in self._sets:
293 + # Filter out indirect members of world (from nested sets)
294 + # since only direct members of world are desired here.
295 + world_set = self.roots[self.target_root].sets["world"]
296 for arg, atom in self._missing_args:
297 - if arg.name == "world":
298 + if arg.name == "world" and atom in world_set:
299 world_problems = True
300 break
301
302 @@ -9022,8 +9054,7 @@
303 emergelog(self.xterm_titles, *pargs, **kwargs)
304
305 class _failed_pkg(SlotObject):
306 - __slots__ = ("build_dir", "build_log",
307 - "fetch_log", "pkg", "returncode")
308 + __slots__ = ("build_dir", "build_log", "pkg", "returncode")
309
310 class _ConfigPool(object):
311 """Interface for a task to temporarily allocate a config
312 @@ -9116,7 +9147,7 @@
313 self._failed_pkgs = []
314 self._failed_pkgs_all = []
315 self._failed_pkgs_die_msgs = []
316 - self._failed_fetches = []
317 + self._post_mod_echo_msgs = []
318 self._parallel_fetch = False
319 merge_count = len([x for x in mergelist \
320 if isinstance(x, Package) and x.operation == "merge"])
321 @@ -9156,7 +9187,7 @@
322 elif len(mergelist) > 1:
323 self._parallel_fetch = True
324
325 - if background or self._parallel_fetch:
326 + if self._parallel_fetch:
327 # clear out existing fetch log if it exists
328 try:
329 open(self._fetch_log, 'w')
330 @@ -9475,34 +9506,6 @@
331
332 return prefetcher
333
334 - def _show_failed_fetches(self):
335 - failed_fetches = self._failed_fetches
336 - if not failed_fetches or not \
337 - ("--fetchonly" in self.myopts or \
338 - "--fetch-all-uri" in self.myopts):
339 - return
340 -
341 - if self._background:
342 - msg = "Some fetch errors were " + \
343 - "encountered. Please see %s for details." % \
344 - self._fetch_log
345 - else:
346 - msg = "Some fetch errors were " + \
347 - "encountered. Please see above for details."
348 -
349 - prefix = bad(" * ")
350 - msg = "".join("%s%s\n" % (prefix, line) \
351 - for line in textwrap.wrap(msg, 70))
352 - writemsg_level(msg, level=logging.ERROR, noiselevel=-1)
353 -
354 - msg = []
355 - msg.append("")
356 - for cpv in failed_fetches:
357 - msg.append(" %s" % cpv)
358 - msg.append("")
359 - writemsg_level("".join("%s%s\n" % (prefix, line) \
360 - for line in msg), level=logging.ERROR, noiselevel=-1)
361 -
362 def _is_restart_scheduled(self):
363 """
364 Check if the merge list contains a replacement
365 @@ -9602,15 +9605,13 @@
366 return rval
367
368 keep_going = "--keep-going" in self.myopts
369 + fetchonly = self._build_opts.fetchonly
370 mtimedb = self._mtimedb
371 failed_pkgs = self._failed_pkgs
372
373 while True:
374 rval = self._merge()
375 - self._show_failed_fetches()
376 - del self._failed_fetches[:]
377 -
378 - if rval == os.EX_OK or not keep_going:
379 + if rval == os.EX_OK or fetchonly or not keep_going:
380 break
381 if "resume" not in mtimedb:
382 break
383 @@ -9630,29 +9631,13 @@
384 if not mergelist:
385 break
386
387 - dropped_tasks = self._calc_resume_list()
388 - if dropped_tasks is None:
389 + if not self._calc_resume_list():
390 break
391
392 clear_caches(self.trees)
393 if not self._mergelist:
394 break
395
396 - if dropped_tasks:
397 -
398 - def _eerror(lines):
399 - for l in lines:
400 - eerror(l, phase="other", key=failed_pkg.pkg.cpv)
401 -
402 - msg = []
403 - msg.append("One or more packages have been " + \
404 - "dropped due to unsatisfied dependencies:")
405 - msg.append("")
406 - msg.extend(" " + str(task) for task in dropped_tasks)
407 - msg.append("")
408 - _eerror(msg)
409 - del _eerror, msg
410 - del dropped_tasks
411 self._save_resume_list()
412 self._pkg_count.curval = 0
413 self._pkg_count.maxval = len([x for x in self._mergelist \
414 @@ -9691,10 +9676,15 @@
415 log_file.close()
416 failure_log_shown = True
417
418 + # Dump mod_echo output now since it tends to flood the terminal.
419 + # This allows us to avoid having more important output, generated
420 + # later, from being swept away by the mod_echo output.
421 + mod_echo_output = _flush_elog_mod_echo()
422 +
423 if background and not failure_log_shown and \
424 self._failed_pkgs_all and \
425 self._failed_pkgs_die_msgs and \
426 - not _flush_elog_mod_echo():
427 + not mod_echo_output:
428
429 printer = portage.output.EOutput()
430 for mysettings, key, logentries in self._failed_pkgs_die_msgs:
431 @@ -9714,8 +9704,11 @@
432 for line in msgcontent:
433 printer.eerror(line.strip("\n"))
434
435 + if self._post_mod_echo_msgs:
436 + for msg in self._post_mod_echo_msgs:
437 + msg()
438 +
439 if len(self._failed_pkgs_all) > 1:
440 - _flush_elog_mod_echo()
441 msg = "The following packages have " + \
442 "failed to build or install:"
443 prefix = bad(" * ")
444 @@ -9745,9 +9738,6 @@
445
446 log_paths = [failed_pkg.build_log]
447
448 - if not (build_dir and os.path.isdir(build_dir)):
449 - log_paths.append(failed_pkg.fetch_log)
450 -
451 for log_path in log_paths:
452 if not log_path:
453 continue
454 @@ -9787,11 +9777,10 @@
455 settings = merge.merge.settings
456 build_dir = settings.get("PORTAGE_BUILDDIR")
457 build_log = settings.get("PORTAGE_LOG_FILE")
458 - fetch_log = self._fetch_log
459
460 self._failed_pkgs.append(self._failed_pkg(
461 build_dir=build_dir, build_log=build_log,
462 - fetch_log=fetch_log, pkg=pkg,
463 + pkg=pkg,
464 returncode=merge.returncode))
465 self._failed_pkg_msg(self._failed_pkgs[-1], "install", "to")
466
467 @@ -9831,12 +9820,11 @@
468 else:
469 settings = build.settings
470 build_dir = settings.get("PORTAGE_BUILDDIR")
471 - fetch_log = self._fetch_log
472 build_log = settings.get("PORTAGE_LOG_FILE")
473
474 self._failed_pkgs.append(self._failed_pkg(
475 build_dir=build_dir, build_log=build_log,
476 - fetch_log=fetch_log, pkg=build.pkg,
477 + pkg=build.pkg,
478 returncode=build.returncode))
479 self._failed_pkg_msg(self._failed_pkgs[-1], "emerge", "for")
480
481 @@ -9998,6 +9986,10 @@
482 if self._poll_event_handlers:
483 self._poll_loop()
484
485 + def _keep_scheduling(self):
486 + return bool(self._pkg_queue and \
487 + not (self._failed_pkgs and not self._build_opts.fetchonly))
488 +
489 def _schedule_tasks(self):
490 self._schedule_tasks_imp()
491 self._status_display.display()
492 @@ -10009,7 +10001,7 @@
493
494 # Cancel prefetchers if they're the only reason
495 # the main poll loop is still running.
496 - if self._failed_pkgs and \
497 + if self._failed_pkgs and not self._build_opts.fetchonly and \
498 not (self._jobs or self._task_queues.merge) and \
499 self._task_queues.fetch:
500 self._task_queues.fetch.clear()
501 @@ -10019,7 +10011,7 @@
502 self._schedule_tasks_imp()
503 self._status_display.display()
504
505 - return bool(self._pkg_queue and not self._failed_pkgs)
506 + return self._keep_scheduling()
507
508 def _job_delay(self):
509 """
510 @@ -10049,7 +10041,7 @@
511
512 while True:
513
514 - if not self._pkg_queue or self._failed_pkgs:
515 + if not self._keep_scheduling():
516 return bool(state_change)
517
518 if self._choose_pkg_return_early or \
519 @@ -10106,7 +10098,6 @@
520 config_pool=self._ConfigPool(pkg.root,
521 self._allocate_config, self._deallocate_config),
522 emerge_opts=self.myopts,
523 - failed_fetches=self._failed_fetches,
524 find_blockers=self._find_blockers(pkg), logger=self._logger,
525 mtimedb=self._mtimedb, pkg=pkg, pkg_count=self._pkg_count.copy(),
526 pkg_to_replace=pkg_to_replace,
527 @@ -10165,9 +10156,8 @@
528 """
529 Use the current resume list to calculate a new one,
530 dropping any packages with unsatisfied deps.
531 - @rtype: set
532 - @returns: a possibly empty set of dropped tasks, or
533 - None if an error occurs.
534 + @rtype: bool
535 + @returns: True if successful, False otherwise.
536 """
537 print colorize("GOOD", "*** Resuming merge...")
538
539 @@ -10203,42 +10193,50 @@
540 print "\b\b... done!"
541
542 if e is not None:
543 - mydepgraph.display_problems()
544 - out = portage.output.EOutput()
545 - out.eerror("One or more packages are either masked or " + \
546 - "have missing dependencies:")
547 - out.eerror("")
548 - indent = " "
549 - for dep in e.value:
550 - if dep.atom is None:
551 - out.eerror(indent + "Masked package:")
552 - out.eerror(2 * indent + str(dep.parent))
553 - out.eerror("")
554 - else:
555 - out.eerror(indent + str(dep.atom) + " pulled in by:")
556 - out.eerror(2 * indent + str(dep.parent))
557 - out.eerror("")
558 - msg = "The resume list contains packages " + \
559 - "that are either masked or have " + \
560 - "unsatisfied dependencies. " + \
561 - "Please restart/continue " + \
562 - "the operation manually, or use --skipfirst " + \
563 - "to skip the first package in the list and " + \
564 - "any other packages that may be " + \
565 - "masked or have missing dependencies."
566 - for line in textwrap.wrap(msg, 72):
567 - out.eerror(line)
568 - return None
569 + def unsatisfied_resume_dep_msg():
570 + mydepgraph.display_problems()
571 + out = portage.output.EOutput()
572 + out.eerror("One or more packages are either masked or " + \
573 + "have missing dependencies:")
574 + out.eerror("")
575 + indent = " "
576 + show_parents = set()
577 + for dep in e.value:
578 + if dep.parent in show_parents:
579 + continue
580 + show_parents.add(dep.parent)
581 + if dep.atom is None:
582 + out.eerror(indent + "Masked package:")
583 + out.eerror(2 * indent + str(dep.parent))
584 + out.eerror("")
585 + else:
586 + out.eerror(indent + str(dep.atom) + " pulled in by:")
587 + out.eerror(2 * indent + str(dep.parent))
588 + out.eerror("")
589 + msg = "The resume list contains packages " + \
590 + "that are either masked or have " + \
591 + "unsatisfied dependencies. " + \
592 + "Please restart/continue " + \
593 + "the operation manually, or use --skipfirst " + \
594 + "to skip the first package in the list and " + \
595 + "any other packages that may be " + \
596 + "masked or have missing dependencies."
597 + for line in textwrap.wrap(msg, 72):
598 + out.eerror(line)
599 + self._post_mod_echo_msgs.append(unsatisfied_resume_dep_msg)
600 + return False
601
602 - if self._show_list():
603 + if success and self._show_list():
604 mylist = mydepgraph.altlist()
605 - if "--tree" in self.myopts:
606 - mylist.reverse()
607 - mydepgraph.display(mylist, favorites=self._favorites)
608 + if mylist:
609 + if "--tree" in self.myopts:
610 + mylist.reverse()
611 + mydepgraph.display(mylist, favorites=self._favorites)
612
613 + if not success:
614 + self._post_mod_echo_msgs.append(mydepgraph.display_problems)
615 + return False
616 mydepgraph.display_problems()
617 - if not success:
618 - return None
619
620 mylist = mydepgraph.altlist()
621 mydepgraph.break_refs(mylist)
622 @@ -10247,8 +10245,28 @@
623
624 self._mergelist = mylist
625 self._set_digraph(mydepgraph.digraph)
626 - return dropped_tasks
627
628 + msg_width = 75
629 + for task in dropped_tasks:
630 + if not (isinstance(task, Package) and task.operation == "merge"):
631 + continue
632 + pkg = task
633 + msg = "emerge --keep-going:" + \
634 + " %s" % (pkg.cpv,)
635 + if pkg.root != "/":
636 + msg += " for %s" % (pkg.root,)
637 + msg += " dropped due to unsatisfied dependency."
638 + for line in textwrap.wrap(msg, msg_width):
639 + eerror(line, phase="other", key=pkg.cpv)
640 + settings = mydepgraph.pkgsettings[pkg.root]
641 + # Ensure that log collection from $T is disabled inside
642 + # elog_process(), since any logs that might exist are
643 + # not valid here.
644 + settings.pop("T", None)
645 + portage.elog.elog_process(pkg.cpv, settings)
646 +
647 + return True
648 +
649 def _show_list(self):
650 myopts = self.myopts
651 if "--quiet" not in myopts and \
652
653 Modified: main/branches/prefix/pym/portage/__init__.py
654 ===================================================================
655 --- main/branches/prefix/pym/portage/__init__.py 2008-10-15 19:39:42 UTC (rev 11693)
656 +++ main/branches/prefix/pym/portage/__init__.py 2008-10-15 20:33:21 UTC (rev 11694)
657 @@ -3643,6 +3643,7 @@
658 del distlocks_subdir
659
660 distdir_writable = can_fetch and not fetch_to_ro
661 + failed_files = set()
662
663 for myfile in filedict:
664 """
665 @@ -4080,31 +4081,57 @@
666
667 if listonly:
668 writemsg_stdout("\n", noiselevel=-1)
669 - elif fetched != 2:
670 + if fetched != 2:
671 if restrict_fetch:
672 - print "\n!!!", mysettings["CATEGORY"] + "/" + \
673 - mysettings["PF"], "has fetch restriction turned on."
674 - print "!!! This probably means that this " + \
675 - "ebuild's files must be downloaded"
676 - print "!!! manually. See the comments in" + \
677 - " the ebuild for more information.\n"
678 - ebuild_phase = mysettings.get("EBUILD_PHASE")
679 - try:
680 - mysettings["EBUILD_PHASE"] = "nofetch"
681 - spawn(_shell_quote(EBUILD_SH_BINARY) + \
682 - " nofetch", mysettings)
683 - finally:
684 - if ebuild_phase is None:
685 - mysettings.pop("EBUILD_PHASE", None)
686 - else:
687 - mysettings["EBUILD_PHASE"] = ebuild_phase
688 + msg = ("\n!!! %s/%s" + \
689 + " has fetch restriction turned on.\n" + \
690 + "!!! This probably means that this " + \
691 + "ebuild's files must be downloaded\n" + \
692 + "!!! manually. See the comments in" + \
693 + " the ebuild for more information.\n\n") % \
694 + (mysettings["CATEGORY"], mysettings["PF"])
695 + portage.util.writemsg_level(msg,
696 + level=logging.ERROR, noiselevel=-1)
697 + if not parallel_fetchonly:
698 + # To spawn pkg_nofetch requires PORTAGE_BUILDDIR for
699 + # ensuring sane $PWD (bug #239560) and storing elog
700 + # messages. Therefore, calling code needs to ensure that
701 + # PORTAGE_BUILDDIR is already clean and locked here.
702 +
703 + # All the pkg_nofetch goes to stderr since it's considered
704 + # to be an error message.
705 + fd_pipes = {
706 + 0 : sys.stdin.fileno(),
707 + 1 : sys.stderr.fileno(),
708 + 2 : sys.stderr.fileno(),
709 + }
710 +
711 + ebuild_phase = mysettings.get("EBUILD_PHASE")
712 + try:
713 + mysettings["EBUILD_PHASE"] = "nofetch"
714 + spawn(_shell_quote(EBUILD_SH_BINARY) + \
715 + " nofetch", mysettings, fd_pipes=fd_pipes)
716 + finally:
717 + if ebuild_phase is None:
718 + mysettings.pop("EBUILD_PHASE", None)
719 + else:
720 + mysettings["EBUILD_PHASE"] = ebuild_phase
721 + if listonly:
722 + continue
723 + elif listonly:
724 + continue
725 elif not filedict[myfile]:
726 writemsg("Warning: No mirrors available for file" + \
727 " '%s'\n" % (myfile), noiselevel=-1)
728 else:
729 writemsg("!!! Couldn't download '%s'. Aborting.\n" % myfile,
730 noiselevel=-1)
731 + if fetchonly and not restrict_fetch:
732 + failed_files.add(myfile)
733 + continue
734 return 0
735 + if failed_files:
736 + return 0
737 return 1
738
739 def digestgen(myarchives, mysettings, overwrite=1, manifestonly=0, myportdb=None):
740 @@ -5479,8 +5506,7 @@
741
742 # Build directory creation isn't required for any of these.
743 have_build_dirs = False
744 - if not (mydo in ("digest", "help", "manifest") or \
745 - (mydo == "fetch" and listonly)):
746 + if not mydo in ("digest", "help", "manifest"):
747 mystatus = prepare_build_dirs(myroot, mysettings, cleanup)
748 if mystatus:
749 return mystatus
750
751 Modified: main/branches/prefix/pym/portage/dbapi/bintree.py
752 ===================================================================
753 --- main/branches/prefix/pym/portage/dbapi/bintree.py 2008-10-15 19:39:42 UTC (rev 11693)
754 +++ main/branches/prefix/pym/portage/dbapi/bintree.py 2008-10-15 20:33:21 UTC (rev 11694)
755 @@ -555,7 +555,8 @@
756 "unrecognized category: '%s'\n") % full_path,
757 noiselevel=-1)
758 writemsg(("!!! '%s' has a category that is not" + \
759 - " listed in /etc/portage/categories\n") % mycpv,
760 + " listed in %setc/portage/categories\n") % \
761 + (mycpv, self.settings["PORTAGE_CONFIGROOT"]),
762 noiselevel=-1)
763 continue
764 pkg_paths[mycpv] = mypath
765 @@ -723,7 +724,8 @@
766 "unrecognized category: '%s'\n") % fullpkg,
767 noiselevel=-1)
768 writemsg(("!!! '%s' has a category that is not" + \
769 - " listed in /etc/portage/categories\n") % fullpkg,
770 + " listed in %setc/portage/categories\n") % \
771 + (fullpkg, self.settings["PORTAGE_CONFIGROOT"]),
772 noiselevel=-1)
773 continue
774 mykey = dep_getkey(fullpkg)
775
776 Modified: main/branches/prefix/pym/portage/dbapi/porttree.py
777 ===================================================================
778 --- main/branches/prefix/pym/portage/dbapi/porttree.py 2008-10-15 19:39:42 UTC (rev 11693)
779 +++ main/branches/prefix/pym/portage/dbapi/porttree.py 2008-10-15 20:33:21 UTC (rev 11694)
780 @@ -728,7 +728,8 @@
781 d[mysplit[0]+"/"+pf] = None
782 if invalid_category and d:
783 writemsg(("\n!!! '%s' has a category that is not listed in " + \
784 - "/etc/portage/categories\n") % mycp, noiselevel=-1)
785 + "%setc/portage/categories\n") % \
786 + (mycp, self.mysettings["PORTAGE_CONFIGROOT"]), noiselevel=-1)
787 mylist = []
788 else:
789 mylist = d.keys()
790
791 Modified: main/branches/prefix/pym/portage/dbapi/vartree.py
792 ===================================================================
793 --- main/branches/prefix/pym/portage/dbapi/vartree.py 2008-10-15 19:39:42 UTC (rev 11693)
794 +++ main/branches/prefix/pym/portage/dbapi/vartree.py 2008-10-15 20:33:21 UTC (rev 11694)
795 @@ -1295,10 +1295,10 @@
796 # -MERGING- should never be a cpv, nor should files.
797 try:
798 if catpkgsplit(subpath) is None:
799 - self.invalidentry(os.path.join(self.root, subpath))
800 + self.invalidentry(self.getpath(subpath))
801 continue
802 except InvalidData:
803 - self.invalidentry(os.path.join(self.root, subpath))
804 + self.invalidentry(self.getpath(subpath))
805 continue
806 returnme.append(subpath)
807 return returnme
808
809 Modified: main/branches/prefix/pym/portage/elog/__init__.py
810 ===================================================================
811 --- main/branches/prefix/pym/portage/elog/__init__.py 2008-10-15 19:39:42 UTC (rev 11693)
812 +++ main/branches/prefix/pym/portage/elog/__init__.py 2008-10-15 20:33:21 UTC (rev 11694)
813 @@ -72,7 +72,13 @@
814 except ImportError:
815 pass
816
817 - ebuild_logentries = collect_ebuild_messages(os.path.join(mysettings["T"], "logging"))
818 + if "T" in mysettings:
819 + ebuild_logentries = collect_ebuild_messages(
820 + os.path.join(mysettings["T"], "logging"))
821 + else:
822 + # A build dir isn't necessarily required since the messages.e*
823 + # functions allow messages to be generated in-memory.
824 + ebuild_logentries = {}
825 all_logentries = collect_messages()
826 if cpv in all_logentries:
827 all_logentries[cpv] = _merge_logentries(ebuild_logentries, all_logentries[cpv])