#XXX: These two are now implemented in portage_util.py but are needed here
#XXX: until the isvalidatom() dependency is sorted out.
-def grabdict_package(myfilename,juststrings=0):
- pkgs=grabdict(myfilename, juststrings=juststrings, empty=1)
+def grabdict_package(myfilename,juststrings=0,recursive=0):
+ pkgs=grabdict(myfilename, juststrings=juststrings, empty=1,recursive=recursive)
for x in pkgs.keys():
if not isvalidatom(x):
del(pkgs[x])
writemsg("--- Invalid atom in %s: %s\n" % (myfilename, x))
return pkgs
-def grabfile_package(myfilename,compatlevel=0):
- pkgs=grabfile(myfilename,compatlevel)
+def grabfile_package(myfilename,compatlevel=0,recursive=0):
+ pkgs=grabfile(myfilename,compatlevel,recursive=recursive)
for x in range(len(pkgs)-1,-1,-1):
pkg = pkgs[x]
if pkg[0] == "-":
if os.path.isdir(ov+"/profiles"):
locations.append(ov+"/profiles")
- pusedict=grabdict_package(USER_CONFIG_PATH+"/package.use")
+ pusedict=grabdict_package(USER_CONFIG_PATH+"/package.use", recursive=1)
self.pusedict = {}
for key in pusedict.keys():
cp = dep_getkey(key)
self.pusedict[cp][key] = pusedict[key]
#package.keywords
- pkgdict=grabdict_package(USER_CONFIG_PATH+"/package.keywords")
+ pkgdict=grabdict_package(USER_CONFIG_PATH+"/package.keywords", recursive=1)
self.pkeywordsdict = {}
for key in pkgdict.keys():
# default to ~arch if no specific keyword is given
self.pkeywordsdict[cp][key] = pkgdict[key]
#package.unmask
- pkgunmasklines = grabfile_package(USER_CONFIG_PATH+"/package.unmask")
+ pkgunmasklines = grabfile_package(USER_CONFIG_PATH+"/package.unmask",recursive=1)
self.punmaskdict = {}
for x in pkgunmasklines:
mycatpkg=dep_getkey(x)
self.loadVirtuals('/')
#package.mask
- pkgmasklines = grab_multiple("package.mask", self.profiles + locations, grabfile_package)
+ pkgmasklines = grab_multiple("package.mask", self.profiles, grabfile_package)
+ for l in locations:
+ pkgmasklines.append(grabfile_package(l+os.path.sep+"package.mask", recursive=1))
pkgmasklines = stack_lists(pkgmasklines, incremental=1)
self.pmaskdict = {}
check_config_instance(mysettings)
- custommirrors=grabdict(CUSTOM_MIRRORS_FILE)
+ custommirrors=grabdict(CUSTOM_MIRRORS_FILE,recursive=1)
mymirrors=[]
os.chown(mysettings["T"],portage_uid,portage_gid)
os.chmod(mysettings["T"],02770)
+ logdir = mysettings["T"]+"/logging"
+ if not os.path.exists(logdir):
+ os.makedirs(logdir)
+ os.chown(logdir, portage_uid, portage_gid)
+ os.chmod(logdir, 0770)
+
try: # XXX: negative RESTRICT
if not (("nouserpriv" in string.split(mysettings["PORTAGE_RESTRICT"])) or \
("userpriv" in string.split(mysettings["PORTAGE_RESTRICT"]))):
mysettings["DISTCC_DIR"]=""
mysettings["WORKDIR"]=mysettings["BUILDDIR"]+"/work"
- mysettings["D"]=os.path.join(mysettings["BUILDDIR"], "image", portage_const.PREFIX.lstrip(os.path.sep))
+ mysettings["DEST"]=os.path.join(mysettings["BUILDDIR"],"image")
+ mysettings["D"]=mysettings["BUILDDIR"]+"/image"+portage_const.PREFIX
if mysettings.has_key("PORT_LOGDIR"):
if os.access(mysettings["PORT_LOGDIR"]+"/",os.W_OK):
try:
os.chmod(mysettings["PORT_LOGDIR"],02770)
if not mysettings.has_key("LOG_PF") or (mysettings["LOG_PF"] != mysettings["PF"]):
mysettings["LOG_PF"]=mysettings["PF"]
- mysettings["LOG_COUNTER"]=str(db[myroot]["vartree"].get_counter_tick_core("/"))
+ mysettings["LOG_COUNTER"]=str(db[myroot]["vartree"].dbapi.get_counter_tick_core("/"))
logfile="%s/%s-%s.log" % (mysettings["PORT_LOGDIR"],mysettings["LOG_COUNTER"],mysettings["LOG_PF"])
except OSError, e:
mysettings["PORT_LOGDIR"]=""
mysettings["PORT_LOGDIR"]=""
if mydo=="unmerge":
- return unmerge(mysettings["CATEGORY"],mysettings["PF"],myroot+portage_const.PREFIX,mysettings)
+ return unmerge(mysettings["CATEGORY"],mysettings["PF"],myroot,mysettings)
# if any of these are being called, handle them -- running them out of the sandbox -- and stop now.
if mydo=="clean":
print "!!! mydo=qmerge, but install phase hasn't been ran"
sys.exit(1)
#qmerge is specifically not supposed to do a runtime dep check
- return merge(mysettings["CATEGORY"],mysettings["PF"],mysettings["D"],mysettings["BUILDDIR"]+"/build-info",myroot,mysettings,myebuild=mysettings["EBUILD"],mytree=tree)
+ return merge(mysettings["CATEGORY"],mysettings["PF"],mysettings["DEST"],mysettings["BUILDDIR"]+"/build-info",myroot,mysettings,myebuild=mysettings["EBUILD"],mytree=tree)
elif mydo=="merge":
retval=spawnebuild("install",actionmap,mysettings,debug,alwaysdep=1,logfile=logfile)
if retval:
return retval
- return merge(mysettings["CATEGORY"],mysettings["PF"],mysettings["D"],mysettings["BUILDDIR"]+"/build-info",myroot,mysettings,myebuild=mysettings["EBUILD"],mytree=tree)
+ return merge(mysettings["CATEGORY"],mysettings["PF"],mysettings["DEST"],mysettings["BUILDDIR"]+"/build-info",myroot,mysettings,myebuild=mysettings["EBUILD"],mytree=tree)
else:
print "!!! Unknown mydo:",mydo
sys.exit(1)
mylink.unmerge(trimworld=mytrimworld,cleanup=1)
mylink.delete()
-def relparse(myver):
- "converts last version part into three components"
- number=0
- suffix=0
- endtype=0
- endnumber=0
-
- mynewver=string.split(myver,"_")
- myver=mynewver[0]
-
- #normal number or number with letter at end
- divider=len(myver)-1
- if myver[divider:] not in "1234567890":
- #letter at end
- suffix=ord(myver[divider:])
- number=string.atof(myver[0:divider])
- else:
- number=string.atof(myver)
-
- if len(mynewver)==2:
- #an endversion
- for x in endversion_keys:
- elen=len(x)
- if mynewver[1][:elen] == x:
- match=1
- endtype=endversion[x]
- try:
- endnumber=string.atof(mynewver[1][elen:])
- except SystemExit, e:
- raise
- except:
- endnumber=0
- break
- return [number,suffix,endtype,endnumber]
-
-#returns 1 if valid version string, else 0
-# valid string in format: <v1>.<v2>...<vx>[a-z,_{endversion}[vy]]
-# ververify doesn't do package rev.
-
-vercache={}
-def ververify(myorigval,silent=1):
- try:
- return vercache[myorigval]
- except KeyError:
- pass
- if len(myorigval)==0:
- if not silent:
- print "!!! Name error: package contains empty \"-\" part."
- return 0
- myval=string.split(myorigval,'.')
- if len(myval)==0:
- if not silent:
- print "!!! Name error: empty version string."
- vercache[myorigval]=0
- return 0
- #all but the last version must be a numeric
- for x in myval[:-1]:
- if not len(x):
- if not silent:
- print "!!! Name error in",myorigval+": two decimal points in a row"
- vercache[myorigval]=0
- return 0
- try:
- foo=int(x)
- except SystemExit, e:
- raise
- except:
- if not silent:
- print "!!! Name error in",myorigval+": \""+x+"\" is not a valid version component."
- vercache[myorigval]=0
- return 0
- if not len(myval[-1]):
- if not silent:
- print "!!! Name error in",myorigval+": two decimal points in a row"
- vercache[myorigval]=0
- return 0
- try:
- foo=int(myval[-1])
- vercache[myorigval]=1
- return 1
- except SystemExit, e:
- raise
- except:
- pass
- #ok, our last component is not a plain number or blank, let's continue
- if myval[-1][-1] in string.lowercase:
- try:
- foo=int(myval[-1][:-1])
- vercache[myorigval]=1
- return 1
- # 1a, 2.0b, etc.
- except SystemExit, e:
- raise
- except:
- pass
- #ok, maybe we have a 1_alpha or 1_beta2; let's see
- #ep="endpart"
- ep=string.split(myval[-1],"_")
- if len(ep)!=2:
- if not silent:
- print "!!! Name error in",myorigval
- vercache[myorigval]=0
- return 0
- try:
- foo=int(ep[0][-1])
- chk=ep[0]
- except SystemExit, e:
- raise
- except:
- # because it's ok last char is not numeric. example: foo-1.0.0a_pre1
- chk=ep[0][:-1]
-
- try:
- foo=int(chk)
- except SystemExit, e:
- raise
- except:
- #this needs to be numeric or numeric+single letter,
- #i.e. the "1" in "1_alpha" or "1a_alpha"
- if not silent:
- print "!!! Name error in",myorigval+": characters before _ must be numeric or numeric+single letter"
- vercache[myorigval]=0
- return 0
- for mye in endversion_keys:
- if ep[1][0:len(mye)]==mye:
- if len(mye)==len(ep[1]):
- #no trailing numeric; ok
- vercache[myorigval]=1
- return 1
- else:
- try:
- foo=int(ep[1][len(mye):])
- vercache[myorigval]=1
- return 1
- except SystemExit, e:
- raise
- except:
- #if no endversions work, *then* we return 0
- pass
- if not silent:
- print "!!! Name error in",myorigval
- vercache[myorigval]=0
- return 0
-
def isvalidatom(atom):
mycpv_cps = catpkgsplit(dep_getcpv(atom))
operator = get_operator(atom)
iscache[mypkg]=0
return 0
-# This function can be used as a package verification function, i.e.
-# "pkgsplit("foo-1.2-1") will return None if foo-1.2-1 isn't a valid
-# package (with version) name. If it is a valid name, pkgsplit will
-# return a list containing: [ pkgname, pkgversion(norev), pkgrev ].
-# For foo-1.2-1, this list would be [ "foo", "1.2", "1" ]. For
-# Mesa-3.0, this list would be [ "Mesa", "3.0", "0" ].
-pkgcache={}
-
-def pkgsplit(mypkg,silent=1):
- try:
- if not pkgcache[mypkg]:
- return None
- return pkgcache[mypkg][:]
- except KeyError:
- pass
- myparts=string.split(mypkg,'-')
- if len(myparts)<2:
- if not silent:
- print "!!! Name error in",mypkg+": missing a version or name part."
- pkgcache[mypkg]=None
- return None
- for x in myparts:
- if len(x)==0:
- if not silent:
- print "!!! Name error in",mypkg+": empty \"-\" part."
- pkgcache[mypkg]=None
- return None
- #verify rev
- revok=0
- myrev=myparts[-1]
- if len(myrev) and myrev[0]=="r":
- try:
- int(myrev[1:])
- revok=1
- except SystemExit, e:
- raise
- except:
- pass
- if revok:
- if ververify(myparts[-2]):
- if len(myparts)==2:
- pkgcache[mypkg]=None
- return None
- else:
- for x in myparts[:-2]:
- if ververify(x):
- pkgcache[mypkg]=None
- return None
- #names can't have versiony looking parts
- myval=[string.join(myparts[:-2],"-"),myparts[-2],myparts[-1]]
- pkgcache[mypkg]=myval
- return myval
- else:
- pkgcache[mypkg]=None
- return None
-
- elif ververify(myparts[-1],silent=silent):
- if len(myparts)==1:
- if not silent:
- print "!!! Name error in",mypkg+": missing name part."
- pkgcache[mypkg]=None
- return None
- else:
- for x in myparts[:-1]:
- if ververify(x):
- if not silent:
- print "!!! Name error in",mypkg+": multiple version parts."
- pkgcache[mypkg]=None
- return None
- myval=[string.join(myparts[:-1],"-"),myparts[-1],"r0"]
- pkgcache[mypkg]=myval[:]
- return myval
- else:
- pkgcache[mypkg]=None
- return None
-
def getCPFromCPV(mycpv):
"""Calls pkgsplit on a cpv and returns only the cp."""
return pkgsplit(mycpv)[0]
-catcache={}
-def catpkgsplit(mydata,silent=1):
- "returns [cat, pkgname, version, rev ]"
- try:
- if not catcache[mydata]:
- return None
- return catcache[mydata][:]
- except KeyError:
- pass
- mysplit=mydata.split("/")
- p_split=None
- if len(mysplit)==1:
- retval=["null"]
- p_split=pkgsplit(mydata,silent=silent)
- elif len(mysplit)==2:
- retval=[mysplit[0]]
- p_split=pkgsplit(mysplit[1],silent=silent)
- if not p_split:
- catcache[mydata]=None
- return None
- retval.extend(p_split)
- catcache[mydata]=retval
- return retval
-
-# vercmp:
-# This takes two version strings and returns an integer to tell you whether
-# the versions are the same, val1>val2 or val2>val1.
-vcmpcache={}
-def vercmp(val1,val2):
- if val1==val2:
- #quick short-circuit
- return 0
- valkey=val1+" "+val2
- try:
- return vcmpcache[valkey]
- try:
- return -vcmpcache[val2+" "+val1]
- except KeyError:
- pass
- except KeyError:
- pass
-
- # consider 1_p2 vc 1.1
- # after expansion will become (1_p2,0) vc (1,1)
- # then 1_p2 is compared with 1 before 0 is compared with 1
- # to solve the bug we need to convert it to (1,0_p2)
- # by splitting _prepart part and adding it back _after_expansion
- val1_prepart = val2_prepart = ''
- if val1.count('_'):
- val1, val1_prepart = val1.split('_', 1)
- if val2.count('_'):
- val2, val2_prepart = val2.split('_', 1)
-
- # replace '-' by '.'
- # FIXME: Is it needed? can val1/2 contain '-'?
- val1=string.split(val1,'-')
- if len(val1)==2:
- val1[0]=val1[0]+"."+val1[1]
- val2=string.split(val2,'-')
- if len(val2)==2:
- val2[0]=val2[0]+"."+val2[1]
-
- val1=string.split(val1[0],'.')
- val2=string.split(val2[0],'.')
-
- #add back decimal point so that .03 does not become "3" !
- for x in range(1,len(val1)):
- if val1[x][0] == '0' :
- val1[x]='.' + val1[x]
- for x in range(1,len(val2)):
- if val2[x][0] == '0' :
- val2[x]='.' + val2[x]
-
- # extend version numbers
- if len(val2)<len(val1):
- val2.extend(["0"]*(len(val1)-len(val2)))
- elif len(val1)<len(val2):
- val1.extend(["0"]*(len(val2)-len(val1)))
-
- # add back _prepart tails
- if val1_prepart:
- val1[-1] += '_' + val1_prepart
- if val2_prepart:
- val2[-1] += '_' + val2_prepart
- #The above code will extend version numbers out so they
- #have the same number of digits.
- for x in range(0,len(val1)):
- cmp1=relparse(val1[x])
- cmp2=relparse(val2[x])
- for y in range(0,4):
- myret=cmp1[y]-cmp2[y]
- if myret != 0:
- vcmpcache[valkey]=myret
- return myret
- vcmpcache[valkey]=0
- return 0
-
-
-def pkgcmp(pkg1,pkg2):
- """if returnval is less than zero, then pkg2 is newer than pkg1, zero if equal and positive if older."""
- if pkg1[0] != pkg2[0]:
- return None
- mycmp=vercmp(pkg1[1],pkg2[1])
- if mycmp>0:
- return 1
- if mycmp<0:
- return -1
- r1=int(pkg1[2][1:])
- r2=int(pkg2[2][1:])
- if r1>r2:
- return 1
- if r2>r1:
- return -1
- return 0
-
def dep_parenreduce(mysplit,mypos=0):
"Accepts a list of strings, and converts '(' and ')' surrounded items to sub-lists"
while (mypos<len(mysplit)):
return deplist
def getmaskingreason(mycpv):
+ from portage_util import grablines
global portdb
mysplit = catpkgsplit(mycpv)
if not mysplit:
raise KeyError("CPV %s does not exist" % mycpv)
mycp=mysplit[0]+"/"+mysplit[1]
+ pmasklines = grablines(settings["PORTDIR"]+"/profiles/package.mask", recursive=1)
if settings.pmaskdict.has_key(mycp):
for x in settings.pmaskdict[mycp]:
if mycpv in portdb.xmatch("match-all", x):
- pmaskfile = open(settings["PORTDIR"]+"/profiles/package.mask")
comment = ""
l = "\n"
- while len(l) > 0:
- l = pmaskfile.readline()
- if len(l) == 0:
- pmaskfile.close()
- return None
- if l[0] == "#":
- comment += l
- elif l == "\n":
+ i = 0
+ while i < len(pmasklines):
+ l = pmasklines[i].strip()
+ if l == "":
comment = ""
- elif l.strip() == x:
- pmaskfile.close()
+ elif l[0] == "#":
+ comment += (l+"\n")
+ elif l == x:
return comment
- pmaskfile.close()
+ i = i + 1
return None
def getmaskingstatus(mycpv):
if gp=="*":
kmask=None
break
- elif gp=="-*":
- fallback="-*"
elif gp=="-"+myarch:
kmask="-"+myarch
break
elif gp=="~"+myarch:
kmask="~"+myarch
break
- if kmask == "missing" and fallback:
- kmask = fallback
if kmask:
rValue.append(kmask+" keyword")
self.settings = mysettings
if self.settings==1:
raise ValueError
-
+
self.myroot=myroot
- self.mergedir = myroot + "/" + portage_const.PREFIX
+ self.mergedir = os.path.normpath(myroot+os.path.sep+portage_const.PREFIX)
self.updateprotect()
self.contentscache=[]
#do prerm script
if myebuildpath and os.path.exists(myebuildpath):
- a=doebuild(myebuildpath,"prerm",self.myroot+portage_const.PREFIX,self.settings,cleanup=cleanup,use_cache=0,tree=self.treetype)
+ a=doebuild(myebuildpath,"prerm",self.myroot,self.settings,cleanup=cleanup,use_cache=0,tree=self.treetype)
# XXX: Decide how to handle failures here.
if a != 0:
writemsg("!!! FAILED prerm: "+str(a)+"\n")
if dircache.has_key(self.dbcatdir):
del dircache[self.dbcatdir]
print ">>>",self.mycpv,"merged."
+
+ # Process ebuild logfiles
+ elog_process(self.mycpv, self.settings)
+
return 0
def mergeme(self,srcroot,destroot,outfile,secondhand,stufftomerge,cfgfiledict,thismtime):
+ prefix=os.path.normpath(portage_const.PREFIX)
+ os.path.normpath(os.path.sep+srcroot)
+ if srcroot.endswith(prefix):
+ # Trim prefix from srcroot
+ srcroot=srcroot[:-len(prefix)+1]
srcroot=os.path.normpath("///"+srcroot)+"/"
destroot=os.path.normpath("///"+destroot)+"/"
# this is supposed to merge a list of files. There will be 2 forms of argument passing.
mysrc=os.path.normpath("///"+srcroot+offset+x)
mydest=os.path.normpath("///"+destroot+offset+x)
# myrealdest is mydest without the $ROOT prefix (makes a difference if ROOT!="/")
- myrealdest=portage_const.PREFIX+offset+x
+ myrealdest=os.path.normpath(os.path.sep+offset+x)
# stat file once, test using S_* macros many times (faster that way)
try:
mystat=os.lstat(mysrc)
print zing+" "+mydest
def merge(self,mergeroot,inforoot,myroot,myebuild=None,cleanup=0):
- #return self.treewalk(mergeroot,myroot,inforoot,myebuild,cleanup=cleanup)
- return self.treewalk(mergeroot,myroot+"/"+portage_const.PREFIX,inforoot,myebuild,cleanup=cleanup)
+ return self.treewalk(mergeroot,myroot,inforoot,myebuild,cleanup=cleanup)
+
def getstring(self,name):
"returns contents of a file with whitespace converted to spaces"
if not os.path.exists(self.dbdir+"/"+name):
os.chdir(pkgloc)
mysettings.configdict["pkg"]["CATEGORY"] = mycat;
- a=doebuild(myebuild,"setup",myroot+portage_const.PREFIX,mysettings,tree="bintree")
+ a=doebuild(myebuild,"setup",myroot,mysettings,tree="bintree")
print ">>> extracting",mypkg
notok=spawn("bzip2 -dqc -- '"+mytbz2+"' | tar xpf -",mysettings,free=1)
if notok:
# the merge takes care of pre/postinst and old instance
# auto-unmerge, virtual/provides updates, etc.
mysettings.load_infodir(infloc)
- mylink=dblink(mycat,mypkg,myroot+portage_const.PREFIX,mysettings,treetype="bintree")
- mylink.merge(pkgloc,infloc,myroot+portage_const.PREFIX,myebuild,cleanup=1)
+ mylink=dblink(mycat,mypkg,myroot,mysettings,treetype="bintree")
+ mylink.merge(pkgloc,infloc,myroot,myebuild,cleanup=1)
if not os.path.exists(infloc+"/RDEPEND"):
returnme=""
writemsg("portage: couldn't create "+root+portage_const.PREFIX+"/var/tmp; exiting.\n")
sys.exit(1)
-if not os.path.exists(root+portage_const.PREFIX+"var/lib"):
+if not os.path.exists(root+portage_const.PREFIX+"var/lib/portage"):
writemsg(">>> "+root+portage_const.PREFIX+"var/lib doesn't exist, creating it...\n")
try:
os.mkdir(root+portage_const.PREFIX+"var",0755)
"version", "starttime",
"resume", "ldpath"
]
-mtimedbfile=root+"var/cache/edb/mtimedb"
+mtimedbfile=root+portage_const.PREFIX+"var/cache/edb/mtimedb"
try:
mypickle=cPickle.Unpickler(open(mtimedbfile))
mypickle.find_global=None
update_files={}
file_contents={}
myxfiles = ["package.mask","package.unmask","package.keywords","package.use"]
- myxfiles = myxfiles + prefix_array(myxfiles, "profile/")
+ myxfiles.extend(prefix_array(myxfiles, "profile/"))
+ recursivefiles = []
+ for x in myxfiles:
+ if os.path.isdir(USER_CONFIG_PATH+os.path.sep+x):
+ recursivefiles.extend([x+os.path.sep+y for y in listdir(USER_CONFIG_PATH+os.path.sep+x, filesonly=1, recursive=1)])
+ else:
+ recursivefiles.append(x)
+ myxfiles = recursivefiles
for x in myxfiles:
try:
- myfile = open("/etc/portage/"+x,"r")
+ myfile = open(USER_CONFIG_PATH+os.path.sep+x,"r")
file_contents[x] = myfile.readlines()
myfile.close()
except IOError:
for x in update_files:
mydblink = dblink('','','/',settings)
- if mydblink.isprotected(portage_const.PREFIX+"etc/portage/"+x):
- updating_file=new_protect_filename(portage_const.PREFIX+"etc/portage/"+x)[0]
+ if mydblink.isprotected(USER_CONFIG_PATH+os.path.sep+x):
+ updating_file=new_protect_filename(USER_CONFIG_PATH+os.path.sep+x)[0]
else:
- updating_file=portage_const.PREFIX+"etc/portage/"+x
+ updating_file=USER_CONFIG_PATH+os.path.sep+x
try:
myfile=open(updating_file,"w")
myfile.writelines(file_contents[x])