--- emerge.old 2006-06-16 17:26:52.647176688 +0000 +++ emerge 2006-06-16 18:28:43.544034616 +0000 @@ -882,1277 +882,6 @@ mynewdict[portage.dep_getkey(x)]=x return mynewdict -olddbapi=None -class depgraph: - - def __init__(self,myaction,myopts): - global olddbapi - self.pkgsettings = portage.config(clone=portage.settings) - if not self.pkgsettings["ARCH"]: - portage.writemsg(red("\a!!! ARCH is not set... Are you missing the /etc/make.profile symlink?\n"), - noiselevel=-1) - portage.writemsg(red("\a!!! Is the symlink correct? Is your portage tree complete?\n\n"), - noiselevel=-1) - sys.exit(9) - self.applied_useflags = {} - - self.missingbins=[] - self.myaction=myaction - self.digraph=portage.digraph() - self.orderedkeys=[] - self.outdatedpackages=[] - self.mydbapi={} - self.mydbapi["/"] = portage.fakedbapi() - if "empty" not in myparams or portage.root != "/": - for pkg in portage.db["/"]["vartree"].getallcpv(): - self.mydbapi["/"].cpv_inject(pkg) - if portage.root != "/": - self.mydbapi[portage.root] = portage.fakedbapi() - if "empty" not in myparams: - for pkg in portage.db[portage.root]["vartree"].getallcpv(): - self.mydbapi[portage.root].cpv_inject(pkg) - - if "--usepkg" in myopts: - portage.db["/"]["bintree"].populate(("--getbinpkg" in myopts), ("--getbinpkgonly" in myopts)) - - def create(self,mybigkey,myparent=None,addme=1,myuse=None): - """creates the actual digraph of packages to merge. return 1 on success, 0 on failure - mybigkey = specification of package to merge; myparent = parent package (one depending on me); - addme = should I be added to the tree? (for the --onlydeps mode)""" - #stuff to add: - #SLOT-aware emerge - #IUSE-aware emerge - #"no downgrade" emerge - #print "mybigkey:",mybigkey - - jbigkey=string.join(mybigkey) - if self.digraph.hasnode(jbigkey+" merge") or self.digraph.hasnode(jbigkey+" nomerge"): - #this conditional is needed to prevent infinite recursion on already-processed deps - return 1 - - update_spinner() - - mytype,myroot,mykey=mybigkey - # select the correct /var database that we'll be checking against - vardbapi=portage.db[myroot]["vartree"].dbapi - - # if the package is already on the system, we add a "nomerge" - # directive, otherwise we add a "merge" directive. - if mytype=="blocks": - # we've encountered a "blocks" node. We will totally ignore this - # node and not add it to our digraph if it doesn't apply to us. - if addme and "--buildpkgonly" not in myopts and myparent and (self.mydbapi[myroot].match(mykey) or vardbapi.match(mykey)): - mybigkey.append(myparent.split()[2]) - self.digraph.addnode(string.join(mybigkey),myparent) - return 1 - - if myuse is None: - self.pkgsettings.setcpv(mykey) - myuse = self.pkgsettings["USE"].split() - self.applied_useflags[mykey] = myuse - - merging=1 - if addme: - # this is where we add the node to the list of packages to merge - if not myparent: - # command-line specified or part of a world list... - if ("self" not in myparams) or (("selective" in myparams) and vardbapi.cpv_exists(mykey)): - # the package is on the system, so don't merge it. - merging=0 - elif ("selective" in myparams) and vardbapi.cpv_exists(mykey): - merging=0 - - if (merging==0 and "--newuse" in myopts and vardbapi.cpv_exists(mykey)): - old_use = vardbapi.aux_get(mykey, ["USE"])[0].split() - if mytype == "binary": - iuses = portage.db["/"]["bintree"].dbapi.aux_get(mykey, ["IUSE"])[0].split() - else: - iuses = portage.db["/"]["porttree"].dbapi.aux_get(mykey, ["IUSE"])[0].split() - for x in iuses: - if (old_use.count(x) and not myuse.count(x)) or (not old_use.count(x) and myuse.count(x)): - merging=1 - break - else: - #onlydeps mode; don't merge - merging=2 - if merging==1: - mybigkey.append("merge") - else: - mybigkey.append("nomerge") - - # whatever the case, we need to add the node to our digraph so - # that children can depend upon it. - self.digraph.addnode(string.join(mybigkey),myparent) - if ("deep" not in myparams) and (not merging): - return 1 - elif "recurse" not in myparams: - return 1 - - edepend={} - if mytype=="binary": - mypkgparts=portage.catpkgsplit(mykey) - tbz2name = string.split(mykey, "/")[1]+".tbz2" - if tbz2name in portage.db[portage.root]["bintree"].invalids: - sys.stderr.write("\nINVALID PACKAGE (is required to continue): "+str(mykey)+"\n") - sys.exit(1) - if portage.db[portage.root]["bintree"].isremote(mykey): - edepend = portage.db[portage.root]["bintree"].remotepkgs[tbz2name] - edepend["DEPEND"] ="" - edepend["RDEPEND"]=string.join(string.split(edepend["RDEPEND"])," ") - edepend["PDEPEND"]=string.join(string.split(edepend["PDEPEND"])," ") - edepend["SLOT"] =string.strip(edepend["SLOT"]) - #portage.db[portage.root]["bintree"].gettbz2(mykey) - else: # It's local. - mytbz2=xpak.tbz2(portage.db[portage.root]["bintree"].getname(mykey)) - edepend["DEPEND"] ="" - edepend["RDEPEND"]=string.join(mytbz2.getelements("RDEPEND")," ") - edepend["PDEPEND"]=string.join(mytbz2.getelements("PDEPEND")," ") - edepend["SLOT"] =mytbz2.getfile("SLOT",mypkgparts[2]) - elif mytype=="ebuild": - try: - mymeta = ["DEPEND","RDEPEND","PDEPEND"] - myfoo = portage.portdb.aux_get(mykey, mymeta) - for index in range(0,len(mymeta)): - edepend[mymeta[index]] = myfoo[index] - if "--buildpkgonly" in myopts: - edepend["RDEPEND"] = "" - edepend["PDEPEND"] = "" - except (KeyError,IOError): - print "emerge: create(): aux_get() error on",mykey+"; aborting..." - sys.exit(1) - mydep={} - mp=string.join(mybigkey) - - if myroot=="/": - mydep["/"]=edepend["DEPEND"]+" "+edepend["RDEPEND"] - if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse): - return 0 - else: - mydep["/"]=edepend["DEPEND"] - mydep[myroot]=edepend["RDEPEND"] - if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse): - return 0 - if not self.select_dep(myroot,mydep[myroot],myparent=mp,myuse=myuse): - return 0 - - if edepend.has_key("PDEPEND") and edepend["PDEPEND"]: - # Post Depend -- Add to the list without a parent, as it depends - # on a package being present AND must be built after that package. - if not self.select_dep(myroot,edepend["PDEPEND"],myuse=myuse): - return 0 - - return 1 - - def select_files(self,myfiles): - "given a list of .tbz2s, .ebuilds and deps, create the appropriate depgraph and return a favorite list" - myfavorites=[] - for x in myfiles: - ext = os.path.splitext(x)[1] - if ext==".tbz2": - if not os.path.exists(x): - if os.path.exists(self.pkgsettings["PKGDIR"]+"/All/"+x): - x=self.pkgsettings["PKGDIR"]+"/All/"+x - elif os.path.exists(self.pkgsettings["PKGDIR"]+"/"+x): - x=self.pkgsettings["PKGDIR"]+"/"+x - else: - print "\n\n!!! Binary package '"+str(x)+"' does not exist." - print "!!! Please ensure the tbz2 exists as specified.\n" - sys.exit(1) - mytbz2=xpak.tbz2(x) - mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.splitext(os.path.basename(x))[0] - if os.path.realpath(portage.db["/"]["bintree"].getname(mykey)) != os.path.realpath(x): - print red("\n*** You need to adjust PKGDIR to emerge this package.\n") - sys.exit(1) - if not self.create(["binary",portage.root,mykey],None,"--onlydeps" not in myopts): - return (0,myfavorites) - elif not "--oneshot" in myopts: - myfavorites.append(mykey) - elif ext==".ebuild": - x = os.path.realpath(x) - mykey=os.path.basename(os.path.normpath(x+"/../.."))+"/"+os.path.splitext(os.path.basename(x))[0] - ebuild_path = portage.db["/"]["porttree"].dbapi.findname(mykey) - if ebuild_path: - if os.path.realpath(ebuild_path) != x: - print red("\n*** You need to adjust PORTDIR or PORTDIR_OVERLAY to emerge this package.\n") - sys.exit(1) - if mykey not in portage.db["/"]["porttree"].dbapi.xmatch("match-visible", portage.dep_getkey(mykey)): - print red("\n*** You are emerging a masked package. It is MUCH better to use") - print red("*** /etc/portage/package.* to accomplish this. See portage(5) man") - print red("*** page for details.") - countdown(EMERGE_WARNING_DELAY, "Continuing...") - else: - raise portage_exception.PackageNotFound( - "%s is not in a valid portage tree hierarchy or does not exist" % x) - if not self.create(["ebuild",portage.root,mykey],None,"--onlydeps" not in myopts): - return (0,myfavorites) - elif not "--oneshot" in myopts: - myfavorites.append(mykey) - else: - if not is_valid_package_atom(x): - portage.writemsg("\n\n!!! '%s' is not a valid package atom.\n" % x, - noiselevel=-1) - portage.writemsg("!!! Please check ebuild(5) for full details.\n") - portage.writemsg("!!! (Did you specify a version but forget to prefix with '='?)\n") - return (0,[]) - try: - mykey=portage.dep_expand(x,mydb=portage.portdb) - except ValueError, errpkgs: - print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous. Please specify" - print "!!! one of the following fully-qualified ebuild names instead:\n" - for i in errpkgs[0]: - print " " + green(i) - print - sys.exit(1) - - # select needs to return 0 on dep_check failure - - sys.stdout.flush() - sys.stderr.flush() - - try: - self.mysd = self.select_dep(portage.root,mykey,arg=x) - except portage_exception.MissingSignature, e: - portage.writemsg("\n\n!!! A missing gpg signature is preventing portage from calculating the\n") - portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n") - portage.writemsg("!!! to aid in the detection of malicious intent.\n\n") - portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n") - portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1) - sys.exit(1) - except portage_exception.InvalidSignature, e: - portage.writemsg("\n\n!!! An invalid gpg signature is preventing portage from calculating the\n") - portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n") - portage.writemsg("!!! to aid in the detection of malicious intent.\n\n") - portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n") - portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1) - sys.exit(1) - except SystemExit, e: - raise # Needed else can't exit - except Exception, e: - if "--debug" in myopts: - raise - print "\n\n!!! Problem in",mykey,"dependencies." - print "!!!",str(e),e.__module__ - sys.exit(1) - - if not self.mysd: - return (0,myfavorites) - elif not "--oneshot" in myopts: - myfavorites.append(portage.dep_getkey(mykey)) - - missing=0 - if "--usepkgonly" in myopts: - for x in self.digraph.dict.keys(): - xs=string.split(x," ") - if (xs[0] != "binary") and (xs[3]=="merge"): - if missing == 0: - print - missing += 1 - print "Missing binary for:",xs[2] - - # We're true here unless we are missing binaries. - return (not missing,myfavorites) - - def is_newer_ver_installed(self,myroot,pkg,pkgver): - "if there is a version of pkg installed newer than pkgver, return it" - vardbapi=portage.db[myroot]["vartree"].dbapi - - matches=portage.db[myroot]["vartree"].dbapi.match(pkg) - if matches: - myslot=portage.db["/"]["porttree"].getslot(pkgver) - for match in matches: - if portage.pkgcmp(portage.catpkgsplit(pkgver)[1:], portage.catpkgsplit(match)[1:]) < 0: - curslot=portage.db[myroot]["vartree"].getslot(match) - if curslot == myslot: - return match - - def select_dep(self,myroot,depstring,myparent=None,arg=None,myuse=None,raise_on_missing=False): - "given a dependency string, create the appropriate depgraph and return 1 on success and 0 on failure" - if "--debug" in myopts: - print - print "Parent: ",myparent - print "Depstring:",depstring - if not arg: - #processing dependencies - mycheck=portage.dep_check(depstring,self.mydbapi[myroot],self.pkgsettings,myuse=myuse,use_binaries=("--usepkgonly" in myopts),myroot=myroot) - - if not mycheck[0]: - mymerge=[] - else: - mymerge=mycheck[1] - - else: - #we're processing a command-line argument; unconditionally merge it even if it's already merged - mymerge=[depstring] - - # dep_check has been run so we can now add our parent to our - # build state to update virtuals and other settings. This - # happens after the package is added to the tree so that a - # package can depend on a virtual which it satisfies. - if myparent: - myp = myparent.split() - if myp[3]=="merge": - self.mydbapi[myroot].cpv_inject(myp[2]) - if myp[0]=="binary": - self.pkgsettings.setinst(myp[2],portage.db["/"]["bintree"].dbapi) - else: - self.pkgsettings.setinst(myp[2],portage.db[myroot]["porttree"].dbapi) - - if not mymerge: - return 1 - - if "--debug" in myopts: - print "Candidates:",mymerge - for x in mymerge: - myk=None - binpkguseflags=None - if x[0]=="!": - # if this package is myself, don't append it to block list. - if "--debug" in myopts: - print "Myparent",myparent - if (myparent): - if myparent.split()[2] in portage.portdb.xmatch("match-all", x[1:]): - # myself, so exit. - continue - # adding block - myk=["blocks",myroot,x[1:]] - else: - #We are not processing a blocker but a normal dependency - myeb=None - myeb_matches = portage.portdb.xmatch("match-visible",x) - if ("--usepkgonly" not in myopts): - myeb=portage.best(myeb_matches) - - myeb_pkg=None - if ("--usepkg" in myopts): - # The next line assumes the binarytree has been populated. - # XXX: Need to work out how we use the binary tree with roots. - myeb_pkg_matches=portage.db["/"]["bintree"].dbapi.match(x) - if ("--usepkgonly" not in myopts): - # Remove any binary package entries that are masked in the portage tree (#55871) - for idx in range(len(myeb_pkg_matches)-1,-1,-1): - if myeb_pkg_matches[idx] not in myeb_matches: - del myeb_pkg_matches[idx] - myeb_pkg = portage.best(myeb_pkg_matches) - - if not myeb_pkg: - myeb_pkg = None - elif ("--newuse" in myopts): - iuses=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["IUSE"])[0]) - old_use=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["USE"])[0]) - self.pkgsettings.setcpv(myeb_pkg) - now_use=string.split(self.pkgsettings["USE"]) - for x in iuses: - if (old_use.count(x) and not now_use.count(x)) or (not old_use.count(x) and now_use.count(x)): - myeb_pkg = None - break - - if (not myeb) and (not myeb_pkg): - if raise_on_missing: - raise ValueError - if not arg: - xinfo='"'+x+'"' - else: - xinfo='"'+arg+'"' - if myparent: - xfrom = '(dependency required by '+green('"'+myparent.split()[2]+'"')+red(' ['+myparent.split()[0]+"]")+')' - alleb=portage.portdb.xmatch("match-all",x) - if alleb: - if "--usepkgonly" not in myopts: - print "\n!!! "+red("All ebuilds that could satisfy ")+green(xinfo)+red(" have been masked.") - print "!!! One of the following masked packages is required to complete your request:" - oldcomment = "" - for p in alleb: - mreasons = portage.getmaskingstatus(p) - print "- "+p+" (masked by: "+string.join(mreasons, ", ")+")" - comment = portage.getmaskingreason(p) - if comment and comment != oldcomment: - print comment - oldcomment = comment - print - print "For more information, see MASKED PACKAGES section in the emerge man page or " - print "refer to the Gentoo Handbook." - else: - print "\n!!! "+red("There are no packages available to satisfy: ")+green(xinfo) - print "!!! Either add a suitable binary package or compile from an ebuild." - else: - print "\nemerge: there are no ebuilds to satisfy "+green(xinfo)+"." - if myparent: - print xfrom - print - return 0 - - if "--debug" in myopts: - print "ebuild:",myeb - print "binpkg:",myeb_pkg - - if myeb and myeb_pkg: - myeb_s = portage.catpkgsplit(myeb) - myeb_s = [myeb_s[0]+"/"+myeb_s[1], myeb_s[2], myeb_s[3]] - myeb_pkg_s = portage.catpkgsplit(myeb_pkg) - myeb_pkg_s = [myeb_pkg_s[0]+"/"+myeb_pkg_s[1], myeb_pkg_s[2], myeb_pkg_s[3]] - - if portage.pkgcmp(myeb_s, myeb_pkg_s) == 0: # pkg is same version as ebuild - myeb = None - else: - myeb_pkg = None - - if myeb: - myk=["ebuild",myroot,myeb] - elif myeb_pkg: - binpkguseflags=portage.db[portage.root]["bintree"].get_use(myeb_pkg) - myk=["binary",myroot,myeb_pkg] - else: - sys.stderr.write("!!! Confused... Don't know what's being used for dependency info. :(\n") - sys.exit(1) - - #if "--usepkg" in myopts: - # #If we want to use packages, see if we have a pre-built one... - # mypk=portage.db["/"]["bintree"].dbapi.match(x) - # if myeb in mypk: - # #Use it only if it's exactly the version we want. - # myk=["binary",myroot,myeb] - # else: - # myk=["ebuild",myroot,myeb] - #else: - # myk=["ebuild",myroot,myeb] - if myparent: - #we are a dependency, so we want to be unconditionally added - if not self.create(myk,myparent,myuse=binpkguseflags): - return 0 - else: - #if mysource is not set, then we are a command-line dependency and should not be added - #if --onlydeps is specified. - if not self.create(myk,myparent,"--onlydeps" not in myopts,myuse=binpkguseflags): - return 0 - - if "--debug" in myopts: - print "Exiting...",myparent - return 1 - - - def altlist(self): - mygraph=self.digraph.copy() - dolist=["/"] - retlist=[] - for x in portage.db.keys(): - portage.db[x]["merge"]=[] - if x not in dolist: - dolist.append(x) - while (not mygraph.empty()): - mycurkey=mygraph.firstzero() - if not mycurkey: - print "!!! Error: circular dependencies:" - print - for x in mygraph.dict.keys(): - for y in mygraph.dict[x][1]: - print y,"depends on",x - print - sys.exit(1) - splitski=string.split(mycurkey) - #I'm not sure of the significance of the following lines (vestigal?) so I'm commenting 'em out. - #These lines remove already-merged things from our alt-list - #if "--update" in myopts: - # if not portage.db["/"]["vartree"].exists_specific(splitski[2]): - # portage.db["/"]["merge"].append(splitski) - #else: - portage.db[splitski[1]]["merge"].append(splitski) - mygraph.delnode(mycurkey) - for x in dolist: - for y in portage.db[x]["merge"]: - retlist.append(y) - return retlist - - def xcreate(self,mode="system"): - global syslist - world_problems = False - if mode=="system": - mylist=syslist - else: - #world mode - worldlist=getlist("world") - sysdict=genericdict(syslist) - worlddict=genericdict(worldlist) - - for x in worlddict.keys(): - if not portage.isvalidatom(x): - world_problems = True - elif not portage.db["/"]["vartree"].dbapi.match(x): - world_problems = True - else: - sysdict[x]=worlddict[x] - - mylist = sysdict.keys() - - newlist = [] - for atom in mylist: - if portage.dep_getkey(atom).split("/")[-1] == "portage": - newlist.insert(0, atom) - else: - newlist.append(atom) - mylist = newlist - - missing_atoms = [] - for mydep in mylist: - try: - if not self.select_dep(portage.root, mydep, raise_on_missing=True): - print "\n\n!!! Problem resolving dependencies for", mydep - return 0 - except ValueError: - if "--debug" in myopts: - raise - missing_atoms.append(mydep) - - if world_problems: - print "\n!!! Problems have been detected with your world file" - print "!!! Please run "+green("emaint --check world")+"\n" - - if missing_atoms and "--verbose" in myopts: - print "\n!!! Packages for the following atoms are either all" - print "!!! masked or don't exist:" - print " ".join(missing_atoms) + "\n" - - return 1 - - def match(self,mydep,myroot=portage.root,mykey=None): - # support mutual exclusive deps - mydep2=mydep - if mydep2[0]=="!": - mydep2=mydep[1:] - - if mydep[0]=="!": - #add our blocker; it will be ignored later if necessary (if we are remerging the same pkg, for example) - myk="blocks "+myroot+" "+mydep2 - else: - myeb=portage.db[portage.root]["porttree"].dep_bestmatch(mydep2) - if not myeb: - if not mykey: - print "\n!!! Error: couldn't find match for",mydep - else: - print "\n!!! Error: couldn't find match for",mydep,"in",mykey - print - sys.exit(1) - - if "--usepkg" in myopts: - mypk=portage.db[portage.root]["bintree"].dep_bestmatch(mydep) - if myeb==mypk: - myk="binary "+portage.root+" "+mypk - else: - myk="ebuild "+myroot+" "+myeb - else: - myk="ebuild "+myroot+" "+myeb - - return myk - - def display(self,mylist,verbosity=("--quiet" in myopts and 1 or "--verbose" in myopts and 3 or 2 )): - changelogs=[] - p=[] - totalsize=0 - - if verbosity == 1: - def create_use_string(*args): - return "" - else: - def create_use_string(name, cur_iuse, cur_use, old_iuse, old_use, is_new, - all_flags=(verbosity == 3), alphabetical=("--alphabetical" in myopts)): - enabled = [] - if alphabetical: - disabled = enabled - else: - disabled = [] - for flag in cur_iuse: - if flag in cur_use: - if is_new or flag in old_use and all_flags: - enabled.append(red(flag)) - elif flag not in old_iuse: - enabled.append(yellow(flag)+"%") - elif flag not in old_use: - enabled.append(green(flag)+"*") - else: - if is_new or flag in old_iuse and flag not in old_use and all_flags: - disabled.append(blue("-"+flag)) - elif flag not in old_iuse: - disabled.append(yellow("-"+flag)+"%") - elif flag in old_use: - disabled.append(green("-"+flag)+"*") - - enabled = " ".join(enabled) - if alphabetical: - disabled = "" - else: - disabled = " ".join(disabled) - if enabled and disabled: - ret = enabled + " " + disabled - elif enabled: - ret = enabled - else: - ret = disabled - if ret: - ret = '%s="%s" ' % (name, ret) - return ret - - if verbosity == 3: - overlays = self.pkgsettings["PORTDIR_OVERLAY"].split() - overlays_real = [os.path.realpath(t) \ - for t in self.pkgsettings["PORTDIR_OVERLAY"].split()] - - if "--tree" in myopts: - mylist.reverse() - mygraph=self.digraph.copy() - - i = 0 - while i < len(mylist): - if mylist[i][-1]=="nomerge": - if not ("--tree" in myopts): - # we don't care about this elements - mylist.pop(i) - continue - if (i == (len(mylist) - 1)) \ - or (mygraph.depth(string.join(mylist[i])) \ - >= mygraph.depth(string.join(mylist[i+1]))): - # end of a useless branch (may be the last one) - # -> delete the element and test the previous one - mylist.pop(i) - if i > 0: - i -= 1 - continue - # the branch continues, or we've found a good element. - # -> let's see what's next, if anything - i += 1 - - display_overlays=False - # files to fetch list - avoids counting a same file twice - # in size display (verbose mode) - myfetchlist=[] - for x in mylist: - pkg_type = x[0] - pkg_key = x[2] - if pkg_key not in self.applied_useflags: - if "binary" == pkg_type: - self.applied_useflags[pkg_key] = portage.db["/"]["bintree"].dbapi.aux_get(pkg_key, ["USE"])[0].split() - elif "ebuild" == pkg_type: - self.pkgsettings.setcpv(pkg_key) - self.applied_useflags[pkg_key] = self.pkgsettings["USE"].split() - - fetch=" " - - if x[0]=="blocks": - addl=""+red("B")+" "+fetch+" " - resolved=portage.db[x[1]]["vartree"].resolve_key(x[2]) - print "["+x[0]+" "+addl+"]",red(resolved), - if resolved!=x[2]: - if x[3]: - print red("(\""+x[2]+"\" is blocking "+x[3]+")") - else: - print red("(\""+x[2]+"\")") - else: - if x[3]: - print red("(is blocking "+x[3]+")") - else: - print - else: - if (x[0]!="binary") and ("fetch" in string.split(portage.portdb.aux_get(x[2],["RESTRICT"])[0])): - fetch = red("F") - if portage.portdb.fetch_check(x[2], self.applied_useflags[x[2]]): - fetch = green("f") - - #we need to use "--emptrytree" testing here rather than "empty" param testing because "empty" - #param is used for -u, where you still *do* want to see when something is being upgraded. - myoldbest="" - if (not "--emptytree" in myopts) and portage.db[x[1]]["vartree"].exists_specific(x[2]): - addl=" "+yellow("R")+fetch+" " - elif (not "--emptytree" in myopts) and portage.db[x[1]]["vartree"].exists_specific_cat(x[2]): - if x[0] == "binary": - mynewslot=portage.db["/"]["bintree"].getslot(x[2]) - elif x[0] == "ebuild": - mynewslot=portage.db["/"]["porttree"].getslot(x[2]) - myoldlist=portage.db[x[1]]["vartree"].dbapi.match(portage.pkgsplit(x[2])[0]) - myinslotlist=filter((lambda p: portage.db[portage.root]["vartree"].getslot(p)==mynewslot),myoldlist) - if myinslotlist: - myoldbest=portage.best(myinslotlist) - addl=" "+fetch - if portage.pkgcmp(portage.pkgsplit(x[2]), portage.pkgsplit(myoldbest)) < 0: - # Downgrade in slot - addl+=turquoise("U")+blue("D") - else: - # Update in slot - addl+=turquoise("U")+" " - else: - # New slot, mark it new. - addl=" "+green("NS")+fetch+" " - - if "--changelog" in myopts: - changelogs.extend(self.calc_changelog( - portage.portdb.findname(x[2]), - portage.db[x[1]]["vartree"].dep_bestmatch('/'.join(portage.catpkgsplit(x[2])[:2])), - x[2] - )) - else: - addl=" "+green("N")+" "+fetch+" " - - verboseadd="" - - if x[2] in self.applied_useflags: - # USE flag display - if x[0] == "binary": - cur_iuse = string.split(portage.db["/"]["bintree"].dbapi.aux_get(x[2],["IUSE"])[0]) - elif x[0] == "ebuild": - cur_iuse = string.split(portage.portdb.aux_get(x[2],["IUSE"])[0]) - else: - cur_iuse = [] - - cur_iuse = portage.unique_array(cur_iuse) - cur_iuse = [flag for flag in cur_iuse if flag not in portage.settings.usemask] - cur_iuse.sort() - cur_use = self.applied_useflags[x[2]] - cur_use = [flag for flag in cur_use if flag in cur_iuse] - - if myoldbest: - pkg = myoldbest - else: - pkg = x[2] - if portage.db[x[1]]["vartree"].dbapi.cpv_exists(pkg): - (old_iuse, old_use) = portage.db[x[1]]["vartree"].dbapi.aux_get(pkg, ["IUSE", "USE"]) - old_iuse = portage.unique_array(old_iuse.split()) - old_iuse.sort() - old_use = old_use.split() - is_new = False - else: - old_iuse = [] - old_use = [] - is_new = True - old_iuse = [flag for flag in old_iuse if flag not in portage.settings.usemask] - old_use = [flag for flag in old_use if flag in old_iuse] - - use_expand = portage.settings["USE_EXPAND"].lower().split() - use_expand.sort() - use_expand.reverse() - use_expand_hidden = portage.settings["USE_EXPAND_HIDDEN"].lower().split() - - def map_to_use_expand(myvals): - ret = {} - for exp in use_expand: - ret[exp] = [] - for val in myvals[:]: - if val.startswith(exp.lower()+"_"): - ret[exp].append(val[len(exp)+1:]) - myvals.remove(val) - ret["USE"] = myvals - for exp in use_expand_hidden: - if exp in ret: - del ret[exp] - return ret - - cur_iuse_map = map_to_use_expand(cur_iuse) - cur_use_map = map_to_use_expand(cur_use) - old_iuse_map = map_to_use_expand(old_iuse) - old_use_map = map_to_use_expand(old_use) - - use_expand.sort() - use_expand.insert(0, "USE") - - for key in use_expand: - if key in use_expand_hidden: - continue - verboseadd += create_use_string(key.upper(), cur_iuse_map[key], cur_use_map[key], - old_iuse_map[key], old_use_map[key], is_new) - - if verbosity == 3: - # size verbose - mysize=0 - if x[0] == "ebuild" and x[-1]!="nomerge": - myfilesdict=portage.portdb.getfetchsizes(x[2], useflags=self.applied_useflags[x[2]], debug=edebug) - if myfilesdict is None: - myfilesdict="[empty/missing/bad digest]" - else: - for myfetchfile in myfilesdict.keys(): - if myfetchfile not in myfetchlist: - mysize+=myfilesdict[myfetchfile] - myfetchlist.append(myfetchfile) - totalsize+=mysize - verboseadd+=format_size(mysize)+" " - - # overlay verbose - # XXX: Invalid binaries have caused tracebacks here. 'if file_name' - # x = ['binary', '/', 'sys-apps/pcmcia-cs-3.2.7.2.6', 'merge'] - file_name=portage.portdb.findname(x[2]) - if file_name: # It might not exist in the tree - dir_name=os.path.abspath(os.path.dirname(file_name)+"/../..") - if (overlays_real.count(dir_name)>0): - verboseadd+=teal("["+str(overlays_real.index( - os.path.normpath(dir_name))+1)+"]")+" " - display_overlays=True - else: - verboseadd += "[No ebuild?]" - - xs=portage.pkgsplit(x[2]) - if xs[2]=="r0": - xs[2]="" - else: - xs[2]="-"+xs[2] - - if self.pkgsettings.has_key("COLUMNWIDTH"): - mywidth=int(self.pkgsettings.settings["COLUMNWIDTH"]) - else: - mywidth=130 - oldlp=mywidth-30 - newlp=oldlp-30 - - indent="" - if ("--tree" in myopts): - indent=" "*mygraph.depth(string.join(x)) - - if myoldbest: - myoldbest=portage.pkgsplit(myoldbest)[1]+"-"+portage.pkgsplit(myoldbest)[2] - if myoldbest[-3:]=="-r0": - myoldbest=myoldbest[:-3] - myoldbest=blue("["+myoldbest+"]") - - if x[1]!="/": - if myoldbest: - myoldbest +=" " - if "--columns" in myopts: - if "--quiet" in myopts: - myprint=addl+" "+indent+darkgreen(xs[0]) - myprint=myprint+darkblue(" "+xs[1]+xs[2])+" " - myprint=myprint+myoldbest - myprint=myprint+darkgreen("to "+x[1]) - else: - myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0]) - if (newlp-nc_len(myprint)) > 0: - myprint=myprint+(" "*(newlp-nc_len(myprint))) - myprint=myprint+"["+darkblue(xs[1]+xs[2])+"] " - if (oldlp-nc_len(myprint)) > 0: - myprint=myprint+" "*(oldlp-nc_len(myprint)) - myprint=myprint+myoldbest - myprint=myprint+darkgreen("to "+x[1])+" "+verboseadd - else: - myprint="["+x[0]+" "+addl+"] "+darkgreen(x[2])+" "+myoldbest+darkgreen("to "+x[1])+" "+verboseadd - else: - if "--columns" in myopts: - if "--quiet" in myopts: - myprint=addl+" "+indent+darkgreen(xs[0]) - myprint=myprint+" "+green(xs[1]+xs[2])+" " - myprint=myprint+myoldbest - else: - myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0]) - if (newlp-nc_len(myprint)) > 0: - myprint=myprint+(" "*(newlp-nc_len(myprint))) - myprint=myprint+green(" ["+xs[1]+xs[2]+"] ") - if (oldlp-nc_len(myprint)) > 0: - myprint=myprint+(" "*(oldlp-nc_len(myprint))) - myprint=myprint+myoldbest+" "+verboseadd - else: - if x[3]=="nomerge": - myprint=darkblue("[nomerge ] "+indent+x[2]+" "+myoldbest+" ")+verboseadd - else: - myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(x[2])+" "+myoldbest+" "+verboseadd - p.append(myprint) - - mysplit = portage.pkgsplit(x[2]) - if "--tree" not in myopts and mysplit and len(mysplit) == 3 and \ - mysplit[0] == "sys-apps/portage" and x[1] == "/": - - if mysplit[2] == "r0": - myversion = mysplit[1] - else: - myversion = "%s-%s" % (mysplit[1], mysplit[2]) - - if myversion != portage.VERSION : - if "--emptytree" in myopts: - p.append(red("***")+" Please update portage to the above version before proceeding.") - p.append(" Failure to do so may result in failed or improper merges.") - p.append(" A simple '"+green("emerge portage")+"' is sufficient.") - p.append("") - elif mylist.index(x) < len(mylist) - 1 and \ - "livecvsportage" not in portage.settings.features: - p.append(red("*** Portage will stop merging at this point and reload itself,")) - p.append(red(" then resume the merge.")) - print - del mysplit - - for x in p: - print x - - if verbosity == 3: - print - print "Total size of downloads: "+format_size(totalsize) - if overlays and display_overlays: - print "Portage overlays:" - y=0 - for x in overlays: - y=y+1 - print " "+teal("["+str(y)+"]"),x - - if "--changelog" in myopts: - print - for revision,text in changelogs: - print bold('*'+revision) - sys.stdout.write(text) - - def calc_changelog(self,ebuildpath,current,next): - current = '-'.join(portage.catpkgsplit(current)[1:]) - if current.endswith('-r0'): current = current[:-3] - next = '-'.join(portage.catpkgsplit(next)[1:]) - if next.endswith('-r0'): next = next[:-3] - changelogpath = os.path.join(os.path.split(ebuildpath)[0],'ChangeLog') - try: - changelog = open(changelogpath).read() - except SystemExit, e: - raise # Needed else can't exit - except: - return [] - divisions = self.find_changelog_tags(changelog) - #print 'XX from',current,'to',next - #for div,text in divisions: print 'XX',div - # skip entries for all revisions above the one we are about to emerge - for i in range(len(divisions)): - if divisions[i][0]==next: - divisions = divisions[i:] - break - # find out how many entries we are going to display - for i in range(len(divisions)): - if divisions[i][0]==current: - divisions = divisions[:i] - break - else: - # couldnt find the current revision in the list. display nothing - return [] - return divisions - - def find_changelog_tags(self,changelog): - divs = [] - release = None - while 1: - match = re.search(r'^\*\ ?([-a-zA-Z0-9_.+]*)(?:\ .*)?\n',changelog,re.M) - if match is None: - if release is not None: - divs.append((release,changelog)) - return divs - if release is not None: - divs.append((release,changelog[:match.start()])) - changelog = changelog[match.end():] - release = match.group(1) - if release.endswith('.ebuild'): - release = release[:-7] - if release.endswith('-r0'): - release = release[:-3] - - def outdated(self): - return self.outdatedpackages - - def merge(self,mylist): - returnme=0 - mymergelist=[] - - #check for blocking dependencies - if ("--fetchonly" not in myopts) and ("--buildpkgonly" not in myopts): - for x in mylist: - if x[0]=="blocks": - print "\n!!! Error: the "+x[2]+" package conflicts with another package;" - print "!!! the two packages cannot be installed on the same system together." - print "!!! Please use 'emerge --pretend' to determine blockers." - print - if ("--pretend" not in myopts): - try: - del portage.mtimedb["resume"] - except KeyError: - pass - sys.exit(1) - - #buildsyspkg: I need mysysdict also on resume (moved from the else block) - mysysdict=genericdict(syslist) - if ("--resume" in myopts): - # We're resuming. - print green("*** Resuming merge...") - emergelog(" *** Resuming merge...") - mymergelist=portage.mtimedb["resume"]["mergelist"][:] - if ("--skipfirst" in myopts) and mymergelist: - del portage.mtimedb["resume"]["mergelist"][0] - del mymergelist[0] - validate_merge_list(mymergelist) - else: - myfavs = portage.grabfile(os.path.join(portage.root, portage.WORLD_FILE)) - myfavdict=genericdict(myfavs) - for x in range(len(mylist)): - if mylist[x][3]!="nomerge": - # Add to the mergelist - mymergelist.append(mylist[x]) - else: - myfavkey=portage.cpv_getkey(mylist[x][2]) - if "--onlydeps" in myopts: - continue - # Add to the world file. Since we won't be able to later. - if (not "--fetchonly" in myopts) and (myfavkey in favorites): - #don't record if already in system profile or already recorded - if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)): - #we don't have a favorites entry for this package yet; add one - myfavdict[myfavkey]=myfavkey - print ">>> Recording",myfavkey,"in \"world\" favorites file..." - if not "--fetchonly" in myopts: - portage.write_atomic( - os.path.join(portage.root, portage.WORLD_FILE), - "\n".join(myfavdict.values())) - - portage.mtimedb["resume"]["mergelist"]=mymergelist[:] - - # We need to yank the harmful-to-new-builds settings from features. - myorigfeat=self.pkgsettings["FEATURES"] - myfeat=myorigfeat.split() - while ("keeptemp" in myfeat): - del myfeat[myfeat.index("keeptemp")] - while ("keepwork" in myfeat): - del myfeat[myfeat.index("keepwork")] - - self.pkgsettings["FEATURES"]=string.join(myfeat) - - if "parallel-fetch" in myfeat and not ("--ask" in myopts or "--pretend" in myopts or "--fetchonly" in myopts): - if "distlocks" not in myfeat: - print red("!!!") - print red("!!!")+" parallel-fetching requires the distlocks feature enabled" - print red("!!!")+" you have it disabled, thus parallel-fetching is being disabled" - print red("!!!") - elif len(mymergelist) > 1: - print ">>> starting parallel fetching" - pid = os.fork() - if not pid: - sys.stdin.close() - sys.stdout.close() - sys.stderr.close() - time.sleep(3) # allow the parent to have first fetch - sys.stdout = open("/dev/null","w") - sys.stderr = open("/dev/null","w") - os.dup2(sys.stdout.fileno(), 1) - os.dup2(sys.stdout.fileno(), 2) - # wipe the mtimedb so that portage doesn't attempt to flush it. - # do not convert this code away from a fork without correcting this. - portage.mtimedb = None - for x in ("autoaddcvs", "cvs"): - try: myfeat.remove(x) - except ValueError: pass - self.pkgsettings["FEATURES"] = " ".join(myfeat) - ret = 0 - for x in mymergelist: - if x[0] != "ebuild": - continue - try: - ret = portage.doebuild(portage.portdb.findname(x[2]), "fetch", x[1], self.pkgsettings, - cleanup=0, fetchonly=True, tree="porttree") - except SystemExit: - raise - except Exception: - ret = 1 - sys.exit(0) - portage.portage_exec.spawned_pids.append(pid) - - mergecount=0 - for x in mymergelist: - mergecount+=1 - myroot=x[1] - pkgindex=2 - if x[0]=="blocks": - pkgindex=3 - y=portage.portdb.findname(x[pkgindex]) - if not "--pretend" in myopts: - print ">>> Emerging ("+str(mergecount)+" of "+str(len(mymergelist))+")",x[pkgindex],"to",x[1] - emergelog(" >>> emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" to "+x[1]) - - self.pkgsettings["EMERGE_FROM"] = x[0][:] - self.pkgsettings.backup_changes("EMERGE_FROM") - self.pkgsettings.reset() - - #buildsyspkg: Check if we need to _force_ binary package creation - issyspkg = ("buildsyspkg" in myfeat) \ - and x[0] != "blocks" \ - and mysysdict.has_key(portage.cpv_getkey(x[2])) \ - and not ("--buildpkg" in myopts) - if x[0] in ["ebuild","blocks"]: - if (x[0]=="blocks") and ("--fetchonly" not in myopts): - raise Exception, "Merging a blocker" - elif ("--fetchonly" in myopts) or ("--fetch-all-uri" in myopts): - if ("--fetch-all-uri" in myopts): - retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in myopts),fetchonly=1,fetchall=1,tree="porttree") - else: - retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in myopts),fetchonly=1,tree="porttree") - if (retval is None) or retval: - print - print "!!! Fetch for",y,"failed, continuing..." - print - returnme=1 - continue - elif "--buildpkg" in myopts or issyspkg: - #buildsyspkg: Sounds useful to display something, but I don't know if we should also log it - if issyspkg: - print ">>> This is a system package, let's pack a rescue tarball." - #emergelog(">>> This is a system package, let's pack a rescue tarball.") - #create pkg, then merge pkg - short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean" - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) - retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree") - if (retval is None): - portage_util.writemsg("Unable to run required binary.\n", - noiselevel=-1) - sys.exit(127) - if retval: - sys.exit(retval) - short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile" - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Packaging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) - retval=portage.doebuild(y,"package",myroot,self.pkgsettings,edebug,tree="porttree") - if (retval is None): - portage_util.writemsg("Unable to run required binary.\n", - noiselevel=-1) - sys.exit(127) - if retval: - sys.exit(retval) - #dynamically update our database - if "--buildpkgonly" not in myopts: - portage.db[portage.root]["bintree"].inject(x[2]) - mytbz2=portage.db[portage.root]["bintree"].getname(x[2]) - short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge" - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) - - self.pkgsettings["EMERGE_FROM"] = "binary" - self.pkgsettings.backup_changes("EMERGE_FROM") - - retval=portage.pkgmerge(mytbz2,myroot,self.pkgsettings) - if retval is None: - sys.exit(1) - elif "noclean" not in self.pkgsettings.features: - portage.doebuild(y, "clean", myroot, self.pkgsettings, - edebug, tree="porttree") - else: - short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean" - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) - retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree") - if (retval is None): - portage_util.writemsg("Unable to run required binary.\n", - noiselevel=-1) - sys.exit(127) - if retval: - sys.exit(retval) - short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile" - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) - retval=portage.doebuild(y,"merge",myroot,self.pkgsettings,edebug,tree="porttree") - if (retval is None): - portage_util.writemsg("Unable to run required binary.\n", - noiselevel=-1) - sys.exit(127) - if retval: - sys.exit(retval) - #dynamically update our database - elif x[0]=="binary": - #merge the tbz2 - mytbz2=portage.db[portage.root]["bintree"].getname(x[2]) - if portage.db[portage.root]["bintree"].isremote(x[2]): - short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Fetch" - emergelog(" --- ("+str(mergecount)+" of "+str(len(mymergelist))+") Fetching Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg) - if not portage.db[portage.root]["bintree"].gettbz2(x[2]): - sys.exit(1) - - if ("--fetchonly" in myopts) or ("--fetch-all-uri" in myopts): - continue - - short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge Binary" - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg) - retval=portage.pkgmerge(mytbz2,x[1],self.pkgsettings) - if retval is None: - sys.exit(1) - #need to check for errors - if "--buildpkgonly" not in myopts: - portage.db[x[1]]["vartree"].inject(x[2]) - myfavkey=portage.cpv_getkey(x[2]) - if "--fetchonly" not in myopts and "--fetch-all-uri" not in myopts and myfavkey in favorites: - myfavs = portage.grabfile(os.path.join(myroot, portage.WORLD_FILE)) - myfavdict=genericdict(myfavs) - mysysdict=genericdict(syslist) - #don't record if already in system profile or already recorded - if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)): - #we don't have a favorites entry for this package yet; add one - myfavdict[myfavkey]=myfavkey - print ">>> Recording",myfavkey,"in \"world\" favorites file..." - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Updating world file ("+x[pkgindex]+")") - portage.write_atomic( - os.path.join(myroot, portage.WORLD_FILE), - "\n".join(myfavdict.values())) - - if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts): - # Clean the old package that we have merged over top of it. - if self.pkgsettings["AUTOCLEAN"]=="yes": - xsplit=portage.pkgsplit(x[2]) - emergelog(" >>> AUTOCLEAN: "+xsplit[0]) - if x[1] == portage.settings["ROOT"]: - # Compare against portage.settings["ROOT"] because - # the value of self.pkgsettings["ROOT"] does not - # match the original value! - retval = unmerge("clean", [xsplit[0]]) - else: - retval = unmerge_overlapping(x[2], x[1], - self.pkgsettings, portage.db[x[1]]["vartree"]) - if not retval: - emergelog(" --- AUTOCLEAN: Nothing unmerged.") - else: - portage.writemsg_stdout(colorize("WARN", "WARNING:") - + " AUTOCLEAN is disabled. This can cause serious" - + " problems due to overlapping packages.\n") - - # Figure out if we need a restart. - mysplit=portage.pkgsplit(x[2]) - if mysplit[0] == "sys-apps/portage" and x[1] == "/": - myver=mysplit[1]+"-"+mysplit[2] - if myver[-3:]=='-r0': - myver=myver[:-3] - if (myver != portage.VERSION) and \ - ("livecvsportage" not in portage.settings.features): - if len(mymergelist) > mergecount: - emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1]) - emergelog(" *** RESTARTING emerge via exec() after change of portage version.") - del portage.mtimedb["resume"]["mergelist"][0] - portage.run_exitfuncs() - mynewargv=[sys.argv[0],"--resume"] - badlongopts = ("--ask","--tree","--changelog","--skipfirst","--resume") - for arg in myopts: - if arg in badlongopts: - continue - mynewargv.append(arg) - # priority only needs to be adjusted on the first run - os.environ["PORTAGE_NICENESS"] = "0" - os.execv(mynewargv[0], mynewargv) - - if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts): - if "noclean" not in portage.settings.features: - short_msg = "emerge: (%s of %s) %s Clean Post" % \ - (mergecount, len(mymergelist), x[pkgindex]) - emergelog(" === (%s of %s) Post-Build Cleaning (%s::%s)" % \ - (mergecount, len(mymergelist), x[pkgindex], y), short_msg=short_msg) - emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1]) - - # Unsafe for parallel merges - del portage.mtimedb["resume"]["mergelist"][0] - # Commit after each merge so that --resume may still work in - # in the event that portage is not allowed to exit normally - # due to power failure, SIGKILL, etc... - portage.commit_mtimedb() - - emergelog(" *** Finished. Cleaning up...") - - # We're out of the loop... We're done. Delete the resume data. - if portage.mtimedb.has_key("resume"): - del portage.mtimedb["resume"] - - if ("--pretend" not in myopts): - if ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts): - if (mergecount>0): - if retval: - portage.env_update() - - #by doing an exit this way, --fetchonly can continue to try to - #fetch everything even if a particular download fails. - if "--fetchonly" in myopts or "--fetch-all-uri" in myopts: - if returnme: - print "\n\n!!! Some fetch errors were encountered. Please see above for details.\n\n" - sys.exit(returnme) - else: - sys.exit(0) - def unmerge_overlapping(pkg_key, myroot, mysettings, vartree): """Unmerge any packages that overlap with the given package (overlapping packages fill the same SLOT). Unlike emerge's unmerge() function, this @@ -2589,6 +1318,23 @@ print red("!!! the merge operation manually.") sys.exit(1) +import depgraph +dg = depgraph +depgraph = dg.depgraph +dg.is_valid_package_atom = is_valid_package_atom +dg.update_spinner = update_spinner +dg.edebug = edebug +dg.format_size = format_size +dg.genericdict = genericdict +dg.syslist = getlist("system") +dg.emergelog = emergelog +dg.unmerge = unmerge +dg.EMERGE_WARNING_DELAY = EMERGE_WARNING_DELAY +dg.countdown = countdown +dg.validate_merge_list = validate_merge_list +dg.unmerge_overlapping = unmerge_overlapping + + # general options that should be taken into account before any action if "--debug" in myopts: edebug=1 @@ -3268,11 +2014,11 @@ if not "--pretend" in myopts: #just check pretend, since --ask implies pretend emergelog(" >>> depclean") - mydepgraph=depgraph(myaction,myopts) + mydepgraph=depgraph(myaction,myopts,myparams) if not ("--quiet" in myopts): print "\nCalculating dependencies ", - if not mydepgraph.xcreate("world"): + if not mydepgraph.xcreate(syslist,"world"): print "\n!!! Failed to create deptree." sys.exit(1) if not ("--quiet" in myopts): @@ -3383,7 +2129,7 @@ if myopt not in myresumeopts: myresumeopts.append(myopt) myopts=myresumeopts - mydepgraph=depgraph("resume",myopts) + mydepgraph=depgraph("resume",myopts,myparams) if "--resume" not in myopts: myopts+=["--resume"] else: @@ -3392,12 +2138,12 @@ print darkgreen("emerge: It seems we have nothing to resume...") sys.exit(0) - mydepgraph=depgraph(myaction,myopts) + mydepgraph=depgraph(myaction,myopts,myparams) if myaction in ["system","world"]: if not ("--quiet" in myopts): print "Calculating",myaction,"dependencies ", sys.stdout.flush() - if not mydepgraph.xcreate(myaction): + if not mydepgraph.xcreate(syslist, myaction): print "!!! Depgraph creation failed." sys.exit(1) if not ("--quiet" in myopts): @@ -3502,7 +2248,7 @@ pkglist.append(pkg) else: pkglist = mydepgraph.altlist() - mydepgraph.merge(pkglist) + mydepgraph.merge(pkglist, favorites) if portage.mtimedb.has_key("resume"): del portage.mtimedb["resume"] --- depgraph.old 2006-06-16 18:36:46.000000000 +0000 +++ depgraph.py 2006-06-16 18:32:22.565738256 +0000 @@ -0,0 +1,1310 @@ + +import portage +import os,sys + +import xpak,string,re,commands,time +from stat import * +from output import * + +import portage_util +import portage_exception +from portage_const import PROFILE_PATH + +# Globals needed, which are overridden as we are imported! +# These globals will need to be modualarized before this script can be set free upon the world!!! +# -- Retrieved with pychecker -- +update_spinner=lambda: None +is_valid_package_atom=lambda: None +format_size=lambda: None +emergelog=lambda: None +format_size=lambda: None +edebug=lambda: None +unmerge=lambda: None +genericdict=dict + +EMERGE_WARNING_DELAY=5 +countdown=lambda: None +getlist=lambda: None +validate_merge_list=lambda: None +unmerge_overlapping=lambda: None +# End list + +olddbapi=None +class depgraph: + + def __init__(self,myaction,myopts,myparams): + self.myopts = myopts + self.myparams = myparams + global olddbapi + self.pkgsettings = portage.config(clone=portage.settings) + if not self.pkgsettings["ARCH"]: + portage.writemsg(red("\a!!! ARCH is not set... Are you missing the /etc/make.profile symlink?\n"), + noiselevel=-1) + portage.writemsg(red("\a!!! Is the symlink correct? Is your portage tree complete?\n\n"), + noiselevel=-1) + sys.exit(9) + self.applied_useflags = {} + + self.missingbins=[] + self.myaction=myaction + self.digraph=portage.digraph() + self.orderedkeys=[] + self.outdatedpackages=[] + self.mydbapi={} + self.mydbapi["/"] = portage.fakedbapi() + if "empty" not in self.myparams or portage.root != "/": + for pkg in portage.db["/"]["vartree"].getallcpv(): + self.mydbapi["/"].cpv_inject(pkg) + if portage.root != "/": + self.mydbapi[portage.root] = portage.fakedbapi() + if "empty" not in self.myparams: + for pkg in portage.db[portage.root]["vartree"].getallcpv(): + self.mydbapi[portage.root].cpv_inject(pkg) + + if "--usepkg" in self.myopts: + portage.db["/"]["bintree"].populate(("--getbinpkg" in self.myopts), ("--getbinpkgonly" in self.myopts)) + + def create(self,mybigkey,myparent=None,addme=1,myuse=None): + """creates the actual digraph of packages to merge. return 1 on success, 0 on failure + mybigkey = specification of package to merge; myparent = parent package (one depending on me); + addme = should I be added to the tree? (for the --onlydeps mode)""" + #stuff to add: + #SLOT-aware emerge + #IUSE-aware emerge + #"no downgrade" emerge + #print "mybigkey:",mybigkey + + jbigkey=string.join(mybigkey) + if self.digraph.hasnode(jbigkey+" merge") or self.digraph.hasnode(jbigkey+" nomerge"): + #this conditional is needed to prevent infinite recursion on already-processed deps + return 1 + + update_spinner() + + mytype,myroot,mykey=mybigkey + # select the correct /var database that we'll be checking against + vardbapi=portage.db[myroot]["vartree"].dbapi + + # if the package is already on the system, we add a "nomerge" + # directive, otherwise we add a "merge" directive. + if mytype=="blocks": + # we've encountered a "blocks" node. We will totally ignore this + # node and not add it to our digraph if it doesn't apply to us. + if addme and "--buildpkgonly" not in self.myopts and myparent and (self.mydbapi[myroot].match(mykey) or vardbapi.match(mykey)): + mybigkey.append(myparent.split()[2]) + self.digraph.addnode(string.join(mybigkey),myparent) + return 1 + + if myuse is None: + self.pkgsettings.setcpv(mykey) + myuse = self.pkgsettings["USE"].split() + self.applied_useflags[mykey] = myuse + + merging=1 + if addme: + # this is where we add the node to the list of packages to merge + if not myparent: + # command-line specified or part of a world list... + if ("self" not in self.myparams) or (("selective" in self.myparams) and vardbapi.cpv_exists(mykey)): + # the package is on the system, so don't merge it. + merging=0 + elif ("selective" in self.myparams) and vardbapi.cpv_exists(mykey): + merging=0 + + if (merging==0 and "--newuse" in self.myopts and vardbapi.cpv_exists(mykey)): + old_use = vardbapi.aux_get(mykey, ["USE"])[0].split() + if mytype == "binary": + iuses = portage.db["/"]["bintree"].dbapi.aux_get(mykey, ["IUSE"])[0].split() + else: + iuses = portage.db["/"]["porttree"].dbapi.aux_get(mykey, ["IUSE"])[0].split() + for x in iuses: + if (old_use.count(x) and not myuse.count(x)) or (not old_use.count(x) and myuse.count(x)): + merging=1 + break + else: + #onlydeps mode; don't merge + merging=2 + if merging==1: + mybigkey.append("merge") + else: + mybigkey.append("nomerge") + + # whatever the case, we need to add the node to our digraph so + # that children can depend upon it. + self.digraph.addnode(string.join(mybigkey),myparent) + if ("deep" not in self.myparams) and (not merging): + return 1 + elif "recurse" not in self.myparams: + return 1 + + edepend={} + if mytype=="binary": + mypkgparts=portage.catpkgsplit(mykey) + tbz2name = string.split(mykey, "/")[1]+".tbz2" + if tbz2name in portage.db[portage.root]["bintree"].invalids: + sys.stderr.write("\nINVALID PACKAGE (is required to continue): "+str(mykey)+"\n") + sys.exit(1) + if portage.db[portage.root]["bintree"].isremote(mykey): + edepend = portage.db[portage.root]["bintree"].remotepkgs[tbz2name] + edepend["DEPEND"] ="" + edepend["RDEPEND"]=string.join(string.split(edepend["RDEPEND"])," ") + edepend["PDEPEND"]=string.join(string.split(edepend["PDEPEND"])," ") + edepend["SLOT"] =string.strip(edepend["SLOT"]) + #portage.db[portage.root]["bintree"].gettbz2(mykey) + else: # It's local. + mytbz2=xpak.tbz2(portage.db[portage.root]["bintree"].getname(mykey)) + edepend["DEPEND"] ="" + edepend["RDEPEND"]=string.join(mytbz2.getelements("RDEPEND")," ") + edepend["PDEPEND"]=string.join(mytbz2.getelements("PDEPEND")," ") + edepend["SLOT"] =mytbz2.getfile("SLOT",mypkgparts[2]) + elif mytype=="ebuild": + try: + mymeta = ["DEPEND","RDEPEND","PDEPEND"] + myfoo = portage.portdb.aux_get(mykey, mymeta) + for index in range(0,len(mymeta)): + edepend[mymeta[index]] = myfoo[index] + if "--buildpkgonly" in self.myopts: + edepend["RDEPEND"] = "" + edepend["PDEPEND"] = "" + except (KeyError,IOError): + print "emerge: create(): aux_get() error on",mykey+"; aborting..." + sys.exit(1) + mydep={} + mp=string.join(mybigkey) + + if myroot=="/": + mydep["/"]=edepend["DEPEND"]+" "+edepend["RDEPEND"] + if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse): + return 0 + else: + mydep["/"]=edepend["DEPEND"] + mydep[myroot]=edepend["RDEPEND"] + if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse): + return 0 + if not self.select_dep(myroot,mydep[myroot],myparent=mp,myuse=myuse): + return 0 + + if edepend.has_key("PDEPEND") and edepend["PDEPEND"]: + # Post Depend -- Add to the list without a parent, as it depends + # on a package being present AND must be built after that package. + if not self.select_dep(myroot,edepend["PDEPEND"],myuse=myuse): + return 0 + + return 1 + + def select_files(self,myfiles): + "given a list of .tbz2s, .ebuilds and deps, create the appropriate depgraph and return a favorite list" + myfavorites=[] + for x in myfiles: + ext = os.path.splitext(x)[1] + if ext==".tbz2": + if not os.path.exists(x): + if os.path.exists(self.pkgsettings["PKGDIR"]+"/All/"+x): + x=self.pkgsettings["PKGDIR"]+"/All/"+x + elif os.path.exists(self.pkgsettings["PKGDIR"]+"/"+x): + x=self.pkgsettings["PKGDIR"]+"/"+x + else: + print "\n\n!!! Binary package '"+str(x)+"' does not exist." + print "!!! Please ensure the tbz2 exists as specified.\n" + sys.exit(1) + mytbz2=xpak.tbz2(x) + mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.splitext(os.path.basename(x))[0] + if os.path.realpath(portage.db["/"]["bintree"].getname(mykey)) != os.path.realpath(x): + print red("\n*** You need to adjust PKGDIR to emerge this package.\n") + sys.exit(1) + if not self.create(["binary",portage.root,mykey],None,"--onlydeps" not in self.myopts): + return (0,myfavorites) + elif not "--oneshot" in self.myopts: + myfavorites.append(mykey) + elif ext==".ebuild": + x = os.path.realpath(x) + mykey=os.path.basename(os.path.normpath(x+"/../.."))+"/"+os.path.splitext(os.path.basename(x))[0] + ebuild_path = portage.db["/"]["porttree"].dbapi.findname(mykey) + if ebuild_path: + if os.path.realpath(ebuild_path) != x: + print red("\n*** You need to adjust PORTDIR or PORTDIR_OVERLAY to emerge this package.\n") + sys.exit(1) + if mykey not in portage.db["/"]["porttree"].dbapi.xmatch("match-visible", portage.dep_getkey(mykey)): + print red("\n*** You are emerging a masked package. It is MUCH better to use") + print red("*** /etc/portage/package.* to accomplish this. See portage(5) man") + print red("*** page for details.") + countdown(EMERGE_WARNING_DELAY, "Continuing...") + else: + raise portage_exception.PackageNotFound( + "%s is not in a valid portage tree hierarchy or does not exist" % x) + if not self.create(["ebuild",portage.root,mykey],None,"--onlydeps" not in self.myopts): + return (0,myfavorites) + elif not "--oneshot" in self.myopts: + myfavorites.append(mykey) + else: + if not is_valid_package_atom(x): + portage.writemsg("\n\n!!! '%s' is not a valid package atom.\n" % x, + noiselevel=-1) + portage.writemsg("!!! Please check ebuild(5) for full details.\n") + portage.writemsg("!!! (Did you specify a version but forget to prefix with '='?)\n") + return (0,[]) + try: + mykey=portage.dep_expand(x,mydb=portage.portdb) + except ValueError, errpkgs: + print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous. Please specify" + print "!!! one of the following fully-qualified ebuild names instead:\n" + for i in errpkgs[0]: + print " " + green(i) + print + sys.exit(1) + + # select needs to return 0 on dep_check failure + + sys.stdout.flush() + sys.stderr.flush() + + try: + self.mysd = self.select_dep(portage.root,mykey,arg=x) + except portage_exception.MissingSignature, e: + portage.writemsg("\n\n!!! A missing gpg signature is preventing portage from calculating the\n") + portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n") + portage.writemsg("!!! to aid in the detection of malicious intent.\n\n") + portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n") + portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1) + sys.exit(1) + except portage_exception.InvalidSignature, e: + portage.writemsg("\n\n!!! An invalid gpg signature is preventing portage from calculating the\n") + portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n") + portage.writemsg("!!! to aid in the detection of malicious intent.\n\n") + portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF TAMPERED FILES -- CHECK CAREFULLY.\n") + portage.writemsg("!!! Affected file: %s\n" % (e), noiselevel=-1) + sys.exit(1) + except SystemExit, e: + raise # Needed else can't exit + except Exception, e: + if "--debug" in self.myopts: + raise + print "\n\n!!! Problem in",mykey,"dependencies." + print "!!!",str(e),e.__module__ + sys.exit(1) + + if not self.mysd: + return (0,myfavorites) + elif not "--oneshot" in self.myopts: + myfavorites.append(portage.dep_getkey(mykey)) + + missing=0 + if "--usepkgonly" in self.myopts: + for x in self.digraph.dict.keys(): + xs=string.split(x," ") + if (xs[0] != "binary") and (xs[3]=="merge"): + if missing == 0: + print + missing += 1 + print "Missing binary for:",xs[2] + + # We're true here unless we are missing binaries. + return (not missing,myfavorites) + + def is_newer_ver_installed(self,myroot,pkg,pkgver): + "if there is a version of pkg installed newer than pkgver, return it" + vardbapi=portage.db[myroot]["vartree"].dbapi # not used???? + + matches=portage.db[myroot]["vartree"].dbapi.match(pkg) + if matches: + myslot=portage.db["/"]["porttree"].getslot(pkgver) + for match in matches: + if portage.pkgcmp(portage.catpkgsplit(pkgver)[1:], portage.catpkgsplit(match)[1:]) < 0: + curslot=portage.db[myroot]["vartree"].getslot(match) + if curslot == myslot: + return match + return None #explicitly return None, was implicit + + def select_dep(self,myroot,depstring,myparent=None,arg=None,myuse=None,raise_on_missing=False): + "given a dependency string, create the appropriate depgraph and return 1 on success and 0 on failure" + if "--debug" in self.myopts: + print + print "Parent: ",myparent + print "Depstring:",depstring + if not arg: + #processing dependencies + mycheck=portage.dep_check(depstring,self.mydbapi[myroot],self.pkgsettings,myuse=myuse,use_binaries=("--usepkgonly" in self.myopts),myroot=myroot) + + if not mycheck[0]: + mymerge=[] + else: + mymerge=mycheck[1] + + else: + #we're processing a command-line argument; unconditionally merge it even if it's already merged + mymerge=[depstring] + + # dep_check has been run so we can now add our parent to our + # build state to update virtuals and other settings. This + # happens after the package is added to the tree so that a + # package can depend on a virtual which it satisfies. + if myparent: + myp = myparent.split() + if myp[3]=="merge": + self.mydbapi[myroot].cpv_inject(myp[2]) + if myp[0]=="binary": + self.pkgsettings.setinst(myp[2],portage.db["/"]["bintree"].dbapi) + else: + self.pkgsettings.setinst(myp[2],portage.db[myroot]["porttree"].dbapi) + + if not mymerge: + return 1 + + if "--debug" in self.myopts: + print "Candidates:",mymerge + for x in mymerge: + myk=None + binpkguseflags=None + if x[0]=="!": + # if this package is myself, don't append it to block list. + if "--debug" in self.myopts: + print "Myparent",myparent + if (myparent): + if myparent.split()[2] in portage.portdb.xmatch("match-all", x[1:]): + # myself, so exit. + continue + # adding block + myk=["blocks",myroot,x[1:]] + else: + #We are not processing a blocker but a normal dependency + myeb=None + myeb_matches = portage.portdb.xmatch("match-visible",x) + if ("--usepkgonly" not in self.myopts): + myeb=portage.best(myeb_matches) + + myeb_pkg=None + if ("--usepkg" in self.myopts): + # The next line assumes the binarytree has been populated. + # XXX: Need to work out how we use the binary tree with roots. + myeb_pkg_matches=portage.db["/"]["bintree"].dbapi.match(x) + if ("--usepkgonly" not in self.myopts): + # Remove any binary package entries that are masked in the portage tree (#55871) + for idx in range(len(myeb_pkg_matches)-1,-1,-1): + if myeb_pkg_matches[idx] not in myeb_matches: + del myeb_pkg_matches[idx] + myeb_pkg = portage.best(myeb_pkg_matches) + + if not myeb_pkg: + myeb_pkg = None + elif ("--newuse" in self.myopts): + iuses=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["IUSE"])[0]) + old_use=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["USE"])[0]) + self.pkgsettings.setcpv(myeb_pkg) + now_use=string.split(self.pkgsettings["USE"]) + for x in iuses: + if (old_use.count(x) and not now_use.count(x)) or (not old_use.count(x) and now_use.count(x)): + myeb_pkg = None + break + + if (not myeb) and (not myeb_pkg): + if raise_on_missing: + raise ValueError + if not arg: + xinfo='"'+x+'"' + else: + xinfo='"'+arg+'"' + if myparent: + xfrom = '(dependency required by '+green('"'+myparent.split()[2]+'"')+red(' ['+myparent.split()[0]+"]")+')' + alleb=portage.portdb.xmatch("match-all",x) + if alleb: + if "--usepkgonly" not in self.myopts: + print "\n!!! "+red("All ebuilds that could satisfy ")+green(xinfo)+red(" have been masked.") + print "!!! One of the following masked packages is required to complete your request:" + oldcomment = "" + for p in alleb: + mreasons = portage.getmaskingstatus(p) + print "- "+p+" (masked by: "+string.join(mreasons, ", ")+")" + comment = portage.getmaskingreason(p) + if comment and comment != oldcomment: + print comment + oldcomment = comment + print + print "For more information, see MASKED PACKAGES section in the emerge man page or " + print "refer to the Gentoo Handbook." + else: + print "\n!!! "+red("There are no packages available to satisfy: ")+green(xinfo) + print "!!! Either add a suitable binary package or compile from an ebuild." + else: + print "\nemerge: there are no ebuilds to satisfy "+green(xinfo)+"." + if myparent: + print xfrom + print + return 0 + + if "--debug" in self.myopts: + print "ebuild:",myeb + print "binpkg:",myeb_pkg + + if myeb and myeb_pkg: + myeb_s = portage.catpkgsplit(myeb) + myeb_s = [myeb_s[0]+"/"+myeb_s[1], myeb_s[2], myeb_s[3]] + myeb_pkg_s = portage.catpkgsplit(myeb_pkg) + myeb_pkg_s = [myeb_pkg_s[0]+"/"+myeb_pkg_s[1], myeb_pkg_s[2], myeb_pkg_s[3]] + + if portage.pkgcmp(myeb_s, myeb_pkg_s) == 0: # pkg is same version as ebuild + myeb = None + else: + myeb_pkg = None + + if myeb: + myk=["ebuild",myroot,myeb] + elif myeb_pkg: + binpkguseflags=portage.db[portage.root]["bintree"].get_use(myeb_pkg) + myk=["binary",myroot,myeb_pkg] + else: + sys.stderr.write("!!! Confused... Don't know what's being used for dependency info. :(\n") + sys.exit(1) + + #if "--usepkg" in self.myopts: + # #If we want to use packages, see if we have a pre-built one... + # mypk=portage.db["/"]["bintree"].dbapi.match(x) + # if myeb in mypk: + # #Use it only if it's exactly the version we want. + # myk=["binary",myroot,myeb] + # else: + # myk=["ebuild",myroot,myeb] + #else: + # myk=["ebuild",myroot,myeb] + if myparent: + #we are a dependency, so we want to be unconditionally added + if not self.create(myk,myparent,myuse=binpkguseflags): + return 0 + else: + #if mysource is not set, then we are a command-line dependency and should not be added + #if --onlydeps is specified. + if not self.create(myk,myparent,"--onlydeps" not in self.myopts,myuse=binpkguseflags): + return 0 + + if "--debug" in self.myopts: + print "Exiting...",myparent + return 1 + + + def altlist(self): + mygraph=self.digraph.copy() + dolist=["/"] + retlist=[] + for x in portage.db.keys(): + portage.db[x]["merge"]=[] + if x not in dolist: + dolist.append(x) + while (not mygraph.empty()): + mycurkey=mygraph.firstzero() + if not mycurkey: + print "!!! Error: circular dependencies:" + print + for x in mygraph.dict.keys(): + for y in mygraph.dict[x][1]: + print y,"depends on",x + print + sys.exit(1) + splitski=string.split(mycurkey) + #I'm not sure of the significance of the following lines (vestigal?) so I'm commenting 'em out. + #These lines remove already-merged things from our alt-list + #if "--update" in self.myopts: + # if not portage.db["/"]["vartree"].exists_specific(splitski[2]): + # portage.db["/"]["merge"].append(splitski) + #else: + portage.db[splitski[1]]["merge"].append(splitski) + mygraph.delnode(mycurkey) + for x in dolist: + for y in portage.db[x]["merge"]: + retlist.append(y) + return retlist + + def xcreate(self,sysl,mode="system"): + global syslist + syslist = sysl + world_problems = False + if mode=="system": + mylist=syslist + else: + #world mode + worldlist=getlist("world") + sysdict=genericdict(syslist) + worlddict=genericdict(worldlist) + + for x in worlddict.keys(): + if not portage.isvalidatom(x): + world_problems = True + elif not portage.db["/"]["vartree"].dbapi.match(x): + world_problems = True + else: + sysdict[x]=worlddict[x] + + mylist = sysdict.keys() + + newlist = [] + for atom in mylist: + if portage.dep_getkey(atom).split("/")[-1] == "portage": + newlist.insert(0, atom) + else: + newlist.append(atom) + mylist = newlist + + missing_atoms = [] + for mydep in mylist: + try: + if not self.select_dep(portage.root, mydep, raise_on_missing=True): + print "\n\n!!! Problem resolving dependencies for", mydep + return 0 + except ValueError: + if "--debug" in self.myopts: + raise + missing_atoms.append(mydep) + + if world_problems: + print "\n!!! Problems have been detected with your world file" + print "!!! Please run "+green("emaint --check world")+"\n" + + if missing_atoms and "--verbose" in self.myopts: + print "\n!!! Packages for the following atoms are either all" + print "!!! masked or don't exist:" + print " ".join(missing_atoms) + "\n" + + return 1 + + def match(self,mydep,myroot=portage.root,mykey=None): + # support mutual exclusive deps + mydep2=mydep + if mydep2[0]=="!": + mydep2=mydep[1:] + + if mydep[0]=="!": + #add our blocker; it will be ignored later if necessary (if we are remerging the same pkg, for example) + myk="blocks "+myroot+" "+mydep2 + else: + myeb=portage.db[portage.root]["porttree"].dep_bestmatch(mydep2) + if not myeb: + if not mykey: + print "\n!!! Error: couldn't find match for",mydep + else: + print "\n!!! Error: couldn't find match for",mydep,"in",mykey + print + sys.exit(1) + + if "--usepkg" in self.myopts: + mypk=portage.db[portage.root]["bintree"].dep_bestmatch(mydep) + if myeb==mypk: + myk="binary "+portage.root+" "+mypk + else: + myk="ebuild "+myroot+" "+myeb + else: + myk="ebuild "+myroot+" "+myeb + + return myk + + def display(self,mylist,verbosity=999): + if verbosity == 999: + verbosity = ("--quiet" in self.myopts and 1 or "--verbose" in self.myopts and 3 or 2 ); + changelogs=[] + p=[] + totalsize=0 + + if verbosity == 1: + def create_use_string(*args): + return "" + else: + def create_use_string(name, cur_iuse, cur_use, old_iuse, old_use, is_new, + all_flags=(verbosity == 3), alphabetical=("--alphabetical" in self.myopts)): + enabled = [] + if alphabetical: + disabled = enabled + else: + disabled = [] + for flag in cur_iuse: + if flag in cur_use: + if is_new or flag in old_use and all_flags: + enabled.append(red(flag)) + elif flag not in old_iuse: + enabled.append(yellow(flag)+"%") + elif flag not in old_use: + enabled.append(green(flag)+"*") + else: + if is_new or flag in old_iuse and flag not in old_use and all_flags: + disabled.append(blue("-"+flag)) + elif flag not in old_iuse: + disabled.append(yellow("-"+flag)+"%") + elif flag in old_use: + disabled.append(green("-"+flag)+"*") + + enabled = " ".join(enabled) + if alphabetical: + disabled = "" + else: + disabled = " ".join(disabled) + if enabled and disabled: + ret = enabled + " " + disabled + elif enabled: + ret = enabled + else: + ret = disabled + if ret: + ret = '%s="%s" ' % (name, ret) + return ret + + if verbosity == 3: + overlays = self.pkgsettings["PORTDIR_OVERLAY"].split() + overlays_real = [os.path.realpath(t) \ + for t in self.pkgsettings["PORTDIR_OVERLAY"].split()] + + if "--tree" in self.myopts: + mylist.reverse() + mygraph=self.digraph.copy() + + i = 0 + while i < len(mylist): + if mylist[i][-1]=="nomerge": + if not ("--tree" in self.myopts): + # we don't care about this elements + mylist.pop(i) + continue + if (i == (len(mylist) - 1)) \ + or (mygraph.depth(string.join(mylist[i])) \ + >= mygraph.depth(string.join(mylist[i+1]))): + # end of a useless branch (may be the last one) + # -> delete the element and test the previous one + mylist.pop(i) + if i > 0: + i -= 1 + continue + # the branch continues, or we've found a good element. + # -> let's see what's next, if anything + i += 1 + + display_overlays=False + # files to fetch list - avoids counting a same file twice + # in size display (verbose mode) + myfetchlist=[] + for x in mylist: + pkg_type = x[0] + pkg_key = x[2] + if pkg_key not in self.applied_useflags: + if "binary" == pkg_type: + self.applied_useflags[pkg_key] = portage.db["/"]["bintree"].dbapi.aux_get(pkg_key, ["USE"])[0].split() + elif "ebuild" == pkg_type: + self.pkgsettings.setcpv(pkg_key) + self.applied_useflags[pkg_key] = self.pkgsettings["USE"].split() + + fetch=" " + + if x[0]=="blocks": + addl=""+red("B")+" "+fetch+" " + resolved=portage.db[x[1]]["vartree"].resolve_key(x[2]) + print "["+x[0]+" "+addl+"]",red(resolved), + if resolved!=x[2]: + if x[3]: + print red("(\""+x[2]+"\" is blocking "+x[3]+")") + else: + print red("(\""+x[2]+"\")") + else: + if x[3]: + print red("(is blocking "+x[3]+")") + else: + print + else: + if (x[0]!="binary") and ("fetch" in string.split(portage.portdb.aux_get(x[2],["RESTRICT"])[0])): + fetch = red("F") + if portage.portdb.fetch_check(x[2], self.applied_useflags[x[2]]): + fetch = green("f") + + #we need to use "--emptrytree" testing here rather than "empty" param testing because "empty" + #param is used for -u, where you still *do* want to see when something is being upgraded. + myoldbest="" + if (not "--emptytree" in self.myopts) and portage.db[x[1]]["vartree"].exists_specific(x[2]): + addl=" "+yellow("R")+fetch+" " + elif (not "--emptytree" in self.myopts) and portage.db[x[1]]["vartree"].exists_specific_cat(x[2]): + if x[0] == "binary": + mynewslot=portage.db["/"]["bintree"].getslot(x[2]) + elif x[0] == "ebuild": + mynewslot=portage.db["/"]["porttree"].getslot(x[2]) + myoldlist=portage.db[x[1]]["vartree"].dbapi.match(portage.pkgsplit(x[2])[0]) + myinslotlist=filter((lambda p: portage.db[portage.root]["vartree"].getslot(p)==mynewslot),myoldlist) + if myinslotlist: + myoldbest=portage.best(myinslotlist) + addl=" "+fetch + if portage.pkgcmp(portage.pkgsplit(x[2]), portage.pkgsplit(myoldbest)) < 0: + # Downgrade in slot + addl+=turquoise("U")+blue("D") + else: + # Update in slot + addl+=turquoise("U")+" " + else: + # New slot, mark it new. + addl=" "+green("NS")+fetch+" " + + if "--changelog" in self.myopts: + changelogs.extend(self.calc_changelog( + portage.portdb.findname(x[2]), + portage.db[x[1]]["vartree"].dep_bestmatch('/'.join(portage.catpkgsplit(x[2])[:2])), + x[2] + )) + else: + addl=" "+green("N")+" "+fetch+" " + + verboseadd="" + + if x[2] in self.applied_useflags: + # USE flag display + if x[0] == "binary": + cur_iuse = string.split(portage.db["/"]["bintree"].dbapi.aux_get(x[2],["IUSE"])[0]) + elif x[0] == "ebuild": + cur_iuse = string.split(portage.portdb.aux_get(x[2],["IUSE"])[0]) + else: + cur_iuse = [] + + cur_iuse = portage.unique_array(cur_iuse) + cur_iuse = [flag for flag in cur_iuse if flag not in portage.settings.usemask] + cur_iuse.sort() + cur_use = self.applied_useflags[x[2]] + cur_use = [flag for flag in cur_use if flag in cur_iuse] + + if myoldbest: + pkg = myoldbest + else: + pkg = x[2] + if portage.db[x[1]]["vartree"].dbapi.cpv_exists(pkg): + (old_iuse, old_use) = portage.db[x[1]]["vartree"].dbapi.aux_get(pkg, ["IUSE", "USE"]) + old_iuse = portage.unique_array(old_iuse.split()) + old_iuse.sort() + old_use = old_use.split() + is_new = False + else: + old_iuse = [] + old_use = [] + is_new = True + old_iuse = [flag for flag in old_iuse if flag not in portage.settings.usemask] + old_use = [flag for flag in old_use if flag in old_iuse] + + use_expand = portage.settings["USE_EXPAND"].lower().split() + use_expand.sort() + use_expand.reverse() + use_expand_hidden = portage.settings["USE_EXPAND_HIDDEN"].lower().split() + + def map_to_use_expand(myvals): + ret = {} + for exp in use_expand: + ret[exp] = [] + for val in myvals[:]: + if val.startswith(exp.lower()+"_"): + ret[exp].append(val[len(exp)+1:]) + myvals.remove(val) + ret["USE"] = myvals + for exp in use_expand_hidden: + if exp in ret: + del ret[exp] + return ret + + cur_iuse_map = map_to_use_expand(cur_iuse) + cur_use_map = map_to_use_expand(cur_use) + old_iuse_map = map_to_use_expand(old_iuse) + old_use_map = map_to_use_expand(old_use) + + use_expand.sort() + use_expand.insert(0, "USE") + + for key in use_expand: + if key in use_expand_hidden: + continue + verboseadd += create_use_string(key.upper(), cur_iuse_map[key], cur_use_map[key], + old_iuse_map[key], old_use_map[key], is_new) + + if verbosity == 3: + # size verbose + mysize=0 + if x[0] == "ebuild" and x[-1]!="nomerge": + myfilesdict=portage.portdb.getfetchsizes(x[2], useflags=self.applied_useflags[x[2]], debug=edebug) + if myfilesdict is None: + myfilesdict="[empty/missing/bad digest]" + else: + for myfetchfile in myfilesdict.keys(): + if myfetchfile not in myfetchlist: + mysize+=myfilesdict[myfetchfile] + myfetchlist.append(myfetchfile) + totalsize+=mysize + verboseadd+=format_size(mysize)+" " + + # overlay verbose + # XXX: Invalid binaries have caused tracebacks here. 'if file_name' + # x = ['binary', '/', 'sys-apps/pcmcia-cs-3.2.7.2.6', 'merge'] + file_name=portage.portdb.findname(x[2]) + if file_name: # It might not exist in the tree + dir_name=os.path.abspath(os.path.dirname(file_name)+"/../..") + if (overlays_real.count(dir_name)>0): + verboseadd+=teal("["+str(overlays_real.index( + os.path.normpath(dir_name))+1)+"]")+" " + display_overlays=True + else: + verboseadd += "[No ebuild?]" + + xs=portage.pkgsplit(x[2]) + if xs[2]=="r0": + xs[2]="" + else: + xs[2]="-"+xs[2] + + if self.pkgsettings.has_key("COLUMNWIDTH"): + mywidth=int(self.pkgsettings.settings["COLUMNWIDTH"]) + else: + mywidth=130 + oldlp=mywidth-30 + newlp=oldlp-30 + + indent="" + if ("--tree" in self.myopts): + indent=" "*mygraph.depth(string.join(x)) + + if myoldbest: + myoldbest=portage.pkgsplit(myoldbest)[1]+"-"+portage.pkgsplit(myoldbest)[2] + if myoldbest[-3:]=="-r0": + myoldbest=myoldbest[:-3] + myoldbest=blue("["+myoldbest+"]") + + if x[1]!="/": + if myoldbest: + myoldbest +=" " + if "--columns" in self.myopts: + if "--quiet" in self.myopts: + myprint=addl+" "+indent+darkgreen(xs[0]) + myprint=myprint+darkblue(" "+xs[1]+xs[2])+" " + myprint=myprint+myoldbest + myprint=myprint+darkgreen("to "+x[1]) + else: + myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0]) + if (newlp-nc_len(myprint)) > 0: + myprint=myprint+(" "*(newlp-nc_len(myprint))) + myprint=myprint+"["+darkblue(xs[1]+xs[2])+"] " + if (oldlp-nc_len(myprint)) > 0: + myprint=myprint+" "*(oldlp-nc_len(myprint)) + myprint=myprint+myoldbest + myprint=myprint+darkgreen("to "+x[1])+" "+verboseadd + else: + myprint="["+x[0]+" "+addl+"] "+darkgreen(x[2])+" "+myoldbest+darkgreen("to "+x[1])+" "+verboseadd + else: + if "--columns" in self.myopts: + if "--quiet" in self.myopts: + myprint=addl+" "+indent+darkgreen(xs[0]) + myprint=myprint+" "+green(xs[1]+xs[2])+" " + myprint=myprint+myoldbest + else: + myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0]) + if (newlp-nc_len(myprint)) > 0: + myprint=myprint+(" "*(newlp-nc_len(myprint))) + myprint=myprint+green(" ["+xs[1]+xs[2]+"] ") + if (oldlp-nc_len(myprint)) > 0: + myprint=myprint+(" "*(oldlp-nc_len(myprint))) + myprint=myprint+myoldbest+" "+verboseadd + else: + if x[3]=="nomerge": + myprint=darkblue("[nomerge ] "+indent+x[2]+" "+myoldbest+" ")+verboseadd + else: + myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(x[2])+" "+myoldbest+" "+verboseadd + p.append(myprint) + + mysplit = portage.pkgsplit(x[2]) + if "--tree" not in self.myopts and mysplit and len(mysplit) == 3 and \ + mysplit[0] == "sys-apps/portage" and x[1] == "/": + + if mysplit[2] == "r0": + myversion = mysplit[1] + else: + myversion = "%s-%s" % (mysplit[1], mysplit[2]) + + if myversion != portage.VERSION : + if "--emptytree" in self.myopts: + p.append(red("***")+" Please update portage to the above version before proceeding.") + p.append(" Failure to do so may result in failed or improper merges.") + p.append(" A simple '"+green("emerge portage")+"' is sufficient.") + p.append("") + elif mylist.index(x) < len(mylist) - 1 and \ + "livecvsportage" not in portage.settings.features: + p.append(red("*** Portage will stop merging at this point and reload itself,")) + p.append(red(" then resume the merge.")) + print + del mysplit + + for x in p: + print x + + if verbosity == 3: + print + print "Total size of downloads: "+format_size(totalsize) + if overlays and display_overlays: + print "Portage overlays:" + y=0 + for x in overlays: + y=y+1 + print " "+teal("["+str(y)+"]"),x + + if "--changelog" in self.myopts: + print + for revision,text in changelogs: + print bold('*'+revision) + sys.stdout.write(text) + + def calc_changelog(self,ebuildpath,current,next): + current = '-'.join(portage.catpkgsplit(current)[1:]) + if current.endswith('-r0'): current = current[:-3] + next = '-'.join(portage.catpkgsplit(next)[1:]) + if next.endswith('-r0'): next = next[:-3] + changelogpath = os.path.join(os.path.split(ebuildpath)[0],'ChangeLog') + try: + changelog = open(changelogpath).read() + except SystemExit, e: + raise # Needed else can't exit + except: + return [] + divisions = self.find_changelog_tags(changelog) + #print 'XX from',current,'to',next + #for div,text in divisions: print 'XX',div + # skip entries for all revisions above the one we are about to emerge + for i in range(len(divisions)): + if divisions[i][0]==next: + divisions = divisions[i:] + break + # find out how many entries we are going to display + for i in range(len(divisions)): + if divisions[i][0]==current: + divisions = divisions[:i] + break + else: + # couldnt find the current revision in the list. display nothing + return [] + return divisions + + def find_changelog_tags(self,changelog): + divs = [] + release = None + while 1: + match = re.search(r'^\*\ ?([-a-zA-Z0-9_.+]*)(?:\ .*)?\n',changelog,re.M) + if match is None: + if release is not None: + divs.append((release,changelog)) + return divs + if release is not None: + divs.append((release,changelog[:match.start()])) + changelog = changelog[match.end():] + release = match.group(1) + if release.endswith('.ebuild'): + release = release[:-7] + if release.endswith('-r0'): + release = release[:-3] + + def outdated(self): + return self.outdatedpackages + + def merge(self,mylist,fav): + self.favorites=fav # XXX: HACK + print "Favorites set to " + repr(fav) + returnme=0 + mymergelist=[] + + #check for blocking dependencies + if ("--fetchonly" not in self.myopts) and ("--buildpkgonly" not in self.myopts): + for x in mylist: + if x[0]=="blocks": + print "\n!!! Error: the "+x[2]+" package conflicts with another package;" + print "!!! the two packages cannot be installed on the same system together." + print "!!! Please use 'emerge --pretend' to determine blockers." + print + if ("--pretend" not in self.myopts): + try: + del portage.mtimedb["resume"] + except KeyError: + pass + sys.exit(1) + + #buildsyspkg: I need mysysdict also on resume (moved from the else block) + mysysdict=genericdict(syslist) + if ("--resume" in self.myopts): + # We're resuming. + print green("*** Resuming merge...") + emergelog(" *** Resuming merge...") + mymergelist=portage.mtimedb["resume"]["mergelist"][:] + if ("--skipfirst" in self.myopts) and mymergelist: + del portage.mtimedb["resume"]["mergelist"][0] + del mymergelist[0] + validate_merge_list(mymergelist) + else: + myfavs = portage.grabfile(os.path.join(portage.root, portage.WORLD_FILE)) + myfavdict=genericdict(myfavs) + for x in range(len(mylist)): + if mylist[x][3]!="nomerge": + # Add to the mergelist + mymergelist.append(mylist[x]) + else: + myfavkey=portage.cpv_getkey(mylist[x][2]) + if "--onlydeps" in self.myopts: + continue + # Add to the world file. Since we won't be able to later. + if (not "--fetchonly" in self.myopts) and (myfavkey in self.favorites): + #don't record if already in system profile or already recorded + if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)): + #we don't have a favorites entry for this package yet; add one + myfavdict[myfavkey]=myfavkey + print ">>> Recording",myfavkey,"in \"world\" favorites file..." + if not "--fetchonly" in self.myopts: + portage.write_atomic( + os.path.join(portage.root, portage.WORLD_FILE), + "\n".join(myfavdict.values())) + + portage.mtimedb["resume"]["mergelist"]=mymergelist[:] + + # We need to yank the harmful-to-new-builds settings from features. + myorigfeat=self.pkgsettings["FEATURES"] + myfeat=myorigfeat.split() + while ("keeptemp" in myfeat): + del myfeat[myfeat.index("keeptemp")] + while ("keepwork" in myfeat): + del myfeat[myfeat.index("keepwork")] + + self.pkgsettings["FEATURES"]=string.join(myfeat) + + if "parallel-fetch" in myfeat and not ("--ask" in self.myopts or "--pretend" in self.myopts or "--fetchonly" in self.myopts): + if "distlocks" not in myfeat: + print red("!!!") + print red("!!!")+" parallel-fetching requires the distlocks feature enabled" + print red("!!!")+" you have it disabled, thus parallel-fetching is being disabled" + print red("!!!") + elif len(mymergelist) > 1: + print ">>> starting parallel fetching" + pid = os.fork() + if not pid: + sys.stdin.close() + sys.stdout.close() + sys.stderr.close() + time.sleep(3) # allow the parent to have first fetch + sys.stdout = open("/dev/null","w") + sys.stderr = open("/dev/null","w") + os.dup2(sys.stdout.fileno(), 1) + os.dup2(sys.stdout.fileno(), 2) + # wipe the mtimedb so that portage doesn't attempt to flush it. + # do not convert this code away from a fork without correcting this. + portage.mtimedb = None + for x in ("autoaddcvs", "cvs"): + try: myfeat.remove(x) + except ValueError: pass + self.pkgsettings["FEATURES"] = " ".join(myfeat) + ret = 0 + for x in mymergelist: + if x[0] != "ebuild": + continue + try: + ret = portage.doebuild(portage.portdb.findname(x[2]), "fetch", x[1], self.pkgsettings, + cleanup=0, fetchonly=True, tree="porttree") + except SystemExit: + raise + except Exception: + ret = 1 + sys.exit(0) + portage.portage_exec.spawned_pids.append(pid) + + mergecount=0 + for x in mymergelist: + mergecount+=1 + myroot=x[1] + pkgindex=2 + if x[0]=="blocks": + pkgindex=3 + y=portage.portdb.findname(x[pkgindex]) + if not "--pretend" in self.myopts: + print ">>> Emerging ("+str(mergecount)+" of "+str(len(mymergelist))+")",x[pkgindex],"to",x[1] + emergelog(" >>> emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" to "+x[1]) + + self.pkgsettings["EMERGE_FROM"] = x[0][:] + self.pkgsettings.backup_changes("EMERGE_FROM") + self.pkgsettings.reset() + + #buildsyspkg: Check if we need to _force_ binary package creation + issyspkg = ("buildsyspkg" in myfeat) \ + and x[0] != "blocks" \ + and mysysdict.has_key(portage.cpv_getkey(x[2])) \ + and not ("--buildpkg" in self.myopts) + if x[0] in ["ebuild","blocks"]: + if (x[0]=="blocks") and ("--fetchonly" not in self.myopts): + raise Exception, "Merging a blocker" + elif ("--fetchonly" in self.myopts) or ("--fetch-all-uri" in self.myopts): + if ("--fetch-all-uri" in self.myopts): + retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in self.myopts),fetchonly=1,fetchall=1,tree="porttree") + else: + retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in self.myopts),fetchonly=1,tree="porttree") + if (retval is None) or retval: + print + print "!!! Fetch for",y,"failed, continuing..." + print + returnme=1 + continue + elif "--buildpkg" in self.myopts or issyspkg: + #buildsyspkg: Sounds useful to display something, but I don't know if we should also log it + if issyspkg: + print ">>> This is a system package, let's pack a rescue tarball." + #emergelog(">>> This is a system package, let's pack a rescue tarball.") + #create pkg, then merge pkg + short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean" + emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) + retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree") + if (retval is None): + portage_util.writemsg("Unable to run required binary.\n", + noiselevel=-1) + sys.exit(127) + if retval: + sys.exit(retval) + short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile" + emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Packaging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) + retval=portage.doebuild(y,"package",myroot,self.pkgsettings,edebug,tree="porttree") + if (retval is None): + portage_util.writemsg("Unable to run required binary.\n", + noiselevel=-1) + sys.exit(127) + if retval: + sys.exit(retval) + #dynamically update our database + if "--buildpkgonly" not in self.myopts: + portage.db[portage.root]["bintree"].inject(x[2]) + mytbz2=portage.db[portage.root]["bintree"].getname(x[2]) + short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge" + emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) + + self.pkgsettings["EMERGE_FROM"] = "binary" + self.pkgsettings.backup_changes("EMERGE_FROM") + + retval=portage.pkgmerge(mytbz2,myroot,self.pkgsettings) + if retval is None: + sys.exit(1) + elif "noclean" not in self.pkgsettings.features: + portage.doebuild(y, "clean", myroot, self.pkgsettings, + edebug, tree="porttree") + else: + short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean" + emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) + retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1,tree="porttree") + if (retval is None): + portage_util.writemsg("Unable to run required binary.\n", + noiselevel=-1) + sys.exit(127) + if retval: + sys.exit(retval) + short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile" + emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) + retval=portage.doebuild(y,"merge",myroot,self.pkgsettings,edebug,tree="porttree") + if (retval is None): + portage_util.writemsg("Unable to run required binary.\n", + noiselevel=-1) + sys.exit(127) + if retval: + sys.exit(retval) + #dynamically update our database + elif x[0]=="binary": + #merge the tbz2 + mytbz2=portage.db[portage.root]["bintree"].getname(x[2]) + if portage.db[portage.root]["bintree"].isremote(x[2]): + short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Fetch" + emergelog(" --- ("+str(mergecount)+" of "+str(len(mymergelist))+") Fetching Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg) + if not portage.db[portage.root]["bintree"].gettbz2(x[2]): + sys.exit(1) + + if ("--fetchonly" in self.myopts) or ("--fetch-all-uri" in self.myopts): + continue + + short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge Binary" + emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg) + retval=portage.pkgmerge(mytbz2,x[1],self.pkgsettings) + if retval is None: + sys.exit(1) + #need to check for errors + if "--buildpkgonly" not in self.myopts: + portage.db[x[1]]["vartree"].inject(x[2]) + myfavkey=portage.cpv_getkey(x[2]) + if "--fetchonly" not in self.myopts and "--fetch-all-uri" not in self.myopts and myfavkey in self.favorites: + myfavs = portage.grabfile(os.path.join(myroot, portage.WORLD_FILE)) + myfavdict=genericdict(myfavs) + mysysdict=genericdict(syslist) + #don't record if already in system profile or already recorded + if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)): + #we don't have a favorites entry for this package yet; add one + myfavdict[myfavkey]=myfavkey + print ">>> Recording",myfavkey,"in \"world\" favorites file..." + emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Updating world file ("+x[pkgindex]+")") + portage.write_atomic( + os.path.join(myroot, portage.WORLD_FILE), + "\n".join(myfavdict.values())) + + if ("--pretend" not in self.myopts) and ("--fetchonly" not in self.myopts) and ("--fetch-all-uri" not in self.myopts): + # Clean the old package that we have merged over top of it. + if self.pkgsettings["AUTOCLEAN"]=="yes": + xsplit=portage.pkgsplit(x[2]) + emergelog(" >>> AUTOCLEAN: "+xsplit[0]) + if x[1] == portage.settings["ROOT"]: + # Compare against portage.settings["ROOT"] because + # the value of self.pkgsettings["ROOT"] does not + # match the original value! + retval = unmerge("clean", [xsplit[0]]) + else: + retval = unmerge_overlapping(x[2], x[1], + self.pkgsettings, portage.db[x[1]]["vartree"]) + if not retval: + emergelog(" --- AUTOCLEAN: Nothing unmerged.") + else: + portage.writemsg_stdout(colorize("WARN", "WARNING:") + + " AUTOCLEAN is disabled. This can cause serious" + + " problems due to overlapping packages.\n") + + # Figure out if we need a restart. + mysplit=portage.pkgsplit(x[2]) + if mysplit[0] == "sys-apps/portage" and x[1] == "/": + myver=mysplit[1]+"-"+mysplit[2] + if myver[-3:]=='-r0': + myver=myver[:-3] + if (myver != portage.VERSION) and \ + ("livecvsportage" not in portage.settings.features): + if len(mymergelist) > mergecount: + emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1]) + emergelog(" *** RESTARTING emerge via exec() after change of portage version.") + del portage.mtimedb["resume"]["mergelist"][0] + portage.run_exitfuncs() + mynewargv=[sys.argv[0],"--resume"] + badlongopts = ("--ask","--tree","--changelog","--skipfirst","--resume") + for arg in self.myopts: + if arg in badlongopts: + continue + mynewargv.append(arg) + # priority only needs to be adjusted on the first run + os.environ["PORTAGE_NICENESS"] = "0" + os.execv(mynewargv[0], mynewargv) + + if ("--pretend" not in self.myopts) and ("--fetchonly" not in self.myopts) and ("--fetch-all-uri" not in self.myopts): + if "noclean" not in portage.settings.features: + short_msg = "emerge: (%s of %s) %s Clean Post" % \ + (mergecount, len(mymergelist), x[pkgindex]) + emergelog(" === (%s of %s) Post-Build Cleaning (%s::%s)" % \ + (mergecount, len(mymergelist), x[pkgindex], y), short_msg=short_msg) + emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1]) + + # Unsafe for parallel merges + del portage.mtimedb["resume"]["mergelist"][0] + # Commit after each merge so that --resume may still work in + # in the event that portage is not allowed to exit normally + # due to power failure, SIGKILL, etc... + portage.commit_mtimedb() + + emergelog(" *** Finished. Cleaning up...") + + # We're out of the loop... We're done. Delete the resume data. + if portage.mtimedb.has_key("resume"): + del portage.mtimedb["resume"] + + if ("--pretend" not in self.myopts): + if ("--fetchonly" not in self.myopts) and ("--fetch-all-uri" not in self.myopts): + if (mergecount>0): + if retval: + portage.env_update() + + #by doing an exit this way, --fetchonly can continue to try to + #fetch everything even if a particular download fails. + if "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts: + if returnme: + print "\n\n!!! Some fetch errors were encountered. Please see above for details.\n\n" + sys.exit(returnme) + else: + sys.exit(0) +