--- portage.py.org 2003-09-09 02:05:08.000000000 +0200 +++ portage.py.org 2003-09-11 07:52:58.000000000 +0200 @@ -4175,6 +4175,7 @@ self.dbdir=os.path.normpath(myroot+"///var/db/pkg/"+cat+"/"+pkg) self.myroot=myroot self.updateprotect() + self.contentscache=[] def getpath(self): "return path to location of db information (for >>> informational display)" @@ -4213,6 +4214,8 @@ def getcontents(self): if not os.path.exists(self.dbdir+"/CONTENTS"): return None + if self.contentscache != []: + return self.contentscache pkgfiles={} myc=open(self.dbdir+"/CONTENTS","r") mylines=myc.readlines() @@ -4253,6 +4256,7 @@ except (KeyError,IndexError): print "portage: CONTENTS line",pos,"corrupt!" pos += 1 + self.contentscache=pkgfiles return pkgfiles def updateprotect(self): @@ -4499,11 +4503,71 @@ if myebuildpath and os.path.exists(myebuildpath): a=doebuild(myebuildpath,"postrm",self.myroot) + def isowner(self,filename,destroot): + """ check if filename is a new file or belongs to this package + (for this or a previous version)""" + destfile = os.path.normpath(destroot+"/"+filename) + if not os.path.exists(destfile): + return True + if self.getcontents() and filename in self.getcontents().keys(): + return True + + return False + def treewalk(self,srcroot,destroot,inforoot,myebuild): global settings # srcroot = ${D}; destroot=where to merge, ie. ${ROOT}, inforoot=root of db entry, # secondhand = list of symlinks that have been skipped due to their target not existing (will merge later), "this is going to be the new merge code" + + # check for package collisions + # need to wait for python-2.3 to use os.walk(), use popen until then + if "collision-protect" in features: + myfilelist = os.popen("find "+srcroot+" -type f", "r").readlines() + stopmerge=False + starttime=time.time() + i=0 + # this is a ugly hack to get the other versions of the same package, + # feel free to improve + otherpkg=[self.cat+"/"+mydir.split("/")[-1] for mydir in os.listdir(self.myroot+"var/db/pkg/"+self.cat)] + otherversions=filter(lambda a: a[1] == catpkgsplit(self.pkg)[1], [catpkgsplit(p) for p in otherpkg]) + otherversions=map(lambda a: (a[1]+"-"+a[2]+"-"+a[3]).replace("-r0",""), otherversions) + otherversions.remove(self.pkg) # we already checked this package + mypkglist=[] + for v in otherversions: + # should we check for same SLOT here ? + mypkglist.append(dblink(self.cat,v,destroot)) + + print green("*")+" checking "+str(len(myfilelist))+" files for package collisions" + for f in myfilelist: + i=i+1 + if i % 1000 == 0: + print str(i)+" files checked ..." + f=f[len(srcroot)-1:-1] + isowned = False + for ver in [self]+mypkglist: + if (ver.isowner(f, destroot) or ver.isprotected(f)): + isowned = True + break + if not isowned: + print "existing file "+f+" is not owned by this package" + stopmerge=True + print green("*")+" spend "+str(time.time()-starttime)+" seconds checking for file collisions" + if stopmerge: + print red("*")+" This package is blocked because it wants to overwrite" + print red("*")+" files belonging to other packages (see messages above)." + print red("*")+" If you have no clue what this is all about report it " + print red("*")+" as a bug for this package on http://bugs.gentoo.org" + print + print red("package "+self.cat+"/"+self.pkg+" NOT merged") + print + # Why is the package already merged here db-wise? Shouldn't be the case + # only unmerge if it ia new package and has no contents + if not self.getcontents(): + self.unmerge() + self.delete() + sys.exit(1) + if not os.path.exists(self.dbdir): self.create()