Hola.

Attached is a patch that 
A) adds EAPI awareness to portage; mainly, if >0, complain and be 
   unwilling to merge the package
B) tweaks to portage_db_flat, addition of portage_db_metadata, and 
   portage_db_flat_hash

Flat_hash is the replacement cache format for metadata/cache; assuming 
nobody does anything stupid with EAPI, it will allow us to deploy new 
metadata in the tree without forcing a breakage every time we do so.

portage_db_metadata.py is a compability implementation; basically 
detects if it's flat_list (portage_db_flat), or flat_hash and calls 
accordingly.

Aside from that, tried to keep changes as minimal as possible.  The 
patch isn't complete due to the fact we need to add an EAPI cache 
compatibility check for --metadata transfer, but can't do that till I 
get some feedback from -dev ml regarding a bit of tree cleanup that 
will go along with it.

Please test this out; if you want to test the EAPI checking, tag 
EAPI=1 into an ebuild, and try making emerge bail.

If you're less adventurous, please test the compatibility cache 
testing; 
in /etc/portage/modules
portdbapi.metadbmodule=portage_db_metadata.database

Will enable the autodetection.  Additionally, 
portdbapi.auxdbmodule=portage_db_flat_hash.database

being flipped on would be appreciated, although you will have to wipe 
your cache and run emerge --metadata; with the settings above, you're 
testing the auto-detect functionality, and the new format.

Thanks,
~harring
diff -urN portage-old/bin/emerge portage/bin/emerge
--- portage-old/bin/emerge      2005-08-27 05:28:09.000000000 -0500
+++ portage/bin/emerge  2005-08-27 05:27:17.000000000 -0500
@@ -612,7 +612,7 @@
        help()
        sys.exit(0)
 elif portage.secpass!=2:
-       if myaction in ["search", "info", "regen"]:
+       if myaction in ["search", "info", "regen", "metadata"]:
                pass
        elif (not myaction) and (not myfiles):
                pass
@@ -1497,7 +1497,7 @@
                myfetchlist=[]
                for x in mylist:
                        fetch=" "
-
+                       stupid_if_logic_hack = True
                        if x[0]=="blocks":
                                addl=""+red("B")+"  "+fetch+"  "
                                
resolved=portage.db[x[1]]["vartree"].resolve_key(x[2])
@@ -1512,7 +1512,22 @@
                                                print red("(is blocking 
"+x[3]+")")
                                        else:
                                                print
+                               stupid_if_logic_hack = False
+
                        else:
+                               if x[0] == "ebuild":    source = "porttree"
+                               elif x[0] == "binary":  source = "bintree"
+                               elif x[0] == ("nomerge", "blocker"):    source 
= None
+                               else:
+                                       print "EAPI check, unknown source 
"+str(x[0])+" for "+x[2]+", this shouldn't occur",mylist
+                                       sys.exit(1)
+                               if source:
+                                       needed = 
portage.db[x[1]][source].dbapi.aux_get(x[2], ["EAPI"])[0]
+                                       if needed > portage.EAPI:
+                                               print '[%s] %s %s, EAPI:%i 
installed portage EAPI:%i' % (x[0].ljust(13), x[2], red("UNMERGABLE"),needed, 
portage.EAPI)
+                                               stupid_if_logic_hack = True
+
+                       if stupid_if_logic_hack:
                                if (x[0]!="binary") and ("fetch" in 
string.split(portage.portdb.aux_get(x[2],["RESTRICT"])[0])):
                                        fetch = red("F")
                                        if portage.portdb.fetch_check(x[2], 
portage.settings):
@@ -1830,6 +1845,34 @@
                self.pkgsettings["FEATURES"]=string.join(myfeat)
 
                mergecount=0
+               
+               unmergable = []
+               for source, root, cpv, action in mymergelist:
+                       if source == "ebuild":  source = "porttree"
+                       elif source == "binary": source = "bintree"
+                       elif source in ("nomerge", "blocks"):
+                               continue
+                       else:
+                               print "EAPI check, unknown source 
"+str(source)+" for "+cpv+", this shouldn't occur",mymergelist
+                               sys.exit(1)
+                       needed = portage.db[root][source].dbapi.aux_get(cpv, 
["EAPI"])[0]
+                       if portage.EAPI < needed:
+                               unmergable.append((needed, cpv))
+
+               if len(unmergable):
+                       print
+                       print red("!!!")
+                       print red("!!!")+" %s" % red("Ebuild API 
incompatibility")
+                       print red("!!!")+" installed portage EAPI is %i, the 
following packages require a higher version" % portage.EAPI
+                       print red("!!!")+" This version of portage is incapable 
of installing the higher version"
+                       print red("!!!")+" A portage upgrade should solve this"
+                       print red("!!!")
+                       for needed, cpv in unmergable:
+                               print ">>>    %s requires EAPI %s" % (cpv, 
red(str(needed)))
+                       print
+                       if not ("--fetchonly" in myopts or "--fetch-all-uri" in 
myopts or "--pretend" in myopts):
+                               sys.exit(1)
+
                for x in mymergelist:
                        mergecount+=1
                        myroot=x[1]
diff -urN 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-27 05:27:26.000000000 -0500
@@ -81,7 +81,7 @@
          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
@@ -5077,9 +5071,9 @@
   '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)
 
@@ -5373,10 +5367,15 @@
                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] = int(returnme[idx])
+                       except ValueError:
+                               # string
+                               returnme[idx] = 0
 
                return returnme
 
diff -urN 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 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 @@
                                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 @@
 
                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 -urN 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 -urN 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)
--- portage-old/pym/portage_const.py    2005-04-28 23:56:35.000000000 -0500
+++ portage/pym/portage_const.py        2005-08-27 03:59:09.000000000 -0500
@@ -43,6 +43,9 @@
 
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"]
 
+# supported EBUILD api versions.
+EAPI = 0
+
 # ===========================================================================
 # END OF CONSTANTS -- END OF CONSTANTS -- END OF CONSTANTS -- END OF CONSTANT
 # ===========================================================================

Attachment: pgpHVzeEVHT1x.pgp
Description: PGP signature

Reply via email to