2 # Copyright 1999-2006 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4 # $Id: emerge 5976 2007-02-17 09:14:53Z genone $
7 # This block ensures that ^C interrupts are handled quietly.
11 def exithandler(signum,frame):
12 signal.signal(signal.SIGINT, signal.SIG_IGN)
13 signal.signal(signal.SIGTERM, signal.SIG_IGN)
16 signal.signal(signal.SIGINT, exithandler)
17 signal.signal(signal.SIGTERM, exithandler)
18 signal.signal(signal.SIGPIPE, signal.SIG_DFL)
20 except KeyboardInterrupt:
25 os.environ["PORTAGE_LEGACY_GLOBALS"] = "false"
29 from os import path as osp
30 sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
32 del os.environ["PORTAGE_LEGACY_GLOBALS"]
33 from portage import digraph, portdbapi
34 from portage.const import NEWS_LIB_PATH, CACHE_PATH, PRIVATE_PATH
37 import portage.xpak, commands, errno, re, socket, time, types
38 from portage.output import blue, bold, colorize, darkblue, darkgreen, darkred, green, \
39 havecolor, nc_len, nocolor, red, teal, turquoise, white, xtermTitle, \
40 xtermTitleReset, yellow
41 from portage.output import create_color_func
42 good = create_color_func("GOOD")
43 bad = create_color_func("BAD")
44 # white looks bad on terminals with white background
45 from portage.output import bold as white
48 portage.dep._dep_check_strict = True
51 import portage.exception
52 from portage.data import secpass
53 from portage.util import normalize_path as normpath
54 from portage.util import writemsg
55 from portage.sets import InternalPackageSet
56 from portage.sets.profiles import PackagesSystemSet as SystemSet
57 from portage.sets.files import WorldSet
59 from itertools import chain, izip
60 from UserDict import DictMixin
65 import pickle as cPickle
67 class stdout_spinner(object):
69 "Gentoo Rocks ("+os.uname()[0]+")",
70 "Thank you for using Gentoo. :)",
71 "Are you actually trying to read this?",
72 "How many times have you stared at this?",
73 "We are generating the cache right now",
74 "You are paying too much attention.",
75 "A theory is better than its explanation.",
76 "Phasers locked on target, Captain.",
77 "Thrashing is just virtual crashing.",
78 "To be is to program.",
79 "Real Users hate Real Programmers.",
80 "When all else fails, read the instructions.",
81 "Functionality breeds Contempt.",
82 "The future lies ahead.",
83 "3.1415926535897932384626433832795028841971694",
84 "Sometimes insanity is the only alternative.",
85 "Inaccuracy saves a world of explanation.",
88 twirl_sequence = "/-\\|/-\\|/-\\|/-\\|\\-/|\\-/|\\-/|\\-/|"
92 self.update = self.update_twirl
93 self.scroll_sequence = self.scroll_msgs[
94 int(time.time() * 100) % len(self.scroll_msgs)]
96 def update_basic(self):
97 self.spinpos = (self.spinpos + 1) % 500
98 if (self.spinpos % 100) == 0:
100 sys.stdout.write(". ")
102 sys.stdout.write(".")
105 def update_scroll(self):
106 if(self.spinpos >= len(self.scroll_sequence)):
107 sys.stdout.write(darkgreen(" \b\b\b" + self.scroll_sequence[
108 len(self.scroll_sequence) - 1 - (self.spinpos % len(self.scroll_sequence))]))
110 sys.stdout.write(green("\b " + self.scroll_sequence[self.spinpos]))
112 self.spinpos = (self.spinpos + 1) % (2 * len(self.scroll_sequence))
114 def update_twirl(self):
115 self.spinpos = (self.spinpos + 1) % len(self.twirl_sequence)
116 sys.stdout.write("\b\b " + self.twirl_sequence[self.spinpos])
119 def update_quiet(self):
122 def userquery(prompt, responses=None, colours=None):
123 """Displays a prompt and a set of responses, then waits for a response
124 which is checked against the responses and the first to match is
125 returned. An empty response will match the first value in responses. The
126 input buffer is *not* cleared prior to the prompt!
129 responses: a List of Strings.
130 colours: a List of Functions taking and returning a String, used to
131 process the responses for display. Typically these will be functions
132 like red() but could be e.g. lambda x: "DisplayString".
133 If responses is omitted, defaults to ["Yes", "No"], [green, red].
134 If only colours is omitted, defaults to [bold, ...].
136 Returns a member of the List responses. (If called without optional
137 arguments, returns "Yes" or "No".)
138 KeyboardInterrupt is converted to SystemExit to avoid tracebacks being
140 if responses is None:
141 responses = ["Yes", "No"]
143 create_color_func("PROMPT_CHOICE_DEFAULT"),
144 create_color_func("PROMPT_CHOICE_OTHER")
146 elif colours is None:
148 colours=(colours*len(responses))[:len(responses)]
152 response=raw_input("["+"/".join([colours[i](responses[i]) for i in range(len(responses))])+"] ")
153 for key in responses:
154 # An empty response will match the first value in responses.
155 if response.upper()==key[:len(response)].upper():
157 print "Sorry, response '%s' not understood." % response,
158 except (EOFError, KeyboardInterrupt):
163 "clean", "config", "depclean",
165 "prune", "regen", "search",
166 "sync", "system", "unmerge", "world",
169 "--ask", "--alphabetical",
170 "--buildpkg", "--buildpkgonly",
171 "--changelog", "--columns",
175 "--fetchonly", "--fetch-all-uri",
176 "--getbinpkg", "--getbinpkgonly",
177 "--help", "--ignore-default-opts",
179 "--newuse", "--nocolor",
180 "--nodeps", "--noreplace",
181 "--nospinner", "--oneshot",
182 "--onlydeps", "--pretend",
183 "--quiet", "--resume",
184 "--searchdesc", "--selective",
188 "--usepkg", "--usepkgonly",
189 "--verbose", "--version"
195 "b":"--buildpkg", "B":"--buildpkgonly",
196 "c":"--clean", "C":"--unmerge",
197 "d":"--debug", "D":"--deep",
199 "f":"--fetchonly", "F":"--fetch-all-uri",
200 "g":"--getbinpkg", "G":"--getbinpkgonly",
202 "k":"--usepkg", "K":"--usepkgonly",
204 "n":"--noreplace", "N":"--newuse",
205 "o":"--onlydeps", "O":"--nodeps",
206 "p":"--pretend", "P":"--prune",
208 "s":"--search", "S":"--searchdesc",
211 "v":"--verbose", "V":"--version"
214 def emergelog(xterm_titles, mystr, short_msg=None):
216 if short_msg == None:
218 if "HOSTNAME" in os.environ:
219 short_msg = os.environ["HOSTNAME"]+": "+short_msg
220 xtermTitle(short_msg)
222 file_path = "/var/log/emerge.log"
223 mylogfile = open(file_path, "a")
224 portage.util.apply_secpass_permissions(file_path,
225 uid=portage.portage_uid, gid=portage.portage_gid,
229 mylock = portage.locks.lockfile(mylogfile)
230 # seek because we may have gotten held up by the lock.
231 # if so, we may not be positioned at the end of the file.
233 mylogfile.write(str(time.time())[:10]+": "+mystr+"\n")
237 portage.locks.unlockfile(mylock)
239 except (IOError,OSError,portage.exception.PortageException), e:
241 print >> sys.stderr, "emergelog():",e
243 def countdown(secs=5, doing="Starting"):
245 print ">>> Waiting",secs,"seconds before starting..."
246 print ">>> (Control-C to abort)...\n"+doing+" in: ",
250 sys.stdout.write(colorize("UNMERGE_WARN", str(sec+1)+" "))
255 # formats a size given in bytes nicely
256 def format_size(mysize):
257 if type(mysize) not in [types.IntType,types.LongType]:
259 if 0 != mysize % 1024:
260 # Always round up to the next kB so that it doesn't show 0 kB when
261 # some small file still needs to be fetched.
262 mysize += 1024 - mysize % 1024
263 mystr=str(mysize/1024)
267 mystr=mystr[:mycount]+","+mystr[mycount:]
271 def getgccversion(chost):
274 return: the current in-use gcc version
277 gcc_ver_command = 'gcc -dumpversion'
278 gcc_ver_prefix = 'gcc-'
280 gcc_not_found_error = red(
281 "!!! No gcc found. You probably need to 'source /etc/profile'\n" +
282 "!!! to update the environment of this terminal and possibly\n" +
283 "!!! other terminals also.\n"
286 mystatus, myoutput = commands.getstatusoutput("eselect compiler show")
287 if mystatus == os.EX_OK and len(myoutput.split("/")) == 2:
288 part1, part2 = myoutput.split("/")
289 if part1.startswith(chost + "-"):
290 return myoutput.replace(chost + "-", gcc_ver_prefix, 1)
292 mystatus, myoutput = commands.getstatusoutput("gcc-config -c")
293 if mystatus == os.EX_OK and myoutput.startswith(chost + "-"):
294 return myoutput.replace(chost + "-", gcc_ver_prefix, 1)
296 mystatus, myoutput = commands.getstatusoutput(
297 chost + "-" + gcc_ver_command)
298 if mystatus == os.EX_OK:
299 return gcc_ver_prefix + myoutput
301 mystatus, myoutput = commands.getstatusoutput(gcc_ver_command)
302 if mystatus == os.EX_OK:
303 return gcc_ver_prefix + myoutput
305 portage.writemsg(gcc_not_found_error, noiselevel=-1)
306 return "[unavailable]"
308 def getportageversion(portdir, target_root, profile, chost, vardb):
309 profilever = "unavailable"
311 realpath = os.path.realpath(profile)
312 basepath = os.path.realpath(os.path.join(portdir, "profiles"))
313 if realpath.startswith(basepath):
314 profilever = realpath[1 + len(basepath):]
317 profilever = "!" + os.readlink(profile)
320 del realpath, basepath
323 libclist = vardb.match("virtual/libc")
324 libclist += vardb.match("virtual/glibc")
325 libclist = portage.util.unique_array(libclist)
327 xs=portage.catpkgsplit(x)
329 libcver+=","+"-".join(xs[1:])
331 libcver="-".join(xs[1:])
333 libcver="unavailable"
335 gccver = getgccversion(chost)
336 unameout=os.uname()[2]+" "+os.uname()[4]
338 return "Portage " + portage.VERSION +" ("+profilever+", "+gccver+", "+libcver+", "+unameout+")"
340 def create_depgraph_params(myopts, myaction):
341 #configure emerge engine parameters
343 # self: include _this_ package regardless of if it is merged.
344 # selective: exclude the package if it is merged
345 # recurse: go into the dependencies
346 # deep: go into the dependencies of already merged packages
347 # empty: pretend nothing is merged
348 myparams = set(["recurse"])
349 if "--update" in myopts or \
350 "--newuse" in myopts or \
351 "--reinstall" in myopts or \
352 "--noreplace" in myopts or \
353 myaction in ("system", "world"):
354 myparams.add("selective")
355 if "--emptytree" in myopts:
356 myparams.add("empty")
357 myparams.discard("selective")
358 if "--nodeps" in myopts:
359 myparams.discard("recurse")
360 if "--deep" in myopts:
364 # search functionality
365 class search(object):
376 def __init__(self, settings, portdb, vartree, spinner, searchdesc,
378 """Searches the available and installed packages for the supplied search key.
379 The list of available and installed packages is created at object instantiation.
380 This makes successive searches faster."""
381 self.settings = settings
383 self.vartree = vartree
384 self.spinner = spinner
385 self.verbose = verbose
386 self.searchdesc = searchdesc
388 def execute(self,searchkey):
389 """Performs the search for the supplied search key"""
391 self.searchkey=searchkey
392 self.packagematches = []
395 self.matches = {"pkg":[], "desc":[]}
398 self.matches = {"pkg":[]}
399 print "Searching... ",
402 if self.searchkey.startswith('%'):
404 self.searchkey = self.searchkey[1:]
405 if self.searchkey.startswith('@'):
407 self.searchkey = self.searchkey[1:]
409 self.searchre=re.compile(self.searchkey,re.I)
411 self.searchre=re.compile(re.escape(self.searchkey), re.I)
412 for package in self.portdb.cp_all():
413 self.spinner.update()
416 match_string = package[:]
418 match_string = package.split("/")[-1]
421 if self.searchre.search(match_string):
422 if not self.portdb.xmatch("match-visible", package):
424 self.matches["pkg"].append([package,masked])
425 elif self.searchdesc: # DESCRIPTION searching
426 full_package = self.portdb.xmatch("bestmatch-visible", package)
428 #no match found; we don't want to query description
429 full_package = portage.best(
430 self.portdb.xmatch("match-all", package))
436 full_desc = self.portdb.aux_get(
437 full_package, ["DESCRIPTION"])[0]
439 print "emerge: search: aux_get() failed, skipping"
441 if self.searchre.search(full_desc):
442 self.matches["desc"].append([full_package,masked])
444 for mtype in self.matches:
445 self.matches[mtype].sort()
446 self.mlen += len(self.matches[mtype])
449 """Outputs the results of the search."""
450 print "\b\b \n[ Results for search key : "+white(self.searchkey)+" ]"
451 print "[ Applications found : "+white(str(self.mlen))+" ]"
453 for mtype in self.matches:
454 for match,masked in self.matches[mtype]:
457 full_package = self.portdb.xmatch(
458 "bestmatch-visible", match)
460 #no match found; we don't want to query description
462 full_package = portage.best(
463 self.portdb.xmatch("match-all",match))
466 match = portage.pkgsplit(match)[0]
470 desc, homepage, license = self.portdb.aux_get(
471 full_package, ["DESCRIPTION","HOMEPAGE","LICENSE"])
473 print "emerge: search: aux_get() failed, skipping"
476 print green("*")+" "+white(match)+" "+red("[ Masked ]")
478 print green("*")+" "+white(match)
479 myversion = self.getVersion(full_package, search.VERSION_RELEASE)
482 mycat = match.split("/")[0]
483 mypkg = match.split("/")[1]
484 mycpv = match + "-" + myversion
485 myebuild = self.portdb.findname(mycpv)
486 pkgdir = os.path.dirname(myebuild)
487 from portage import manifest
488 mf = manifest.Manifest(
489 pkgdir, self.settings["DISTDIR"])
490 fetchlist = self.portdb.getfetchlist(mycpv,
491 mysettings=self.settings, all=True)[1]
493 mysum[0] = mf.getDistfilesSize(fetchlist)
494 mystr = str(mysum[0]/1024)
498 mystr=mystr[:mycount]+","+mystr[mycount:]
501 mysum[0] = "Unknown (missing digest for %s)" % str(e)
504 print " ", darkgreen("Latest version available:"),myversion
505 print " ", self.getInstallationStatus(mycat+'/'+mypkg)
506 print " ", darkgreen("Size of files:"),mysum[0]
507 print " ", darkgreen("Homepage:")+" ",homepage
508 print " ", darkgreen("Description:")+" ",desc
509 print " ", darkgreen("License:")+" ",license
515 def getInstallationStatus(self,package):
516 installed_package = self.vartree.dep_bestmatch(package)
518 version = self.getVersion(installed_package,search.VERSION_RELEASE)
520 result = darkgreen("Latest version installed:")+" "+version
522 result = darkgreen("Latest version installed:")+" [ Not Installed ]"
525 def getVersion(self,full_package,detail):
526 if len(full_package) > 1:
527 package_parts = portage.catpkgsplit(full_package)
528 if detail == search.VERSION_RELEASE and package_parts[3] != 'r0':
529 result = package_parts[2]+ "-" + package_parts[3]
531 result = package_parts[2]
537 #build our package digraph
538 def getlist(settings, mode):
540 mylines = settings.packages
543 file_path = os.path.join(settings["ROOT"], portage.WORLD_FILE)
544 myfile = open(file_path, "r")
545 mylines = myfile.readlines()
547 except (OSError, IOError), e:
548 if e.errno == errno.ENOENT:
549 portage.writemsg("\n!!! World file does not exist: '%s'\n" % file_path)
555 myline=" ".join(x.split())
564 mynewlines.append(myline.strip())
568 def clean_world(vardb, cpv):
569 """Remove a package from the world file when unmerged."""
570 world_set = WorldSet("world", vardb.settings["ROOT"])
572 worldlist = list(world_set) # loads latest from disk
573 mykey = portage.cpv_getkey(cpv)
576 if portage.dep_getkey(x) == mykey:
577 matches = vardb.match(x, use_cache=0)
581 elif len(matches) == 1 and matches[0] == cpv:
585 #others are around; keep it.
586 newworldlist.append(x)
588 #this doesn't match the package we're unmerging; keep it.
589 newworldlist.append(x)
591 world_set.replace(newworldlist)
595 class RootConfig(object):
596 """This is used internally by depgraph to track information about a
598 def __init__(self, trees):
600 self.settings = trees["vartree"].settings
601 self.root = self.settings["ROOT"]
603 world_set = WorldSet("world", self.root)
604 self.sets["world"] = world_set
605 system_set = SystemSet("system", self.settings.profiles)
606 self.sets["system"] = system_set
608 def create_world_atom(pkg_key, metadata, args_set, root_config):
609 """Create a new atom for the world file if one does not exist. If the
610 argument atom is precise enough to identify a specific slot then a slot
611 atom will be returned. Atoms that are in the system set may also be stored
612 in world since system atoms can only match one slot while world atoms can
613 be greedy with respect to slots. Unslotted system packages will not be
615 arg_atom = args_set.findAtomForPackage(pkg_key, metadata)
616 cp = portage.dep_getkey(arg_atom)
618 sets = root_config.sets
619 portdb = root_config.trees["porttree"].dbapi
620 vardb = root_config.trees["vartree"].dbapi
621 available_slots = set(portdb.aux_get(cpv, ["SLOT"])[0] \
622 for cpv in portdb.match(cp))
623 slotted = len(available_slots) > 1 or \
624 (len(available_slots) == 1 and "0" not in available_slots)
626 # check the vdb in case this is multislot
627 available_slots = set(vardb.aux_get(cpv, ["SLOT"])[0] \
628 for cpv in vardb.match(cp))
629 slotted = len(available_slots) > 1 or \
630 (len(available_slots) == 1 and "0" not in available_slots)
631 if slotted and arg_atom != cp:
632 # If the user gave a specific atom, store it as a
633 # slot atom in the world file.
634 slot_atom = "%s:%s" % (cp, metadata["SLOT"])
635 # First verify the slot is in the portage tree to avoid
636 # adding a bogus slot like that produced by multislot.
637 if portdb.match(slot_atom):
638 # Now verify that the argument is precise enough to identify a
640 matches = portdb.match(arg_atom)
641 matched_slots = set()
643 matched_slots.add(portdb.aux_get(cpv, ["SLOT"])[0])
644 if len(matched_slots) == 1:
645 new_world_atom = slot_atom
646 if new_world_atom == sets["world"].findAtomForPackage(pkg_key, metadata):
647 # Both atoms would be identical, so there's nothing to add.
650 # Unlike world atoms, system atoms are not greedy for slots, so they
651 # can't be safely excluded from world if they are slotted.
652 system_atom = sets["system"].findAtomForPackage(pkg_key, metadata)
654 if not portage.dep_getkey(system_atom).startswith("virtual/"):
656 # System virtuals aren't safe to exclude from world since they can
657 # match multiple old-style virtuals but only one of them will be
658 # pulled in by update or depclean.
659 providers = portdb.mysettings.getvirtuals().get(
660 portage.dep_getkey(system_atom))
661 if providers and len(providers) == 1 and providers[0] == cp:
663 return new_world_atom
665 def filter_iuse_defaults(iuse):
667 if flag.startswith("+") or flag.startswith("-"):
672 class DepPriority(object):
674 This class generates an integer priority level based of various
675 attributes of the dependency relationship. Attributes can be assigned
676 at any time and the new integer value will be generated on calls to the
677 __int__() method. Rich comparison operators are supported.
679 The boolean attributes that affect the integer value are "satisfied",
680 "buildtime", "runtime", and "system". Various combinations of
681 attributes lead to the following priority levels:
683 Combination of properties Priority level
685 not satisfied and buildtime 0
686 not satisfied and runtime -1
687 satisfied and buildtime -2
688 satisfied and runtime -3
689 (none of the above) -4
691 Several integer constants are defined for categorization of priority
694 MEDIUM The upper boundary for medium dependencies.
695 MEDIUM_SOFT The upper boundary for medium-soft dependencies.
696 SOFT The upper boundary for soft dependencies.
697 MIN The lower boundary for soft dependencies.
699 __slots__ = ("__weakref__", "satisfied", "buildtime", "runtime", "runtime_post")
704 def __init__(self, **kwargs):
705 for myattr in self.__slots__:
706 if myattr == "__weakref__":
708 myvalue = kwargs.get(myattr, False)
709 setattr(self, myattr, myvalue)
711 if not self.satisfied:
716 if self.runtime_post:
722 if self.runtime_post:
725 def __lt__(self, other):
726 return self.__int__() < other
727 def __le__(self, other):
728 return self.__int__() <= other
729 def __eq__(self, other):
730 return self.__int__() == other
731 def __ne__(self, other):
732 return self.__int__() != other
733 def __gt__(self, other):
734 return self.__int__() > other
735 def __ge__(self, other):
736 return self.__int__() >= other
739 return copy.copy(self)
741 myvalue = self.__int__()
742 if myvalue > self.MEDIUM:
744 if myvalue > self.MEDIUM_SOFT:
746 if myvalue > self.SOFT:
750 class FakeVartree(portage.vartree):
751 """This is implements an in-memory copy of a vartree instance that provides
752 all the interfaces required for use by the depgraph. The vardb is locked
753 during the constructor call just long enough to read a copy of the
754 installed package information. This allows the depgraph to do it's
755 dependency calculations without holding a lock on the vardb. It also
756 allows things like vardb global updates to be done in memory so that the
757 user doesn't necessarily need write access to the vardb in cases where
758 global updates are necessary (updates are performed when necessary if there
759 is not a matching ebuild in the tree)."""
760 def __init__(self, real_vartree, portdb):
761 self.root = real_vartree.root
762 self.settings = real_vartree.settings
763 self.dbapi = portage.fakedbapi(settings=real_vartree.settings)
764 vdb_path = os.path.join(self.root, portage.VDB_PATH)
766 # At least the parent needs to exist for the lock file.
767 portage.util.ensure_dirs(vdb_path)
768 except portage.exception.PortageException:
772 if os.access(vdb_path, os.W_OK):
773 vdb_lock = portage.locks.lockdir(vdb_path)
774 mykeys = ["SLOT", "COUNTER", "PROVIDE", "USE", "IUSE",
775 "RESTRICT", "DEPEND", "RDEPEND", "PDEPEND", "repository"]
776 real_dbapi = real_vartree.dbapi
778 for cpv in real_dbapi.cpv_all():
779 metadata = dict(izip(mykeys, real_dbapi.aux_get(cpv, mykeys)))
780 myslot = metadata["SLOT"]
781 mycp = portage.dep_getkey(cpv)
782 myslot_atom = "%s:%s" % (mycp, myslot)
784 mycounter = long(metadata["COUNTER"])
787 metadata["COUNTER"] = str(mycounter)
788 other_counter = slot_counters.get(myslot_atom, None)
789 if other_counter is not None:
790 if other_counter > mycounter:
792 slot_counters[myslot_atom] = mycounter
793 self.dbapi.cpv_inject(cpv, metadata=metadata)
794 real_dbapi.flush_cache()
797 portage.locks.unlockdir(vdb_lock)
798 # Populate the old-style virtuals using the cached values.
799 if not self.settings.treeVirtuals:
800 self.settings.treeVirtuals = portage.util.map_dictlist_vals(
801 portage.getCPFromCPV, self.get_all_provides())
803 # Intialize variables needed for lazy cache pulls of the live ebuild
804 # metadata. This ensures that the vardb lock is released ASAP, without
805 # being delayed in case cache generation is triggered.
806 self._aux_get = self.dbapi.aux_get
807 self.dbapi.aux_get = self._aux_get_wrapper
808 self._aux_get_history = set()
809 self._portdb_keys = ["DEPEND", "RDEPEND", "PDEPEND"]
810 self._portdb = portdb
811 self._global_updates = None
813 def _aux_get_wrapper(self, pkg, wants):
814 if pkg in self._aux_get_history:
815 return self._aux_get(pkg, wants)
816 self._aux_get_history.add(pkg)
818 # Use the live ebuild metadata if possible.
819 live_metadata = dict(izip(self._portdb_keys,
820 self._portdb.aux_get(pkg, self._portdb_keys)))
821 self.dbapi.aux_update(pkg, live_metadata)
822 except (KeyError, portage.exception.PortageException):
823 if self._global_updates is None:
824 self._global_updates = \
825 grab_global_updates(self._portdb.porttree_root)
826 perform_global_updates(
827 pkg, self.dbapi, self._global_updates)
828 return self._aux_get(pkg, wants)
830 def grab_global_updates(portdir):
831 from portage.update import grab_updates, parse_updates
832 updpath = os.path.join(portdir, "profiles", "updates")
834 rawupdates = grab_updates(updpath)
835 except portage.exception.DirectoryNotFound:
838 for mykey, mystat, mycontent in rawupdates:
839 commands, errors = parse_updates(mycontent)
840 upd_commands.extend(commands)
843 def perform_global_updates(mycpv, mydb, mycommands):
844 from portage.update import update_dbentries
845 aux_keys = ["DEPEND", "RDEPEND", "PDEPEND"]
846 aux_dict = dict(izip(aux_keys, mydb.aux_get(mycpv, aux_keys)))
847 updates = update_dbentries(mycommands, aux_dict)
849 mydb.aux_update(mycpv, updates)
851 class BlockerCache(DictMixin):
852 """This caches blockers of installed packages so that dep_check does not
853 have to be done for every single installed package on every invocation of
854 emerge. The cache is invalidated whenever it is detected that something
855 has changed that might alter the results of dep_check() calls:
856 1) the set of installed packages (including COUNTER) has changed
857 2) the old-style virtuals have changed
859 class BlockerData(object):
860 def __init__(self, counter, atoms):
861 self.counter = counter
864 def __init__(self, myroot, vardb):
866 self._installed_pkgs = set(vardb.cpv_all())
867 self._virtuals = vardb.settings.getvirtuals()
868 self._cache_filename = os.path.join(myroot,
869 portage.CACHE_PATH.lstrip(os.path.sep), "vdb_blockers.pickle")
870 self._cache_version = "1"
871 self._cache_data = None
872 self._modified = False
877 f = open(self._cache_filename)
878 mypickle = cPickle.Unpickler(f)
879 mypickle.find_global = None
880 self._cache_data = mypickle.load()
883 except (IOError, OSError, EOFError, cPickle.UnpicklingError):
885 cache_valid = self._cache_data and \
886 isinstance(self._cache_data, dict) and \
887 self._cache_data.get("version") == self._cache_version and \
888 self._cache_data.get("virtuals") == self._virtuals and \
889 set(self._cache_data.get("blockers", [])) == self._installed_pkgs
891 for pkg in self._installed_pkgs:
892 if long(self._vardb.aux_get(pkg, ["COUNTER"])[0]) != \
897 self._cache_data = {"version":self._cache_version}
898 self._cache_data["blockers"] = {}
899 self._cache_data["virtuals"] = self._virtuals
900 self._modified = False
903 """If the current user has permission and the internal blocker cache
904 been updated, save it to disk and mark it unmodified. This is called
905 by emerge after it has proccessed blockers for all installed packages.
906 Currently, the cache is only written if the user has superuser
907 privileges (since that's required to obtain a lock), but all users
908 have read access and benefit from faster blocker lookups (as long as
909 the entire cache is still valid). The cache is stored as a pickled
910 dict object with the following format:
914 "blockers" : {cpv1:(counter,(atom1, atom2...)), cpv2...},
915 "virtuals" : vardb.settings.getvirtuals()
918 if self._modified and \
921 f = portage.util.atomic_ofstream(self._cache_filename)
922 cPickle.dump(self._cache_data, f, -1)
924 portage.util.apply_secpass_permissions(
925 self._cache_filename, gid=portage.portage_gid, mode=0644)
926 except (IOError, OSError), e:
928 self._modified = False
930 def __setitem__(self, cpv, blocker_data):
932 Update the cache and mark it as modified for a future call to
935 @param cpv: Package for which to cache blockers.
937 @param blocker_data: An object with counter and atoms attributes.
938 @type blocker_data: BlockerData
940 self._cache_data["blockers"][cpv] = \
941 (blocker_data.counter, blocker_data.atoms)
942 self._modified = True
944 def __getitem__(self, cpv):
947 @returns: An object with counter and atoms attributes.
949 return self.BlockerData(*self._cache_data["blockers"][cpv])
952 """This needs to be implemented so that self.__repr__() doesn't raise
953 an AttributeError."""
954 if self._cache_data and "blockers" in self._cache_data:
955 return self._cache_data["blockers"].keys()
958 def show_invalid_depstring_notice(parent_node, depstring, error_msg):
960 from formatter import AbstractFormatter, DumbWriter
961 f = AbstractFormatter(DumbWriter(maxcol=72))
963 print "\n\n!!! Invalid or corrupt dependency specification: "
971 p_type, p_root, p_key, p_status = parent_node
973 if p_status == "nomerge":
974 category, pf = portage.catsplit(p_key)
975 pkg_location = os.path.join(p_root, portage.VDB_PATH, category, pf)
976 msg.append("Portage is unable to process the dependencies of the ")
977 msg.append("'%s' package. " % p_key)
978 msg.append("In order to correct this problem, the package ")
979 msg.append("should be uninstalled, reinstalled, or upgraded. ")
980 msg.append("As a temporary workaround, the --nodeps option can ")
981 msg.append("be used to ignore all dependencies. For reference, ")
982 msg.append("the problematic dependencies can be found in the ")
983 msg.append("*DEPEND files located in '%s/'." % pkg_location)
985 msg.append("This package can not be installed. ")
986 msg.append("Please notify the '%s' package maintainer " % p_key)
987 msg.append("about this problem.")
990 f.add_flowing_data(x)
993 class depgraph(object):
998 "installed":"vartree"}
1000 def __init__(self, settings, trees, myopts, myparams, spinner):
1001 self.settings = settings
1002 self.target_root = settings["ROOT"]
1003 self.myopts = myopts
1004 self.myparams = myparams
1006 if settings.get("PORTAGE_DEBUG", "") == "1":
1008 self.spinner = spinner
1009 self.pkgsettings = {}
1010 # Maps cpv to digraph node for all nodes added to the graph.
1011 self.pkg_node_map = {}
1012 # Maps slot atom to digraph node for all nodes added to the graph.
1013 self._slot_node_map = {}
1014 # Maps nodes to the reasons they were selected for reinstallation.
1015 self._reinstall_nodes = {}
1017 self._mydbapi_keys = ["SLOT", "DEPEND", "RDEPEND", "PDEPEND",
1018 "USE", "IUSE", "PROVIDE", "RESTRICT", "repository"]
1022 for myroot in trees:
1023 self.trees[myroot] = {}
1024 for tree in ("porttree", "bintree"):
1025 self.trees[myroot][tree] = trees[myroot][tree]
1026 self.trees[myroot]["vartree"] = \
1027 FakeVartree(trees[myroot]["vartree"],
1028 trees[myroot]["porttree"].dbapi)
1029 self.pkgsettings[myroot] = portage.config(
1030 clone=self.trees[myroot]["vartree"].settings)
1031 self.pkg_node_map[myroot] = {}
1032 self._slot_node_map[myroot] = {}
1033 vardb = self.trees[myroot]["vartree"].dbapi
1034 self.roots[myroot] = RootConfig(self.trees[myroot])
1035 # This fakedbapi instance will model the state that the vdb will
1036 # have after new packages have been installed.
1037 fakedb = portage.fakedbapi(settings=self.pkgsettings[myroot])
1038 self.mydbapi[myroot] = fakedb
1039 if "--nodeps" not in self.myopts and \
1040 "--buildpkgonly" not in self.myopts:
1041 # --nodeps bypasses this, since it isn't needed in this case
1042 # and the cache pulls might trigger (slow) cache generation.
1043 for pkg in vardb.cpv_all():
1044 self.spinner.update()
1045 fakedb.cpv_inject(pkg,
1046 metadata=dict(izip(self._mydbapi_keys,
1047 vardb.aux_get(pkg, self._mydbapi_keys))))
1049 self.useFlags[myroot] = {}
1050 if "--usepkg" in self.myopts:
1051 self.trees[myroot]["bintree"].populate(
1052 "--getbinpkg" in self.myopts,
1053 "--getbinpkgonly" in self.myopts)
1057 self.digraph=portage.digraph()
1058 # Tracks simple parent/child relationships (PDEPEND relationships are
1060 self._parent_child_digraph = digraph()
1062 self.outdatedpackages=[]
1063 # contains all sets added to the graph
1065 # contains atoms given as arguments
1066 self._sets["args"] = InternalPackageSet()
1067 # contains all atoms from all sets added to the graph, including
1068 # atoms given as arguments
1069 self._set_atoms = InternalPackageSet()
1070 # contains all nodes pulled in by self._set_atoms
1071 self._set_nodes = set()
1072 self.blocker_digraph = digraph()
1073 self.blocker_parents = {}
1074 self._unresolved_blocker_parents = {}
1075 self._slot_collision_info = []
1076 # Slot collision nodes are not allowed to block other packages since
1077 # blocker validation is only able to account for one package per slot.
1078 self._slot_collision_nodes = set()
1079 self._altlist_cache = {}
1080 self._pprovided_args = []
1082 def _show_slot_collision_notice(self, packages):
1083 """Show an informational message advising the user to mask one of the
1084 the packages. In some cases it may be possible to resolve this
1085 automatically, but support for backtracking (removal nodes that have
1086 already been selected) will be required in order to handle all possible
1090 msg.append("\n!!! Multiple versions within a single " + \
1091 "package slot have been \n")
1092 msg.append("!!! pulled into the dependency graph:\n\n")
1093 for node, parents in packages:
1094 msg.append(str(node))
1096 msg.append(" pulled in by\n")
1097 for parent in parents:
1099 msg.append(str(parent))
1102 msg.append(" (no parents)\n")
1104 sys.stderr.write("".join(msg))
1107 if "--quiet" in self.myopts:
1111 msg.append("It may be possible to solve this problem ")
1112 msg.append("by using package.mask to prevent one of ")
1113 msg.append("those packages from being selected. ")
1114 msg.append("However, it is also possible that conflicting ")
1115 msg.append("dependencies exist such that they are impossible to ")
1116 msg.append("satisfy simultaneously. If such a conflict exists in ")
1117 msg.append("the dependencies of two different packages, then those ")
1118 msg.append("packages can not be installed simultaneously.")
1120 from formatter import AbstractFormatter, DumbWriter
1121 f = AbstractFormatter(DumbWriter(sys.stderr, maxcol=72))
1123 f.add_flowing_data(x)
1127 msg.append("For more information, see MASKED PACKAGES ")
1128 msg.append("section in the emerge man page or refer ")
1129 msg.append("to the Gentoo Handbook.")
1131 f.add_flowing_data(x)
1135 def _reinstall_for_flags(self, forced_flags,
1136 orig_use, orig_iuse, cur_use, cur_iuse):
1137 """Return a set of flags that trigger reinstallation, or None if there
1138 are no such flags."""
1139 if "--newuse" in self.myopts:
1140 flags = orig_iuse.symmetric_difference(
1141 cur_iuse).difference(forced_flags)
1142 flags.update(orig_iuse.intersection(orig_use).symmetric_difference(
1143 cur_iuse.intersection(cur_use)))
1146 elif "changed-use" == self.myopts.get("--reinstall"):
1147 flags = orig_iuse.intersection(orig_use).symmetric_difference(
1148 cur_iuse.intersection(cur_use))
1153 def create(self, mybigkey, myparent=None, addme=1, myuse=None,
1154 priority=DepPriority(), rev_dep=False, arg=None):
1156 Fills the digraph with nodes comprised of packages to merge.
1157 mybigkey is the package spec of the package to merge.
1158 myparent is the package depending on mybigkey ( or None )
1159 addme = Should we add this package to the digraph or are we just looking at it's deps?
1160 Think --onlydeps, we need to ignore packages in that case.
1163 #IUSE-aware emerge -> USE DEP aware depgraph
1164 #"no downgrade" emerge
1166 mytype, myroot, mykey = mybigkey
1167 existing_node = None
1169 existing_node = self.pkg_node_map[myroot].get(mykey)
1171 self._parent_child_digraph.add(existing_node, myparent)
1172 if existing_node != myparent:
1173 # Refuse to make a node depend on itself so that the we don't
1174 # don't create a bogus circular dependency in self.altlist().
1175 if rev_dep and myparent:
1176 self.digraph.addnode(myparent, existing_node,
1179 self.digraph.addnode(existing_node, myparent,
1183 if "--nodeps" not in self.myopts:
1184 self.spinner.update()
1185 if mytype == "blocks":
1187 "--buildpkgonly" not in self.myopts and \
1188 "--nodeps" not in self.myopts and \
1189 myparent not in self._slot_collision_nodes:
1190 mybigkey[1] = myparent[1]
1191 self.blocker_parents.setdefault(
1192 tuple(mybigkey), set()).add(myparent)
1195 # select the correct /var database that we'll be checking against
1196 vardbapi = self.trees[myroot]["vartree"].dbapi
1197 portdb = self.trees[myroot]["porttree"].dbapi
1198 bindb = self.trees[myroot]["bintree"].dbapi
1199 pkgsettings = self.pkgsettings[myroot]
1201 # if the package is already on the system, we add a "nomerge"
1202 # directive, otherwise we add a "merge" directive.
1204 mydbapi = self.trees[myroot][self.pkg_tree_map[mytype]].dbapi
1205 metadata = dict(izip(self._mydbapi_keys,
1206 mydbapi.aux_get(mykey, self._mydbapi_keys)))
1207 if mytype == "ebuild":
1208 pkgsettings.setcpv(mykey, mydb=portdb)
1209 metadata["USE"] = pkgsettings["USE"]
1210 myuse = pkgsettings["USE"].split()
1212 if not arg and myroot == self.target_root:
1214 arg = self._set_atoms.findAtomForPackage(mykey, metadata)
1215 except portage.exception.InvalidDependString, e:
1216 if mytype != "installed":
1217 show_invalid_depstring_notice(tuple(mybigkey+["merge"]),
1218 metadata["PROVIDE"], str(e))
1222 reinstall_for_flags = None
1224 if mytype == "installed":
1226 if addme and mytype != "installed":
1227 # this is where we add the node to the list of packages to merge
1228 if "selective" in self.myparams or not arg:
1229 if "empty" not in self.myparams and vardbapi.cpv_exists(mykey):
1232 """ If we aren't merging, perform the --newuse check.
1233 If the package has new iuse flags or different use flags then if
1234 --newuse is specified, we need to merge the package. """
1235 if merging == 0 and \
1236 myroot == self.target_root and \
1237 ("--newuse" in self.myopts or
1238 "--reinstall" in self.myopts) and \
1239 vardbapi.cpv_exists(mykey):
1240 pkgsettings.setcpv(mykey, mydb=mydbapi)
1241 forced_flags = set()
1242 forced_flags.update(pkgsettings.useforce)
1243 forced_flags.update(pkgsettings.usemask)
1244 old_use = vardbapi.aux_get(mykey, ["USE"])[0].split()
1245 iuses = set(filter_iuse_defaults(metadata["IUSE"].split()))
1246 old_iuse = set(filter_iuse_defaults(
1247 vardbapi.aux_get(mykey, ["IUSE"])[0].split()))
1248 reinstall_for_flags = self._reinstall_for_flags(
1249 forced_flags, old_use, old_iuse, myuse, iuses)
1250 if reinstall_for_flags:
1253 if addme and merging == 1:
1254 mybigkey.append("merge")
1256 mybigkey.append("nomerge")
1257 jbigkey = tuple(mybigkey)
1260 if merging == 0 and vardbapi.cpv_exists(mykey) and \
1261 mytype != "installed":
1262 mytype = "installed"
1263 mybigkey[0] = "installed"
1265 jbigkey = tuple(mybigkey)
1266 metadata = dict(izip(self._mydbapi_keys,
1267 mydbapi.aux_get(mykey, self._mydbapi_keys)))
1268 myuse = metadata["USE"].split()
1269 slot_atom = "%s:%s" % (portage.dep_getkey(mykey), metadata["SLOT"])
1270 existing_node = self._slot_node_map[myroot].get(
1272 slot_collision = False
1274 e_type, myroot, e_cpv, e_status = existing_node
1276 # The existing node can be reused.
1277 self._parent_child_digraph.add(existing_node, myparent)
1278 if rev_dep and myparent:
1279 ptype, proot, pkey, pstatus = myparent
1280 self.digraph.addnode(myparent, existing_node,
1283 self.digraph.addnode(existing_node, myparent,
1287 # A slot collision has occurred. Sometimes this coincides
1288 # with unresolvable blockers, so the slot collision will be
1289 # shown later if there are no unresolvable blockers.
1290 e_parents = self._parent_child_digraph.parent_nodes(
1294 myparents.append(myparent)
1295 self._slot_collision_info.append(
1296 ((jbigkey, myparents), (existing_node, e_parents)))
1297 self._slot_collision_nodes.add(jbigkey)
1298 slot_collision = True
1301 # Now add this node to the graph so that self.display()
1302 # can show use flags and --tree portage.output. This node is
1303 # only being partially added to the graph. It must not be
1304 # allowed to interfere with the other nodes that have been
1305 # added. Do not overwrite data for existing nodes in
1306 # self.pkg_node_map and self.mydbapi since that data will
1307 # be used for blocker validation.
1308 self.pkg_node_map[myroot].setdefault(mykey, jbigkey)
1309 self.useFlags[myroot].setdefault(mykey, myuse)
1310 # Even though the graph is now invalid, continue to process
1311 # dependencies so that things like --fetchonly can still
1312 # function despite collisions.
1314 self.mydbapi[myroot].cpv_inject(mykey, metadata=metadata)
1315 self._slot_node_map[myroot][slot_atom] = jbigkey
1316 self.pkg_node_map[myroot][mykey] = jbigkey
1317 self.useFlags[myroot][mykey] = myuse
1318 if reinstall_for_flags:
1319 self._reinstall_nodes[jbigkey] = reinstall_for_flags
1321 if rev_dep and myparent:
1322 self.digraph.addnode(myparent, jbigkey,
1325 self.digraph.addnode(jbigkey, myparent,
1329 self._set_nodes.add(jbigkey)
1331 # Do this even when addme is False (--onlydeps) so that the
1332 # parent/child relationship is always known in case
1333 # self._show_slot_collision_notice() needs to be called later.
1334 self._parent_child_digraph.add(jbigkey, myparent)
1336 """ This section determines whether we go deeper into dependencies or not.
1337 We want to go deeper on a few occasions:
1338 Installing package A, we need to make sure package A's deps are met.
1339 emerge --deep <pkgspec>; we need to recursively check dependencies of pkgspec
1340 If we are in --nodeps (no recursion) mode, we obviously only check 1 level of dependencies.
1342 if "deep" not in self.myparams and not merging and \
1343 not ("--update" in self.myopts and arg and merging):
1345 elif "recurse" not in self.myparams:
1348 """ Check DEPEND/RDEPEND/PDEPEND/SLOT
1349 Pull from bintree if it's binary package, porttree if it's ebuild.
1350 Binpkg's can be either remote or local. """
1353 depkeys = ["DEPEND","RDEPEND","PDEPEND"]
1355 edepend[k] = metadata[k]
1357 if mytype == "ebuild":
1358 if "--buildpkgonly" in self.myopts:
1359 edepend["RDEPEND"] = ""
1360 edepend["PDEPEND"] = ""
1361 if not (arg and "--onlydeps" in self.myopts and \
1362 mytype == "ebuild") and \
1363 self.myopts.get("--with-bdeps", "n") == "n" and \
1364 (mytype == "binary" or mybigkey[3] == "nomerge"):
1365 edepend["DEPEND"] = ""
1367 """ We have retrieve the dependency information, now we need to recursively
1368 process them. DEPEND gets processed for root = "/", {R,P}DEPEND in myroot. """
1370 mp = tuple(mybigkey)
1373 if not self.select_dep("/", edepend["DEPEND"], myparent=mp,
1374 myuse=myuse, priority=DepPriority(buildtime=True),
1377 """RDEPEND is soft by definition. However, in order to ensure
1378 correct merge order, we make it a hard dependency. Otherwise, a
1379 build time dependency might not be usable due to it's run time
1380 dependencies not being installed yet.
1382 if not self.select_dep(myroot,edepend["RDEPEND"], myparent=mp,
1383 myuse=myuse, priority=DepPriority(runtime=True),
1386 if edepend.has_key("PDEPEND") and edepend["PDEPEND"]:
1387 # Post Depend -- Add to the list without a parent, as it depends
1388 # on a package being present AND must be built after that package.
1389 if not self.select_dep(myroot, edepend["PDEPEND"], myparent=mp,
1390 myuse=myuse, priority=DepPriority(runtime_post=True),
1393 except ValueError, e:
1395 portage.writemsg("\n\n!!! An atom in the dependencies " + \
1396 "is not fully-qualified. Multiple matches:\n\n", noiselevel=-1)
1398 portage.writemsg(" %s\n" % cpv, noiselevel=-1)
1399 portage.writemsg("\n", noiselevel=-1)
1400 if mytype == "binary":
1402 "!!! This binary package cannot be installed: '%s'\n" % \
1403 mykey, noiselevel=-1)
1404 elif mytype == "ebuild":
1405 myebuild, mylocation = portdb.findname2(mykey)
1406 portage.writemsg("!!! This ebuild cannot be installed: " + \
1407 "'%s'\n" % myebuild, noiselevel=-1)
1408 portage.writemsg("!!! Please notify the package maintainer " + \
1409 "that atoms must be fully-qualified.\n", noiselevel=-1)
1413 def select_files(self,myfiles):
1414 "given a list of .tbz2s, .ebuilds and deps, create the appropriate depgraph and return a favorite list"
1416 myroot = self.target_root
1417 portdb = self.trees[myroot]["porttree"].dbapi
1418 bindb = self.trees[myroot]["bintree"].dbapi
1419 pkgsettings = self.pkgsettings[myroot]
1421 def visible(mylist):
1422 matches = portdb.gvisible(portdb.visible(mylist))
1423 return [x for x in mylist \
1424 if x in matches or not portdb.cpv_exists(x)]
1426 ext = os.path.splitext(x)[1]
1428 if not os.path.exists(x):
1430 os.path.join(pkgsettings["PKGDIR"], "All", x)):
1431 x = os.path.join(pkgsettings["PKGDIR"], "All", x)
1432 elif os.path.exists(
1433 os.path.join(pkgsettings["PKGDIR"], x)):
1434 x = os.path.join(pkgsettings["PKGDIR"], x)
1436 print "\n\n!!! Binary package '"+str(x)+"' does not exist."
1437 print "!!! Please ensure the tbz2 exists as specified.\n"
1438 return 0, myfavorites
1439 mytbz2=portage.xpak.tbz2(x)
1440 mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.splitext(os.path.basename(x))[0]
1441 if os.path.realpath(x) != \
1442 os.path.realpath(self.trees[myroot]["bintree"].getname(mykey)):
1443 print colorize("BAD", "\n*** You need to adjust PKGDIR to emerge this package.\n")
1444 return 0, myfavorites
1445 if not self.create(["binary", myroot, mykey],
1446 None, "--onlydeps" not in self.myopts,
1447 myuse=mytbz2.getelements("USE"), arg=x):
1448 return (0,myfavorites)
1449 arg_atoms.append((x, "="+mykey))
1450 elif ext==".ebuild":
1451 ebuild_path = portage.util.normalize_path(os.path.abspath(x))
1452 pkgdir = os.path.dirname(ebuild_path)
1453 tree_root = os.path.dirname(os.path.dirname(pkgdir))
1454 cp = pkgdir[len(tree_root)+1:]
1455 e = portage.exception.PackageNotFound(
1456 ("%s is not in a valid portage tree " + \
1457 "hierarchy or does not exist") % x)
1458 if not portage.isvalidatom(cp):
1460 cat = portage.catsplit(cp)[0]
1461 mykey = cat + "/" + os.path.basename(ebuild_path[:-7])
1462 if not portage.isvalidatom("="+mykey):
1464 ebuild_path = portdb.findname(mykey)
1466 if ebuild_path != os.path.join(os.path.realpath(tree_root),
1467 cp, os.path.basename(ebuild_path)):
1468 print colorize("BAD", "\n*** You need to adjust PORTDIR or PORTDIR_OVERLAY to emerge this package.\n")
1469 return 0, myfavorites
1470 if mykey not in portdb.xmatch(
1471 "match-visible", portage.dep_getkey(mykey)):
1472 print colorize("BAD", "\n*** You are emerging a masked package. It is MUCH better to use")
1473 print colorize("BAD", "*** /etc/portage/package.* to accomplish this. See portage(5) man")
1474 print colorize("BAD", "*** page for details.")
1475 countdown(int(self.settings["EMERGE_WARNING_DELAY"]),
1478 raise portage.exception.PackageNotFound(
1479 "%s is not in a valid portage tree hierarchy or does not exist" % x)
1480 if not self.create(["ebuild", myroot, mykey],
1481 None, "--onlydeps" not in self.myopts, arg=x):
1482 return (0,myfavorites)
1483 arg_atoms.append((x, "="+mykey))
1485 if not is_valid_package_atom(x):
1486 portage.writemsg("\n\n!!! '%s' is not a valid package atom.\n" % x,
1488 portage.writemsg("!!! Please check ebuild(5) for full details.\n")
1489 portage.writemsg("!!! (Did you specify a version but forget to prefix with '='?)\n")
1493 if "--usepkg" in self.myopts:
1494 mykey = portage.dep_expand(x, mydb=bindb,
1495 settings=pkgsettings)
1496 if (mykey and not mykey.startswith("null/")) or \
1497 "--usepkgonly" in self.myopts:
1498 arg_atoms.append((x, mykey))
1501 mykey = portage.dep_expand(x,
1502 mydb=portdb, settings=pkgsettings)
1503 arg_atoms.append((x, mykey))
1504 except ValueError, errpkgs:
1505 print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous. Please specify"
1506 print "!!! one of the following fully-qualified ebuild names instead:\n"
1507 for i in errpkgs[0]:
1508 print " " + green(i)
1512 if "--update" in self.myopts:
1513 """Make sure all installed slots are updated when possible. Do this
1514 with --emptytree also, to ensure that all slots are remerged."""
1515 vardb = self.trees[self.target_root]["vartree"].dbapi
1517 for myarg, myatom in arg_atoms:
1518 greedy_atoms.append((myarg, myatom))
1520 for cpv in vardb.match(myatom):
1521 myslots.add(vardb.aux_get(cpv, ["SLOT"])[0])
1524 if "--usepkg" in self.myopts:
1525 mymatches = bindb.match(myatom)
1526 if "--usepkgonly" not in self.myopts:
1527 mymatches = visible(mymatches)
1528 best_pkg = portage.best(mymatches)
1530 best_slot = bindb.aux_get(best_pkg, ["SLOT"])[0]
1531 best_pkgs.append(("binary", best_pkg, best_slot))
1532 if "--usepkgonly" not in self.myopts:
1533 best_pkg = portage.best(portdb.match(myatom))
1535 best_slot = portdb.aux_get(best_pkg, ["SLOT"])[0]
1536 best_pkgs.append(("ebuild", best_pkg, best_slot))
1538 best_pkg = portage.best([x[1] for x in best_pkgs])
1539 best_pkgs = [x for x in best_pkgs if x[1] == best_pkg]
1540 best_slot = best_pkgs[0][2]
1541 myslots.add(best_slot)
1542 if len(myslots) > 1:
1543 for myslot in myslots:
1544 myslot_atom = "%s:%s" % \
1545 (portage.dep_getkey(myatom), myslot)
1547 if "--usepkgonly" not in self.myopts and \
1548 self.trees[self.target_root][
1549 "porttree"].dbapi.match(myslot_atom):
1551 elif "--usepkg" in self.myopts:
1552 mymatches = bindb.match(myslot_atom)
1553 if "--usepkgonly" not in self.myopts:
1554 mymatches = visible(mymatches)
1558 greedy_atoms.append((myarg, myslot_atom))
1559 arg_atoms = greedy_atoms
1561 oneshot = "--oneshot" in self.myopts or "--onlydeps" in self.myopts
1562 """ These are used inside self.create() in order to ensure packages
1563 that happen to match arguments are not incorrectly marked as nomerge."""
1564 args_set = self._sets["args"]
1565 for myarg, myatom in arg_atoms:
1566 if myatom in args_set:
1568 args_set.add(myatom)
1569 self._set_atoms.add(myatom)
1571 myfavorites.append(myatom)
1572 for myarg, myatom in arg_atoms:
1574 self.mysd = self.select_dep(myroot, myatom, arg=myarg)
1575 except portage.exception.MissingSignature, e:
1576 portage.writemsg("\n\n!!! A missing gpg signature is preventing portage from calculating the\n")
1577 portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
1578 portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
1579 portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n")
1580 portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1)
1582 except portage.exception.InvalidSignature, e:
1583 portage.writemsg("\n\n!!! An invalid gpg signature is preventing portage from calculating the\n")
1584 portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
1585 portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
1586 portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n")
1587 portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1)
1589 except SystemExit, e:
1590 raise # Needed else can't exit
1591 except Exception, e:
1592 print >> sys.stderr, "\n\n!!! Problem in '%s' dependencies." % mykey
1593 print >> sys.stderr, "!!!", str(e), getattr(e, "__module__", None)
1597 return (0,myfavorites)
1600 if "--usepkgonly" in self.myopts:
1601 for xs in self.digraph.all_nodes():
1602 if len(xs) >= 4 and xs[0] != "binary" and xs[3] == "merge":
1606 print "Missing binary for:",xs[2]
1608 if not self.validate_blockers():
1609 return False, myfavorites
1611 # We're true here unless we are missing binaries.
1612 return (not missing,myfavorites)
1614 def select_dep(self, myroot, depstring, myparent=None, arg=None,
1615 myuse=None, raise_on_missing=False, priority=DepPriority(),
1616 rev_deps=False, parent_arg=None):
1617 """ Given a depstring, create the depgraph such that all dependencies are satisfied.
1618 myroot = $ROOT from environment, where {R,P}DEPENDs are merged to.
1619 myparent = the node whose depstring is being passed in
1620 arg = package was specified on the command line, merge even if it's already installed
1621 myuse = USE flags at present
1622 raise_on_missing = Given that the depgraph is not proper, raise an exception if true
1623 else continue trying.
1624 return 1 on success, 0 for failure
1627 portdb = self.trees[myroot]["porttree"].dbapi
1628 bindb = self.trees[myroot]["bintree"].dbapi
1629 vardb = self.trees[myroot]["vartree"].dbapi
1630 pkgsettings = self.pkgsettings[myroot]
1632 p_type, p_root, p_key, p_status = myparent
1634 if "--debug" in self.myopts:
1636 print "Parent: ",myparent
1637 print "Depstring:",depstring
1639 print "Reverse:", rev_deps
1640 print "Priority:", priority
1642 #processing dependencies
1643 """ Call portage.dep_check to evaluate the use? conditionals and make sure all
1644 dependencies are satisfiable. """
1646 mymerge = [depstring]
1647 pprovided = pkgsettings.pprovideddict.get(
1648 portage.dep_getkey(depstring))
1649 if pprovided and portage.match_from_list(depstring, pprovided):
1653 if myparent and p_status == "nomerge":
1654 portage.dep._dep_check_strict = False
1655 mycheck = portage.dep_check(depstring, None,
1656 pkgsettings, myuse=myuse,
1657 use_binaries=("--usepkgonly" in self.myopts),
1658 myroot=myroot, trees=self.trees)
1660 portage.dep._dep_check_strict = True
1664 show_invalid_depstring_notice(
1665 myparent, depstring, mycheck[1])
1667 sys.stderr.write("\n%s\n%s\n" % (depstring, mycheck[1]))
1669 mymerge = mycheck[1]
1671 if not mymerge and arg:
1672 # A provided package has been specified on the command line. The
1673 # package will not be merged and a warning will be displayed.
1674 if depstring in self._set_atoms:
1675 self._pprovided_args.append((arg, depstring))
1678 # The parent is added after it's own dep_check call so that it
1679 # isn't allowed to satisfy a direct bootstrap dependency on itself
1680 # via an old-style virtual. This isn't a problem with new-style
1681 # virtuals, which are preferenced in dep_zapdeps by looking only at
1682 # the depstring, vdb, and available packages.
1684 p_type, p_root, p_key, p_status = myparent
1685 if p_status == "merge":
1686 # Update old-style virtuals if this package provides any.
1687 # These are needed for dep_virtual calls inside dep_check.
1688 p_db = self.mydbapi[p_root] # contains cached metadata
1689 if myparent in self._slot_collision_nodes:
1690 # The metadata isn't cached due to the slot collision.
1691 p_db = self.trees[p_root][self.pkg_tree_map[p_type]].dbapi
1693 self.pkgsettings[p_root].setinst(p_key, p_db)
1694 # For consistency, also update the global virtuals.
1695 settings = self.roots[p_root].settings
1697 settings.setinst(p_key, p_db)
1699 except portage.exception.InvalidDependString, e:
1700 provide = p_db.aux_get(p_key, ["PROVIDE"])[0]
1701 show_invalid_depstring_notice(myparent, provide, str(e))
1705 if "--debug" in self.myopts:
1706 print "Candidates:",mymerge
1710 selected_pkg = ["blocks", myroot, x[1:], None]
1712 #We are not processing a blocker but a normal dependency
1714 """In some cases, dep_check will return deps that shouldn't
1715 be proccessed any further, so they are identified and
1717 if "empty" not in self.myparams and \
1718 "deep" not in self.myparams and \
1719 not ("--update" in self.myopts and parent_arg) and \
1723 # List of acceptable packages, ordered by type preference.
1724 matched_packages = []
1725 myeb_matches = portdb.xmatch("match-visible", x)
1727 if "--usepkgonly" not in self.myopts:
1728 myeb = portage.best(myeb_matches)
1731 if "--usepkg" in self.myopts:
1732 # The next line assumes the binarytree has been populated.
1733 # XXX: Need to work out how we use the binary tree with roots.
1734 myeb_pkg_matches = bindb.match(x)
1735 if "--usepkgonly" not in self.myopts:
1736 # Remove any binary package entries that are masked in the portage tree (#55871)
1737 myeb_pkg_matches = [pkg for pkg in myeb_pkg_matches \
1738 if pkg in myeb_matches or \
1739 not portdb.cpv_exists(pkg)]
1740 if myeb_pkg_matches:
1741 myeb_pkg = portage.best(myeb_pkg_matches)
1744 ("--newuse" in self.myopts or \
1745 "--reinstall" in self.myopts):
1746 iuses = set(filter_iuse_defaults(
1747 bindb.aux_get(myeb_pkg, ["IUSE"])[0].split()))
1748 old_use = bindb.aux_get(myeb_pkg, ["USE"])[0].split()
1750 if "--usepkgonly" not in self.myopts and myeb:
1753 pkgsettings.setcpv(myeb, mydb=mydb)
1755 pkgsettings.setcpv(myeb_pkg, mydb=mydb)
1756 now_use = pkgsettings["USE"].split()
1757 forced_flags = set()
1758 forced_flags.update(pkgsettings.useforce)
1759 forced_flags.update(pkgsettings.usemask)
1761 if "--usepkgonly" not in self.myopts and myeb:
1762 cur_iuse = set(filter_iuse_defaults(
1763 portdb.aux_get(myeb, ["IUSE"])[0].split()))
1764 if self._reinstall_for_flags(
1765 forced_flags, old_use, iuses, now_use, cur_iuse):
1769 self.trees[myroot]["bintree"].dbapi.aux_get(
1770 myeb_pkg, ["USE"])[0].split()
1771 matched_packages.append(
1772 ["binary", myroot, myeb_pkg, binpkguseflags])
1774 if "--usepkgonly" not in self.myopts and myeb_matches:
1775 matched_packages.append(
1776 ["ebuild", myroot, myeb, None])
1778 if not matched_packages and \
1779 not (arg and "selective" not in self.myparams):
1780 """Fall back to the installed package database. This is a
1781 last resort because the metadata tends to diverge from that
1782 of the ebuild in the tree."""
1783 myeb_inst_matches = vardb.match(x)
1784 if "--usepkgonly" not in self.myopts:
1785 """ TODO: Improve masking check for installed and
1786 binary packages. bug #149816"""
1787 myeb_inst_matches = [pkg for pkg in myeb_inst_matches \
1788 if not portdb.cpv_exists(pkg)]
1790 if myeb_inst_matches:
1791 myeb_inst = portage.best(myeb_inst_matches)
1793 binpkguseflags = vardb.aux_get(
1794 myeb_inst, ["USE"])[0].split()
1795 matched_packages.append(
1796 ["installed", myroot, myeb_inst, binpkguseflags])
1798 if not matched_packages:
1799 if raise_on_missing:
1806 xfrom = '(dependency required by '+ \
1807 green('"%s"' % myparent[2]) + \
1808 red(' [%s]' % myparent[0]) + ')'
1809 alleb = portdb.xmatch("match-all", x)
1811 if "--usepkgonly" not in self.myopts:
1812 print "\n!!! "+red("All ebuilds that could satisfy ")+green(xinfo)+red(" have been masked.")
1813 print "!!! One of the following masked packages is required to complete your request:"
1817 mreasons = portage.getmaskingstatus(p,
1818 settings=pkgsettings, portdb=portdb)
1819 print "- "+p+" (masked by: "+", ".join(mreasons)+")"
1820 if "package.mask" in mreasons:
1821 comment, filename = \
1822 portage.getmaskingreason(p,
1823 settings=pkgsettings, portdb=portdb,
1824 return_location=True)
1825 if comment and comment != oldcomment:
1828 oldcomment = comment
1830 licenses = portdb.aux_get(p, ["LICENSE"])[0]
1832 # Corruption will have been reported above.
1836 pkgsettings.setcpv(p, mydb=portdb)
1837 uselist = pkgsettings.get("USE", "").split()
1838 missing_licenses = []
1840 missing_licenses = \
1841 pkgsettings.getMissingLicenses(
1842 licenses, p, uselist)
1843 except portage.exception.InvalidDependString:
1844 # This will have already been reported
1845 # above via mreasons.
1847 for l in missing_licenses:
1848 l_path = portdb.findLicensePath(l)
1849 if l in shown_licenses:
1851 msg = ("A copy of the '%s' license" + \
1852 " is located at '%s'.") % (l, l_path)
1855 shown_licenses.append(l)
1857 print "For more information, see MASKED PACKAGES section in the emerge man page or "
1858 print "refer to the Gentoo Handbook."
1860 print "\n!!! "+red("There are no packages available to satisfy: ")+green(xinfo)
1861 print "!!! Either add a suitable binary package or compile from an ebuild."
1863 print "\nemerge: there are no ebuilds to satisfy "+green(xinfo)+"."
1869 if "--debug" in self.myopts:
1870 for pkg in matched_packages:
1871 print (pkg[0] + ":").rjust(10), pkg[2]
1873 if len(matched_packages) > 1:
1874 bestmatch = portage.best(
1875 [pkg[2] for pkg in matched_packages])
1876 matched_packages = [pkg for pkg in matched_packages \
1877 if pkg[2] == bestmatch]
1879 # ordered by type preference ("ebuild" type is the last resort)
1880 selected_pkg = matched_packages[0]
1881 pkgtype, myroot, mycpv, myuse = selected_pkg
1882 mydbapi = self.trees[myroot][self.pkg_tree_map[pkgtype]].dbapi
1883 slot_atom = "%s:%s" % (portage.dep_getkey(mycpv),
1884 mydbapi.aux_get(mycpv, ["SLOT"])[0])
1885 existing_node = self._slot_node_map[myroot].get(
1888 e_type, myroot, e_cpv, e_status = existing_node
1889 if portage.match_from_list(x, [e_cpv]):
1890 # The existing node can be reused.
1891 selected_pkg = [e_type, myroot, e_cpv,
1892 self.useFlags[myroot][e_cpv]]
1895 #we are a dependency, so we want to be unconditionally added
1896 mypriority = priority.copy()
1898 mypriority.satisfied = True
1899 if not self.create(selected_pkg[0:3], myparent,
1900 myuse=selected_pkg[-1], priority=mypriority,
1901 rev_dep=rev_deps, arg=arg):
1904 #if mysource is not set, then we are a command-line dependency and should not be added
1905 #if --onlydeps is specified.
1906 if not self.create(selected_pkg[0:3], myparent,
1907 addme=("--onlydeps" not in self.myopts),
1908 myuse=selected_pkg[-1], rev_dep=rev_deps, arg=arg):
1911 if "--debug" in self.myopts:
1912 print "Exiting...",myparent
1915 def validate_blockers(self):
1916 """Remove any blockers from the digraph that do not match any of the
1917 packages within the graph. If necessary, create hard deps to ensure
1918 correct merge order such that mutually blocking packages are never
1919 installed simultaneously."""
1921 if "--buildpkgonly" in self.myopts or \
1922 "--nodeps" in self.myopts:
1926 for myroot in self.trees:
1928 modified_slots[myroot] = myslots
1929 final_db = self.mydbapi[myroot]
1930 slot_node_map = self._slot_node_map[myroot]
1931 for slot_atom, mynode in slot_node_map.iteritems():
1932 mytype, myroot, mycpv, mystatus = mynode
1933 if mystatus == "merge":
1934 myslots[slot_atom] = mycpv
1936 #if "deep" in self.myparams:
1938 # Pull in blockers from all installed packages that haven't already
1939 # been pulled into the depgraph. This is not enabled by default
1940 # due to the performance penalty that is incurred by all the
1941 # additional dep_check calls that are required.
1943 # Optimization hack for dep_check calls that minimizes the
1944 # available matches by replacing the portdb with a fakedbapi
1946 class FakePortageTree(object):
1947 def __init__(self, mydb):
1949 dep_check_trees = {}
1950 for myroot in self.trees:
1951 dep_check_trees[myroot] = self.trees[myroot].copy()
1952 dep_check_trees[myroot]["porttree"] = \
1953 FakePortageTree(self.mydbapi[myroot])
1955 dep_keys = ["DEPEND","RDEPEND","PDEPEND"]
1956 for myroot in self.trees:
1957 pkg_node_map = self.pkg_node_map[myroot]
1958 vardb = self.trees[myroot]["vartree"].dbapi
1959 portdb = self.trees[myroot]["porttree"].dbapi
1960 pkgsettings = self.pkgsettings[myroot]
1961 final_db = self.mydbapi[myroot]
1962 cpv_all_installed = self.trees[myroot]["vartree"].dbapi.cpv_all()
1963 blocker_cache = BlockerCache(myroot, vardb)
1964 for pkg in cpv_all_installed:
1965 blocker_atoms = None
1966 matching_node = pkg_node_map.get(pkg, None)
1967 if matching_node and \
1968 matching_node[3] == "nomerge":
1970 # If this node has any blockers, create a "nomerge"
1971 # node for it so that they can be enforced.
1972 self.spinner.update()
1973 blocker_data = blocker_cache.get(pkg)
1975 blocker_atoms = blocker_data.atoms
1977 dep_vals = vardb.aux_get(pkg, dep_keys)
1978 myuse = vardb.aux_get(pkg, ["USE"])[0].split()
1979 depstr = " ".join(dep_vals)
1980 # It is crucial to pass in final_db here in order to
1981 # optimize dep_check calls by eliminating atoms via
1982 # dep_wordreduce and dep_eval calls.
1984 portage.dep._dep_check_strict = False
1986 success, atoms = portage.dep_check(depstr,
1987 final_db, pkgsettings, myuse=myuse,
1988 trees=dep_check_trees, myroot=myroot)
1989 except Exception, e:
1990 if isinstance(e, SystemExit):
1992 # This is helpful, for example, if a ValueError
1993 # is thrown from cpv_expand due to multiple
1994 # matches (this can happen if an atom lacks a
1996 show_invalid_depstring_notice(
1997 ("installed", myroot, pkg, "nomerge"),
2002 portage.dep._dep_check_strict = True
2004 slot_atom = "%s:%s" % (portage.dep_getkey(pkg),
2005 vardb.aux_get(pkg, ["SLOT"])[0])
2006 if slot_atom in modified_slots[myroot]:
2007 # This package is being replaced anyway, so
2008 # ignore invalid dependencies so as not to
2009 # annoy the user too much (otherwise they'd be
2010 # forced to manually unmerge it first).
2012 show_invalid_depstring_notice(
2013 ("installed", myroot, pkg, "nomerge"),
2016 blocker_atoms = [myatom for myatom in atoms \
2017 if myatom.startswith("!")]
2018 counter = long(vardb.aux_get(pkg, ["COUNTER"])[0])
2019 blocker_cache[pkg] = \
2020 blocker_cache.BlockerData(counter, blocker_atoms)
2022 # Don't store this parent in pkg_node_map, because it's
2023 # not needed there and it might overwrite a "merge"
2024 # node with the same cpv.
2025 myparent = ("installed", myroot, pkg, "nomerge")
2026 for myatom in blocker_atoms:
2027 blocker = ("blocks", myroot, myatom[1:])
2029 self.blocker_parents.get(blocker, None)
2032 self.blocker_parents[blocker] = myparents
2033 myparents.add(myparent)
2034 blocker_cache.flush()
2037 for blocker in self.blocker_parents.keys():
2038 mytype, myroot, mydep = blocker
2039 initial_db = self.trees[myroot]["vartree"].dbapi
2040 final_db = self.mydbapi[myroot]
2041 blocked_initial = initial_db.match(mydep)
2042 blocked_final = final_db.match(mydep)
2043 if not blocked_initial and not blocked_final:
2044 del self.blocker_parents[blocker]
2046 blocked_slots_initial = {}
2047 blocked_slots_final = {}
2048 for cpv in blocked_initial:
2049 blocked_slots_initial[cpv] = \
2050 "%s:%s" % (portage.dep_getkey(cpv),
2051 initial_db.aux_get(cpv, ["SLOT"])[0])
2052 for cpv in blocked_final:
2053 blocked_slots_final[cpv] = \
2054 "%s:%s" % (portage.dep_getkey(cpv),
2055 final_db.aux_get(cpv, ["SLOT"])[0])
2056 for parent in list(self.blocker_parents[blocker]):
2057 ptype, proot, pcpv, pstatus = parent
2058 pdbapi = self.trees[proot][self.pkg_tree_map[ptype]].dbapi
2059 pslot = pdbapi.aux_get(pcpv, ["SLOT"])[0]
2060 pslot_atom = "%s:%s" % (portage.dep_getkey(pcpv), pslot)
2061 parent_static = pslot_atom not in modified_slots[proot]
2062 unresolved_blocks = False
2063 depends_on_order = set()
2064 for cpv in blocked_initial:
2065 slot_atom = blocked_slots_initial[cpv]
2066 if slot_atom == pslot_atom:
2067 # TODO: Support blocks within slots in cases where it
2068 # might make sense. For example, a new version might
2069 # require that the old version be uninstalled at build
2072 if parent_static and \
2073 slot_atom not in modified_slots[myroot]:
2074 # This blocker will be handled the next time that a
2075 # merge of either package is triggered.
2077 if pstatus == "merge" and \
2078 slot_atom in modified_slots[myroot]:
2079 replacement = final_db.match(slot_atom)
2081 if not portage.match_from_list(mydep, replacement):
2082 # Apparently a replacement may be able to
2083 # invalidate this block.
2084 replacement_node = \
2085 self.pkg_node_map[proot][replacement[0]]
2086 depends_on_order.add((replacement_node, parent))
2088 # None of the above blocker resolutions techniques apply,
2089 # so apparently this one is unresolvable.
2090 unresolved_blocks = True
2091 for cpv in blocked_final:
2092 slot_atom = blocked_slots_final[cpv]
2093 if slot_atom == pslot_atom:
2094 # TODO: Support blocks within slots.
2096 if parent_static and \
2097 slot_atom not in modified_slots[myroot]:
2098 # This blocker will be handled the next time that a
2099 # merge of either package is triggered.
2101 if not parent_static and pstatus == "nomerge" and \
2102 slot_atom in modified_slots[myroot]:
2103 replacement = final_db.match(pslot_atom)
2105 replacement_node = \
2106 self.pkg_node_map[proot][replacement[0]]
2107 if replacement_node not in \
2108 self.blocker_parents[blocker]:
2109 # Apparently a replacement may be able to
2110 # invalidate this block.
2111 blocked_node = self.pkg_node_map[proot][cpv]
2112 depends_on_order.add(
2113 (replacement_node, blocked_node))
2115 # None of the above blocker resolutions techniques apply,
2116 # so apparently this one is unresolvable.
2117 unresolved_blocks = True
2118 if not unresolved_blocks and depends_on_order:
2119 for node, pnode in depends_on_order:
2120 # Enforce correct merge order with a hard dep.
2121 self.digraph.addnode(node, pnode,
2122 priority=DepPriority(buildtime=True))
2123 # Count references to this blocker so that it can be
2124 # invalidated after nodes referencing it have been
2126 self.blocker_digraph.addnode(node, blocker)
2127 if not unresolved_blocks and not depends_on_order:
2128 self.blocker_parents[blocker].remove(parent)
2129 if unresolved_blocks:
2130 self._unresolved_blocker_parents.setdefault(
2131 blocker, set()).add(parent)
2132 if not self.blocker_parents[blocker]:
2133 del self.blocker_parents[blocker]
2134 # Validate blockers that depend on merge order.
2135 if not self.blocker_digraph.empty():
2137 if self._slot_collision_info:
2138 # The user is only notified of a slot collision if there are no
2139 # unresolvable blocks.
2140 for x in self.altlist():
2141 if x[0] == "blocks":
2143 self._show_slot_collision_notice(self._slot_collision_info[0])
2144 if not self._accept_collisions():
2148 def _accept_collisions(self):
2150 for x in ("--nodeps", "--pretend", "--fetchonly", "--fetch-all-uri"):
2151 if x in self.myopts:
2156 def _merge_order_bias(self, mygraph):
2157 """Order nodes from highest to lowest overall reference count for
2158 optimal leaf node selection."""
2160 for node in mygraph.order:
2161 node_info[node] = len(mygraph.parent_nodes(node))
2162 def cmp_merge_preference(node1, node2):
2163 return node_info[node2] - node_info[node1]
2164 mygraph.order.sort(cmp_merge_preference)
2166 def altlist(self, reversed=False):
2167 if reversed in self._altlist_cache:
2168 return self._altlist_cache[reversed][:]
2170 retlist = self.altlist()
2172 self._altlist_cache[reversed] = retlist[:]
2174 mygraph=self.digraph.copy()
2175 for node in mygraph.order[:]:
2176 if node[-1] == "nomerge":
2177 mygraph.remove(node)
2178 self._merge_order_bias(mygraph)
2179 myblockers = self.blocker_digraph.copy()
2181 circular_blocks = False
2185 get_nodes = mygraph.root_nodes
2187 get_nodes = mygraph.leaf_nodes
2188 for cpv, node in self.pkg_node_map["/"].iteritems():
2189 if "portage" == portage.catsplit(portage.dep_getkey(cpv))[-1]:
2190 asap_nodes.append(node)
2192 ignore_priority_soft_range = [None]
2193 ignore_priority_soft_range.extend(
2194 xrange(DepPriority.MIN, DepPriority.SOFT + 1))
2195 tree_mode = "--tree" in self.myopts
2196 # Tracks whether or not the current iteration should prefer asap_nodes
2197 # if available. This is set to False when the previous iteration
2198 # failed to select any nodes. It is reset whenever nodes are
2199 # successfully selected.
2201 while not mygraph.empty():
2202 selected_nodes = None
2203 if prefer_asap and asap_nodes:
2204 """ASAP nodes are merged before their soft deps."""
2205 asap_nodes = [node for node in asap_nodes \
2206 if mygraph.contains(node)]
2207 for node in asap_nodes:
2208 if not mygraph.child_nodes(node,
2209 ignore_priority=DepPriority.SOFT):
2210 selected_nodes = [node]
2211 asap_nodes.remove(node)
2213 if not selected_nodes and \
2214 not (prefer_asap and asap_nodes):
2215 for ignore_priority in ignore_priority_soft_range:
2216 nodes = get_nodes(ignore_priority=ignore_priority)
2220 if ignore_priority is None and not tree_mode:
2221 # Greedily pop all of these nodes since no relationship
2222 # has been ignored. This optimization destroys --tree
2223 # output, so it's disabled in reversed mode.
2224 selected_nodes = nodes
2226 # For optimal merge order:
2227 # * Only pop one node.
2228 # * Removing a root node (node without a parent)
2229 # will not produce a leaf node, so avoid it.
2231 if mygraph.parent_nodes(node):
2232 # found a non-root node
2233 selected_nodes = [node]
2235 if not selected_nodes:
2236 # settle for a root node
2237 selected_nodes = [nodes[0]]
2238 if not selected_nodes:
2239 nodes = get_nodes(ignore_priority=DepPriority.MEDIUM)
2241 """Recursively gather a group of nodes that RDEPEND on
2242 eachother. This ensures that they are merged as a group
2243 and get their RDEPENDs satisfied as soon as possible."""
2244 def gather_deps(ignore_priority,
2245 mergeable_nodes, selected_nodes, node):
2246 if node in selected_nodes:
2248 if node not in mergeable_nodes:
2250 selected_nodes.add(node)
2251 for child in mygraph.child_nodes(node,
2252 ignore_priority=ignore_priority):
2253 if not gather_deps(ignore_priority,
2254 mergeable_nodes, selected_nodes, child):
2257 mergeable_nodes = set(nodes)
2258 if prefer_asap and asap_nodes:
2260 for ignore_priority in xrange(DepPriority.SOFT,
2261 DepPriority.MEDIUM_SOFT + 1):
2263 selected_nodes = set()
2264 if gather_deps(ignore_priority,
2265 mergeable_nodes, selected_nodes, node):
2268 selected_nodes = None
2272 if prefer_asap and asap_nodes and not selected_nodes:
2273 # We failed to find any asap nodes to merge, so ignore
2274 # them for the next iteration.
2278 if selected_nodes and ignore_priority > DepPriority.SOFT:
2279 # Try to merge ignored medium deps as soon as possible.
2280 for node in selected_nodes:
2281 children = set(mygraph.child_nodes(node))
2282 soft = children.difference(
2283 mygraph.child_nodes(node,
2284 ignore_priority=DepPriority.SOFT))
2285 medium_soft = children.difference(
2286 mygraph.child_nodes(node,
2287 ignore_priority=DepPriority.MEDIUM_SOFT))
2288 medium_soft.difference_update(soft)
2289 for child in medium_soft:
2290 if child in selected_nodes:
2292 if child in asap_nodes:
2294 # TODO: Try harder to make these nodes get
2295 # merged absolutely as soon as possible.
2296 asap_nodes.append(child)
2298 if not selected_nodes:
2299 if not myblockers.is_empty():
2300 """A blocker couldn't be circumnavigated while keeping all
2301 dependencies satisfied. The user will have to resolve this
2302 manually. This is a panic condition and thus the order
2303 doesn't really matter, so just pop a random node in order
2304 to avoid a circular dependency panic if possible."""
2305 if not circular_blocks:
2306 circular_blocks = True
2307 blocker_deps = myblockers.leaf_nodes()
2309 # Some of these nodes might have already been selected
2310 # by the normal node selection process after the
2311 # circular_blocks flag has been set. Therefore, we
2312 # have to verify that they're still in the graph so
2313 # that they're not selected more than once.
2314 node = blocker_deps.pop()
2315 if mygraph.contains(node):
2316 selected_nodes = [node]
2319 if not selected_nodes:
2320 # No leaf nodes are available, so we have a circular
2321 # dependency panic situation. Reduce the noise level to a
2322 # minimum via repeated elimination of root nodes since they
2323 # have no parents and thus can not be part of a cycle.
2325 root_nodes = mygraph.root_nodes(
2326 ignore_priority=DepPriority.SOFT)
2329 for node in root_nodes:
2330 mygraph.remove(node)
2331 # Display the USE flags that are enabled on nodes that are part
2332 # of dependency cycles in case that helps the user decide to
2333 # disable some of them.
2335 tempgraph = mygraph.copy()
2336 while not tempgraph.empty():
2337 nodes = tempgraph.leaf_nodes()
2339 node = tempgraph.order[0]
2342 display_order.append(list(node))
2343 tempgraph.remove(node)
2344 display_order.reverse()
2345 self.myopts.pop("--quiet", None)
2346 self.myopts.pop("--verbose", None)
2347 self.myopts["--tree"] = True
2348 self.display(display_order)
2349 print "!!! Error: circular dependencies:"
2351 mygraph.debug_print()
2353 print "!!! Note that circular dependencies can often be avoided by temporarily"
2354 print "!!! disabling USE flags that trigger optional dependencies."
2357 # At this point, we've succeeded in selecting one or more nodes, so
2358 # it's now safe to reset the prefer_asap to it's default state.
2361 for node in selected_nodes:
2362 retlist.append(list(node))
2363 mygraph.remove(node)
2364 if not reversed and not circular_blocks and myblockers.contains(node):
2365 """This node may have invalidated one or more blockers."""
2366 myblockers.remove(node)
2367 for blocker in myblockers.root_nodes():
2368 if not myblockers.child_nodes(blocker):
2369 myblockers.remove(blocker)
2371 self._unresolved_blocker_parents.get(blocker)
2373 self.blocker_parents[blocker] = unresolved
2375 del self.blocker_parents[blocker]
2378 """Blocker validation does not work with reverse mode,
2379 so self.altlist() should first be called with reverse disabled
2380 so that blockers are properly validated."""
2381 self.blocker_digraph = myblockers
2383 """ Add any unresolved blocks so that they can be displayed."""
2384 for blocker in self.blocker_parents:
2385 retlist.append(list(blocker))
2386 self._altlist_cache[reversed] = retlist[:]
2389 def xcreate(self,mode="system"):
2390 vardb = self.trees[self.target_root]["vartree"].dbapi
2391 portdb = self.trees[self.target_root]["porttree"].dbapi
2392 bindb = self.trees[self.target_root]["bintree"].dbapi
2393 def visible(mylist):
2394 matches = portdb.gvisible(portdb.visible(mylist))
2395 return [x for x in mylist \
2396 if x in matches or not portdb.cpv_exists(x)]
2397 world_problems = False
2399 root_config = self.roots[self.target_root]
2400 world_set = root_config.sets["world"]
2401 system_set = root_config.sets["system"]
2402 mylist = list(system_set)
2403 self._sets["system"] = system_set
2405 self._sets["world"] = world_set
2407 if not portage.isvalidatom(x):
2408 world_problems = True
2410 elif not vardb.match(x):
2411 world_problems = True
2413 if "--usepkgonly" not in self.myopts and \
2416 elif "--usepkg" in self.myopts:
2417 mymatches = bindb.match(x)
2418 if "--usepkgonly" not in self.myopts:
2419 mymatches = visible(mymatches)
2428 mykey = portage.dep_getkey(atom)
2430 newlist.append(atom)
2431 if mode == "system" or atom not in world_set:
2432 # only world is greedy for slots, not system
2434 # Make sure all installed slots are updated when possible.
2435 # Do this with --emptytree also, to ensure that all slots are
2438 for cpv in vardb.match(mykey):
2439 myslots.add(vardb.aux_get(cpv, ["SLOT"])[0])
2442 if "--usepkg" in self.myopts:
2443 mymatches = bindb.match(atom)
2444 if "--usepkgonly" not in self.myopts:
2445 mymatches = visible(mymatches)
2446 best_pkg = portage.best(mymatches)
2448 best_slot = bindb.aux_get(best_pkg, ["SLOT"])[0]
2449 best_pkgs.append(("binary", best_pkg, best_slot))
2450 if "--usepkgonly" not in self.myopts:
2451 best_pkg = portage.best(portdb.match(atom))
2453 best_slot = portdb.aux_get(best_pkg, ["SLOT"])[0]
2454 best_pkgs.append(("ebuild", best_pkg, best_slot))
2456 best_pkg = portage.best([x[1] for x in best_pkgs])
2457 best_pkgs = [x for x in best_pkgs if x[1] == best_pkg]
2458 best_slot = best_pkgs[0][2]
2459 myslots.add(best_slot)
2460 if len(myslots) > 1:
2461 for myslot in myslots:
2462 myslot_atom = "%s:%s" % (mykey, myslot)
2464 if "--usepkgonly" not in self.myopts and \
2465 self.trees[self.target_root][
2466 "porttree"].dbapi.match(myslot_atom):
2468 elif "--usepkg" in self.myopts:
2469 mymatches = bindb.match(myslot_atom)
2470 if "--usepkgonly" not in self.myopts:
2471 mymatches = visible(mymatches)
2475 newlist.append(myslot_atom)
2478 for myatom in mylist:
2479 self._set_atoms.add(myatom)
2482 for mydep in mylist:
2484 if not self.select_dep(
2485 self.target_root, mydep, raise_on_missing=True, arg=mydep):
2486 print >> sys.stderr, "\n\n!!! Problem resolving dependencies for", mydep
2489 missing_atoms.append(mydep)
2491 if not self.validate_blockers():
2495 print >> sys.stderr, "\n!!! Problems have been detected with your world file"
2496 print >> sys.stderr, "!!! Please run "+green("emaint --check world")+"\n"
2499 print >> sys.stderr, "\n" + colorize("BAD", "!!!") + \
2500 " Ebuilds for the following packages are either all"
2501 print >> sys.stderr, colorize("BAD", "!!!") + " masked or don't exist:"
2502 print >> sys.stderr, " ".join(missing_atoms) + "\n"
2506 def display(self, mylist, favorites=[], verbosity=None):
2507 if verbosity is None:
2508 verbosity = ("--quiet" in self.myopts and 1 or \
2509 "--verbose" in self.myopts and 3 or 2)
2510 favorites_set = InternalPackageSet(favorites)
2515 counters = PackageCounters()
2517 if verbosity == 1 and "--verbose" not in self.myopts:
2518 def create_use_string(*args):
2521 def create_use_string(name, cur_iuse, iuse_forced, cur_use,
2523 is_new, all_flags=(verbosity == 3 or "--quiet" in self.myopts),
2524 alphabetical=("--alphabetical" in self.myopts)):
2532 cur_iuse = set(cur_iuse)
2533 enabled_flags = cur_iuse.intersection(cur_use)
2534 removed_iuse = set(old_iuse).difference(cur_iuse)
2535 any_iuse = cur_iuse.union(old_iuse)
2536 any_iuse = list(any_iuse)
2538 for flag in any_iuse:
2541 if flag in enabled_flags:
2543 if is_new or flag in old_use and all_flags:
2544 flag_str = red(flag)
2545 elif flag not in old_iuse:
2546 flag_str = yellow(flag) + "%*"
2547 elif flag not in old_use:
2548 flag_str = green(flag) + "*"
2549 elif flag in removed_iuse:
2551 flag_str = yellow("-" + flag) + "%"
2554 flag_str = "(" + flag_str + ")"
2555 removed.append(flag_str)
2558 if is_new or flag in old_iuse and flag not in old_use and all_flags:
2559 flag_str = blue("-" + flag)
2560 elif flag not in old_iuse:
2561 flag_str = yellow("-" + flag)
2562 if flag not in iuse_forced:
2564 elif flag in old_use:
2565 flag_str = green("-" + flag) + "*"
2567 if flag in iuse_forced:
2568 flag_str = "(" + flag_str + ")"
2570 enabled.append(flag_str)
2572 disabled.append(flag_str)
2575 ret = " ".join(enabled)
2577 ret = " ".join(enabled + disabled + removed)
2579 ret = '%s="%s" ' % (name, ret)
2582 repo_display = RepoDisplay(self.roots)
2586 mygraph = self._parent_child_digraph
2591 if "blocks" == x[0]:
2592 display_list.append((x, 0, True))
2594 graph_key = tuple(x)
2595 if "--tree" in self.myopts:
2596 depth = len(tree_nodes)
2597 while depth and graph_key not in \
2598 mygraph.child_nodes(tree_nodes[depth-1]):
2601 tree_nodes = tree_nodes[:depth]
2602 tree_nodes.append(graph_key)
2603 display_list.append((x, depth, True))
2604 shown_edges.add((graph_key, tree_nodes[depth-1]))
2606 traversed_nodes = set() # prevent endless circles
2607 traversed_nodes.add(graph_key)
2608 def add_parents(current_node, ordered):
2610 # Do not traverse to parents if this node is an
2611 # an argument or a direct member of a set that has
2612 # been specified as an argument (system or world).
2613 if current_node not in self._set_nodes:
2614 parent_nodes = mygraph.parent_nodes(current_node)
2616 child_nodes = set(mygraph.child_nodes(current_node))
2617 selected_parent = None
2618 # First, try to avoid a direct cycle.
2619 for node in parent_nodes:
2620 if node not in traversed_nodes and \
2621 node not in child_nodes:
2622 edge = (current_node, node)
2623 if edge in shown_edges:
2625 selected_parent = node
2627 if not selected_parent:
2628 # A direct cycle is unavoidable.
2629 for node in parent_nodes:
2630 if node not in traversed_nodes:
2631 edge = (current_node, node)
2632 if edge in shown_edges:
2634 selected_parent = node
2637 shown_edges.add((current_node, selected_parent))
2638 traversed_nodes.add(selected_parent)
2639 add_parents(selected_parent, False)
2640 display_list.append((list(current_node),
2641 len(tree_nodes), ordered))
2642 tree_nodes.append(current_node)
2644 add_parents(graph_key, True)
2646 display_list.append((x, depth, True))
2647 mylist = display_list
2649 last_merge_depth = 0
2650 for i in xrange(len(mylist)-1,-1,-1):
2651 graph_key, depth, ordered = mylist[i]
2652 if not ordered and depth == 0 and i > 0 \
2653 and graph_key == mylist[i-1][0] and \
2654 mylist[i-1][1] == 0:
2655 # An ordered node got a consecutive duplicate when the tree was
2659 if "blocks" == graph_key[0]:
2661 if ordered and graph_key[-1] != "nomerge":
2662 last_merge_depth = depth
2664 if depth >= last_merge_depth or \
2665 i < len(mylist) - 1 and \
2666 depth >= mylist[i+1][1]:
2669 from portage import flatten
2670 from portage.dep import use_reduce, paren_reduce
2671 # files to fetch list - avoids counting a same file twice
2672 # in size display (verbose mode)
2675 for mylist_index in xrange(len(mylist)):
2676 x, depth, ordered = mylist[mylist_index]
2681 portdb = self.trees[myroot]["porttree"].dbapi
2682 bindb = self.trees[myroot]["bintree"].dbapi
2683 vardb = self.trees[myroot]["vartree"].dbapi
2684 vartree = self.trees[myroot]["vartree"]
2685 pkgsettings = self.pkgsettings[myroot]
2690 addl=""+red("B")+" "+fetch+" "
2692 counters.blocks += 1
2693 resolved = portage.key_expand(
2694 pkg_key, mydb=vardb, settings=pkgsettings)
2695 if "--columns" in self.myopts and "--quiet" in self.myopts:
2696 addl = addl + " " + red(resolved)
2698 addl = "[blocks " + addl + "] " + red(resolved)
2699 block_parents = self.blocker_parents[tuple(x)]
2700 block_parents = set([pnode[2] for pnode in block_parents])
2701 block_parents = ", ".join(block_parents)
2703 addl += bad(" (\"%s\" is blocking %s)") % \
2704 (pkg_key, block_parents)
2706 addl += bad(" (is blocking %s)") % block_parents
2707 blockers.append(addl)
2710 pkg_merge = ordered and pkg_status != "nomerge"
2711 if pkg_node in self._slot_collision_nodes or \
2712 (pkg_status == "nomerge" and pkg_type != "installed"):
2713 # The metadata isn't cached due to a slot collision or
2715 mydbapi = self.trees[myroot][self.pkg_tree_map[pkg_type]].dbapi
2717 mydbapi = self.mydbapi[myroot] # contains cached metadata
2718 metadata = dict(izip(self._mydbapi_keys,
2719 mydbapi.aux_get(pkg_key, self._mydbapi_keys)))
2721 repo_name = metadata["repository"]
2722 if pkg_type == "ebuild":
2723 ebuild_path = portdb.findname(pkg_key)
2724 if not ebuild_path: # shouldn't happen
2725 raise portage.exception.PackageNotFound(pkg_key)
2726 repo_path_real = os.path.dirname(os.path.dirname(
2727 os.path.dirname(ebuild_path)))
2729 repo_path_real = portdb.getRepositoryPath(repo_name)
2730 if pkg_key not in self.useFlags[myroot]:
2731 """If this is a --resume then the USE flags need to be
2732 fetched from the appropriate locations here."""
2733 self.useFlags[myroot][pkg_key] = mydbapi.aux_get(
2734 pkg_key, ["USE"])[0].split()
2737 restrict = flatten(use_reduce(paren_reduce(
2738 mydbapi.aux_get(pkg_key, ["RESTRICT"])[0]),
2739 uselist=self.useFlags[myroot][pkg_key]))
2740 except portage.exception.InvalidDependString, e:
2741 if pkg_status != "nomerge":
2742 restrict = mydbapi.aux_get(pkg_key, ["RESTRICT"])[0]
2743 show_invalid_depstring_notice(x, restrict, str(e))
2747 if "ebuild" == pkg_type and x[3] != "nomerge" and \
2748 "fetch" in restrict:
2751 counters.restrict_fetch += 1
2752 if portdb.fetch_check(
2753 pkg_key, self.useFlags[myroot][pkg_key]):
2756 counters.restrict_fetch_satisfied += 1
2758 #we need to use "--emptrytree" testing here rather than "empty" param testing because "empty"
2759 #param is used for -u, where you still *do* want to see when something is being upgraded.
2761 if vardb.cpv_exists(pkg_key):
2762 addl=" "+yellow("R")+fetch+" "
2763 if x[3] != "nomerge":
2765 counters.reinst += 1
2766 elif vardb.match(portage.dep_getkey(pkg_key)):
2767 mynewslot = mydbapi.aux_get(pkg_key, ["SLOT"])[0]
2768 myoldlist = self.trees[x[1]]["vartree"].dbapi.match(
2769 portage.pkgsplit(x[2])[0])
2770 myinslotlist = [inst_pkg for inst_pkg in myoldlist
2771 if mynewslot == vardb.aux_get(inst_pkg, ["SLOT"])[0]]
2773 myoldbest=portage.best(myinslotlist)
2775 if portage.pkgcmp(portage.pkgsplit(x[2]), portage.pkgsplit(myoldbest)) < 0:
2777 addl+=turquoise("U")+blue("D")
2779 counters.downgrades += 1
2782 addl+=turquoise("U")+" "
2784 counters.upgrades += 1
2786 # New slot, mark it new.
2787 addl=" "+green("NS")+fetch+" "
2789 counters.newslot += 1
2791 if "--changelog" in self.myopts:
2792 slot_atom = "%s:%s" % (portage.dep_getkey(pkg_key),
2793 mydbapi.aux_get(pkg_key, ["SLOT"])[0])
2794 inst_matches = vardb.match(slot_atom)
2796 changelogs.extend(self.calc_changelog(
2797 portdb.findname(pkg_key),
2798 inst_matches[0], pkg_key))
2800 addl=" "+green("N")+" "+fetch+" "
2806 if pkg_key in self.useFlags[myroot]:
2808 cur_iuse = list(filter_iuse_defaults(
2809 mydbapi.aux_get(pkg_key, ["IUSE"])[0].split()))
2811 forced_flags = set()
2812 forced_flags.update(pkgsettings.useforce)
2813 forced_flags.update(pkgsettings.usemask)
2815 cur_iuse = portage.unique_array(cur_iuse)
2817 cur_use = self.useFlags[myroot][pkg_key]
2818 cur_use = [flag for flag in cur_use if flag in cur_iuse]
2824 if self.trees[x[1]]["vartree"].dbapi.cpv_exists(pkg):
2825 old_iuse, old_use = \
2826 self.trees[x[1]]["vartree"].dbapi.aux_get(
2827 pkg, ["IUSE", "USE"])
2828 old_iuse = list(set(
2829 filter_iuse_defaults(old_iuse.split())))
2831 old_use = old_use.split()
2838 old_use = [flag for flag in old_use if flag in old_iuse]
2840 use_expand = pkgsettings["USE_EXPAND"].lower().split()
2842 use_expand.reverse()
2843 use_expand_hidden = \
2844 pkgsettings["USE_EXPAND_HIDDEN"].lower().split()
2846 def map_to_use_expand(myvals, forcedFlags=False,
2850 for exp in use_expand:
2853 for val in myvals[:]:
2854 if val.startswith(exp.lower()+"_"):
2855 if val in forced_flags:
2856 forced[exp].add(val[len(exp)+1:])
2857 ret[exp].append(val[len(exp)+1:])
2860 forced["USE"] = [val for val in myvals \
2861 if val in forced_flags]
2863 for exp in use_expand_hidden:
2869 # Prevent USE_EXPAND_HIDDEN flags from being hidden if they
2870 # are the only thing that triggered reinstallation.
2871 reinst_flags_map = None
2872 reinstall_for_flags = self._reinstall_nodes.get(pkg_node)
2873 if reinstall_for_flags:
2874 reinst_flags_map = map_to_use_expand(
2875 list(reinstall_for_flags), removeHidden=False)
2876 if reinst_flags_map["USE"]:
2877 reinst_flags_map = None
2879 for k in reinst_flags_map.keys():
2880 if not reinst_flags_map[k]:
2881 del reinst_flags_map[k]
2882 if reinst_flags_map and \
2883 not set(reinst_flags_map).difference(
2885 use_expand_hidden = set(use_expand_hidden).difference(
2888 cur_iuse_map, iuse_forced = \
2889 map_to_use_expand(cur_iuse, forcedFlags=True)
2890 cur_use_map = map_to_use_expand(cur_use)
2891 old_iuse_map = map_to_use_expand(old_iuse)
2892 old_use_map = map_to_use_expand(old_use)
2895 use_expand.insert(0, "USE")
2897 for key in use_expand:
2898 if key in use_expand_hidden:
2900 verboseadd += create_use_string(key.upper(),
2901 cur_iuse_map[key], iuse_forced[key],
2902 cur_use_map[key], old_iuse_map[key],
2903 old_use_map[key], is_new)
2908 if pkg_type == "ebuild" and pkg_merge:
2910 myfilesdict = portdb.getfetchsizes(pkg_key,
2911 useflags=self.useFlags[myroot][pkg_key],
2913 except portage.exception.InvalidDependString, e:
2914 src_uri = portdb.aux_get(pkg_key, ["SRC_URI"])[0]
2915 show_invalid_depstring_notice(x, src_uri, str(e))
2918 if myfilesdict is None:
2919 myfilesdict="[empty/missing/bad digest]"
2921 for myfetchfile in myfilesdict:
2922 if myfetchfile not in myfetchlist:
2923 mysize+=myfilesdict[myfetchfile]
2924 myfetchlist.append(myfetchfile)
2925 counters.totalsize += mysize
2926 verboseadd+=format_size(mysize)+" "
2929 # assign index for a previous version in the same slot
2930 has_previous = False
2931 repo_name_prev = None
2932 slot_atom = "%s:%s" % (portage.dep_getkey(pkg_key),
2934 slot_matches = vardb.match(slot_atom)
2937 repo_name_prev = vardb.aux_get(slot_matches[0],
2940 # now use the data to generate output
2942 if pkg_status == "nomerge" or not has_previous:
2943 repoadd = repo_display.repoStr(repo_path_real)
2945 repo_path_prev = None
2947 repo_path_prev = portdb.getRepositoryPath(
2949 repoadd = "%s=>%s" % (
2950 repo_display.repoStr(repo_path_prev),
2951 repo_display.repoStr(repo_path_real))
2953 verboseadd += teal("[%s]" % repoadd)
2955 xs = list(portage.pkgsplit(x[2]))
2962 if "COLUMNWIDTH" in self.settings:
2964 mywidth = int(self.settings["COLUMNWIDTH"])
2965 except ValueError, e:
2966 portage.writemsg("!!! %s\n" % str(e), noiselevel=-1)
2968 "!!! Unable to parse COLUMNWIDTH='%s'\n" % \
2969 self.settings["COLUMNWIDTH"], noiselevel=-1)
2974 indent = " " * depth
2977 myoldbest=portage.pkgsplit(myoldbest)[1]+"-"+portage.pkgsplit(myoldbest)[2]
2978 if myoldbest[-3:]=="-r0":
2979 myoldbest=myoldbest[:-3]
2980 myoldbest=blue("["+myoldbest+"]")
2983 root_config = self.roots[myroot]
2984 system_set = root_config.sets["system"]
2985 world_set = root_config.sets["world"]
2990 pkg_system = system_set.findAtomForPackage(pkg_key, metadata)
2991 pkg_world = world_set.findAtomForPackage(pkg_key, metadata)
2992 if not pkg_world and myroot == self.target_root and \
2993 favorites_set.findAtomForPackage(pkg_key, metadata):
2994 # Maybe it will be added to world now.
2995 if create_world_atom(pkg_key, metadata,
2996 favorites_set, root_config):
2998 except portage.exception.InvalidDependString:
2999 # This is reported elsewhere if relevant.
3005 return colorize("PKG_MERGE_SYSTEM", pkg)
3007 return colorize("PKG_MERGE_WORLD", pkg)
3009 return colorize("PKG_MERGE", pkg)
3012 return colorize("PKG_NOMERGE_SYSTEM", pkg)
3014 return colorize("PKG_NOMERGE_WORLD", pkg)
3016 return colorize("PKG_NOMERGE", pkg)
3021 if "--columns" in self.myopts:
3022 if "--quiet" in self.myopts:
3023 myprint=addl+" "+indent+pkgprint(pkg_cp)
3024 myprint=myprint+darkblue(" "+xs[1]+xs[2])+" "
3025 myprint=myprint+myoldbest
3026 myprint=myprint+darkgreen("to "+x[1])
3028 myprint="["+pkgprint(pkg_type)+" "+addl+"] "+indent+pkgprint(pkg_cp)
3029 if (newlp-nc_len(myprint)) > 0:
3030 myprint=myprint+(" "*(newlp-nc_len(myprint)))
3031 myprint=myprint+"["+darkblue(xs[1]+xs[2])+"] "
3032 if (oldlp-nc_len(myprint)) > 0:
3033 myprint=myprint+" "*(oldlp-nc_len(myprint))
3034 myprint=myprint+myoldbest
3035 myprint=myprint+darkgreen("to "+x[1])+" "+verboseadd
3038 myprint = "[%s ] " % pkgprint("nomerge")
3040 myprint = "[" + pkg_type + " " + addl + "] "
3041 myprint += indent + pkgprint(pkg_key) + " " + \
3042 myoldbest + darkgreen("to " + myroot) + " " + \
3045 if "--columns" in self.myopts:
3046 if "--quiet" in self.myopts:
3047 myprint=addl+" "+indent+pkgprint(pkg_cp)
3048 myprint=myprint+" "+green(xs[1]+xs[2])+" "
3049 myprint=myprint+myoldbest
3051 myprint="["+pkgprint(pkg_type)+" "+addl+"] "+indent+pkgprint(pkg_cp)
3052 if (newlp-nc_len(myprint)) > 0:
3053 myprint=myprint+(" "*(newlp-nc_len(myprint)))
3054 myprint=myprint+green(" ["+xs[1]+xs[2]+"] ")
3055 if (oldlp-nc_len(myprint)) > 0:
3056 myprint=myprint+(" "*(oldlp-nc_len(myprint)))
3057 myprint=myprint+myoldbest+" "+verboseadd
3060 myprint="["+pkgprint("nomerge")+" ] "+indent+pkgprint(pkg_key)+" "+myoldbest+" "+verboseadd
3062 myprint="["+pkgprint(pkg_type)+" "+addl+"] "+indent+pkgprint(pkg_key)+" "+myoldbest+" "+verboseadd
3065 mysplit = portage.pkgsplit(x[2])
3066 if "--tree" not in self.myopts and mysplit and \
3067 len(mysplit) == 3 and mysplit[0] == "sys-apps/portage" and \
3070 if mysplit[2] == "r0":
3071 myversion = mysplit[1]
3073 myversion = "%s-%s" % (mysplit[1], mysplit[2])
3075 if myversion != portage.VERSION and "--quiet" not in self.myopts:
3076 if mylist_index < len(mylist) - 1 and \
3077 "livecvsportage" not in self.settings.features:
3078 p.append(colorize("WARN", "*** Portage will stop merging at this point and reload itself,"))
3079 p.append(colorize("WARN", " then resume the merge."))
3091 sys.stdout.write(str(repo_display))
3093 if "--changelog" in self.myopts:
3095 for revision,text in changelogs:
3096 print bold('*'+revision)
3097 sys.stdout.write(text)
3099 if self._pprovided_args:
3101 for arg_atom in self._pprovided_args:
3102 arg, atom = arg_atom
3103 arg_refs[arg_atom] = []
3104 cp = portage.dep_getkey(atom)
3105 for set_name, atom_set in self._sets.iteritems():
3106 if atom in atom_set:
3107 arg_refs[arg_atom].append(set_name)
3109 msg.append(bad("\nWARNING: "))
3110 if len(self._pprovided_args) > 1:
3111 msg.append("Requested packages will not be " + \
3112 "merged because they are listed in\n")
3114 msg.append("A requested package will not be " + \
3115 "merged because it is listed in\n")
3116 msg.append("package.provided:\n\n")
3117 problems_sets = set()
3118 for (arg, atom), refs in arg_refs.iteritems():
3121 problems_sets.update(refs)
3123 ref_string = ", ".join(["'%s'" % name for name in refs])
3124 ref_string = " pulled in by " + ref_string
3125 msg.append(" %s%s\n" % (colorize("INFORM", arg), ref_string))
3127 if "world" in problems_sets:
3128 msg.append("This problem can be solved in one of the following ways:\n\n")
3129 msg.append(" A) Use emaint to clean offending packages from world (if not installed).\n")
3130 msg.append(" B) Uninstall offending packages (cleans them from world).\n")
3131 msg.append(" C) Remove offending entries from package.provided.\n\n")
3132 msg.append("The best course of action depends on the reason that an offending\n")
3133 msg.append("package.provided entry exists.\n\n")
3134 sys.stderr.write("".join(msg))
3137 def calc_changelog(self,ebuildpath,current,next):
3138 if ebuildpath == None or not os.path.exists(ebuildpath):
3140 current = '-'.join(portage.catpkgsplit(current)[1:])
3141 if current.endswith('-r0'):
3142 current = current[:-3]
3143 next = '-'.join(portage.catpkgsplit(next)[1:])
3144 if next.endswith('-r0'):
3146 changelogpath = os.path.join(os.path.split(ebuildpath)[0],'ChangeLog')
3148 changelog = open(changelogpath).read()
3149 except SystemExit, e:
3150 raise # Needed else can't exit
3153 divisions = self.find_changelog_tags(changelog)
3154 #print 'XX from',current,'to',next
3155 #for div,text in divisions: print 'XX',div
3156 # skip entries for all revisions above the one we are about to emerge
3157 for i in range(len(divisions)):
3158 if divisions[i][0]==next:
3159 divisions = divisions[i:]
3161 # find out how many entries we are going to display
3162 for i in range(len(divisions)):
3163 if divisions[i][0]==current:
3164 divisions = divisions[:i]
3167 # couldnt find the current revision in the list. display nothing
3171 def find_changelog_tags(self,changelog):
3175 match = re.search(r'^\*\ ?([-a-zA-Z0-9_.+]*)(?:\ .*)?\n',changelog,re.M)
3177 if release is not None:
3178 divs.append((release,changelog))
3180 if release is not None:
3181 divs.append((release,changelog[:match.start()]))
3182 changelog = changelog[match.end():]
3183 release = match.group(1)
3184 if release.endswith('.ebuild'):
3185 release = release[:-7]
3186 if release.endswith('-r0'):
3187 release = release[:-3]
3189 def saveNomergeFavorites(self):
3190 """Find atoms in favorites that are not in the mergelist and add them
3191 to the world file if necessary."""
3192 for x in ("--fetchonly", "--fetch-all-uri",
3193 "--oneshot", "--onlydeps", "--pretend"):
3194 if x in self.myopts:
3196 root_config = self.roots[self.target_root]
3197 world_set = root_config.sets["world"]
3199 world_set.load() # maybe it's changed on disk
3200 args_set = self._sets["args"]
3201 portdb = self.trees[self.target_root]["porttree"].dbapi
3202 added_favorites = set()
3203 for x in self._set_nodes:
3204 pkg_type, root, pkg_key, pkg_status = x
3205 if pkg_status != "nomerge":
3207 metadata = dict(izip(self._mydbapi_keys,
3208 self.mydbapi[root].aux_get(pkg_key, self._mydbapi_keys)))
3210 myfavkey = create_world_atom(pkg_key, metadata,
3211 args_set, root_config)
3213 if myfavkey in added_favorites:
3215 added_favorites.add(myfavkey)
3216 world_set.add(myfavkey)
3217 print ">>> Recording",myfavkey,"in \"world\" favorites file..."
3218 except portage.exception.InvalidDependString, e:
3219 writemsg("\n\n!!! '%s' has invalid PROVIDE: %s\n" % \
3220 (pkg_key, str(e)), noiselevel=-1)
3221 writemsg("!!! see '%s'\n\n" % os.path.join(
3222 root, portage.VDB_PATH, pkg_key, "PROVIDE"), noiselevel=-1)
3226 def loadResumeCommand(self, resume_data):
3228 Add a resume command to the graph and validate it in the process. This
3229 will raise a PackageNotFound exception if a package is not available.
3231 self._sets["args"].update(resume_data.get("favorites", []))
3232 mergelist = resume_data.get("mergelist", [])
3233 fakedb = self.mydbapi
3238 pkg_type, myroot, pkg_key, action = x
3239 if pkg_type not in self.pkg_tree_map:
3241 if action != "merge":
3243 mydb = trees[myroot][self.pkg_tree_map[pkg_type]].dbapi
3245 metadata = dict(izip(self._mydbapi_keys,
3246 mydb.aux_get(pkg_key, self._mydbapi_keys)))
3248 # It does no exist or it is corrupt.
3249 raise portage.exception.PackageNotFound(pkg_key)
3250 fakedb[myroot].cpv_inject(pkg_key, metadata=metadata)
3251 if pkg_type == "ebuild":
3252 pkgsettings = self.pkgsettings[myroot]
3253 pkgsettings.setcpv(pkg_key, mydb=fakedb[myroot])
3254 fakedb[myroot].aux_update(pkg_key, {"USE":pkgsettings["USE"]})
3255 self.spinner.update()
3257 class RepoDisplay(object):
3258 def __init__(self, roots):
3259 self._shown_repos = {}
3260 self._unknown_repo = False
3262 for root_config in roots.itervalues():
3263 portdir = root_config.settings.get("PORTDIR")
3265 repo_paths.add(portdir)
3266 overlays = root_config.settings.get("PORTDIR_OVERLAY")
3268 repo_paths.update(overlays.split())
3269 repo_paths = list(repo_paths)
3270 self._repo_paths = repo_paths
3271 self._repo_paths_real = [ os.path.realpath(repo_path) \
3272 for repo_path in repo_paths ]
3274 # pre-allocate index for PORTDIR so that it always has index 0.
3275 for root_config in roots.itervalues():
3276 portdb = root_config.trees["porttree"].dbapi
3277 portdir = portdb.porttree_root
3279 self.repoStr(portdir)
3281 def repoStr(self, repo_path_real):
3284 real_index = self._repo_paths_real.index(repo_path_real)
3285 if real_index == -1:
3287 self._unknown_repo = True
3289 shown_repos = self._shown_repos
3290 repo_paths = self._repo_paths
3291 repo_path = repo_paths[real_index]
3292 index = shown_repos.get(repo_path)
3294 index = len(shown_repos)
3295 shown_repos[repo_path] = index
3301 shown_repos = self._shown_repos
3302 unknown_repo = self._unknown_repo
3303 if shown_repos or self._unknown_repo:
3304 output.append("Portage tree and overlays:\n")
3305 show_repo_paths = list(shown_repos)
3306 for repo_path, repo_index in shown_repos.iteritems():
3307 show_repo_paths[repo_index] = repo_path
3309 for index, repo_path in enumerate(show_repo_paths):
3310 output.append(" "+teal("["+str(index)+"]")+" %s\n" % repo_path)
3312 output.append(" "+teal("[?]") + \
3313 " indicates that the source repository could not be determined\n")
3314 return "".join(output)
3316 class PackageCounters(object):
3326 self.restrict_fetch = 0
3327 self.restrict_fetch_satisfied = 0
3330 total_installs = self.upgrades + self.downgrades + self.newslot + self.new + self.reinst
3333 myoutput.append("Total: %s package" % total_installs)
3334 if total_installs != 1:
3335 myoutput.append("s")
3336 if total_installs != 0:
3337 myoutput.append(" (")
3338 if self.upgrades > 0:
3339 details.append("%s upgrade" % self.upgrades)
3340 if self.upgrades > 1:
3342 if self.downgrades > 0:
3343 details.append("%s downgrade" % self.downgrades)
3344 if self.downgrades > 1:
3347 details.append("%s new" % self.new)
3348 if self.newslot > 0:
3349 details.append("%s in new slot" % self.newslot)
3350 if self.newslot > 1:
3353 details.append("%s reinstall" % self.reinst)
3357 details.append("%s block" % self.blocks)
3360 myoutput.append(", ".join(details))
3361 if total_installs != 0:
3362 myoutput.append(")")
3363 myoutput.append(", Size of downloads: %s" % format_size(self.totalsize))
3364 if self.restrict_fetch:
3365 myoutput.append("\nFetch Restriction: %s package" % \
3366 self.restrict_fetch)
3367 if self.restrict_fetch > 1:
3368 myoutput.append("s")
3369 if self.restrict_fetch_satisfied < self.restrict_fetch:
3370 myoutput.append(bad(" (%s unsatisfied)") % \
3371 (self.restrict_fetch - self.restrict_fetch_satisfied))
3372 return "".join(myoutput)
3374 class MergeTask(object):
3376 def __init__(self, settings, trees, myopts):
3377 self.settings = settings
3378 self.target_root = settings["ROOT"]
3380 self.myopts = myopts
3382 if settings.get("PORTAGE_DEBUG", "") == "1":
3384 self.pkgsettings = {}
3385 self.pkgsettings[self.target_root] = portage.config(clone=settings)
3386 if self.target_root != "/":
3387 self.pkgsettings["/"] = \
3388 portage.config(clone=trees["/"]["vartree"].settings)
3391 def merge(self, mylist, favorites, mtimedb):
3392 from portage.elog import elog_process
3393 from portage.elog.filtering import filter_mergephases
3395 fetchonly = "--fetchonly" in self.myopts or \
3396 "--fetch-all-uri" in self.myopts
3397 pretend = "--pretend" in self.myopts
3399 ldpath_mtimes = mtimedb["ldpath"]
3400 xterm_titles = "notitles" not in self.settings.features
3402 #check for blocking dependencies
3403 if "--fetchonly" not in self.myopts and \
3404 "--fetch-all-uri" not in self.myopts and \
3405 "--buildpkgonly" not in self.myopts:
3408 print "\n!!! Error: the "+x[2]+" package conflicts with another package;"
3409 print "!!! the two packages cannot be installed on the same system together."
3410 print "!!! Please use 'emerge --pretend' to determine blockers."
3411 if "--quiet" not in self.myopts:
3412 show_blocker_docs_link()
3415 if "--resume" in self.myopts:
3417 print colorize("GOOD", "*** Resuming merge...")
3418 emergelog(xterm_titles, " *** Resuming merge...")
3419 mylist = mtimedb["resume"]["mergelist"][:]
3420 if "--skipfirst" in self.myopts and mylist:
3421 del mtimedb["resume"]["mergelist"][0]
3424 mymergelist = mylist
3426 # Verify all the manifests now so that the user is notified of failure
3427 # as soon as possible.
3428 if "--fetchonly" not in self.myopts and \
3429 "--fetch-all-uri" not in self.myopts and \
3430 "strict" in self.settings.features:
3431 shown_verifying_msg = False
3433 for myroot, pkgsettings in self.pkgsettings.iteritems():
3434 quiet_config = portage.config(clone=pkgsettings)
3435 quiet_config["PORTAGE_QUIET"] = "1"
3436 quiet_config.backup_changes("PORTAGE_QUIET")
3437 quiet_settings[myroot] = quiet_config
3440 if x[0] != "ebuild" or x[-1] == "nomerge":
3442 if not shown_verifying_msg:
3443 shown_verifying_msg = True
3444 print ">>> Verifying ebuild Manifests..."
3445 mytype, myroot, mycpv, mystatus = x
3446 portdb = self.trees[myroot]["porttree"].dbapi
3447 quiet_config = quiet_settings[myroot]
3448 quiet_config["O"] = os.path.dirname(portdb.findname(mycpv))
3449 if not portage.digestcheck([], quiet_config, strict=True):
3451 del x, mytype, myroot, mycpv, mystatus, quiet_config
3452 del shown_verifying_msg, quiet_settings
3454 root_config = RootConfig(self.trees[self.target_root])
3455 system_set = root_config.sets["system"]
3456 args_set = InternalPackageSet(favorites)
3457 world_set = root_config.sets["world"]
3458 if "--resume" not in self.myopts:
3459 mymergelist = mylist
3460 mtimedb["resume"]["mergelist"]=mymergelist[:]
3463 myfeat = self.settings.features[:]
3464 bad_resume_opts = set(["--ask", "--tree", "--changelog", "--skipfirst",
3466 if "parallel-fetch" in myfeat and \
3467 not ("--pretend" in self.myopts or \
3468 "--fetch-all-uri" in self.myopts or \
3469 "--fetchonly" in self.myopts):
3470 if "distlocks" not in myfeat:
3472 print red("!!!")+" parallel-fetching requires the distlocks feature enabled"
3473 print red("!!!")+" you have it disabled, thus parallel-fetching is being disabled"
3475 elif len(mymergelist) > 1:
3476 print ">>> starting parallel fetching"
3477 fetch_log = "/var/log/emerge-fetch.log"
3478 logfile = open(fetch_log, "w")
3479 fd_pipes = {1:logfile.fileno(), 2:logfile.fileno()}
3480 portage.util.apply_secpass_permissions(fetch_log,
3481 uid=portage.portage_uid, gid=portage.portage_gid,
3483 fetch_env = os.environ.copy()
3484 fetch_env["FEATURES"] = fetch_env.get("FEATURES", "") + " -cvs"
3485 fetch_env["PORTAGE_NICENESS"] = "0"
3486 fetch_args = [sys.argv[0], "--resume", "--fetchonly"]
3487 resume_opts = self.myopts.copy()
3488 # For automatic resume, we need to prevent
3489 # any of bad_resume_opts from leaking in
3490 # via EMERGE_DEFAULT_OPTS.
3491 resume_opts["--ignore-default-opts"] = True
3492 for myopt, myarg in resume_opts.iteritems():
3493 if myopt not in bad_resume_opts:
3495 fetch_args.append(myopt)
3497 fetch_args.append(myopt +"="+ myarg)
3498 portage.process.spawn(fetch_args, env=fetch_env,
3499 fd_pipes=fd_pipes, returnpid=True)
3500 logfile.close() # belongs to the spawned process
3501 del fetch_log, logfile, fd_pipes, fetch_env, fetch_args, \
3504 metadata_keys = [k for k in portage.auxdbkeys \
3505 if not k.startswith("UNUSED_")] + ["USE"]
3508 for x in mymergelist:
3514 portdb = self.trees[myroot]["porttree"].dbapi
3515 bindb = self.trees[myroot]["bintree"].dbapi
3516 vartree = self.trees[myroot]["vartree"]
3517 pkgsettings = self.pkgsettings[myroot]
3519 if pkg_type == "blocks":
3521 elif pkg_type == "ebuild":
3523 metadata.update(izip(metadata_keys,
3524 mydbapi.aux_get(pkg_key, metadata_keys)))
3525 pkgsettings.setcpv(pkg_key, mydb=mydbapi)
3526 metadata["USE"] = pkgsettings["USE"]
3528 if pkg_type == "binary":
3531 raise AssertionError("Package type: '%s'" % pkg_type)
3532 metadata.update(izip(metadata_keys,
3533 mydbapi.aux_get(pkg_key, metadata_keys)))
3536 y = portdb.findname(pkg_key)
3537 if "--pretend" not in self.myopts:
3538 print "\n>>> Emerging (" + \
3539 colorize("MERGE_LIST_PROGRESS", str(mergecount)) + " of " + \
3540 colorize("MERGE_LIST_PROGRESS", str(len(mymergelist))) + ") " + \
3541 colorize("GOOD", x[pkgindex]) + " to " + x[1]
3542 emergelog(xterm_titles, " >>> emerge ("+\
3543 str(mergecount)+" of "+str(len(mymergelist))+\
3544 ") "+x[pkgindex]+" to "+x[1])
3546 pkgsettings["EMERGE_FROM"] = x[0]
3547 pkgsettings.backup_changes("EMERGE_FROM")
3550 #buildsyspkg: Check if we need to _force_ binary package creation
3551 issyspkg = ("buildsyspkg" in myfeat) \
3552 and x[0] != "blocks" \
3553 and system_set.findAtomForPackage(pkg_key, metadata) \
3554 and "--buildpkg" not in self.myopts
3555 if x[0] in ["ebuild","blocks"]:
3556 if x[0] == "blocks" and "--fetchonly" not in self.myopts:
3557 raise Exception, "Merging a blocker"
3558 elif "--fetchonly" in self.myopts or \
3559 "--fetch-all-uri" in self.myopts:
3560 if "--fetch-all-uri" in self.myopts:
3561 retval = portage.doebuild(y, "fetch", myroot,
3562 pkgsettings, self.edebug,
3563 "--pretend" in self.myopts, fetchonly=1,
3564 fetchall=1, mydbapi=portdb, tree="porttree")
3566 retval = portage.doebuild(y, "fetch", myroot,
3567 pkgsettings, self.edebug,
3568 "--pretend" in self.myopts, fetchonly=1,
3569 mydbapi=portdb, tree="porttree")
3570 if (retval is None) or retval:
3572 print "!!! Fetch for",y,"failed, continuing..."
3574 failed_fetches.append(pkg_key)
3578 portage.doebuild_environment(y, "setup", myroot,
3579 pkgsettings, self.edebug, 1, portdb)
3580 catdir = os.path.dirname(pkgsettings["PORTAGE_BUILDDIR"])
3581 portage.util.ensure_dirs(os.path.dirname(catdir),
3582 uid=portage.portage_uid, gid=portage.portage_gid,
3584 builddir_lock = None
3587 catdir_lock = portage.locks.lockdir(catdir)
3588 portage.util.ensure_dirs(catdir,
3589 uid=portage.portage_uid, gid=portage.portage_gid,
3591 builddir_lock = portage.locks.lockdir(
3592 pkgsettings["PORTAGE_BUILDDIR"])
3594 portage.locks.unlockdir(catdir_lock)
3597 msg = " === (%s of %s) Cleaning (%s::%s)" % \
3598 (mergecount, len(mymergelist), pkg_key, y)
3599 short_msg = "emerge: (%s of %s) %s Clean" % \
3600 (mergecount, len(mymergelist), pkg_key)
3601 emergelog(xterm_titles, msg, short_msg=short_msg)
3602 retval = portage.doebuild(y, "clean", myroot,
3603 pkgsettings, self.edebug, cleanup=1,
3604 mydbapi=portdb, tree="porttree")
3605 if retval != os.EX_OK:
3607 if "--buildpkg" in self.myopts or issyspkg:
3609 print ">>> This is a system package, " + \
3610 "let's pack a rescue tarball."
3611 msg = " === (%s of %s) Compiling/Packaging (%s::%s)" % \
3612 (mergecount, len(mymergelist), pkg_key, y)
3613 short_msg = "emerge: (%s of %s) %s Compile" % \
3614 (mergecount, len(mymergelist), pkg_key)
3615 emergelog(xterm_titles, msg, short_msg=short_msg)
3616 self.trees[myroot]["bintree"].prevent_collision(pkg_key)
3617 binpkg_tmpfile = os.path.join(pkgsettings["PKGDIR"],
3618 pkg_key + ".tbz2." + str(os.getpid()))
3619 pkgsettings["PORTAGE_BINPKG_TMPFILE"] = binpkg_tmpfile
3620 pkgsettings.backup_changes("PORTAGE_BINPKG_TMPFILE")
3621 retval = portage.doebuild(y, "package", myroot,
3622 pkgsettings, self.edebug, mydbapi=portdb,
3624 del pkgsettings["PORTAGE_BINPKG_TMPFILE"]
3625 if retval != os.EX_OK or \
3626 "--buildpkgonly" in self.myopts:
3627 elog_process(pkg_key, pkgsettings, phasefilter=filter_mergephases)
3628 if retval != os.EX_OK:
3630 bintree = self.trees[myroot]["bintree"]
3631 bintree.inject(pkg_key, filename=binpkg_tmpfile)
3632 if "--buildpkgonly" not in self.myopts:
3633 msg = " === (%s of %s) Merging (%s::%s)" % \
3634 (mergecount, len(mymergelist), pkg_key, y)
3635 short_msg = "emerge: (%s of %s) %s Merge" % \
3636 (mergecount, len(mymergelist), pkg_key)
3637 emergelog(xterm_titles, msg, short_msg=short_msg)
3638 retval = portage.merge(pkgsettings["CATEGORY"],
3639 pkgsettings["PF"], pkgsettings["D"],
3640 os.path.join(pkgsettings["PORTAGE_BUILDDIR"],
3641 "build-info"), myroot, pkgsettings,
3642 myebuild=pkgsettings["EBUILD"],
3643 mytree="porttree", mydbapi=portdb,
3644 vartree=vartree, prev_mtimes=ldpath_mtimes)
3645 if retval != os.EX_OK:
3647 elif "noclean" not in pkgsettings.features:
3648 portage.doebuild(y, "clean", myroot,
3649 pkgsettings, self.edebug, mydbapi=portdb,
3652 msg = " === (%s of %s) Compiling/Merging (%s::%s)" % \
3653 (mergecount, len(mymergelist), pkg_key, y)
3654 short_msg = "emerge: (%s of %s) %s Compile" % \
3655 (mergecount, len(mymergelist), pkg_key)
3656 emergelog(xterm_titles, msg, short_msg=short_msg)
3657 retval = portage.doebuild(y, "merge", myroot,
3658 pkgsettings, self.edebug, vartree=vartree,
3659 mydbapi=portdb, tree="porttree",
3660 prev_mtimes=ldpath_mtimes)
3661 if retval != os.EX_OK:
3665 portage.locks.unlockdir(builddir_lock)
3668 # Lock catdir for removal if empty.
3669 catdir_lock = portage.locks.lockdir(catdir)
3675 if e.errno not in (errno.ENOENT,
3676 errno.ENOTEMPTY, errno.EEXIST):
3679 portage.locks.unlockdir(catdir_lock)
3681 elif x[0]=="binary":
3683 mytbz2 = self.trees[myroot]["bintree"].getname(pkg_key)
3684 if "--getbinpkg" in self.myopts:
3687 if "distlocks" in pkgsettings.features and \
3688 os.access(pkgsettings["PKGDIR"], os.W_OK):
3689 portage.util.ensure_dirs(os.path.dirname(mytbz2))
3690 tbz2_lock = portage.locks.lockfile(mytbz2,
3692 if self.trees[myroot]["bintree"].isremote(pkg_key):
3693 msg = " --- (%s of %s) Fetching Binary (%s::%s)" %\
3694 (mergecount, len(mymergelist), pkg_key, mytbz2)
3695 short_msg = "emerge: (%s of %s) %s Fetch" % \
3696 (mergecount, len(mymergelist), pkg_key)
3697 emergelog(xterm_titles, msg, short_msg=short_msg)
3699 self.trees[myroot]["bintree"].gettbz2(pkg_key)
3700 except portage.exception.FileNotFound:
3701 writemsg("!!! Fetching Binary failed " + \
3702 "for '%s'\n" % pkg_key, noiselevel=-1)
3705 failed_fetches.append(pkg_key)
3706 except portage.exception.DigestException, e:
3707 writemsg("\n!!! Digest verification failed:\n",
3709 writemsg("!!! %s\n" % e.value[0],
3711 writemsg("!!! Reason: %s\n" % e.value[1],
3713 writemsg("!!! Got: %s\n" % e.value[2],
3715 writemsg("!!! Expected: %s\n" % e.value[3],
3720 failed_fetches.append(pkg_key)
3723 portage.locks.unlockfile(tbz2_lock)
3725 if "--fetchonly" in self.myopts or \
3726 "--fetch-all-uri" in self.myopts:
3730 short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge Binary"
3731 emergelog(xterm_titles, " === ("+str(mergecount)+\
3732 " of "+str(len(mymergelist))+") Merging Binary ("+\
3733 x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
3734 retval = portage.pkgmerge(mytbz2, x[1], pkgsettings,
3736 vartree=self.trees[myroot]["vartree"],
3737 prev_mtimes=ldpath_mtimes)
3738 if retval != os.EX_OK:
3740 #need to check for errors
3741 if "--buildpkgonly" not in self.myopts:
3742 self.trees[x[1]]["vartree"].inject(x[2])
3743 myfavkey = portage.cpv_getkey(x[2])
3744 if not fetchonly and not pretend and \
3745 args_set.findAtomForPackage(pkg_key, metadata):
3747 world_set.load() # maybe it's changed on disk
3748 myfavkey = create_world_atom(pkg_key, metadata,
3749 args_set, root_config)
3751 print ">>> Recording",myfavkey,"in \"world\" favorites file..."
3752 emergelog(xterm_titles, " === ("+\
3753 str(mergecount)+" of "+\
3754 str(len(mymergelist))+\
3755 ") Updating world file ("+x[pkgindex]+")")
3756 world_set.add(myfavkey)
3759 if "--pretend" not in self.myopts and \
3760 "--fetchonly" not in self.myopts and \
3761 "--fetch-all-uri" not in self.myopts:
3762 # Clean the old package that we have merged over top of it.
3763 if pkgsettings.get("AUTOCLEAN", "yes") == "yes":
3764 xsplit=portage.pkgsplit(x[2])
3765 emergelog(xterm_titles, " >>> AUTOCLEAN: " + xsplit[0])
3766 retval = unmerge(pkgsettings, self.myopts, vartree,
3767 "clean", [xsplit[0]], ldpath_mtimes, autoclean=1)
3769 emergelog(xterm_titles,
3770 " --- AUTOCLEAN: Nothing unmerged.")
3772 portage.writemsg_stdout(colorize("WARN", "WARNING:")
3773 + " AUTOCLEAN is disabled. This can cause serious"
3774 + " problems due to overlapping packages.\n")
3776 # Figure out if we need a restart.
3777 mysplit=portage.pkgsplit(x[2])
3778 if mysplit[0] == "sys-apps/portage" and x[1] == "/":
3779 myver=mysplit[1]+"-"+mysplit[2]
3780 if myver[-3:]=='-r0':
3782 if (myver != portage.VERSION) and \
3783 "livecvsportage" not in self.settings.features:
3784 if len(mymergelist) > mergecount:
3785 emergelog(xterm_titles,
3786 " ::: completed emerge ("+ \
3787 str(mergecount)+" of "+ \
3788 str(len(mymergelist))+") "+ \
3790 emergelog(xterm_titles, " *** RESTARTING " + \
3791 "emerge via exec() after change of " + \
3793 del mtimedb["resume"]["mergelist"][0]
3795 portage.run_exitfuncs()
3796 mynewargv=[sys.argv[0],"--resume"]
3797 resume_opts = self.myopts.copy()
3798 # For automatic resume, we need to prevent
3799 # any of bad_resume_opts from leaking in
3800 # via EMERGE_DEFAULT_OPTS.
3801 resume_opts["--ignore-default-opts"] = True
3802 for myopt, myarg in resume_opts.iteritems():
3803 if myopt not in bad_resume_opts:
3805 mynewargv.append(myopt)
3807 mynewargv.append(myopt +"="+ myarg)
3808 # priority only needs to be adjusted on the first run
3809 os.environ["PORTAGE_NICENESS"] = "0"
3810 os.execv(mynewargv[0], mynewargv)
3812 if "--pretend" not in self.myopts and \
3813 "--fetchonly" not in self.myopts and \
3814 "--fetch-all-uri" not in self.myopts:
3815 if "noclean" not in self.settings.features:
3816 short_msg = "emerge: (%s of %s) %s Clean Post" % \
3817 (mergecount, len(mymergelist), x[pkgindex])
3818 emergelog(xterm_titles, (" === (%s of %s) " + \
3819 "Post-Build Cleaning (%s::%s)") % \
3820 (mergecount, len(mymergelist), x[pkgindex], y),
3821 short_msg=short_msg)
3822 emergelog(xterm_titles, " ::: completed emerge ("+\
3823 str(mergecount)+" of "+str(len(mymergelist))+") "+\
3826 # Unsafe for parallel merges
3827 del mtimedb["resume"]["mergelist"][0]
3828 # Commit after each merge so that --resume may still work in
3829 # in the event that portage is not allowed to exit normally
3830 # due to power failure, SIGKILL, etc...
3834 if "--pretend" not in self.myopts:
3835 emergelog(xterm_titles, " *** Finished. Cleaning up...")
3837 # We're out of the loop... We're done. Delete the resume data.
3838 if mtimedb.has_key("resume"):
3839 del mtimedb["resume"]
3842 #by doing an exit this way, --fetchonly can continue to try to
3843 #fetch everything even if a particular download fails.
3844 if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts:
3846 sys.stderr.write("\n\n!!! Some fetch errors were " + \
3847 "encountered. Please see above for details.\n\n")
3848 for cpv in failed_fetches:
3849 sys.stderr.write(" ")
3850 sys.stderr.write(cpv)
3851 sys.stderr.write("\n")
3852 sys.stderr.write("\n")
3858 def unmerge(settings, myopts, vartree, unmerge_action, unmerge_files,
3859 ldpath_mtimes, autoclean=0):
3860 candidate_catpkgs=[]
3862 xterm_titles = "notitles" not in settings.features
3864 vdb_path = os.path.join(settings["ROOT"], portage.VDB_PATH)
3866 # At least the parent needs to exist for the lock file.
3867 portage.util.ensure_dirs(vdb_path)
3868 except portage.exception.PortageException:
3872 if os.access(vdb_path, os.W_OK):
3873 vdb_lock = portage.locks.lockdir(vdb_path)
3874 realsyslist = getlist(settings, "system")
3876 for x in realsyslist:
3877 mycp = portage.dep_getkey(x)
3878 if mycp in settings.getvirtuals():
3880 for provider in settings.getvirtuals()[mycp]:
3881 if vartree.dbapi.match(provider):
3882 providers.append(provider)
3883 if len(providers) == 1:
3884 syslist.extend(providers)
3886 syslist.append(mycp)
3888 mysettings = portage.config(clone=settings)
3890 if not unmerge_files or "world" in unmerge_files or \
3891 "system" in unmerge_files:
3892 if "unmerge"==unmerge_action:
3894 print bold("emerge unmerge") + " can only be used with " + \
3895 "specific package names, not with "+bold("world")+" or"
3896 print bold("system")+" targets."
3903 # process all arguments and add all
3904 # valid db entries to candidate_catpkgs
3906 if not unmerge_files or "world" in unmerge_files:
3907 candidate_catpkgs.extend(vartree.dbapi.cp_all())
3908 elif "system" in unmerge_files:
3909 candidate_catpkgs.extend(getlist(settings, "system"))
3911 #we've got command-line arguments
3912 if not unmerge_files:
3913 print "\nNo packages to unmerge have been provided.\n"
3915 for x in unmerge_files:
3916 arg_parts = x.split('/')
3917 if x[0] not in [".","/"] and \
3918 arg_parts[-1][-7:] != ".ebuild":
3919 #possible cat/pkg or dep; treat as such
3920 candidate_catpkgs.append(x)
3921 elif unmerge_action in ["prune","clean"]:
3922 print "\n!!! Prune and clean do not accept individual" + \
3923 " ebuilds as arguments;\n skipping.\n"
3926 # it appears that the user is specifying an installed
3927 # ebuild and we're in "unmerge" mode, so it's ok.
3928 if not os.path.exists(x):
3929 print "\n!!! The path '"+x+"' doesn't exist.\n"
3932 absx = os.path.abspath(x)
3933 sp_absx = absx.split("/")
3934 if sp_absx[-1][-7:] == ".ebuild":
3936 absx = "/".join(sp_absx)
3938 sp_absx_len = len(sp_absx)
3940 vdb_path = os.path.join(settings["ROOT"], portage.VDB_PATH)
3941 vdb_len = len(vdb_path)
3943 sp_vdb = vdb_path.split("/")
3944 sp_vdb_len = len(sp_vdb)
3946 if not os.path.exists(absx+"/CONTENTS"):
3947 print "!!! Not a valid db dir: "+str(absx)
3950 if sp_absx_len <= sp_vdb_len:
3951 # The Path is shorter... so it can't be inside the vdb.
3954 print "\n!!!",x,"cannot be inside "+ \
3955 vdb_path+"; aborting.\n"
3958 for idx in range(0,sp_vdb_len):
3959 if idx >= sp_absx_len or sp_vdb[idx] != sp_absx[idx]:
3962 print "\n!!!", x, "is not inside "+\
3963 vdb_path+"; aborting.\n"
3966 print "="+"/".join(sp_absx[sp_vdb_len:])
3967 candidate_catpkgs.append(
3968 "="+"/".join(sp_absx[sp_vdb_len:]))
3971 if (not "--quiet" in myopts):
3973 if settings["ROOT"] != "/":
3974 print darkgreen(newline+ \
3975 ">>> Using system located in ROOT tree "+settings["ROOT"])
3976 if (("--pretend" in myopts) or ("--ask" in myopts)) and \
3977 not ("--quiet" in myopts):
3978 print darkgreen(newline+\
3979 ">>> These are the packages that would be unmerged:")
3983 for x in candidate_catpkgs:
3984 # cycle through all our candidate deps and determine
3985 # what will and will not get unmerged
3987 mymatch=localtree.dep_match(x)
3990 except ValueError, errpkgs:
3991 print "\n\n!!! The short ebuild name \"" + \
3992 x + "\" is ambiguous. Please specify"
3993 print "!!! one of the following fully-qualified " + \
3994 "ebuild names instead:\n"
3995 for i in errpkgs[0]:
3996 print " " + green(i)
4000 if not mymatch and x[0] not in "<>=~":
4001 #add a "=" if missing
4002 mymatch=localtree.dep_match("="+x)
4004 portage.writemsg("\n--- Couldn't find '%s' to %s.\n" % \
4005 (x, unmerge_action), noiselevel=-1)
4007 mykey = portage.key_expand(
4009 mymatch[0]), mydb=vartree.dbapi, settings=settings)
4010 if not pkgmap.has_key(mykey):
4011 pkgmap[mykey]={"protected":[], "selected":[], "omitted":[] }
4012 if unmerge_action=="unmerge":
4014 if y not in pkgmap[mykey]["selected"]:
4015 pkgmap[mykey]["selected"].append(y)
4016 numselected=numselected+len(mymatch)
4019 #unmerge_action in ["prune", clean"]
4021 for mypkg in mymatch:
4022 if unmerge_action=="clean":
4023 myslot=localtree.getslot(mypkg)
4025 # since we're pruning, we don't care about slots
4026 # and put all the pkgs in together
4028 if not slotmap.has_key(myslot):
4030 slotmap[myslot][localtree.dbapi.cpv_counter(mypkg)]=mypkg
4031 for myslot in slotmap:
4032 counterkeys=slotmap[myslot].keys()
4037 pkgmap[mykey]["protected"].append(
4038 slotmap[myslot][counterkeys[-1]])
4040 #be pretty and get them in order of merge:
4041 for ckey in counterkeys:
4042 pkgmap[mykey]["selected"].append(slotmap[myslot][ckey])
4043 numselected=numselected+1
4044 # ok, now the last-merged package
4045 # is protected, and the rest are selected
4046 if global_unmerge and not numselected:
4047 portage.writemsg_stdout("\n>>> No outdated packages were found on your system.\n")
4051 portage.writemsg_stdout(
4052 "\n>>> No packages selected for removal by " + \
4053 unmerge_action + "\n")
4057 portage.locks.unlockdir(vdb_lock)
4059 for y in localtree.dep_match(x):
4060 if y not in pkgmap[x]["omitted"] and \
4061 y not in pkgmap[x]["selected"] and \
4062 y not in pkgmap[x]["protected"]:
4063 pkgmap[x]["omitted"].append(y)
4064 if global_unmerge and not pkgmap[x]["selected"]:
4065 #avoid cluttering the preview printout with stuff that isn't getting unmerged
4067 if not (pkgmap[x]["protected"] or pkgmap[x]["omitted"]) and (x in syslist):
4068 print colorize("BAD","\a\n\n!!! '%s' is part of your system profile." % x)
4069 print colorize("WARN","\a!!! Unmerging it may be damaging to your system.\n")
4070 if "--pretend" not in myopts and "--ask" not in myopts:
4071 countdown(int(settings["EMERGE_WARNING_DELAY"]),
4072 colorize("UNMERGE_WARN", "Press Ctrl-C to Stop"))
4073 if "--quiet" not in myopts:
4074 print "\n "+white(x)
4076 print white(x)+": ",
4077 for mytype in ["selected","protected","omitted"]:
4078 if "--quiet" not in myopts:
4079 portage.writemsg_stdout((mytype + ": ").rjust(14), noiselevel=-1)
4080 if pkgmap[x][mytype]:
4081 for mypkg in pkgmap[x][mytype]:
4082 mysplit=portage.catpkgsplit(mypkg)
4083 if mysplit[3]=="r0":
4084 myversion=mysplit[2]
4086 myversion=mysplit[2]+"-"+mysplit[3]
4087 if mytype=="selected":
4088 portage.writemsg_stdout(
4089 colorize("UNMERGE_WARN", myversion + " "), noiselevel=-1)
4091 portage.writemsg_stdout(
4092 colorize("GOOD", myversion + " "), noiselevel=-1)
4094 portage.writemsg_stdout("none ", noiselevel=-1)
4095 if "--quiet" not in myopts:
4096 portage.writemsg_stdout("\n", noiselevel=-1)
4097 if "--quiet" in myopts:
4098 portage.writemsg_stdout("\n", noiselevel=-1)
4100 portage.writemsg_stdout("\n>>> " + colorize("UNMERGE_WARN", "'Selected'") + \
4101 " packages are slated for removal.\n")
4102 portage.writemsg_stdout(">>> " + colorize("GOOD", "'Protected'") + \
4103 " and " + colorize("GOOD", "'omitted'") + \
4104 " packages will not be removed.\n\n")
4106 if "--pretend" in myopts:
4107 #we're done... return
4109 if "--ask" in myopts:
4110 if userquery("Would you like to unmerge these packages?")=="No":
4111 # enter pretend mode for correct formatting of results
4112 myopts["--pretend"] = True
4117 #the real unmerging begins, after a short delay....
4119 countdown(int(settings["CLEAN_DELAY"]), ">>> Unmerging")
4122 for y in pkgmap[x]["selected"]:
4123 print ">>> Unmerging "+y+"..."
4124 emergelog(xterm_titles, "=== Unmerging... ("+y+")")
4125 mysplit=y.split("/")
4127 retval = portage.unmerge(mysplit[0], mysplit[1], settings["ROOT"],
4128 mysettings, unmerge_action not in ["clean","prune"],
4129 vartree=vartree, ldpath_mtimes=ldpath_mtimes)
4130 if retval != os.EX_OK:
4131 emergelog(xterm_titles, " !!! unmerge FAILURE: "+y)
4132 ebuild = vartree.dbapi.findname(y)
4133 show_unmerge_failure_message(y, ebuild, retval)
4136 clean_world(vartree.dbapi, y)
4137 emergelog(xterm_titles, " >>> unmerge success: "+y)
4140 def show_unmerge_failure_message(pkg, ebuild, retval):
4142 from formatter import AbstractFormatter, DumbWriter
4143 f = AbstractFormatter(DumbWriter(sys.stderr, maxcol=72))
4146 msg.append("A removal phase of the '%s' package " % pkg)
4147 msg.append("has failed with exit value %s. " % retval)
4148 msg.append("The problem occurred while executing ")
4149 msg.append("the ebuild located at '%s'. " % ebuild)
4150 msg.append("If necessary, manually remove the ebuild " )
4151 msg.append("in order to skip the execution of removal phases.")
4155 f.add_flowing_data(x)
4159 def chk_updated_info_files(root, infodirs, prev_mtimes, retval):
4161 if os.path.exists("/usr/bin/install-info"):
4166 inforoot=normpath(root+z)
4167 if os.path.isdir(inforoot):
4168 infomtime = long(os.stat(inforoot).st_mtime)
4169 if inforoot not in prev_mtimes or \
4170 prev_mtimes[inforoot] != infomtime:
4171 regen_infodirs.append(inforoot)
4173 if not regen_infodirs:
4174 portage.writemsg_stdout(" "+green("*")+" GNU info directory index is up-to-date.\n")
4176 portage.writemsg_stdout(" "+green("*")+" Regenerating GNU info directory index...\n")
4180 for inforoot in regen_infodirs:
4183 for filename in ("dir", "dir.gz", "dir.bz2"):
4184 file_path = os.path.join(inforoot, filename)
4186 os.rename(file_path, file_path + ".old")
4188 if e.errno != errno.ENOENT:
4192 if not os.path.isdir(inforoot):
4195 file_list = os.listdir(inforoot)
4198 if (x[0] == ".") or (x in ["dir","dir.old"]) or (os.path.isdir(inforoot+"/"+x)):
4200 myso=commands.getstatusoutput("LANG=C LANGUAGE=C /usr/bin/install-info --dir-file="+inforoot+"/dir "+inforoot+"/"+x)[1]
4201 existsstr="already exists, for file `"
4203 if re.search(existsstr,myso):
4204 # Already exists... Don't increment the count for this.
4206 elif myso[:44]=="install-info: warning: no info dir entry in ":
4207 # This info file doesn't contain a DIR-header: install-info produces this
4208 # (harmless) warning (the --quiet switch doesn't seem to work).
4209 # Don't increment the count for this.
4213 errmsg += myso + "\n"
4216 #update mtime so we can potentially avoid regenerating.
4217 prev_mtimes[inforoot] = long(os.stat(inforoot).st_mtime)
4220 print " "+yellow("*")+" Processed",icount,"info files;",badcount,"errors."
4223 print " "+green("*")+" Processed",icount,"info files."
4226 def display_news_notification(trees):
4227 for target_root in trees:
4228 if len(trees) > 1 and target_root != "/":
4230 settings = trees[target_root]["vartree"].settings
4231 portdb = trees[target_root]["porttree"].dbapi
4232 vardb = trees[target_root]["vartree"].dbapi
4233 NEWS_PATH = os.path.join("metadata", "news")
4234 UNREAD_PATH = os.path.join(target_root, NEWS_LIB_PATH, "news")
4235 newsReaderDisplay = False
4237 for repo in portdb.getRepositories():
4238 unreadItems = checkUpdatedNewsItems(
4239 portdb, vardb, NEWS_PATH, UNREAD_PATH, repo)
4241 if not newsReaderDisplay:
4242 newsReaderDisplay = True
4244 print colorize("WARN", " * IMPORTANT:"),
4245 print "%s news items need reading for repository '%s'." % (unreadItems, repo)
4248 if newsReaderDisplay:
4249 print colorize("WARN", " *"),
4250 print "Use " + colorize("GOOD", "eselect news") + " to read news items."
4253 def post_emerge(trees, mtimedb, retval):
4255 Misc. things to run at the end of a merge session.
4261 Display preserved libs warnings
4264 @param trees: A dictionary mapping each ROOT to it's package databases
4266 @param mtimedb: The mtimeDB to store data needed across merge invocations
4267 @type mtimedb: MtimeDB class instance
4268 @param retval: Emerge's return value
4272 1. Calls sys.exit(retval)
4274 for target_root in trees:
4275 if len(trees) > 1 and target_root != "/":
4277 vardbapi = trees[target_root]["vartree"].dbapi
4278 settings = vardbapi.settings
4279 info_mtimes = mtimedb["info"]
4281 # Load the most current variables from ${ROOT}/etc/profile.env
4283 settings.regenerate()
4286 config_protect = settings.get("CONFIG_PROTECT","").split()
4287 infodirs = settings.get("INFOPATH","").split(":") + \
4288 settings.get("INFODIR","").split(":")
4292 emergelog("notitles" not in settings.features,
4293 " *** exiting successfully.")
4295 # Dump the mod_echo output now so that our other notifications are shown
4297 from portage.elog import mod_echo
4300 if "noinfo" not in settings.features:
4301 chk_updated_info_files(target_root, infodirs, info_mtimes, retval)
4303 chk_updated_cfg_files(target_root, config_protect)
4305 display_news_notification(trees)
4307 if vardbapi.plib_registry.hasEntries():
4308 print colorize("WARN", "!!!") + " existing preserved libs:"
4309 plibdata = vardbapi.plib_registry.getPreservedLibs()
4310 for cpv in plibdata:
4311 print colorize("WARN", ">>>") + " package: %s" % cpv
4312 for f in plibdata[cpv]:
4313 print colorize("WARN", " * ") + " - %s" % f
4314 print "Use " + colorize("GOOD", "revdep-rebuild") + " to rebuild packages using these libraries"
4315 print "and then remerge the packages listed above."
4321 def chk_updated_cfg_files(target_root, config_protect):
4323 #number of directories with some protect files in them
4325 for x in config_protect:
4326 x = os.path.join(target_root, x.lstrip(os.path.sep))
4328 mymode = os.lstat(x).st_mode
4331 if stat.S_ISDIR(mymode):
4332 mycommand = "cd '%s'; find . -iname '._cfg????_*'" % x
4334 mycommand = "cd '%s'; find . -maxdepth 1 -iname '._cfg????_%s'" % \
4335 os.path.split(x.rstrip(os.path.sep))
4336 a = commands.getstatusoutput(mycommand + \
4337 " ! -iname '.*~' ! -iname '.*.bak'")
4339 print >> sys.stderr, " " + bad("*")+ " error scanning '%s'" % x
4341 files = a[1].split()
4344 print colorize("WARN", " * IMPORTANT:"),
4345 if stat.S_ISDIR(mymode):
4346 print "%d config files in '%s' need updating." % \
4349 print "config file '%s' needs updating." % x
4352 #print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files."
4353 print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files."
4355 def checkUpdatedNewsItems(portdb, vardb, NEWS_PATH, UNREAD_PATH, repo_id):
4357 Examines news items in repodir + '/' + NEWS_PATH and attempts to find unread items
4358 Returns the number of unread (yet relevent) items.
4360 @param portdb: a portage tree database
4361 @type portdb: pordbapi
4362 @param vardb: an installed package database
4363 @type vardb: vardbapi
4372 1. The number of unread but relevant news items.
4375 from portage.news import NewsManager
4376 manager = NewsManager(portdb, vardb, NEWS_PATH, UNREAD_PATH)
4377 return manager.getUnreadItems( repo_id, update=True )
4379 def is_valid_package_atom(x):
4381 testkey = portage.dep_getkey(x)
4382 except portage.exception.InvalidData:
4384 if testkey.startswith("null/"):
4385 testatom = x.replace(testkey[5:], "cat/"+testkey[5:])
4390 return portage.isvalidatom(testatom)
4392 def show_blocker_docs_link():
4394 print "For more information about " + bad("Blocked Packages") + ", please refer to the following"
4395 print "section of the Gentoo Linux x86 Handbook (architecture is irrelevant):"
4397 print "http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?full=1#blocked"
4400 def action_sync(settings, trees, mtimedb, myopts, myaction):
4401 xterm_titles = "notitles" not in settings.features
4402 emergelog(xterm_titles, " === sync")
4403 myportdir = settings.get("PORTDIR", None)
4405 sys.stderr.write("!!! PORTDIR is undefined. Is /etc/make.globals missing?\n")
4407 if myportdir[-1]=="/":
4408 myportdir=myportdir[:-1]
4409 if not os.path.exists(myportdir):
4410 print ">>>",myportdir,"not found, creating it."
4411 os.makedirs(myportdir,0755)
4412 syncuri=settings["SYNC"].rstrip()
4414 updatecache_flg = False
4415 if myaction == "metadata":
4416 print "skipping sync"
4417 updatecache_flg = True
4418 tmpservertimestampfile = None
4419 elif syncuri[:8]=="rsync://":
4420 if not os.path.exists("/usr/bin/rsync"):
4421 print "!!! /usr/bin/rsync does not exist, so rsync support is disabled."
4422 print "!!! Type \"emerge net-misc/rsync\" to enable rsync support."
4427 import shlex, StringIO
4428 if settings["PORTAGE_RSYNC_OPTS"] == "":
4429 portage.writemsg("PORTAGE_RSYNC_OPTS empty or unset, using hardcoded defaults\n")
4431 "--recursive", # Recurse directories
4432 "--links", # Consider symlinks
4433 "--safe-links", # Ignore links outside of tree
4434 "--perms", # Preserve permissions
4435 "--times", # Preserive mod times
4436 "--compress", # Compress the data transmitted
4437 "--force", # Force deletion on non-empty dirs
4438 "--whole-file", # Don't do block transfers, only entire files
4439 "--delete", # Delete files that aren't in the master tree
4440 "--delete-after", # Delete only after everything else is done
4441 "--stats", # Show final statistics about what was transfered
4442 "--timeout="+str(mytimeout), # IO timeout if not done in X seconds
4443 "--exclude=/distfiles", # Exclude distfiles from consideration
4444 "--exclude=/local", # Exclude local from consideration
4445 "--exclude=/packages", # Exclude packages from consideration
4446 "--filter=H_**/files/digest-*", # Exclude manifest1 digests and delete on the receiving side
4450 # The below validation is not needed when using the above hardcoded
4453 portage.writemsg("Using PORTAGE_RSYNC_OPTS instead of hardcoded defaults\n", 1)
4454 lexer = shlex.shlex(StringIO.StringIO(
4455 settings.get("PORTAGE_RSYNC_OPTS","")), posix=True)
4456 lexer.whitespace_split = True
4457 rsync_opts.extend(lexer)
4460 for opt in ("--recursive", "--times"):
4461 if opt not in rsync_opts:
4462 portage.writemsg(yellow("WARNING:") + " adding required option " + \
4463 "%s not included in PORTAGE_RSYNC_OPTS\n" % opt)
4464 rsync_opts.append(opt)
4466 for exclude in ("distfiles", "local", "packages"):
4467 opt = "--exclude=/%s" % exclude
4468 if opt not in rsync_opts:
4469 portage.writemsg(yellow("WARNING:") + \
4470 " adding required option %s not included in " % opt + \
4471 "PORTAGE_RSYNC_OPTS (can be overridden with --exclude='!')\n")
4472 rsync_opts.append(opt)
4474 if settings["RSYNC_TIMEOUT"] != "":
4475 portage.writemsg("WARNING: usage of RSYNC_TIMEOUT is deprecated, " + \
4476 "use PORTAGE_RSYNC_EXTRA_OPTS instead\n")
4478 mytimeout = int(settings["RSYNC_TIMEOUT"])
4479 rsync_opts.append("--timeout=%d" % mytimeout)
4480 except ValueError, e:
4481 portage.writemsg("!!! %s\n" % str(e))
4483 # TODO: determine options required for official servers
4484 if syncuri.rstrip("/").endswith(".gentoo.org/gentoo-portage"):
4486 def rsync_opt_startswith(opt_prefix):
4487 for x in rsync_opts:
4488 if x.startswith(opt_prefix):
4492 if not rsync_opt_startswith("--timeout="):
4493 rsync_opts.append("--timeout=%d" % mytimeout)
4495 for opt in ("--compress", "--whole-file"):
4496 if opt not in rsync_opts:
4497 portage.writemsg(yellow("WARNING:") + " adding required option " + \
4498 "%s not included in PORTAGE_RSYNC_OPTS\n" % opt)
4499 rsync_opts.append(opt)
4501 if "--quiet" in myopts:
4502 rsync_opts.append("--quiet") # Shut up a lot
4504 rsync_opts.append("--verbose") # Print filelist
4506 if "--verbose" in myopts:
4507 rsync_opts.append("--progress") # Progress meter for each file
4509 if "--debug" in myopts:
4510 rsync_opts.append("--checksum") # Force checksum on all files
4512 if settings["RSYNC_EXCLUDEFROM"] != "":
4513 portage.writemsg(yellow("WARNING:") + \
4514 " usage of RSYNC_EXCLUDEFROM is deprecated, use " + \
4515 "PORTAGE_RSYNC_EXTRA_OPTS instead\n")
4516 if os.path.exists(settings["RSYNC_EXCLUDEFROM"]):
4517 rsync_opts.append("--exclude-from=%s" % \
4518 settings["RSYNC_EXCLUDEFROM"])
4520 portage.writemsg("!!! RSYNC_EXCLUDEFROM specified," + \
4521 " but file does not exist.\n")
4523 if settings["RSYNC_RATELIMIT"] != "":
4524 portage.writemsg(yellow("WARNING:") + \
4525 " usage of RSYNC_RATELIMIT is deprecated, use " + \
4526 "PORTAGE_RSYNC_EXTRA_OPTS instead")
4527 rsync_opts.append("--bwlimit=%s" % \
4528 settings["RSYNC_RATELIMIT"])
4530 # Real local timestamp file.
4531 servertimestampfile = os.path.join(
4532 myportdir, "metadata", "timestamp.chk")
4533 # Temporary file for remote server timestamp comparison.
4534 tmpservertimestampfile = os.path.join(
4535 settings["PORTAGE_TMPDIR"], "timestamp.chk")
4537 content = portage.util.grabfile(servertimestampfile)
4541 mytimestamp = time.mktime(time.strptime(content[0],
4542 "%a, %d %b %Y %H:%M:%S +0000"))
4543 except (OverflowError, ValueError):
4548 rsync_initial_timeout = \
4549 int(settings.get("PORTAGE_RSYNC_INITIAL_TIMEOUT", "15"))
4551 rsync_initial_timeout = 15
4554 if settings.has_key("RSYNC_RETRIES"):
4555 print yellow("WARNING:")+" usage of RSYNC_RETRIES is deprecated, use PORTAGE_RSYNC_RETRIES instead"
4556 maxretries=int(settings["RSYNC_RETRIES"])
4558 maxretries=int(settings["PORTAGE_RSYNC_RETRIES"])
4559 except SystemExit, e:
4560 raise # Needed else can't exit
4562 maxretries=3 #default number of retries
4565 user_name, hostname, port = re.split(
4566 "rsync://([^:/]+@)?([^:/]*)(:[0-9]+)?", syncuri, maxsplit=3)[1:4]
4569 if user_name is None:
4571 updatecache_flg=True
4572 all_rsync_opts = set(rsync_opts)
4573 lexer = shlex.shlex(StringIO.StringIO(
4574 settings.get("PORTAGE_RSYNC_EXTRA_OPTS","")), posix=True)
4575 lexer.whitespace_split = True
4576 extra_rsync_opts = list(lexer)
4578 all_rsync_opts.update(extra_rsync_opts)
4579 family = socket.AF_INET
4580 if "-4" in all_rsync_opts or "--ipv4" in all_rsync_opts:
4581 family = socket.AF_INET
4582 elif socket.has_ipv6 and \
4583 ("-6" in all_rsync_opts or "--ipv6" in all_rsync_opts):
4584 family = socket.AF_INET6
4591 for addrinfo in socket.getaddrinfo(
4592 hostname, None, family, socket.SOCK_STREAM):
4593 if addrinfo[0] == socket.AF_INET6:
4594 # IPv6 addresses need to be enclosed in square brackets
4595 ips.append("[%s]" % addrinfo[4][0])
4597 ips.append(addrinfo[4][0])
4598 from random import shuffle
4600 except SystemExit, e:
4601 raise # Needed else can't exit
4602 except Exception, e:
4603 print "Notice:",str(e)
4608 dosyncuri = syncuri.replace(
4609 "//" + user_name + hostname + port + "/",
4610 "//" + user_name + ips[0] + port + "/", 1)
4611 except SystemExit, e:
4612 raise # Needed else can't exit
4613 except Exception, e:
4614 print "Notice:",str(e)
4618 if "--ask" in myopts:
4619 if userquery("Do you want to sync your Portage tree with the mirror at\n" + blue(dosyncuri) + bold("?"))=="No":
4624 emergelog(xterm_titles, ">>> Starting rsync with " + dosyncuri)
4625 if "--quiet" not in myopts:
4626 print ">>> Starting rsync with "+dosyncuri+"..."
4628 emergelog(xterm_titles,
4629 ">>> Starting retry %d of %d with %s" % \
4630 (retries,maxretries,dosyncuri))
4631 print "\n\n>>> Starting retry %d of %d with %s" % (retries,maxretries,dosyncuri)
4633 if mytimestamp != 0 and "--quiet" not in myopts:
4634 print ">>> Checking server timestamp ..."
4636 rsynccommand = ["/usr/bin/rsync"] + rsync_opts + extra_rsync_opts
4638 if "--debug" in myopts:
4643 # Even if there's no timestamp available locally, fetch the
4644 # timestamp anyway as an initial probe to verify that the server is
4645 # responsive. This protects us from hanging indefinitely on a
4646 # connection attempt to an unresponsive server which rsync's
4647 # --timeout option does not prevent.
4649 mycommand = rsynccommand[:]
4650 mycommand.append(dosyncuri.rstrip("/") + \
4651 "/metadata/timestamp.chk")
4652 mycommand.append(tmpservertimestampfile)
4656 def timeout_handler(signum, frame):
4657 raise portage.exception.PortageException("timed out")
4658 signal.signal(signal.SIGALRM, timeout_handler)
4659 # Timeout here in case the server is unresponsive. The
4660 # --timeout rsync option doesn't apply to the initial
4661 # connection attempt.
4662 if rsync_initial_timeout:
4663 signal.alarm(rsync_initial_timeout)
4665 mypids.extend(portage.process.spawn(
4666 mycommand, env=settings.environ(), returnpid=True))
4667 exitcode = os.waitpid(mypids[0], 0)[1]
4668 content = portage.grabfile(tmpservertimestampfile)
4670 if rsync_initial_timeout:
4673 os.unlink(tmpservertimestampfile)
4676 except portage.exception.PortageException, e:
4680 if mypids and os.waitpid(mypids[0], os.WNOHANG) == (0,0):
4681 os.kill(mypids[0], signal.SIGTERM)
4682 os.waitpid(mypids[0], 0)
4683 # This is the same code rsync uses for timeout.
4686 if exitcode != os.EX_OK:
4688 exitcode = (exitcode & 0xff) << 8
4690 exitcode = exitcode >> 8
4692 portage.process.spawned_pids.remove(mypids[0])
4695 servertimestamp = time.mktime(time.strptime(
4696 content[0], "%a, %d %b %Y %H:%M:%S +0000"))
4697 except (OverflowError, ValueError):
4699 del mycommand, mypids, content
4700 if exitcode == os.EX_OK:
4701 if (servertimestamp != 0) and (servertimestamp == mytimestamp):
4702 emergelog(xterm_titles,
4703 ">>> Cancelling sync -- Already current.")
4706 print ">>> Timestamps on the server and in the local repository are the same."
4707 print ">>> Cancelling all further sync action. You are already up to date."
4709 print ">>> In order to force sync, remove '%s'." % servertimestampfile
4713 elif (servertimestamp != 0) and (servertimestamp < mytimestamp):
4714 emergelog(xterm_titles,
4715 ">>> Server out of date: %s" % dosyncuri)
4718 print ">>> SERVER OUT OF DATE: %s" % dosyncuri
4720 print ">>> In order to force sync, remove '%s'." % servertimestampfile
4723 elif (servertimestamp == 0) or (servertimestamp > mytimestamp):
4725 mycommand = rsynccommand + [dosyncuri+"/", myportdir]
4726 exitcode = portage.process.spawn(mycommand,
4727 env=settings.environ())
4728 if exitcode in [0,1,3,4,11,14,20,21]:
4730 elif exitcode in [1,3,4,11,14,20,21]:
4733 # Code 2 indicates protocol incompatibility, which is expected
4734 # for servers with protocol < 29 that don't support
4735 # --prune-empty-directories. Retry for a server that supports
4736 # at least rsync protocol version 29 (>=rsync-2.6.4).
4741 if retries<=maxretries:
4742 print ">>> Retrying..."
4747 updatecache_flg=False
4751 emergelog(xterm_titles, "=== Sync completed with %s" % dosyncuri)
4755 print darkred("!!!")+green(" Rsync has reported that there is a syntax error. Please ensure")
4756 print darkred("!!!")+green(" that your SYNC statement is proper.")
4757 print darkred("!!!")+green(" SYNC="+settings["SYNC"])
4759 print darkred("!!!")+green(" Rsync has reported that there is a File IO error. Normally")
4760 print darkred("!!!")+green(" this means your disk is full, but can be caused by corruption")
4761 print darkred("!!!")+green(" on the filesystem that contains PORTDIR. Please investigate")
4762 print darkred("!!!")+green(" and try again after the problem has been fixed.")
4763 print darkred("!!!")+green(" PORTDIR="+settings["PORTDIR"])
4765 print darkred("!!!")+green(" Rsync was killed before it finished.")
4767 print darkred("!!!")+green(" Rsync has not successfully finished. It is recommended that you keep")
4768 print darkred("!!!")+green(" trying or that you use the 'emerge-webrsync' option if you are unable")
4769 print darkred("!!!")+green(" to use rsync due to firewall or other restrictions. This should be a")
4770 print darkred("!!!")+green(" temporary problem unless complications exist with your network")
4771 print darkred("!!!")+green(" (and possibly your system's filesystem) configuration.")
4774 elif syncuri[:6]=="cvs://":
4775 if not os.path.exists("/usr/bin/cvs"):
4776 print "!!! /usr/bin/cvs does not exist, so CVS support is disabled."
4777 print "!!! Type \"emerge dev-util/cvs\" to enable CVS support."
4780 cvsdir=os.path.dirname(myportdir)
4781 if not os.path.exists(myportdir+"/CVS"):
4783 print ">>> Starting initial cvs checkout with "+syncuri+"..."
4784 if os.path.exists(cvsdir+"/gentoo-x86"):
4785 print "!!! existing",cvsdir+"/gentoo-x86 directory; exiting."
4790 if e.errno != errno.ENOENT:
4792 "!!! existing '%s' directory; exiting.\n" % myportdir)
4795 if portage.spawn("cd "+cvsdir+"; cvs -z0 -d "+cvsroot+" co -P gentoo-x86",settings,free=1):
4796 print "!!! cvs checkout error; exiting."
4798 os.rename(os.path.join(cvsdir, "gentoo-x86"), myportdir)
4801 print ">>> Starting cvs update with "+syncuri+"..."
4802 retval = portage.spawn("cd '%s'; cvs -z0 -q update -dP" % \
4803 myportdir, settings, free=1)
4804 if retval != os.EX_OK:
4808 print "!!! rsync setting: ",syncuri,"not recognized; exiting."
4811 if updatecache_flg and \
4812 myaction != "metadata" and \
4813 "metadata-transfer" not in settings.features:
4814 updatecache_flg = False
4816 # Reload the whole config from scratch.
4817 settings, trees, mtimedb = load_emerge_config(trees=trees)
4818 portdb = trees[settings["ROOT"]]["porttree"].dbapi
4820 if os.path.exists(myportdir+"/metadata/cache") and updatecache_flg:
4821 action_metadata(settings, portdb, myopts)
4823 if portage._global_updates(trees, mtimedb["updates"]):
4825 # Reload the whole config from scratch.
4826 settings, trees, mtimedb = load_emerge_config(trees=trees)
4827 portdb = trees[settings["ROOT"]]["porttree"].dbapi
4829 mybestpv = portdb.xmatch("bestmatch-visible", "sys-apps/portage")
4830 mypvs = portage.best(
4831 trees[settings["ROOT"]]["vartree"].dbapi.match("sys-apps/portage"))
4833 chk_updated_cfg_files("/", settings.get("CONFIG_PROTECT","").split())
4835 if myaction != "metadata":
4836 if os.access(portage.USER_CONFIG_PATH + "/bin/post_sync", os.X_OK):
4837 retval = portage.process.spawn(
4838 [os.path.join(portage.USER_CONFIG_PATH, "bin", "post_sync"),
4839 dosyncuri], env=settings.environ())
4840 if retval != os.EX_OK:
4841 print red(" * ")+bold("spawn failed of "+ portage.USER_CONFIG_PATH + "/bin/post_sync")
4843 if(mybestpv != mypvs) and not "--quiet" in myopts:
4845 print red(" * ")+bold("An update to portage is available.")+" It is _highly_ recommended"
4846 print red(" * ")+"that you update portage now, before any other packages are updated."
4848 print red(" * ")+"To update portage, run 'emerge portage' now."
4851 display_news_notification(trees)
4853 def action_metadata(settings, portdb, myopts):
4854 portage.writemsg_stdout("\n>>> Updating Portage cache: ")
4855 old_umask = os.umask(0002)
4856 cachedir = os.path.normpath(settings.depcachedir)
4857 if cachedir in ["/", "/bin", "/dev", "/etc", "/home",
4858 "/lib", "/opt", "/proc", "/root", "/sbin",
4859 "/sys", "/tmp", "/usr", "/var"]:
4860 print >> sys.stderr, "!!! PORTAGE_DEPCACHEDIR IS SET TO A PRIMARY " + \
4861 "ROOT DIRECTORY ON YOUR SYSTEM."
4862 print >> sys.stderr, \
4863 "!!! This is ALMOST CERTAINLY NOT what you want: '%s'" % cachedir
4865 if not os.path.exists(cachedir):
4868 ec = portage.eclass_cache.cache(portdb.porttree_root)
4869 myportdir = os.path.realpath(settings["PORTDIR"])
4870 cm = settings.load_best_module("portdbapi.metadbmodule")(
4871 myportdir, "metadata/cache", portage.auxdbkeys[:])
4873 from portage.cache import util
4875 class percentage_noise_maker(util.quiet_mirroring):
4876 def __init__(self, dbapi):
4878 self.cp_all = dbapi.cp_all()
4879 l = len(self.cp_all)
4880 self.call_update_min = 100000000
4881 self.min_cp_all = l/100.0
4886 for x in self.cp_all:
4888 if self.count > self.min_cp_all:
4889 self.call_update_min = 0
4891 for y in self.dbapi.cp_list(x):
4893 self.call_update_mine = 0
4895 def update(self, *arg):
4896 try: self.pstr = int(self.pstr) + 1
4897 except ValueError: self.pstr = 1
4898 sys.stdout.write("%s%i%%" % \
4899 ("\b" * (len(str(self.pstr))+1), self.pstr))
4901 self.call_update_min = 10000000
4903 def finish(self, *arg):
4904 sys.stdout.write("\b\b\b\b100%\n")
4907 if "--quiet" in myopts:
4908 def quicky_cpv_generator(cp_all_list):
4909 for x in cp_all_list:
4910 for y in portdb.cp_list(x):
4912 source = quicky_cpv_generator(portdb.cp_all())
4913 noise_maker = portage.cache.util.quiet_mirroring()
4915 noise_maker = source = percentage_noise_maker(portdb)
4916 portage.cache.util.mirror_cache(source, cm, portdb.auxdb[myportdir],
4917 eclass_cache=ec, verbose_instance=noise_maker)
4922 def action_regen(settings, portdb):
4923 xterm_titles = "notitles" not in settings.features
4924 emergelog(xterm_titles, " === regen")
4925 #regenerate cache entries
4926 print "Regenerating cache entries... "
4928 os.close(sys.stdin.fileno())
4929 except SystemExit, e:
4930 raise # Needed else can't exit
4934 mynodes = portdb.cp_all()
4935 from portage.cache.cache_errors import CacheError
4937 for mytree in portdb.porttrees:
4939 dead_nodes[mytree] = set(portdb.auxdb[mytree].iterkeys())
4940 except CacheError, e:
4941 print "\n error listing cache entries for " + \
4942 "'%s': %s, continuing..." % (mytree, e)
4947 mymatches = portdb.cp_list(x)
4948 portage.writemsg_stdout("processing %s\n" % x)
4951 foo = portdb.aux_get(y,["DEPEND"])
4952 except SystemExit, e:
4953 # sys.exit is an exception... And consequently, we can't catch it.
4955 except Exception, e:
4956 print "\n error processing %(cpv)s, continuing... (%(e)s)" % {"cpv":y,"e":str(e)}
4958 for mytree in portdb.porttrees:
4959 if portdb.findname2(y, mytree=mytree)[0]:
4960 dead_nodes[mytree].discard(y)
4962 for mytree, nodes in dead_nodes.iteritems():
4963 auxdb = portdb.auxdb[mytree]
4967 except (KeyError, CacheError):
4971 def action_config(settings, trees, myopts, myfiles):
4972 if len(myfiles) != 1 or "system" in myfiles or "world" in myfiles:
4973 print red("!!! config can only take a single package atom at this time\n")
4975 if not is_valid_package_atom(myfiles[0]):
4976 portage.writemsg("!!! '%s' is not a valid package atom.\n" % myfiles[0],
4978 portage.writemsg("!!! Please check ebuild(5) for full details.\n")
4979 portage.writemsg("!!! (Did you specify a version but forget to prefix with '='?)\n")
4983 pkgs = trees[settings["ROOT"]]["vartree"].dbapi.match(myfiles[0])
4984 except ValueError, e:
4985 # Multiple matches thrown from cpv_expand
4988 print "No packages found.\n"
4991 if "--ask" in myopts:
4993 print "Please select a package to configure:"
4997 options.append(str(idx))
4998 print options[-1]+") "+pkg
5001 idx = userquery("Selection?", options)
5004 pkg = pkgs[int(idx)-1]
5006 print "The following packages available:"
5009 print "\nPlease use a specific atom or the --ask option."
5015 if "--ask" in myopts:
5016 if userquery("Ready to configure "+pkg+"?") == "No":
5019 print "Configuring pkg..."
5021 ebuildpath = trees[settings["ROOT"]]["vartree"].dbapi.findname(pkg)
5022 mysettings = portage.config(clone=settings)
5023 portage.doebuild(ebuildpath, "config", settings["ROOT"], mysettings,
5024 debug=(settings.get("PORTAGE_DEBUG", "") == 1), cleanup=True,
5025 mydbapi=trees[settings["ROOT"]]["vartree"].dbapi, tree="vartree")
5028 def action_info(settings, trees, myopts, myfiles):
5029 unameout=commands.getstatusoutput("uname -mrp")[1]
5030 print getportageversion(settings["PORTDIR"], settings["ROOT"],
5031 settings.profile_path, settings["CHOST"],
5032 trees[settings["ROOT"]]["vartree"].dbapi)
5034 header_title = "System Settings"
5036 print header_width * "="
5037 print header_title.rjust(int(header_width/2 + len(header_title)/2))
5038 print header_width * "="
5039 print "System uname: "+unameout
5040 gentoo_release = portage.grabfile(os.path.join(
5041 settings["PORTAGE_CONFIGROOT"], "etc", "gentoo-release"))
5043 print gentoo_release[0]
5045 print "Unknown Host Operating System"
5046 lastSync = portage.grabfile(os.path.join(
5047 settings["PORTDIR"], "metadata", "timestamp.chk"))
5048 print "Timestamp of tree:",
5054 output=commands.getstatusoutput("distcc --version")
5056 print str(output[1].split("\n",1)[0]),
5057 if "distcc" in settings.features:
5062 output=commands.getstatusoutput("ccache -V")
5064 print str(output[1].split("\n",1)[0]),
5065 if "ccache" in settings.features:
5070 myvars = ["sys-devel/autoconf", "sys-devel/automake", "virtual/os-headers",
5071 "sys-devel/binutils", "sys-devel/libtool", "dev-lang/python"]
5072 myvars += portage.util.grabfile(settings["PORTDIR"]+"/profiles/info_pkgs")
5073 myvars = portage.util.unique_array(myvars)
5077 if portage.isvalidatom(x):
5078 pkg_matches = trees["/"]["vartree"].dbapi.match(x)
5079 pkg_matches = [portage.catpkgsplit(cpv)[1:] for cpv in pkg_matches]
5080 pkg_matches.sort(portage.pkgcmp)
5082 for pn, ver, rev in pkg_matches:
5084 pkgs.append(ver + "-" + rev)
5088 pkgs = ", ".join(pkgs)
5089 print "%-20s %s" % (x+":", pkgs)
5091 print "%-20s %s" % (x+":", "[NOT VALID]")
5093 libtool_vers = ",".join(trees["/"]["vartree"].dbapi.match("sys-devel/libtool"))
5095 if "--verbose" in myopts:
5096 myvars=settings.keys()
5098 myvars = ['GENTOO_MIRRORS', 'CONFIG_PROTECT', 'CONFIG_PROTECT_MASK',
5099 'PORTDIR', 'DISTDIR', 'PKGDIR', 'PORTAGE_TMPDIR',
5100 'PORTDIR_OVERLAY', 'USE', 'CHOST', 'CFLAGS', 'CXXFLAGS',
5101 'ACCEPT_KEYWORDS', 'SYNC', 'FEATURES', 'EMERGE_DEFAULT_OPTS']
5103 myvars.extend(portage.util.grabfile(settings["PORTDIR"]+"/profiles/info_vars"))
5105 myvars = portage.util.unique_array(myvars)
5111 print '%s="%s"' % (x, settings[x])
5113 use = set(settings["USE"].split())
5114 use_expand = settings["USE_EXPAND"].split()
5116 for varname in use_expand:
5117 flag_prefix = varname.lower() + "_"
5119 if f.startswith(flag_prefix):
5123 print 'USE="%s"' % " ".join(use),
5124 for varname in use_expand:
5125 myval = settings.get(varname)
5127 print '%s="%s"' % (varname, myval),
5130 unset_vars.append(x)
5132 print "Unset: "+", ".join(unset_vars)
5135 if "--debug" in myopts:
5136 for x in dir(portage):
5137 module = getattr(portage, x)
5138 if "cvs_id_string" in dir(module):
5139 print "%s: %s" % (str(x), str(module.cvs_id_string))
5141 # See if we can find any packages installed matching the strings
5142 # passed on the command line
5144 vardb = trees[settings["ROOT"]]["vartree"].dbapi
5145 portdb = trees[settings["ROOT"]]["porttree"].dbapi
5147 mypkgs.extend(vardb.match(x))
5149 # If some packages were found...
5151 # Get our global settings (we only print stuff if it varies from
5152 # the current config)
5153 mydesiredvars = [ 'CHOST', 'CFLAGS', 'CXXFLAGS' ]
5154 auxkeys = mydesiredvars + [ "USE", "IUSE"]
5156 pkgsettings = portage.config(clone=settings)
5158 for myvar in mydesiredvars:
5159 global_vals[myvar] = set(settings.get(myvar, "").split())
5161 # Loop through each package
5162 # Only print settings if they differ from global settings
5163 header_title = "Package Settings"
5164 print header_width * "="
5165 print header_title.rjust(int(header_width/2 + len(header_title)/2))
5166 print header_width * "="
5167 from portage.output import EOutput
5170 # Get all package specific variables
5171 auxvalues = vardb.aux_get(pkg, auxkeys)
5173 for i in xrange(len(auxkeys)):
5174 valuesmap[auxkeys[i]] = set(auxvalues[i].split())
5176 for myvar in mydesiredvars:
5177 # If the package variable doesn't match the
5178 # current global variable, something has changed
5179 # so set diff_found so we know to print
5180 if valuesmap[myvar] != global_vals[myvar]:
5181 diff_values[myvar] = valuesmap[myvar]
5182 valuesmap["IUSE"] = set(filter_iuse_defaults(valuesmap["IUSE"]))
5183 valuesmap["USE"] = valuesmap["USE"].intersection(valuesmap["IUSE"])
5185 # If a matching ebuild is no longer available in the tree, maybe it
5186 # would make sense to compare against the flags for the best
5187 # available version with the same slot?
5189 if portdb.cpv_exists(pkg):
5191 pkgsettings.setcpv(pkg, mydb=mydb)
5192 if valuesmap["IUSE"].intersection(pkgsettings["USE"].split()) != \
5194 diff_values["USE"] = valuesmap["USE"]
5195 # If a difference was found, print the info for
5198 # Print package info
5199 print "%s was built with the following:" % pkg
5200 for myvar in mydesiredvars + ["USE"]:
5201 if myvar in diff_values:
5202 mylist = list(diff_values[myvar])
5204 print "%s=\"%s\"" % (myvar, " ".join(mylist))
5206 print ">>> Attempting to run pkg_info() for '%s'" % pkg
5207 ebuildpath = vardb.findname(pkg)
5208 if not ebuildpath or not os.path.exists(ebuildpath):
5209 out.ewarn("No ebuild found for '%s'" % pkg)
5211 portage.doebuild(ebuildpath, "info", pkgsettings["ROOT"],
5212 pkgsettings, debug=(settings.get("PORTAGE_DEBUG", "") == 1),
5213 mydbapi=trees[settings["ROOT"]]["vartree"].dbapi,
5216 def action_search(settings, portdb, vartree, myopts, myfiles, spinner):
5218 print "emerge: no search terms provided."
5220 searchinstance = search(settings, portdb,
5221 vartree, spinner, "--searchdesc" in myopts,
5222 "--quiet" not in myopts)
5223 for mysearch in myfiles:
5225 searchinstance.execute(mysearch)
5226 except re.error, comment:
5227 print "\n!!! Regular expression error in \"%s\": %s" % ( mysearch, comment )
5229 searchinstance.output()
5231 def action_depclean(settings, trees, ldpath_mtimes,
5233 # Kill packages that aren't explicitly merged or are required as a
5234 # dependency of another package. World file is explicit.
5237 msg.append("Depclean may break link level dependencies. Thus, it is\n")
5238 msg.append("recommended to use a tool such as " + good("`revdep-rebuild`") + " (from\n")
5239 msg.append("app-portage/gentoolkit) in order to detect such breakage.\n")
5241 msg.append("Also study the list of packages to be cleaned for any obvious\n")
5242 msg.append("mistakes. Packages that are part of the world set will always\n")
5243 msg.append("be kept. They can be manually added to this set with\n")
5244 msg.append(good("`emerge --noreplace <atom>`") + ". Packages that are listed in\n")
5245 msg.append("package.provided (see portage(5)) will be removed by\n")
5246 msg.append("depclean, even if they are part of the world set.\n")
5248 msg.append("As a safety measure, depclean will not remove any packages\n")
5249 msg.append("unless *all* required dependencies have been resolved. As a\n")
5250 msg.append("consequence, it is often necessary to run\n")
5251 msg.append(good("`emerge --update --newuse --deep world`") + " prior to depclean.\n")
5253 portage.writemsg_stdout("\n")
5255 portage.writemsg_stdout(colorize("BAD", "*** WARNING *** ") + x)
5257 xterm_titles = "notitles" not in settings.features
5258 myroot = settings["ROOT"]
5259 portdb = trees[myroot]["porttree"].dbapi
5260 dep_check_trees = {}
5261 dep_check_trees[myroot] = {}
5262 dep_check_trees[myroot]["vartree"] = \
5263 FakeVartree(trees[myroot]["vartree"], trees[myroot]["porttree"].dbapi)
5264 vardb = dep_check_trees[myroot]["vartree"].dbapi
5265 # Constrain dependency selection to the installed packages.
5266 dep_check_trees[myroot]["porttree"] = dep_check_trees[myroot]["vartree"]
5267 system_set = SystemSet("system", settings.profiles)
5268 syslist = list(system_set)
5269 world_set = WorldSet("world", myroot)
5270 worldlist = list(world_set)
5271 fakedb = portage.fakedbapi(settings=settings)
5272 myvarlist = vardb.cpv_all()
5275 print "\n!!! You have no system list.",
5277 print "\n!!! You have no world file.",
5279 print "\n!!! You have no installed package database (%s)." % portage.VDB_PATH,
5281 if not (syslist and worldlist and myvarlist):
5282 print "\n!!! Proceeding "+(syslist and myvarlist and "may" or "will")
5283 print " break your installation.\n"
5284 if "--pretend" not in myopts:
5285 countdown(int(settings["EMERGE_WARNING_DELAY"]), ">>> Depclean")
5287 if not "--pretend" in myopts: #just check pretend, since --ask implies pretend
5288 emergelog(xterm_titles, " >>> depclean")
5290 if "--quiet" not in myopts:
5291 print "\nCalculating dependencies ",
5295 remaining_atoms = [(atom, 'world', hard) for atom in worldlist if vardb.match(atom)]
5296 remaining_atoms += [(atom, 'system', hard) for atom in syslist if vardb.match(atom)]
5298 aux_keys = ["DEPEND", "RDEPEND", "PDEPEND"]
5299 metadata_keys = ["PROVIDE", "SLOT", "USE"]
5301 while remaining_atoms:
5302 atom, parent, priority = remaining_atoms.pop()
5303 pkgs = vardb.match(atom)
5305 if not atom.startswith("!") and priority == hard:
5306 unresolveable.setdefault(atom, []).append(parent)
5308 if len(pkgs) > 1 and parent != "world":
5309 # Prune all but the best matching slot, since that's all that a
5310 # deep world update would pull in. Don't prune if this atom comes
5311 # directly from world though, since world atoms are greedy when
5312 # they don't specify a slot.
5313 visible_in_portdb = [cpv for cpv in pkgs if portdb.match("="+cpv)]
5314 if visible_in_portdb:
5315 # For consistency with the update algorithm, keep the highest
5316 # visible version and prune any versions that are either masked
5317 # or no longer exist in the portage tree.
5318 pkgs = visible_in_portdb
5319 pkgs = [portage.best(pkgs)]
5321 if fakedb.cpv_exists(pkg):
5324 fakedb.cpv_inject(pkg)
5325 myaux = dict(izip(aux_keys, vardb.aux_get(pkg, aux_keys)))
5327 if myopts.get("--with-bdeps", "y") == "y":
5328 mydeps.append((myaux["DEPEND"], soft))
5330 mydeps.append((" ".join(myaux.values()), hard))
5331 usedef = vardb.aux_get(pkg, ["USE"])[0].split()
5332 for depstr, priority in mydeps:
5337 if "--debug" in myopts:
5339 print "Parent: ", pkg
5340 print "Depstring:", depstr
5342 if priority == soft:
5348 portage.dep._dep_check_strict = False
5349 success, atoms = portage.dep_check(depstr, None, settings,
5350 myuse=usedef, trees=dep_check_trees, myroot=myroot)
5352 portage.dep._dep_check_strict = True
5354 show_invalid_depstring_notice(
5355 ("installed", myroot, pkg, "nomerge"),
5359 if "--debug" in myopts:
5360 print "Candidates:", atoms
5363 remaining_atoms.append((atom, pkg, priority))
5365 if "--quiet" not in myopts:
5366 print "\b\b... done!\n"
5369 print "Dependencies could not be completely resolved due to"
5370 print "the following required packages not being installed:"
5372 for atom in unresolveable:
5373 print atom, "required by", " ".join(unresolveable[atom])
5375 print "Have you forgotten to run " + good("`emerge --update --newuse --deep world`") + " prior to"
5376 print "depclean? It may be necessary to manually uninstall packages that no longer"
5377 print "exist in the portage tree since it may not be possible to satisfy their"
5378 print "dependencies. Also, be aware of the --with-bdeps option that is documented"
5379 print "in " + good("`man emerge`") + "."
5383 cleanlist = [pkg for pkg in vardb.cpv_all() if not fakedb.cpv_exists(pkg)]
5386 unmerge(settings, myopts, trees[settings["ROOT"]]["vartree"],
5387 "unmerge", cleanlist, ldpath_mtimes)
5389 print "Packages installed: "+str(len(myvarlist))
5390 print "Packages in world: "+str(len(worldlist))
5391 print "Packages in system: "+str(len(syslist))
5392 print "Unique package names: "+str(len(myvarlist))
5393 print "Required packages: "+str(len(fakedb.cpv_all()))
5394 if "--pretend" in myopts:
5395 print "Number to remove: "+str(len(cleanlist))
5397 print "Number removed: "+str(len(cleanlist))
5399 def action_build(settings, trees, mtimedb,
5400 myopts, myaction, myfiles, spinner):
5401 ldpath_mtimes = mtimedb["ldpath"]
5404 pretend = "--pretend" in myopts
5405 fetchonly = "--fetchonly" in myopts or "--fetch-all-uri" in myopts
5406 if pretend or fetchonly:
5407 # make the mtimedb readonly
5408 mtimedb.filename = None
5409 if "--quiet" not in myopts and \
5410 ("--pretend" in myopts or "--ask" in myopts or \
5411 "--tree" in myopts or "--verbose" in myopts):
5413 if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
5417 if "--tree" in myopts and action != "fetched": # Tree doesn't work with fetching
5419 print darkgreen("These are the packages that would be %s, in reverse order:") % action
5423 print darkgreen("These are the packages that would be %s, in order:") % action
5426 # validate the state of the resume data
5427 # so that we can make assumptions later.
5428 for k in ("resume", "resume_backup"):
5430 if "mergelist" in mtimedb[k]:
5431 if not mtimedb[k]["mergelist"]:
5436 if "--resume" in myopts and \
5437 ("resume" in mtimedb or
5438 "resume_backup" in mtimedb):
5439 if "resume" not in mtimedb:
5440 mtimedb["resume"] = mtimedb["resume_backup"]
5441 del mtimedb["resume_backup"]
5444 # Adjust config according to options of the command being resumed.
5445 for myroot in trees:
5446 mysettings = trees[myroot]["vartree"].settings
5448 adjust_config(myopts, mysettings)
5450 del myroot, mysettings
5452 # "myopts" is a list for backward compatibility.
5453 resume_opts = mtimedb["resume"].get("myopts", [])
5454 if isinstance(resume_opts, list):
5455 resume_opts = dict((k,True) for k in resume_opts)
5456 for opt in ("--skipfirst", "--ask", "--tree"):
5457 resume_opts.pop(opt, None)
5458 myopts.update(resume_opts)
5459 show_spinner = "--quiet" not in myopts and "--nodeps" not in myopts
5460 if not show_spinner:
5461 spinner.update = spinner.update_quiet
5463 print "Calculating dependencies ",
5464 myparams = create_depgraph_params(myopts, myaction)
5465 mydepgraph = depgraph(settings, trees,
5466 myopts, myparams, spinner)
5468 mydepgraph.loadResumeCommand(mtimedb["resume"])
5469 except portage.exception.PackageNotFound:
5472 from portage.output import EOutput
5474 out.eerror("Error: The resume list contains packages that are no longer")
5475 out.eerror(" available to be emerged. Please restart/continue")
5476 out.eerror(" the merge operation manually.")
5479 print "\b\b... done!"
5481 if ("--resume" in myopts):
5482 print darkgreen("emerge: It seems we have nothing to resume...")
5485 myparams = create_depgraph_params(myopts, myaction)
5486 if myaction in ["system","world"]:
5487 if "--quiet" not in myopts and "--nodeps" not in myopts:
5488 print "Calculating",myaction,"dependencies ",
5490 mydepgraph = depgraph(settings, trees, myopts, myparams, spinner)
5491 if not mydepgraph.xcreate(myaction):
5492 print "!!! Depgraph creation failed."
5494 if "--quiet" not in myopts and "--nodeps" not in myopts:
5495 print "\b\b... done!"
5497 if "--quiet" not in myopts and "--nodeps" not in myopts:
5498 print "Calculating dependencies ",
5500 mydepgraph = depgraph(settings, trees, myopts, myparams, spinner)
5502 retval, favorites = mydepgraph.select_files(myfiles)
5503 except portage.exception.PackageNotFound, e:
5504 portage.writemsg("\n!!! %s\n" % str(e), noiselevel=-1)
5508 if "--quiet" not in myopts and "--nodeps" not in myopts:
5509 print "\b\b... done!"
5511 if ("--usepkgonly" in myopts) and mydepgraph.missingbins:
5512 sys.stderr.write(red("The following binaries are not available for merging...\n"))
5514 if mydepgraph.missingbins:
5515 for x in mydepgraph.missingbins:
5516 sys.stderr.write(" "+str(x)+"\n")
5517 sys.stderr.write("\nThese are required by '--usepkgonly' -- Terminating.\n\n")
5520 if "--pretend" not in myopts and \
5521 ("--ask" in myopts or "--tree" in myopts or \
5522 "--verbose" in myopts) and \
5523 not ("--quiet" in myopts and "--ask" not in myopts):
5524 if "--resume" in myopts:
5525 mymergelist = mtimedb["resume"]["mergelist"]
5526 if "--skipfirst" in myopts:
5527 mymergelist = mymergelist[1:]
5528 if len(mymergelist) == 0:
5529 print colorize("INFORM", "emerge: It seems we have nothing to resume...")
5531 favorites = mtimedb["resume"]["favorites"]
5532 retval = mydepgraph.display(mymergelist, favorites=favorites)
5533 if retval != os.EX_OK:
5535 prompt="Would you like to resume merging these packages?"
5537 retval = mydepgraph.display(
5538 mydepgraph.altlist(reversed=("--tree" in myopts)),
5539 favorites=favorites)
5540 if retval != os.EX_OK:
5543 for x in mydepgraph.altlist():
5544 if x[0] != "blocks" and x[3] != "nomerge":
5546 #check for blocking dependencies
5547 if x[0]=="blocks" and "--fetchonly" not in myopts and "--fetch-all-uri" not in myopts:
5548 print "\n!!! Error: The above package list contains packages which cannot be installed"
5549 print "!!! at the same time on the same system."
5550 if "--quiet" not in myopts:
5551 show_blocker_docs_link()
5554 if "--noreplace" in myopts and favorites:
5557 print " %s %s" % (good("*"), x)
5558 prompt="Would you like to add these packages to your world favorites?"
5559 elif settings["AUTOCLEAN"] and "yes"==settings["AUTOCLEAN"]:
5560 prompt="Nothing to merge; would you like to auto-clean packages?"
5563 print "Nothing to merge; quitting."
5566 elif "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
5567 prompt="Would you like to fetch the source files for these packages?"
5569 prompt="Would you like to merge these packages?"
5571 if "--ask" in myopts and userquery(prompt) == "No":
5576 # Don't ask again (e.g. when auto-cleaning packages after merge)
5577 myopts.pop("--ask", None)
5579 if ("--pretend" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
5580 if ("--resume" in myopts):
5581 mymergelist = mtimedb["resume"]["mergelist"]
5582 if "--skipfirst" in myopts:
5583 mymergelist = mymergelist[1:]
5584 if len(mymergelist) == 0:
5585 print colorize("INFORM", "emerge: It seems we have nothing to resume...")
5587 favorites = mtimedb["resume"]["favorites"]
5588 retval = mydepgraph.display(mymergelist, favorites=favorites)
5589 if retval != os.EX_OK:
5592 retval = mydepgraph.display(
5593 mydepgraph.altlist(reversed=("--tree" in myopts)),
5594 favorites=favorites)
5595 if retval != os.EX_OK:
5597 if "--buildpkgonly" in myopts and \
5598 not mydepgraph.digraph.hasallzeros(ignore_priority=DepPriority.MEDIUM):
5599 print "\n!!! --buildpkgonly requires all dependencies to be merged."
5600 print "!!! You have to merge the dependencies before you can build this package.\n"
5603 if ("--buildpkgonly" in myopts):
5604 if not mydepgraph.digraph.hasallzeros(ignore_priority=DepPriority.MEDIUM):
5605 print "\n!!! --buildpkgonly requires all dependencies to be merged."
5606 print "!!! Cannot merge requested packages. Merge deps and try again.\n"
5609 if ("--resume" in myopts):
5610 favorites=mtimedb["resume"]["favorites"]
5611 mergetask = MergeTask(settings, trees, myopts)
5612 if "--fetchonly" in myopts:
5613 """ parallel-fetch uses --resume --fetchonly and we don't want
5614 it to write the mtimedb"""
5615 mtimedb.filename = None
5616 time.sleep(3) # allow the parent to have first fetch
5618 retval = mergetask.merge(
5619 mtimedb["resume"]["mergelist"], favorites, mtimedb)
5620 merge_count = mergetask.curval
5622 if "resume" in mtimedb and \
5623 "mergelist" in mtimedb["resume"] and \
5624 len(mtimedb["resume"]["mergelist"]) > 1:
5625 mtimedb["resume_backup"] = mtimedb["resume"]
5626 del mtimedb["resume"]
5628 mtimedb["resume"]={}
5629 # XXX: Stored as a list for backward compatibility.
5630 mtimedb["resume"]["myopts"] = \
5631 [k for k in myopts if myopts[k] is True]
5632 mtimedb["resume"]["favorites"]=favorites
5633 if ("--digest" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
5634 for pkgline in mydepgraph.altlist():
5635 if pkgline[0]=="ebuild" and pkgline[3]=="merge":
5636 y = trees[pkgline[1]]["porttree"].dbapi.findname(pkgline[2])
5637 tmpsettings = portage.config(clone=settings)
5639 if settings.get("PORTAGE_DEBUG", "") == "1":
5641 retval = portage.doebuild(
5642 y, "digest", settings["ROOT"], tmpsettings, edebug,
5643 ("--pretend" in myopts),
5644 mydbapi=trees[pkgline[1]]["porttree"].dbapi,
5646 if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
5648 for pkg in mydepgraph.altlist():
5649 if pkg[0] != "blocks":
5652 pkglist = mydepgraph.altlist()
5654 mydepgraph.saveNomergeFavorites()
5656 mergetask = MergeTask(settings, trees, myopts)
5657 retval = mergetask.merge(pkglist, favorites, mtimedb)
5658 merge_count = mergetask.curval
5660 if retval == os.EX_OK and not (pretend or fetchonly):
5661 mtimedb.pop("resume", None)
5662 if "yes" == settings.get("AUTOCLEAN"):
5663 portage.writemsg_stdout(">>> Auto-cleaning packages...\n")
5664 vartree = trees[settings["ROOT"]]["vartree"]
5665 unmerge(settings, myopts, vartree, "clean", ["world"],
5666 ldpath_mtimes, autoclean=1)
5668 portage.writemsg_stdout(colorize("WARN", "WARNING:")
5669 + " AUTOCLEAN is disabled. This can cause serious"
5670 + " problems due to overlapping packages.\n")
5672 if merge_count and not (pretend or fetchonly):
5673 post_emerge(trees, mtimedb, retval)
5676 def multiple_actions(action1, action2):
5677 sys.stderr.write("\n!!! Multiple actions requested... Please choose one only.\n")
5678 sys.stderr.write("!!! '%s' or '%s'\n\n" % (action1, action2))
5681 def parse_opts(tmpcmdline, silent=False):
5686 global actions, options, shortmapping
5688 longopt_aliases = {"--cols":"--columns", "--skip-first":"--skipfirst"}
5689 argument_options = {
5691 "help":"specify the location for portage configuration files",
5695 "help":"enable or disable color output",
5697 "choices":("y", "n")
5700 "help":"include unnecessary build time dependencies",
5702 "choices":("y", "n")
5705 "help":"specify conditions to trigger package reinstallation",
5707 "choices":["changed-use"]
5711 from optparse import OptionParser
5712 parser = OptionParser()
5713 if parser.has_option("--help"):
5714 parser.remove_option("--help")
5716 for action_opt in actions:
5717 parser.add_option("--" + action_opt, action="store_true",
5718 dest=action_opt.replace("-", "_"), default=False)
5719 for myopt in options:
5720 parser.add_option(myopt, action="store_true",
5721 dest=myopt.lstrip("--").replace("-", "_"), default=False)
5722 for shortopt, longopt in shortmapping.iteritems():
5723 parser.add_option("-" + shortopt, action="store_true",
5724 dest=longopt.lstrip("--").replace("-", "_"), default=False)
5725 for myalias, myopt in longopt_aliases.iteritems():
5726 parser.add_option(myalias, action="store_true",
5727 dest=myopt.lstrip("--").replace("-", "_"), default=False)
5729 for myopt, kwargs in argument_options.iteritems():
5730 parser.add_option(myopt,
5731 dest=myopt.lstrip("--").replace("-", "_"), **kwargs)
5733 myoptions, myargs = parser.parse_args(args=tmpcmdline)
5735 for myopt in options:
5736 v = getattr(myoptions, myopt.lstrip("--").replace("-", "_"))
5738 myopts[myopt] = True
5740 for myopt in argument_options:
5741 v = getattr(myoptions, myopt.lstrip("--").replace("-", "_"), None)
5745 for action_opt in actions:
5746 v = getattr(myoptions, action_opt.replace("-", "_"))
5749 multiple_actions(myaction, action_opt)
5751 myaction = action_opt
5754 if x in actions and myaction != "search":
5755 if not silent and x not in ["system", "world"]:
5756 print red("*** Deprecated use of action '%s', use '--%s' instead" % (x,x))
5757 # special case "search" so people can search for action terms, e.g. emerge -s sync
5759 multiple_actions(myaction, x)
5765 if "--nocolor" in myopts:
5767 sys.stderr.write("*** Deprecated use of '--nocolor', " + \
5768 "use '--color=n' instead.\n")
5769 del myopts["--nocolor"]
5770 myopts["--color"] = "n"
5772 return myaction, myopts, myfiles
5774 def validate_ebuild_environment(trees):
5775 for myroot in trees:
5776 mysettings = trees[myroot]["vartree"].settings
5777 for var in "ARCH", "USERLAND":
5778 if mysettings.get(var):
5780 print >> sys.stderr, bad(("\a!!! %s is not set... " % var) + \
5781 "Are you missing the '%setc/make.profile' symlink?" % \
5782 mysettings["PORTAGE_CONFIGROOT"])
5783 print >> sys.stderr, bad("\a!!! Is the symlink correct? " + \
5784 "Is your portage tree complete?\n")
5786 del myroot, mysettings
5788 def load_emerge_config(trees=None):
5790 for k, envvar in (("config_root", "PORTAGE_CONFIGROOT"), ("target_root", "ROOT")):
5791 kwargs[k] = os.environ.get(envvar, None)
5792 trees = portage.create_trees(trees=trees, **kwargs)
5794 settings = trees["/"]["vartree"].settings
5796 for myroot in trees:
5798 settings = trees[myroot]["vartree"].settings
5801 mtimedbfile = os.path.join("/", portage.CACHE_PATH.lstrip(os.path.sep), "mtimedb")
5802 mtimedb = portage.MtimeDB(mtimedbfile)
5803 return settings, trees, mtimedb
5805 def adjust_config(myopts, settings):
5806 """Make emerge specific adjustments to the config."""
5808 # To enhance usability, make some vars case insensitive by forcing them to
5810 for myvar in ("AUTOCLEAN", "NOCOLOR"):
5811 if myvar in settings:
5812 settings[myvar] = settings[myvar].lower()
5813 settings.backup_changes(myvar)
5816 # Kill noauto as it will break merges otherwise.
5817 if "noauto" in settings.features:
5818 while "noauto" in settings.features:
5819 settings.features.remove("noauto")
5820 settings["FEATURES"] = " ".join(settings.features)
5821 settings.backup_changes("FEATURES")
5825 CLEAN_DELAY = int(settings.get("CLEAN_DELAY", str(CLEAN_DELAY)))
5826 except ValueError, e:
5827 portage.writemsg("!!! %s\n" % str(e), noiselevel=-1)
5828 portage.writemsg("!!! Unable to parse integer: CLEAN_DELAY='%s'\n" % \
5829 settings["CLEAN_DELAY"], noiselevel=-1)
5830 settings["CLEAN_DELAY"] = str(CLEAN_DELAY)
5831 settings.backup_changes("CLEAN_DELAY")
5833 EMERGE_WARNING_DELAY = 10
5835 EMERGE_WARNING_DELAY = int(settings.get(
5836 "EMERGE_WARNING_DELAY", str(EMERGE_WARNING_DELAY)))
5837 except ValueError, e:
5838 portage.writemsg("!!! %s\n" % str(e), noiselevel=-1)
5839 portage.writemsg("!!! Unable to parse integer: EMERGE_WARNING_DELAY='%s'\n" % \
5840 settings["EMERGE_WARNING_DELAY"], noiselevel=-1)
5841 settings["EMERGE_WARNING_DELAY"] = str(EMERGE_WARNING_DELAY)
5842 settings.backup_changes("EMERGE_WARNING_DELAY")
5844 if "--quiet" in myopts:
5845 settings["PORTAGE_QUIET"]="1"
5846 settings.backup_changes("PORTAGE_QUIET")
5848 # Set so that configs will be merged regardless of remembered status
5849 if ("--noconfmem" in myopts):
5850 settings["NOCONFMEM"]="1"
5851 settings.backup_changes("NOCONFMEM")
5853 # Set various debug markers... They should be merged somehow.
5856 PORTAGE_DEBUG = int(settings.get("PORTAGE_DEBUG", str(PORTAGE_DEBUG)))
5857 if PORTAGE_DEBUG not in (0, 1):
5858 portage.writemsg("!!! Invalid value: PORTAGE_DEBUG='%i'\n" % \
5859 PORTAGE_DEBUG, noiselevel=-1)
5860 portage.writemsg("!!! PORTAGE_DEBUG must be either 0 or 1\n",
5863 except ValueError, e:
5864 portage.writemsg("!!! %s\n" % str(e), noiselevel=-1)
5865 portage.writemsg("!!! Unable to parse integer: PORTAGE_DEBUG='%s'\n" %\
5866 settings["PORTAGE_DEBUG"], noiselevel=-1)
5868 if "--debug" in myopts:
5870 settings["PORTAGE_DEBUG"] = str(PORTAGE_DEBUG)
5871 settings.backup_changes("PORTAGE_DEBUG")
5873 if settings.get("NOCOLOR") not in ("yes","true"):
5874 portage.output.havecolor = 1
5876 """The explicit --color < y | n > option overrides the NOCOLOR environment
5877 variable and stdout auto-detection."""
5878 if "--color" in myopts:
5879 if "y" == myopts["--color"]:
5880 portage.output.havecolor = 1
5881 settings["NOCOLOR"] = "false"
5883 portage.output.havecolor = 0
5884 settings["NOCOLOR"] = "true"
5885 settings.backup_changes("NOCOLOR")
5886 elif not sys.stdout.isatty() and settings.get("NOCOLOR") != "no":
5887 portage.output.havecolor = 0
5888 settings["NOCOLOR"] = "true"
5889 settings.backup_changes("NOCOLOR")
5892 global portage # NFC why this is necessary now - genone
5893 # Disable color until we're sure that it should be enabled (after
5894 # EMERGE_DEFAULT_OPTS has been parsed).
5895 portage.output.havecolor = 0
5896 # This first pass is just for options that need to be known as early as
5897 # possible, such as --config-root. They will be parsed again later,
5898 # together with EMERGE_DEFAULT_OPTS (which may vary depending on the
5899 # the value of --config-root).
5900 myaction, myopts, myfiles = parse_opts(sys.argv[1:], silent=True)
5901 if "--debug" in myopts:
5902 os.environ["PORTAGE_DEBUG"] = "1"
5903 if "--config-root" in myopts:
5904 os.environ["PORTAGE_CONFIGROOT"] = myopts["--config-root"]
5906 # Portage needs to ensure a sane umask for the files it creates.
5908 settings, trees, mtimedb = load_emerge_config()
5909 portdb = trees[settings["ROOT"]]["porttree"].dbapi
5912 os.nice(int(settings.get("PORTAGE_NICENESS", "0")))
5913 except (OSError, ValueError), e:
5914 portage.writemsg("!!! Failed to change nice value to '%s'\n" % \
5915 settings["PORTAGE_NICENESS"])
5916 portage.writemsg("!!! %s\n" % str(e))
5919 if portage._global_updates(trees, mtimedb["updates"]):
5921 # Reload the whole config from scratch.
5922 settings, trees, mtimedb = load_emerge_config(trees=trees)
5923 portdb = trees[settings["ROOT"]]["porttree"].dbapi
5925 xterm_titles = "notitles" not in settings.features
5928 if "--ignore-default-opts" not in myopts:
5929 tmpcmdline.extend(settings["EMERGE_DEFAULT_OPTS"].split())
5930 tmpcmdline.extend(sys.argv[1:])
5931 myaction, myopts, myfiles = parse_opts(tmpcmdline)
5933 if "--digest" in myopts:
5934 os.environ["FEATURES"] = os.environ.get("FEATURES","") + " digest"
5935 # Reload the whole config from scratch so that the portdbapi internal
5936 # config is updated with new FEATURES.
5937 settings, trees, mtimedb = load_emerge_config(trees=trees)
5938 portdb = trees[settings["ROOT"]]["porttree"].dbapi
5940 for myroot in trees:
5941 mysettings = trees[myroot]["vartree"].settings
5943 adjust_config(myopts, mysettings)
5945 del myroot, mysettings
5947 spinner = stdout_spinner()
5948 if "candy" in settings.features:
5949 spinner.update = spinner.update_scroll
5951 if "--quiet" not in myopts:
5952 portage.deprecated_profile_check()
5954 #Freeze the portdbapi for enhanced performance:
5955 for myroot in trees:
5956 trees[myroot]["porttree"].dbapi.freeze()
5959 if "moo" in myfiles:
5962 Larry loves Gentoo (""" + os.uname()[0] + """)
5964 _______________________
5965 < Have you mooed today? >
5966 -----------------------
5975 if (myaction in ["world", "system"]) and myfiles:
5976 print "emerge: please specify a package class (\"world\" or \"system\") or individual packages, but not both."
5980 ext = os.path.splitext(x)[1]
5981 if (ext == ".ebuild" or ext == ".tbz2") and os.path.exists(os.path.abspath(x)):
5982 print colorize("BAD", "\n*** emerging by path is broken and may not always work!!!\n")
5985 if ("--tree" in myopts) and ("--columns" in myopts):
5986 print "emerge: can't specify both of \"--tree\" and \"--columns\"."
5989 if ("--quiet" in myopts):
5990 spinner.update = spinner.update_quiet
5991 portage.util.noiselimit = -1
5993 # Always create packages if FEATURES=buildpkg
5994 # Imply --buildpkg if --buildpkgonly
5995 if ("buildpkg" in settings.features) or ("--buildpkgonly" in myopts):
5996 if "--buildpkg" not in myopts:
5997 myopts["--buildpkg"] = True
5999 # Also allow -S to invoke search action (-sS)
6000 if ("--searchdesc" in myopts):
6001 if myaction and myaction != "search":
6002 myfiles.append(myaction)
6003 if "--search" not in myopts:
6004 myopts["--search"] = True
6007 # Always try and fetch binary packages if FEATURES=getbinpkg
6008 if ("getbinpkg" in settings.features):
6009 myopts["--getbinpkg"] = True
6011 if "--skipfirst" in myopts and "--resume" not in myopts:
6012 myopts["--resume"] = True
6014 if ("--getbinpkgonly" in myopts) and not ("--usepkgonly" in myopts):
6015 myopts["--usepkgonly"] = True
6017 if ("--getbinpkgonly" in myopts) and not ("--getbinpkg" in myopts):
6018 myopts["--getbinpkg"] = True
6020 if ("--getbinpkg" in myopts) and not ("--usepkg" in myopts):
6021 myopts["--usepkg"] = True
6023 # Also allow -K to apply --usepkg/-k
6024 if ("--usepkgonly" in myopts) and not ("--usepkg" in myopts):
6025 myopts["--usepkg"] = True
6027 # Allow -p to remove --ask
6028 if ("--pretend" in myopts) and ("--ask" in myopts):
6029 print ">>> --pretend disables --ask... removing --ask from options."
6032 # forbid --ask when not in a terminal
6033 # note: this breaks `emerge --ask | tee logfile`, but that doesn't work anyway.
6034 if ("--ask" in myopts) and (not sys.stdin.isatty()):
6035 portage.writemsg("!!! \"--ask\" should only be used in a terminal. Exiting.\n",
6039 if settings.get("PORTAGE_DEBUG", "") == "1":
6040 spinner.update = spinner.update_quiet
6042 if "python-trace" in settings.features:
6043 import portage.debug
6044 portage.debug.set_trace(True)
6046 if ("--resume" in myopts):
6047 if "--tree" in myopts:
6048 print "* --tree is currently broken with --resume. Disabling..."
6049 del myopts["--tree"]
6051 if not ("--quiet" in myopts):
6052 if not sys.stdout.isatty() or ("--nospinner" in myopts):
6053 spinner.update = spinner.update_basic
6055 if "--version" in myopts:
6056 print getportageversion(settings["PORTDIR"], settings["ROOT"],
6057 settings.profile_path, settings["CHOST"],
6058 trees[settings["ROOT"]]["vartree"].dbapi)
6060 elif "--help" in myopts:
6061 emerge.help.help(myaction, myopts, portage.output.havecolor)
6064 if "--debug" in myopts:
6065 print "myaction", myaction
6066 print "myopts", myopts
6068 if not myaction and not myfiles and "--resume" not in myopts:
6069 emerge.help.help(myaction, myopts, portage.output.havecolor)
6072 # check if root user is the current user for the actions where emerge needs this
6073 if portage.secpass < 2:
6074 # We've already allowed "--version" and "--help" above.
6075 if "--pretend" not in myopts and myaction not in ("search","info"):
6076 need_superuser = not \
6077 ("--fetchonly" in myopts or \
6078 "--fetch-all-uri" in myopts or \
6079 myaction in ("metadata", "regen") or \
6080 (myaction == "sync" and os.access(settings["PORTDIR"], os.W_OK)))
6081 if portage.secpass < 1 or \
6084 access_desc = "superuser"
6086 access_desc = "portage group"
6087 # Always show portage_group_warning() when only portage group
6088 # access is required but the user is not in the portage group.
6089 from portage.data import portage_group_warning
6090 if "--ask" in myopts:
6091 myopts["--pretend"] = True
6093 print ("%s access is required... " + \
6094 "adding --pretend to options.\n") % access_desc
6095 if portage.secpass < 1 and not need_superuser:
6096 portage_group_warning()
6098 sys.stderr.write(("emerge: %s access is " + \
6099 "required.\n\n") % access_desc)
6100 if portage.secpass < 1 and not need_superuser:
6101 portage_group_warning()
6104 disable_emergelog = False
6105 for x in ("--pretend", "--fetchonly", "--fetch-all-uri"):
6107 disable_emergelog = True
6109 if myaction in ("search", "info"):
6110 disable_emergelog = True
6111 if disable_emergelog:
6112 """ Disable emergelog for everything except build or unmerge
6113 operations. This helps minimize parallel emerge.log entries that can
6114 confuse log parsers. We especially want it disabled during
6115 parallel-fetch, which uses --resume --fetchonly."""
6117 def emergelog(*pargs, **kargs):
6120 if not "--pretend" in myopts:
6121 emergelog(xterm_titles, "Started emerge on: "+\
6122 time.strftime("%b %d, %Y %H:%M:%S", time.localtime()))
6125 myelogstr=" ".join(myopts)
6127 myelogstr+=" "+myaction
6129 myelogstr+=" "+" ".join(myfiles)
6130 emergelog(xterm_titles, " *** emerge " + myelogstr)
6132 def emergeexitsig(signum, frame):
6133 signal.signal(signal.SIGINT, signal.SIG_IGN)
6134 signal.signal(signal.SIGTERM, signal.SIG_IGN)
6135 portage.util.writemsg("\n\nExiting on signal %(signal)s\n" % {"signal":signum})
6136 sys.exit(100+signum)
6137 signal.signal(signal.SIGINT, emergeexitsig)
6138 signal.signal(signal.SIGTERM, emergeexitsig)
6141 """This gets out final log message in before we quit."""
6142 if "--pretend" not in myopts:
6143 emergelog(xterm_titles, " *** terminating.")
6144 if "notitles" not in settings.features:
6146 portage.atexit_register(emergeexit)
6148 if myaction in ("config", "metadata", "regen", "sync"):
6149 if "--pretend" in myopts:
6150 sys.stderr.write(("emerge: The '%s' action does " + \
6151 "not support '--pretend'.\n") % myaction)
6153 if "sync" == myaction:
6154 action_sync(settings, trees, mtimedb, myopts, myaction)
6155 elif "metadata" == myaction:
6156 action_metadata(settings, portdb, myopts)
6157 elif myaction=="regen":
6158 validate_ebuild_environment(trees)
6159 action_regen(settings, portdb)
6161 elif "config"==myaction:
6162 validate_ebuild_environment(trees)
6163 action_config(settings, trees, myopts, myfiles)
6166 elif "info"==myaction:
6167 action_info(settings, trees, myopts, myfiles)
6170 elif "search"==myaction:
6171 validate_ebuild_environment(trees)
6172 action_search(settings, portdb, trees["/"]["vartree"],
6173 myopts, myfiles, spinner)
6174 elif "unmerge"==myaction or "prune"==myaction or "clean"==myaction:
6175 validate_ebuild_environment(trees)
6176 vartree = trees[settings["ROOT"]]["vartree"]
6177 if 1 == unmerge(settings, myopts, vartree, myaction, myfiles,
6179 if "--pretend" not in myopts:
6180 post_emerge(trees, mtimedb, os.EX_OK)
6182 elif "depclean"==myaction:
6183 validate_ebuild_environment(trees)
6184 action_depclean(settings, trees, mtimedb["ldpath"],
6186 if "--pretend" not in myopts:
6187 post_emerge(trees, mtimedb, os.EX_OK)
6188 # "update", "system", or just process files:
6190 validate_ebuild_environment(trees)
6191 if "--pretend" not in myopts:
6192 display_news_notification(trees)
6193 retval = action_build(settings, trees, mtimedb,
6194 myopts, myaction, myfiles, spinner)
6195 if "--pretend" in myopts:
6196 display_news_notification(trees)
6199 if __name__ == "__main__":
6200 retval = emerge_main()