From: Zac Medico <zmedico@gmail.com>
To: gentoo-portage-dev@lists.gentoo.org
Subject: Re: [gentoo-portage-dev] the refactoring of emerge, continued... (was PATCH: refactor emerge spinner (#102073))
Date: Sat, 13 Aug 2005 15:25:17 -0700 [thread overview]
Message-ID: <42FE734D.5020808@gmail.com> (raw)
In-Reply-To: <42FE2F3F.7000806@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 501 bytes --]
Hi,
In #gentoo-portage Jason requested for me to split out some parts of the the emerge_cmd.perform() method. Actually, I should have done that before I posted to the list earlier but I was anxious to show people what I had done. Sorry for the extra post. :-)
I have split out 4 new methods called action_sync(), action_info(), action_depclean(), and action_merge(). This time I am posting a patch against portage-2.1.0_alpha20050718. As always, I would appreciate feedback.
Thanks again,
Zac
[-- Attachment #2: emerge-2.1.0_alpha20050718-refactored-r1.patch --]
[-- Type: text/x-patch, Size: 121392 bytes --]
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)<len(mylist)-1:
p.append(red("*** Portage will stop merging at this point and reload itself,"))
p.append(red(" recalculate dependencies, and complete the merge."))
- if "--update" not in myopts:
+ if "--update" not in self.myopts:
p.append(darkgreen(" You may avoid the remerging of packages by updating portage on its own."))
print
else:
- if mysplit[0]=="sys-apps/portage" and ("--emptytree" in myopts):
+ if mysplit[0]=="sys-apps/portage" and ("--emptytree" in self.myopts):
if mysplit[1]+mysplit[2]!=portage.VERSION:
p.append(red("***")+" Please update portage to the above version before proceeding.")
p.append(" Failure to do so may result in failed or improper merges.")
@@ -1612,7 +1269,7 @@ class depgraph:
for x in p:
print x
- if verbosity:
+ if self.verbosity:
print
print "Total size of downloads: "+format_size(totalsize)
if overlays and display_overlays:
@@ -1622,7 +1279,7 @@ class depgraph:
y=y+1
print " "+teal("["+str(y)+"]"),x
- if "--changelog" in myopts:
+ if "--changelog" in self.myopts:
print
for revision,text in changelogs:
print bold('*'+revision)
@@ -1697,29 +1354,29 @@ class depgraph:
if ret:
return False
- def merge(self,mylist):
+ def merge(self,mylist,favorites):
returnme=0
mymergelist=[]
#check for blocking dependencies
- if ("--fetchonly" not in myopts) and ("--buildpkgonly" not in myopts):
+ if ("--fetchonly" not in self.myopts) and ("--buildpkgonly" not in self.myopts):
for x in mylist:
if x[0]=="blocks":
print "\n!!! Error: the "+x[2]+" package conflicts with another package."
print "!!! both can't be installed on the same system together."
print "!!! Please use 'emerge --pretend' to determine blockers."
print
- if ("--pretend" not in myopts):
+ if ("--pretend" not in self.myopts):
sys.exit(1)
#buildsyspkg: I need mysysdict also on resume (moved from the else block)
- mysysdict=genericdict(syslist)
- if ("--resume" in myopts):
+ mysysdict=genericdict(getlist("system"))
+ if ("--resume" in self.myopts):
# We're resuming.
print green("*** Resuming merge...")
- emergelog(" *** Resuming merge...")
+ self.emergelog(" *** Resuming merge...")
mymergelist=portage.mtimedb["resume"]["mergelist"][:]
- if ("--skipfirst" in myopts) and mymergelist:
+ if ("--skipfirst" in self.myopts) and mymergelist:
del portage.mtimedb["resume"]["mergelist"][0]
del mymergelist[0]
else:
@@ -1731,16 +1388,16 @@ class depgraph:
mymergelist.append(mylist[x])
else:
myfavkey=portage.cpv_getkey(mylist[x][2])
- if "--onlydeps" in myopts:
+ if "--onlydeps" in self.myopts:
continue
# Add to the world file. Since we won't be able to later.
- if (not "--fetchonly" in myopts) and (myfavkey in favorites):
+ if (not "--fetchonly" in self.myopts) and (myfavkey in favorites):
#don't record if already in system profile or already recorded
if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
#we don't have a favorites entry for this package yet; add one
myfavdict[myfavkey]=myfavkey
print ">>> Recording",myfavkey,"in \"world\" favorites file..."
- if not "--fetchonly" in myopts:
+ 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()
prev parent reply other threads:[~2005-08-13 22:19 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-08-11 5:08 [gentoo-portage-dev] PATCH: refactor emerge spinner (#102073) Zac Medico
2005-08-11 12:14 ` Alec Warner
2005-08-11 14:06 ` Jason Stubbs
2005-08-12 5:19 ` [gentoo-portage-dev] the refactoring of emerge, continued... (was PATCH: refactor emerge spinner (#102073)) Zac Medico
2005-08-12 12:36 ` Alec Warner
2005-08-12 20:57 ` Zac Medico
2005-08-12 21:48 ` warnera6
2005-08-12 22:10 ` Marius Mauch
2005-08-12 22:12 ` warnera6
2005-08-12 22:49 ` Zac Medico
2005-08-13 1:06 ` Jason Stubbs
2005-08-13 17:34 ` Zac Medico
2005-08-13 22:25 ` Zac Medico [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=42FE734D.5020808@gmail.com \
--to=zmedico@gmail.com \
--cc=gentoo-portage-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox