Currently vardbapi.aux_get only works for a subset of all auxdbkeys, as some like KEYWORDS or DESCRIPTIOn aren't stored in vdb directly. They are however stored in environment.bz2, but not accessible there. This is unintuitive and limits tools like equery or my own auxget and metascan tools in their usability.
There are two solutions to this problem: a) enhance vardbapi.aux_get so it can use environment.bz2 b) store more keys in vdb Now there is a tradeoff to made: a) doesn't need space but is slow while b) is fast but needs space, both in non-trivial amounts (runtime increased from 1s to 9s for a metascan -i run and from 0.5s to 0.8s for auxget -i, haven't actually checked the size increase, expect somewhere between 1 and 10 megabytes on a typical install). I'm attaching a patch that implements both (each in it's own hunk) as well as a new emaint option to create the missing entries offline. A not so obvious issue with a) is that due to the recent storage optimizations (empty entries not being stored) it's worse than I originally expected, as any entry missing a file will be looked up in env.bz2 instead. Only way to avoid that would be to add special casing in aux_get which I really dislike. Opinions? Marius -- Public Key at http://www.genone.de/info/gpg-key.pub In the beginning, there was nothing. And God said, 'Let there be Light.' And there was still nothing, but you could see a bit better.
--- /home/gentoo/svn/portage/main/trunk/bin/ebuild.sh 2006-01-08 04:30:16.000000000 +0100
+++ /usr/lib/portage/bin/ebuild.sh 2006-01-10 18:27:15.000000000 +0100
@@ -914,7 +914,8 @@
for f in ASFLAGS CATEGORY CBUILD CC CFLAGS CHOST CTARGET CXX \
CXXFLAGS DEPEND EXTRA_ECONF EXTRA_EINSTALL EXTRA_MAKE \
FEATURES INHERITED IUSE LDFLAGS LIBCFLAGS LIBCXXFLAGS \
- LICENSE PDEPEND PF PKGUSE PROVIDE RDEPEND RESTRICT SLOT; do
+ LICENSE PDEPEND PF PKGUSE PROVIDE RDEPEND RESTRICT SLOT \
+ KEYWORDS HOMEPAGE SRC_URI DESCRIPTION; do
[ -n "${!f}" ] && echo $(echo "${!f}" | tr '\n,\r,\t' ' , , ' | sed s/' \+'/' '/g) > ${f}
done
echo "${USE}" > USE
--- /home/gentoo/svn/portage/main/trunk/pym/portage.py 2006-01-08 04:30:11.000000000 +0100
+++ /usr/lib/portage/pym/portage.py 2006-01-10 18:28:00.000000000 +0100
@@ -4501,17 +4477,32 @@
def aux_get(self, mycpv, wants):
global auxdbkeys
results = []
+ envlines = None
for x in wants:
- myfn = self.root+VDB_PATH+"/"+str(mycpv)+"/"+str(x)
- if os.access(myfn,os.R_OK):
- myf = open(myfn, "r")
+ mydir = self.root+VDB_PATH+"/"+str(mycpv)+"/"
+ if os.access(mydir+str(x),os.R_OK):
+ myf = open(mydir+str(x), "r")
myd = myf.read()
myf.close()
- myd = re.sub("[\n\r\t]+"," ",myd)
- myd = re.sub(" +"," ",myd)
- myd = string.strip(myd)
+ # Fallback to searching environment.bz2 if no key-specific file exists
+ elif os.access(mydir+"environment.bz2", os.R_OK):
+ if not envlines:
+ env = os.popen("bzip2 -dcq "+mydir+"environment.bz2", "r")
+ envlines = env.read().split("\n")
+ env.close()
+ myd = [l for l in envlines if l.strip("\"\'").startswith(x+"=")]
+ if len(myd) > 1:
+ raise portage_exception.CorruptionError("multiple matches for "+x+" found in "+mydir+"environment.bz2")
+ elif len(myd) == 0:
+ myd = ""
+ else:
+ myd = myd[0].split("=",1)[1]
+ myd = myd.lstrip("$").strip("\'\"")
+ myd = re.sub("(\\\\[nrt])+", " ", myd)
else:
myd = ""
+ myd = re.sub("[\n\r\t]+"," ",myd)
+ myd = re.sub(" +"," ",myd)
+ myd = string.strip(myd)
results.append(myd)
if "EAPI" in wants:
idx = wants.index("EAPI")
--- /home/gentoo/svn/portage/main/trunk/bin/emaint 2006-01-08 04:30:16.000000000 +0100
+++ /usr/lib/portage/bin/emaint 2006-01-10 19:29:20.000000000 +0100
@@ -4,7 +4,7 @@
from copy import copy
from optparse import OptionParser, OptionValueError
-
+import re
import os, portage, portage_const
class WorldHandler(object):
@@ -44,8 +44,65 @@
errors.append(portage_const.WORLD_FILE + " could not be opened for writing")
return errors
+class VdbKeyHandler(object):
+ def name():
+ return "vdbkeys"
+ name = staticmethod(name)
+
+ def __init__(self):
+ self.list = portage.db["/"]["vartree"].dbapi.cpv_all()
+ self.missing = []
+ self.keys = ["HOMEPAGE", "SRC_URI", "KEYWORDS", "DESCRIPTION"]
+
+ for p in self.list:
+ mydir = "/var/db/pkg/"+p
+ ismissing = True
+ for k in self.keys:
+ if os.path.exists(mydir+"/"+k):
+ ismissing = False
+ break
+ if ismissing:
+ self.missing.append(p)
+
+ def check(self):
+ return ["%s has missing keys" % x for x in self.missing]
+
+ def fix(self):
+
+ errors = []
+
+ for p in self.missing:
+ mydir = "/var/db/pkg/"+p
+ if not os.access(mydir+"/environment.bz2", os.R_OK):
+ errors.append("Can't access %s" % (mydir+"/environment.bz2"))
+ elif not os.access(mydir, os.W_OK):
+ errors.append("Can't create files in %s" % mydir)
+ else:
+ env = os.popen("bzip2 -dcq "+mydir+"/environment.bz2", "r")
+ envlines = env.read().split("\n")
+ env.close()
+ for k in self.keys:
+ s = [l for l in envlines if l.strip("\"\'").startswith(k+"=")]
+ if len(s) > 1:
+ errors.append("multiple matches for %s found in %s/environment.bz2" % (k, mydir))
+ elif len(s) == 0:
+ s = ""
+ else:
+ s = s[0].split("=",1)[1]
+ s = s.lstrip("$").strip("\'\"")
+ s = re.sub("(\\\\[nrt])+", " ", s)
+ s = re.sub("[\n\r\t]+"," ",s)
+ s = re.sub(" +"," ",s)
+ s = s.strip()
+ if s != "":
+ keyfile = open(mydir+"/"+k, "w")
+ keyfile.write(s+"\n")
+ keyfile.close()
+
+ return errors
-modules = {"world" : WorldHandler}
+modules = {"world" : WorldHandler,
+ "vdbkeys": VdbKeyHandler}
module_names = modules.keys()
signature.asc
Description: PGP signature
