Index: portage-2.1.0_alpha20050718/bin/emerge =================================================================== --- portage-2.1.0_alpha20050718.orig/bin/emerge +++ portage-2.1.0_alpha20050718/bin/emerge @@ -21,64 +21,95 @@ import portage_exec, sync from portage_dep import DependencyGraph import portage_dep, portage_versions +def emergeexitsig(signum, frame): + signal.signal(signal.SIGINT, signal.SIG_IGN) + portage.portageexit() + portage_util.writemsg("\n\nExiting on signal %(signal)s\n" % {"signal":signum}) + sys.exit(100+signum) +signal.signal(signal.SIGINT, emergeexitsig) -spinner_msgs = ["Gentoo Rocks ("+os.uname()[0]+")", - "Thank you for using Gentoo. :)", - "Are you actually trying to read this?", - "How many times have you stared at this?", - "We are generating the cache right now", - "You are paying too much attention.", - "A theory is better than its explanation.", - "Phasers locked on target, Captain.", - "Thrashing is just virtual crashing.", - "To be is to program.", - "Real Users hate Real Programmers.", - "When all else fails, read the instructions.", - "Functionality breeds Contempt.", - "The future lies ahead.", - "3.1415926535897932384626433832795028841971694", - "Sometimes insanity is the only alternative.", - "Inaccuracy saves a world of explanation.", - ] - - -def update_basic_spinner(): - global spinner, spinpos - spinpos = (spinpos+1) % 500 - if (spinpos % 100) == 0: - if spinpos == 0: - sys.stdout.write(". ") - else: - sys.stdout.write(".") - sys.stdout.flush() - -def update_scroll_spinner(): - global spinner, spinpos - if(spinpos >= len(spinner)): - sys.stdout.write(darkgreen(" \b\b\b"+spinner[len(spinner)-1-(spinpos%len(spinner))])) - else: - sys.stdout.write(green("\b "+spinner[spinpos])) - sys.stdout.flush() - spinpos = (spinpos+1) % (2*len(spinner)) - -def update_twirl_spinner(): - global spinner, spinpos - spinpos = (spinpos+1) % len(spinner) - sys.stdout.write("\b\b "+spinner[spinpos]) - sys.stdout.flush() - -spinpos = 0 -spinner = "/-\\|/-\\|/-\\|/-\\|\\-/|\\-/|\\-/|\\-/|" -update_spinner = update_twirl_spinner -if "candy" in portage.settings.features: - spinner = spinner_msgs[int(time.time()*100)%len(spinner_msgs)] - update_spinner = update_scroll_spinner -if not sys.stdout.isatty() or ("--nospinner" in sys.argv): - update_spinner = update_basic_spinner +def emergelog(edebug,mystr,short_msg=None): + if "notitles" not in portage.features: + if short_msg: + xtermTitle(short_msg) + else: + xtermTitle(mystr) + try: + #seems odd opening a file each write... + if not os.path.exists("/var/log/emerge.log"): + mylogfile=open("/var/log/emerge.log", "w") + os.chmod("/var/log/emerge.log", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) + os.chown("/var/log/emerge.log", portage.portage_uid, portage.portage_gid) + else: + mylogfile=open("/var/log/emerge.log", "a") + + l=portage_locks.lockfile(mylogfile) + # seek because we may have gotten held up by the lock. + # if so, we may not be positioned at the end of the file. + mylogfile.seek(0,2) + mylogfile.write(str(time.time())[:10]+": "+mystr+"\n") + mylogfile.flush() + portage_locks.unlockfile(l) + mylogfile.close() + except SystemExit, e: + raise # Needed else can't exit + except Exception, e: + if edebug: + print "emergelog():",e + pass -if (not sys.stdout.isatty()) or (portage.settings["NOCOLOR"] in ["yes","true"]): - nocolor() +class stdout_spinner: + + def __init__(self): + spinner_msgs = ["Gentoo Rocks ("+os.uname()[0]+")", + "Thank you for using Gentoo. :)", + "Are you actually trying to read this?", + "How many times have you stared at this?", + "We are generating the cache right now", + "You are paying too much attention.", + "A theory is better than its explanation.", + "Phasers locked on target, Captain.", + "Thrashing is just virtual crashing.", + "To be is to program.", + "Real Users hate Real Programmers.", + "When all else fails, read the instructions.", + "Functionality breeds Contempt.", + "The future lies ahead.", + "3.1415926535897932384626433832795028841971694", + "Sometimes insanity is the only alternative.", + "Inaccuracy saves a world of explanation.", + ] + + self.spinpos = 0 + self.spinner = "/-\\|/-\\|/-\\|/-\\|\\-/|\\-/|\\-/|\\-/|" + self.update_spinner = self.update_twirl_spinner + + if "candy" in portage.settings.features: + self.spinner = spinner_msgs[int(time.time()*100)%len(spinner_msgs)] + self.update_spinner = self.update_scroll_spinner + + def update_basic_spinner(self): + self.spinpos = (self.spinpos+1) % 500 + if (self.spinpos % 100) == 0: + if self.spinpos == 0: + sys.stdout.write(". ") + else: + sys.stdout.write(".") + sys.stdout.flush() + + def update_scroll_spinner(self): + if(self.spinpos >= len(self.spinner)): + sys.stdout.write(darkgreen(" \b\b\b"+self.spinner[len(self.spinner)-1-(self.spinpos%len(self.spinner))])) + else: + sys.stdout.write(green("\b "+self.spinner[self.spinpos])) + sys.stdout.flush() + self.spinpos = (self.spinpos+1) % (2*len(self.spinner)) + + def update_twirl_spinner(self): + self.spinpos = (self.spinpos+1) % len(self.spinner) + sys.stdout.write("\b\b "+self.spinner[self.spinpos]) + sys.stdout.flush() def normpath(mystr): if mystr and (mystr[0]=='/'): @@ -120,307 +151,6 @@ def userquery(prompt, responses=None, co print "Interrupted." sys.exit(1) -if portage.settings.has_key("PORTAGE_NICENESS"): - try: - os.nice(int(portage.settings["PORTAGE_NICENESS"])) - except SystemExit, e: - raise # Needed else can't exit - 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: - portage.features.remove('noauto') - -#number of ebuilds merged -merged=0 -params=["selective", "deep", "self", "recurse", "empty"] -actions=[ -"clean", "config", "depclean", -"info", "inject", "metadata", -"prune", "regen", "rsync", "search", -"sync", "system", "unmerge", "world", -] -options=[ -"--ask", -"--buildpkg", "--buildpkgonly", -"--changelog", "--columns", -"--debug", "--deep", -"--digest", -"--emptytree", -"--fetchonly", "--fetch-all-uri", -"--getbinpkg", "--getbinpkgonly", -"--help", "--noconfmem", -"--newuse", -"--nodeps", "--noreplace", -"--nospinner", "--oneshot", -"--onlydeps", "--pretend", -"--quiet", "--resume", -"--searchdesc", "--selective", -"--skipfirst", -"--tree", -"--update", -"--usepkg", "--usepkgonly", -"--verbose", "--version" -] - -shortmapping={ -"1":"--oneshot", -"a":"--ask", -"b":"--buildpkg", "B":"--buildpkgonly", -"c":"--clean", "C":"--unmerge", -"d":"--debug", "D":"--deep", -"e":"--emptytree", -"f":"--fetchonly", "F":"--fetch-all-uri", -"g":"--getbinpkg", "G":"--getbinpkgonly", -"h":"--help", -"k":"--usepkg", "K":"--usepkgonly", -"l":"--changelog", -"n":"--noreplace", "N":"--newuse", -"o":"--onlydeps", "O":"--nodeps", -"p":"--pretend", "P":"--prune", -"q":"--quiet", -"s":"--search", "S":"--searchdesc", -'t':"--tree", -"u":"--update", -"v":"--verbose", "V":"--version" -} - -myaction=None -myopts=[] -myfiles=[] -edebug=0 -verbosity=0 - -# process short actions -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]=="--verbose": - verbosity += 1 - elif 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 options and 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" or x=="rsync": - # "emerge --rsync" - print - print red("*** '--rsync' has been deprecated.") - print red("*** Please use '--sync' instead.") - print - 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": - # "emerge rsync" - print - print red("*** 'rsync' will now install the package rsync.") - print red("*** To sync the tree, please use '--sync' instead.") - print - myfiles.append(x) - continue - if 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 - elif x[-1]=="/": - # this little conditional helps tab completion - myfiles.append(x[:-1]) - else: - myfiles.append(x) - -if verbosity: - import portage_metadata - -if "moo" in myfiles: - print """ - - Gentoo (""" + os.uname()[0] + """) - - _______________________ -< Have you mooed today? > - ----------------------- - \ ^__^ - \ (oo)\_______ - (__)\ )\/\ - ||----w | - || || - -""" - -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) - -for x in myfiles: - if (x.endswith(".ebuild") or x.endswith(".tbz2")) and os.path.exists(os.path.abspath(x)): - print "emerging by path implies --oneshot... adding --oneshot to options." - print red("\n*** emerging by path is broken and may not always work!!!\n") - break - -if ("--tree" in myopts) and ("--columns" in myopts): - print "emerge: can't specify both of \"--tree\" and \"--columns\"." - 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") - -# --tree only makes sense with --pretend -if "--tree" in myopts and not (("--pretend" in myopts) or ("--ask" in myopts)): - print ">>> --tree implies --pretend... adding --pretend to options." - myopts.append("--pretend") - -# Also allow -S to invoke search action (-sS) -if ("--searchdesc" in myopts): - if myaction and myaction != "search": - myfiles.append(myaction) - if "--search" not in myopts: - myopts.append("--search") - myaction = "search" - -# Always try and fetch binary packages if FEATURES=getbinpkg -if ("getbinpkg" in portage.features): - myopts.append("--getbinpkg") - -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 -l to apply --pretend/-p, but if already in --ask mode -if ("--changelog" in myopts) and not (("--pretend" in myopts) or ("--ask" in myopts)): - print ">>> --changelog implies --pretend... adding --pretend to options." - myopts.append("--pretend") - -# Allow -p to remove --ask -if ("--pretend" in myopts) and ("--ask" in myopts): - print ">>> --pretend disables --ask... removing --ask from options." - myopts.remove("--ask") - -# forbid --ask when not in a terminal -# note: this breaks `emerge --ask | tee logfile`, but that doesn't work anyway. -if ("--ask" in myopts) and (not sys.stdout.isatty()): - portage.writemsg("!!! \"--ask\" should only be used in a terminal. Exiting.\n") - sys.exit(1) - -# Set so that configs will be merged regardless of remembered status -if ("--noconfmem" in myopts): - portage.settings.unlock() - portage.settings["NOCONFMEM"]="1" - portage.settings.backup_changes("NOCONFMEM") - portage.settings.lock() - -# Set various debug markers... They should be merged somehow. -if ("--debug" in myopts): - portage.settings.unlock() - portage.settings["PORTAGE_DEBUG"]="1" - portage.settings.backup_changes("PORTAGE_DEBUG") - portage.debug=1 - portage.settings.lock() - -CLEAN_DELAY = 5 -EMERGE_WARNING_DELAY = 10 -if portage.settings["CLEAN_DELAY"]: - CLEAN_DELAY = int("0"+portage.settings["CLEAN_DELAY"]) -if portage.settings["EMERGE_WARNING_DELAY"]: - EMERGE_WARNING_DELAY = int("0"+portage.settings["EMERGE_WARNING_DELAY"]) - - -def emergelog(mystr,short_msg=None): - if "notitles" not in portage.features: - if short_msg: - xtermTitle(short_msg) - else: - xtermTitle(mystr) - try: - #seems odd opening a file each write... - if not os.path.exists("/var/log/emerge.log"): - mylogfile=open("/var/log/emerge.log", "w") - os.chmod("/var/log/emerge.log", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) - os.chown("/var/log/emerge.log", portage.portage_uid, portage.portage_gid) - else: - mylogfile=open("/var/log/emerge.log", "a") - - l=portage_locks.lockfile(mylogfile) - # seek because we may have gotten held up by the lock. - # if so, we may not be positioned at the end of the file. - mylogfile.seek(0,2) - mylogfile.write(str(time.time())[:10]+": "+mystr+"\n") - mylogfile.flush() - portage_locks.unlockfile(l) - mylogfile.close() - except SystemExit, e: - raise # Needed else can't exit - except Exception, e: - if edebug: - print "emergelog():",e - pass - -def emergeexit(): - """This gets out final log message in before we quit.""" - if "--pretend" not in myopts: - emergelog(" *** terminating.") - if "notitles" not in portage.features: - xtermTitleReset() -atexit.register(emergeexit) - -def emergeexitsig(signum, frame): - signal.signal(signal.SIGINT, signal.SIG_IGN) - portage.portageexit() - portage_util.writemsg("\n\nExiting on signal %(signal)s\n" % {"signal":signum}) - sys.exit(100+signum) -signal.signal(signal.SIGINT, emergeexitsig) - def countdown(secs=5, doing="Starting"): if secs: print ">>> Waiting",secs,"seconds before starting..." @@ -541,85 +271,6 @@ def getportageversion(): return "Portage " + portage.VERSION +" ("+profilever+", "+gccver+", "+libcver+", "+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 ("--fetchonly" in myopts or "--fetch-all-uri" 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", "info", "regen", "metadata"]: - pass - elif (not myaction) and (not myfiles): - pass - elif ("--pretend" in myopts) and (myaction in ["world","system","clean","prune","unmerge"]): - pass - else: - if "--debug" in myopts: - 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=" ".join(myopts) - if myaction: - myelogstr+=" "+myaction - if myfiles: - myelogstr+=" "+" ".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) - # search functionality class search: @@ -632,19 +283,22 @@ class search: # # public interface # - def __init__(self): + def __init__(self,myopts,edebug,verbosity,spinner): """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"] + self.myopts=myopts + self.edebug=edebug + self.verbosity=verbosity + self.spinner=spinner def execute(self,searchkey): """Performs the search for the supplied search key""" - global myopts match_category = 0 self.searchkey=searchkey self.packagematches = [] - if "--searchdesc" in myopts: + if "--searchdesc" in self.myopts: self.searchdesc=1 self.matches = {"pkg":[], "desc":[]} else: @@ -663,7 +317,7 @@ class search: self.searchkey=re.sub("\+\+","\+\+",self.searchkey) self.searchre=re.compile(self.searchkey.lower(),re.I) for package in portage.portdb.cp_all(): - update_spinner() + self.spinner.update_spinner() if match_category: match_string = package[:] @@ -746,18 +400,18 @@ class search: except SystemExit, e: raise # Needed else can't exit except Exception, e: - if edebug: + if self.edebug: print "!!! Exception:",e mysum[0]=" [no/bad digest]" - if "--quiet" not in myopts: + if "--quiet" not in self.myopts: print " ", darkgreen("Latest version available:"),myversion print " ", self.getInstallationStatus(mycat+'/'+mypkg) print " ", darkgreen("Size of downloaded files:"),mysum[0] print " ", darkgreen("Homepage:")+" ",homepage print " ", darkgreen("Description:"),desc print " ", darkgreen("License:")+" ",license - if (verbosity): + if (self.verbosity): # show herd/maintainers if verbosity>=1 (ie: -vv) metadata_file=portage.settings["PORTDIR"] + "/" + match + "/metadata.xml" if not os.path.exists(metadata_file): @@ -835,11 +489,15 @@ def genericdict(mylist): mynewdict[portage.portage_dep.dep_getkey(x)]=x return mynewdict -olddbapi=None class depgraph: - def __init__(self,myaction,myopts): - global olddbapi + def __init__(self,myaction,myopts,myparams,edebug,verbosity,EMERGE_WARNING_DELAY,spinner): + self.myparams=myparams + self.myopts=myopts + self.edebug=edebug + self.verbosity=verbosity + self.EMERGE_WARNING_DELAY=EMERGE_WARNING_DELAY + self.spinner=spinner 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")) @@ -854,17 +512,17 @@ class depgraph: self.outdatedpackages=[] self.mydbapi={} self.mydbapi["/"] = portage.fakedbapi() - if "empty" not in myparams: + if "empty" not in self.myparams: 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: + 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 myopts: - portage.db["/"]["bintree"].populate(("--getbinpkg" in myopts), ("--getbinpkgonly" in myopts)) + 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 @@ -887,7 +545,7 @@ class depgraph: #this conditional is needed to prevent infinite recursion on already-processed deps return 1 - update_spinner() + self.spinner.update_spinner() mytype,myroot,mykey=mybigkey # select the correct /var database that we'll be checking against @@ -914,13 +572,13 @@ class depgraph: # 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)): + 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 myparams) and vardbapi.cpv_exists(mykey): + elif ("selective" in self.myparams) and vardbapi.cpv_exists(mykey): merging=0 - if (merging==0 and "--newuse" in myopts and vardbapi.cpv_exists(mykey)): + if (merging==0 and "--newuse" in self.myopts and vardbapi.cpv_exists(mykey)): iuses=portage.portdb.aux_get(mykey, ["IUSE"])[0].split() old_use=vardbapi.aux_get(mykey, ["USE"])[0].split() now_use=self.pkgsettings["USE"].split() @@ -944,9 +602,9 @@ class depgraph: self.mynewgraph.add_node(" ".join(mybigkey)) if myparent: self.mynewgraph.add_relationship(myparent, " ".join(mybigkey)) - if ("deep" not in myparams) and (not merging): + if ("deep" not in self.myparams) and (not merging): return 1 - elif "recurse" not in myparams: + elif "recurse" not in self.myparams: return 1 edepend={} @@ -1022,9 +680,9 @@ class depgraph: 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): + if not self.create(["binary",portage.root,mykey],None,"--onlydeps" not in self.myopts): return (0,myfavorites) - elif not "--oneshot" in myopts: + elif not "--oneshot" in self.myopts: myfavorites.append(mykey) elif x[-7:]==".ebuild": x = os.path.realpath(x) @@ -1038,13 +696,13 @@ class depgraph: 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...") + countdown(self.EMERGE_WARNING_DELAY, "Continuing...") else: print red("\n*** "+x+" does not exist") sys.exit(1) - if not self.create(["ebuild",portage.root,mykey],None,"--onlydeps" not in myopts): + if not self.create(["ebuild",portage.root,mykey],None,"--onlydeps" not in self.myopts): return (0,myfavorites) - elif not "--oneshot" in myopts: + elif not "--oneshot" in self.myopts: myfavorites.append(mykey) else: try: @@ -1081,7 +739,7 @@ class depgraph: except SystemExit, e: raise # Needed else can't exit except Exception, e: - if "--debug" in myopts: + if "--debug" in self.myopts: raise print "\n\n!!! Problem in",mykey,"dependencies." print "!!!",str(e),e.__module__ @@ -1089,11 +747,11 @@ class depgraph: if not self.mysd: return (0,myfavorites) - elif not "--oneshot" in myopts: + elif not "--oneshot" in self.myopts: myfavorites.append(mykey) missing=0 - if "--usepkgonly" in myopts: + if "--usepkgonly" in self.myopts: for x in self.mynewgraph.get_all_nodes(): xs=x.split(" ") if (xs[0] != "binary") and (xs[3]=="merge"): @@ -1107,13 +765,13 @@ class depgraph: def select_dep(self,myroot,depstring,myparent=None,arg=None,myuse=None): "given a dependency string, create the appropriate depgraph and return 1 on success and 0 on failure" - if "--debug" in myopts: + 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=("--usepkg" in myopts)) + mycheck=portage.dep_check(depstring,self.mydbapi[myroot],self.pkgsettings,myuse=myuse,use_binaries=("--usepkg" in self.myopts)) #mycheck=portage.dep_check(depstring,self.mydbapi[myroot],self.pkgsettings,myuse=myuse) if not mycheck[0]: @@ -1141,14 +799,14 @@ class depgraph: if not mymerge: return 1 - if "--debug" in myopts: + 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 myopts: + if "--debug" in self.myopts: print "Myparent",myparent if (myparent): if myparent.split()[2] in portage.portdb.xmatch("match-all", x[1:]): @@ -1160,15 +818,15 @@ class depgraph: #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): + if ("--usepkgonly" not in self.myopts): myeb=portage.best(myeb_matches) myeb_pkg=None - if ("--usepkg" in myopts): + 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 myopts): + 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: @@ -1186,7 +844,7 @@ class depgraph: 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: + 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 = "" @@ -1211,7 +869,7 @@ class depgraph: print return 0 - if "--debug" in myopts: + if "--debug" in self.myopts: print "ebuild:",myeb print "binpkg:",myeb_pkg @@ -1253,10 +911,10 @@ class depgraph: 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): + if not self.create(myk,myparent,"--onlydeps" not in self.myopts,myuse=binpkguseflags): return 0 - if "--debug" in myopts: + if "--debug" in self.myopts: print "Exiting...",myparent return 1 @@ -1280,20 +938,19 @@ class depgraph: return retlist def xcreate(self,mode="system"): - global syslist if mode=="system": - mylist=syslist + mylist=getlist("system") else: #world mode worldlist=getlist("world") - sysdict=genericdict(syslist) + sysdict=genericdict(getlist("system")) 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 "empty" in self.myparams: if portage.db["/"]["vartree"].dbapi.match(x): sysdict[x]=worlddict[x] elif portage.db[portage.root]["vartree"].dbapi.match(x): @@ -1312,12 +969,12 @@ class depgraph: #THIS NEXT BUNCH OF CODE NEEDS TO BE REPLACED TO SUPPORT WORLD ANTI-DEPS #if mydep2[0]=="!":, etc. binpkguseflags = None - if "--usepkg" in myopts: + if "--usepkg" in self.myopts: mypk=portage.db[portage.root]["bintree"].dep_bestmatch(mydep) if myeb==mypk: myk=["binary",portage.root,mypk] binpkguseflags=portage.db[portage.root]["bintree"].get_use(mypk) - elif "--usepkgonly" in myopts: + elif "--usepkgonly" in self.myopts: if not mypk: self.missingbins += [myeb] myk=["binary",portage.root,myeb] @@ -1351,7 +1008,7 @@ class depgraph: print sys.exit(1) - if "--usepkg" in myopts: + if "--usepkg" in self.myopts: mypk=portage.db[portage.root]["bintree"].dep_bestmatch(mydep) if myeb==mypk: myk="binary "+portage.root+" "+mypk @@ -1367,7 +1024,7 @@ class depgraph: p=[] totalsize=0 - if verbosity: + if self.verbosity: overlays = portage.settings['PORTDIR_OVERLAY'].split() i = 0 @@ -1410,9 +1067,9 @@ class depgraph: #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]): + if (not "--emptytree" in self.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]): + 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": @@ -1432,7 +1089,7 @@ class depgraph: # New slot, mark it new. addl=" "+green("NS")+fetch+" " - if "--changelog" in myopts: + if "--changelog" in self.myopts: changelogs.extend(self.calc_changelog( portage.portdb.findname(x[2]), portage.db["/"]["vartree"].dep_bestmatch('/'.join(portage_versions.catpkgsplit(x[2])[:2])), @@ -1442,7 +1099,7 @@ class depgraph: addl=" "+green("N")+" "+fetch+" " verboseadd="" - if verbosity > 0: + if self.verbosity > 0: # iuse verbose try: if x[0] == "binary": @@ -1488,8 +1145,8 @@ class depgraph: else: iuse=blue("-"+ebuild_iuse) verboseadd+=iuse+usechange+" " - if (verbosity and "--pretend" not in myopts) or \ - (verbosity > 1 and "--pretend" in myopts): + if (self.verbosity and "--pretend" not in self.myopts) or \ + (self.verbosity > 1 and "--pretend" in self.myopts): # show herd/maintainers. metadata_file=portage.settings["PORTDIR"] + "/" + portage.portage_versions.pkgsplit(x[2])[0] + "/metadata.xml" if not os.path.exists(metadata_file): @@ -1513,7 +1170,7 @@ class depgraph: # 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) + myfilesdict=portage.portdb.getfetchsizes(x[2], useflags=self.applied_useflags[x[2]], debug=self.edebug) if myfilesdict==None: myfilesdict="[empty/missing/bad digest]" else: @@ -1558,7 +1215,7 @@ class depgraph: myoldbest=blue("["+myoldbest+"]") if x[1]!="/": - if "--columns" in myopts: + if "--columns" in self.myopts: myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0]) if (newlp-nc_len(myprint)) > 0: myprint=myprint+(" "*(newlp-nc_len(myprint))) @@ -1570,7 +1227,7 @@ class depgraph: else: myprint="["+x[0]+" "+addl+"] "+darkgreen(x[2])+" "+myoldbest+" "+darkgreen("to "+x[1])+" "+verboseadd else: - if "--columns" in myopts: + if "--columns" in self.myopts: myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0]) if (newlp-nc_len(myprint)) > 0: myprint=myprint+(" "*(newlp-nc_len(myprint))) @@ -1585,23 +1242,23 @@ class depgraph: myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(x[2])+" "+myoldbest+" "+verboseadd p.append(myprint) - if ("--tree" not in myopts): + if ("--tree" not in self.myopts): mysplit=portage_versions.pkgsplit(x[2]) # XXX mysplit _can_ be None.... Why? if mysplit and (len(mysplit)==3): - if "--emptytree" not in myopts: + if "--emptytree" not in self.myopts: if mysplit[0]=="sys-apps/portage": if (mysplit[1]+mysplit[2]!=portage.VERSION and "livecvsportage" not in portage.settings.features): if mylist.index(x)>> Recording",myfavkey,"in \"world\" favorites file..." - if not "--fetchonly" in myopts: + if not "--fetchonly" in self.myopts: portage.writedict(myfavdict,portage.root+portage.WORLD_FILE,writekey=0) portage.mtimedb["resume"]["mergelist"]=mymergelist[:] @@ -1759,7 +1416,7 @@ class depgraph: # parallel-fetch should only kick in when not pretending, emerge isn't just fetching, # and there is more then one node being processed. if "parallel-fetch" in self.pkgsettings["FEATURES"] and not \ - ("--ask" in myopts or "--pretend" in myopts or "--fetchonly" in myopts) and \ + ("--ask" in self.myopts or "--pretend" in self.myopts or "--fetchonly" in self.myopts) and \ len(mymergelist) > 1: if "distlocks" not in self.pkgsettings["FEATURES"]: print red("!!!") @@ -1780,7 +1437,7 @@ class depgraph: print ">>> parallel fetching is in the house, hizzay" print ">>> represent." portage_exec.spawn_func(self.__fetch,[mymergelist],{"verbosity":1,\ - "fetchall":("--fetchalluri" in myopts)},returnpid=True,fd_pipes={1:1,2:2}) + "fetchall":("--fetchalluri" in self.myopts)},returnpid=True,fd_pipes={1:1,2:2}) # time.sleep(2) mergecount=0 @@ -1791,9 +1448,9 @@ class depgraph: if x[0]=="blocks": pkgindex=3 y=portage.portdb.findname(x[pkgindex]) - if not "--pretend" in myopts: + if not "--pretend" in self.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]) + self.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") @@ -1802,43 +1459,43 @@ class depgraph: issyspkg = ("buildsyspkg" in myfeat) \ and x[0] != "blocks" \ and mysysdict.has_key(portage.cpv_getkey(x[2])) \ - and not ("--buildpkg" in myopts) + and not ("--buildpkg" in self.myopts) if x[0] in ["ebuild","blocks"]: - if (x[0]=="blocks") and ("--fetchonly" not in myopts): + if (x[0]=="blocks") and ("--fetchonly" not in self.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) + 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,self.edebug,("--pretend" in self.myopts),fetchonly=1,fetchall=1) else: - retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in myopts),fetchonly=1) + retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,self.edebug,("--pretend" in self.myopts),fetchonly=1) if retval: print print "!!! Fetch for",y,"failed, continuing..." print returnme=1 continue - elif "--buildpkg" in myopts or issyspkg: + 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) + self.emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) + retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,self.edebug,cleanup=1) if retval: sys.exit(1) 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) + self.emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Packaging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) + retval=portage.doebuild(y,"package",myroot,self.pkgsettings,self.edebug) if retval: sys.exit(1) #dynamically update our database - if "--buildpkgonly" not in myopts: + 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.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") @@ -1848,13 +1505,13 @@ class depgraph: sys.exit(1) 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) + self.emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) + retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,self.edebug,cleanup=1) if retval: sys.exit(1) 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) + self.emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) + retval=portage.doebuild(y,"merge",myroot,self.pkgsettings,self.edebug) if retval: sys.exit(1) #dynamically update our database @@ -1863,48 +1520,48 @@ class depgraph: 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) + self.emergelog(" --- ("+str(mergecount)+" of "+str(len(mymergelist))+") Fetching Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg) portage.db[portage.root]["bintree"].gettbz2(x[2]) - if ("--fetchonly" in myopts) or ("--fetch-all-uri" in myopts): + 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) + self.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==None: sys.exit(1) #need to check for errors - if "--buildpkgonly" not in myopts: + if "--buildpkgonly" not in self.myopts: portage.db[x[1]]["vartree"].inject(x[2]) myfavkey=portage.cpv_getkey(x[2]) - if (not "--fetchonly" in myopts) and (not "--fetch-all-uri" in myopts) and (myfavkey in favorites): + if (not "--fetchonly" in self.myopts) and (not "--fetch-all-uri" in self.myopts) and (myfavkey in favorites): myfavs=portage.grabfile(myroot+portage.WORLD_FILE) myfavdict=genericdict(myfavs) - mysysdict=genericdict(syslist) + mysysdict=genericdict(getlist("system")) #don't record if already in system profile or already recorded - if ("--update" not in myopts or not portage.db[portage.root]["vartree"].dbapi.match(myfavkey)) and \ + if ("--update" not in self.myopts or not portage.db[portage.root]["vartree"].dbapi.match(myfavkey)) and \ (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]+")") + self.emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Updating world file ("+x[pkgindex]+")") portage.writedict(myfavdict,myroot+portage.WORLD_FILE,writekey=0) if ("noclean" not in portage.features) and (x[0] != "binary"): short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean Post" - emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Post-Build Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) - retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1) + self.emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Post-Build Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg) + retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,self.edebug,cleanup=1) if retval: sys.exit(1) - if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts): + 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. xsplit=portage.portage_versions.pkgsplit(x[2]) - emergelog(" >>> AUTOCLEAN: "+xsplit[0]) - retval=unmerge("clean", [xsplit[0]]) + self.emergelog(" >>> AUTOCLEAN: "+xsplit[0]) + retval=self.unmerge("clean", [xsplit[0]]) if not retval: - emergelog(" --- AUTOCLEAN: Nothing unmerged.") + self.emergelog(" --- AUTOCLEAN: Nothing unmerged.") # Figure out if we need a restart. mysplit=portage.portage_versions.pkgsplit(x[2]) @@ -1925,7 +1582,7 @@ class depgraph: del myargv[myr] myr-=1 myr+=1 - emergelog(" *** RESTARTING emerge via exec() after change of portage version.") + self.emergelog(" *** RESTARTING emerge via exec() after change of portage version.") portage.portageexit() badlongopts = ["--ask","--tree","--changelog"] badshortopts = ["a","t","l"] @@ -1946,8 +1603,8 @@ class depgraph: mynewargv += [arg] os.execv("/usr/lib/portage/bin/emerge", mynewargv) - if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts): - emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1]) + if ("--pretend" not in self.myopts) and ("--fetchonly" not in self.myopts) and ("--fetch-all-uri" not in self.myopts): + self.emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1]) # Unsafe for parallel merges del portage.mtimedb["resume"]["mergelist"][0] @@ -1956,31 +1613,40 @@ class depgraph: self.thread.join() self.thread=None - emergelog(" *** Finished. Cleaning up...") + self.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 ("--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(portage.root) #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 "--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) + def emergelog(self,mystr,short_msg=None): + emergelog(self.edebug,mystr,short_msg) + + def unmerge(self,unmerge_action,unmerge_files): + return unmerge(self.myopts, self.edebug, self.EMERGE_WARNING_DELAY, unmerge_action, unmerge_files) + class graph_display: - def __init__(self, mygraph): + def __init__(self,mygraph,myopts,edebug,verbosity): self.graph = mygraph.clone() + self.myopts=myopts + self.edebug=edebug + self.verbosity=verbosity merge_nodes = self.graph.get_all_nodes() for x in range(len(merge_nodes)-1,-1,-1): @@ -2208,7 +1874,7 @@ class graph_display: def format_size(self, mydep): mysize = 0 if mydep[0] == "ebuild" and mydep[3] != "nomerge": - myfilesdict=portage.portdb.getfetchsizes(mydep[2], useflags=self.use_flags(mydep), debug=edebug) + myfilesdict=portage.portdb.getfetchsizes(mydep[2], useflags=self.use_flags(mydep), debug=self.edebug) if myfilesdict: for myfetchfile in myfilesdict.keys(): mysize += myfilesdict[myfetchfile] @@ -2308,13 +1974,13 @@ class graph_display: funclist = [self.format_summary, self.format_cpv, self.format_old_version] postfuncs = [] - if verbosity: + if self.verbosity: funclist += [self.format_flags] - if verbosity >= 2: + if self.verbosity >= 2: funclist += [self.format_metadata] funclist += [self.format_size, self.format_overlay] postfuncs += [self.post_size_msg, self.post_overlay_msg] - if "--changelog" in myopts: + if "--changelog" in self.myopts: funclist += [self.format_changelog] postfuncs += [self.post_changelog_msg] @@ -2344,13 +2010,13 @@ class graph_display: funclist = [self.format_summary, self.format_name, self.format_new_version, self.format_old_version] postfuncs = [] - if verbosity: + if self.verbosity: funclist += [self.format_flags] - if verbosity >= 2: + if self.verbosity >= 2: funclist += [self.format_metadata] funclist += [self.format_size, self.format_overlay] postfuncs += [self.post_size_msg, self.post_overlay_msg] - if "--changelog" in myopts: + if "--changelog" in self.myopts: funclist += [self.format_changelog] postfuncs += [self.post_changelog_msg] @@ -2394,13 +2060,13 @@ class graph_display: funclist = [self.format_cpv, self.format_old_version] postfuncs = [] - if verbosity: + if self.verbosity: funclist += [self.format_flags] - if verbosity >= 2: + if self.verbosity >= 2: funclist += [self.format_metadata] funclist += [self.format_size, self.format_overlay] postfuncs += [self.post_size_msg, self.post_overlay_msg] - if "--changelog" in myopts: + if "--changelog" in self.myopts: funclist += [self.format_changelog] postfuncs += [self.post_changelog_msg] @@ -2446,10 +2112,7 @@ class graph_display: if msg: print msg - - - -def unmerge(unmerge_action, unmerge_files): +def unmerge(myopts, edebug, EMERGE_WARNING_DELAY, unmerge_action, unmerge_files): candidate_catpkgs=[] global_unmerge=0 @@ -2460,8 +2123,7 @@ def unmerge(unmerge_action, unmerge_file if mycp in portage.settings.virtuals: syslist.extend(portage.settings.virtuals[mycp]) syslist.append(mycp) - - global myopts + mysettings = portage.config(clone=portage.settings) if not unmerge_files or "world" in unmerge_files or "system" in unmerge_files: @@ -2570,11 +2232,10 @@ def unmerge(unmerge_action, unmerge_file pkgmap[mykey]["selected"].append(y) numselected=numselected+len(mymatch) if not (pkgmap[mykey]["protected"] or pkgmap[mykey]["omitted"]) and \ - (mykey in syslist+["sys-apps/portage"]): + (mykey in syslist+["sys-apps/portage"]): print red("\a\n\n!!! Trying to unmerge package(s) in system profile. '%s'" % (mykey)) print yellow("\a!!! This could be damaging to your system.\n") if "--pretend" not in myopts: - global EMERGE_WARNING_DELAY countdown(EMERGE_WARNING_DELAY,red("Press Ctrl-C to Stop")) else: @@ -2615,8 +2276,8 @@ def unmerge(unmerge_action, unmerge_file for x in keys: for y in localtree.dep_match(x): if y not in pkgmap[x]["omitted"] and \ - y not in pkgmap[x]["selected"] and \ - y not in pkgmap[x]["protected"]: + y not in pkgmap[x]["selected"] and \ + y not in pkgmap[x]["protected"]: pkgmap[x]["omitted"].append(y) if global_unmerge and not pkgmap[x]["selected"]: #avoid cluttering the preview printout with stuff that isn't getting unmerged @@ -2655,20 +2316,22 @@ def unmerge(unmerge_action, unmerge_file return 0 #the real unmerging begins, after a short delay.... - global CLEAN_DELAY + CLEAN_DELAY = 5 + if portage.settings["CLEAN_DELAY"]: + CLEAN_DELAY = int("0"+portage.settings["CLEAN_DELAY"]) countdown(CLEAN_DELAY, ">>> Unmerging") for x in pkgmap.keys(): for y in pkgmap[x]["selected"]: print ">>> Unmerging "+y+"..." - emergelog("=== Unmerging... ("+y+")") + emergelog(edebug,"=== Unmerging... ("+y+")") mysplit=y.split("/") #unmerge... retval=portage.unmerge(mysplit[0],mysplit[1],portage.root,mysettings,unmerge_action not in ["clean","prune"]) if retval: - emergelog(" !!! unmerge FAILURE: "+y) + emergelog(edebug," !!! unmerge FAILURE: "+y) else: - emergelog(" >>> unmerge success: "+y) + emergelog(edebug," >>> unmerge success: "+y) #run ldconfig, etc... portage.env_update(portage.root) if not numselected: @@ -2676,7 +2339,6 @@ def unmerge(unmerge_action, unmerge_file else: return 1 - def chk_updated_info_files(): root=portage.root @@ -2759,22 +2421,6 @@ def chk_updated_info_files(): else: print " "+green("*")+" Processed",icount,"info files." - -def post_emerge(retval=0): - global myopts - os.chdir("/") - if "--pretend" in myopts: - sys.exit(retval) - - emergelog(" *** exiting successfully.") - - if "noinfo" not in portage.settings.features: - chk_updated_info_files() - - chk_updated_cfg_files() - - sys.exit(retval) - def chk_updated_cfg_files(): if portage.settings["CONFIG_PROTECT"]: #number of directories with some protect files in them @@ -2794,719 +2440,1107 @@ def chk_updated_cfg_files(): print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files." print -# general options that should be taken into account before any action -if "--debug" in myopts: - edebug=1 - -if myaction in ["sync","rsync","metadata"] and (not "--help" in myopts): - if "--pretend" in myopts: - print "emerge: \"sync\" actions do not support \"--pretend.\"" - sys.exit(1) - - emergelog(" === "+str(myaction)) - 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=portage.settings["SYNC"].rstrip() - os.umask(0022) - - sync_verbosity=0 - if "--quiet" in myopts: - sync_verbosity = 1 - elif "--verbose" in myopts: - sync_verbosity = 3 - else: - sync_verbosity = 2 - - print "sync_verbosity=",sync_verbosity - tmpservertimestampfile = None - - protocol,host_uri = sync.parseSyncUri(syncuri) - print "host_uri=",host_uri - - if myaction == "metadata": - if "--ask" in myopts: - if userquery("Are you sure?") == "No": - #userquery("Are you sure you should be using *NIX?",["Definately Not"]) - sys.exit(1) - print "skipping sync" - updatecache_flg = True - tmpservertimestampfile = None - elif protocol == "rsync": - mytimeout=180 - if portage.settings.has_key("RSYNC_TIMEOUT"): +class emerge_cmd: + + def __init__(self): + self.myaction=None + self.myopts=[] + self.myfiles=[] + self.myparams=None + self.edebug=0 + self.verbosity=0 + self.EMERGE_WARNING_DELAY = 10 + if portage.settings["EMERGE_WARNING_DELAY"]: + self.EMERGE_WARNING_DELAY = int("0"+portage.settings["EMERGE_WARNING_DELAY"]) + + spinner=stdout_spinner() + + if (not sys.stdout.isatty()) or (portage.settings["NOCOLOR"] in ["yes","true"]): + nocolor() + + if portage.settings.has_key("PORTAGE_NICENESS"): try: - mytimeout=int(portage.settings["RSYNC_TIMEOUT"]) + os.nice(int(portage.settings["PORTAGE_NICENESS"])) except SystemExit, e: raise # Needed else can't exit - except: - pass - - syncer=sync.rsync.RsyncHost(host_uri) - - servertimestampdir = portage.settings.depcachedir+"/" - servertimestampfile = portage.settings.depcachedir+"/timestamp.chk" - tmpservertimestampdir = portage.settings["PORTAGE_TMPDIR"]+"/" - tmpservertimestampfile = portage.settings["PORTAGE_TMPDIR"]+"/timestamp.chk" - - # We only use the backup if a timestamp exists in the portdir. - - content=None - if os.path.exists(myportdir+"/metadata/timestamp.chk"): - content=portage.grabfile(servertimestampfile) - if (not content): - content=portage.grabfile(myportdir+"/metadata/timestamp.chk") - - if (content): - try: - mytimestamp=time.mktime(time.strptime(content[0], "%a, %d %b %Y %H:%M:%S +0000")) - except ValueError: - mytimestamp=0 - else: - mytimestamp=0 - - if not os.path.exists(servertimestampdir): - os.mkdir(servertimestampdir) - os.chown(servertimestampdir, os.getuid(), portage.portage_gid) - os.chmod(servertimestampdir, 0775) - - #exitcode=0 - try: - maxretries=int(portage.settings["RSYNC_RETRIES"]) - except SystemExit, e: - raise # Needed else can't exit - except: - maxretries=3 #default number of retries - - retries=0 - updatecache_flg=True - - ips=syncer.get_ips() - if ips == None: - ips=[None] - while (1): - if (retries==0): - if "--ask" in myopts: - if userquery("Do you want to sync your Portage tree with the mirror %s at %s\n" \ - % (host_uri, blue(str(ips[0])))+bold("?"))=="No": + 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: + portage.features.remove('noauto') + + def emergelog(self,mystr,short_msg=None): + emergelog(self.edebug,mystr,short_msg) + + def help(self): + # Move all the help stuff out of this file. + emergehelp.help(self.myaction,self.myopts,havecolor) + + def parse_args(self,args): + + actions=[ + "clean", "config", "depclean", + "info", "inject", "metadata", + "prune", "regen", "rsync", "search", + "sync", "system", "unmerge", "world", + ] + options=[ + "--ask", + "--buildpkg", "--buildpkgonly", + "--changelog", "--columns", + "--debug", "--deep", + "--digest", + "--emptytree", + "--fetchonly", "--fetch-all-uri", + "--getbinpkg", "--getbinpkgonly", + "--help", "--noconfmem", + "--newuse", + "--nodeps", "--noreplace", + "--nospinner", "--oneshot", + "--onlydeps", "--pretend", + "--quiet", "--resume", + "--searchdesc", "--selective", + "--skipfirst", + "--tree", + "--update", + "--usepkg", "--usepkgonly", + "--verbose", "--version" + ] + + shortmapping={ + "1":"--oneshot", + "a":"--ask", + "b":"--buildpkg", "B":"--buildpkgonly", + "c":"--clean", "C":"--unmerge", + "d":"--debug", "D":"--deep", + "e":"--emptytree", + "f":"--fetchonly", "F":"--fetch-all-uri", + "g":"--getbinpkg", "G":"--getbinpkgonly", + "h":"--help", + "k":"--usepkg", "K":"--usepkgonly", + "l":"--changelog", + "n":"--noreplace", "N":"--newuse", + "o":"--onlydeps", "O":"--nodeps", + "p":"--pretend", "P":"--prune", + "q":"--quiet", + "s":"--search", "S":"--searchdesc", + 't':"--tree", + "u":"--update", + "v":"--verbose", "V":"--version" + } + + # process short actions + tmpcmdline=args[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]=="--verbose": + self.verbosity += 1 + elif 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 options and command arguments + for x in cmdline: + if not x: + continue + if len(x)>=2 and x[0:2]=="--": + if x in options: + self.myopts.append(x) + elif x[2:] in actions: + if x[2:]=="rsync" or x=="rsync": + # "emerge --rsync" print - print "Quitting." + print red("*** '--rsync' has been deprecated.") + print red("*** Please use '--sync' instead.") print - sys.exit(0) - emergelog(">>> starting rsync with "+host_uri) - if "--quiet" not in myopts: - print ">>> starting rsync with %s, ip %s..." % (host_uri,ips[0]) - else: - emergelog(">>> Starting retry %d of %d with %s ip %s" % \ - (retries,maxretries,host_uri,ips[0])) - print "\n\n>>> Starting retry %d of %d with %s" % (retries,maxretries,host_uri) - - try: - if "--quiet" not in myopts: - print ">>> syncing..." - exitcode=syncer.sync(portage.settings,tmpservertimestampdir, \ - remote_path=syncer.get_remote_path()+"/metadata/timestamp.chk", - verbosity=0, cleanup=False, ip=ips[0]) - if exitcode==True: - exitcode=0 - except (sync.rsync.RSyncSyntaxError,IOError),e: - print e - exitcode=1 - - if exitcode==0: - try: - servertimestamp = time.mktime(time.strptime(portage.grabfile(tmpservertimestampfile)[0], "%a, %d %b %Y %H:%M:%S +0000")) - except SystemExit, e: - raise # Needed else can't exit - except: - servertimestamp = 0 - - if (servertimestamp != 0) and (servertimestamp == mytimestamp): - emergelog(">>> Cancelling sync -- Already current.") - print - print ">>>" - print ">>> Timestamps on the server and in the local repository are the same." - print ">>> Cancelling all further sync action. You are already up to date." - print ">>>" - print - sys.exit(0) - elif (servertimestamp != 0) and (servertimestamp < mytimestamp): - emergelog(">>> Server out of date: %s" % dosyncuri) + x="--sync" + if self.myaction: + if self.myaction not in ["system", "world"]: + self.myaction="--"+self.myaction + print + print red("!!!")+green(" Multiple actions requested... Please choose one only.") + print red("!!!")+" '"+darkgreen(self.myaction)+"' "+red("or")+" '"+darkgreen(x)+"'" + print + sys.exit(1) + self.myaction=x[2:] + else: + print "!!! Error:",x,"is an invalid option." + sys.exit(1) + elif (not self.myaction) and (x in actions): + if x not in ["system", "world"]: + #print red("*** Deprecated use of action '"+x+"'") + if x=="rsync": + # "emerge rsync" + print + print red("*** 'rsync' will now install the package rsync.") + print red("*** To sync the tree, please use '--sync' instead.") + print + self.myfiles.append(x) + continue + if self.myaction: print - print ">>>" - print ">>> SERVER OUT OF DATE: %s" % dosyncuri - print ">>>" + print red("!!!")+green(" Multiple actions requested... Please choose one only.") + print red("!!! '")+darkgreen(self.myaction)+"' "+red("or")+" '"+darkgreen(x)+"'" print - elif (servertimestamp == 0) or (servertimestamp > mytimestamp): - # actual sync - try: - exitcode=syncer.sync(portage.settings,portage.settings["PORTDIR"], - verbosity=sync_verbosity, - excludes=('/distfiles','/local','/packages'),ip=ips[0]) - if exitcode==True: - exitcode=0 - except (sync.rsync.RSyncSyntaxError,IOError),e: - print e - exitcode=21 - if exitcode in [0,1,2,3,4,11,14,20,21]: - break - elif exitcode in [0,1,2,3,4,11,14,20,21]: - break - - retries=retries+1 - - if retries<=maxretries: - print ">>> retry ..." - time.sleep(11) - else: - # over retries - # exit loop - updatecache_flg=False + sys.exit(1) + self.myaction=x + elif x[-1]=="/": + # this little conditional helps tab completion + self.myfiles.append(x[:-1]) + else: + self.myfiles.append(x) + + if self.verbosity: + import portage_metadata + + if "moo" in self.myfiles: + print """ + + Gentoo (""" + os.uname()[0] + """) + + _______________________ + < Have you mooed today? > + ----------------------- + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || + +""" + + if (self.myaction in ["world", "system"]) and self.myfiles: + print "emerge: please specify a package class (\"world\" or \"system\") or individual packages, but not both." + sys.exit(1) + + for x in self.myfiles: + if (x.endswith(".ebuild") or x.endswith(".tbz2")) and os.path.exists(os.path.abspath(x)): + print "emerging by path implies --oneshot... adding --oneshot to options." + print red("\n*** emerging by path is broken and may not always work!!!\n") break - - if (exitcode==0): - emergelog("=== Sync completed with %s: %s" % (host_uri,ips[0])) - elif (exitcode>0): - print - try: - exitcode=syncer.sync(portage.settings,portage.settings["PORTDIR"], - excludes=("/distfiles","/local","/packages"),verbosity=sync_verbosity,ip=ips[0]) - if exitcode == True: - exitcode=0 - except sync.rsync.RSyncSyntaxError, rsse: - 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="+rsse.value) - except IOError, ie: - 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"]) - if exitcode==20: - print darkred("!!!")+green(" Rsync was killed before it finished.") - elif exitcode > 0: - 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.") - if exitcode: - print "bailing",exitcode - sys.exit(exitcode) - else: - updatecache_flg=True - elif protocol == "cvs": - syncer=sync.cvs.CvsHost(host_uri) - try: - print ">>> starting cvs update with "+syncuri+"..." - syncer.sync(portage.settings["PORTDIR"],compress=False) - print ">>> finished" - except sync.cvs.CVSIOError, ce: - print red("!!!")+"cvs operation failed-" - print str(ce) + + if ("--tree" in self.myopts) and ("--columns" in self.myopts): + print "emerge: can't specify both of \"--tree\" and \"--columns\"." sys.exit(1) - elif protocol == "snapshot": - fetcher=portage.get_preferred_fetcher() - print 'host_uri=',host_uri - if host_uri == None: - print ">>> choosing a random mirror from the mirror list" - host_uri = portage.thirdpartymirrors["gentoo"][:] - random.shuffle(host_uri) - host_uri=host_uri[0].replace("distfiles","snapshots") - print ">>> using %s" % host_uri - if not os.path.exists(portage.settings["PORTAGE_TMPDIR"]+"/snapshots"): - os.mkdir(portage.settings["PORTAGE_TMPDIR"]+"/snapshots") - syncer=sync.snapshot.SnapshotHost(host_uri,portage.settings["DISTDIR"], \ - portage.settings["PORTAGE_TMPDIR"]+"/snapshots", fetcher=fetcher) - if not syncer.sync(portage.settings["PORTDIR"],verbosity=sync_verbosity): - print "!!! snapshot failed" + + # Always create packages if FEATURES=buildpkg + # Imply --buildpkg if --buildpkgonly + if ("buildpkg" in portage.features) or ("--buildpkgonly" in self.myopts): + if "--buildpkg" not in self.myopts: + self.myopts.append("--buildpkg") + + # --tree only makes sense with --pretend + if "--tree" in self.myopts and not (("--pretend" in self.myopts) or ("--ask" in self.myopts)): + print ">>> --tree implies --pretend... adding --pretend to options." + self.myopts.append("--pretend") + + # Also allow -S to invoke search action (-sS) + if ("--searchdesc" in self.myopts): + if self.myaction and self.myaction != "search": + self.myfiles.append(self.myaction) + if "--search" not in self.myopts: + self.myopts.append("--search") + self.myaction = "search" + + # Always try and fetch binary packages if FEATURES=getbinpkg + if ("getbinpkg" in portage.features): + self.myopts.append("--getbinpkg") + + if ("--getbinpkgonly" in self.myopts) and not ("--usepkgonly" in self.myopts): + self.myopts.append("--usepkgonly") + + if ("--getbinpkgonly" in self.myopts) and not ("--getbinpkg" in self.myopts): + self.myopts.append("--getbinpkg") + + if ("--getbinpkg" in self.myopts) and not ("--usepkg" in self.myopts): + self.myopts.append("--usepkg") + + # Also allow -K to apply --usepkg/-k + if ("--usepkgonly" in self.myopts) and not ("--usepkg" in self.myopts): + self.myopts.append("--usepkg") + + # Also allow -l to apply --pretend/-p, but if already in --ask mode + if ("--changelog" in self.myopts) and not (("--pretend" in self.myopts) or ("--ask" in self.myopts)): + print ">>> --changelog implies --pretend... adding --pretend to options." + self.myopts.append("--pretend") + + # Allow -p to remove --ask + if ("--pretend" in self.myopts) and ("--ask" in self.myopts): + print ">>> --pretend disables --ask... removing --ask from options." + self.myopts.remove("--ask") + + # forbid --ask when not in a terminal + # note: this breaks `emerge --ask | tee logfile`, but that doesn't work anyway. + if ("--ask" in self.myopts) and (not sys.stdout.isatty()): + portage.writemsg("!!! \"--ask\" should only be used in a terminal. Exiting.\n") + sys.exit(1) + + # Set so that configs will be merged regardless of remembered status + if ("--noconfmem" in self.myopts): + portage.settings.unlock() + portage.settings["NOCONFMEM"]="1" + portage.settings.backup_changes("NOCONFMEM") + portage.settings.lock() + + # Set various debug markers... They should be merged somehow. + if ("--debug" in self.myopts): + portage.settings.unlock() + portage.settings["PORTAGE_DEBUG"]="1" + portage.settings.backup_changes("PORTAGE_DEBUG") + portage.debug=1 + portage.settings.lock() + + # check if root user is the current user for the actions where emerge needs this + if ("--pretend" in self.myopts) or ("--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts) or (self.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 self.myopts: + print getportageversion() + sys.exit(0) + elif "--help" in self.myopts: + self.help() + sys.exit(0) + elif portage.secpass!=2: + if self.myaction in ["search", "info", "regen", "metadata"]: + pass + elif (not self.myaction) and (not self.myfiles): + pass + elif ("--pretend" in self.myopts) and (self.myaction in ["world","system","clean","prune","unmerge"]): + pass + else: + if "--debug" in self.myopts: + print "myaction",self.myaction + print "myopts",self.myopts + print "emerge: root access required." + sys.exit(1) + + if not "--pretend" in self.myopts: + self.emergelog("Started emerge on: "+time.strftime("%b %d, %Y %H:%M:%S", time.localtime())) + myelogstr="" + if self.myopts: + myelogstr=" ".join(self.myopts) + if self.myaction: + myelogstr+=" "+self.myaction + if self.myfiles: + myelogstr+=" "+" ".join(self.myfiles) + self.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 + self.myparams=["self","recurse"] + add=[] + sub=[] + if "--update" in self.myopts: + add.extend(["selective","empty"]) + if "--emptytree" in self.myopts: + add.extend(["empty"]) + sub.extend(["selective"]) + if "--nodeps" in self.myopts: + sub.extend(["recurse"]) + if "--noreplace" in self.myopts: + add.extend(["selective"]) + if "--deep" in self.myopts: + add.extend(["deep"]) + if "--selective" in self.myopts: + add.extend(["selective"]) + if self.myaction in ["world","system"]: + add.extend(["selective"]) + elif self.myaction in ["depclean"]: + add.extend(["empty"]) + sub.extend(["selective"]) + for x in add: + if (x not in self.myparams) and (x not in sub): + self.myparams.append(x) + for x in sub: + if x in self.myparams: + self.myparams.remove(x) + + # general options that should be taken into account before any action + if "--debug" in self.myopts: + self.edebug=1 + + self.spinner=stdout_spinner() + if not sys.stdout.isatty() or ("--nospinner" in args): + self.spinner.update_spinner = self.spinner.update_basic_spinner + + def perform(self): + if self.myaction in ["sync","rsync","metadata"] and (not "--help" in self.myopts): + self.action_sync() + elif self.myaction=="regen": + self.emergelog(" === regen") + #regenerate cache entries + print "Regenerating cache entries... " + portage.portdb.regen_keys() + print "done!" + # HELP action + elif "config"==self.myaction: + self.emergelog(" === config") + print + print "Currently, \'config\' is a help option only." + print + # INFO action + elif "info"==self.myaction: + self.action_info() + # SEARCH action + elif "search"==self.myaction: + if not self.myfiles: + print "emerge: no search terms provided." + else: + searchinstance = search(self.myopts,self.edebug,self.verbosity,self.spinner) + for mysearch in self.myfiles: + try: + searchinstance.execute(mysearch) + except re.error, comment: + print "\n!!! Regular expression error in \"%s\": %s" % ( mysearch, comment ) + sys.exit(1) + searchinstance.output() + elif "unmerge"==self.myaction or "prune"==self.myaction or "clean"==self.myaction: + if 1==self.unmerge(self.myaction, self.myfiles): + self.post_emerge() + + elif "depclean"==self.myaction: + self.action_depclean() + + # "update", "system", or just process files: + else: + self.action_merge() + + def action_sync(self): + if "--pretend" in self.myopts: + print "emerge: \"sync\" actions do not support \"--pretend.\"" sys.exit(1) - if os.path.exists("%s/metadata/timestamp.chk" % portage.settings["PORTAGE_PORTDIR"]): - tmpservertimestampfile = "%s/metadata.timestamp.chk" % portage.settings["PORTAGE_PORTDIR"] - - updatecache_flg = True - else: - print "!!! rsync setting: ",syncuri,"not recognized; exiting." - sys.exit(1) - - - if os.path.exists(myportdir+"/metadata/cache") and updatecache_flg: - if "--quiet" not in myopts: - print "\n>>> Updating Portage cache: ", - os.umask(0002) - cachedir = os.path.normpath(portage.settings.depcachedir) - if cachedir in ["/", "/bin", "/dev", "/etc", "/home", - "/lib", "/opt", "/proc", "/root", "/sbin", - "/sys", "/tmp", "/usr", "/var"]: - print "!!! PORTAGE_CACHEDIR IS SET TO A PRIMARY ROOT DIRECTORY ON YOUR SYSTEM." - print "!!! This is ALMOST CERTAINLY NOT what you want: "+str(cachedir) - sys.exit(73) - if not os.path.exists(cachedir): - os.mkdir(cachedir) - - if (os.path.exists(cachedir) and os.path.exists(cachedir+"/app-portage")): - # removed old style cache. - # XXX: Compat Code, and Potentially bad. - portage.spawn("rm -Rf "+cachedir+"/*",portage.settings,free=1) - - # save timestamp.chk for next timestamp check. - try: - if tmpservertimestampfile != None: - portage.movefile(tmpservertimestampfile, servertimestampfile) - except SystemExit, e: - raise # Needed else can't exit - except Exception, e: - print "!!! Failed to save current timestamp." - print "!!!",e - - portage.portdb.flush_cache() - - try: - os.umask(002) - os.chown(cachedir, os.getuid(), portage.portage_gid) - os.chmod(cachedir, 00775) - except SystemExit, e: - raise # Needed else can't exit - except: - pass - # we don't make overlay trees cache here. - #grab our own eclass_cache. - ec = portage.eclass_cache.cache(portage.portdb.porttree_root) - # kinda ugly. - cm = portage.settings.load_best_module("portdbapi.metadbmodule") - cmi = cm("metadata/cache", cm.auxdbkey_order, basepath=myportdir) - - def quicky_cpv_generator(dbapi): - for x in dbapi.cp_all(): - for y in dbapi.cp_list(x): - yield y - - import cache.util - # mangle the settings var. - config=portage.config(clone=portage.settings) - config["PORTDIR_OVERLAY"] = '' - config["PORTDIR"] = myportdir - pdb=portage.portdbapi(myportdir, config) - cache.util.mirror_cache(quicky_cpv_generator(pdb), cmi, - pdb.auxdb[myportdir], eclass_cache=ec, - verbose_instance=cache.util.non_quiet_mirroring()) - del ec - del cmi - del cm - del pdb -# mynodes=portage.portdb.cp_all() -# mynodes.sort() -# pcnt=0 -# pcntstr="" -# pcntcount=len(mynodes)/100.0 -# nextupdate=pcntcount -# current=0 -# # need to add a callback option to regen_keys to take advantage of the happy spinny eye-candy stuff. -# portage.portdb.regen_keys(src_cache=myportdir+"/metadata/cache",debug=("cachedebug" in portage.features), -# verbose=False) -# portage.portdb.porttrees=backup_porttrees - sys.stdout.write("\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")) - - chk_updated_cfg_files() - - if(mybestpv != mypvs): - print - print red(" * ")+bold("An update to portage is available.")+" It is _highly_ recommended" - print red(" * ")+"that you update portage now, before any other packages are updated." - print red(" * ")+"Please do so and then update "+bold("ALL")+" of your configuration files." - print -elif myaction=="regen": - emergelog(" === regen") - #regenerate cache entries - print "Regenerating cache entries... " - portage.portdb.regen_keys() - print "done!" -# HELP action -elif "config"==myaction: - emergelog(" === config") - print - print "Currently, \'config\' is a help option only." - print -# INFO action -elif "info"==myaction: - unameout=portage_exec.spawn_get_output("uname -mrp")[1] - print getportageversion() - print "=================================================================" - print "System uname: "+unameout - if os.path.exists("/etc/gentoo-release"): - portage_exec.spawn("cat /etc/gentoo-release") - else: - print "Unknown Host Operating System" - py_vers = string.join(portage.db["/"]["vartree"].dbapi.match("dev-lang/python"), ",") - py_this = string.strip(string.split(sys.version,"\n")[0]) - print "%-20s %s [%s]" % ("Python:",py_vers,py_this) - - output=portage_exec.spawn_get_output("distcc --version") - if not output[0]: - print output[1].split("\n",1)[0], - if "distcc" in portage.features: - print "[enabled]" - else: - print "[disabled]" - - output=portage_exec.spawn_get_output("ccache -V") - if not output[0]: - print output[1].split("\n",1)[0], - if "ccache" in portage.features: - print "[enabled]" - else: - print "[disabled]" - - myvars = ["sys-devel/autoconf", "sys-devel/automake", "virtual/os-headers", - "sys-devel/binutils", "sys-devel/libtool", "dev-lang/python"] - myvars += portage_util.grabfile(portage.settings["PORTDIR"]+"/profiles/info_pkgs") - myvars = portage_util.unique_array(myvars) - myvars.sort() - - for x in myvars: - if portage.portage_dep.isvalidatom(x): - pkg_matches = portage.db["/"]["vartree"].dbapi.match(x) - pkgs = "" - for y in pkg_matches: - mycpv = portage.catpkgsplit(y) - if pkgs: - pkgs += ", " - pkgs += str(mycpv[2]) - if(mycpv[3] != "r0"): - pkgs += "-" + str(mycpv[3]) - if not pkgs: - pkgs = "[Not Present]" - print "%-20s %s" % (x+":", pkgs) + self.emergelog(" === "+str(self.myaction)) + 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=portage.settings["SYNC"].rstrip() + os.umask(0022) + + sync_verbosity=0 + if "--quiet" in self.myopts: + sync_verbosity = 1 + elif "--verbose" in self.myopts: + sync_verbosity = 3 else: - print "%-20s %s" % (x+":", "[NOT VALID]") - - libtool_vers = string.join(portage.db["/"]["vartree"].dbapi.match("sys-devel/libtool"), ",") + sync_verbosity = 2 - if "--verbose" in myopts: - myvars=portage.settings.keys() - else: - myvars = ['GENTOO_MIRRORS', 'CONFIG_PROTECT', 'CONFIG_PROTECT_MASK', - 'PORTDIR', 'DISTDIR', 'PKGDIR', 'PORTAGE_TMPDIR', - 'PORTDIR_OVERLAY', 'USE', 'CHOST', 'CFLAGS', 'CXXFLAGS', - 'ACCEPT_KEYWORDS', 'SYNC', 'FEATURES'] - - myvars.extend(portage_util.grabfile(portage.settings["PORTDIR"]+"/profiles/info_vars")) - - myvars = portage_util.unique_array(myvars) - unset_vars = [] - myvars.sort() - for x in myvars: - if portage.settings.has_key(x): - print x+'="'+portage.settings[x]+'"' - else: - unset_vars.append(x) - if unset_vars: - print "Unset: "+", ".join(unset_vars) - print - - config_files = [portage.MAKE_CONF_FILE, - portage.MODULES_FILE_PATH, - portage.USER_VIRTUALS_FILE, - portage.EBUILD_SH_ENV_FILE, - portage.CUSTOM_MIRRORS_FILE] - config_files += [portage.USER_CONFIG_PATH+"/package."+x for x in ["mask","unmask","keywords","env"]] - config_files += [portage.CUSTOM_PROFILE_PATH+"/"+x for x in ["make.defaults","packages","use.mask","virtuals","profile.bashrc","use.defaults"]] - print "Config files: "+(", ".join([x for x in config_files if os.path.exists(x)])) - - if "--debug" in myopts: - for x in dir(portage): - module = getattr(portage, x) - if "cvs_id_string" in dir(module): - print "%s: %s" % (str(x), str(module.cvs_id_string)) - -# SEARCH action -elif "search"==myaction: - if not myfiles: - print "emerge: no search terms provided." - else: - searchinstance = search() - for mysearch in myfiles: + print "sync_verbosity=",sync_verbosity + tmpservertimestampfile = None + + protocol,host_uri = sync.parseSyncUri(syncuri) + print "host_uri=",host_uri + + if self.myaction == "metadata": + if "--ask" in self.myopts: + if userquery("Are you sure?") == "No": + #userquery("Are you sure you should be using *NIX?",["Definately Not"]) + sys.exit(1) + print "skipping sync" + updatecache_flg = True + tmpservertimestampfile = None + elif protocol == "rsync": + mytimeout=180 + if portage.settings.has_key("RSYNC_TIMEOUT"): + try: + mytimeout=int(portage.settings["RSYNC_TIMEOUT"]) + except SystemExit, e: + raise # Needed else can't exit + except: + pass + + syncer=sync.rsync.RsyncHost(host_uri) + + servertimestampdir = portage.settings.depcachedir+"/" + servertimestampfile = portage.settings.depcachedir+"/timestamp.chk" + tmpservertimestampdir = portage.settings["PORTAGE_TMPDIR"]+"/" + tmpservertimestampfile = portage.settings["PORTAGE_TMPDIR"]+"/timestamp.chk" + + # We only use the backup if a timestamp exists in the portdir. + + content=None + if os.path.exists(myportdir+"/metadata/timestamp.chk"): + content=portage.grabfile(servertimestampfile) + if (not content): + content=portage.grabfile(myportdir+"/metadata/timestamp.chk") + + if (content): + try: + mytimestamp=time.mktime(time.strptime(content[0], "%a, %d %b %Y %H:%M:%S +0000")) + except ValueError: + mytimestamp=0 + else: + mytimestamp=0 + + if not os.path.exists(servertimestampdir): + os.mkdir(servertimestampdir) + os.chown(servertimestampdir, os.getuid(), portage.portage_gid) + os.chmod(servertimestampdir, 0775) + + #exitcode=0 + try: + maxretries=int(portage.settings["RSYNC_RETRIES"]) + except SystemExit, e: + raise # Needed else can't exit + except: + maxretries=3 #default number of retries + + retries=0 + updatecache_flg=True + + ips=syncer.get_ips() + if ips == None: + ips=[None] + while (1): + if (retries==0): + if "--ask" in self.myopts: + if userquery("Do you want to sync your Portage tree with the mirror %s at %s\n" \ + % (host_uri, blue(str(ips[0])))+bold("?"))=="No": + print + print "Quitting." + print + sys.exit(0) + self.emergelog(">>> starting rsync with "+host_uri) + if "--quiet" not in self.myopts: + print ">>> starting rsync with %s, ip %s..." % (host_uri,ips[0]) + else: + self.emergelog(">>> Starting retry %d of %d with %s ip %s" % \ + (retries,maxretries,host_uri,ips[0])) + print "\n\n>>> Starting retry %d of %d with %s" % (retries,maxretries,host_uri) + + try: + if "--quiet" not in self.myopts: + print ">>> syncing..." + exitcode=syncer.sync(portage.settings,tmpservertimestampdir, \ + remote_path=syncer.get_remote_path()+"/metadata/timestamp.chk", + verbosity=0, cleanup=False, ip=ips[0]) + if exitcode==True: + exitcode=0 + except (sync.rsync.RSyncSyntaxError,IOError),e: + print e + exitcode=1 + + if exitcode==0: + try: + servertimestamp = time.mktime(time.strptime(portage.grabfile(tmpservertimestampfile)[0], "%a, %d %b %Y %H:%M:%S +0000")) + except SystemExit, e: + raise # Needed else can't exit + except: + servertimestamp = 0 + + if (servertimestamp != 0) and (servertimestamp == mytimestamp): + self.emergelog(">>> Cancelling sync -- Already current.") + print + print ">>>" + print ">>> Timestamps on the server and in the local repository are the same." + print ">>> Cancelling all further sync action. You are already up to date." + print ">>>" + print + sys.exit(0) + elif (servertimestamp != 0) and (servertimestamp < mytimestamp): + self.emergelog(">>> Server out of date: %s" % dosyncuri) + print + print ">>>" + print ">>> SERVER OUT OF DATE: %s" % dosyncuri + print ">>>" + print + elif (servertimestamp == 0) or (servertimestamp > mytimestamp): + # actual sync + try: + exitcode=syncer.sync(portage.settings,portage.settings["PORTDIR"], + verbosity=sync_verbosity, + excludes=('/distfiles','/local','/packages'),ip=ips[0]) + if exitcode==True: + exitcode=0 + except (sync.rsync.RSyncSyntaxError,IOError),e: + print e + exitcode=21 + if exitcode in [0,1,2,3,4,11,14,20,21]: + break + elif exitcode in [0,1,2,3,4,11,14,20,21]: + break + + retries=retries+1 + + if retries<=maxretries: + print ">>> retry ..." + time.sleep(11) + else: + # over retries + # exit loop + updatecache_flg=False + break + + if (exitcode==0): + self.emergelog("=== Sync completed with %s: %s" % (host_uri,ips[0])) + elif (exitcode>0): + print + try: + exitcode=syncer.sync(portage.settings,portage.settings["PORTDIR"], + excludes=("/distfiles","/local","/packages"),verbosity=sync_verbosity,ip=ips[0]) + if exitcode == True: + exitcode=0 + except sync.rsync.RSyncSyntaxError, rsse: + 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="+rsse.value) + except IOError, ie: + 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"]) + if exitcode==20: + print darkred("!!!")+green(" Rsync was killed before it finished.") + elif exitcode > 0: + 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.") + if exitcode: + print "bailing",exitcode + sys.exit(exitcode) + else: + updatecache_flg=True + elif protocol == "cvs": + syncer=sync.cvs.CvsHost(host_uri) try: - searchinstance.execute(mysearch) - except re.error, comment: - print "\n!!! Regular expression error in \"%s\": %s" % ( mysearch, comment ) + print ">>> starting cvs update with "+syncuri+"..." + syncer.sync(portage.settings["PORTDIR"],compress=False) + print ">>> finished" + except sync.cvs.CVSIOError, ce: + print red("!!!")+"cvs operation failed-" + print str(ce) + sys.exit(1) + elif protocol == "snapshot": + fetcher=portage.get_preferred_fetcher() + print 'host_uri=',host_uri + if host_uri == None: + print ">>> choosing a random mirror from the mirror list" + host_uri = portage.thirdpartymirrors["gentoo"][:] + random.shuffle(host_uri) + host_uri=host_uri[0].replace("distfiles","snapshots") + print ">>> using %s" % host_uri + if not os.path.exists(portage.settings["PORTAGE_TMPDIR"]+"/snapshots"): + os.mkdir(portage.settings["PORTAGE_TMPDIR"]+"/snapshots") + syncer=sync.snapshot.SnapshotHost(host_uri,portage.settings["DISTDIR"], \ + portage.settings["PORTAGE_TMPDIR"]+"/snapshots", fetcher=fetcher) + if not syncer.sync(portage.settings["PORTDIR"],verbosity=sync_verbosity): + print "!!! snapshot failed" sys.exit(1) - searchinstance.output() -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 ***")+" : emerge --update --deep --newuse world TO VERIFY" - print red("*** WARNING ***")+" : SANITY IN THIS REGARD." - 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 ("--pretend" not in myopts) and ("--ask" not in myopts): - countdown(EMERGE_WARNING_DELAY, ">>> 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.mynewgraph.get_all_nodes() - 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 installed package tree (%s). This is a problem." % portage.VDB_PATH - if not alldeps: - print "!!! You have no dependencies. Impossible. Bug." - - if not (syslist and worldlist and myvarlist and alldeps): - print - sys.exit(1) - - reallist=[] - for x in alldeps: - myparts=portage_versions.catpkgsplit(x.split()[2]) - if not myparts: - sys.stderr.write( - red("!!! There appears to be a problem with the following package:\n")+ - red("!!! "+str(x.split()[2])+"\n\n")+ - "!!! Please ensure that blocking/conflicting packages are not merged."+ - "!!! 'emerge -p "+str(x.split()[2])+"\n\n") - if ("--pretend" not in myopts) and ("--ask" not in myopts): - countdown(EMERGE_WARNING_DELAY, "*** 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_versions.catpkgsplit(x) - if myparts: - mycat = "" - myparts = list(myparts) - if myparts[0][0] in ('<','>','='): - mycat = myparts[0][1:] - elif myparts[0][:2] in ('<=','>='): - mycat = myparts[0][2:] - catpack=mycat+"/"+myparts[1] - else: - catpack=x - if catpack in cleanlist: - cleanlist.remove(catpack) - - #print "\n\n\nCleaning: " - #for x in cleanlist: - # print x - #print - - if len(cleanlist): - unmerge("unmerge", cleanlist) - - 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)) - post_emerge() -# "update", "system", or just process files: -else: - favorites=[] - syslist=getlist("system") - if (("--pretend" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts)) or ("--ask" in myopts): - if "--tree" in myopts: - print - print darkgreen("These are the packages that I would merge, in reverse order:") - print + if os.path.exists("%s/metadata/timestamp.chk" % portage.settings["PORTAGE_PORTDIR"]): + tmpservertimestampfile = "%s/metadata.timestamp.chk" % portage.settings["PORTAGE_PORTDIR"] + + updatecache_flg = True else: - 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"][:] - - while "--skipfirst" in myresumeopts: - myresumeopts.remove("--skipfirst") - while "--ask" in myresumeopts: - myresumeopts.remove("--ask") + print "!!! rsync setting: ",syncuri,"not recognized; exiting." + sys.exit(1) + + + if os.path.exists(myportdir+"/metadata/cache") and updatecache_flg: + if "--quiet" not in self.myopts: + print "\n>>> Updating Portage cache: ", + os.umask(0002) + cachedir = os.path.normpath(portage.settings.depcachedir) + if cachedir in ["/", "/bin", "/dev", "/etc", "/home", + "/lib", "/opt", "/proc", "/root", "/sbin", + "/sys", "/tmp", "/usr", "/var"]: + print "!!! PORTAGE_CACHEDIR IS SET TO A PRIMARY ROOT DIRECTORY ON YOUR SYSTEM." + print "!!! This is ALMOST CERTAINLY NOT what you want: "+str(cachedir) + sys.exit(73) + if not os.path.exists(cachedir): + os.mkdir(cachedir) + + if (os.path.exists(cachedir) and os.path.exists(cachedir+"/app-portage")): + # removed old style cache. + # XXX: Compat Code, and Potentially bad. + portage.spawn("rm -Rf "+cachedir+"/*",portage.settings,free=1) + + # save timestamp.chk for next timestamp check. + try: + if tmpservertimestampfile != None: + portage.movefile(tmpservertimestampfile, servertimestampfile) + except SystemExit, e: + raise # Needed else can't exit + except Exception, e: + print "!!! Failed to save current timestamp." + print "!!!",e + + portage.portdb.flush_cache() + + try: + os.umask(002) + os.chown(cachedir, os.getuid(), portage.portage_gid) + os.chmod(cachedir, 00775) + except SystemExit, e: + raise # Needed else can't exit + except: + pass + # we don't make overlay trees cache here. + #grab our own eclass_cache. + ec = portage.eclass_cache.cache(portage.portdb.porttree_root) + # kinda ugly. + cm = portage.settings.load_best_module("portdbapi.metadbmodule") + cmi = cm("metadata/cache", cm.auxdbkey_order, basepath=myportdir) - 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) - - mydepgraph=depgraph(myaction,myopts) - if myaction in ["system","world"]: - print "Calculating",myaction,"dependencies ", - sys.stdout.flush() - 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 ", + def quicky_cpv_generator(dbapi): + for x in dbapi.cp_all(): + for y in dbapi.cp_list(x): + yield y + + import cache.util + # mangle the settings var. + config=portage.config(clone=portage.settings) + config["PORTDIR_OVERLAY"] = '' + config["PORTDIR"] = myportdir + pdb=portage.portdbapi(myportdir, config) + cache.util.mirror_cache(quicky_cpv_generator(pdb), cmi, + pdb.auxdb[myportdir], eclass_cache=ec, + verbose_instance=cache.util.non_quiet_mirroring()) + del ec + del cmi + del cm + del pdb + # mynodes=portage.portdb.cp_all() + # mynodes.sort() + # pcnt=0 + # pcntstr="" + # pcntcount=len(mynodes)/100.0 + # nextupdate=pcntcount + # current=0 + # # need to add a callback option to regen_keys to take advantage of the happy spinny eye-candy stuff. + # portage.portdb.regen_keys(src_cache=myportdir+"/metadata/cache",debug=("cachedebug" in portage.features), + # verbose=False) + # portage.portdb.porttrees=backup_porttrees + sys.stdout.write("\n\n") sys.stdout.flush() - retval,favorites=mydepgraph.select_files(myfiles) - if not retval: - 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")) - - if mydepgraph.missingbins: + + 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")) + + chk_updated_cfg_files() + + if(mybestpv != mypvs): + print + print red(" * ")+bold("An update to portage is available.")+" It is _highly_ recommended" + print red(" * ")+"that you update portage now, before any other packages are updated." + print red(" * ")+"Please do so and then update "+bold("ALL")+" of your configuration files." + print + + def action_info(self): + unameout=portage_exec.spawn_get_output("uname -mrp")[1] + print getportageversion() + print "=================================================================" + print "System uname: "+unameout + if os.path.exists("/etc/gentoo-release"): + portage_exec.spawn("cat /etc/gentoo-release") + else: + print "Unknown Host Operating System" + + py_vers = string.join(portage.db["/"]["vartree"].dbapi.match("dev-lang/python"), ",") + py_this = string.strip(string.split(sys.version,"\n")[0]) + print "%-20s %s [%s]" % ("Python:",py_vers,py_this) + + output=portage_exec.spawn_get_output("distcc --version") + if not output[0]: + print output[1].split("\n",1)[0], + if "distcc" in portage.features: + print "[enabled]" + else: + print "[disabled]" + + output=portage_exec.spawn_get_output("ccache -V") + if not output[0]: + print output[1].split("\n",1)[0], + if "ccache" in portage.features: + print "[enabled]" + else: + print "[disabled]" + + myvars = ["sys-devel/autoconf", "sys-devel/automake", "virtual/os-headers", + "sys-devel/binutils", "sys-devel/libtool", "dev-lang/python"] + myvars += portage_util.grabfile(portage.settings["PORTDIR"]+"/profiles/info_pkgs") + myvars = portage_util.unique_array(myvars) + myvars.sort() + + for x in myvars: + if portage.portage_dep.isvalidatom(x): + pkg_matches = portage.db["/"]["vartree"].dbapi.match(x) + pkgs = "" + for y in pkg_matches: + mycpv = portage.catpkgsplit(y) + if pkgs: + pkgs += ", " + pkgs += str(mycpv[2]) + if(mycpv[3] != "r0"): + pkgs += "-" + str(mycpv[3]) + if not pkgs: + pkgs = "[Not Present]" + print "%-20s %s" % (x+":", pkgs) + else: + print "%-20s %s" % (x+":", "[NOT VALID]") + + libtool_vers = string.join(portage.db["/"]["vartree"].dbapi.match("sys-devel/libtool"), ",") + + if "--verbose" in self.myopts: + myvars=portage.settings.keys() + else: + myvars = ['GENTOO_MIRRORS', 'CONFIG_PROTECT', 'CONFIG_PROTECT_MASK', + 'PORTDIR', 'DISTDIR', 'PKGDIR', 'PORTAGE_TMPDIR', + 'PORTDIR_OVERLAY', 'USE', 'CHOST', 'CFLAGS', 'CXXFLAGS', + 'ACCEPT_KEYWORDS', 'SYNC', 'FEATURES'] + + myvars.extend(portage_util.grabfile(portage.settings["PORTDIR"]+"/profiles/info_vars")) + + myvars = portage_util.unique_array(myvars) + unset_vars = [] + myvars.sort() + for x in myvars: + if portage.settings.has_key(x): + print x+'="'+portage.settings[x]+'"' + else: + unset_vars.append(x) + if unset_vars: + print "Unset: "+", ".join(unset_vars) + print + + config_files = [portage.MAKE_CONF_FILE, + portage.MODULES_FILE_PATH, + portage.USER_VIRTUALS_FILE, + portage.EBUILD_SH_ENV_FILE, + portage.CUSTOM_MIRRORS_FILE] + config_files += [portage.USER_CONFIG_PATH+"/package."+x for x in ["mask","unmask","keywords","env"]] + config_files += [portage.CUSTOM_PROFILE_PATH+"/"+x for x in ["make.defaults","packages","use.mask","virtuals","profile.bashrc","use.defaults"]] + print "Config files: "+(", ".join([x for x in config_files if os.path.exists(x)])) + + if "--debug" in self.myopts: + for x in dir(portage): + module = getattr(portage, x) + if "cvs_id_string" in dir(module): + print "%s: %s" % (str(x), str(module.cvs_id_string)) + + def action_depclean(self): + # 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 ***")+" : emerge --update --deep --newuse world TO VERIFY" + print red("*** WARNING ***")+" : SANITY IN THIS REGARD." + 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 ("--pretend" not in self.myopts) and ("--ask" not in self.myopts): + countdown(self.EMERGE_WARNING_DELAY, ">>> Depclean") + self.emergelog(" >>> depclean") + + mydepgraph=depgraph(self.myaction,self.myopts,self.myparams,self.edebug,self.verbosity,self.EMERGE_WARNING_DELAY,self.spinner) + syslist=getlist("system") + worldlist=getlist("world") + + print "Calculating",self.myaction,"dependencies ", + if not mydepgraph.xcreate("world"): + print "\n!!! Failed to create deptree." + sys.exit(1) + print "\b\b ... done!" + + if ("--usepkgonly" in self.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) - - if "--ask" in myopts: - if "--resume" in myopts: - mydepgraph.display(portage.mtimedb["resume"]["mergelist"]) - prompt="Do you want me to resume merging these packages?" - else: - graphdisp = graph_display(mydepgraph.mynewgraph) - if "--tree" in myopts: - graphdisp.display_tree() - elif "--columns" in myopts: - graphdisp.display_columns() - else: - graphdisp.display_flat() - mergecount=0 - for x in mydepgraph.altlist(): - if x[3]!="nomerge": - mergecount+=1 - #check for blocking dependencies - if x[0]=="blocks": - print "\n!!! Error: The above package list contains packages which cannot be installed" - print "!!! on the same system." - print + + alldeps=mydepgraph.mynewgraph.get_all_nodes() + 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 installed package tree (%s). This is a problem." % portage.VDB_PATH + if not alldeps: + print "!!! You have no dependencies. Impossible. Bug." + + if not (syslist and worldlist and myvarlist and alldeps): + print + sys.exit(1) + + reallist=[] + for x in alldeps: + myparts=portage_versions.catpkgsplit(x.split()[2]) + if not myparts: + sys.stderr.write( + red("!!! There appears to be a problem with the following package:\n")+ + red("!!! "+str(x.split()[2])+"\n\n")+ + "!!! Please ensure that blocking/conflicting packages are not merged."+ + "!!! 'emerge -p "+str(x.split()[2])+"\n\n") + if ("--pretend" not in self.myopts) and ("--ask" not in self.myopts): + countdown(self.EMERGE_WARNING_DELAY, "*** 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_versions.catpkgsplit(x) + if myparts: + mycat = "" + myparts = list(myparts) + if myparts[0][0] in ('<','>','='): + mycat = myparts[0][1:] + elif myparts[0][:2] in ('<=','>='): + mycat = myparts[0][2:] + catpack=mycat+"/"+myparts[1] + else: + catpack=x + if catpack in cleanlist: + cleanlist.remove(catpack) + + #print "\n\n\nCleaning: " + #for x in cleanlist: + # print x + #print + + if len(cleanlist): + self.unmerge("unmerge", cleanlist) + + 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 self.myopts: + print "Number to remove: "+str(len(cleanlist)) + else: + print "Number removed: "+str(len(cleanlist)) + self.post_emerge() + + def action_merge(self): + favorites=[] + syslist=getlist("system") + if (("--pretend" in self.myopts) and not ("--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts)) or ("--ask" in self.myopts): + if "--tree" in self.myopts: + print + print darkgreen("These are the packages that I would merge, in reverse order:") + print + else: + print + print darkgreen("These are the packages that I would merge, in order:") + print + + if ("--resume" in self.myopts) and portage.mtimedb.has_key("resume"): + myresumeopts=portage.mtimedb["resume"]["myopts"][:] + + while "--skipfirst" in myresumeopts: + myresumeopts.remove("--skipfirst") + while "--ask" in myresumeopts: + myresumeopts.remove("--ask") + + for myopt in self.myopts: + if myopt not in myresumeopts: + myresumeopts.append(myopt) + self.myopts=myresumeopts + mydepgraph=depgraph("resume",self.myopts,self.myparams,self.edebug,self.verbosity,self.EMERGE_WARNING_DELAY,self.spinner) + if "--resume" not in self.myopts: + self.myopts+=["--resume"] + else: + if ("--resume" in self.myopts): + del self.myopts[self.myopts.index("--resume")] + print darkgreen("emerge: It seems we have nothing to resume...") + sys.exit(0) + + mydepgraph=depgraph(self.myaction,self.myopts,self.myparams,self.edebug,self.verbosity,self.EMERGE_WARNING_DELAY,self.spinner) + if self.myaction in ["system","world"]: + print "Calculating",self.myaction,"dependencies ", + sys.stdout.flush() + if not mydepgraph.xcreate(self.myaction): + print "!!! Depgraph creation failed." sys.exit(1) - if mergecount==0: - prompt="Nothing to merge; do you want me to auto-clean packages?" - elif "--fetchonly" in myopts or "--fetch-all-uri" in myopts: - prompt="Do you want me to fetch the source files for these packages?" + print "\b\b ...done!" else: - prompt="Do you want me to merge these packages?" - print - if userquery(prompt)=="No": - print - print "Quitting." + if not self.myfiles: + print "emerge: please tell me what to do." + self.help() + sys.exit(1) + #we don't have any files to process; skip this step and exit + print "Calculating dependencies ", + sys.stdout.flush() + retval,favorites=mydepgraph.select_files(self.myfiles) + if not retval: + sys.exit(1) + print "\b\b ...done!" + + if ("--usepkgonly" in self.myopts) and mydepgraph.missingbins: + sys.stderr.write(red("The following binaries are not available for merging...\n")) + + 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) + + if "--ask" in self.myopts: + if "--resume" in self.myopts: + mydepgraph.display(portage.mtimedb["resume"]["mergelist"]) + prompt="Do you want me to resume merging these packages?" + else: + graphdisp = graph_display(mydepgraph.mynewgraph,self.myopts,self.edebug,self.verbosity) + if "--tree" in self.myopts: + graphdisp.display_tree() + elif "--columns" in self.myopts: + graphdisp.display_columns() + else: + graphdisp.display_flat() + mergecount=0 + for x in mydepgraph.altlist(): + if x[3]!="nomerge": + mergecount+=1 + #check for blocking dependencies + if x[0]=="blocks": + print "\n!!! Error: The above package list contains packages which cannot be installed" + print "!!! on the same system." + print + sys.exit(1) + if mergecount==0: + prompt="Nothing to merge; do you want me to auto-clean packages?" + elif "--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts: + prompt="Do you want me to fetch the source files for these packages?" + else: + prompt="Do you want me to merge these packages?" print - sys.exit(0) - # Don't ask again (e.g. when auto-cleaning packages after merge) - myopts.remove("--ask") - - if ("--pretend" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts): - if ("--resume" in myopts): - mydepgraph.display(portage.mtimedb["resume"]["mergelist"]) - else: - graphdisp = graph_display(mydepgraph.mynewgraph) - if "--tree" in myopts: - graphdisp.display_tree() - elif "--columns" in myopts: - graphdisp.display_columns() + if userquery(prompt)=="No": + print + print "Quitting." + print + sys.exit(0) + # Don't ask again (e.g. when auto-cleaning packages after merge) + self.myopts.remove("--ask") + + if ("--pretend" in self.myopts) and not ("--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts): + if ("--resume" in self.myopts): + mydepgraph.display(portage.mtimedb["resume"]["mergelist"]) + else: + graphdisp = graph_display(mydepgraph.mynewgraph,self.myopts,self.edebug,self.verbosity) + if "--tree" in self.myopts: + graphdisp.display_tree() + elif "--columns" in self.myopts: + graphdisp.display_columns() + else: + graphdisp.display_flat() + else: + if ("--buildpkgonly" in self.myopts): + has_deps = False + for node in mydepgraph.mynewgraph.get_all_nodes(): + if mydepgraph.mynewgraph.get_relationships(node)[0]: + has_deps = True + if has_deps: + print "\n!!! --buildpkgonly requires all dependencies to be merged." + print "!!! Cannot merge requested packages. Merge deps and try again.\n" + sys.exit(1) + + if ("--resume" in self.myopts): + mydepgraph.merge(portage.mtimedb["resume"]["mergelist"],portage.mtimedb["resume"]["favorites"]) else: - graphdisp.display_flat() - else: - if ("--buildpkgonly" in myopts): - has_deps = False - for node in mydepgraph.mynewgraph.get_all_nodes(): - if mydepgraph.mynewgraph.get_relationships(node)[0]: - has_deps = True - if has_deps: - print "\n!!! --buildpkgonly requires all dependencies to be merged." - print "!!! Cannot merge requested packages. Merge deps and try again.\n" - sys.exit(1) - - 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 or "--fetch-all-uri" in myopts): - for pkgline in mydepgraph.altlist(): - if pkgline[0]=="ebuild" and pkgline[3]=="merge": - y=portage.portdb.findname(pkgline[2]) - tmpsettings = portage.config(clone=portage.settings) - retval=portage.doebuild(y,"digest",portage.root,tmpsettings,edebug,("--pretend" in myopts)) - mydepgraph.merge(mydepgraph.altlist()) + portage.mtimedb["resume"]={} + portage.mtimedb["resume"]["myopts"]=self.myopts + portage.mtimedb["resume"]["favorites"]=favorites + if ("--digest" in self.myopts) and not ("--fetchonly" in self.myopts or "--fetch-all-uri" in self.myopts): + for pkgline in mydepgraph.altlist(): + if pkgline[0]=="ebuild" and pkgline[3]=="merge": + y=portage.portdb.findname(pkgline[2]) + tmpsettings = portage.config(clone=portage.settings) + retval=portage.doebuild(y,"digest",portage.root,tmpsettings,self.edebug,("--pretend" in self.myopts)) + mydepgraph.merge(mydepgraph.altlist(),favorites) + + if portage.mtimedb.has_key("resume"): + del portage.mtimedb["resume"] + print ">>> Auto-cleaning packages ..." + self.unmerge("clean", ["world"]) + self.post_emerge() + + def post_emerge(self,retval=0): + os.chdir("/") + if "--pretend" in self.myopts: + sys.exit(retval) + + self.emergelog(" *** exiting successfully.") + + if "noinfo" not in portage.settings.features: + chk_updated_info_files() + + chk_updated_cfg_files() + + sys.exit(retval) - if portage.mtimedb.has_key("resume"): - del portage.mtimedb["resume"] - print ">>> Auto-cleaning packages ..." - unmerge("clean", ["world"]) - post_emerge() + def unmerge(self,unmerge_action,unmerge_files): + return unmerge(self.myopts, self.edebug, self.EMERGE_WARNING_DELAY, unmerge_action, unmerge_files) + def exit(self): + """This gets out final log message in before we quit.""" + if "--pretend" not in self.myopts: + self.emergelog(" *** terminating.") + if "notitles" not in portage.features: + xtermTitleReset() + +if __name__=="__main__": + cmd=emerge_cmd() + def emergeexit(): + cmd.exit() + atexit.register(emergeexit) + cmd.parse_args(sys.argv) + cmd.perform()