--- emergehelp.py 2003-08-27 04:04:47.000000000 -0400 +++ emergehelp.py 2003-08-27 04:03:43.000000000 -0400 @@ -1,2079 +1,361 @@ #!/usr/bin/env python2.2 # Copyright 1999-2003 Gentoo Technologies, Inc. # Distributed under the terms of the GNU General Public License v2 -# $Header: /home/cvsroot/gentoo-src/portage/bin/emerge,v 1.224 2003/08/21 01:01:26 carpaski Exp $ - -import os -os.environ["PORTAGE_CALLER"]="emerge" +# $Header: /home/cvsroot/gentoo-src/portage/bin/emergehelp.py,v 1.16 2003/08/16 07:28:22 carpaski Exp $ -import sys,emergehelp,xpak,string,re,commands,time,shutil,traceback,atexit,signal -from stat import * +import os,sys from output import * -import portage -if (not sys.stdout.isatty()) or (portage.settings["NOCOLOR"] in ["yes","true"]): - nocolor() - -if portage.settings.has_key("PORTAGE_NICENESS"): - try: - os.nice(int(portage.settings["PORTAGE_NICENESS"])) - except Exception,e: - print "!!! Failed to change nice value to '"+str(portage.settings["PORTAGE_NICENESS"])+"'" - print "!!!",e - -#Freeze the portdbapi for enhanced performance: -portage.portdb.freeze() - -# Kill noauto as it will break merges otherwise. -while 'noauto' in portage.features: - del portage.features[portage.features.index('noauto')] - - -spinner="\|/-\|/-" -spinpos=0 -#number of ebuilds merged -merged=0 -params=["selective", "deep", "self", "recurse", "empty"] -actions=[ -"clean", "config", "depclean", "help", "info", "inject", "prune", -"regen", "rsync", "search", "sync", "system", "unmerge", "world" -] -options=[ -"--buildpkg", "--buildpkgonly", -"--changelog", "--columns", -"--debug", "--deep", -"--digest", -"--emptytree", "--fetchonly", -"--getbinpkg", "--getbinpkgonly", -"--help", "--noconfmem", -"--nodeps", "--noreplace", -"--nospinner", "--oneshot", -"--onlydeps", "--pretend", -"--quiet", "--resume", -"--searchdesc", "--selective", -"--skipfirst", -"--update", "--upgradeonly", -"--usepkg", "--usepkgonly", -"--verbose", "--version" -] - -shortmapping={ -"b":"--buildpkg", "B":"--buildpkgonly", -"c":"--clean", "C":"--unmerge", -"d":"--debug", "D":"--deep", -"e":"--emptytree", -"f":"--fetchonly", -"g":"--getbinpkg", "G":"--getbinpkgonly", -"h":"--help", -"i":"--inject", -"k":"--usepkg", "K":"--usepkgonly", -"l":"--changelog", -"n":"--noreplace", -"o":"--onlydeps", "O":"--nodeps", -"p":"--pretend", "P":"--prune", -"q":"--quiet", -"s":"--search", "S":"--searchdesc", -"u":"--update", "U":"--upgradeonly", -"v":"--verbose", "V":"--version" -} - -myaction=None -myopts=[] -myfiles=[] -edebug=0 - -# process short actions and options -tmpcmdline=sys.argv[1:] -#tmpcmdline.extend(portage.settings["EMERGE_OPTS"].split()) -cmdline=[] -for x in tmpcmdline: - if x[0:1]=="-"and x[1:2]!="-": - for y in x[1:]: - if shortmapping.has_key(y): - if shortmapping[y] in cmdline: - print - print "*** Warning: Redundant use of",shortmapping[y] - else: - cmdline.append(shortmapping[y]) - else: - print "!!! Error: -"+y+" is an invalid short action or option." - sys.exit(1) - else: - cmdline.append(x) - -# process the command arguments -for x in cmdline: - if not x: - continue - if len(x)>=2 and x[0:2]=="--": - if x in options: - myopts.append(x) - elif x[2:] in actions: - if x[2:]=="rsync": - #print - #print red("*** --rsync has been deprecated.") - #print red("*** Please use '--sync' instead.") - x="--sync" - if myaction: - if myaction not in ["system", "world"]: - myaction="--"+myaction - print - print red("!!!")+green(" Multiple actions requested... Please choose one only.") - print red("!!!")+" '"+darkgreen(myaction)+"' "+red("or")+" '"+darkgreen(x)+"'" - print - sys.exit(1) - myaction=x[2:] - else: - print "!!! Error:",x,"is an invalid option." - sys.exit(1) - elif (not myaction) and (x in actions): - if x not in ["system", "world"]: - #print red("*** Deprecated use of action '"+x+"'") - if x=="rsync": - #print red("*** Please use '--sync' instead.") - x="sync" - #else: - #print red("*** Please use '--"+x+"' instead.") - if myaction: - print - print red("!!!")+green(" Multiple actions requested... Please choose one only.") - #print red("!!! '")+darkgreen("--"+myaction)+"' "+red("or")+" '"+darkgreen("--"+x)+"'" - print red("!!! '")+darkgreen(myaction)+"' "+red("or")+" '"+darkgreen(x)+"'" - print - sys.exit(1) - myaction=x - elif x[-1]=="/": - # this little conditional helps tab completion - myfiles.append(x[:-1]) - else: - myfiles.append(x) - -if (myaction in ["world", "system"]) and myfiles: - print "emerge: please specify a package class (\"world\" or \"system\") or individual packages, but not both." - sys.exit(1) - -# Always create packages if FEATURES=buildpkg -# Imply --buildpkg if --buildpkgonly -if ("buildpkg" in portage.features) or ("--buildpkgonly" in myopts): - if "--buildpkg" not in myopts: - myopts.append("--buildpkg") - -# Also allow -S to invoke search action (-sS) -if ("--searchdesc" in myopts) and (not myaction): - myaction = "search" - -if ("--getbinpkgonly" in myopts) and not ("--usepkgonly" in myopts): - myopts.append("--usepkgonly") - -if ("--getbinpkgonly" in myopts) and not ("--getbinpkg" in myopts): - myopts.append("--getbinpkg") - -if ("--getbinpkg" in myopts) and not ("--usepkg" in myopts): - myopts.append("--usepkg") - -# Also allow -K to apply --usepkg/-k -if ("--usepkgonly" in myopts) and not ("--usepkg" in myopts): - myopts.append("--usepkg") - -# Also allow -U to apply --update/-u -if ("--upgradeonly" in myopts) and not ("--update" in myopts): - print ">>> --upgradeonly implies --update... adding --update to options." - myopts.append("--update") - -# Also allow -l to apply --pretend/-p -if ("--changelog" in myopts) and not ("--pretend" in myopts): - print ">>> --changelog implies --pretend... adding --pretend to options." - myopts.append("--pretend") - -# Set so that configs will be merged regardless of remembered status -if ("--noconfmem" in myopts): - portage.settings["NOCONFMEM"]="1" - -# Set various debug markers... They should be merged somehow. -if ("--debug" in myopts): - portage.settings["PORTAGE_DEBUG"]="1" - portage.debug=1 - - -def emergelog(mystr): - if "notitles" not in portage.features: - xtermTitle(mystr) - try: - mylogfile=open("/var/log/emerge.log", "a") - mylogfile.write(str(time.time())[:10]+": "+mystr+"\n") - mylogfile.flush() - mylogfile.close() - except Exception, e: - if edebug: - print "emergelog():",e - pass - -def emergeexit(): - """This gets out final log message in before we quit. As it overrides - any other atexit's we have setup, we need to call them ourself.""" - #portage.portageexit() - emergelog(" *** terminating.") - if "notitles" not in portage.features: - xtermTitleReset() -atexit.register(emergeexit) - -def emergeexitsig(signum, frame): - emergeexit() - sys.exit(100+signum) -signal.signal(signal.SIGINT, emergeexitsig) +def shorthelp(): + print + print + print bold("Usage:") + print " "+turquoise("emerge")+" [ "+green("options")+" ] [ "+green("action")+" ] [ "+turquoise("ebuildfile")+" | "+turquoise("tbz2file")+" | "+turquoise("dependency")+" ] [ ... ]" + print " "+turquoise("emerge")+" [ "+green("options")+" ] [ "+green("action")+" ] < "+turquoise("system")+" | "+turquoise("world")+" >" + print " "+turquoise("emerge")+" < "+turquoise("sync")+" | "+turquoise("info")+" >" + print " "+turquoise("emerge")+" "+turquoise("--resume")+" ["+green("--pretend")+" | "+green("--skip-first")+"]" + print " "+turquoise("emerge")+" "+turquoise("help")+" [ "+green("system")+" | "+green("config")+" | "+green("sync")+" ] " + print bold("Options:")+" "+green("-")+"["+green("bcCdDefhikKlnoOpPsSuUvV")+"] ["+green("--once-only")+"] ["+green("--forget-configuration")+"]" + print " ["+green("--columns")+"] ["+green("--no-spinner")+"]" + print bold("Actions:")+" [ "+green("clean")+" | "+green("depclean")+" | "+green("inject")+" | "+green("prune")+" | "+green("regen")+" | "+green("search")+" | "+green("unmerge")+" ]" + print -def countdown(secs=5, doing="Starting"): - if secs: - print ">>> Waiting",secs,"seconds before starting..." - print ">>> (Control-C to abort)...\n"+doing+" in: ", - ticks=range(secs) - ticks.reverse() - for sec in ticks: - sys.stdout.write(red(str(sec+1)+" ")) - sys.stdout.flush() - time.sleep(1) +def help(myaction,myopts,havecolor=1): + if not havecolor: + nocolor() + if not myaction and ("--help" not in myopts): + shorthelp() print - -def getportageversion(): - try: - profilever=os.path.basename(os.path.normpath(os.readlink("/etc/make.profile"))) - except: - profilever="unavailable" - glibcver=[] - for x in portage.vardbapi(portage.root).match("glibc"): - xs=portage.pkgsplit(x) - if glibcver: - glibcver+=","+xs[1]+"-"+xs[2] - else: - glibcver=xs[1]+"-"+xs[2] - if glibcver==[]: - glibcver="unavailable" - - gccout=commands.getstatusoutput("`which gcc` -dumpversion") - if gccout[0]: - print "!!! No gcc found. You probably need to 'source /etc/profile' to update" - print "!!! the environment of this terminal and possibly other terminals also." + print " For more help try 'emerge --help' or consult the man page." print - gccver="[unavailable]" - else: - gccver="gcc-"+gccout[1] - - unameout=commands.getstatusoutput("uname -r")[1] - - return "Portage " + portage.VERSION +" ("+profilever+", "+gccver+", glibc-"+glibcver+", "+unameout+")" - -def help(): - # Move all the help stuff out of this file. - emergehelp.help(myaction,myopts,havecolor) - -# check if root user is the current user for the actions where emerge needs this -if ("--pretend" in myopts) or (myaction=="search"): - if not portage.secpass: - if portage.wheelgid==portage.portage_gid: - print "emerge: wheel group membership required for \"--pretend\" and search." - print "emerge: wheel group use is being deprecated. Please update group and passwd to" - print " include the portage user as noted above, and then use group portage." - else: - print "emerge: portage group membership required for \"--pretend\" and search." - sys.exit(1) -elif "--version" in myopts: - print getportageversion() - sys.exit(0) -elif "--help" in myopts: - help() - sys.exit(0) -elif portage.secpass!=2: - if myaction in ["search", "help", "info"]: - pass - elif (not myaction) and (not myfiles): - pass - elif ("--pretend" in myopts) and (myaction in ["world","system","clean","prune","unmerge"]): - pass - else: - print "myaction",myaction - print "myopts",myopts - print "emerge: root access required." - sys.exit(1) - -if not "--pretend" in myopts: - emergelog("Started emerge on: "+time.strftime("%b %d, %Y %H:%M:%S", time.localtime())) - myelogstr="" - if myopts: - myelogstr=string.join(myopts, " ") - if myaction: - myelogstr+=" "+myaction - if myfiles: - myelogstr+=" "+string.join(myfiles, " ") - emergelog(" *** emerge "+myelogstr) - -#configure emerge engine parameters -# -# self: include _this_ package regardless of if it is merged. -# selective: exclude the package if it is merged -# recurse: go into the dependencies -# empty: pretend nothing is merged -myparams=["self","recurse"] -add=[] -sub=[] -if "--update" in myopts: - add.extend(["selective","empty"]) -if "--emptytree" in myopts: - add.extend(["empty"]) - sub.extend(["selective"]) -if "--nodeps" in myopts: - sub.extend(["recurse"]) -if "--noreplace" in myopts: - add.extend(["selective"]) -if "--deep" in myopts: - add.extend(["deep"]) -if "--selective" in myopts: - add.extend(["selective"]) -if myaction in ["world","system"]: - add.extend(["selective"]) -elif myaction in ["depclean"]: - add.extend(["empty"]) - sub.extend(["selective"]) -for x in add: - if (x not in myparams) and (x not in sub): - myparams.append(x) -for x in sub: - if x in myparams: - myparams.remove(x) - -def update_spinner(): - global spinner, spinpos - if sys.stdout.isatty() and not ("--nospinner" in myopts): - sys.stdout.write("\b"+spinner[spinpos]) - spinpos=(spinpos+1)%8 - sys.stdout.flush() - -# search functionality -class search: - - # - # class constants - # - VERSION_SHORT=1 - VERSION_RELEASE=2 - - # - # public interface - # - def __init__(self): - """Searches the available and installed packages for the supplied search key. - The list of available and installed packages is created at object instantiation. - This makes successive searches faster.""" - self.installcache = portage.db["/"]["vartree"] - - def execute(self,searchkey): - """Performs the search for the supplied search key""" - global myopts - self.searchkey=searchkey - self.packagematches = [] - if "--searchdesc" in myopts: - self.searchdesc=1 - self.matches = {"pkg":[], "desc":[]} - else: - self.searchdesc=0 - self.matches = {"pkg":[]} - print "Searching... ", - if self.searchkey=="*": - #hack for people who aren't regular expression gurus - self.searchkey==".*" - if re.search("\+\+", self.searchkey): - #hack for people who aren't regular expression gurus - self.searchkey=re.sub("\+\+","\+\+",self.searchkey) - self.searchre=re.compile(self.searchkey.lower(),re.I) - for package in portage.portdb.cp_all(): - update_spinner() - package_parts=package.split("/") - masked=0 - if self.searchre.search(package_parts[1]): - if not portage.portdb.xmatch("match-visible",package): - masked=1 - self.matches["pkg"].append([package,masked]) - elif self.searchdesc: # DESCRIPTION searching - full_package = portage.portdb.xmatch("bestmatch-visible",package) - if not full_package: - #no match found; we don't want to query description - full_package=portage.best(portage.portdb.xmatch("match-all",package)) - if not full_package: - continue - else: - masked=1 - try: - full_desc = portage.portdb.aux_get(full_package,["DESCRIPTION"])[0] - except KeyError: - print "emerge: search: aux_get() failed, skipping" - continue - if self.searchre.search(full_desc): - self.matches["desc"].append([full_package,masked]) - self.mlen=0 - for mtype in self.matches.keys(): - self.matches[mtype].sort() - self.mlen += len(self.matches[mtype]) - - def output(self): - """Outputs the results of the search.""" - print "\b\b \n[ Results for search key : "+white(self.searchkey)+" ]" - print "[ Applications found : "+white(str(self.mlen))+" ]" - print " " - for mtype in self.matches.keys(): - for match,masked in self.matches[mtype]: - if mtype=="pkg": - catpack=match - full_package = portage.portdb.xmatch("bestmatch-visible",match) - if not full_package: - #no match found; we don't want to query description - masked=1 - full_package=portage.best(portage.portdb.xmatch("match-all",match)) - else: - full_package=match - catpack=portage.pkgsplit(match)[0] - if full_package: - try: - desc, homepage = portage.portdb.aux_get(full_package,["DESCRIPTION","HOMEPAGE"]) - except KeyError: - print "emerge: search: aux_get() failed, skipping" - continue - if masked: - print green("*")+" "+white(match)+" "+red("[ Masked ]") - else: - print green("*")+" "+white(match) - myversion = self.getVersion(full_package, search.VERSION_RELEASE) - - mysum = [0,0] - mycat = match.split("/")[0] - mypkg = match.split("/")[1] + "-" + myversion - - mydigest = portage.db["/"]["porttree"].dbapi.finddigest(mycat+"/"+mypkg) - - try: - myfile = open(mydigest,"r") - for line in myfile.readlines(): - mysum[0] += int(line.split(" ")[3]) - myfile.close() - mystr = str(mysum[0]/1024) - mycount=len(mystr) - while (mycount > 3): - mycount-=3 - mystr=mystr[:mycount]+","+mystr[mycount:] - mysum[0]=mystr+" kB" - except Exception, e: - if edebug: - print "!!! Exception:",e - mysum[0]=" [no/bad digest]" - - if "--quiet" not in myopts: - print " ", darkgreen("Latest version available:"),myversion - print " ", self.getInstallationStatus(catpack) - print " ", darkgreen("Size of downloaded files:"),mysum[0] - print " ", darkgreen("Homepage:")+" ",homepage - print " ", darkgreen("Description:"),desc - print + elif not myaction: + shorthelp() print - # - # private interface - # - def getInstallationStatus(self,package): - installed_package = self.installcache.dep_bestmatch(package) - result = "" - version = self.getVersion(installed_package,search.VERSION_RELEASE) - if len(version) > 0: - result = darkgreen("Latest version installed:")+" "+version - else: - result = darkgreen("Latest version installed:")+" [ Not Installed ]" - return result - - def getVersion(self,full_package,detail): - if len(full_package) > 1: - package_parts = portage.catpkgsplit(full_package) - if detail == search.VERSION_RELEASE and package_parts[3] != 'r0': - result = package_parts[2]+ "-" + package_parts[3] - else: - result = package_parts[2] - else: - result = "" - return result - - -#build our package digraph -def getlist(mode): - if mode=="system": - if portage.profiledir: - pfile=portage.profiledir+"/packages" - else: - print "!!! No profile directory; system mode unavailable." - sys.exit(1) - elif mode=="world": - pfile=portage.root+"var/cache/edb/world" - try: - myfile=open(pfile,"r") - mylines=myfile.readlines() - myfile.close() - except OSError: - print "!!! Couldn't open "+pfile+"; exiting." - sys.exit(1) - except IOError: - #world file doesn't exist - mylines=[] - mynewlines=[] - for x in mylines: - myline=string.join(string.split(x)) - if not len(myline): - continue - elif myline[0]=="#": - continue - elif mode=="system": - if myline[0]!="*": - continue - myline=myline[1:] - mynewlines.append(myline.strip()) - return mynewlines - -def genericdict(mylist): - mynewdict={} - for x in mylist: - mynewdict[portage.dep_getkey(x)]=x - return mynewdict - -olddbapi=None -class depgraph: - - def __init__(self,myaction,myopts): - global olddbapi - self.missingbins=[] - self.myaction=myaction - self.virts=portage.getvirtuals("/") - self.digraph=portage.digraph() - self.orderedkeys=[] - #the following is so we have an empty vartree (used in emerge update calculations) - self.fakedbapi=portage.fakedbapi() - #self.fakedbapi.cpv_inject("sys-libs/glibc-2.3") - self.outdatedpackages=[] - self.mydbapi={} - if "empty" in myparams: - #for --update, we want to rebuild an entire empty tree of dependencies, and then we won't merge was is already merged. - self.mydbapi["/"]=self.fakedbapi - else: - self.mydbapi["/"]=portage.db["/"]["vartree"].dbapi - if portage.root!="/": - if "empty" in myparams: - self.mydbapi[portage.root]=self.fakedbapi - else: - self.mydbapi[portage.root]=portage.db[portage.root]["vartree"].dbapi - - if "--usepkg" in myopts: - try: - portage.db["/"]["bintree"].populate(("--getbinpkg" in myopts), ("--getbinpkgonly" in myopts)) - except ValueError, e: - sys.stderr.write(red("!!! Failed to get all metadata: "+str(e)+"\n")) - sys.exit(1) - - def create(self,mybigkey,myparent=None,addme=1): - """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 - - merging=1 - # this is where we add the node to the list of packages to merge - if addme: - # 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 myparent and (self.mydbapi[myroot].match(mykey) or vardbapi.match(mykey)): - # otherwise, encode parent information where we would normally - # write "(no)merge" and continue: - parenttype,parentroot,parentkey,mergeme=string.split(myparent) - mykexp=portage.dep_expand(mykey,self.mydbapi[myroot]) - pakexp=portage.dep_expand(parentkey,self.mydbapi[myroot]) - myrealkey=portage.dep_getkey(mykexp) - parealkey=portage.dep_getkey(pakexp) - if myrealkey!=parealkey: - mybigkey.append(myparent.split()[2]) - self.digraph.addnode(string.join(mybigkey),myparent) - # since our blocks doesn't match any installed packages, - # it doesn't apply to us and we can ignore it. - return 1 - 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 - 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 portage.db[portage.root]["bintree"].isremote(mykey) and ("--pretend" in myopts): - # It's remote, and we have the info already. In pretend, - # we don't want to be downloading the tbz2's. - #if not portage.db[portage.root]["bintree"].remotepkgs.has_key(mypkgparts[1]): - # sys.stderr.write("\nThere are no packages available to satisfy "+str(mykey)+"\n\n") - # sys.exit(1) - 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["CDEPEND"]=string.join(string.split(edepend["CDEPEND"])," ") - edepend["SLOT"] =string.strip(edepend["SLOT"]) - else: - if portage.db[portage.root]["bintree"].isremote(mykey) or \ - tbz2name in portage.db[portage.root]["bintree"].invalids: - # Get the tbz2 - if not portage.db[portage.root]["bintree"].remotepkgs.has_key(tbz2name): - sys.stderr.write("\nThere are no packages available to satisfy "+str(mykey)+"\n\n") - sys.exit(1) - portage.db[portage.root]["bintree"].gettbz2(mykey) - 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["CDEPEND"]=string.join(mytbz2.getelements("CDEPEND")," ") - edepend["REBUILD"]=string.join(mytbz2.getelements("REBUILD")," ") - edepend["SLOT"] =mytbz2.getfile("SLOT",mypkgparts[2]) - elif mytype=="ebuild": - try: - #edepend=portage.portdb.aux_get(mykey,["DEPEND","RDEPEND"]) - for x in ["DEPEND","RDEPEND","PDEPEND","REBUILD"]: - edepend[x]=string.join(portage.portdb.aux_get(mykey,[x]), " ") - 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): - return 0 - else: - mydep["/"]=edepend["DEPEND"] - mydep[myroot]=edepend["RDEPEND"] - if not self.select_dep("/",mydep["/"],myparent=mp): - return 0 - elif not self.select_dep(myroot,mydep[myroot],myparent=mp): - 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"]): - 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: - if x[-5:]==".tbz2": - if not os.path.exists(x): - if os.path.exists(portage.settings["PKGDIR"]+"/All/"+x): - x=portage.settings["PKGDIR"]+"/All/"+x - elif os.path.exists(portage.settings["PKGDIR"]+"/"+x): - x=portage.settings["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.basename(x)[:-5] - 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 x[-7:]==".ebuild": - mykey=os.path.basename(os.path.abspath(x+"/../.."))+"/"+os.path.basename(x)[:-7] - 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: - mykey=portage.dep_expand(x,portage.portdb) - # select needs to return 0 on dep_check failure - try: - self.mysd=self.select_dep(portage.root,mykey,arg=x) - except Exception, e: - print "\n!!! Problem in",mykey,"dependencies." - print "!!!",e - sys.exit(1) - - if not self.mysd: - return (0,myfavorites) - elif not "--oneshot" in myopts: - myfavorites.append(mykey) - - self.missingbins=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 self.missingbins == 0: - print - self.missingbins+=1 - print "Missing binary for:",xs[2] - - # We're true here unless we are missing binaries. - return (not self.missingbins,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 - - myslot=portage.portdb.aux_get(pkgver,["SLOT"])[0] - alleb=portage.portdb.xmatch("match-all",pkg) - while alleb: - cand=portage.portdb.xmatch("bestmatch-list",pkg,mylist=alleb) - if not cand: - break - curslot=portage.portdb.aux_get(cand,["SLOT"])[0] - if (curslot==myslot) and vardbapi.cpv_exists(cand): - # installed, is this package newer? - if portage.pkgcmp(portage.catpkgsplit(pkgver)[1:], portage.catpkgsplit(cand)[1:]) < 0: - return cand - break - alleb.remove(cand) - - def select_dep(self,myroot,depstring,myparent=None,arg=None): - "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]) - if not mycheck[0]: - return 0 - mymerge=mycheck[1] - else: - #we're processing a command-line argument; unconditionally merge it even if it's already merged - mymerge=[depstring] - if "--debug" in myopts: - print "Candidates:",mymerge - for x in mymerge: - if x[0]=="!": - #add our blocker; it will be ignored later if necessary (if we are remerging the same pkg, for example) - myk=["blocks",myroot,x[1:]] - else: - #We are not processing a blocker but a normal dependency - myeb_pkg=None - if ("--usepkg" in myopts): - myeb_pkg=portage.db[portage.root]["bintree"].dep_bestmatch(x) - - myeb=None - if ("--usepkgonly" not in myopts): - myeb=portage.portdb.xmatch("bestmatch-visible",x) - - if (not myeb) and (not myeb_pkg): - 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.") - if myparent: - print "!!! "+red(xfrom) - 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 masked or unmasked ebuilds to satisfy "+xinfo+"." - 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: # eb is newer than pkg - myeb_pkg = None - else: - myeb = None - - if "--upgradeonly" in myopts: - # Check that there isn't a newer version of this package already installed - cand=self.is_newer_ver_installed(myroot,x,myeb) - if cand: - myeb=cand - - if myeb: - myk=["ebuild",myroot,myeb] - elif myeb_pkg: - myk=["binary",myroot,myeb_pkg] - else: - sys.stderr.write("!!! Confused... Don't know what I'm using 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): - 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): - 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 - if mode=="system": - mylist=syslist - else: - #world mode - worldlist=getlist("world") - sysdict=genericdict(syslist) - worlddict=genericdict(worldlist) - #we're effectively upgrading sysdict to contain all new deps from worlddict - for x in worlddict.keys(): - #only add the world node if the package is: - #actually installed -- this prevents the remerging of already unmerged packages when we do a world --update; - #actually available -- this prevents emerge from bombing out due to no match being found (we want a silent ignore) - if "empty" in myparams: - if portage.db["/"]["vartree"].dbapi.match(x): - sysdict[x]=worlddict[x] - elif portage.db[portage.root]["vartree"].dbapi.match(x): - #package is installed - sysdict[x]=worlddict[x] - else: - print "\n*** Package in world file is not installed: "+x - mylist=[] - for x in sysdict.keys(): - mylist.append(sysdict[x]) - - for mydep in mylist: - myeb=portage.portdb.xmatch("bestmatch-visible",mydep) - if not myeb: - #this is an unavailable world entry; just continue - continue - - if "--upgradeonly" in myopts: - cand=self.is_newer_ver_installed(portage.root,mydep,myeb) - if cand: - myeb=cand - - #THIS NEXT BUNCH OF CODE NEEDS TO BE REPLACED TO SUPPORT WORLD ANTI-DEPS - #if mydep2[0]=="!":, etc. - if "--usepkg" in myopts: - mypk=portage.db[portage.root]["bintree"].dep_bestmatch(mydep) - if myeb==mypk: - myk=["binary",portage.root,mypk] - elif "--usepkgonly" in myopts: - self.missingbins += [myeb] - myk=["binary",portage.root,myeb] - #print "mypk:",mypk - #print "myeb:",myeb - else: - myk=["ebuild",portage.root,myeb] - else: - myk=["ebuild",portage.root,myeb] - if not self.create(myk): - print - print "!!! Problem with",myk[0],myk[2] - print "!!! Possibly a DEPEND/*DEPEND problem." - print - return 0 - 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): - changelogs=[] - for x in mylist: - #print x - 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]+"\" from pkg "+x[3]+")") - else: - print red("(\""+x[2]+"\")") - else: - if x[3]: - print red("(from pkg "+x[3]+")") - else: - print - else: - if x[3]=="nomerge": - continue - - if ("fetch" in string.split(portage.portdb.aux_get(x[2],["RESTRICT"])[0])): - fetch = red("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]): - myoldbest=portage.best(portage.db[x[1]]["vartree"].dbapi.match(portage.pkgsplit(x[2])[0])) - - try: - myoldslot=portage.db[portage.root]["vartree"].getslot(myoldbest) - except: - myoldslot=None - mynewslot=portage.portdb.aux_get(x[2],["SLOT"])[0] - - addl=" "+fetch - if (myoldslot==mynewslot) and portage.pkgcmp(portage.pkgsplit(x[2]), portage.pkgsplit(myoldbest)) < 0: - addl+=turquoise("U")+blue("D") - else: - if myoldslot: - addl+=turquoise("U")+" " - else: - addl+=turquoise("U")+blue("-") - - if "--changelog" in myopts: - changelogs.extend(self.calc_changelog( - portage.portdb.findname(x[2]), - portage.db["/"]["vartree"].dep_bestmatch('/'.join(portage.catpkgsplit(x[2])[:2])), - x[2] - )) - else: - addl=" "+green("N")+" "+fetch+" " - if myoldbest: - myoldbest=portage.pkgsplit(myoldbest)[1]+"-"+portage.pkgsplit(myoldbest)[2] - if myoldbest[-3:]=="-r0": - myoldbest=myoldbest[:-3] - myoldbest=blue("["+myoldbest+"]") - - iuse="" - if "--verbose" in myopts: - for ebuild_iuse in string.split(portage.portdb.aux_get(x[2],["IUSE"])[0], " "): - try: - if (portage.usesplit.index(ebuild_iuse) >= 0) : - iuse=iuse+red("+"+ebuild_iuse)+" " - except ValueError: - if ebuild_iuse != "": - iuse=iuse+blue("-"+ebuild_iuse)+" " - - xs=portage.pkgsplit(x[2]) - if xs[2]=="r0": - xs[2]="" - else: - xs[2]="-"+xs[2] - - if portage.settings.has_key("COLUMNWIDTH"): - mywidth=int(portage.settings["COLUMNWIDTH"]) - else: - mywidth=130 - oldlp=mywidth-30 - newlp=oldlp-30 - - if x[1]!="/": - if "--columns" in myopts: - myprint="["+x[0]+" "+addl+"] "+darkgreen(xs[0]) - if (newlp-len(myprint)) > 0: - myprint=myprint+(" "*(newlp-len(myprint))) - myprint=myprint+"["+darkblue(xs[1]+xs[2])+"] " - if (oldlp-len(myprint)) > 0: - myprint=myprint+" "*(oldlp-len(myprint)) - myprint=myprint+myoldbest - myprint=myprint+darkgreen(" to "+x[1])+" "+iuse - else: - myprint="["+x[0]+" "+addl+"] "+darkgreen(x[2])+" "+myoldbest+" "+darkgreen("to "+x[1])+" "+iuse - else: - if "--columns" in myopts: - myprint="["+x[0]+" "+addl+"] "+darkgreen(xs[0]) - if (newlp-len(myprint)) > 0: - myprint=myprint+(" "*(newlp-len(myprint))) - myprint=myprint+green(" ["+xs[1]+xs[2]+"] ") - if (oldlp-len(myprint)) > 0: - myprint=myprint+(" "*(oldlp-len(myprint))) - myprint=myprint+myoldbest+" "+iuse - else: - myprint="["+x[0]+" "+addl+"] "+darkgreen(x[2])+" "+myoldbest+" "+iuse - print myprint - - mysplit=portage.pkgsplit(x[2]) - # XXX mysplit _can_ be None.... Why? - if mysplit and (len(mysplit)==3): - if "--emptytree" not in myopts: - if mysplit[0]=="sys-apps/portage": - if mysplit[1]+mysplit[2]!=portage.VERSION: - if mylist.index(x)>> Recording",myfavkey,"in \"world\" favorites file..." - if not "--fetchonly" in myopts: - portage.writedict(myfavdict,portage.root+"var/cache/edb/world",writekey=0) - - portage.mtimedb["resume"]["mergelist"]=mymergelist[:] - - # We need to yank the harmful-to-new-builds settings from features. - myorigfeat=portage.settings["FEATURES"] - myfeat=myorigfeat.split() - while ("keeptemp" in myfeat): - del myfeat[myfeat.index("keeptemp")] - while ("keepwork" in myfeat): - del myfeat[myfeat.index("keepwork")] - portage.settings["FEATURES"]=string.join(myfeat) - - 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 ">>> emerge ("+str(mergecount)+" of "+str(len(mymergelist))+")",x[pkgindex],"to",x[1] - emergelog(" >>> emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" to "+x[1]) - if x[0] in ["ebuild","blocks"]: - if ("--fetchonly" in myopts) or (x[0]=="blocks"): - retval=portage.doebuild(y,"fetch",myroot,edebug,("--pretend" in myopts),fetchonly=1) - if retval: - print - print "!!! Fetch for",y,"failed, continuing..." - print - returnme=1 - continue - elif "--buildpkg" in myopts: - #create pkg, then merge pkg - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+y+")") - retval=portage.doebuild(y,"clean",myroot,edebug) - if retval: - sys.exit(1) - portage.settings["FEATURES"]=myorigfeat # Put back flags. - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Packaging ("+y+")") - retval=portage.doebuild(y,"package",myroot,edebug) - if retval: - sys.exit(1) - #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]) - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging ("+y+")") - retval=portage.pkgmerge(mytbz2,myroot) - if retval==None: - sys.exit(1) - else: - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+y+")") - retval=portage.doebuild(y,"clean",myroot,edebug) - if retval: - sys.exit(1) - portage.settings["FEATURES"]=myorigfeat # Put back flags. - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Merging ("+y+")") - retval=portage.doebuild(y,"merge",myroot,edebug) - if retval: - sys.exit(1) - #dynamically update our database - elif x[0]=="binary": - #merge the tbz2 - mytbz2=portage.db[portage.root]["bintree"].getname(x[2]) - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging Binary ("+y+")") - retval=portage.pkgmerge(mytbz2,x[1]) - if retval==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 (not "--fetchonly" in myopts) and (myfavkey in favorites): - myfavs=portage.grabfile(myroot+"var/cache/edb/world") - 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 ("+y+")") - portage.writedict(myfavdict,myroot+"var/cache/edb/world",writekey=0) - - if ("noclean" not in portage.features) and (x[0] != "binary"): - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Post-Build Cleaning ("+y+")") - retval=portage.doebuild(y,"clean",myroot,edebug) - if retval: - sys.exit(1) - - if ("--pretend" not in myopts) and ("--fetchonly" not in myopts): - # Clean the old package that we have merged over top of it. - if portage.settings.has_key("AUTOCLEAN") and (portage.settings["AUTOCLEAN"]=="yes"): - xsplit=portage.pkgsplit(x[2]) - emergelog(" >>> AUTOCLEAN: "+xsplit[0]) - if not unmerge("clean", [xsplit[0]]): - emergelog(" --- AUTOCLEAN: Nothing unmerged.") - - # Figure out if we need a restart. - mysplit=portage.pkgsplit(x[2]) - if mysplit[0]=="sys-apps/portage": - myver=mysplit[1]+"-"+mysplit[2] - if myver[-3:]=='-r0': - myver=myver[:-3] - if myver!=portage.VERSION: - if len(mymergelist) > mergecount: - myargv=sys.argv - myr=0 - for myra in range(len(myargv)): - if myargv[myr][0:len("portage")]=="portage": - del myargv[myr] - myr-=1 - if myargv[myr][0:len("sys-apps/portage")]=="sys-apps/portage": - del myargv[myr] - myr-=1 - myr+=1 - emergelog(" *** RESTARTING emerge via exec() after change of portage version.") - portage.portageexit() - os.execv("/usr/lib/portage/bin/emerge", myargv) - - if ("--pretend" not in myopts) and ("--fetchonly" not in myopts): - emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1]) - - # Unsafe for parallel merges - del portage.mtimedb["resume"]["mergelist"][0] - - 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): - if (mergecount>0): - 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: - 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(unmerge_action, unmerge_files): - candidate_catpkgs=[] - global_unmerge=0 - - if not unmerge_files or "world" in unmerge_files or "system" in unmerge_files: - if "unmerge"==unmerge_action: - print - print bold("emerge unmerge")+" can only be used with specific package names, not with "+bold("world")+" or" - print bold("system")+" targets." - print - return 0 - else: - global_unmerge=1 - - localtree=portage.db[portage.root]["vartree"] - # process all arguments and add all valid db entries to candidate_catpkgs - if global_unmerge: - if not unmerge_files or "world" in unmerge_files: - candidate_catpkgs.extend(localtree.getallnodes()) - elif "system" in unmerge_files: - candidate_catpkgs.extend(getlist("system")) - else: - #we've got command-line arguments - if not unmerge_files: - print "\nNo packages to unmerge have been provided.\n" - return 0 - for x in unmerge_files: - arg_parts=x.split('/') - if arg_parts[-1][-7:]!=".ebuild": - #possible cat/pkg or dep; treat as such - candidate_catpkgs.append(x) - elif unmerge_action in ["prune","clean"]: - print "\n!!! Prune and clean do not accept individual ebuilds as arguments;\n skipping.\n" - continue - else: - # it appears that the user is specifying an installed ebuild and we're in "unmerge" mode, so it's - # ok. - if not os.path.exists(x): - print "\n!!! The path '"+x+"' doesn't exist.\n" - return 0 - absx=os.path.abspath(x) - spabsx=absx.split("/") - if absx[:12]!="/var/db/pkg/" or len(spabsx)!=7: - print spabsx - print absx - print "\n!!!",x,"is not inside /var/db/pkg; aborting.\n" - return 0 - candidate_catpkgs.append("="+spabsx[4]+"/"+spabsx[5]) - - if "--pretend" in myopts: - print darkgreen("\n>>> These are the packages that I would unmerge:") - - pkgmap={} - numselected=0 - for x in candidate_catpkgs: - #cycle through all our candidate deps and determine what will and will not get unmerged - mymatch=localtree.dep_match(x) - if not mymatch and x[0] not in "<>=~": - #add a "=" if missing - mymatch=localtree.dep_match("="+x) - if not mymatch: - print "\n!!! Couldn't find match for",white(x) - continue - mykey=portage.key_expand(portage.dep_getkey(mymatch[0]),portage.db["/"]["vartree"].dbapi) - if not pkgmap.has_key(mykey): - pkgmap[mykey]={"protected":[], "selected":[], "omitted":[] } - if unmerge_action=="unmerge": - for y in mymatch: - if not y in pkgmap[mykey]["selected"]: - pkgmap[mykey]["selected"].append(y) - numselected=numselected+len(mymatch) - else: - #unmerge_action in ["prune", clean"] - slotmap={} - for mypkg in mymatch: - if unmerge_action=="clean": - myslot=localtree.getslot(mypkg) - else: - #since we're pruning, we don't care about slots and put all the pkgs in together - myslot=0 - if not slotmap.has_key(myslot): - slotmap[myslot]={} - slotmap[myslot][localtree.dbapi.cpv_counter(mypkg)]=mypkg - for myslot in slotmap.keys(): - counterkeys=slotmap[myslot].keys() - counterkeys.sort() - if not counterkeys: - continue - counterkeys.sort() - pkgmap[mykey]["protected"].append(slotmap[myslot][counterkeys[-1]]) - del counterkeys[-1] - #be pretty and get them in order of merge: - for ckey in counterkeys: - pkgmap[mykey]["selected"].append(slotmap[myslot][ckey]) - numselected=numselected+1 - #ok, now the last-merged package is protected, and the rest are selected - if global_unmerge and not numselected: - print "\n>>> No outdated packages were found on your system.\n" - return 0 - - if not numselected: - print "\n>>>",unmerge_action+": No packages selected for removal.\n" - return 0 - - for x in candidate_catpkgs: - for y in localtree.dep_nomatch(mymatch[0]): - if y not in pkgmap[mykey]["omitted"] and \ - y not in pkgmap[mykey]["selected"] and \ - y not in pkgmap[mykey]["protected"]: - pkgmap[mykey]["omitted"].append(y) - - for x in pkgmap.keys(): - if global_unmerge and not pkgmap[x]["selected"]: - #avoid cluttering the preview printout with stuff that isn't getting unmerged - continue - print "\n "+white(x) - for mytype in ["selected","protected","omitted"]: - print string.rjust(mytype,12)+":", - if pkgmap[x][mytype]: - for mypkg in pkgmap[x][mytype]: - mysplit=portage.catpkgsplit(mypkg) - if mysplit[3]=="r0": - myversion=mysplit[2] - else: - myversion=mysplit[2]+"-"+mysplit[3] - if mytype=="selected": - print red(myversion), - else: - print green(myversion), - else: - print "none", - print - - print "\n>>> Packages in",red("red"),"are slated for removal." - print ">>> Packages in",green("green"),"will not be removed.\n" - - if "--pretend" in myopts: - #we're done... return - return 0 - #the real unmerging begins, after a short delay.... - - if portage.settings["CLEAN_DELAY"]: - secs=string.atoi(portage.settings["CLEAN_DELAY"]) - else: - secs=5 - countdown(secs, ">>> Unmerging") - - for x in pkgmap.keys(): - for y in pkgmap[x]["selected"]: - print ">>> Unmerging "+y+"..." - emergelog("=== Unmerging... ("+y+")") - mysplit=string.split(y,"/") - #unmerge... - retval=portage.unmerge(mysplit[0],mysplit[1],portage.root,unmerge_action not in ["clean","prune"]) - if retval: - emergelog(" !!! unmerge FAILURE: "+y) - else: - emergelog(" >>> unmerge success: "+y) - #run ldconfig, etc... - portage.env_update() - if not numselected: - return 0 - else: - return 1 - - -def post_emerge(retval=0): - auxpat=re.compile('^([^-]*)(-\d+)?\.info(-\d+)?(\.gz)?') - os.chdir("/") - global myopts - print - if "--pretend" in myopts: - sys.exit(retval) - - emergelog(" *** exiting successfully.") - root=portage.root - - infodirs=[] - infodirs.extend(string.split(portage.settings["INFOPATH"], ":")) - infodirs.extend(string.split(portage.settings["INFODIR"], ":")) - - if os.path.exists("/usr/bin/install-info"): - regen=0 - for z in infodirs: - if z=='': - continue - inforoot=root+z - if os.path.isdir(inforoot): - try: - infomtime=os.stat(inforoot)[ST_MTIME] - except: - infomtime=0 - - if not portage.mtimedb.has_key("info"): - portage.mtimedb["info"]={} - if portage.mtimedb["info"].has_key(inforoot): - if portage.mtimedb["info"][inforoot]==infomtime: - pass - else: - portage.mtimedb["info"][inforoot]=0 - regen+=1 - else: - regen+=1 - - if not regen: - print " "+green("*")+" GNU info directory index is up-to-date." - else: - print " "+green("*")+" Regenerating GNU info directory index..." - - icount=0 - badcount=0 - for z in infodirs: - if z=='': - continue - inforoot=root+z - if portage.mtimedb["info"].has_key(inforoot): - if portage.mtimedb["info"][inforoot]!=0: - continue - try: - os.rename(inforoot+"/dir",inforoot+"/dir.old") - except: - pass - - if not os.path.isdir(inforoot): - continue - for x in os.listdir(inforoot): - aux=auxpat.search(x) - if not aux: - continue - auxgroups=aux.groups() - if not (auxgroups[1] or auxgroups[2]): - myso=commands.getstatusoutput("/usr/bin/install-info --dir-file="+inforoot+"/dir "+inforoot+"/"+x)[1] - if myso!="": - badcount=badcount+1 - if "--verbose" in myopts: - print myso - icount=icount+1 - #update mtime so we can potentially avoid regenerating. - portage.mtimedb["info"][inforoot]=os.stat(inforoot)[ST_MTIME] - - if badcount: - if "--verbose" not in myopts: - print " "+yellow("*")+" Processed",icount,"info files:",badcount,"errors; run with "+green("emerge --verbose")+" to view errors." - else: - print " "+yellow("*")+" Processed",icount,"info files;",badcount,"errors." - else: - print " "+green("*")+" Processed",icount,"info files." - - if portage.settings["CONFIG_PROTECT"]: - #number of directories with some protect files in them - procount=0 - for x in string.split(portage.settings["CONFIG_PROTECT"]): - if os.path.isdir(x): - a=commands.getstatusoutput("cd "+x+"; find . -iname '._cfg????_*'") - if a[0]!=0: - print " "+red("*")+" error scanning",x - else: - files=string.split(a[1]) - if files: - procount=procount+1 - print " "+yellow("* IMPORTANT:")+"",len(files),"config files in",x,"need updating." - if procount: - #print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files." - print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files." + print turquoise("Help (this screen):") + print " "+green("--help")+" ("+green("-h")+" short option)" + print " Displays this help; an additional argument (see above) will tell" + print " emerge to display detailed help." print - sys.exit(retval) - -# general options that should be taken into account before any action -if "--debug" in myopts: - edebug=1 - -if myaction in ["sync","rsync"] and (not "--help" in myopts): - if "--pretend" in myopts: - print "emerge: the \"sync\" action does not support \"--pretend.\"" - sys.exit(1) - - emergelog(" === rsync") - myportdir=portage.settings["PORTDIR"] - if myportdir[-1]=="/": - myportdir=myportdir[:-1] - if not os.path.exists(myportdir): - print ">>>",myportdir,"not found, creating it." - os.makedirs(myportdir,0755) - syncuri=string.rstrip(portage.settings["SYNC"]) - os.umask(0022) - if syncuri[:8]=="rsync://": - if not os.path.exists("/usr/bin/rsync"): - print "!!! /usr/bin/rsync does not exist, so rsync support is disabled." - print "!!! Type \"emerge net-misc/rsync\" to enable rsync support." - sys.exit(1) - mytimeout=180 - if portage.settings.has_key("RSYNC_TIMEOUT"): - try: - mytimeout=int(portage.settings["RSYNC_TIMEOUT"]) - except: - pass - mycommand="/usr/bin/rsync -rlptDvz --progress --stats --delete --delete-after --timeout="+str(mytimeout)+" --exclude='distfiles/*' --exclude='local/*' --exclude='packages/*' " - if portage.settings.has_key("RSYNC_EXCLUDEFROM"): - if os.path.exists(portage.settings["RSYNC_EXCLUDEFROM"]): - mycommand=mycommand+" --exclude-from "+portage.settings["RSYNC_EXCLUDEFROM"] - else: - print "!!! RSYNC_EXCLUDEFROM specified, but file does not exist." - mycommand=mycommand+" "+syncuri+"/* "+myportdir - print ">>> starting rsync with "+syncuri+"..." - exitcode=portage.spawn(mycommand,free=1) - try: - maxretries=int(portage.settings["RSYNC_RETRIES"]) - except: - maxretries=3 #default number of retries - retries=1 - while (exitcode not in [0,1,2,3,4,11,14,20,21]) and (retries<=maxretries): - print "\n\n>>> Starting retry %d of %d"% (retries,maxretries) - time.sleep(11) - retries=retries+1 - exitcode=portage.spawn(mycommand,free=1) - if (exitcode>0): - print - if exitcode==1: - print darkred("!!!")+green(" Rsync has reported that there is a syntax error. Please ensure") - print darkred("!!!")+green(" that your SYNC statement is proper.") - print darkred("!!!")+green(" SYNC="+portage.settings["SYNC"]) - elif exitcode==11: - print darkred("!!!")+green(" Rsync has reported that there is a File IO error. Normally") - print darkred("!!!")+green(" this means your disk is full, but can be caused by corruption") - print darkred("!!!")+green(" on the filesystem that contains PORTDIR. Please investigate") - print darkred("!!!")+green(" and try again after the problem has been fixed.") - print darkred("!!!")+green(" PORTDIR="+portage.settings["PORTDIR"]) - elif exitcode==20: - print darkred("!!!")+green(" Rsync was killed before it finished.") - else: - print darkred("!!!")+green(" Rsync has not successfully finished. It is recommended that you keep") - print darkred("!!!")+green(" trying or that you use the 'emerge-webrsync' option if you are unable") - print darkred("!!!")+green(" to use rsync due to firewall or other restrictions. This should be a") - print darkred("!!!")+green(" temporary problem unless complications exist with your network") - print darkred("!!!")+green(" (and possibly your system's filesystem) configuration.") - print - sys.exit(exitcode) - elif syncuri[:6]=="cvs://": - if not os.path.exists("/usr/bin/cvs"): - print "!!! /usr/bin/cvs does not exist, so rsync support is disabled." - print "!!! Type \"emerge dev-util/cvs\" to enable CVS support." - sys.exit(1) - cvsroot=syncuri[6:] - cvsdir=os.path.dirname(myportdir) - if not os.path.exists(myportdir+"/CVS"): - #initial checkout - print ">>> starting initial cvs checkout with "+syncuri+"..." - if not portage.spawn("cd "+cvsdir+"; cvs -d "+cvsroot+" login",free=1): - print "!!! cvs login error; exiting." - sys.exit(1) - if os.path.exists(cvsdir+"/gentoo-x86"): - print "!!! existing",cvsdir+"/gentoo-x86 directory; exiting." - sys.exit(1) - if not portage.spawn("cd "+cvsdir+"; cvs -z0 -d "+cvsroot+" co gentoo-x86",free=1): - print "!!! cvs checkout error; exiting." - sys.exit(1) - if cvsdir!=myportdir: - portage.movefile(cvsdir,portage.settings["PORTDIR"]) - sys.exit(0) - else: - #cvs update - print ">>> starting cvs update with "+syncuri+"..." - sys.exit(portage.spawn("cd "+myportdir+"; cvs -z0 -q update -dP",free=1)) - else: - print "!!! rsync setting: ",syncuri,"not recognized; exiting." - sys.exit(1) - if os.path.exists(myportdir+"/metadata/cache"): - print "\n>>> Updating Portage cache... ", - os.umask(0002) - if os.path.exists(portage.dbcachedir): - portage.spawn("rm -Rf "+portage.dbcachedir,free=1) - try: - os.mkdir(portage.dbcachedir) - os.chown(portage.dbcachedir, os.getuid(), portage.portage_gid) - os.chmod(portage.dbcachedir, 06775) - os.umask(002) - except: - pass - mynodes=portage.portdb.cp_all() - for x in mynodes: - myxsplit=x.split("/") - if not os.path.exists(portage.dbcachedir+"/"+myxsplit[0]): - os.mkdir(portage.dbcachedir+"/"+myxsplit[0]) - os.chown(portage.dbcachedir+"/"+myxsplit[0], os.getuid(), portage.portage_gid) - os.chmod(portage.dbcachedir+"/"+myxsplit[0], 06775) - mymatches=portage.portdb.xmatch("match-all",x) - for y in mymatches: - update_spinner() - try: - ignored=portage.portdb.aux_get(y,[],metacachedir=myportdir+"/metadata/cache") - except: - pass - portage.spawn("chmod -R g+rw "+portage.dbcachedir, free=1) - sys.stdout.write("\b\b ...done!\n\n") - sys.stdout.flush() - - portage.portageexit() - reload(portage) - mybestpv=portage.portdb.xmatch("bestmatch-visible","sys-apps/portage") - mypvs=portage.best(portage.db[portage.root]["vartree"].dbapi.match("sys-apps/portage")) - - if(mybestpv != mypvs): + print turquoise("Actions:") + print " "+green("clean")+" ("+green("-c")+" short option)" + print " Cleans the system by removing outdated packages which will not" + print " remove functionalities or prevent your system from working." + print " The arguments can be in several different formats :" + print " * world " + print " * system " + print " * /var/db/pkg/category/package-version, or" + print " * 'dependency specification' (in single quotes is best.)" + print " Here are a few examples of the dependency specification format:" + print " "+bold("binutils")+" matches" + print " binutils-2.11.90.0.7 and binutils-2.11.92.0.12.3-r1" + print " "+bold(">binutils-2.11.90.0.7")+" matches" + print " binutils-2.11.92.0.12.3-r1" + print " "+bold("sys-devel/binutils")+" matches" + print " binutils-2.11.90.0.7 and binutils-2.11.92.0.12.3-r1" + print " "+bold("sys-devel/binutils-2.11.90.0.7")+" matches" + print " binutils-2.11.90.0.7" + print " "+bold(">sys-devel/binutils-2.11.90.0.7")+" matches" + print " binutils-2.11.92.0.12.3-r1" + print " "+bold(">=sys-devel/binutils-2.11.90.0.7")+" matches" + print " binutils-2.11.90.0.7 and binutils-2.11.92.0.12.3-r1" + print " "+bold("","<","=","!"]: - print "!!! '"+x+"' is an invalid specification." - print "!!! Must be 'category/package-version' with no other symbols." - print - continue - mycps=portage.catpkgsplit(x) - if (not mycps) or (mycps[0]=="null"): - print "!!!",x,"is not a specific cat/pkg-version, skipping..." - continue - if portage.db["/"]["vartree"].exists_specific(x): - print "!!! Not injecting",x+"; Package already exists." - else: - portage.db["/"]["vartree"].dbapi.cpv_inject(x) - print ">>> Injected",x+"." - emergelog(" === inject: "+x) -elif "unmerge"==myaction or "prune"==myaction or "clean"==myaction: - if 1==unmerge(myaction, myfiles): - post_emerge() - -elif "depclean"==myaction: - # Kill packages that aren't explicitly merged or are required as a - # dependency of another package. World file is explicit. - - print - print red("*** WARNING ***")+" : DEPCLEAN CAN SERIOUSLY IMPAIR YOUR SYSTEM. USE CAUTION." - print red("*** WARNING ***")+" : (Cancel: CONTROL-C) -- ALWAYS VERIFY ALL PACKAGES IN THE" - print red("*** WARNING ***")+" : CANDIDATE LIST FOR SANITY BEFORE ALLOWING DEPCLEAN TO" - print red("*** WARNING ***")+" : UNMERGE ANY PACKAGES." - print red("*** WARNING ***")+" :" - print red("*** WARNING ***")+" : USE FLAGS MAY HAVE AN EXTREME EFFECT ON THE OUTPUT." - print red("*** WARNING ***")+" : SOME LIBRARIES MAY BE USED BY PACKAGES BUT ARE NOT" - print red("*** WARNING ***")+" : CONSIDERED TO BE A DEPEND DUE TO USE FLAG SETTINGS." - print red("*** WARNING ***")+" :" - print red("*** WARNING ***")+" : Packages in the list that are desired may be added" - print red("*** WARNING ***")+" : directly to the world file to cause them to be ignored" - print red("*** WARNING ***")+" : by depclean and maintained in the future. BREAKAGES DUE" - print red("*** WARNING ***")+" : TO UNMERGING AN ==IN-USE LIBRARY== MAY BE REPAIRED BY" - print red("*** WARNING ***")+" : MERGING *** THE PACKAGE THAT COMPLAINS *** ABOUT THE" - print red("*** WARNING ***")+" : MISSING LIBRARY." - print - if not "--pretend" in myopts: - countdown(10, ">>> Depclean") - emergelog(" >>> depclean") - - mydepgraph=depgraph(myaction,myopts) - syslist=getlist("system") - worldlist=getlist("world") - - print "Calculating",myaction,"dependencies ", - if not mydepgraph.xcreate("world"): - print "\n!!! Failed to create deptree." - sys.exit(1) - print "\b\b ... done!" - - if ("--usepkgonly" in myopts) and mydepgraph.missingbins: - sys.stderr.write(red("The following binaries are not available for merging...\n")) - for x in mydepgraph.missingbins: - sys.stderr.write(" "+str(x)+"\n") - sys.stderr.write("\nThese are required by '--usepkgonly' -- Terminating.\n\n") - sys.exit(1) - - alldeps=mydepgraph.digraph.allnodes() - myvarlist=portage.vardbapi(portage.root).cp_all() - - if not syslist: - print "!!! You have no system list. Cannot determine system from world." - if not worldlist: - print "!!! You have no world file. Cannot determine explicit merges." - if not myvarlist: - print "!!! You have no /var/db tree. This is a problem." - if not alldeps: - print "!!! You have no dependencies. Impossible. Bug." - - if not (syslist and worldlist and myvarlist and alldeps): + print " "+green("info") + print " Displays important portage variables that will be exported to" + print " ebuild.sh when performing merges. This information is useful" + print " for bug reports and verification of settings. All settings in" + print " make.{conf,globals,defaults} and the environment show up if" + print " run with the '--verbose' flag." print - sys.exit(1) - - reallist=[] - for x in alldeps: - myparts=portage.catpkgsplit(string.split(x)[2]) - if not myparts: - sys.stderr.write( - red("!!! There appears to be a problem with the following package:\n")+ - red("!!! "+str(string.split(x)[2])+"\n\n")+ - "!!! Please ensure that blocking/conflicting packages are not merged."+ - "!!! 'emerge -p "+str(string.split(x)[2])+"\n\n") - if "--pretend" not in myopts: - countdown(15, "*** Continuing") - continue - - catpack=myparts[0]+"/"+myparts[1] - if catpack not in reallist: - reallist.append(catpack) - - cleanlist=[] - for x in myvarlist: - if x not in reallist: - if x not in cleanlist: - cleanlist.append(x) - - for x in syslist+worldlist: - myparts = portage.catpkgsplit(x) - if myparts: - if myparts[0][0] in ('<','>','='): - myparts[0] = myparts[0][1:] - if myparts[0][0] in ('<','>','='): - myparts[0] = myparts[0][1:] - catpack=myparts[0]+"/"+myparts[1] - else: - catpack=x - if catpack in cleanlist: - cleanlist.remove(catpack) - - #print "\n\n\nCleaning: " - #for x in cleanlist: - # print x - #print + print " "+green("inject")+" ("+green("-i")+" short option)" + print " Add a stub entry for a package so that Portage thinks that it's" + print " installed when it really isn't. Handy if you roll your own" + print " packages. Example: " + #NOTE: this next line *needs* the "sys-kernel/"; *please* don't remove it! + print " "+bold("emerge inject sys-kernel/gentoo-sources-2.4.19") + print + print " "+green("prune")+" ("+green("-P")+" short option)" + print " "+turquoise("WARNING: This action can remove important packages!") + print " Removes all older versions of a package from your system." + print " This action doesn't always verify the possible binary" + print " incompatibility between versions and can thus remove essential" + print " dependencies from your system." + print " The argument format is the same as for the "+bold("clean")+" action." + print + print " "+green("regen") + print " Causes portage to check and update the dependency cache of all" + print " ebuilds in the portage tree. This is not recommended for rsync" + print " users as rsync updates the cache using server-side caches." + print " Rsync users should simply 'emerge sync' to regenerate." + print + print " "+green("search")+" ("+green("-s")+" short option)" + print " searches for matches of the supplied string in the current local" + print " portage tree. The search string is a regular expression." + print " A few examples: " + print " "+bold("emerge search '^kde'") + print " list all packages starting with kde" + print " "+bold("emerge search 'gcc$'") + print " list all packages ending with gcc" + print " "+bold("emerge search ''")+" or" + print " "+bold("emerge search '.*'") + print " list all available packages " + print + print " "+green("unmerge")+" ("+green("-C")+" short option)" + print " "+turquoise("WARNING: This action can remove important packages!") + print " Removes all matching packages without checking for outdated" + print " versions, effectively removing a package "+bold("completely")+" from" + print " your system. Specify arguments using the dependency specification" + print " format described in the "+bold("clean")+" action above." + print + print turquoise("Options:") + print " "+green("--build-package")+" ("+green("-b")+" short option)" + print " tell emerge to build binary packages for all ebuilds processed" + print " (in addition to actually merging the packages. Useful for" + print " maintainers or if you administrate multiple Gentoo Linux" + print " systems (build once, emerge tbz2s everywhere)." + print + print " "+green("--build-package-only")+" ("+green("-B")+" short option)" + print " Creates binary a binary package, but does not merge it to the" + print " system. This has the restriction that unsatisfied dependencies" + print " must not exist for the desired package as they cannot be used if" + print " they do not exist on the system." + print + print " "+green("--changelog")+" ("+green("-l")+" short option)" + print " When pretending, also display the ChangeLog entries for packages" + print " that will be upgraded." + print + print " "+green("--columns") + print " Display the pretend output in a tabular form. Versions are" + print " aligned vertically." + print + print " "+green("--debug")+" ("+green("-d")+" short option)" + print " Tell emerge to run the ebuild command in --debug mode. In this" + print " mode, the bash build environment will run with the -x option," + print " causing it to output verbose debug information print to stdout." + print " --debug is great for finding bash syntax errors as providing" + print " very verbose information about the dependency and build process." + print + print " "+green("--deep")+" ("+green("-D")+" short option)" + print " When used in conjunction with --update, this flag forces emerge" + print " to consider the entire dependency tree of packages, instead of" + print " checking only the immediate dependencies of the packages. As an" + print " example, this catches updates in libraries that are not directly" + print " listed in the dependencies of a package." + print + print " "+green("--empty-tree")+" ("+green("-e")+" short option)" + print " Virtually tweaks the tree of installed packages to only contain" + print " glibc, this is great to use together with --pretend. This makes" + print " it possible for developers to get a complete overview of the" + print " complete dependency tree of a certain package." + print + print " "+green("--fetch-only")+" ("+green("-f")+" short option)" + print " Instead of doing any package building, just perform fetches for" + print " all packages (main package as well as all dependencies.) When" + print " used in combination with --pretend all the SRC_URIs will be" + print " displayed multiple mirrors per line, one line per file." + print + print " "+green("--get-binary-package")+" ("+green("-g")+" short option)" + print " Using the server and location defined in PORTAGE_BINHOST, portage" + print " will download the information from each binary file there and it" + print " will use that information to help build the dependency list. This" + print " option implies '-k'. (Use -gK for binary-only merging.)" + print + print " "+green("--get-binary-package-only")+" ("+green("-G")+" short option)" + print " This option is identical to -g, as above, except it will not use" + print " ANY information from the local machine. All binaries will be" + print " downloaded from the remote server without consulting packages" + print " existing in the packages directory." + print + print " "+green("--forget-configuration") + print " Portage keeps track of files that have been placed into" + print " CONFIG_PROTECT directories, and normally it will not merge the" + print " same file more than once, as that would become annoying. This" + print " can lead to problems when the user wants the file in the case" + print " of accidental deletion. With this option, files will always be" + print " merged to the live fs instead of silently dropped." + print + print " "+green("--no-dependencies")+" ("+green("-O")+" short option)" + print " Merge specified packages, but don't merge any dependencies." + print " Note that the build may fail if deps aren't satisfied." + print + print " "+green("--no-replace")+" ("+green("-n")+" short option)" + print " Skip the packages specified on the command-line that have" + print " already been installed. Without this option, any packages," + print " ebuilds, or deps you specify on the command-line *will* cause" + print " Portage to remerge the package, even if it is already installed." + print " Note that Portage won't remerge dependencies by default." + print + print " "+green("--no-spinner") + print " Disables the spinner regardless of terminal type." + print + print " "+green("--once-only") + print " Emerge as normal, but don't add packages to the world profile for" + print " later updating. This prevents consideration of this package" + print " unless this package is depended upon by another package." + print + print " "+green("--dependencies-only")+" ("+green("-o")+" short option)" + print " Only merge (or pretend to merge) the dependencies of the" + print " specified packages, not the packages themselves." + print + print " "+green("--pretend")+" ("+green("-p")+" short option)" + print " instead of actually performing the merge, simply display what" + print " ebuilds and tbz2s *would* have been installed if --pretend" + print " weren't used. Using --pretend is strongly recommended before" + print " installing an unfamiliar package. In the printout, N = new," + print " U = updating, R = replacing, B = blocked by an already installed" + print " package, D = possible downgrading. --verbose causes affecting" + print " use flags to be printed out accompanied by a '+' for enabled" + print " and a '-' for disabled flags." + print + print " "+green("--quiet")+" ("+green("-q")+" short option)" + print " Effects vary, but the general outcome is a reduced or condensed" + print " output from portage's displays." + print + print " "+green("--resume") + print " Resumes the last merge operation. Can be treated just like a" + print " regular merge as --pretend and other options work along side." + print " 'emerge --resume' only returns an error on failure. Nothing to" + print " do exits with a message and a success condition." + print + print " "+green("--search-description")+" ("+green("-S")+" short option)" + print " Matches the search string against the description field as well" + print " the package's name. Take caution as the descriptions are also" + print " matched as regular expressions." + print " emerge -S html" + print " emerge -S applet" + print " emerge -S 'perl.*module'" + print + print " "+green("--skip-first") + print " This option is only valid in a resume situation. It removes the" + print " first package in the resume list so that a merge may continue in" + print " the presence of an uncorrectable or inconsequential error. This" + print " should only be used in cases where skipping the package will not" + print " result in failed dependencies." + print + print " "+green("--update")+" ("+green("-u")+" short option)" + print " Updates packages to the best version available, which may not" + print " always be the highest version number due to masking for testing" + print " and development." + print + print " "+green("--upgrade-only")+" ("+green("-U")+" short option)" + print " Updates packages, but excludes updates that would result in a" + print " lower version of the package being installed. SLOTs are" + print " considered at a basic level." + print + print " "+green("--use-package")+" ("+green("-k")+" short option)" + print " Tell emerge to use binary packages (from $PKGDIR) if they are" + print " available, thus possibly avoiding some time-consuming compiles." + print " This option is useful for CD installs; you can export" + print " PKGDIR=/mnt/cdrom/packages and then use this option to have" + print " emerge \"pull\" binary packages from the CD in order to satisfy" + print " dependencies." + print + print " "+green("--use-package-only")+" ("+green("-K")+" short option)" + print " Like --use-package above, except this only allows the use of binary" + print " packages, and it will abort the emerge if the package is not" + print " available at the time of dependency calculation." + print + print " "+green("--verbose")+" ("+green("-v")+" short option)" + print " Effects vary, but the general outcome is an increased or expanded" + print " display of content in portage's displays." + print + print " "+green("--version")+" ("+green("-V")+" short option)" + print " Displays the currently installed version of portage along with" + print " other information useful for quick reference on a system. See" + print " "+bold("emerge info")+" for more advanced information." + print + elif myaction in ["rsync","sync"]: + print + print bold("Usage: ")+turquoise("emerge")+" "+turquoise("sync") + print + print " 'emerge sync' tells emerge to update the Portage tree as specified in" + print " The SYNC variable found in /etc/make.conf. By default, SYNC instructs" + print " emerge to perform an rsync-style update with rsync.gentoo.org." + # Available" + #print " sync methods are rsync and anoncvs. To use anoncvs rather than rsync," + #print " put 'SYNC=\"cvs://:pserver:cvs.gentoo.org:/home/cvsroot\" in your" + #print " /etc/make.conf. If you haven't used anoncvs before, you'll be prompted" + #print " for a password, which for cvs.gentoo.org is empty (just hit enter.)" + print + print " 'emerge-webrsync' exists as a helper app to emerge sync, providing a" + print " method to receive the entire portage tree as a tarball that can be" + print " extracted and used. First time syncs would benefit greatly from this." + print + print " "+turquoise("WARNING:") + print " If using our rsync server, emerge will clean out all files that do not" + print " exist on it, including ones that you may have created." + print + elif myaction=="system": + print + print bold("Usage: ")+turquoise("emerge")+" [ "+green("options")+" ] "+turquoise("system") + print + print " \"emerge system\" is the Portage system update command. When run, it" + print " will scan the etc/make.profile/packages file and determine what" + print " packages need to be installed so that your system meets the minimum" + print " requirements of your current system profile. Note that this doesn't" + print " necessarily bring your system up-to-date at all; instead, it just" + print " ensures that you have no missing parts. For example, if your system" + print " profile specifies that you should have sys-apps/iptables installed" + print " and you don't, then \"emerge system\" will install it (the most" + print " recent version that matches the profile spec) for you. It's always a" + print " good idea to do an \"emerge --pretend system\" before an \"emerge" + print " system\", just so you know what emerge is planning to do." + print + elif myaction=="config": + outstuff=green("Config file management support (preliminary)")+""" - if len(cleanlist): - unmerge("unmerge", cleanlist) +Portage has a special feature called "config file protection". The purpose of +this feature is to prevent new package installs from clobbering existing +configuration files. By default, config file protection is turned on for /etc +and the KDE configuration dirs; more may be added in the future. - print - print "Packages installed: "+str(len(myvarlist)) - print "Packages in world: "+str(len(worldlist)) - print "Packages in system: "+str(len(syslist)) - print "Unique package names: "+str(len(reallist)) - print "Required packages: "+str(len(alldeps)) - if "--pretend" in myopts: - print "Number to remove: "+str(len(cleanlist)) - else: - print "Number removed: "+str(len(cleanlist)) +When Portage installs a file into a protected directory tree like /etc, any +existing files will not be overwritten. If a file of the same name already +exists, Portage will change the name of the to-be- installed file from 'foo' to +'._cfg0000_foo'. If '._cfg0000_foo' already exists, this name becomes +'._cfg0001_foo', etc. In this way, existing files are not overwritten, +allowing the administrator to manually merge the new config files and avoid any +unexpected changes. - post_emerge() +In addition to protecting overwritten files, Portage will not delete any files +from a protected directory when a package is unmerged. While this may be a +little bit untidy, it does prevent potentially valuable config files from being +deleted, which is of paramount importance. -# "update", "system", or just process files: -else: - favorites=[] - syslist=getlist("system") - if ("--pretend" in myopts) and not ("--fetchonly" in myopts): - print - print darkgreen("These are the packages that I would merge, in order:") - print - if ("--resume" in myopts) and portage.mtimedb.has_key("resume"): - myresumeopts=portage.mtimedb["resume"]["myopts"][:] - for myopt in myopts: - if myopt not in myresumeopts: - myresumeopts.append(myopt) - myopts=myresumeopts - mydepgraph=depgraph("resume",myopts) - if "--resume" not in myopts: - myopts+=["--resume"] - else: - if ("--resume" in myopts): - del myopts[myopts.index("--resume")] - print darkgreen("emerge: It seems we have nothing to resume...") - sys.exit(0) +Protected directories are set using the CONFIG_PROTECT variable, normally +defined in /etc/make.globals. Directory exceptions to the CONFIG_PROTECTed +directories can be specified using the CONFIG_PROTECT_MASK variable. To find +files that need to be updated in /etc, type: - mydepgraph=depgraph(myaction,myopts) - if myaction in ["system","world"]: - print "Calculating",myaction,"dependencies ", - if not mydepgraph.xcreate(myaction): - print "!!! Depgraph creation failed." - sys.exit(1) - print "\b\b ...done!" - else: - if not myfiles: - print "emerge: please tell me what to do." - help() - sys.exit(1) - #we don't have any files to process; skip this step and exit - print "Calculating dependencies ", - retval,favorites=mydepgraph.select_files(myfiles) - if not retval: - print "\n!!! Error calculating dependencies. Please correct." - sys.exit(1) - print "\b\b ...done!" +# find /etc -iname '._cfg????_*' - if ("--usepkgonly" in myopts) and mydepgraph.missingbins: - sys.stderr.write(red("The following binaries are not available for merging...\n")) +You can disable this feature by setting CONFIG_PROTECT="-*" in /etc/make.conf. +Then, Portage will mercilessly auto-update your config files. Alternatively, +you can leave Config File Protection on but tell Portage that it can overwrite +files in certain specific /etc subdirectories. For example, if you wanted +Portage to automatically update your rc scripts and your wget configuration, +but didn't want any other changes made without your explicit approval, you'd +add this to /etc/make.conf: - if mydepgraph.missingbins: - for x in mydepgraph.missingbins: - sys.stderr.write(" "+str(x)+"\n") - sys.stderr.write("\nThese are required by '--usepkgonly' -- Terminating.\n\n") - sys.exit(1) +CONFIG_PROTECT_MASK="/etc/wget /etc/rc.d" - if ("--pretend" in myopts) and ("--fetchonly" not in myopts): - if ("--resume" in myopts): - mydepgraph.display(portage.mtimedb["resume"]["mergelist"]) - else: - mydepgraph.display(mydepgraph.altlist()) - else: - if ("--buildpkgonly" in myopts): - if not mydepgraph.digraph.hasallzeros(): - print "\n!!! --buildpkgonly requires all dependencies to be merged." - print "!!! Cannot merge requested packages. Merge deps and try again.\n" - sys.exit(1) +etc-update is also available to aid in the merging of these files. It provides +a vimdiff interactive merging setup and can auto-merge trivial changes. - if ("--resume" in myopts): - favorites=portage.mtimedb["resume"]["favorites"] - mydepgraph.merge(portage.mtimedb["resume"]["mergelist"]) - else: - portage.mtimedb["resume"]={} - portage.mtimedb["resume"]["myopts"]=myopts - portage.mtimedb["resume"]["favorites"]=favorites - if ("--digest" in myopts) and not ("--fetchonly" in myopts): - for pkgline in mydepgraph.altlist(): - if pkgline[0]=="ebuild" and pkgline[3]=="merge": - y=portage.portdb.findname(pkgline[2]) - retval=portage.doebuild(y,"digest",portage.root,edebug,("--pretend" in myopts)) - mydepgraph.merge(mydepgraph.altlist()) +""" + print outstuff - if portage.mtimedb.has_key("resume"): - del portage.mtimedb["resume"] - if portage.settings["AUTOCLEAN"] and "yes"==portage.settings["AUTOCLEAN"]: - print ">>> Auto-cleaning packages ..." - unmerge("clean", ["world"]) - post_emerge()