From d9fc4acc572c6647a4f27b838d35d27d805d190e Mon Sep 17 00:00:00 2001 From: Jason Stubbs Date: Sun, 28 Aug 2005 08:37:44 +0000 Subject: Migration (without history) of the current stable line to subversion. svn path=/main/branches/2.0/; revision=1941 --- spec/emerge.syntax | 1149 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1149 insertions(+) create mode 100755 spec/emerge.syntax (limited to 'spec/emerge.syntax') diff --git a/spec/emerge.syntax b/spec/emerge.syntax new file mode 100755 index 000000000..17b8131a2 --- /dev/null +++ b/spec/emerge.syntax @@ -0,0 +1,1149 @@ +#!/usr/bin/env python +import os +from os.path import walk, splitext, exists, basename, dirname +import sys + +import output +from output import * +import portage +import xpak +import string +from string import strip, find, replace, split +import commands +import shutil +import re +import time + +#number of ebuilds merged +merged=0 +# there can only be one action specified; the default action is to merge +# specified packages, not update. +actions=["help", + "rebuild", + "search", + "update", + "clean", + "zap", + "rsync"] +# emerge (prints help) +# emerge help (prints help) +# emerge help config (prints config file management help) + +# emerge rsync + +# the default behavior of emerge is to satisfy dependencies specified by merging packages. +# emerge system (satisfy deps for "system" package class) +# emerge world (equivalent to emerge system since "world" doesn't offer any new deps) +# emerge (satisfy dep by merging most recent version of app available that satisfies dep) +# NOTE: this will cause something to be merged again if the dep happens to be already satisfied +# "unslotted" is invalid for a package class here because it only applies to already-installed ebuilds. +# pkgclass support: "system", "world", , , , + +# no changes here except we use "update" rather than "--update" +# emerge update +# emerge update (defaults to "world") +# "emerge update doesn't make too much sense. +# But it should do the same thing are "emerge ". + +# rebuild is like "update" except that all packages will be rebuilt even if they currently are installed. +# emerge rebuild (defaults to "world") +# emerge rebuild +# "emerge rebuild doesn't make too much sense. +# But it should do the same thing are "emerge ". + +# emerge search (invalid) +# emerge search + +# clean does "cleaning" only; it does not do anything that would generally be considered dangerous +# emerge clean (defaults to "world"; apply default AUTOCLEAN behavior defined in make.conf) +# emerge --rev clean (defaults to "world", cleans out old revisions) +# emerge --slot clean (defaults to "world", cleans out old stuff from slots) +# emerge [--rev/--slot] clean +# AUTOCLEAN var can be set to "slot", "rev", or "none/off/etc". + +# zap flat out removes stuff. No holds barred. Can be dangerous. +# emerge zap (only "unslotted" is valid, which is still dangerous. Or a dep "=foo/bar") +# NOTE: of course, "emerge zap" alone is invalid and will *not* default to a "world" package class + +pkgclass=["world","system","unslotted"] +helpclass=["config"] + +# These next options are the only long options for Portage 1.8.9 except for "--help" (equiv. to "help") + +options=["--autoclean", + "--buildpkg", + "--debug", + "--fetchonly", + "--noreplace", + "--onlydeps", + "--pretend", + "--usepkg", + "--verbose", + "--emptytree", + "--rev", + "--slot", + "--help"] + +# Here are the currently supported short mappings. + +shortmapping={"a":"--autoclean", + "b":"--buildpkg", + "d":"--debug", + "f":"--fetchonly", + "h":"--help", + "k":"--usepkg", + "n":"--noreplace", + "o":"--onlydeps", + "p":"--pretend", + "v":"--verbose" } + +# end of spec + +myaction=None +myopts=[] +mymode=[] +myfiles=[] +edebug=0 + +# process short actions and options +for x in sys.argv[1:]: + if x[0:1]=="-"and not x[1:2]=="-": + for y in x[1:]: + if shortmapping.has_key(y): + sys.argv.append(shortmapping[y]) + else: + print y + print "!!! Error: -"+y+" is an invalid short action or option." + sys.argv.remove(x) + +# process the command arguments +for x in sys.argv[1:]: + if x=="update" or x=="--unmerge" or x=="--world": + print + if x=="update": + print " "+red("* WARNING:"),green("emerge update"),"has been deprecated, use",green("emerge --update"),"instead." + elif x=="--unmerge": + print " "+red("* WARNING:"),green("emerge --unmerge"),"has been deprecated, use",green("emerge --zap"),"instead." + elif x=="--world": + print " "+red("* WARNING:"),green("emerge --world"),"has been deprecated, use",green("emerge world"),"instead." + print " "+red("*"),"Read",green("emerge --help"),"to get a complete overview of the interface changes." + print + sys.exit(1) + + if len(x)>=2: + if x[0:1]=="-": + if x[1:2]=="-": + if x in actions: + if myaction: + print "!!! Error: more than one action specified on command-line." + print "!!! Available actions:",actions + sys.exit(1) + else: + myaction=x + elif x in options: + myopts.append(x) + else: + print "!!! Error:",x,"is an invalid action or option." + sys.exit(1) + else: + for y in x[1:]: + if shortmapping.has_key(y): + myopts.append(shortmapping[y]) + else: + print y + print "!!! Error: -"+y+" is an invalid short action or option." + elif x in modes: + if len(mymode)>=1: + print "!!! Error: more than one mode specified on command-line." + print "!!! Available modes:",modes + sys.exit(1) + else: + mymode.append(x) + else: + # this little conditional helps tab completion + if x[-1]=="/": + myfiles.append(x[:-1]) + else: + myfiles.append(x) + +# check if root user is the current user for the actions where emerge needs this +if os.getuid()!=0 and "--help"!=myaction and "--search"!=myaction: + print "!!! to be able to perform the requested action, emerge must be run by root." + sys.exit(1) + +# search functionality +class search: + + # + # class constants + # + VERSION_SHORT=1 + VERSION_RELEASE=2 + + # + # public interface + # + def __init__(self,searchkey=""): + """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.searchkey = searchkey + self.treecache = portage.portagetree() + self.treecache.populate() + self.installcache = portage.vartree() + self.installcache.populate() + self.re_portagedir = re.compile('/usr/portage/') + self.re_description = re.compile('DESCRIPTION="') + self.initResults() + + def setKey(self,searchkey): + """changes the search key""" + self.searchkey = searchkey + self.initResults() + + def execute(self): + """Performs the saerch for the supplied search key""" + if self.searchkey: + self.initResults() + for package in self.treecache.getallnodes(): + package_parts=package.split("/") + if package_parts: + if self.searchkey != "*": + if re.search(self.searchkey.lower(), package_parts[1].lower()): + self.packagematches.append(package) + else: + self.packagematches.append(package) + + def output(self): + """Outputs the results of the search.""" + print "[ Results for search key : "+white(self.searchkey)+" ]" + print "[ Applications found : "+white(str(len(self.packagematches)))+" ]" + print " " + for match in self.packagematches: + full_package = strip(self.treecache.dep_bestmatch(match)) + if len(full_package) > 1: + print green("*")+" "+white(match) + print " ", "Latest version Available:",self.getVersion(full_package, search.VERSION_RELEASE) + print " ", self.getInstallationStatus(match) + print " ", "Description:",self.getDescription(self.getFullPath(match, full_package),self.getVersion(full_package, search.VERSION_SHORT)) + print " " + else: + print green("*")+" "+white(match)+" "+red("[ Masked ]") + print " " + + # + # private interface + # + def initResults(self): + self.packagematches = [] + + def getInstallationStatus(self,package): + installed_package = self.installcache.dep_bestmatch(package) + result = "" + version = self.getVersion(installed_package,search.VERSION_RELEASE) + if len(version) > 1: + result = "Latest version Installed: "+version + else: + result = "Latest version Installed: [ Not Installed ]" + return result + + def getDescription(self,ebuildPath,packageVersion): ## Gets description from latest ebuild ## + file = open(ebuildPath) + result = ""; + indescription=0 + while 1: + data = file.readline() + if data: + if self.re_description.match(data.upper()): + indescription=1 + p = self.re_description.split(data) + p = p[1].split('"') + result = p[0].strip() + if len(p)>1: + break + elif indescription==1: + if '"' in data: + p = data.split('"') + result = result+" "+p[0].strip() + indescription = 0 + else: + result = result+" "+data.strip() + else: + break; + result = replace(result, "${PV}", packageVersion) + result = replace(result, "${pv}", packageVersion) + result = replace(result, "${description}", "KDE " + packageVersion + " ") + result = replace(result, "\n", "") + file.close() + # format and wrap the description text nicely + wraplength=60 + formatted_result="" + while len(result)>wraplength: + lineposition=0 + position=wraplength + while result[lineposition+position]!=' ' and position != 0: + position = position-1 + if position==0: + position=wraplength + if len(formatted_result)==0: + formatted_result=result[:position] + else: + formatted_result=formatted_result+"\n "+result[:position] + result=result[position+1:] + if wraplength==60: + wraplength=73 + formatted_result=formatted_result+"\n "+result + return formatted_result + + def getFullPath(self,packageShortName,packageFullName): ## Returns the full path of the ebuild ## + absolute_path = '/usr/portage/' + strip(packageShortName) + package_parts = packageFullName.split("/") + result = absolute_path + "/" + package_parts[1] + ".ebuild" + return result + + def getVersion(self,full_package,detail): + if len(full_package) > 1: + package_parts = portage.catpkgsplit(full_package) + if detail == search.VERSION_RELEASE and package_parts[3] != 'r0': + result = package_parts[2]+ "-" + package_parts[3] + else: + result = package_parts[2] + else: + result = "" + return result + +#build our package digraph +def getsyslist(): + if os.path.exists(portage.profiledir+"/packages"): + pfile=portage.profiledir+"/packages" + else: + print "!!! Couldn't find",portage.profiledir+"/packages;" + print "\"system\" mode unavailable." + sys.exit(1) + myfile=open(pfile,"r") + mylines=myfile.readlines() + myfile.close() + + mynewlines=[] + for x in mylines: + myline=string.join(string.split(x)) + if not len(myline): + continue + elif myline[0]=="#": + continue + elif myline[0]!="*": + continue + myline=myline[1:] + mynewlines.append(myline.strip()) + + return mynewlines + +class depgraph: + + def __init__(self,mymode,myaction,myopts): + self.mymode=mymode + self.myaction=myaction + self.myopts=myopts + virts=portage.getvirtuals("/") + self.db={} + self.db["/"]={"virtuals":virts,"vartree":portage.vartree("/",virts),"porttree":portage.portagetree("/",virts),"bintree":portage.binarytree("/",virts)} + if portage.root!="/": + pr=portage.root + virts=portage.getvirtuals(pr) + self.db[pr]={"virtuals":virts,"vartree":portage.vartree(pr,virts),"porttree":portage.portagetree(pr,virts),"bintree":portage.binarytree(pr,virts)} + self.digraph=portage.digraph() + self.orderedkeys=[] + #the following is so we have an empty vartree (used in emerge update calculations) + self.emptytree=portage.vartree("/",virts,self.db["/"]["vartree"]) + self.emptytree.tree={} + if "--emptytree" in myopts: + print "Running in empty tree mode" + self.db["/"]["vartree"].tree=self.emptytree.tree + self.db["/"]["vartree"].populated=1 + self.db["/"]["vartree"].inject("virtual/glibc-1.0") + self.outdatedpackages=[] + def create(self,mybigkey,myparent=None,addme=1): + """creates the actual digraph of packages to merge. return 1 on success, 0 on failure + mybigkey = specification of package to merge; myparent = parent package (one depending on me); + addme = should I be added to the tree? (for the --onlydeps mode)""" + if mybigkey==None: + return + sys.stdout.write(".") + sys.stdout.flush() + if self.digraph.hasnode(mybigkey): + #if we've already hit this node before, we're already recursing on the dependencies. + #no need to recurse again. + if addme: + if myparent: + self.digraph.addnode(mybigkey,myparent) + return 1 + mytype,myroot,mykey=string.split(mybigkey) + if "--noreplace" in self.myopts: + if self.db[myroot]["vartree"].exists_specific(mykey): + print "\n>>>",mykey,"already merged in",myroot+", skipping...\n" + return 1 + if mytype=="binary": + if not self.db[portage.root]["bintree"].exists_specific(mykey): + print "\n\n!!!",mytype,mykey,"not found (possibly blocked by package.mask)\n" + sys.exit(1) + mypkgparts=portage.catpkgsplit(mykey) + mytbz2=xpak.tbz2(self.db[portage.root]["bintree"].getname(mykey)) + edepend=["",string.join(mytbz2.getelements("RDEPEND")," "),mytbz2.getfile("SLOT",mypkgparts[2])] + elif mytype=="ebuild": + if not self.db[myroot]["porttree"].exists_specific(mykey): + print "\n\n!!!",mytype,mykey,"not found (possibly blocked by package.mask)\n" + sys.exit(1) + mydep={} + myebuild=self.db[myroot]["porttree"].getname(mykey) + edepend=portage.doebuild(myebuild,"depend",myroot,1,edebug) + if edepend==1: + print "!!! emerge aborting." + sys.exit(1) + elif mytype=="blocks": + edepend=None + parenttype,parentroot,parentkey=string.split(myparent) + mykeyparts=portage.catpkgsplit(mykey) + parentkeyparts=portage.catpkgsplit(parentkey) + # only add blocking deps that aren't from the same package that is installing + if mykeyparts[0]!=parentkeyparts[0] or mykeyparts[1]!=parentkeyparts[1]: + self.digraph.addnode(mybigkey,myparent) + + if edepend: + mydep={} + if myroot=="/": + mydep["/"]=edepend[0]+" "+edepend[1] + else: + mydep["/"],mydep[myroot]=edepend + if addme: + self.digraph.addnode(mybigkey,myparent) + for dep in mydep.keys(): + if "--update"==self.myaction: + mycheck=self.emptytree.depcheck(mydep[dep]) + else: + mycheck=self.db[dep]["vartree"].depcheck(mydep[dep]) + if mycheck[0]==0: + print "!!! depgraph.create() error: string format:",mydep + return 0 + for x in mycheck[1]: + mynew=self.match(x,dep,mykey) + if not self.digraph.hasnode(mynew): + if addme: + if not self.create(mynew,mybigkey): + return 0 + else: + if not self.create(mynew,None): + return 0 + else: + self.digraph.addnode(mynew,mybigkey) + + return 1 + + def altlist(self): + mygraph=self.digraph.copy() + dolist=["/"] + retlist=[] + for x in self.db.keys(): + self.db[x]["merge"]=[] + if x not in dolist: + dolist.append(x) + while (not mygraph.empty()): + mycurkey=mygraph.firstzero() + if not mycurkey: + print "!!! Error: circular dependencies" + sys.exit(1) + splitski=string.split(mycurkey) + if "--update"==self.myaction: + if not self.db["/"]["vartree"].exists_specific(splitski[2]): + self.db["/"]["merge"].append(splitski) + else: + self.db[splitski[1]]["merge"].append(splitski) + mygraph.delnode(mycurkey) + for x in dolist: + for y in self.db[x]["merge"]: + retlist.append(y) + return retlist + + def syscreate(self,mylines=[]): + for myline in mylines: + if "--update"==self.myaction or "--rebuild"==self.myaction: + self.create(self.match(myline,mykey="update (likely old /var/db/pkg entry)")) + else: + mycheck=self.db[portage.root]["vartree"].depcheck(myline) + if mycheck[0]==0: + print "\n!!! Warning:",myline,"has an invalid depstring\n" + continue + if mycheck[1]==None: + continue + for x in mycheck[1]: + self.create(self.match(myline,mykey="syscreate1")) + + def match(self,mydep,myroot=portage.root,mykey=None): + # support mutual exclusive deps + mydep2=mydep + if mydep2[0]=="!": + mydep2=mydep[1:] + + if self.myaction=="--rebuild": + myeb=self.db[portage.root]["vartree"].dep_bestmatch(mydep2) + if not self.db[portage.root]["porttree"].exists_specific(myeb): + self.outdatedpackages.append(myeb) + return None + else: + myeb=self.db[portage.root]["porttree"].dep_bestmatch(mydep2) + if not myeb: + if not mykey: + print "\n!!! Warning: couldn't find match for",mydep + else: + print "\n!!! Warning: couldn't find match for",mydep,"in",mykey + return None + + # handle filtering of virtual deps for the rebuild action + if self.myaction=="--rebuild" and myeb[0:len("virtual")]=="virtual": + return None + + # handle filtering of non slot packages + if "noslot" in mymode and self.db[portage.root]["vartree"].slotted(myeb)==1: + return None + + if mydep[0]=="!": + myk="blocks "+myroot+" "+myeb + else: + if "--usepkg" in self.myopts: + mypk=self.db[portage.root]["bintree"].dep_bestmatch(mydep) + if myeb==mypk: + myk="binary "+portage.root+" "+mypk + else: + myk="ebuild "+myroot+" "+myeb + else: + myk="ebuild "+myroot+" "+myeb + + return myk + + def display(self,mylist): + for x in mylist: + if x[0]=="blocks": + addl=""+red("B")+" " + print "["+x[0]+" "+addl+"]",red(x[2]) + else: + if self.db[x[1]]["vartree"].exists_specific(x[2]): + addl=" "+yellow("R")+" " + elif self.db[x[1]]["vartree"].exists_specific_cat(x[2]): + addl=" "+turquoise("U")+" " + else: + addl=" "+green("N")+" " + print "["+x[0]+" "+addl+"]",x[2],"to",x[1] + + def outdated(self): + return self.outdatedpackages + + def merge(self,mylist): + returnme=0 + #check for blocking dependencies + for x in mylist: + if x[0]=="blocks": + print "\n!!! Error: the "+x[2]+" package conflicts with this package and both can't be installed on the same system together." + sys.exit(1) + + #above line used by --fetchonly + for x in mylist: + myroot=x[1] + print ">>> emerge",x[2],"to",x[1] + #the last argument in the portage.doebuild() tells doebuild to *not* do dep checking + #(emerge is already handling that) + y=self.db[myroot]["porttree"].getname(x[2]) + if x[0]=="ebuild": + if "--fetchonly" in self.myopts: + retval=portage.doebuild(y,"fetch",myroot,0,edebug) + if retval: + print + print "!!! Fetch for",y,"failed, continuing..." + print + returnme=1 + elif "--buildpkg" in self.myopts: + #create pkg, then merge pkg + retval=portage.doebuild(y,"clean",myroot,0,edebug) + if retval: + print "!!! emerge aborting on ",y,"." + sys.exit(1) + retval=portage.doebuild(y,"package",myroot,0,edebug) + if retval: + print "!!! emerge aborting on ",y,"." + sys.exit(1) + #dynamically update our database + self.db[portage.root]["bintree"].inject(x[2]) + mytbz2=self.db[portage.root]["bintree"].getname(x[2]) + retval=portage.pkgmerge(mytbz2,myroot) + if retval==None: + print "!!! emerge aborting on ",y,"." + sys.exit(1) + else: + retval=portage.doebuild(y,"clean",myroot,0,edebug) + if retval: + print "!!! emerge aborting on ",y,"." + sys.exit(1) + retval=portage.doebuild(y,"merge",myroot,0,edebug) + if retval: + print "!!! emerge aborting on ",y,"." + sys.exit(1) + #dynamically update our database + elif x[0]=="binary": + #merge the tbz2 + mytbz2=self.db[portage.root]["bintree"].getname(x[2]) + retval=portage.pkgmerge(mytbz2,x[1]) + if retval==None: + print "!!! emerge aborting on ",y,"." + sys.exit(1) + #need to check for errors + self.db[x[1]]["vartree"].inject(x[2]) + if "--autoclean" in self.myopts: + retval=portage.doebuild(y,"clean",myroot,0,edebug) + if retval: + print "!!! emerge aborting on ",y,"." + sys.exit(1) + #my doing an exit this way, --fetchonly can continue to try to + #fetch everything even if a particular download fails. + if "--fetchonly" 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 post_emerge(retval=0): + auxpat=re.compile('^([^-]*)(-\d+)?\.info(-\d+)?(\.gz)?') + global myopts + print + if "--pretend" in myopts: + sys.exit(retval) + root=portage.root + if not os.path.isdir(root+"usr/share/info"): + print " "+root+"usr/share/info doesn't exist, skipping info regeneration." + elif not os.path.exists("/usr/bin/install-info"): + print " /usr/bin/install-info doesn't exist; skipping info regeneration." + else: + print " "+green("*")+" Regenerating GNU info directory index..." + if os.path.exists(root+"usr/share/info/dir"): + os.rename(root+"usr/share/info/dir",root+"usr/share/info/dir.old") + icount=0 + badcount=0 + for x in os.listdir(root+"usr/share/info"): + aux=auxpat.search(x) + if not aux: + continue + auxgroups=aux.groups() + if not (auxgroups[1] or auxgroups[2]): + myso=commands.getstatusoutput("/usr/bin/install-info --dir-file="+root+"usr/share/info/dir "+root+"usr/share/info/"+x)[1] + if myso!="": + print auxgroups + badcount=badcount+1 + if "--verbose" in myopts: + print myso + icount=icount+1 + if badcount: + if "--verbose" not in myopts: + print " "+yellow("*")+" Processed",icount,"info files:",badcount,"errors; type "+green("emerge --verbose")+" to view errors." + else: + print " "+yellow("*")+" Processed",icount,"info files;",badcount,"errors." + + else: + print " "+green("*")+" Processed",icount,"info files." + if portage.settings["CONFIG_PROTECT"]: + #number of directories with some protect files in them + procount=0 + for x in string.split(portage.settings["CONFIG_PROTECT"]): + if os.path.isdir(x): + a=commands.getstatusoutput("cd "+x+"; find -iname '._cfg????_*'") + if a[0]!=0: + print " "+red("*")+" error scanning",x + else: + files=string.split(a[1]) + if files: + procount=procount+1 + print " "+yellow("* IMPORTANT:")+"",len(files),"config files in",x,"need updating." + if procount: + print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files." + print + sys.exit(retval) + +# general options that should be taken into account before any action +if not portage.settings.has_key("MAINTAINER_noclean"): + if not "--autoclean" in myopts: + myopts.append("--autoclean") +if "--debug" in myopts: + edebug=1 + +# process modes that aren't in the universal emerge interface format first +# this format is 'emerge --action --option --option [packageset]' +if "rsync" in mymode and not myaction: + if not os.path.exists("/usr/bin/rsync"): + print "!!! /usr/bin/rsync does not exist, so rsync support is disabled." + sys.exit(1) + rclean=0 + 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) + if "--clean" in myopts: + #we'll --delete files when we rsync + rclean=1 + mycommand="/usr/bin/rsync -rlptDv --stats --progress " + if rclean: + mycommand=mycommand+"--delete --exclude='distfiles/*' --exclude='packages/*' " + mycommand=mycommand+"rsync://cvs.gentoo.org/gentoo-x86-portage/* "+myportdir + print ">>> starting rsync with cvs.gentoo.org..." + #protect users that did not set a default umask + os.umask(022) + sys.exit(os.system(mycommand)) + +# HELP action +elif "--help"==myaction: + if len(mymode)==0: + print + print bold("Usage: ")+turquoise("emerge")+" [ "+green("action")+" ] [ "+green("options")+" ] [ "+turquoise("ebuildfile")+" | "+turquoise("tbz2file")+" | "+turquoise("dependency")+" ] ..." + print " "+turquoise("emerge")+" [ "+green("action")+" ] [ "+green("options")+" ] [ "+turquoise("system")+" | "+turquoise("world")+" | "+turquoise("noslot")+" ]" + print " "+turquoise("emerge")+" [ "+green("--clean")+" "+green("-c")+" ] "+turquoise("rsync") + print " "+turquoise("emerge")+" "+green("--help")+" "" "+green("-h")+" [ "+turquoise("rsync")+" | "+turquoise("system")+" | "+turquoise("world")+" | "+turquoise("noslot")+" | "+turquoise("config")+" ] " + print + print turquoise("Actions:") + print " "+green("--help")+" "+green("-h") + print " displays this help, an additional mode specifier provides" + print " detailed help about that mode instead" + print + print " "+green("--update")+" "+green("-u") + print " updates installed packages, this is typically used with",bold("world") + print " and",bold("system") + print + print " "+green("--zap")+" "+green("-z") + print " removes an installed package. the arguments can be in two" + print " different formats : /var/db/pkg/category/package-version" + print " or category/package." + print + print " "+green("--rebuild")+" "+green("-r") + print " forcably rebuild installed packages, this is typically used with" + print " "+bold("world"),"and",bold("system") + print + print " "+green("--search")+" "+green("-s") + print " searches for matches of the supplied string in the current local" + print " portage tree. The search string is a regular expression." + print " A few examples: " + print " "+bold("emerge --search \"^kde\"") + print " list all packages starting with kde" + print " "+bold("emerge --search \"gcc$\"") + print " list all packages ending with gcc" + print " "+bold("emerge --search \"\"")+" or" + print " "+bold("emerge --search \"*\"") + print " list all available packages " + print + print turquoise("Options:") + print " "+green("--autoclean")+" "+green("-a") + print " emerge normally cleans out the package-specific temporary" + print " build directory before it starts the building a package. With" + print " --autoclean, it will also clean the directory *after* the" + print " build completes. This option is automatically enabled for" + print " normal users, but maintainers can use this option to enable" + print " autocleaning." + print + print " "+green("--buildpkg")+" "+green("-b") + print " tell emerge to build binary packages for all ebuilds processed" + print " (in addition to actually merging the packages. Useful for" + print " maintainers or if you administrate multiple Gentoo Linux" + print " systems (build once, emerge tbz2s everywhere)." + print + print " "+green("--debug")+" "+green("-d") + print " Tell emerge to run the ebuild command in --debug mode. In this" + print " mode, the bash build environment will run with the -x option," + print " causing it to output verbose debug information print to stdout." + print " --debug is great for finding bash syntax errors." + print + print " "+green("--fetchonly")+" "+green("-f") + print " Instead of doing any package building, just perform fetches for" + print " all packages (main package as well as all dependencies.)" + print + print " "+green("--onlydeps")+" "+green("-o") + print " Only merge (or pretend to merge) the dependencies of the" + print " specified packages, not the packages themselves." + print + print " "+green("--pretend")+" "+green("-p") + print " instead of actually performing the merge, simply display what" + print " ebuilds and tbz2s *would* have been installed if --pretend" + print " weren't used. Using --pretend is strongly recommended before" + print " installing an unfamiliar package. In the printout, N = new," + print " U = upgrading, R = replacing" + print + print " "+green("--noreplace")+" "+green("-n") + print " Skip the packages specified on the command-line that have" + print " already been installed. Without this option, any packages," + print " ebuilds, or deps you specify on on the command-line *will* cause" + print " Portage to remerge the package, even if it is already installed." + print " Note that Portage will never remerge dependencies automatically." + print + print " "+green("--usepkg")+" "+green("-k") + print " tell emerge to use binary packages (from $PKGDIR) if they are" + print " available, thus possibly avoiding some time-consuming compiles." + print " This option is useful for CD installs; you can export" + print " PKGDIR=/mnt/cdrom/packages and then use this option to have" + print " emerge \"pull\" binary packages from the CD in order to satisfy" + print " dependencies." + print + print " "+green("--verbose")+" "+green("-v") + print " Tell emerge to run in verbose mode. Currently, this causes" + print " emerge to print out GNU info errors, if any." + print + elif "rsync" in mymode: + print + print bold("Usage: ")+turquoise("emerge")+" [ "+green("--clean")+" "+green("-c")+" ] "+turquoise("rsync") + print + print " \"emerge rsync\" initiates an rsync update with cvs.gentoo.org," + print " updating your Portage tree (typically in /usr/portage). This option" + print " will erase any changes that you have made to existing Portage files" + print " so be careful. \"emerge --clean rsync\" does the same thing as \"emerge" + print " rsync\", but files that no longer exist on our server are removed." + print + elif "system" in mymode: + print + print bold("Usage: ")+turquoise("emerge")+" [ "+green("action")+" ] "+" [ "+green("options")+" ] "+turquoise("system") + print + print " \"emerge system\" is the Portage system update command. When run, it" + print " will scan the etc/make.profile/packages file and determine what" + print " packages need to be installed so that your system meets the minimum" + print " requirements of your current system profile. Note that this doesn't" + print " necessarily bring your system up-to-date at all; instead, it just" + print " ensures that you have no missing parts. For example, if your system" + print " profile specifies that you should have sys-apps/iptables installed" + print " and you don't, then \"emerge system\" will install it (the most" + print " recent version that matches the profile spec) for you. It's always a" + print " good idea to do an \"emerge --pretend system\" before an \"emerge" + print " system\", just so you know what emerge is planning to do." + print + elif "world" in mymode: + print + print bold("Usage: ")+turquoise("emerge")+" [ "+green("action")+" ] "+" [ "+green("options")+" ] "+turquoise("world") + print + elif "noslot" in mymode: + print + print bold("Usage: ")+turquoise("emerge")+" [ "+green("action")+" ] "+" [ "+green("options")+" ] "+turquoise("noslot") + print + elif "config" in mymode: + outstuff=green("Config file management support (preliminary)")+""" + +Portage has a special feature called "config file protection". The purpose of +this feature is to prevent new package installs from clobbering existig +configuration files. By default, config file protection is turned on for /etc +and the KDE configuration dirs; more may be added in the future. + +When Portage installs a file into a protected directory tree like /etc, any +existing files will not be overwritten. If a file of the same name already +exists, Portage will change the name of the to-be- installed file from 'foo' to +'._cfg0000_foo'. If '._cfg0000_foo' already exists, this name becomes +'._cfg0001_foo', etc. In this way, existing files are not overwritten, +allowing the administrator to manually merge the new config files and avoid any +unexpected changes. + +In addition to protecting overwritten files, Portage will not delete any files +from a protected directory when a package is unmerged. While this may be a +little bit untidy, it does prevent potentially valuable config files from being +deleted, which is of paramount importance. + +Protected directories are set using the CONFIG_PROTECT variable, normally +defined in /etc/make.globals. Directory exceptions to the CONFIG_PROTECTed +directories can be specified using the CONFIG_PROTECT_MASK variable. To find +files that need to be updated in /etc, type: + +# find /etc -iname '._cfg????_*' + +You can disable this feature by setting CONFIG_PROTECT="" in /etc/make.conf. +Then, Portage will mercilessly auto-update your config files. Alternatively, +you can leave Config File Protection on but tell Portage that it can overwrite +files in certain specific /etc subdirectories. For example, if you wanted +Portage to automatically update your rc scripts and your wget configuration, +but didn't want any other changes made without your explicit approval, you'd +add this to /etc/make.conf: + +CONFIG_PROTECT_MASK="/etc/wget /etc/rc.d" + +""" + print outstuff + +# SEARCH action +elif "--search"==myaction: + if not myfiles: + print + print "No search terms provided." + print + else: + searchinstance = search() + for mysearch in myfiles: + searchinstance.setKey(mysearch) + searchinstance.execute() + searchinstance.output() + +# ZAP action +elif "--zap"==myaction: + if not myfiles and not "noslot" in mymode: + print + print "No packages to unmerge have been provided." + print + else: + full_paths={} + full_ebuild_paths={} + full_package_paths={} + non_slot_packages=[] + + var_path=portage.root+"var/db/pkg" + if "noslot" in mymode: + localtree=portage.vartree(portage.root) + for x in localtree.getallnodes(): + if localtree.slotted(x)==0: + mymatches=localtree.dep_match(x) + for package in mymatches: + myfullpaths=localtree.getebuildpaths(package) + for full_path in myfullpaths : + if not os.path.exists(full_path): + print "The ebuild '"+full_path+"' couldn't be found." + print "Your portage installation tree seems to be corrupted." + else: + full_package_paths[full_path]=package + else: + # process all arguments, verify if they can be resolved to an installed + # ebuild file and add the absolute paths of these ebuild to a list + for x in myfiles: + + # an absolute path has been given + if (x[0]=='/'): + path_parts=split(x, '/') + if len(path_parts) != 6: + print "When providing an absolute path it should be" + print "in the following format : "+var_path+"/category/package" + print "The path '"+x+"' doesn't respect this." + sys.exit(1) + elif not os.path.exists(x): + print "The path '"+x+"' doesn't exist." + sys.exit(1) + elif -1 == find(x, var_path): + print "The path '"+x+"' didn't commence with '"+var_path+"'." + sys.exit(1) + else: + # check if the SLOT file is present, and get the package version + # from the PF file in that case + package_slot_path=strip(x)+"/SLOT" + package_pf_path=strip(x)+"/PF" + if os.path.exists(package_pf_path): + package_pf_file=open(package_pf_path) + package_pf=package_pf_file.readline().strip() + package_pf_file.close() + else: + package_pf=path_parts[5] + full_path=strip(x)+"/"+package_pf+".ebuild" + if not os.path.exists(full_path): + print "The ebuild '"+full_path+"' couldn't be found." + print "Your portage installation tree seems to be corrupted." + else: + path_parts=split(full_path, "/") + full_ebuild_paths[full_path]=path_parts[4]+"/"+package_pf + + # a category and package name have been given + else: + localtree=portage.vartree(portage.root) + mymatches=localtree.dep_match(x) + # if no matches were found, try again by adding a '=' dep symbol if no + # dep symbols are already present + if not mymatches and x[0] not in ('<','>','=','~'): + mymatches=localtree.dep_match("="+x) + + # only loops over the matches if they were found + if mymatches: + for package in mymatches: + myfullpaths=localtree.getebuildpaths(package) + for full_path in myfullpaths : + if not os.path.exists(full_path): + print "The ebuild '"+full_path+"' couldn't be found." + print "Your portage installation tree seems to be corrupted." + else: + full_package_paths[full_path]=package + + # determine what the non slot packages are + if len(full_package_paths) > 0: + # determine the latest installed packages of each cat/pkg key + full_paths_keys=full_package_paths.keys() + # sort the ebuild paths + full_paths_keys.sort() + previous_package_set=None + for full_path in full_paths_keys: + # construct the key that will be used to determine when a new package set + # is being processed, the package slot is taken into account for this + package_parts=portage.pkgsplit(full_package_paths[full_path]) + slot_path=dirname(full_path)+"/SLOT" + if not os.path.exists(slot_path): + package_slot=package_parts[1] + non_slot_packages.append(package_parts[0]+"-"+package_parts[1]) + + full_paths=full_ebuild_paths.keys() + full_paths.extend(full_package_paths.keys()) + + if len(full_paths)==0: + print "Couldn't find any matching installed packages." + sys.exit(1) + else: + if "--pretend" in myopts: + print + print "The are the packages that I would unmerge :" + print + else: + print + print "The following packages are going to be unmerged :" + print + # this makes revisions come before slot versions + # and therefor unmerges the older packages first + full_paths.sort() + for full_path in full_paths: + path_parts=split(full_path, "/") + print " "+path_parts[4]+"/"+path_parts[5] + + if len(non_slot_packages)>0: + print + if "--verbose" not in myopts: + print " "+yellow("* IMPORTANT:"),len(non_slot_packages),"non slot packages; use "+green("--verbose")+" to view details." + else: + print " "+yellow("* IMPORTANT:"),len(non_slot_packages),"non slot packages" + print " "+yellow("*")+" These packages have been merged with an old version of portage that didn't" + print " "+yellow("*")+" support binary compatibility slots. This means that each package with a" + print " "+yellow("*")+" different version number will be considered different and only older versions" + print " "+yellow("*")+" of different releases will be unmerged automatically." + print " "+yellow("*")+" To get rid of all non slot packages, you can rebuild your system with" + print " "+yellow("*")+" "+green("emerge --noslot rebuild")+"." + print + for non_slot_package in non_slot_packages: + print " "+non_slot_package + + if "--pretend" in myopts: + print + else: + secs=string.atoi(portage.settings["UNMERGE_DELAY"]) + if secs > 0: + print + print "Waiting",secs,"seconds to make sure that you want these" + print "packages to be removed ..." + while secs > 0: + sys.stdout.write(str(secs)+" ") + sys.stdout.flush() + time.sleep(1) + secs = secs-1 + print secs + for full_path in full_paths: + print "Unmerging "+os.path.basename(full_path)+" ..." + retval=portage.doebuild(full_path,"unmerge",portage.root,0,edebug) + post_emerge() + +# REBUILD action +elif "--rebuild"==myaction: + if not "system" in mymode and not "world" in mymode and not "noslot" in mymode: + print + print " "+red("* WARNING:"),green("emerge --rebuild"),"shouldn't be used for regular packages" + print " "+red("*"),"it's only intended to be used with",green("system")+", "+green("world")+", and",green("noroot") + print + else: + if "--pretend" in myopts: + print + print "These are the packages that I would rebuild, in order." + print + + if "system" in mymode: + mydepgraph=depgraph(mymode,myaction,myopts) + print "Calculating system dependencies", + mydepgraph.syscreate(getsyslist()) + print " done!" + elif "world" in mymode or "noslot" in mymode: + mydepgraph=depgraph(mymode,myaction,myopts) + print "Calculating world dependencies", + mydepgraph.syscreate(mydepgraph.db["/"]["vartree"].getallnodes()) + print " done!" + + if "--pretend" in myopts: + mydepgraph.display(mydepgraph.altlist()) + + myoutdated=mydepgraph.outdated() + if len(myoutdated): + if "--verbose" not in myopts: + print + print " "+yellow("* IMPORTANT:"),len(myoutdated),"packages aren't available anymore; use "+green("--verbose")+" for details." + else: + print + print " "+yellow("* IMPORTANT:"),len(myoutdated),"packages aren't available anymore" + print " "+yellow("*")+" Your portage tree doesn't contain the ebuilds anymore that correspond to the" + print " "+yellow("*")+" following packages. This means that portage is unable to rebuild them." + print " "+yellow("*")+" Instead you should upgrade to the latest versions or install possible" + print " "+yellow("*")+" alternative packages that provide the same functionalities." + myoutdated.sort() + for mypackage in myoutdated: + print " "+mypackage + else: + mydepgraph.merge(mydepgraph.altlist()) + post_emerge() + +# INSTALL and UPDATE action +elif "--update"==myaction or not myaction: + if not myaction and "world" in mymode: + print + print " "+red("* WARNING:"),green("emerge world"),"can't be used without an action" + print " "+red("*"),green("world"),"is only intended to be used with",green("emerge --update") + print + else: + if "--pretend" in myopts: + print + print "These are the packages that I would merge, in order." + print + + if "system" in mymode: + mydepgraph=depgraph(mymode,myaction,myopts) + print "Calculating system dependencies", + mydepgraph.syscreate(getsyslist()) + print " done!" + elif "world" in mymode: + mydepgraph=depgraph(mymode,myaction,myopts) + print "Calculating world dependencies", + mydepgraph.syscreate(mydepgraph.db["/"]["vartree"].getallnodes()) + print " done!" + elif "noslot" in mymode: + mydepgraph=depgraph(mymode,myaction,myopts) + print "Calculating noslot dependencies", + mydepgraph.syscreate(mydepgraph.db["/"]["vartree"].getallnodes()) + print " done!" + else: + mydepgraph=depgraph(mymode,myaction,myopts) + if not myfiles: + post_emerge() + #we don't have any files to process; skip this step and exit + print "Calculating dependencies", + for mypkg in myfiles: + if mypkg[-5:]==".tbz2": + mytype="binary" + mytbz2=xpak.tbz2(mypkg) + mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.basename(mypkg)[:-5] + elif mypkg[-7:]==".ebuild": + mytype="ebuild" + mykey=os.path.basename(os.path.abspath(mypkg+"/../.."))+"/"+os.path.basename(mypkg)[:-7] + else: + mykey="" + if "--usepkg" in myopts: + mykey=mydepgraph.db[portage.root]["bintree"].dep_bestmatch(mypkg) + mytype="binary" + if not mykey: + mykey=mydepgraph.db[portage.root]["porttree"].dep_bestmatch(mypkg) + mytype="ebuild" + if not mykey: + print "!!! Couldn't find match for",mypkg+"; aborting." + sys.exit(1) + # else: + # print "!!! Error:",x,"is neither an ebuild nor a .tbz2 package." + # sys.exit(1) + mydepgraph.create(mytype+" "+portage.root+" "+mykey,None,"--onlydeps" not in myopts) + print " done!" + + if "--pretend" in myopts: + mydepgraph.display(mydepgraph.altlist()) + else: + mydepgraph.merge(mydepgraph.altlist()) + post_emerge() + -- cgit v1.2.3-1-g7c22