1 |
Author: grobian |
2 |
Date: 2008-05-04 07:51:38 +0000 (Sun, 04 May 2008) |
3 |
New Revision: 10169 |
4 |
|
5 |
Modified: |
6 |
main/branches/prefix/bin/emerge-webrsync |
7 |
main/branches/prefix/pym/_emerge/__init__.py |
8 |
Log: |
9 |
Merged from trunk 10124:10149 |
10 |
|
11 |
| 10126 | Buf #219294 - Fix 'date' and 'cut' arguments for BSD | |
12 |
| zmedico | userland. Thanks to RB <aoz.syn@×××××.com> for this patch. | |
13 |
|
14 |
| 10127 | Use absolute paths for files in ${DISTDIR}. Thanks to RB | |
15 |
| zmedico | <aoz.syn@×××××.com> for this patch. | |
16 |
|
17 |
| 10130 | Similar to the circular dependency display, handle the | |
18 |
| zmedico | unsatisfied blocker display inside _serialize_tasks() since | |
19 |
| | that's a convenient place to bail out. | |
20 |
|
21 |
| 10132 | * Move circular deps and blocker displays to | |
22 |
| zmedico | depgraph.display_problems(). * Always call | |
23 |
| | display_problems() since calling it from inside display() | |
24 |
| | can lead to unwanted recursion. | |
25 |
|
26 |
| 10134 | Improve --resume handling of saved "favorites" argument | |
27 |
| zmedico | atoms: * Save the favorites in oneshot mode too since | |
28 |
| | they're still useful for restoring state upon --resume. * | |
29 |
| | Add a depgraph._load_favorites() method to resume state from | |
30 |
| | a previous select_files() call. This allows Package | |
31 |
| | instances to be matched with DependencyArg instances during | |
32 |
| | graph creation. | |
33 |
|
34 |
| 10136 | Fix logic so display_problems() gets called every time | |
35 |
| zmedico | display() does. | |
36 |
|
37 |
| 10137 | Fix display_problems() logic some more. | |
38 |
| zmedico | | |
39 |
|
40 |
| 10139 | When loadResumeCommand() rejects a resume list, give a more | |
41 |
| zmedico | informative explanation. | |
42 |
|
43 |
| 10141 | Don't clean out old resume lists when in --ask or --pretend | |
44 |
| zmedico | mode. | |
45 |
|
46 |
| 10143 | When a --resume list is rejected due to unsatisfied deps, | |
47 |
| zmedico | display a list of missing deps and which packages they | |
48 |
| | belong to. | |
49 |
|
50 |
| 10145 | When a resume list is rejected, display the invalid resume | |
51 |
| zmedico | list data in case the user is interested. This is enabled | |
52 |
| | with --verbose or --debug. | |
53 |
|
54 |
| 10147 | Validate all the data types inside BlockerCache._load() so | |
55 |
| zmedico | that any corruption is detected as soon as possible. | |
56 |
|
57 |
| 10149 | In BlockerData._load(), salvage as much cache as possible | |
58 |
| zmedico | when some seems to be corrupt. | |
59 |
|
60 |
|
61 |
Modified: main/branches/prefix/bin/emerge-webrsync |
62 |
=================================================================== |
63 |
--- main/branches/prefix/bin/emerge-webrsync 2008-05-04 07:49:43 UTC (rev 10168) |
64 |
+++ main/branches/prefix/bin/emerge-webrsync 2008-05-04 07:51:38 UTC (rev 10169) |
65 |
@@ -91,7 +91,11 @@ |
66 |
|
67 |
get_utc_second_from_string() { |
68 |
local s="$1" |
69 |
- date -d "${s:0:4}-${s:4:2}-${s:6:2}" -u +"%s" |
70 |
+ if [[ ${USERLAND} == BSD ]] ; then |
71 |
+ date -juf "%Y%m%d" "$s" +"%s" |
72 |
+ else |
73 |
+ date -d "${s:0:4}-${s:4:2}-${s:6:2}" -u +"%s" |
74 |
+ fi |
75 |
} |
76 |
|
77 |
get_portage_timestamp() { |
78 |
@@ -133,7 +137,7 @@ |
79 |
if type -P md5sum > /dev/null; then |
80 |
md5sum -c $digest && r=0 |
81 |
elif type -P md5 > /dev/null; then |
82 |
- [ "$(md5 -q $file)" == "$(cut -d \ -f 1 \"$digest\")" ] && r=0 |
83 |
+ [ "$(md5 -q "${file}")" == "$(cut -d ' ' -f 1 "${digest}")" ] && r=0 |
84 |
else |
85 |
eecho "cannot check digest: no suitable md5/md5sum binaries found" |
86 |
fi |
87 |
@@ -248,8 +252,8 @@ |
88 |
local signature="${file}.gpgsig" |
89 |
|
90 |
if [ -s "${file}" -a -s "${digest}" -a -s "${signature}" ] ; then |
91 |
- check_file_digest "${digest}" "${file}" && \ |
92 |
- check_file_signature "${signature}" "${file}" && \ |
93 |
+ check_file_digest "${DISTDIR}/${digest}" "${DISTDIR}/${file}" && \ |
94 |
+ check_file_signature "${DISTDIR}/${signature}" "${DISTDIR}/${file}" && \ |
95 |
have_files=1 |
96 |
fi |
97 |
|
98 |
@@ -257,8 +261,8 @@ |
99 |
fetch_file "${mirror}/snapshots/${digest}" "${digest}" && \ |
100 |
fetch_file "${mirror}/snapshots/${signature}" "${signature}" && \ |
101 |
fetch_file "${mirror}/snapshots/${file}" "${file}" && \ |
102 |
- check_file_digest "${digest}" "${file}" && \ |
103 |
- check_file_signature "${signature}" "${file}" && \ |
104 |
+ check_file_digest "${DISTDIR}/${digest}" "${DISTDIR}/${file}" && \ |
105 |
+ check_file_signature "${DISTDIR}/${signature}" "${DISTDIR}/${file}" && \ |
106 |
have_files=1 |
107 |
fi |
108 |
|
109 |
|
110 |
Modified: main/branches/prefix/pym/_emerge/__init__.py |
111 |
=================================================================== |
112 |
--- main/branches/prefix/pym/_emerge/__init__.py 2008-05-04 07:49:43 UTC (rev 10168) |
113 |
+++ main/branches/prefix/pym/_emerge/__init__.py 2008-05-04 07:51:38 UTC (rev 10169) |
114 |
@@ -1413,6 +1413,51 @@ |
115 |
isinstance(self._cache_data, dict) and \ |
116 |
self._cache_data.get("version") == self._cache_version and \ |
117 |
isinstance(self._cache_data.get("blockers"), dict) |
118 |
+ if cache_valid: |
119 |
+ # Validate all the atoms and counters so that |
120 |
+ # corruption is detected as soon as possible. |
121 |
+ invalid_items = set() |
122 |
+ for k, v in self._cache_data["blockers"].iteritems(): |
123 |
+ if not isinstance(k, basestring): |
124 |
+ invalid_items.add(k) |
125 |
+ continue |
126 |
+ try: |
127 |
+ if portage.catpkgsplit(k) is None: |
128 |
+ invalid_items.add(k) |
129 |
+ continue |
130 |
+ except portage.exception.InvalidData: |
131 |
+ invalid_items.add(k) |
132 |
+ continue |
133 |
+ if not isinstance(v, tuple) or \ |
134 |
+ len(v) != 2: |
135 |
+ invalid_items.add(k) |
136 |
+ continue |
137 |
+ counter, atoms = v |
138 |
+ if not isinstance(counter, (int, long)): |
139 |
+ invalid_items.add(k) |
140 |
+ continue |
141 |
+ if not isinstance(atoms, list): |
142 |
+ invalid_items.add(k) |
143 |
+ continue |
144 |
+ invalid_atom = False |
145 |
+ for atom in atoms: |
146 |
+ if not isinstance(atom, basestring): |
147 |
+ invalid_atom = True |
148 |
+ break |
149 |
+ if atom[:1] != "!" or \ |
150 |
+ not portage.isvalidatom( |
151 |
+ atom, allow_blockers=True): |
152 |
+ invalid_atom = True |
153 |
+ break |
154 |
+ if invalid_atom: |
155 |
+ invalid_items.add(k) |
156 |
+ continue |
157 |
+ |
158 |
+ for k in invalid_items: |
159 |
+ del self._cache_data["blockers"][k] |
160 |
+ if not self._cache_data["blockers"]: |
161 |
+ cache_valid = False |
162 |
+ |
163 |
if not cache_valid: |
164 |
self._cache_data = {"version":self._cache_version} |
165 |
self._cache_data["blockers"] = {} |
166 |
@@ -1780,6 +1825,8 @@ |
167 |
self._missing_args = [] |
168 |
self._masked_installed = [] |
169 |
self._unsatisfied_deps_for_display = [] |
170 |
+ self._unsatisfied_blockers_for_display = None |
171 |
+ self._circular_deps_for_display = None |
172 |
self._dep_stack = [] |
173 |
self._unsatisfied_deps = [] |
174 |
self._ignored_deps = [] |
175 |
@@ -1798,6 +1845,8 @@ |
176 |
if not self._slot_collision_info: |
177 |
return |
178 |
|
179 |
+ self._show_merge_list() |
180 |
+ |
181 |
msg = [] |
182 |
msg.append("\n!!! Multiple versions within a single " + \ |
183 |
"package slot have been pulled\n") |
184 |
@@ -2302,8 +2351,6 @@ |
185 |
root_config = self.roots[self.target_root] |
186 |
sets = root_config.sets |
187 |
getSetAtoms = root_config.setconfig.getSetAtoms |
188 |
- oneshot = "--oneshot" in self.myopts or \ |
189 |
- "--onlydeps" in self.myopts |
190 |
myfavorites=[] |
191 |
myroot = self.target_root |
192 |
dbs = self._filtered_trees[myroot]["dbs"] |
193 |
@@ -2427,8 +2474,7 @@ |
194 |
self._sets[s] = expanded_set |
195 |
args.append(SetArg(arg=x, set=expanded_set, |
196 |
root_config=root_config)) |
197 |
- if not oneshot: |
198 |
- myfavorites.append(x) |
199 |
+ myfavorites.append(x) |
200 |
continue |
201 |
if not is_valid_package_atom(x): |
202 |
portage.writemsg("\n\n!!! '%s' is not a valid package atom.\n" % x, |
203 |
@@ -2515,8 +2561,7 @@ |
204 |
if myatom in args_set: |
205 |
continue |
206 |
args_set.add(myatom) |
207 |
- if not oneshot: |
208 |
- myfavorites.append(myatom) |
209 |
+ myfavorites.append(myatom) |
210 |
self._set_atoms.update(chain(*self._sets.itervalues())) |
211 |
atom_arg_map = self._atom_arg_map |
212 |
for arg in args: |
213 |
@@ -3373,7 +3418,7 @@ |
214 |
|
215 |
return True |
216 |
|
217 |
- def _accept_collisions(self): |
218 |
+ def _accept_blocker_conflicts(self): |
219 |
acceptable = False |
220 |
for x in ("--buildpkgonly", "--fetchonly", |
221 |
"--fetch-all-uri", "--nodeps", "--pretend"): |
222 |
@@ -3746,43 +3791,7 @@ |
223 |
continue |
224 |
|
225 |
if not selected_nodes: |
226 |
- # No leaf nodes are available, so we have a circular |
227 |
- # dependency panic situation. Reduce the noise level to a |
228 |
- # minimum via repeated elimination of root nodes since they |
229 |
- # have no parents and thus can not be part of a cycle. |
230 |
- while True: |
231 |
- root_nodes = mygraph.root_nodes( |
232 |
- ignore_priority=DepPriority.MEDIUM_SOFT) |
233 |
- if not root_nodes: |
234 |
- break |
235 |
- for node in root_nodes: |
236 |
- mygraph.remove(node) |
237 |
- # Display the USE flags that are enabled on nodes that are part |
238 |
- # of dependency cycles in case that helps the user decide to |
239 |
- # disable some of them. |
240 |
- display_order = [] |
241 |
- tempgraph = mygraph.copy() |
242 |
- while not tempgraph.empty(): |
243 |
- nodes = tempgraph.leaf_nodes() |
244 |
- if not nodes: |
245 |
- node = tempgraph.order[0] |
246 |
- else: |
247 |
- node = nodes[0] |
248 |
- display_order.append(node) |
249 |
- tempgraph.remove(node) |
250 |
- display_order.reverse() |
251 |
- self.myopts.pop("--quiet", None) |
252 |
- self.myopts.pop("--verbose", None) |
253 |
- self.myopts["--tree"] = True |
254 |
- print |
255 |
- print |
256 |
- self.display(display_order) |
257 |
- print "!!! Error: circular dependencies:" |
258 |
- print |
259 |
- mygraph.debug_print() |
260 |
- print |
261 |
- print "!!! Note that circular dependencies can often be avoided by temporarily" |
262 |
- print "!!! disabling USE flags that trigger optional dependencies." |
263 |
+ self._circular_deps_for_display = mygraph |
264 |
raise self._unknown_internal_error() |
265 |
|
266 |
# At this point, we've succeeded in selecting one or more nodes, so |
267 |
@@ -3860,8 +3869,81 @@ |
268 |
self.myparams.add("complete") |
269 |
raise self._serialize_tasks_retry("") |
270 |
|
271 |
+ if unsolvable_blockers and \ |
272 |
+ not self._accept_blocker_conflicts(): |
273 |
+ self._unsatisfied_blockers_for_display = unsolvable_blockers |
274 |
+ self._serialized_tasks_cache = retlist[:] |
275 |
+ raise self._unknown_internal_error() |
276 |
+ |
277 |
+ if self._slot_collision_info and \ |
278 |
+ not self._accept_blocker_conflicts(): |
279 |
+ self._serialized_tasks_cache = retlist[:] |
280 |
+ raise self._unknown_internal_error() |
281 |
+ |
282 |
return retlist |
283 |
|
284 |
+ def _show_circular_deps(self, mygraph): |
285 |
+ # No leaf nodes are available, so we have a circular |
286 |
+ # dependency panic situation. Reduce the noise level to a |
287 |
+ # minimum via repeated elimination of root nodes since they |
288 |
+ # have no parents and thus can not be part of a cycle. |
289 |
+ while True: |
290 |
+ root_nodes = mygraph.root_nodes( |
291 |
+ ignore_priority=DepPriority.MEDIUM_SOFT) |
292 |
+ if not root_nodes: |
293 |
+ break |
294 |
+ mygraph.difference_update(root_nodes) |
295 |
+ # Display the USE flags that are enabled on nodes that are part |
296 |
+ # of dependency cycles in case that helps the user decide to |
297 |
+ # disable some of them. |
298 |
+ display_order = [] |
299 |
+ tempgraph = mygraph.copy() |
300 |
+ while not tempgraph.empty(): |
301 |
+ nodes = tempgraph.leaf_nodes() |
302 |
+ if not nodes: |
303 |
+ node = tempgraph.order[0] |
304 |
+ else: |
305 |
+ node = nodes[0] |
306 |
+ display_order.append(node) |
307 |
+ tempgraph.remove(node) |
308 |
+ display_order.reverse() |
309 |
+ self.myopts.pop("--quiet", None) |
310 |
+ self.myopts.pop("--verbose", None) |
311 |
+ self.myopts["--tree"] = True |
312 |
+ portage.writemsg("\n\n", noiselevel=-1) |
313 |
+ self.display(display_order) |
314 |
+ prefix = colorize("BAD", " * ") |
315 |
+ portage.writemsg("\n", noiselevel=-1) |
316 |
+ portage.writemsg(prefix + "Error: circular dependencies:\n", |
317 |
+ noiselevel=-1) |
318 |
+ portage.writemsg("\n", noiselevel=-1) |
319 |
+ mygraph.debug_print() |
320 |
+ portage.writemsg("\n", noiselevel=-1) |
321 |
+ portage.writemsg(prefix + "Note that circular dependencies " + \ |
322 |
+ "can often be avoided by temporarily\n", noiselevel=-1) |
323 |
+ portage.writemsg(prefix + "disabling USE flags that trigger " + \ |
324 |
+ "optional dependencies.\n", noiselevel=-1) |
325 |
+ |
326 |
+ def _show_merge_list(self): |
327 |
+ if self._serialized_tasks_cache is not None: |
328 |
+ display_list = self._serialized_tasks_cache[:] |
329 |
+ if "--tree" in self.myopts: |
330 |
+ display_list.reverse() |
331 |
+ self.display(display_list) |
332 |
+ |
333 |
+ def _show_unsatisied_blockers(self, blockers): |
334 |
+ self._show_merge_list() |
335 |
+ msg = "Error: The above package list contains " + \ |
336 |
+ "packages which cannot be installed " + \ |
337 |
+ "at the same time on the same system." |
338 |
+ prefix = colorize("BAD", " * ") |
339 |
+ from textwrap import wrap |
340 |
+ portage.writemsg("\n", noiselevel=-1) |
341 |
+ for line in wrap(msg, 70): |
342 |
+ portage.writemsg(prefix + line + "\n", noiselevel=-1) |
343 |
+ if "--quiet" not in self.myopts: |
344 |
+ show_blocker_docs_link() |
345 |
+ |
346 |
def display(self, mylist, favorites=[], verbosity=None): |
347 |
if verbosity is None: |
348 |
verbosity = ("--quiet" in self.myopts and 1 or \ |
349 |
@@ -4539,7 +4621,6 @@ |
350 |
sys.stdout.write(text) |
351 |
|
352 |
sys.stdout.flush() |
353 |
- self.display_problems() |
354 |
return os.EX_OK |
355 |
|
356 |
def display_problems(self): |
357 |
@@ -4551,17 +4632,16 @@ |
358 |
to ensure that the user is notified of problems with the graph. |
359 |
""" |
360 |
|
361 |
- task_list = self._serialized_tasks_cache |
362 |
+ if self._circular_deps_for_display is not None: |
363 |
+ self._show_circular_deps( |
364 |
+ self._circular_deps_for_display) |
365 |
|
366 |
- # Any blockers must be appended to the tail of the list, |
367 |
- # so we only need to check the last item. |
368 |
- have_blocker_conflict = bool(task_list and \ |
369 |
- (isinstance(task_list[-1], Blocker) and \ |
370 |
- not task_list[-1].satisfied)) |
371 |
- |
372 |
# The user is only notified of a slot conflict if |
373 |
# there are no unresolvable blocker conflicts. |
374 |
- if not have_blocker_conflict: |
375 |
+ if self._unsatisfied_blockers_for_display is not None: |
376 |
+ self._show_unsatisied_blockers( |
377 |
+ self._unsatisfied_blockers_for_display) |
378 |
+ else: |
379 |
self._show_slot_collision_notice() |
380 |
|
381 |
# TODO: Add generic support for "set problem" handlers so that |
382 |
@@ -4752,11 +4832,15 @@ |
383 |
Add a resume command to the graph and validate it in the process. This |
384 |
will raise a PackageNotFound exception if a package is not available. |
385 |
""" |
386 |
- self._sets["args"].update(resume_data.get("favorites", [])) |
387 |
- mergelist = resume_data.get("mergelist", []) |
388 |
+ |
389 |
+ if not isinstance(resume_data, dict): |
390 |
+ return False |
391 |
favorites = resume_data.get("favorites") |
392 |
- if not isinstance(favorites, list): |
393 |
- favorites = [] |
394 |
+ if isinstance(favorites, list): |
395 |
+ self._load_favorites(resume_data) |
396 |
+ mergelist = resume_data.get("mergelist") |
397 |
+ if not isinstance(mergelist, list): |
398 |
+ mergelist = [] |
399 |
|
400 |
if mergelist and "--skipfirst" in self.myopts: |
401 |
for i, task in enumerate(mergelist): |
402 |
@@ -4813,15 +4897,9 @@ |
403 |
if not serialized_tasks or "--nodeps" in self.myopts: |
404 |
self._serialized_tasks_cache = serialized_tasks |
405 |
else: |
406 |
- favorites_set = InternalPackageSet(atom for atom in favorites \ |
407 |
- if isinstance(atom, basestring) and portage.isvalidatom(atom)) |
408 |
- for node in serialized_tasks: |
409 |
- if isinstance(node, Package) and \ |
410 |
- node.operation == "merge" and \ |
411 |
- favorites_set.findAtomForPackage(node.cpv, node.metadata): |
412 |
- self._set_nodes.add(node) |
413 |
+ self._select_package = self._select_pkg_from_graph |
414 |
+ self.myparams.add("selective") |
415 |
|
416 |
- self._select_package = self._select_pkg_from_graph |
417 |
for task in serialized_tasks: |
418 |
if isinstance(task, Package) and \ |
419 |
task.operation == "merge": |
420 |
@@ -4836,22 +4914,84 @@ |
421 |
# This probably means that a required package |
422 |
# was dropped via --skipfirst. It makes the |
423 |
# resume list invalid, so convert it to a |
424 |
- # PackageNotFound exception. |
425 |
- raise portage.exception.PackageNotFound( |
426 |
- self._unsatisfied_deps[0].atom) |
427 |
+ # UnsatisfiedResumeDep exception. |
428 |
+ raise self.UnsatisfiedResumeDep( |
429 |
+ self._unsatisfied_deps) |
430 |
self._serialized_tasks_cache = None |
431 |
try: |
432 |
self.altlist() |
433 |
except self._unknown_internal_error: |
434 |
return False |
435 |
|
436 |
- for node in self.digraph.root_nodes(): |
437 |
- if isinstance(node, Package) and \ |
438 |
- node.operation == "merge": |
439 |
- # Give hint to the --tree display. |
440 |
- self._set_nodes.add(node) |
441 |
return True |
442 |
|
443 |
+ def _load_favorites(self, favorites): |
444 |
+ """ |
445 |
+ Use a list of favorites to resume state from a |
446 |
+ previous select_files() call. This creates similar |
447 |
+ DependencyArg instances to those that would have |
448 |
+ been created by the original select_files() call. |
449 |
+ This allows Package instances to be matched with |
450 |
+ DependencyArg instances during graph creation. |
451 |
+ """ |
452 |
+ root_config = self.roots[self.target_root] |
453 |
+ getSetAtoms = root_config.setconfig.getSetAtoms |
454 |
+ sets = root_config.sets |
455 |
+ args = [] |
456 |
+ for x in favorites: |
457 |
+ if not isinstance(x, basestring): |
458 |
+ continue |
459 |
+ if x in ("system", "world"): |
460 |
+ x = SETPREFIX + x |
461 |
+ if x.startswith(SETPREFIX): |
462 |
+ s = x[len(SETPREFIX):] |
463 |
+ if s not in sets: |
464 |
+ continue |
465 |
+ if s in self._sets: |
466 |
+ continue |
467 |
+ # Recursively expand sets so that containment tests in |
468 |
+ # self._get_parent_sets() properly match atoms in nested |
469 |
+ # sets (like if world contains system). |
470 |
+ expanded_set = InternalPackageSet( |
471 |
+ initial_atoms=getSetAtoms(s)) |
472 |
+ self._sets[s] = expanded_set |
473 |
+ args.append(SetArg(arg=x, set=expanded_set, |
474 |
+ root_config=root_config)) |
475 |
+ else: |
476 |
+ if not portage.isvalidatom(x): |
477 |
+ continue |
478 |
+ args.append(AtomArg(arg=x, atom=x, |
479 |
+ root_config=root_config)) |
480 |
+ |
481 |
+ # Create the "args" package set from atoms and |
482 |
+ # packages given as arguments. |
483 |
+ args_set = self._sets["args"] |
484 |
+ for arg in args: |
485 |
+ if not isinstance(arg, (AtomArg, PackageArg)): |
486 |
+ continue |
487 |
+ myatom = arg.atom |
488 |
+ if myatom in args_set: |
489 |
+ continue |
490 |
+ args_set.add(myatom) |
491 |
+ self._set_atoms.update(chain(*self._sets.itervalues())) |
492 |
+ atom_arg_map = self._atom_arg_map |
493 |
+ for arg in args: |
494 |
+ for atom in arg.set: |
495 |
+ atom_key = (atom, arg.root_config.root) |
496 |
+ refs = atom_arg_map.get(atom_key) |
497 |
+ if refs is None: |
498 |
+ refs = [] |
499 |
+ atom_arg_map[atom_key] = refs |
500 |
+ if arg not in refs: |
501 |
+ refs.append(arg) |
502 |
+ |
503 |
+ class UnsatisfiedResumeDep(portage.exception.PortageException): |
504 |
+ """ |
505 |
+ A dependency of a resume list is not installed. This |
506 |
+ can occur when a required package is dropped from the |
507 |
+ merge list via --skipfirst. |
508 |
+ """ |
509 |
+ |
510 |
class _internal_exception(portage.exception.PortageException): |
511 |
def __init__(self, value=""): |
512 |
portage.exception.PortageException.__init__(self, value) |
513 |
@@ -5198,6 +5338,8 @@ |
514 |
failed_fetches = [] |
515 |
fetchonly = "--fetchonly" in self.myopts or \ |
516 |
"--fetch-all-uri" in self.myopts |
517 |
+ oneshot = "--oneshot" in self.myopts or \ |
518 |
+ "--onlydeps" in self.myopts |
519 |
pretend = "--pretend" in self.myopts |
520 |
ldpath_mtimes = mtimedb["ldpath"] |
521 |
xterm_titles = "notitles" not in self.settings.features |
522 |
@@ -5551,10 +5693,8 @@ |
523 |
if retval != os.EX_OK: |
524 |
return retval |
525 |
#need to check for errors |
526 |
- if "--buildpkgonly" not in self.myopts: |
527 |
- self.trees[x[1]]["vartree"].inject(x[2]) |
528 |
- myfavkey = portage.cpv_getkey(x[2]) |
529 |
- if not fetchonly and not pretend and \ |
530 |
+ if not buildpkgonly: |
531 |
+ if not (fetchonly or oneshot or pretend) and \ |
532 |
args_set.findAtomForPackage(pkg_key, metadata): |
533 |
world_set.lock() |
534 |
world_set.load() # maybe it's changed on disk |
535 |
@@ -7707,6 +7847,7 @@ |
536 |
del myopts["--tree"] |
537 |
portage.writemsg(colorize("WARN", " * ") + \ |
538 |
"--tree is broken with --nodeps. Disabling...\n") |
539 |
+ debug = "--debug" in myopts |
540 |
verbose = "--verbose" in myopts |
541 |
quiet = "--quiet" in myopts |
542 |
if pretend or fetchonly: |
543 |
@@ -7760,44 +7901,65 @@ |
544 |
success = False |
545 |
try: |
546 |
success = mydepgraph.loadResumeCommand(mtimedb["resume"]) |
547 |
- except portage.exception.PackageNotFound: |
548 |
+ except (portage.exception.PackageNotFound, |
549 |
+ mydepgraph.UnsatisfiedResumeDep), e: |
550 |
if show_spinner: |
551 |
print |
552 |
+ from textwrap import wrap |
553 |
from portage.output import EOutput |
554 |
out = EOutput() |
555 |
- out.eerror("Error: The resume list contains packages that are no longer") |
556 |
- out.eerror(" available to be emerged. Please restart/continue") |
557 |
- out.eerror(" the merge operation manually.") |
558 |
+ |
559 |
+ resume_data = mtimedb["resume"] |
560 |
+ mergelist = resume_data.get("mergelist") |
561 |
+ if not isinstance(mergelist, list): |
562 |
+ mergelist = [] |
563 |
+ if mergelist and debug or (verbose and not quiet): |
564 |
+ out.eerror("Invalid resume list:") |
565 |
+ out.eerror("") |
566 |
+ indent = " " |
567 |
+ for task in mergelist: |
568 |
+ if isinstance(task, list): |
569 |
+ out.eerror(indent + str(tuple(task))) |
570 |
+ out.eerror("") |
571 |
+ |
572 |
+ if isinstance(e, mydepgraph.UnsatisfiedResumeDep): |
573 |
+ out.eerror("One or more expected dependencies " + \ |
574 |
+ "are not installed:") |
575 |
+ out.eerror("") |
576 |
+ indent = " " |
577 |
+ for dep in e.value: |
578 |
+ out.eerror(indent + str(dep.atom) + " pulled in by:") |
579 |
+ out.eerror(2 * indent + str(dep.parent)) |
580 |
+ out.eerror("") |
581 |
+ msg = "The resume list contains packages " + \ |
582 |
+ "with dependencies that have not been " + \ |
583 |
+ "installed yet. Please restart/continue " + \ |
584 |
+ "the operation manually." |
585 |
+ for line in wrap(msg, 72): |
586 |
+ out.eerror(line) |
587 |
+ elif isinstance(e, portage.exception.PackageNotFound): |
588 |
+ out.eerror("An expected package is " + \ |
589 |
+ "not available: %s" % str(e)) |
590 |
+ out.eerror("") |
591 |
+ msg = "The resume list contains one or more " + \ |
592 |
+ "packages that are no longer " + \ |
593 |
+ "available. Please restart/continue " + \ |
594 |
+ "the operation manually." |
595 |
+ for line in wrap(msg, 72): |
596 |
+ out.eerror(line) |
597 |
else: |
598 |
if show_spinner: |
599 |
print "\b\b... done!" |
600 |
|
601 |
- unsatisfied_block = False |
602 |
- if success: |
603 |
- mymergelist = mydepgraph.altlist() |
604 |
- if mymergelist and \ |
605 |
- (isinstance(mymergelist[-1], Blocker) and \ |
606 |
- not mymergelist[-1].satisfied): |
607 |
- if not fetchonly and not pretend: |
608 |
- unsatisfied_block = True |
609 |
- mydepgraph.display( |
610 |
- mydepgraph.altlist(reversed=tree), |
611 |
- favorites=favorites) |
612 |
- print "\n!!! Error: The above package list contains packages which cannot be installed" |
613 |
- print "!!! at the same time on the same system." |
614 |
- if not quiet: |
615 |
- show_blocker_docs_link() |
616 |
- |
617 |
if not success: |
618 |
mydepgraph.display_problems() |
619 |
+ if not (ask or pretend): |
620 |
+ # delete the current list and also the backup |
621 |
+ # since it's probably stale too. |
622 |
+ for k in ("resume", "resume_backup"): |
623 |
+ mtimedb.pop(k, None) |
624 |
+ mtimedb.commit() |
625 |
|
626 |
- if unsatisfied_block or not success: |
627 |
- # delete the current list and also the backup |
628 |
- # since it's probably stale too. |
629 |
- for k in ("resume", "resume_backup"): |
630 |
- mtimedb.pop(k, None) |
631 |
- mtimedb.commit() |
632 |
- |
633 |
return 1 |
634 |
else: |
635 |
if ("--resume" in myopts): |
636 |
@@ -7814,15 +7976,11 @@ |
637 |
except portage.exception.PackageNotFound, e: |
638 |
portage.writemsg("\n!!! %s\n" % str(e), noiselevel=-1) |
639 |
return 1 |
640 |
+ if show_spinner: |
641 |
+ print "\b\b... done!" |
642 |
if not retval: |
643 |
mydepgraph.display_problems() |
644 |
return 1 |
645 |
- if "--quiet" not in myopts and "--nodeps" not in myopts: |
646 |
- print "\b\b... done!" |
647 |
- display = pretend or \ |
648 |
- ((ask or tree or verbose) and not (quiet and not ask)) |
649 |
- if not display: |
650 |
- mydepgraph.display_problems() |
651 |
|
652 |
if "--pretend" not in myopts and \ |
653 |
("--ask" in myopts or "--tree" in myopts or \ |
654 |
@@ -7837,6 +7995,7 @@ |
655 |
retval = mydepgraph.display( |
656 |
mydepgraph.altlist(reversed=tree), |
657 |
favorites=favorites) |
658 |
+ mydepgraph.display_problems() |
659 |
if retval != os.EX_OK: |
660 |
return retval |
661 |
prompt="Would you like to resume merging these packages?" |
662 |
@@ -7844,21 +8003,14 @@ |
663 |
retval = mydepgraph.display( |
664 |
mydepgraph.altlist(reversed=("--tree" in myopts)), |
665 |
favorites=favorites) |
666 |
+ mydepgraph.display_problems() |
667 |
if retval != os.EX_OK: |
668 |
return retval |
669 |
mergecount=0 |
670 |
for x in mydepgraph.altlist(): |
671 |
- if isinstance(x, Blocker) and x.satisfied: |
672 |
- continue |
673 |
- if x[0] != "blocks" and x[3] != "nomerge": |
674 |
- mergecount+=1 |
675 |
- #check for blocking dependencies |
676 |
- if x[0]=="blocks" and "--fetchonly" not in myopts and "--fetch-all-uri" not in myopts: |
677 |
- print "\n!!! Error: The above package list contains packages which cannot be installed" |
678 |
- print "!!! at the same time on the same system." |
679 |
- if "--quiet" not in myopts: |
680 |
- show_blocker_docs_link() |
681 |
- return 1 |
682 |
+ if isinstance(x, Package) and x.operation == "merge": |
683 |
+ mergecount += 1 |
684 |
+ |
685 |
if mergecount==0: |
686 |
if "--noreplace" in myopts and favorites: |
687 |
print |
688 |
@@ -7895,12 +8047,14 @@ |
689 |
retval = mydepgraph.display( |
690 |
mydepgraph.altlist(reversed=tree), |
691 |
favorites=favorites) |
692 |
+ mydepgraph.display_problems() |
693 |
if retval != os.EX_OK: |
694 |
return retval |
695 |
else: |
696 |
retval = mydepgraph.display( |
697 |
mydepgraph.altlist(reversed=("--tree" in myopts)), |
698 |
favorites=favorites) |
699 |
+ mydepgraph.display_problems() |
700 |
if retval != os.EX_OK: |
701 |
return retval |
702 |
if "--buildpkgonly" in myopts: |
703 |
@@ -7962,30 +8116,6 @@ |
704 |
tree="porttree") |
705 |
|
706 |
pkglist = mydepgraph.altlist() |
707 |
- |
708 |
- if fetchonly or "--buildpkgonly" in myopts: |
709 |
- pkglist = [pkg for pkg in pkglist if pkg[0] != "blocks"] |
710 |
- else: |
711 |
- for x in pkglist: |
712 |
- if isinstance(x, Blocker) and x.satisfied: |
713 |
- continue |
714 |
- if x[0] != "blocks": |
715 |
- continue |
716 |
- retval = mydepgraph.display(mydepgraph.altlist( |
717 |
- reversed=("--tree" in myopts)), |
718 |
- favorites=favorites) |
719 |
- msg = "Error: The above package list contains " + \ |
720 |
- "packages which cannot be installed " + \ |
721 |
- "at the same time on the same system." |
722 |
- prefix = bad(" * ") |
723 |
- from textwrap import wrap |
724 |
- print |
725 |
- for line in wrap(msg, 70): |
726 |
- print prefix + line |
727 |
- if "--quiet" not in myopts: |
728 |
- show_blocker_docs_link() |
729 |
- return 1 |
730 |
- |
731 |
mydepgraph.saveNomergeFavorites() |
732 |
del mydepgraph |
733 |
mergetask = MergeTask(settings, trees, myopts) |
734 |
|
735 |
-- |
736 |
gentoo-commits@l.g.o mailing list |