aboutsummaryrefslogtreecommitdiff
path: root/pym
diff options
context:
space:
mode:
authorBrian Harring <ferringb@gentoo.org>2005-03-07 04:00:30 +0000
committerBrian Harring <ferringb@gentoo.org>2005-03-07 04:00:30 +0000
commit0106830ad0e1624cce29bfd0d45e1f47b440fc17 (patch)
treee3fd9041eeb7499f30960489b04328a05fb56373 /pym
parentAdded a check to make sure the file exists before working with it, when (diff)
downloadportage-cvs-0106830ad0e1624cce29bfd0d45e1f47b440fc17.tar.gz
portage-cvs-0106830ad0e1624cce29bfd0d45e1f47b440fc17.tar.bz2
portage-cvs-0106830ad0e1624cce29bfd0d45e1f47b440fc17.zip
eclass_cache is now eclass_cache.py:cache, config is config.py:config.
Shifted support functions around as needed, left references in portage.py (from blah import) where relevant.
Diffstat (limited to 'pym')
-rw-r--r--pym/config.py811
-rw-r--r--pym/eclass_cache.py109
-rw-r--r--pym/portage.py1071
-rw-r--r--pym/portage_dep.py39
-rw-r--r--pym/portage_file.py81
-rw-r--r--pym/portage_util.py48
6 files changed, 1091 insertions, 1068 deletions
diff --git a/pym/config.py b/pym/config.py
new file mode 100644
index 0000000..93fd217
--- /dev/null
+++ b/pym/config.py
@@ -0,0 +1,811 @@
+import os, copy, re
+import portage_const
+import sys #has a few daft sys.exit
+
+import portage_util, portage_versions, portage_dep
+from portage_util import getconfig, grabfile, grab_multiple, grabfile_package, grabdict, writemsg, grabdict_package, \
+ abssymlink, best_match_to_list, flatten
+
+from portage_file import listdir
+from portage_data import portage_gid
+
+class config:
+ def clone(self, clone):
+ self.incrementals = copy.deepcopy(clone.incrementals)
+ self.profile_path = copy.deepcopy(clone.profile_path)
+
+ self.module_priority = copy.deepcopy(clone.module_priority)
+ self.modules = copy.deepcopy(clone.modules)
+
+ self.depcachedir = copy.deepcopy(clone.depcachedir)
+
+ self.packages = copy.deepcopy(clone.packages)
+ self.virtuals = copy.deepcopy(clone.virtuals)
+
+ self.use_defs = copy.deepcopy(clone.use_defs)
+ self.usemask = copy.deepcopy(clone.usemask)
+
+ self.configlist = copy.deepcopy(clone.configlist)
+ self.configlist[-1] = os.environ.copy()
+ self.configdict = { "globals": self.configlist[0],
+ "defaults": self.configlist[1],
+ "conf": self.configlist[2],
+ "pkg": self.configlist[3],
+ "auto": self.configlist[4],
+ "backupenv": self.configlist[5],
+ "env": self.configlist[6] }
+ self.backupenv = copy.deepcopy(clone.backupenv)
+ self.pusedict = copy.deepcopy(clone.pusedict)
+ self.categories = copy.deepcopy(clone.categories)
+ self.pkeywordsdict = copy.deepcopy(clone.pkeywordsdict)
+ self.pmaskdict = copy.deepcopy(clone.pmaskdict)
+ self.punmaskdict = copy.deepcopy(clone.punmaskdict)
+ self.prevmaskdict = copy.deepcopy(clone.prevmaskdict)
+ self.pprovideddict = copy.deepcopy(clone.pprovideddict)
+ self.lookuplist = copy.deepcopy(clone.lookuplist)
+ self.uvlist = copy.deepcopy(clone.uvlist)
+ self.dirVirtuals = copy.deepcopy(clone.dirVirtuals)
+ self.treeVirtuals = copy.deepcopy(clone.treeVirtuals)
+ self.userVirtuals = copy.deepcopy(clone.userVirtuals)
+
+ def __init__(self, clone=None, mycpv=None, config_profile_path=portage_const.PROFILE_PATH, config_incrementals=None):
+
+ self.already_in_regenerate = 0
+
+ self.locked = 0
+ self.mycpv = None
+ self.puse = []
+ self.modifiedkeys = []
+
+ self.virtuals = {}
+ self.v_count = 0
+
+ if clone:
+ self.clone( clone )
+ else:
+ self.depcachedir = portage_const.DEPCACHE_PATH
+
+ if not os.path.exists(config_profile_path):
+ writemsg("config_profile_path not specified to class config\n")
+ sys.exit(1)
+ self.profile_path = config_profile_path
+
+ if not config_incrementals:
+ import traceback
+ traceback.print_stack()
+ writemsg("incrementals not specified to class config\n")
+ writemsg("sayonara, sucker.\n")
+ sys.exit(1)
+ self.incrementals = copy.deepcopy(config_incrementals)
+
+ self.module_priority = ["user","default"]
+ self.modules = {}
+ self.modules["user"] = getconfig(portage_const.MODULES_FILE_PATH)
+ if self.modules["user"] == None:
+ self.modules["user"] = {}
+ self.modules["default"] = {
+ "portdbapi.metadbmodule": "portage_db_flat.database",
+ "portdbapi.auxdbmodule": "portage_db_flat.database",
+ "eclass_cache.dbmodule": "portage_db_cpickle.database",
+ }
+
+ self.usemask=[]
+ self.configlist=[]
+ self.backupenv={}
+ # back up our incremental variables:
+ self.configdict={}
+ # configlist will contain: [ globals, defaults, conf, pkg, auto, backupenv (incrementals), origenv ]
+
+ # The symlink might not exist or might not be a symlink.
+ try:
+ self.profiles=[abssymlink(self.profile_path)]
+ except (OSError, IOErrror):
+ self.profiles=[self.profile_path]
+
+ mypath = self.profiles[0]
+ while os.path.exists(mypath+"/parent"):
+ mypath = os.path.normpath(mypath+"///"+grabfile(mypath+"/parent")[0])
+ if os.path.exists(mypath):
+ self.profiles.insert(0,mypath)
+
+ if os.environ.get("PORTAGE_CALLER",'') == "repoman":
+ pass
+ else:
+ # XXX: This should depend on ROOT?
+ if os.path.exists("/"+portage_const.CUSTOM_PROFILE_PATH):
+ self.profiles.append("/"+portage_const.CUSTOM_PROFILE_PATH)
+
+ self.packages_list = grab_multiple("packages", self.profiles, grabfile_package)
+ self.packages = stack_lists(self.packages_list, incremental=1)
+ del self.packages_list
+ #self.packages = grab_stacked("packages", self.profiles, grabfile, incremental_lines=1)
+
+ # revmaskdict
+ self.prevmaskdict={}
+ for x in self.packages:
+ mycatpkg=portage_dep.dep_getkey(x)
+ if not self.prevmaskdict.has_key(mycatpkg):
+ self.prevmaskdict[mycatpkg]=[x]
+ else:
+ self.prevmaskdict[mycatpkg].append(x)
+
+ # get profile-masked use flags -- INCREMENTAL Child over parent
+ usemask_lists = grab_multiple("use.mask", self.profiles, grabfile)
+ self.usemask = stack_lists(usemask_lists, incremental=True)
+ del usemask_lists
+ use_defs_lists = grab_multiple("use.defaults", self.profiles, grabdict)
+ self.use_defs = stack_dictlist(use_defs_lists, incremental=True)
+ del use_defs_lists
+
+ try:
+ mygcfg_dlists = grab_multiple("make.globals", self.profiles+["/etc"], getconfig)
+ self.mygcfg = stack_dicts(mygcfg_dlists, incrementals=portage_const.INCREMENTALS, ignore_none=1)
+
+ if self.mygcfg == None:
+ self.mygcfg = {}
+ except SystemExit, e:
+ raise
+ except Exception, e:
+ writemsg("!!! %s\n" % (e))
+ writemsg("!!! Incorrect multiline literals can cause this. Do not use them.\n")
+ writemsg("!!! Errors in this file should be reported on bugs.gentoo.org.\n")
+ sys.exit(1)
+ self.configlist.append(self.mygcfg)
+ self.configdict["globals"]=self.configlist[-1]
+
+ self.mygcfg = {}
+ if self.profiles:
+ try:
+ mygcfg_dlists = grab_multiple("make.defaults", self.profiles, getconfig)
+ self.mygcfg = stack_dicts(mygcfg_dlists, incrementals=self.incrementals[:], ignore_none=1)
+ #self.mygcfg = grab_stacked("make.defaults", self.profiles, getconfig)
+ if self.mygcfg == None:
+ self.mygcfg = {}
+ except SystemExit, e:
+ raise
+ except Exception, e:
+ writemsg("!!! %s\n" % (e))
+ writemsg("!!! 'rm -Rf /usr/portage/profiles; emerge sync' may fix this. If it does\n")
+ writemsg("!!! not then please report this to bugs.gentoo.org and, if possible, a dev\n")
+ writemsg("!!! on #gentoo (irc.freenode.org)\n")
+ sys.exit(1)
+ self.configlist.append(self.mygcfg)
+ self.configdict["defaults"]=self.configlist[-1]
+
+ try:
+ # XXX: Should depend on root?
+ self.mygcfg=getconfig("/"+portage_const.MAKE_CONF_FILE)
+ if self.mygcfg == None:
+ self.mygcfg = {}
+ except SystemExit, e:
+ raise
+ except Exception, e:
+ writemsg("!!! %s\n" % (e))
+ writemsg("!!! Incorrect multiline literals can cause this. Do not use them.\n")
+ sys.exit(1)
+
+
+ self.configlist.append(self.mygcfg)
+ self.configdict["conf"]=self.configlist[-1]
+
+ self.configlist.append({})
+ self.configdict["pkg"]=self.configlist[-1]
+
+ #auto-use:
+ self.configlist.append({})
+ self.configdict["auto"]=self.configlist[-1]
+
+ #backup-env (for recording our calculated incremental variables:)
+ self.backupenv = os.environ.copy()
+ self.configlist.append(self.backupenv) # XXX Why though?
+ self.configdict["backupenv"]=self.configlist[-1]
+
+ self.configlist.append(os.environ.copy())
+ self.configdict["env"]=self.configlist[-1]
+
+ # make lookuplist for loading package.*
+ self.lookuplist=self.configlist[:]
+ self.lookuplist.reverse()
+
+ archlist = grabfile(self["PORTDIR"]+"/profiles/arch.list")
+ self.configdict["conf"]["PORTAGE_ARCHLIST"] = ' '.join(archlist)
+
+ if os.environ.get("PORTAGE_CALLER",'') == "repoman":
+ # repoman shouldn't use local settings.
+ locations = [self["PORTDIR"] + "/profiles"]
+ self.pusedict = {}
+ self.pkeywordsdict = {}
+ self.punmaskdict = {}
+ else:
+ locations = [self["PORTDIR"] + "/profiles", portage_const.USER_CONFIG_PATH]
+
+ # Never set anything in this. It's for non-originals.
+ self.pusedict=grabdict_package(portage_const.USER_CONFIG_PATH+"/package.use")
+
+ #package.keywords
+ pkgdict=grabdict_package(portage_const.USER_CONFIG_PATH+"/package.keywords")
+ self.pkeywordsdict = {}
+
+ for key in pkgdict.keys():
+ # default to ~arch if no specific keyword is given
+ if not pkgdict[key]:
+ mykeywordlist = []
+ if self.configdict["defaults"] and self.configdict["defaults"].has_key("ACCEPT_KEYWORDS"):
+ groups = self.configdict["defaults"]["ACCEPT_KEYWORDS"].split()
+ else:
+ groups = []
+ for keyword in groups:
+ if not keyword[0] in "~-":
+ mykeywordlist.append("~"+keyword)
+ pkgdict[key] = mykeywordlist
+ cp = portage_dep.dep_getkey(key)
+ if not self.pkeywordsdict.has_key(cp):
+ self.pkeywordsdict[cp] = {}
+ self.pkeywordsdict[cp][key] = pkgdict[key]
+
+ #package.unmask
+ pkgunmasklines = grabfile_package(portage_const.USER_CONFIG_PATH+"/package.unmask")
+ self.punmaskdict = {}
+ for x in pkgunmasklines:
+ mycatpkg=portage_dep.dep_getkey(x)
+ L = self.punmaskdict.setdefault(mycatpkg,[])
+ L.append(x)
+
+ #getting categories from an external file now
+ categories = grab_multiple("categories", locations, grabfile)
+ self.categories = stack_lists(categories, incremental=1)
+ del categories
+
+ # get virtuals -- needs categories
+ self.loadVirtuals('/')
+
+ #package.mask
+ # Don't enable per profile package.mask unless the profile
+ # specifically depends on the >=portage-2.0.51 using
+ # <portage-2.0.51 syntax.
+ # don't hardcode portage versions into portage. It's not nice.
+ if self.profiles and (">=sys-apps/portage-2.0.51" in self.packages \
+ or "*>=sys-apps/portage-2.0.51" in self.packages):
+ pkgmasklines = grab_multiple("package.mask", self.profiles + locations, grabfile_package)
+ else:
+ pkgmasklines = grab_multiple("package.mask", locations, grabfile_package)
+ pkgmasklines = stack_lists(pkgmasklines, incremental=1)
+
+ self.pmaskdict = {}
+ for x in pkgmasklines:
+ mycatpkg = portage_dep.dep_getkey(x)
+ L = self.pmaskdict.setdefault(mycatpkg,[])
+ L.append(x)
+
+ pkgprovidedlines = grab_multiple("package.provided", self.profiles, grabfile)
+ pkgprovidedlines = stack_lists(pkgprovidedlines, incremental=1)
+
+ self.pprovideddict = {}
+ for x in pkgprovidedlines:
+ cpv=portage_versions.catpkgsplit(x)
+ if not x:
+ continue
+ mycatpkg=portage_dep.dep_getkey(x)
+ L = self.pprovideddict.setdefault(mycatpkg,[])
+ L.append(x)
+
+
+ self.lookuplist=self.configlist[:]
+ self.lookuplist.reverse()
+
+ useorder=self["USE_ORDER"]
+ if not useorder:
+ # reasonable defaults; this is important as without USE_ORDER,
+ # USE will always be "" (nothing set)!
+ useorder="env:pkg:conf:auto:defaults"
+ useordersplit=useorder.split(":")
+
+ self.uvlist=[]
+ for x in useordersplit:
+ if x in self.configdict:
+ if "PKGUSE" in self.configdict[x]:
+ # Delete PkgUse, Not legal to set.
+ del self.configdict[x]["PKGUSE"]
+ #prepend db to list to get correct order
+ self.uvlist.insert(0,self.configdict[x])
+
+ self.configdict["env"]["PORTAGE_GID"]=str(portage_gid)
+ self.backupenv["PORTAGE_GID"]=str(portage_gid)
+
+ if self.has_key("PORT_LOGDIR") and not self["PORT_LOGDIR"]:
+ # port_logdir is defined, but empty. this causes a traceback in doebuild.
+ writemsg(yellow("!!!")+" PORT_LOGDIR was defined, but set to nothing.\n")
+ writemsg(yellow("!!!")+" Disabling it. Please set it to a non null value.\n")
+ del self["PORT_LOGDIR"]
+
+ if self["PORTAGE_CACHEDIR"]:
+ # XXX: Deprecated -- April 15 -- NJ
+ writemsg(yellow(">>> PORTAGE_CACHEDIR has been deprecated!")+"\n")
+ writemsg(">>> Please use PORTAGE_DEPCACHEDIR instead.\n")
+ self.depcachedir = self["PORTAGE_CACHEDIR"]
+ del self["PORTAGE_CACHEDIR"]
+
+ if self["PORTAGE_DEPCACHEDIR"]:
+ #the auxcache is the only /var/cache/edb/ entry that stays at / even when "root" changes.
+ # XXX: Could move with a CHROOT functionality addition.
+ self.depcachedir = self["PORTAGE_DEPCACHEDIR"]
+ del self["PORTAGE_DEPCACHEDIR"]
+
+ overlays = self["PORTDIR_OVERLAY"].split()
+ if overlays:
+ new_ov=[]
+ for ov in overlays:
+ ov=os.path.normpath(ov)
+ if os.path.isdir(ov):
+ new_ov.append(ov)
+ else:
+ writemsg(red("!!! Invalid PORTDIR_OVERLAY (not a dir): "+ov+"\n"))
+ self["PORTDIR_OVERLAY"] = " ".join(new_ov)
+ self.backup_changes("PORTDIR_OVERLAY")
+
+ self.regenerate()
+
+
+ self.features = portage_util.unique_array(self["FEATURES"].split())
+ self.features.sort()
+
+ #XXX: Should this be temporary? Is it possible at all to have a default?
+ if "gpg" in self.features:
+ if not os.path.exists(self["PORTAGE_GPG_DIR"]) or not os.path.isdir(self["PORTAGE_GPG_DIR"]):
+ writemsg("PORTAGE_GPG_DIR is invalid. Removing gpg from FEATURES.\n")
+ self.features.remove("gpg")
+ self["FEATURES"] = " ".join(self.features)
+ self.backup_changes("FEATURES")
+
+ if mycpv:
+ self.setcpv(mycpv)
+
+ def autouse(self, myvartree, use_cache=1):
+ "returns set of USE variables auto-enabled due to packages being installed"
+ # XXX: harring wonders why profiledir is checked here...
+ from portage import profiledir
+ if profiledir==None:
+ return ""
+ myusevars=""
+ for myuse in self.use_defs:
+ dep_met = True
+ for mydep in self.use_defs[myuse]:
+ if not myvartree.dep_match(mydep,use_cache=True):
+ dep_met = False
+ break
+ if dep_met:
+ myusevars += " "+myuse
+ return myusevars
+
+
+
+ def loadVirtuals(self,root):
+ self.virtuals = self.getvirtuals(root)
+
+ def load_best_module(self,property_string):
+ best_mod = best_from_dict(property_string,self.modules,self.module_priority)
+ return load_mod(best_mod)
+
+ def lock(self):
+ self.locked = 1
+
+ def unlock(self):
+ self.locked = 0
+
+ def modifying(self):
+ if self.locked:
+ raise Exception, "Configuration is locked."
+
+ def backup_changes(self,key=None):
+ if key and self.configdict["env"].has_key(key):
+ self.backupenv[key] = copy.deepcopy(self.configdict["env"][key])
+ else:
+ raise KeyError, "No such key defined in environment: %s" % key
+
+ def reset(self,keeping_pkg=0,use_cache=1):
+ "reset environment to original settings"
+ envdict = self.configdict["env"]
+ # reinitialize env values to those of backupenv
+ envdict.clear()
+ envdict.update(self.backupenv)
+ self.modifiedkeys = []
+ if not keeping_pkg:
+ self.puse = ""
+ self.configdict["pkg"].clear()
+ self.regenerate(use_cache=use_cache)
+
+ def load_infodir(self,infodir):
+ if self.configdict.has_key("pkg"):
+ self.configdict["pkg"].clear()
+ else:
+ writemsg("No pkg setup for settings instance?\n")
+ sys.exit(17)
+
+ if os.path.exists(infodir):
+ if os.path.exists(infodir+"/environment"):
+ self.configdict["pkg"]["PORT_ENV_FILE"] = infodir+"/environment"
+ elif os.path.exists(infodir+"/environment.bz2"):
+ self.configdict["pkg"]["PORT_ENV_FILE"] = infodir+"/environment.bz2"
+# else:
+# print "wth, no env found in the infodir, '%s'" % infodir
+# import traceback
+# traceback.print_stack()
+# sys.exit(15)
+ myre = re.compile('^[A-Z]+$')
+ for filename in listdir(infodir,filesonly=1):
+ if myre.match(filename):
+ try:
+ mydata = open(infodir+"/"+filename).read().strip()
+ if len(mydata)<2048:
+ if filename == "USE":
+ self.configdict["pkg"][filename] = "-* "+mydata
+ else:
+ self.configdict["pkg"][filename] = mydata
+ except SystemExit, e:
+ raise
+ except:
+ writemsg("!!! Unable to read file: %s\n" % infodir+"/"+filename)
+ pass
+ return 1
+ return 0
+
+ def setcpv(self,mycpv,use_cache=1):
+ self.modifying()
+ self.mycpv = mycpv
+ self.pusekey = best_match_to_list(self.mycpv, self.pusedict.keys())
+ if self.pusekey:
+ newpuse = " ".join(self.pusedict[self.pusekey])
+ else:
+ newpuse = ""
+ if newpuse == self.puse:
+ return
+ self.puse = newpuse
+ self.configdict["pkg"]["PKGUSE"] = self.puse[:] # For saving to PUSE file
+ self.configdict["pkg"]["USE"] = self.puse[:] # this gets appended to USE
+ self.reset(keeping_pkg=1,use_cache=use_cache)
+
+ def setinst(self,mycpv,mydbapi):
+ """
+ Grab the virtuals this package provides and add them into the tree virtuals.
+ """
+ provides = mydbapi.aux_get(mycpv, ["PROVIDE"])[0]
+
+ #XXX HACK
+ from portage import portdbapi
+
+ if isinstance(mydbapi, portdbapi):
+ myuse = self["USE"]
+ else:
+ myuse = mydbapi.aux_get(mycpv, ["USE"])[0]
+ virts = flatten(portage_dep.use_reduce(portage_dep.paren_reduce(provides), uselist=myuse.split()))
+
+ cp = portage_dep.dep_getkey(mycpv)
+ for virt in virts:
+ virt = portage_dep.dep_getkey(virt)
+ if not self.treeVirtuals.has_key(virt):
+ self.treeVirtuals[virt] = []
+ self.treeVirtuals[virt] = portage_util.unique_array(self.treeVirtuals[virt]+[cp])
+ # Reconstruct the combined virtuals.
+ val = stack_dictlist( [self.userVirtuals, self.treeVirtuals]+self.dirVirtuals, incremental=1)
+ for v in val.values():
+ v.reverse()
+ self.virtuals = val
+
+ def regenerate(self,useonly=0,use_cache=1):
+ if self.already_in_regenerate:
+ # XXX: THIS REALLY NEEDS TO GET FIXED. autouse() loops.
+ writemsg("!!! Looping in regenerate.\n",1)
+ return
+ else:
+ self.already_in_regenerate = 1
+
+ if useonly:
+ myincrementals=["USE"]
+ else:
+ myincrementals=self.incrementals[:]
+
+ # XXX HACK, harring
+ # this is a design flaw of the code.
+ from portage import db, root
+
+ rootdb = db.get(root)
+ for mykey in myincrementals:
+ if mykey=="USE":
+ mydbs=self.uvlist
+ # XXX Global usage of db... Needs to go away somehow.
+ if rootdb and "vartree" in rootdb:
+ _use = self.autouse( rootdb["vartree"], use_cache=use_cache)
+ else:
+ _use = ""
+ self.configdict["auto"]["USE"]= _use
+ else:
+ mydbs=self.configlist[:-1]
+
+ myflags=[]
+ for curdb in mydbs:
+ if mykey not in curdb:
+ continue
+ #variables are already expanded
+ mysplit=curdb[mykey].split()
+
+ for x in mysplit:
+ if x=="-*":
+ # "-*" is a special "minus" var that means "unset all settings".
+ # so USE="-* gnome" will have *just* gnome enabled.
+ myflags=[]
+ continue
+
+ if x[0]=="+":
+ # Not legal. People assume too much. Complain.
+ writemsg(red("USE flags should not start with a '+': %s\n" % x))
+ x=x[1:]
+
+ if x[0]=="-":
+ if x[1:] in myflags:
+ # Unset/Remove it.
+ myflags.remove(x[1:])
+ continue
+
+ # We got here, so add it now.
+ if x not in myflags:
+ myflags.append(x)
+
+ myflags.sort()
+ #store setting in last element of configlist, the original environment:
+ self.configlist[-1][mykey]=" ".join(myflags)
+ del myflags
+
+ #cache split-up USE var in a global
+ usesplit=[]
+
+ for x in self.configlist[-1]["USE"].split():
+ if x not in self.usemask:
+ usesplit.append(x)
+
+ if self.has_key("USE_EXPAND"):
+ for var in self["USE_EXPAND"].split():
+ if self.has_key(var):
+ for x in self[var].split():
+ mystr = var.lower()+"_"+x
+ if mystr not in usesplit:
+ usesplit.append(mystr)
+
+ # Pre-Pend ARCH variable to USE settings so '-*' in env doesn't kill arch.
+ # XXX: harring wonders why profiledir is checked here...
+ from portage import profiledir
+ if profiledir:
+ if self.configdict["defaults"].has_key("ARCH"):
+ if self.configdict["defaults"]["ARCH"]:
+ if self.configdict["defaults"]["ARCH"] not in usesplit:
+ usesplit.insert(0,self.configdict["defaults"]["ARCH"])
+
+ self.configlist[-1]["USE"]=" ".join(usesplit)
+
+ self.already_in_regenerate = 0
+
+ def getvirtuals(self, myroot):
+ myvirts = {}
+
+ # This breaks catalyst/portage when setting to a fresh/empty root.
+ # Virtuals cannot be calculated because there is nothing to work
+ # from. So the only ROOT prefixed dir should be local configs.
+ #myvirtdirs = prefix_array(self.profiles,myroot+"/")
+ myvirtdirs = copy.deepcopy(self.profiles)
+
+ self.treeVirtuals = {}
+
+ # Repoman should ignore these.
+ user_profile_dir = None
+ if os.environ.get("PORTAGE_CALLER","") != "repoman":
+ user_profile_dir = myroot+portage_const.USER_CONFIG_PATH
+
+ # XXX: Removing this as virtuals and profile/virtuals behave
+ # differently. portage/profile/virtuals overrides the default
+ # virtuals but are overridden by installed virtuals whereas
+ # portage/virtuals overrides everything.
+
+ #if os.path.exists("/etc/portage/virtuals"):
+ # writemsg("\n\n*** /etc/portage/virtuals should be moved to /etc/portage/profile/virtuals\n")
+ # writemsg("*** Please correct this by merging or moving the file. (Deprecation notice)\n\n")
+ # time.sleep(1)
+
+
+ self.dirVirtuals = grab_multiple("virtuals", myvirtdirs, grabdict)
+ self.dirVirtuals.reverse()
+ self.userVirtuals = {}
+ if user_profile_dir and os.path.exists(user_profile_dir+"/virtuals"):
+ self.userVirtuals = grabdict(user_profile_dir+"/virtuals")
+
+ # User settings and profile settings take precedence over tree.
+ profile_virtuals = stack_dictlist([self.userVirtuals]+self.dirVirtuals,incremental=1)
+
+ # repoman doesn't need local virtuals
+ if os.environ.get("PORTAGE_CALLER","") != "repoman":
+ from portage import vartree
+ temp_vartree = vartree(myroot,profile_virtuals,categories=self.categories)
+ myTreeVirtuals = {}
+ for key, val in temp_vartree.get_all_provides().items():
+ myTreeVirtuals[key] = portage_util.unique_array( [ portage_versions.pkgsplit(x)[0] for x in val ] )
+ self.treeVirtuals.update(myTreeVirtuals)
+ del myTreeVirtuals
+# myTreeVirtuals = map_dictlist_vals(getCPFromCPV,temp_vartree.get_all_provides())
+# for x,v in myTreeVirtuals.items():
+# self.treeVirtuals[x] = portage_util.unique_array(v)
+
+ # User settings and profile settings take precedence over tree
+ val = stack_dictlist([self.userVirtuals,self.treeVirtuals]+self.dirVirtuals,incremental=1)
+
+ for x in val.values():
+ x.reverse()
+ return val
+
+ def __delitem__(self,mykey):
+ for x in self.lookuplist:
+ if x != None:
+ if mykey in x:
+ del x[mykey]
+
+ def __getitem__(self,mykey):
+ match = ''
+ for x in self.lookuplist:
+ if x == None:
+ writemsg("!!! lookuplist is null.\n")
+ elif x.has_key(mykey):
+ match = x[mykey]
+ break
+
+ if 0 and match and mykey in ["PORTAGE_BINHOST"]:
+ # These require HTTP Encoding
+ try:
+ import urllib
+ if urllib.unquote(match) != match:
+ writemsg("Note: %s already contains escape codes." % (mykey))
+ else:
+ match = urllib.quote(match)
+ except SystemExit, e:
+ raise
+ except:
+ writemsg("Failed to fix %s using urllib, attempting to continue.\n" % (mykey))
+ pass
+
+ elif mykey == "CONFIG_PROTECT_MASK":
+ match += " /etc/env.d"
+
+ return match
+
+ def has_key(self,mykey):
+ for x in self.lookuplist:
+ if x.has_key(mykey):
+ return 1
+ return 0
+
+ def keys(self):
+ mykeys=[]
+ for x in self.lookuplist:
+ for y in x.keys():
+ if y not in mykeys:
+ mykeys.append(y)
+ return mykeys
+
+ def __setitem__(self,mykey,myvalue):
+ "set a value; will be thrown away at reset() time"
+ if not isinstance(myvalue, str):
+ raise ValueError("Invalid type being used as a value: '%s': '%s'" % (str(mykey),str(myvalue)))
+ self.modifying()
+ self.modifiedkeys += [mykey]
+ self.configdict["env"][mykey]=myvalue
+
+ def environ(self):
+ "return our locally-maintained environment"
+ mydict={}
+ for x in self.keys():
+ mydict[x]=self[x]
+ if not mydict.has_key("HOME") and mydict.has_key("BUILD_PREFIX"):
+ writemsg("*** HOME not set. Setting to "+mydict["BUILD_PREFIX"]+"\n")
+ mydict["HOME"]=mydict["BUILD_PREFIX"][:]
+
+ return mydict
+
+ def bash_environ(self):
+ "return our locally-maintained environment in a suitable bash assignment form"
+ mydict=self.environ()
+ final={}
+ for k in mydict.keys():
+ # quotes and escaped chars suck.
+ s=mydict[k].replace("\\","\\\\\\\\")
+ s=s.replace("'","\\'")
+ s=s.replace("\n","\\\n")
+ final[k]="$'%s'" % s
+ return final
+
+
+def stack_dicts(dicts, incremental=0, incrementals=[], ignore_none=0):
+ """Stacks an array of dict-types into one array. Optionally merging or
+ overwriting matching key/value pairs for the dict[key]->string.
+ Returns a single dict."""
+ final_dict = None
+ for mydict in dicts:
+ if mydict == None:
+ if ignore_none:
+ continue
+ else:
+ return None
+ if final_dict == None:
+ final_dict = {}
+ for y in mydict.keys():
+ if mydict[y]:
+ if final_dict.has_key(y) and (incremental or (y in incrementals)):
+ final_dict[y] += " "+mydict[y][:]
+ else:
+ final_dict[y] = mydict[y][:]
+ mydict[y] = ' '.join(mydict[y].split()) # Remove extra spaces.
+ return final_dict
+
+def stack_lists(lists, incremental=1):
+ """Stacks an array of list-types into one array. Optionally removing
+ distinct values using '-value' notation. Higher index is preferenced."""
+ new_list = []
+ for x in lists:
+ for y in x:
+ if y:
+ if incremental and y[0]=='-':
+ while y[1:] in new_list:
+ del new_list[new_list.index(y[1:])]
+ else:
+ if y not in new_list:
+ new_list.append(y[:])
+ return new_list
+
+def stack_dictlist(original_dicts, incremental=0, incrementals=[], ignore_none=0):
+ """Stacks an array of dict-types into one array. Optionally merging or
+ overwriting matching key/value pairs for the dict[key]->list.
+ Returns a single dict. Higher index in lists is preferenced."""
+ final_dict = None
+ kill_list = {}
+ for mydict in original_dicts:
+ if mydict == None:
+ continue
+ if final_dict == None:
+ final_dict = {}
+ for y in mydict.keys():
+ if not final_dict.has_key(y):
+ final_dict[y] = []
+ if not kill_list.has_key(y):
+ kill_list[y] = []
+
+ for thing in mydict[y]:
+ if thing and (thing not in kill_list[y]):
+ if (incremental or (y in incrementals)) and thing[0] == '-':
+ if thing[1:] not in kill_list[y]:
+ kill_list[y] += [thing[1:]]
+# while(thing[1:] in final_dict[y]):
+# del final_dict[y][final_dict[y].index(thing[1:])]
+ else:
+ if thing not in final_dict[y]:
+ final_dict[y].insert(0,thing[:])
+ if final_dict.has_key(y) and not final_dict[y]:
+ del final_dict[y]
+ return final_dict
+
+
+def best_from_dict(key, top_dict, key_order, EmptyOnError=1, FullCopy=1, AllowEmpty=1):
+ for x in key_order:
+ dico = top_dict.get(x)
+ if dico and key in dico:
+ if FullCopy:
+ return copy.deepcopy(dico[key])
+ else:
+ return dico[key]
+ if EmptyOnError:
+ return ""
+ else:
+ raise KeyError, "Key not found in list; '%s'" % key
+
+
+def load_mod(name):
+ components = name.split('.')
+ modname = ".".join(components[:-1])
+ mod = __import__(modname)
+ for comp in components[1:]:
+ mod = getattr(mod, comp)
+ return mod
diff --git a/pym/eclass_cache.py b/pym/eclass_cache.py
new file mode 100644
index 0000000..9741b43
--- /dev/null
+++ b/pym/eclass_cache.py
@@ -0,0 +1,109 @@
+from portage_util import writemsg
+import portage_file
+import os, sys
+from portage_data import portage_gid
+
+class cache:
+ """
+ Maintains the cache information about eclasses used in ebuild.
+ """
+ def __init__(self,porttree_root,settings):
+ self.porttree_root = porttree_root
+ self.settings = settings
+ self.depcachedir = self.settings.depcachedir[:]
+
+ self.dbmodule = self.settings.load_best_module("eclass_cache.dbmodule")
+
+ self.packages = {} # {"PV": {"eclass1": ["location", "_mtime_"]}}
+ self.eclasses = {} # {"Name": ["location","_mtime_"]}
+
+ self.porttrees=self.settings["PORTDIR_OVERLAY"].split()+[self.porttree_root]
+ self.update_eclasses()
+
+ def close_caches(self):
+ for x in self.packages.keys():
+ for y in self.packages[x].keys():
+ try:
+ self.packages[x][y].sync()
+ self.packages[x][y].close()
+ except SystemExit, e:
+ raise
+ except Exception,e:
+ writemsg("Exception when closing DB: %s: %s\n" % (Exception,e))
+ del self.packages[x][y]
+ del self.packages[x]
+
+ def flush_cache(self):
+ self.packages = {}
+ self.eclasses = {}
+ self.update_eclasses()
+
+ def update_eclasses(self):
+ self.eclasses = {}
+ eclass_len = len(".eclass")
+# for x in suffix_array(self.porttrees, "/eclass"):
+ for x in [portage_file.normpath(os.path.join(y,"eclass")) for y in self.porttrees]:
+ if x and os.path.exists(x):
+ dirlist = os.listdir(x)
+ for y in dirlist:
+ if y[-eclass_len:]==".eclass":
+ ys=y[:-eclass_len]
+ try:
+ ymtime=os.stat(x+"/"+y).st_mtime
+ except OSError:
+ continue
+ self.eclasses[ys] = [x, ymtime]
+
+ def setup_package(self, location, cat, pkg):
+ if not self.packages.has_key(location):
+ self.packages[location] = {}
+
+ if not self.packages[location].has_key(cat):
+ try:
+ self.packages[location][cat] = self.dbmodule(self.depcachedir+"/"+location, cat+"-eclass", [], -1, portage_gid)
+ except SystemExit, e:
+ raise
+ except Exception, e:
+ writemsg("\n!!! Failed to open the dbmodule for eclass caching.\n")
+ writemsg("!!! Generally these are permission problems. Caught exception follows:\n")
+ writemsg("!!! "+str(e)+"\n")
+ writemsg("!!! Dirname: "+str(self.depcachedir+"/"+location)+"\n")
+ writemsg("!!! Basename: "+str(cat+"-eclass")+"\n\n")
+ sys.exit(123)
+
+ def sync(self, location, cat, pkg):
+ if self.packages[location].has_key(cat):
+ self.packages[location][cat].sync()
+
+ def update_package(self, location, cat, pkg, eclass_list):
+ self.setup_package(location, cat, pkg)
+ if not eclass_list:
+ return 1
+
+ data = {}
+ for x in eclass_list:
+ if x not in self.eclasses:
+ writemsg("Eclass '%s' does not exist for '%s'\n" % (x, cat+"/"+pkg))
+ return 0
+ data[x] = [self.eclasses[x][0],self.eclasses[x][1]]
+
+ self.packages[location][cat][pkg] = data
+ self.sync(location,cat,pkg)
+ return 1
+
+ def is_current(self, location, cat, pkg, eclass_list):
+ self.setup_package(location, cat, pkg)
+
+ if not eclass_list:
+ return 1
+
+ if not (self.packages[location][cat].has_key(pkg) and self.packages[location][cat][pkg] and eclass_list):
+ return 0
+
+ myp = self.packages[location][cat][pkg]
+ for x in eclass_list:
+ if not (x in self.eclasses and myp.has_key(x) and myp[x][0] == self.eclasses[x][0] and
+ myp[x][1] == self.eclasses[x][1]):
+ return 0
+
+ return 1
diff --git a/pym/portage.py b/pym/portage.py
index 98262fa..8d3aab0 100644
--- a/pym/portage.py
+++ b/pym/portage.py
@@ -2,10 +2,10 @@
# portage.py -- core Portage functionality
# Copyright 1998-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/pym/portage.py,v 1.576 2005/03/02 13:41:57 jstubbs Exp $
-cvs_id_string="$Id: portage.py,v 1.576 2005/03/02 13:41:57 jstubbs Exp $"[5:-2]
+# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/pym/portage.py,v 1.577 2005/03/07 04:00:30 ferringb Exp $
+cvs_id_string="$Id: portage.py,v 1.577 2005/03/07 04:00:30 ferringb Exp $"[5:-2]
-VERSION="$Revision: 1.576 $"[11:-2] + "-cvs"
+VERSION="$Revision: 1.577 $"[11:-2] + "-cvs"
# ===========================================================================
# START OF IMPORTS -- START OF IMPORTS -- START OF IMPORTS -- START OF IMPORT
@@ -25,7 +25,6 @@ try:
import time,cPickle,traceback,copy
import re,pwd,grp
import shlex,shutil
- from orig_dict_cache import cacheddir
import stat
from time import sleep
from random import shuffle
@@ -64,12 +63,13 @@ except:
bsd_chflags = None
try:
+ from config import config
import ebuild
import cvstree
import xpak
import getbinpkg
import portage_dep
-
+ import eclass_cache
import portage_versions
#assign these to portage's namespace to keep the tool monkeys happy.
@@ -98,9 +98,10 @@ try:
import portage_util
from portage_util import grab_multiple, grabdict, grabdict_package, grabfile, grabfile_package, \
- grabints, map_dictlist_vals, pickle_read, pickle_write, stack_dictlist, stack_dicts, stack_lists, \
- unique_array, varexpand, writedict, writeints, writemsg, getconfig, movefile, flatten
- from portage_file import normpath
+ grabints, pickle_read, pickle_write, stack_dictlist, stack_dicts, stack_lists, \
+ unique_array, varexpand, writedict, writeints, writemsg, getconfig, movefile, flatten, \
+ abssymlink
+ from portage_file import normpath, listdir
import portage_exception
import portage_gpg
import portage_locks
@@ -147,27 +148,6 @@ signal.signal(signal.SIGCHLD, signal.SIG_DFL)
signal.signal(signal.SIGINT, exithandler)
signal.signal(signal.SIGTERM, exithandler)
-def load_mod(name):
- components = name.split('.')
- modname = ".".join(components[:-1])
- mod = __import__(modname)
- for comp in components[1:]:
- mod = getattr(mod, comp)
- return mod
-
-def best_from_dict(key, top_dict, key_order, EmptyOnError=1, FullCopy=1, AllowEmpty=1):
- for x in key_order:
- dico = top_dict.get(x)
- if dico and key in dico:
- if FullCopy:
- return copy.deepcopy(dico[key])
- else:
- return dico[key]
- if EmptyOnError:
- return ""
- else:
- raise KeyError, "Key not found in list; '%s'" % key
-
def getcwd():
"this fixes situations where the current directory doesn't exist"
try:
@@ -179,16 +159,6 @@ def getcwd():
return "/"
getcwd()
-def abssymlink(symlink):
- """
- This reads symlinks, resolving the relative symlinks, and returning the absolute.
- """
- mylink=os.readlink(symlink)
- if mylink[0] != '/':
- mydir=os.path.dirname(symlink)
- mylink=mydir+"/"+mylink
- return os.path.normpath(mylink)
-
def suffix_array(array,suffix,doblanks=1):
"""Appends a given suffix to each element in an Array/List/Tuple.
Returns a List."""
@@ -215,72 +185,6 @@ def prefix_array(array,prefix,doblanks=1):
newarray.append(x)
return newarray
-def listdir(mypath, recursive=False, filesonly=False, ignorecvs=False, ignorelist=[],
- followSymlinks=True, cacheObject=None):
-
- if cacheObject:
- cfunc = cacheObject.cacheddir
- else:
- cfunc = cacheddir
- try:
- list, ftype = cfunc(mypath)
- except SystemExit:
- raise
- except Exception:
- return []
-
- if list is None:
- list=[]
- if ftype is None:
- ftype=[]
-
- if ignorecvs or len(ignorelist):
- x=0
- while x < len(list):
- #we're working with first level entries, no os.path.basename requirement
- if (ignorecvs and (list[x] in ('CVS','.svn') or list[x].startswith(".#"))) and not \
- list[x] in ignorelist:
- list.pop(x)
- ftype.pop(x)
- continue
- x += 1
-
- if not filesonly and not recursive:
- return list
-
- if recursive:
- x=0
- while x<len(ftype):
- b=os.path.basename(list[x])
- # if it was cvs, it was filtered already.
- if ftype[x] == 1 or (followSymlinks and ftype[x] == 3):
-
- l,f = cfunc(mypath+"/"+list[x])
-
- y=0
- while y < len(l):
- # use list comprehension here.
- if not (ignorecvs and (l[y] in ('CVS','.svn') or l[y].startswith(".#"))) \
- and not l[y] in ignorelist:
- l[y]=list[x]+"/"+l[y]
- y += 1
- else:
- l.pop(y)
- f.pop(y)
-
- list=list+l
- ftype=ftype+f
- x+=1
- if filesonly:
- rlist=[]
- for x in range(0,len(ftype)):
- if ftype[x]==0:
- rlist=rlist+[list[x]]
- else:
- rlist=list
-
- return rlist
-
starttime=long(time.time())
features=[]
@@ -801,761 +705,6 @@ def ExtractKernelVersion(base_dir):
return (version,None)
-def check_config_instance(test):
- if not test or (str(test.__class__) != 'portage.config'):
- raise TypeError, "Invalid type for config object: %s" % test.__class__
-
-class config:
- def clone(self, clone):
- self.incrementals = copy.deepcopy(clone.incrementals)
- self.profile_path = copy.deepcopy(clone.profile_path)
- self.user_profile_dir = copy.deepcopy(clone.user_profile_dir)
-
- self.module_priority = copy.deepcopy(clone.module_priority)
- self.modules = copy.deepcopy(clone.modules)
-
- self.depcachedir = copy.deepcopy(clone.depcachedir)
-
- self.packages = copy.deepcopy(clone.packages)
- self.virtuals = copy.deepcopy(clone.virtuals)
-
- self.treeVirtuals = copy.deepcopy(clone.treeVirtuals)
- self.userVirtuals = copy.deepcopy(clone.userVirtuals)
- self.negVirtuals = copy.deepcopy(clone.negVirtuals)
-
- self.use_defs = copy.deepcopy(clone.use_defs)
- self.usemask = copy.deepcopy(clone.usemask)
-
- self.configlist = copy.deepcopy(clone.configlist)
- self.configlist[-1] = os.environ.copy()
- self.configdict = { "globals": self.configlist[0],
- "defaults": self.configlist[1],
- "conf": self.configlist[2],
- "pkg": self.configlist[3],
- "auto": self.configlist[4],
- "backupenv": self.configlist[5],
- "env": self.configlist[6] }
- self.backupenv = copy.deepcopy(clone.backupenv)
- self.pusedict = copy.deepcopy(clone.pusedict)
- self.categories = copy.deepcopy(clone.categories)
- self.pkeywordsdict = copy.deepcopy(clone.pkeywordsdict)
- self.pmaskdict = copy.deepcopy(clone.pmaskdict)
- self.punmaskdict = copy.deepcopy(clone.punmaskdict)
- self.prevmaskdict = copy.deepcopy(clone.prevmaskdict)
- self.pprovideddict = copy.deepcopy(clone.pprovideddict)
- self.lookuplist = copy.deepcopy(clone.lookuplist)
- self.uvlist = copy.deepcopy(clone.uvlist)
- self.dirVirtuals = copy.deepcopy(clone.dirVirtuals)
- self.treeVirtuals = copy.deepcopy(clone.treeVirtuals)
-
- def __init__(self, clone=None, mycpv=None, config_profile_path=PROFILE_PATH, config_incrementals=None):
-
- self.already_in_regenerate = 0
-
- self.locked = 0
- self.mycpv = None
- self.puse = []
- self.modifiedkeys = []
-
- self.virtuals = {}
- self.v_count = 0
-
- # Virtuals obtained from the vartree
- self.treeVirtuals = {}
- # Virtuals by user specification. Includes negatives.
- self.userVirtuals = {}
- # Virtual negatives from user specifications.
- self.negVirtuals = {}
-
- self.user_profile_dir = None
-
- if clone:
- self.clone( clone )
- else:
- self.depcachedir = DEPCACHE_PATH
-
- if not os.path.exists(config_profile_path):
- writemsg("config_profile_path not specified to class config\n")
- sys.exit(1)
- self.profile_path = config_profile_path
-
- if not config_incrementals:
- import traceback
- traceback.print_stack()
- writemsg("incrementals not specified to class config\n")
- writemsg("sayonara, sucker.\n")
- sys.exit(1)
- self.incrementals = copy.deepcopy(config_incrementals)
-
- self.module_priority = ["user","default"]
- self.modules = {}
- self.modules["user"] = getconfig(MODULES_FILE_PATH)
- if self.modules["user"] == None:
- self.modules["user"] = {}
- self.modules["default"] = {
- "portdbapi.metadbmodule": "portage_db_flat.database",
- "portdbapi.auxdbmodule": "portage_db_flat.database",
- "eclass_cache.dbmodule": "portage_db_cpickle.database",
- }
-
- self.usemask=[]
- self.configlist=[]
- self.backupenv={}
- # back up our incremental variables:
- self.configdict={}
- # configlist will contain: [ globals, defaults, conf, pkg, auto, backupenv (incrementals), origenv ]
-
- # The symlink might not exist or might not be a symlink.
- try:
- self.profiles=[abssymlink(self.profile_path)]
- except SystemExit, e:
- raise
- except:
- self.profiles=[self.profile_path]
-
- mypath = self.profiles[0]
- while os.path.exists(mypath+"/parent"):
- mypath = os.path.normpath(mypath+"///"+grabfile(mypath+"/parent")[0])
- if os.path.exists(mypath):
- self.profiles.insert(0,mypath)
-
- if os.environ.get("PORTAGE_CALLER",'') == "repoman":
- pass
- else:
- # XXX: This should depend on ROOT?
- if os.path.exists("/"+CUSTOM_PROFILE_PATH):
- self.user_profile_dir = os.path.normpath("/"+"///"+CUSTOM_PROFILE_PATH)
- self.profiles.append(self.user_profile_dir[:])
-
- self.packages_list = grab_multiple("packages", self.profiles, grabfile_package)
- self.packages = stack_lists(self.packages_list, incremental=1)
- del self.packages_list
- #self.packages = grab_stacked("packages", self.profiles, grabfile, incremental_lines=1)
-
- # revmaskdict
- self.prevmaskdict={}
- for x in self.packages:
- mycatpkg=dep_getkey(x)
- if not self.prevmaskdict.has_key(mycatpkg):
- self.prevmaskdict[mycatpkg]=[x]
- else:
- self.prevmaskdict[mycatpkg].append(x)
-
- # get profile-masked use flags -- INCREMENTAL Child over parent
- usemask_lists = grab_multiple("use.mask", self.profiles, grabfile)
- self.usemask = stack_lists(usemask_lists, incremental=True)
- del usemask_lists
- use_defs_lists = grab_multiple("use.defaults", self.profiles, grabdict)
- self.use_defs = stack_dictlist(use_defs_lists, incremental=True)
- del use_defs_lists
-
- try:
- mygcfg_dlists = grab_multiple("make.globals", self.profiles+["/etc"], getconfig)
- self.mygcfg = stack_dicts(mygcfg_dlists, incrementals=self.incrementals, ignore_none=1)
-
- if self.mygcfg == None:
- self.mygcfg = {}
- except SystemExit, e:
- raise
- except Exception, e:
- writemsg("!!! %s\n" % (e))
- writemsg("!!! Incorrect multiline literals can cause this. Do not use them.\n")
- writemsg("!!! Errors in this file should be reported on bugs.gentoo.org.\n")
- sys.exit(1)
- self.configlist.append(self.mygcfg)
- self.configdict["globals"]=self.configlist[-1]
-
- self.mygcfg = {}
- if self.profiles:
- try:
- mygcfg_dlists = grab_multiple("make.defaults", self.profiles, getconfig)
- self.mygcfg = stack_dicts(mygcfg_dlists, incrementals=self.incrementals, ignore_none=1)
- if self.mygcfg == None:
- self.mygcfg = {}
- except SystemExit, e:
- raise
- except Exception, e:
- writemsg("!!! %s\n" % (e))
- writemsg("!!! 'rm -Rf /usr/portage/profiles; emerge sync' may fix this. If it does\n")
- writemsg("!!! not then please report this to bugs.gentoo.org and, if possible, a dev\n")
- writemsg("!!! on #gentoo (irc.freenode.org)\n")
- sys.exit(1)
- self.configlist.append(self.mygcfg)
- self.configdict["defaults"]=self.configlist[-1]
-
- try:
- # XXX: Should depend on root?
- self.mygcfg=getconfig("/"+MAKE_CONF_FILE,allow_sourcing=True)
- if self.mygcfg == None:
- self.mygcfg = {}
- except SystemExit, e:
- raise
- except Exception, e:
- writemsg("!!! %s\n" % (e))
- writemsg("!!! Incorrect multiline literals can cause this. Do not use them.\n")
- sys.exit(1)
-
-
- self.configlist.append(self.mygcfg)
- self.configdict["conf"]=self.configlist[-1]
-
- self.configlist.append({})
- self.configdict["pkg"]=self.configlist[-1]
-
- #auto-use:
- self.configlist.append({})
- self.configdict["auto"]=self.configlist[-1]
-
- #backup-env (for recording our calculated incremental variables:)
- self.backupenv = os.environ.copy()
- self.configlist.append(self.backupenv) # XXX Why though?
- self.configdict["backupenv"]=self.configlist[-1]
-
- self.configlist.append(os.environ.copy())
- self.configdict["env"]=self.configlist[-1]
-
-
- # make lookuplist for loading package.*
- self.lookuplist=self.configlist[:]
- self.lookuplist.reverse()
-
- archlist = grabfile(self["PORTDIR"]+"/profiles/arch.list")
- self.configdict["conf"]["PORTAGE_ARCHLIST"] = string.join(archlist)
-
- if os.environ.get("PORTAGE_CALLER",'') == "repoman":
- # repoman shouldn't use local settings.
- locations = [self["PORTDIR"] + "/profiles"]
- self.pusedict = {}
- self.pkeywordsdict = {}
- self.punmaskdict = {}
- else:
- locations = [self["PORTDIR"] + "/profiles", USER_CONFIG_PATH]
-
- # Never set anything in this. It's for non-originals.
- self.pusedict=grabdict_package(USER_CONFIG_PATH+"/package.use")
-
- #package.keywords
- pkgdict=grabdict_package(USER_CONFIG_PATH+"/package.keywords")
- self.pkeywordsdict = {}
- for key in pkgdict.keys():
- # default to ~arch if no specific keyword is given
- if not pkgdict[key]:
- mykeywordlist = []
- if self.configdict["defaults"] and self.configdict["defaults"].has_key("ACCEPT_KEYWORDS"):
- groups = self.configdict["defaults"]["ACCEPT_KEYWORDS"].split()
- else:
- groups = []
- for keyword in groups:
- if not keyword[0] in "~-":
- mykeywordlist.append("~"+keyword)
- pkgdict[key] = mykeywordlist
- cp = dep_getkey(key)
- if not self.pkeywordsdict.has_key(cp):
- self.pkeywordsdict[cp] = {}
- self.pkeywordsdict[cp][key] = pkgdict[key]
-
- #package.unmask
- pkgunmasklines = grabfile_package(USER_CONFIG_PATH+"/package.unmask")
- self.punmaskdict = {}
- for x in pkgunmasklines:
- mycatpkg=dep_getkey(x)
- L = self.punmaskdict.setdefault(mycatpkg,[])
- L.append(x)
-
- #getting categories from an external file now
- categories = grab_multiple("categories", locations, grabfile)
- self.categories = stack_lists(categories, incremental=1)
- del categories
-
- # get virtuals -- needs categories
- self.loadVirtuals('/')
-
- #package.mask
- pkgmasklines = grab_multiple("package.mask", self.profiles + locations, grabfile_package)
- pkgmasklines = stack_lists(pkgmasklines, incremental=1)
-
- self.pmaskdict = {}
- for x in pkgmasklines:
- mycatpkg = dep_getkey(x)
- L = self.pmaskdict.setdefault(mycatpkg,[])
- L.append(x)
-
- pkgprovidedlines = grab_multiple("package.provided", self.profiles, grabfile)
- pkgprovidedlines = stack_lists(pkgprovidedlines, incremental=1)
-
- self.pprovideddict = {}
- for x in pkgprovidedlines:
- cpv=portage_versions.catpkgsplit(x)
- if not x:
- continue
- mycatpkg=dep_getkey(x)
- L = self.pprovideddict.setdefault(mycatpkg,[])
- L.append(x)
-
-
- self.lookuplist=self.configlist[:]
- self.lookuplist.reverse()
-
- useorder=self["USE_ORDER"]
- if not useorder:
- # reasonable defaults; this is important as without USE_ORDER,
- # USE will always be "" (nothing set)!
- useorder="env:pkg:conf:auto:defaults"
- useordersplit=useorder.split(":")
-
- self.uvlist=[]
- for x in useordersplit:
- if x in self.configdict:
- if "PKGUSE" in self.configdict[x]:
- # Delete PkgUse, Not legal to set.
- del self.configdict[x]["PKGUSE"]
- #prepend db to list to get correct order
- self.uvlist.insert(0,self.configdict[x])
-
- self.configdict["env"]["PORTAGE_GID"]=str(portage_gid)
- self.backupenv["PORTAGE_GID"]=str(portage_gid)
-
- if self.has_key("PORT_LOGDIR") and not self["PORT_LOGDIR"]:
- # port_logdir is defined, but empty. this causes a traceback in doebuild.
- writemsg(yellow("!!!")+" PORT_LOGDIR was defined, but set to nothing.\n")
- writemsg(yellow("!!!")+" Disabling it. Please set it to a non null value.\n")
- del self["PORT_LOGDIR"]
-
- if self["PORTAGE_CACHEDIR"]:
- # XXX: Deprecated -- April 15 -- NJ
- writemsg(yellow(">>> PORTAGE_CACHEDIR has been deprecated!")+"\n")
- writemsg(">>> Please use PORTAGE_DEPCACHEDIR instead.\n")
- self.depcachedir = self["PORTAGE_CACHEDIR"]
- del self["PORTAGE_CACHEDIR"]
-
- if self["PORTAGE_DEPCACHEDIR"]:
- #the auxcache is the only /var/cache/edb/ entry that stays at / even when "root" changes.
- # XXX: Could move with a CHROOT functionality addition.
- self.depcachedir = self["PORTAGE_DEPCACHEDIR"]
- del self["PORTAGE_DEPCACHEDIR"]
-
- overlays = self["PORTDIR_OVERLAY"].split()
- if overlays:
- new_ov=[]
- for ov in overlays:
- ov=os.path.normpath(ov)
- if os.path.isdir(ov):
- new_ov.append(ov)
- else:
- writemsg(red("!!! Invalid PORTDIR_OVERLAY (not a dir): "+ov+"\n"))
- self["PORTDIR_OVERLAY"] = " ".join(new_ov)
- self.backup_changes("PORTDIR_OVERLAY")
-
- self.regenerate()
-
- self.features = portage_util.unique_array(self["FEATURES"].split())
-
- #XXX: Should this be temporary? Is it possible at all to have a default?
- if "gpg" in self.features:
- if not os.path.exists(self["PORTAGE_GPG_DIR"]) or not os.path.isdir(self["PORTAGE_GPG_DIR"]):
- writemsg("PORTAGE_GPG_DIR is invalid. Removing gpg from FEATURES.\n")
- self.features.remove("gpg")
-
- if "maketest" in self.features and "test" not in self.features:
- self.features.append("test")
-
- self.features.sort()
- self["FEATURES"] = " ".join(["-*"]+self.features)
- self.backup_changes("FEATURES")
-
- if mycpv:
- self.setcpv(mycpv)
-
- def autouse(self, myvartree, use_cache=1):
- "returns set of USE variables auto-enabled due to packages being installed"
- if profiledir==None:
- return ""
- myusevars=""
- for myuse in self.use_defs:
- dep_met = True
- for mydep in self.use_defs[myuse]:
- if not myvartree.dep_match(mydep,use_cache=True):
- dep_met = False
- break
- if dep_met:
- myusevars += " "+myuse
- return myusevars
-
-
-
- def loadVirtuals(self,root):
- self.virtuals = self.getvirtuals(root)
-
- def load_best_module(self,property_string):
- best_mod = best_from_dict(property_string,self.modules,self.module_priority)
- return load_mod(best_mod)
-
- def lock(self):
- self.locked = 1
-
- def unlock(self):
- self.locked = 0
-
- def modifying(self):
- if self.locked:
- raise Exception, "Configuration is locked."
-
- def backup_changes(self,key=None):
- if key and self.configdict["env"].has_key(key):
- self.backupenv[key] = copy.deepcopy(self.configdict["env"][key])
- else:
- raise KeyError, "No such key defined in environment: %s" % key
-
- def reset(self,keeping_pkg=0,use_cache=1):
- "reset environment to original settings"
- envdict = self.configdict["env"]
- # reinitialize env values to those of backupenv
- envdict.clear()
- envdict.update(self.backupenv)
- self.modifiedkeys = []
- if not keeping_pkg:
- self.puse = ""
- self.configdict["pkg"].clear()
- self.regenerate(use_cache=use_cache)
-
- def load_infodir(self,infodir):
- if self.configdict.has_key("pkg"):
- self.configdict["pkg"].clear()
- else:
- writemsg("No pkg setup for settings instance?\n")
- sys.exit(17)
-
- if os.path.exists(infodir):
- if os.path.exists(infodir+"/environment"):
- self.configdict["pkg"]["PORT_ENV_FILE"] = infodir+"/environment"
- elif os.path.exists(infodir+"/environment.bz2"):
- self.configdict["pkg"]["PORT_ENV_FILE"] = infodir+"/environment.bz2"
-# else:
-# print "wth, no env found in the infodir, '%s'" % infodir
-# import traceback
-# traceback.print_stack()
-# sys.exit(15)
- myre = re.compile('^[A-Z]+$')
- for filename in listdir(infodir,filesonly=1):
- if myre.match(filename):
- try:
- mydata = open(infodir+"/"+filename).read().strip()
- if len(mydata)<2048:
- if filename == "USE":
- self.configdict["pkg"][filename] = "-* "+mydata
- else:
- self.configdict["pkg"][filename] = mydata
- except SystemExit, e:
- raise
- except:
- writemsg("!!! Unable to read file: %s\n" % infodir+"/"+filename)
- pass
- return 1
- return 0
-
- def setcpv(self,mycpv,use_cache=1):
- self.modifying()
- self.mycpv = mycpv
- self.pusekey = best_match_to_list(self.mycpv, self.pusedict.keys())
- if self.pusekey:
- newpuse = " ".join(self.pusedict[self.pusekey])
- else:
- newpuse = ""
- if newpuse == self.puse:
- return
- self.puse = newpuse
- self.configdict["pkg"]["PKGUSE"] = self.puse[:] # For saving to PUSE file
- self.configdict["pkg"]["USE"] = self.puse[:] # this gets appended to USE
- self.reset(keeping_pkg=1,use_cache=use_cache)
-
- def setinst(self,mycpv,mydbapi):
- """
- Grab the virtuals this package provides and add them into the tree virtuals.
- """
- provides = mydbapi.aux_get(mycpv, ["PROVIDE"])[0]
- if isinstance(mydbapi, portdbapi):
- myuse = self["USE"]
- else:
- myuse = mydbapi.aux_get(mycpv, ["USE"])[0]
- virts = flatten(portage_dep.use_reduce(portage_dep.paren_reduce(provides), uselist=myuse.split()))
-
- cp = dep_getkey(mycpv)
- for virt in virts:
- virt = dep_getkey(virt)
- if not self.treeVirtuals.has_key(virt):
- self.treeVirtuals[virt] = []
- # XXX: Is this bad? -- It's a permanent modification
- self.treeVirtuals[virt] = portage_util.unique_array(self.treeVirtuals[virt]+[cp])
-
- self.virtuals = self.__getvirtuals_compile()
-
-
- def regenerate(self,useonly=0,use_cache=1):
- global usesplit
-
- if self.already_in_regenerate:
- # XXX: THIS REALLY NEEDS TO GET FIXED. autouse() loops.
- writemsg("!!! Looping in regenerate.\n",1)
- return
- else:
- self.already_in_regenerate = 1
-
- if useonly:
- myincrementals=["USE"]
- else:
- myincrementals=self.incrementals[:]
- rootdb = db.get(root)
- for mykey in myincrementals:
- if mykey=="USE":
- mydbs=self.uvlist
- # XXX Global usage of db... Needs to go away somehow.
- if rootdb and "vartree" in rootdb:
- _use = self.autouse( rootdb["vartree"], use_cache=use_cache)
- else:
- _use = ""
- self.configdict["auto"]["USE"]= _use
- else:
- mydbs=self.configlist[:-1]
-
- myflags=[]
- for curdb in mydbs:
- if mykey not in curdb:
- continue
- #variables are already expanded
- mysplit=curdb[mykey].split()
-
- for x in mysplit:
- if x=="-*":
- # "-*" is a special "minus" var that means "unset all settings".
- # so USE="-* gnome" will have *just* gnome enabled.
- myflags=[]
- continue
-
- if x[0]=="+":
- # Not legal. People assume too much. Complain.
- writemsg(red("USE flags should not start with a '+': %s\n" % x))
- x=x[1:]
-
- if x[0]=="-":
- if x[1:] in myflags:
- # Unset/Remove it.
- myflags.remove(x[1:])
- continue
-
- # We got here, so add it now.
- if x not in myflags:
- myflags.append(x)
-
- myflags.sort()
- #store setting in last element of configlist, the original environment:
- self.configlist[-1][mykey]=" ".join(myflags)
- del myflags
-
- #cache split-up USE var in a global
- usesplit=[]
-
- for x in self.configlist[-1]["USE"].split():
- if x not in self.usemask:
- usesplit.append(x)
-
- if self.has_key("USE_EXPAND"):
- for var in self["USE_EXPAND"].split():
- if self.has_key(var):
- for x in self[var].split():
- mystr = var.lower()+"_"+x
- if mystr not in usesplit:
- usesplit.append(mystr)
-
- # Pre-Pend ARCH variable to USE settings so '-*' in env doesn't kill arch.
- if self.configdict["defaults"].has_key("ARCH"):
- if self.configdict["defaults"]["ARCH"]:
- if self.configdict["defaults"]["ARCH"] not in usesplit:
- usesplit.insert(0,self.configdict["defaults"]["ARCH"])
-
- self.configlist[-1]["USE"]=" ".join(usesplit)
-
- self.already_in_regenerate = 0
-
- def getvirtuals(self, myroot):
- myvirts = {}
-
- # This breaks catalyst/portage when setting to a fresh/empty root.
- # Virtuals cannot be calculated because there is nothing to work
- # from. So the only ROOT prefixed dir should be local configs.
- #myvirtdirs = prefix_array(self.profiles,myroot+"/")
- myvirtdirs = copy.deepcopy(self.profiles)
-
- while self.user_profile_dir in myvirtdirs:
- myvirtdirs.remove(self.user_profile_dir)
-
- self.treeVirtuals = {}
-
- # Rules
- # R1: Collapse profile virtuals
- # R2: Extract user-negatives.
- # R3: Collapse user-virtuals.
- # R4: Apply user negatives to all except user settings.
-
- # Order of preference:
- # 1. user-declared that are installed
- # 3. installed and in profile
- # 4. installed
- # 2. user-declared set
- # 5. profile
-
- self.dirVirtuals = grab_multiple("virtuals", myvirtdirs, grabdict)
- self.dirVirtuals.reverse()
-
- if self.user_profile_dir and os.path.exists(self.user_profile_dir+"/virtuals"):
- self.userVirtuals = grabdict(self.user_profile_dir+"/virtuals")
-
- # Store all the negatives for later.
- for x in self.userVirtuals.keys():
- self.negVirtuals[x] = []
- for y in self.userVirtuals[x]:
- if y[0] == '-':
- self.negVirtuals[x].append(y[:])
-
- # Collapse the user virtuals so that we don't deal with negatives.
- self.userVirtuals = stack_dictlist([self.userVirtuals],incremental=1)
-
- # Collapse all the profile virtuals including user negations.
- self.dirVirtuals = stack_dictlist([self.negVirtuals]+self.dirVirtuals,incremental=1)
-
- # Repoman does not use user or tree virtuals.
- if os.environ.get("PORTAGE_CALLER","") != "repoman":
- # XXX: vartree does not use virtuals, does user set matter?
- temp_vartree = vartree(myroot,self.dirVirtuals,categories=self.categories)
- # Reduce the provides into a list by CP.
- self.treeVirtuals = map_dictlist_vals(getCPFromCPV,temp_vartree.get_all_provides())
-
- return self.__getvirtuals_compile()
-
-
- def __getvirtuals_compile(self):
- """Actually generate the virtuals we have collected.
- The results are reversed so the list order is left to right.
- Given data is [Best,Better,Good] sets of [Good, Better, Best]"""
- # Virtuals by profile+tree preferences.
- ptVirtuals = {}
- # Virtuals by user+tree preferences.
- utVirtuals = {}
-
- # If a user virtual is already installed, we preference it.
- for x in self.userVirtuals.keys():
- utVirtuals[x] = []
- if self.treeVirtuals.has_key(x):
- for y in self.userVirtuals[x]:
- if y in self.treeVirtuals[x]:
- utVirtuals[x].append(y)
- #print "F:",utVirtuals
- #utVirtuals[x].reverse()
- #print "R:",utVirtuals
-
- # If a profile virtual is already installed, we preference it.
- for x in self.dirVirtuals.keys():
- ptVirtuals[x] = []
- if self.treeVirtuals.has_key(x):
- for y in self.dirVirtuals[x]:
- if y in self.treeVirtuals[x]:
- ptVirtuals[x].append(y)
-
- # UserInstalled, ProfileInstalled, Installed, User, Profile
- biglist = [utVirtuals, ptVirtuals, self.treeVirtuals,
- self.userVirtuals, self.dirVirtuals]
-
- # We reverse each dictlist so that the order matches everything
- # else in portage. [-*, a, b] [b, c, d] ==> [b, a]
- for dictlist in biglist:
- for key in dictlist:
- dictlist[key].reverse()
-
- # User settings and profile settings take precedence over tree.
- val = stack_dictlist(biglist,incremental=1)
-
- return val
-
-
- def __delitem__(self,mykey):
- for x in self.lookuplist:
- if x != None:
- if mykey in x:
- del x[mykey]
-
- def __getitem__(self,mykey):
- match = ''
- for x in self.lookuplist:
- if x == None:
- writemsg("!!! lookuplist is null.\n")
- elif x.has_key(mykey):
- match = x[mykey]
- break
-
- if 0 and match and mykey in ["PORTAGE_BINHOST"]:
- # These require HTTP Encoding
- try:
- import urllib
- if urllib.unquote(match) != match:
- writemsg("Note: %s already contains escape codes." % (mykey))
- else:
- match = urllib.quote(match)
- except SystemExit, e:
- raise
- except:
- writemsg("Failed to fix %s using urllib, attempting to continue.\n" % (mykey))
- pass
-
- elif mykey == "CONFIG_PROTECT_MASK":
- match += " /etc/env.d"
-
- return match
-
- def has_key(self,mykey):
- for x in self.lookuplist:
- if x.has_key(mykey):
- return 1
- return 0
-
- def keys(self):
- mykeys=[]
- for x in self.lookuplist:
- for y in x.keys():
- if y not in mykeys:
- mykeys.append(y)
- return mykeys
-
- def __setitem__(self,mykey,myvalue):
- "set a value; will be thrown away at reset() time"
- if type(myvalue) != types.StringType:
- raise ValueError("Invalid type being used as a value: '%s': '%s'" % (str(mykey),str(myvalue)))
- self.modifying()
- self.modifiedkeys += [mykey]
- self.configdict["env"][mykey]=myvalue
-
- def environ(self):
- "return our locally-maintained environment"
- mydict={}
- for x in self.keys():
- mydict[x]=self[x]
- if not mydict.has_key("HOME") and mydict.has_key("BUILD_PREFIX"):
- writemsg("*** HOME not set. Setting to "+mydict["BUILD_PREFIX"]+"\n")
- mydict["HOME"]=mydict["BUILD_PREFIX"][:]
-
- return mydict
-
- def bash_environ(self):
- "return our locally-maintained environment in a suitable bash assignment form"
- mydict=self.environ()
- final={}
- for k in mydict.keys():
- # quotes and escaped chars suck.
- s=mydict[k].replace("\\","\\\\\\\\")
- s=s.replace("'","\\'")
- s=s.replace("\n","\\\n")
- final[k]="$'%s'" % s
- return final
-
-
# XXX This would be to replace getstatusoutput completely.
# XXX Issue: cannot block execution. Deadlock condition.
def spawn(mystring,mysettings,debug=0,free=0,droppriv=0,fd_pipes=None,**keywords):
@@ -1571,7 +720,8 @@ def spawn(mystring,mysettings,debug=0,free=0,droppriv=0,fd_pipes=None,**keywords
env=mysettings
keywords["opt_name"]="[ %s ]" % "portage"
else:
- check_config_instance(mysettings)
+ if not isinstance(mysettings, config):
+ raise TypeError, "Invalid type for config object: %s" % mysettings.__class_
env=mysettings.environ()
keywords["opt_name"]="[%s]" % mysettings["PF"]
@@ -1605,7 +755,8 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",
global thirdpartymirrors
- check_config_instance(mysettings)
+ if not isinstance(mysettings, config):
+ raise TypeError, "Invalid type for config object: %s" % mysettings.__class_
custommirrors=grabdict(CUSTOM_MIRRORS_FILE)
@@ -2306,18 +1457,6 @@ def unmerge(cat,pkg,myroot,mysettings,mytrimworld=1):
mylink.unmerge(trimworld=mytrimworld,cleanup=1)
mylink.delete()
-iscache={}
-def isspecific(mypkg):
- "now supports packages with no category"
- if mypkg in iscache:
- return iscache[mypkg]
- mysplit=mypkg.split("/")
- if not portage_dep.isjustname(mysplit[-1]):
- iscache[mypkg]=1
- return 1
- iscache[mypkg]=0
- return 0
-
def getCPFromCPV(mycpv):
"""Calls portage_versions.pkgsplit on a cpv and returns only the cp."""
return portage_versions.pkgsplit(mycpv)[0]
@@ -2349,7 +1488,6 @@ def dep_opconvert(mysplit,myuse,mysettings):
Does dependency operator conversion
"""
- #check_config_instance(mysettings)
mypos=0
newsplit=[]
@@ -2449,7 +1587,7 @@ def dep_virtual(mysplit, mysettings):
if type(x)==list:
newsplit.append(dep_virtual(x, mysettings))
else:
- mykey=dep_getkey(x)
+ mykey=portage_dep.dep_getkey(x)
if mysettings.virtuals.has_key(mykey):
if len(mysettings.virtuals[mykey])==1:
a=x.replace( mykey, mysettings.virtuals[mykey][0])
@@ -2595,27 +1733,6 @@ def dep_zapdeps(unreduced,reduced,vardbapi=None,use_binaries=0):
x += 1
return returnme
-def dep_getkey(mydep):
- if not len(mydep):
- return mydep
- if mydep[0]=="*":
- mydep=mydep[1:]
- if mydep[-1]=="*":
- mydep=mydep[:-1]
- if mydep[0]=="!":
- mydep=mydep[1:]
- if mydep[:2] in [ ">=", "<=" ]:
- mydep=mydep[2:]
- elif mydep[:1] in "=<>~":
- mydep=mydep[1:]
- if isspecific(mydep):
- mysplit=portage_versions.catpkgsplit(mydep)
- if not mysplit:
- return mydep
- return mysplit[0]+"/"+mysplit[1]
- else:
- return mydep
-
def cpv_getkey(mycpv):
myslash=mycpv.split("/")
mysplit=portage_versions.pkgsplit(myslash[-1])
@@ -2751,7 +1868,6 @@ def dep_expand(mydep,mydb=None,use_cache=1):
return prefix+cpv_expand(mydep,mydb=mydb,use_cache=use_cache)+postfix
def get_parsed_deps(depstring,mydbapi,mysettings,use="yes",mode=None,myuse=None):
- #check_config_instance(mysettings)
if use=="all":
#enable everything (for repoman)
@@ -2845,7 +1961,7 @@ def dep_wordreduce(mydeplist,mysettings,mydbapi,mode,use_cache=1):
elif deplist[mypos]=="||":
pass
else:
- mykey = dep_getkey(deplist[mypos])
+ mykey = portage_dep.dep_getkey(deplist[mypos])
if mysettings and mysettings.pprovideddict.has_key(mykey) and \
match_from_list(deplist[mypos], mysettings.pprovideddict[mykey]):
deplist[mypos]=True
@@ -2909,7 +2025,7 @@ class packagetree:
return key_expand(mykey,mydb=self.dbapi)
def dep_nomatch(self,mypkgdep):
- mykey=dep_getkey(mypkgdep)
+ mykey=portage_dep.dep_getkey(mypkgdep)
nolist=self.dbapi.cp_list(mykey)
mymatch=self.dbapi.match(mypkgdep)
if not mymatch:
@@ -2943,31 +2059,6 @@ def best(mymatches):
p2=portage_versions.catpkgsplit(bestmatch)[1:]
return bestmatch
-def match_to_list(mypkg,mylist):
- """(pkgname,list)
- Searches list for entries that matches the package.
- """
- matches=[]
- for x in mylist:
- if match_from_list(x,[mypkg]):
- if x not in matches:
- matches.append(x)
- return matches
-
-def best_match_to_list(mypkg,mylist):
- """(pkgname,list)
- Returns the most specific entry (assumed to be the longest one)
- that matches the package given.
- """
- # XXX Assumption is wrong sometimes.
- maxlen = 0
- bestm = None
- for x in match_to_list(mypkg,mylist):
- if len(x) > maxlen:
- maxlen = len(x)
- bestm = x
- return bestm
-
def match_from_list(mydep,candidate_list):
if mydep[0] == "!":
mydep = mydep[1:]
@@ -3060,7 +2151,7 @@ def match_from_list_original(mydep,mylist):
Reduces the list down to those that fit the dep
"""
mycpv=portage_dep.dep_getcpv(mydep)
- if isspecific(mycpv):
+ if portage_dep.isspecific(mycpv):
cp_key=portage_versions.catpkgsplit(mycpv)
if cp_key==None:
return []
@@ -3256,7 +2347,7 @@ class dbapi:
def match(self,origdep,use_cache=1):
mydep=dep_expand(origdep,mydb=self)
- mykey=dep_getkey(mydep)
+ mykey=portage_dep.dep_getkey(mydep)
mycat=mykey.split("/")[0]
return match_from_list(mydep,self.cp_list(mykey,use_cache=use_cache))
@@ -3665,7 +2756,7 @@ class vardbapi(dbapi):
def match(self,origdep,use_cache=1):
"caching match function"
mydep=dep_expand(origdep,mydb=self,use_cache=use_cache)
- mykey=dep_getkey(mydep)
+ mykey=portage_dep.dep_getkey(mydep)
mycat=mykey.split("/")[0]
if not use_cache:
if self.matchcache.has_key(mycat):
@@ -3857,112 +2948,6 @@ class vartree(packagetree):
def populate(self):
self.populated=1
-# ----------------------------------------------------------------------------
-class eclass_cache:
- """
- Maintains the cache information about eclasses used in ebuild.
- """
- def __init__(self,porttree_root,settings):
- self.porttree_root = porttree_root
- self.settings = settings
- self.depcachedir = self.settings.depcachedir[:]
-
- self.dbmodule = self.settings.load_best_module("eclass_cache.dbmodule")
-
- self.packages = {} # {"PV": {"eclass1": ["location", "_mtime_"]}}
- self.eclasses = {} # {"Name": ["location","_mtime_"]}
-
- self.porttrees=self.settings["PORTDIR_OVERLAY"].split()+[self.porttree_root]
- self.update_eclasses()
-
- def close_caches(self):
- for x in self.packages.keys():
- for y in self.packages[x].keys():
- try:
- self.packages[x][y].sync()
- self.packages[x][y].close()
- except SystemExit, e:
- raise
- except Exception,e:
- writemsg("Exception when closing DB: %s: %s\n" % (Exception,e))
- del self.packages[x][y]
- del self.packages[x]
-
- def flush_cache(self):
- self.packages = {}
- self.eclasses = {}
- self.update_eclasses()
-
- def update_eclasses(self):
- self.eclasses = {}
- eclass_len = len(".eclass")
- for x in suffix_array(self.porttrees, "/eclass"):
- if x and os.path.exists(x):
- dirlist = listdir(x)
- for y in dirlist:
- if y[-eclass_len:]==".eclass":
- ys=y[:-eclass_len]
- try:
- ymtime=os.stat(x+"/"+y)[stat.ST_MTIME]
- except OSError:
- continue
- self.eclasses[ys] = [x, ymtime]
-
- def setup_package(self, location, cat, pkg):
- if not self.packages.has_key(location):
- self.packages[location] = {}
-
- if not self.packages[location].has_key(cat):
- try:
- self.packages[location][cat] = self.dbmodule(self.depcachedir+"/"+location, cat+"-eclass", [], uid, portage_gid)
- except SystemExit, e:
- raise
- except Exception, e:
- writemsg("\n!!! Failed to open the dbmodule for eclass caching.\n")
- writemsg("!!! Generally these are permission problems. Caught exception follows:\n")
- writemsg("!!! "+str(e)+"\n")
- writemsg("!!! Dirname: "+str(self.depcachedir+"/"+location)+"\n")
- writemsg("!!! Basename: "+str(cat+"-eclass")+"\n\n")
- sys.exit(123)
-
- def sync(self, location, cat, pkg):
- if self.packages[location].has_key(cat):
- self.packages[location][cat].sync()
-
- def update_package(self, location, cat, pkg, eclass_list):
- self.setup_package(location, cat, pkg)
- if not eclass_list:
- return 1
-
- data = {}
- for x in eclass_list:
- if x not in self.eclasses:
- writemsg("Eclass '%s' does not exist for '%s'\n" % (x, cat+"/"+pkg))
- return 0
- data[x] = [self.eclasses[x][0],self.eclasses[x][1]]
-
- self.packages[location][cat][pkg] = data
- self.sync(location,cat,pkg)
- return 1
-
- def is_current(self, location, cat, pkg, eclass_list):
- self.setup_package(location, cat, pkg)
-
- if not eclass_list:
- return 1
-
- if not (self.packages[location][cat].has_key(pkg) and self.packages[location][cat][pkg] and eclass_list):
- return 0
-
- myp = self.packages[location][cat][pkg]
- for x in eclass_list:
- if not (x in self.eclasses and myp.has_key(x) and myp[x][0] == self.eclasses[x][0] and
- myp[x][1] == self.eclasses[x][1]):
- return 0
-
- return 1
-
-# ----------------------------------------------------------------------------
auxdbkeys=[
'DEPEND', 'RDEPEND', 'SLOT', 'SRC_URI',
@@ -4011,7 +2996,7 @@ class portdbapi(dbapi):
self.depcachedir = self.mysettings.depcachedir
- self.eclassdb = eclass_cache(self.porttree_root, self.mysettings)
+ self.eclassdb = eclass_cache.cache(self.porttree_root, self.mysettings)
self.metadb = {}
self.metadbmodule = self.mysettings.load_best_module("portdbapi.metadbmodule")
@@ -4097,7 +3082,7 @@ class portdbapi(dbapi):
myarch = settings["ARCH"]
pkgdict = settings.pkeywordsdict
- cp = dep_getkey(mycpv)
+ cp = portage_dep.dep_getkey(mycpv)
if pkgdict.has_key(cp):
matches = match_to_list(mycpv, pkgdict[cp].keys())
for match in matches:
@@ -4536,7 +3521,7 @@ class portdbapi(dbapi):
#this stuff only runs on first call of xmatch()
#create mydep, mykey from origdep
mydep=dep_expand(origdep,mydb=self)
- mykey=dep_getkey(mydep)
+ mykey=portage_dep.dep_getkey(mydep)
if level=="list-visible":
#a list of all visible packages, not called directly (just by xmatch())
@@ -4648,7 +3633,7 @@ class portdbapi(dbapi):
continue
mygroups=myaux[0].split()
pgroups=groups[:]
- cp = dep_getkey(mycpv)
+ cp = portage_dep.dep_getkey(mycpv)
if cp in pkgdict:
matches = match_to_list(mycpv, pkgdict[cp].keys())
for atom in matches:
@@ -4835,7 +3820,7 @@ class binarytree(packagetree):
continue
mycat=mycat.strip()
fullpkg=mycat+"/"+mypkg[:-5]
- mykey=dep_getkey(fullpkg)
+ mykey=portage_dep.dep_getkey(fullpkg)
try:
# invalid tbz2's can hurt things.
self.dbapi.cpv_inject(fullpkg)
@@ -4869,7 +3854,7 @@ class binarytree(packagetree):
continue
mycat=self.remotepkgs[mypkg]["CATEGORY"].strip()
fullpkg=mycat+"/"+mypkg[:-5]
- mykey=dep_getkey(fullpkg)
+ mykey=portage_dep.dep_getkey(fullpkg)
try:
# invalid tbz2's can hurt things.
#print "cpv_inject("+str(fullpkg)+")"
@@ -4899,7 +3884,7 @@ class binarytree(packagetree):
writemsg("mydep: %s\n" % mydep, 1)
mydep=dep_expand(mydep,mydb=self.dbapi)
writemsg("mydep: %s\n" % mydep, 1)
- mykey=dep_getkey(mydep)
+ mykey=portage_dep.dep_getkey(mydep)
writemsg("mykey: %s\n" % mykey, 1)
mymatch=best(match_from_list(mydep,self.dbapi.cp_list(mykey)))
writemsg("mymatch: %s\n" % mymatch, 1)
@@ -5321,7 +4306,7 @@ class dblink:
mykey=cpv_getkey(self.mycpv)
newworldlist=[]
for x in worldlist:
- if dep_getkey(x)==mykey:
+ if portage_dep.dep_getkey(x)==mykey:
matches=db[self.myroot]["vartree"].dbapi.match(x,use_cache=0)
if not matches:
#zap our world entry
@@ -6483,7 +5468,7 @@ def do_upgrade(mykey):
line=file_contents[x][mypos]
if line.strip()=="" or line.strip()[0]=="#":
continue
- key=dep_getkey(line.split()[0])
+ key=portage_dep.dep_getkey(line.split()[0])
if key==mysplit[1]:
file_contents[x][mypos]=line.replace(mysplit[1],mysplit[2])
update_files[x]=1
diff --git a/pym/portage_dep.py b/pym/portage_dep.py
index 68b071f..bb8409f 100644
--- a/pym/portage_dep.py
+++ b/pym/portage_dep.py
@@ -1,8 +1,8 @@
# deps.py -- Portage dependency resolution functions
# Copyright 2003-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/pym/portage_dep.py,v 1.23 2005/02/26 06:35:20 jstubbs Exp $
-cvs_id_string="$Id: portage_dep.py,v 1.23 2005/02/26 06:35:20 jstubbs Exp $"[5:-2]
+# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/pym/portage_dep.py,v 1.24 2005/03/07 04:00:30 ferringb Exp $
+cvs_id_string="$Id: portage_dep.py,v 1.24 2005/03/07 04:00:30 ferringb Exp $"[5:-2]
# DEPEND SYNTAX:
#
@@ -503,3 +503,38 @@ class DependencyGraph:
# Return our list.
return traversed
+
+def dep_getkey(mydep):
+ if not len(mydep):
+ return mydep
+ if mydep[0]=="*":
+ mydep=mydep[1:]
+ if mydep[-1]=="*":
+ mydep=mydep[:-1]
+ if mydep[0]=="!":
+ mydep=mydep[1:]
+ if mydep[:2] in [ ">=", "<=" ]:
+ mydep=mydep[2:]
+ elif mydep[:1] in "=<>~":
+ mydep=mydep[1:]
+ if isspecific(mydep):
+ mysplit=portage_versions.catpkgsplit(mydep)
+ if not mysplit:
+ return mydep
+ return mysplit[0]+"/"+mysplit[1]
+ else:
+ return mydep
+
+
+iscache={}
+def isspecific(mypkg):
+ "now supports packages with no category"
+ if mypkg in iscache:
+ return iscache[mypkg]
+ mysplit=mypkg.split("/")
+ if not isjustname(mysplit[-1]):
+ iscache[mypkg]=1
+ return 1
+ iscache[mypkg]=0
+ return 0
+
diff --git a/pym/portage_file.py b/pym/portage_file.py
index 6b43dfb..061501d 100644
--- a/pym/portage_file.py
+++ b/pym/portage_file.py
@@ -1,12 +1,13 @@
-# portage_data.py -- Calculated/Discovered Data Values
+# portage_file.py -- general fs stuff. I think.
# Copyright 1998-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/pym/portage_file.py,v 1.4 2005/02/26 06:35:20 jstubbs Exp $
-cvs_id_string="$Id: portage_file.py,v 1.4 2005/02/26 06:35:20 jstubbs Exp $"[5:-2]
+# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/pym/portage_file.py,v 1.5 2005/03/07 04:00:30 ferringb Exp $
+cvs_id_string="$Id: portage_file.py,v 1.5 2005/03/07 04:00:30 ferringb Exp $"[5:-2]
import os
import portage_data
import portage_exception
+import orig_dict_cache
from portage_localization import _
def normpath(mypath):
@@ -51,12 +52,68 @@ def makedirs(path, perms=0755, uid=None, gid=None, must_chown=False):
os.umask(old_umask)
-
-
-
-
-
-
-
-
-
+def listdir(mypath, recursive=False, filesonly=False, ignorecvs=False, ignorelist=[],
+ followSymlinks=True, cacheObject=None):
+
+ if cacheObject:
+ cfunc = cacheObject.cacheddir
+ else:
+ cfunc = orig_dict_cache.cacheddir
+ try:
+ list, ftype = cfunc(mypath)
+ except SystemExit:
+ raise
+ except Exception:
+ return []
+
+ if list is None:
+ list=[]
+ if ftype is None:
+ ftype=[]
+
+ if ignorecvs or len(ignorelist):
+ x=0
+ while x < len(list):
+ #we're working with first level entries, no os.path.basename requirement
+ if (ignorecvs and (list[x] in ('CVS','.svn') or list[x].startswith(".#"))) and not \
+ list[x] in ignorelist:
+ list.pop(x)
+ ftype.pop(x)
+ continue
+ x += 1
+
+ if not filesonly and not recursive:
+ return list
+
+ if recursive:
+ x=0
+ while x<len(ftype):
+ b=os.path.basename(list[x])
+ # if it was cvs, it was filtered already.
+ if ftype[x] == 1 or (followSymlinks and ftype[x] == 3):
+
+ l,f = cfunc(mypath+"/"+list[x])
+
+ y=0
+ while y < len(l):
+ # use list comprehension here.
+ if not (ignorecvs and (l[y] in ('CVS','.svn') or l[y].startswith(".#"))) \
+ and not l[y] in ignorelist:
+ l[y]=list[x]+"/"+l[y]
+ y += 1
+ else:
+ l.pop(y)
+ f.pop(y)
+
+ list=list+l
+ ftype=ftype+f
+ x+=1
+ if filesonly:
+ rlist=[]
+ for x in range(0,len(ftype)):
+ if ftype[x]==0:
+ rlist=rlist+[list[x]]
+ else:
+ rlist=list
+
+ return rlist
diff --git a/pym/portage_util.py b/pym/portage_util.py
index ccb4523..89eaa47 100644
--- a/pym/portage_util.py
+++ b/pym/portage_util.py
@@ -1,7 +1,7 @@
# Copyright 2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/pym/portage_util.py,v 1.19 2005/03/02 00:16:30 jstubbs Exp $
-cvs_id_string="$Id: portage_util.py,v 1.19 2005/03/02 00:16:30 jstubbs Exp $"[5:-2]
+# $Header: /local/data/ulm/cvs/history/var/cvsroot/gentoo-src/portage/pym/portage_util.py,v 1.20 2005/03/07 04:00:30 ferringb Exp $
+cvs_id_string="$Id: portage_util.py,v 1.20 2005/03/07 04:00:30 ferringb Exp $"[5:-2]
import sys,string,shlex,os.path,stat,types
import shutil
@@ -58,15 +58,6 @@ def grabfile(myfilename, compat_level=0):
newlines.append(myline)
return newlines
-def map_dictlist_vals(func,myDict):
- """Performs a function on each value of each key in a dictlist.
- Returns a new dictlist."""
- new_dl = {}
- for key in myDict.keys():
- new_dl[key] = []
- new_dl[key] = map(func,myDict[key])
- return new_dl
-
def stack_dictlist(original_dicts, incremental=0, incrementals=[], ignore_none=0):
"""Stacks an array of dict-types into one array. Optionally merging or
overwriting matching key/value pairs for the dict[key]->list.
@@ -167,6 +158,7 @@ def grabdict(myfilename,juststrings=0,empty=0):
return newdict
def grabdict_package(myfilename,juststrings=0):
+ from portage_dep import isvalidatom
pkgs=grabdict(myfilename, juststrings, empty=1)
for x in pkgs.keys():
if not isvalidatom(x):
@@ -175,6 +167,7 @@ def grabdict_package(myfilename,juststrings=0):
return pkgs
def grabfile_package(myfilename,compatlevel=0):
+ from portage_dep import isvalidatom
pkgs=grabfile(myfilename,compatlevel)
for x in range(len(pkgs)-1,-1,-1):
pkg = pkgs[x]
@@ -642,3 +635,36 @@ def flatten(mytokens):
return newlist
+def abssymlink(symlink):
+ """
+ This reads symlinks, resolving the relative symlinks, and returning the absolute.
+ """
+ mylink=os.readlink(symlink)
+ if mylink[0] != '/':
+ mydir=os.path.dirname(symlink)
+ mylink=mydir+"/"+mylink
+ return os.path.normpath(mylink)
+def match_to_list(mypkg,mylist):
+ """(pkgname,list)
+ Searches list for entries that matches the package.
+ """
+ matches=[]
+ for x in mylist:
+ if match_from_list(x,[mypkg]):
+ if x not in matches:
+ matches.append(x)
+ return matches
+
+def best_match_to_list(mypkg,mylist):
+ """(pkgname,list)
+ Returns the most specific entry (assumed to be the longest one)
+ that matches the package given.
+ """
+ # XXX Assumption is wrong sometimes.
+ maxlen = 0
+ bestm = None
+ for x in match_to_list(mypkg,mylist):
+ if len(x) > maxlen:
+ maxlen = len(x)
+ bestm = x
+ return bestm