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)

Attachment: pgppdMQdgmJUB.pgp
Description: PGP signature

Reply via email to