On Mon, Aug 29, 2005 at 01:52:50PM -0700, Zac Medico wrote: > Brian Harring wrote: > > > >Please test this out; if you want to test the EAPI checking, tag > >EAPI=1 into an ebuild, and try making emerge bail. > > > > Well, it bails too often. :) Mainly cause I generated something of a crap patch leaving a bit of stuff out from the looks of it :)
> It seems that an explicit integer conversion is needed for > and < > comparisons with mixed types > (2.0.51-eapi-awareness-emerge-int-conversion.patch). > >If you're less adventurous, please test the compatibility cache > >testing; > >in /etc/portage/modules > >portdbapi.metadbmodule=portage_db_metadata.database > > > > We need to make sure EAPI defaults to 0 when using old metadata. It seems > like db_template.__getitem__() is a nice central place to do that > (2.0.51-eapi-awareness-db_template.patch). I made another patch for > bindbapi.aux_get() which does the same for old metadata from binpkgs > (2.0.51-eapi-awareness-bindbapi.aux_get.patch). The default'ing should occur outside of the cache layer imo, due to the fact it has to occur in every dbapi. Attached is a patch doing so, using gvisible to mask ebuild's EAPI > portage's EAPI, and a check in doebuild to block people from trying to do things with an ebuild that has an EAPI greater then portage's. The doebuild mod is strictly for non depend phases; the data from a depend's phase gets nuked and EAPI set to -EAPI if it's a later version that what portage knows about. Discussed on irc a bit, but repeating the reasons for those on the ml who've missed the logic; effectively, an EAPI=0 portage generating an EAPI=1 cache entry cannot be guranteed to generate it correctly, contain all needed metadata. So you flag it specially (negated EAPI), and don't store anything. Add a few checks in so when an EAPI=1 portage finds the EAPI=1 cache entry, which has been negated to mean effectively "someone who is EAPI=1, please regenerate me", it gets regenerated, and the entry can be trusted to hold all required EAPI1 metadata. Attached is a patch culminating the feedback, with a few tweaks. Should work a helluva lot better this time around :) ~harring
diff -purN portage-old/bin/ebuild.sh portage/bin/ebuild.sh
--- portage-old/bin/ebuild.sh 2005-08-29 02:16:41.000000000 -0500
+++ portage/bin/ebuild.sh 2005-08-29 17:02:00.000000000 -0500
@@ -1831,6 +1831,7 @@ for myarg in $*; do
echo `echo "$CDEPEND"` >> $dbkey
echo `echo "$PDEPEND"` >> $dbkey
echo `echo "$PROVIDE"` >> $dbkey
+ echo `echo "${EAPI:-0}"` >> $dbkey
echo `echo "$UNUSED_01"` >> $dbkey
echo `echo "$UNUSED_02"` >> $dbkey
echo `echo "$UNUSED_03"` >> $dbkey
@@ -1838,7 +1839,6 @@ for myarg in $*; do
echo `echo "$UNUSED_05"` >> $dbkey
echo `echo "$UNUSED_06"` >> $dbkey
echo `echo "$UNUSED_07"` >> $dbkey
- echo `echo "$UNUSED_08"` >> $dbkey
set +f
#make sure it is writable by our group:
exit 0
diff -purN portage-old/pym/portage.py portage/pym/portage.py
--- portage-old/pym/portage.py 2005-08-27 05:28:02.000000000 -0500
+++ portage/pym/portage.py 2005-08-29 17:11:30.000000000 -0500
@@ -81,7 +81,7 @@ try:
MOVE_BINARY, PRELINK_BINARY, WORLD_FILE, MAKE_CONF_FILE,
MAKE_DEFAULTS_FILE, \
DEPRECATED_PROFILE_FILE, USER_VIRTUALS_FILE, EBUILD_SH_ENV_FILE, \
INVALID_ENV_FILE, CUSTOM_MIRRORS_FILE, SANDBOX_PIDS_FILE,
CONFIG_MEMORY_FILE,\
- INCREMENTALS, STICKIES
+ INCREMENTALS, STICKIES, EAPI
from portage_data import ostype, lchown, userland, secpass, uid,
wheelgid, \
portage_uid, portage_gid
@@ -2402,6 +2396,15 @@ def doebuild(myebuild,mydo,myroot,mysett
raise
except:
pass
+ try:
+ eapi = abs(db[root][tree].dbapi.aux_get(mycpv,
["EAPI"])[0])
+ if portage_const.EAPI != eapi:
+ # can't do anything with this.
+ raise Exception("Unable to do any operations on
'%s', due to the fact it's EAPI is higher then this portage versions. Please
upgrade to a portage version that supports EAPI %i" % (mycpv, eapi))
+ except SystemExit, e:
+ raise
+ except Exception, e:
+ raise Exception("Unable to pull EAPI from cpv %s, tree
%s; can't confirm that it's supported by this portage, thus unable to merge it:
Exception was '%s'" % (mycpv, tree, e))
if mysplit[2] == "r0":
mysettings["PVR"]=mysplit[1]
@@ -3911,7 +3914,10 @@ def getmaskingstatus(mycpv):
rValue.append("package.mask")
# keywords checking
- mygroups = portdb.aux_get(mycpv, ["KEYWORDS"])[0].split()
+ mygroups, eapi = portdb.aux_get(mycpv, ["KEYWORDS", "EAPI"])
+ if abs(eapi) > portage_const.EAPI:
+ return ["required EAPI %i, supported EAPI %i" % (eapi,
portage_const.EAPI)]
+ mygroups = mygroups.split()
pgroups=groups[:]
myarch = settings["ARCH"]
pkgdict = settings.pkeywordsdict
@@ -4531,7 +4537,12 @@ class bindbapi(fakedbapi):
else:
myval = string.join(myval.split(),' ')
mylist.append(myval)
-
+ if "EAPI" in wants:
+ idx = wants.index("EAPI")
+ try:
+ mylist[idx] = abs(int(mylist[idx]))
+ except ValueError:
+ mylist[idx] = 0
return mylist
@@ -4811,6 +4822,12 @@ class vardbapi(dbapi):
else:
myd = ""
results.append(myd)
+ if "EAPI" in wants:
+ idx = wants.index("EAPI")
+ try:
+ results[idx] = abs(int(wants[idx]))
+ except ValueError:
+ results[idx] = 0
return results
@@ -5077,9 +5094,9 @@ auxdbkeys=[
'DEPEND', 'RDEPEND', 'SLOT', 'SRC_URI',
'RESTRICT', 'HOMEPAGE', 'LICENSE', 'DESCRIPTION',
'KEYWORDS', 'INHERITED', 'IUSE', 'CDEPEND',
- 'PDEPEND', 'PROVIDE',
+ 'PDEPEND', 'PROVIDE', 'EAPI',
'UNUSED_01', 'UNUSED_02', 'UNUSED_03', 'UNUSED_04',
- 'UNUSED_05', 'UNUSED_06', 'UNUSED_07', 'UNUSED_08',
+ 'UNUSED_05', 'UNUSED_06', 'UNUSED_07',
]
auxdbkeylen=len(auxdbkeys)
@@ -5293,11 +5310,18 @@ class portdbapi(dbapi):
# we use cache files, which is usually on
/usr/portage/metadata/cache/.
if doregen and mylocation==self.mysettings["PORTDIR"] and
metacachedir and self.metadb[cat].has_key(pkg):
metadata=self.metadb[cat][pkg]
+
+ if metadata.setdefault("EAPI", 0) != portage_const.EAPI:
+ # intentionally wipe keys.
+ metadata = {"EAPI":-metadata["EAPI"]}
+
+ # fun...
+ # we know that metadata cache entries *always* have all
keys
self.eclassdb.update_package(mylocation,cat,pkg,metadata["INHERITED"].split())
self.auxdb[mylocation][cat][pkg] = metadata
self.auxdb[mylocation][cat].sync()
- elif doregen:
+ elif doregen:
writemsg("doregen: %s %s\n" % (doregen,mycpv), 2)
writemsg("Generating cache entry(0) for:
"+str(myebuild)+"\n",1)
@@ -5362,6 +5386,14 @@ class portdbapi(dbapi):
if mylines[x][-1] == '\n':
mylines[x] = mylines[x][:-1]
mydata[auxdbkeys[x]] = mylines[x]
+
+ eapi = int(mydata["EAPI"])
+ if eapi > portage_const.EAPI:
+ # if newer version, wipe everything and negate
eapi
+ mydata = {}
+ map(lambda x:mydata.setdefault(x, ""),
auxdbkeys)
+ mydata["EAPI"] = -eapi
+
mydata["_mtime_"] = emtime
self.auxdb[mylocation][cat][pkg] = mydata
@@ -5373,10 +5405,15 @@ class portdbapi(dbapi):
mydata = self.auxdb[mylocation][cat][pkg]
returnme = []
for x in mylist:
- if mydata.has_key(x):
- returnme.append(mydata[x])
- else:
- returnme.append("")
+ returnme.append(mydata.get(x,""))
+
+ if "EAPI" in mylist:
+ idx = mylist.index("EAPI")
+ try:
+ returnme[idx] = abs(int(returnme[idx]))
+ except ValueError:
+ # string
+ returnme[idx] = 0
return returnme
@@ -5625,14 +5662,14 @@ class portdbapi(dbapi):
#we need to update this next line when we have fully
integrated the new db api
auxerr=0
try:
- myaux=db["/"]["porttree"].dbapi.aux_get(mycpv,
["KEYWORDS"])
+ keys, eapi =
db["/"]["porttree"].dbapi.aux_get(mycpv, ["KEYWORDS", "EAPI"])
except (KeyError,IOError,TypeError):
continue
- if not myaux[0]:
+ if not keys:
# KEYWORDS=""
#print "!!! No KEYWORDS for "+str(mycpv)+" --
Untested Status"
continue
- mygroups=myaux[0].split()
+ mygroups=keys.split()
pgroups=groups[:]
match=0
cp = dep_getkey(mycpv)
@@ -5660,7 +5697,8 @@ class portdbapi(dbapi):
if not match and ((hastesting and "~*" in pgroups) or
(hasstable and "*" in pgroups)):
match=1
if match:
- newlist.append(mycpv)
+ if eapi == portage_const.EAPI:
+ newlist.append(mycpv)
return newlist
class binarytree(packagetree):
diff -purN portage-old/pym/portage_const.py portage/pym/portage_const.py
--- portage-old/pym/portage_const.py 2005-08-29 17:05:10.000000000 -0500
+++ portage/pym/portage_const.py 2005-08-29 17:06:02.000000000 -0500
@@ -43,6 +43,8 @@ CONFIG_MEMORY_FILE = PRIVATE_PATH +
INCREMENTALS=["USE","FEATURES","ACCEPT_KEYWORDS","ACCEPT_LICENSE","CONFIG_PROTECT_MASK","CONFIG_PROTECT","PRELINK_PATH","PRELINK_PATH_MASK"]
STICKIES=["KEYWORDS_ACCEPT","USE","CFLAGS","CXXFLAGS","MAKEOPTS","EXTRA_ECONF","EXTRA_EINSTALL","EXTRA_EMAKE"]
+EAPI = 0
+
# ===========================================================================
# END OF CONSTANTS -- END OF CONSTANTS -- END OF CONSTANTS -- END OF CONSTANT
# ===========================================================================
diff -purN portage-old/pym/portage_db_flat.py portage/pym/portage_db_flat.py
--- portage-old/pym/portage_db_flat.py 2005-08-27 05:27:59.000000000 -0500
+++ portage/pym/portage_db_flat.py 2005-08-27 05:27:43.000000000 -0500
@@ -9,6 +9,10 @@ import stat
import portage_db_template
+# since this format is massively deprecated,
+# we're hardcoding the previously weird line count
+magic_line_count = 22
+
class database(portage_db_template.database):
def module_init(self):
self.lastkey = None # Cache
@@ -42,39 +46,39 @@ class database(portage_db_template.datab
mykeys += [x]
return mykeys
- def get_values(self,key):
+ def get_values(self,key, data=None):
+ """ do not use data unless you know what it does."""
+
if not key:
raise KeyError, "key is not set to a valid value"
- try:
- # give buffering a hint of the pretty much maximal
cache size we deal with
- myf = open(self.fullpath+key, "r", 8192)
- except OSError, oe:
- # either the file didn't exist, or it was removed under
our feet.
- return None
-
+ mydict = {}
+ if data == None:
+ try:
+ # give buffering a hint of the pretty much
maximal cache size we deal with
+ myf = open(self.fullpath+key, "r", 8192)
+ except OSError:
+ # either the file didn't exist, or it was
removed under our feet.
+ raise KeyError("failed reading key")
+
+ # nuke the newlines right off the batt.
+ data = myf.read().splitlines()
+ mydict["_mtime_"] = os.fstat(myf.fileno()).st_mtime
+ myf.close()
+ else:
+ mydict["_mtime_"] = data.pop(-1)
- # nuke the newlines right off the batt.
- data = myf.read().splitlines()
- mdict = {}
-
# rely on exceptions to note differing line counts.
try:
- for x in range(0, len(self.dbkeys)):
- mdict[self.dbkeys[x]] = data[x]
-
- # do this now, rather then earlier- possible that
earlier it might have been wasted
- # if key count mismatched
- mdict["_mtime_"] = os.fstat(myf.fileno()).st_mtime
+ for x in range(magic_line_count):
+ mydict[self.dbkeys[x]] = data[x]
except IndexError:
- myf.close()
raise ValueError, "Key count mistmatch"
- myf.close()
- return mdict
+ return mydict
- def set_values(self,key,val):
+ def set_values(self,key, val, raw=False):
if not key:
raise KeyError, "No key provided. key:%s val:%s" %
(key,val)
if not val:
@@ -86,12 +90,19 @@ class database(portage_db_template.datab
update_fp = self.fullpath + ".update." + str(os.getpid()) + "."
+ key
myf = open(update_fp,"w")
- myf.writelines( [ val[x] +"\n" for x in self.dbkeys] )
+ if not raw:
+ myf.writelines( [ val[x] +"\n" for x in self.dbkeys] )
+ if len(self.dbkeys) != magic_line_count:
+ myf.writelines(["\n"] * len(self.dbkeys) -
magic_line_count)
+ mtime = val["_mtime_"]
+ else:
+ mtime = val.pop(-1)
+ myf.writelines(val)
myf.close()
os.chown(update_fp, self.uid, self.gid)
os.chmod(update_fp, 0664)
- os.utime(update_fp, (-1,long(val["_mtime_"])))
+ os.utime(update_fp, (-1,long(mtime)))
os.rename(update_fp, self.fullpath+key)
def del_key(self,key):
diff -purN portage-old/pym/portage_db_flat_hash.py
portage/pym/portage_db_flat_hash.py
--- portage-old/pym/portage_db_flat_hash.py 1969-12-31 18:00:00.000000000
-0600
+++ portage/pym/portage_db_flat_hash.py 2005-08-27 05:27:43.000000000 -0500
@@ -0,0 +1,38 @@
+# Copyright 2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/pym/Attic/portage_db_flat.py,v
1.13.2.6 2005/04/19 07:14:17 ferringb Exp $
+cvs_id_string="$Id: portage_db_flat.py,v 1.13.2.6 2005/04/19 07:14:17 ferringb
Exp $"[5:-2]
+
+import portage_db_flat, os
+
+class database(portage_db_flat.database):
+
+ def get_values(self, key, data=None):
+ """ do not specify data unless you know what it does"""
+ if not key:
+ raise KeyError("key is not valid")
+
+ if data == None:
+ try:
+ myf = open(self.fullpath + key, "r")
+ except OSError:
+ raise KeyError("failed pulling key")
+
+ data = dict(map(lambda x: x.split("=",1),
myf.read().splitlines()))
+ data["_mtime_"] = os.fstat(myf.fileno()).st_mtime
+ myf.close()
+
+ mydict = {}
+ for x in self.dbkeys:
+ mydict[x] = data.get(x, "")
+ mydict["_mtime_"] = long(data["_mtime_"])
+ return mydict
+
+ def set_values(self, key, values):
+ l = []
+ for x in values.keys():
+ if values[x] and x != "_mtime_":
+ l.append("%s=%s\n" % (x, values[x]))
+ l.append(values["_mtime_"])
+ portage_db_flat.database.set_values(self, key, l, raw=True)
+
diff -purN portage-old/pym/portage_db_metadata.py
portage/pym/portage_db_metadata.py
--- portage-old/pym/portage_db_metadata.py 1969-12-31 18:00:00.000000000
-0600
+++ portage/pym/portage_db_metadata.py 2005-08-27 05:27:43.000000000 -0500
@@ -0,0 +1,49 @@
+# Copyright 2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/pym/Attic/portage_db_flat.py,v
1.13.2.6 2005/04/19 07:14:17 ferringb Exp $
+cvs_id_string="$Id: portage_db_flat.py,v 1.13.2.6 2005/04/19 07:14:17 ferringb
Exp $"[5:-2]
+
+import os, portage_db_flat_hash, portage_db_flat
+
+class database(portage_db_flat_hash.database):
+
+ def get_values(self, key):
+ if not key:
+ raise KeyError("key is not valid")
+
+ try:
+ myf = open(self.fullpath + key, "r")
+ except OSError:
+ raise KeyError("key is not valid")
+ mtime = os.fstat(myf.fileno()).st_mtime
+ data = myf.read().splitlines()
+
+ # easy attempt first.
+ if len(data) != portage_db_flat.magic_line_count:
+ d = dict(map(lambda x: x.split("=",1), data))
+ d["_mtime_"] = mtime
+ return portage_db_flat_hash.database.get_values(self,
key, d)
+ # this one's interesting.
+ d = {}
+
+ for line in data:
+ # yes, meant to iterate over a string.
+ hashed = False
+ for idx, c in enumerate(line):
+ if not c.isalpha():
+ if c == "=" and idx > 0:
+ hashed = True
+ d[line[:idx]] = line[idx + 1:]
+ elif c == "_" or c.isdigit():
+ continue
+ break
+ elif not c.isupper():
+ break
+
+ if not hashed:
+ # non hashed.
+ data.append(mtime)
+ return
portage_db_flat.database.get_values(self, key, data=data)
+
+ d["_mtime_"] = mtime
+ return portage_db_flat_hash.database.get_values(self, key,
data=d)
pgppdMQdgmJUB.pgp
Description: PGP signature
