Thanks again to Chris White for these additional portage_dep docstrings.
Make digestcheck() fail if an ebuild isn't listed in the Manifest.
Thanks to pva for reporting.
Fix emerge --sync with a cvs:// uri so that it runs
/etc/portage/bin/post_sync like it would with a normal rsync:// uri.
Thanks to drizzt for reporting.
Fix initial cvs checkout logic for bug #100478.
For initial gentoo-x86 checkout, if $PORTDIR exists and is empty then
remove it so that the gentoo-x86 checkout can replace it.
For bug #154554, validate all profile virtuals atoms.
Fix depgraph.pkg_node_map so that it properly supports $ROOT.
svn path=/main/branches/prefix/; revision=5014
self.edebug = 1
self.spinner = spinner
self.pkgsettings = {}
+ self.pkg_node_map = {}
for myroot in self.trees:
self.pkgsettings[myroot] = portage.config(
clone=trees[myroot]["vartree"].settings)
+ self.pkg_node_map[myroot] = {}
self.useFlags = {}
self.useFlags[self.target_root] = {}
if self.target_root != "/":
"--getbinpkgonly" in self.myopts)
self.args_keys = []
self.global_updates = {}
- self.pkg_node_map = {}
self.blocker_digraph = digraph()
self.blocker_parents = {}
#"no downgrade" emerge
"""
jbigkey = " ".join(mybigkey) + " merge"
+ mytype, myroot, mykey = mybigkey
if self.digraph.hasnode(jbigkey):
if addme and jbigkey != myparent:
# Refuse to make a node depend on itself so that the we don't
# don't create a bogus circular dependency in self.altlist().
+ self.pkg_node_map[myroot][mykey] = jbigkey
if rev_dep and myparent:
- self.pkg_node_map[myparent.split()[2]] = myparent
+ ptype, proot, pkey, pstatus = myparent.split()
+ self.pkg_node_map[proot][pkey] = myparent
self.digraph.addnode(myparent, jbigkey, priority=priority)
else:
- self.pkg_node_map[mybigkey[2]] = jbigkey
self.digraph.addnode(jbigkey, myparent, priority=priority)
return 1
jbigkey = " ".join(mybigkey) + " nomerge"
if self.digraph.hasnode(jbigkey):
- """XXX: It's possible that this package has been explicitly
- requested as a command line argument. This can be solved by
- checking all args prior to marking packages as nomerge"""
+ self.pkg_node_map[myroot][mykey] = jbigkey
if rev_dep and myparent:
- self.pkg_node_map[myparent.split()[2]] = myparent
+ ptype, proot, pkey, pstatus = myparent.split()
+ self.pkg_node_map[proot][pkey] = myparent
self.digraph.addnode(myparent, jbigkey, priority=priority)
else:
- self.pkg_node_map[mybigkey[2]] = jbigkey
self.digraph.addnode(jbigkey, myparent, priority=priority)
return 1
self.spinner.update()
- mytype,myroot,mykey=mybigkey
if mytype == "blocks":
if addme and "--buildpkgonly" not in self.myopts and myparent:
mybigkey[1] = myparent.split()[1]
depgraph already and returned, or we are here. Whether we are merging or not; we must
add the package to the depgraph; so we do that here. """
jbigkey = " ".join(mybigkey)
+ self.pkg_node_map[myroot][mykey] = jbigkey
if rev_dep and myparent:
- self.pkg_node_map[myparent.split()[2]] = myparent
+ ptype, proot, pkey, pstatus = myparent.split()
+ self.pkg_node_map[proot][pkey] = myparent
self.digraph.addnode(myparent, jbigkey,
priority=priority)
else:
- self.pkg_node_map[mybigkey[2]] = jbigkey
self.digraph.addnode(jbigkey, myparent,
priority=priority)
unresolvable = True
break
# Enforce correct merge order with a hard dep.
- node = self.pkg_node_map[pkg]
+ node = self.pkg_node_map[proot][pkg]
self.digraph.addnode(node, parent,
priority=DepPriority(buildtime=True))
"""Count references to this blocker so that it can be
get_nodes = mygraph.root_nodes
else:
get_nodes = mygraph.leaf_nodes
- for cpv, node in self.pkg_node_map.iteritems():
+ for cpv, node in self.pkg_node_map["/"].iteritems():
if "portage" == portage.catsplit(portage.dep_getkey(cpv))[-1]:
asap_nodes.append(node)
break
os.makedirs(myportdir,0755)
syncuri=string.rstrip(settings["SYNC"])
os.umask(0022)
+ updatecache_flg = False
if myaction == "metadata":
print "skipping sync"
updatecache_flg = True
if os.path.exists(cvsdir+"/gentoo-x86"):
print "!!! existing",cvsdir+"/gentoo-x86 directory; exiting."
sys.exit(1)
+ try:
+ os.rmdir(myportdir)
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ sys.stderr.write(
+ "!!! existing '%s' directory; exiting.\n" % myportdir)
+ sys.exit(1)
+ del e
if portage.spawn("cd "+cvsdir+"; cvs -z0 -d "+cvsroot+" co -P gentoo-x86",settings,free=1):
print "!!! cvs checkout error; exiting."
sys.exit(1)
- if cvsdir!=myportdir:
- portage.movefile(cvsdir,settings["PORTDIR"])
- sys.exit(0)
+ os.rename(os.path.join(cvsdir, "gentoo-x86"), myportdir)
else:
#cvs update
print ">>> Starting cvs update with "+syncuri+"..."
- sys.exit(portage.spawn("cd "+myportdir+"; cvs -z0 -q update -dP",settings,free=1))
+ retval = portage.spawn("cd '%s'; cvs -z0 -q update -dP" % \
+ myportdir, settings, free=1)
+ if retval != os.EX_OK:
+ sys.exit(retval)
+ dosyncuri = syncuri
else:
print "!!! rsync setting: ",syncuri,"not recognized; exiting."
sys.exit(1)
if myaction != "metadata":
if os.access(portage.USER_CONFIG_PATH + "/bin/post_sync", os.X_OK):
- try:
- portage.spawn(portage.USER_CONFIG_PATH + "/bin/post_sync " + dosyncuri, settings, free=1)
- except:
+ retval = portage.portage_exec.spawn(
+ [os.path.join(portage.USER_CONFIG_PATH, "bin", "post_sync"),
+ dosyncuri], env=settings.environ())
+ if retval != os.EX_OK:
print red(" * ")+bold("spawn failed of "+ portage.USER_CONFIG_PATH + "/bin/post_sync")
if(mybestpv != mypvs) and not "--quiet" in myopts:
if self.virtuals:
return self.virtuals
- self.dirVirtuals = stack_dictlist(
- [grabdict_package(os.path.join(x, "virtuals")) \
- for x in self.profiles], incremental=True)
+ virtuals_list = []
+ for x in self.profiles:
+ virtuals_file = os.path.join(x, "virtuals")
+ virtuals_dict = grabdict(virtuals_file)
+ for k in virtuals_dict.keys():
+ if not isvalidatom(k) or dep_getkey(k) != k:
+ writemsg("--- Invalid virtuals atom in %s: %s\n" % \
+ (virtuals_file, k), noiselevel=-1)
+ del virtuals_dict[k]
+ continue
+ myvalues = virtuals_dict[k]
+ for x in myvalues:
+ if not isvalidatom(x):
+ writemsg("--- Invalid atom in %s: %s\n" % \
+ (virtuals_file, x), noiselevel=-1)
+ myvalues.remove(x)
+ if not myvalues:
+ del virtuals_dict[k]
+ if virtuals_dict:
+ virtuals_list.append(virtuals_dict)
+
+ self.dirVirtuals = stack_dictlist(virtuals_list, incremental=True)
+ del virtuals_list
for virt in self.dirVirtuals:
# Preference for virtuals decreases from left to right.
writemsg("!!! Got: %s\n" % e.value[2], noiselevel=-1)
writemsg("!!! Expected: %s\n" % e.value[3], noiselevel=-1)
return 0
+ # Make sure that all of the ebuilds are actually listed in the Manifest.
+ for f in os.listdir(pkgdir):
+ if f.endswith(".ebuild") and not mf.hasFile("EBUILD", f):
+ writemsg("!!! A file is not listed in the Manifest: '%s'\n" % \
+ os.path.join(pkgdir, f), noiselevel=-1)
+ return 0
""" epatch will just grab all the patches out of a directory, so we have to
make sure there aren't any foreign files that it might grab."""
filesdir = os.path.join(pkgdir, "files")
from portage_versions import catpkgsplit, catsplit, pkgcmp, pkgsplit, ververify
def strip_empty(myarr):
+ """
+ Strip all empty elements from an array
+
+ @param myarr: The list of elements
+ @type myarr: List
+ @rtype: Array
+ @return: The array with empty elements removed
+ """
for x in range(len(myarr)-1, -1, -1):
if not myarr[x]:
del myarr[x]
return myarr
def paren_reduce(mystr,tokenize=1):
- "Accepts a list of strings, and converts '(' and ')' surrounded items to sub-lists"
+ """
+ Take a string and convert all paren enclosed entities into sublists, optionally
+ futher splitting the list elements by spaces.
+
+ Example usage:
+ >>> paren_reduce('foobar foo ( bar baz )',1)
+ ['foobar', 'foo', ['bar', 'baz']]
+ >>> paren_reduce('foobar foo ( bar baz )',0)
+ ['foobar foo ', [' bar baz ']]
+
+ @param mystr: The string to reduce
+ @type mystr: String
+ @param tokenize: Split on spaces to produces further list breakdown
+ @type tokenize: Integer
+ @rtype: Array
+ @return: The reduced string in an array
+ """
mylist = []
while mystr:
if ("(" not in mystr) and (")" not in mystr):
"""
Convert a list to a string with sublists enclosed with parens.
+ Example usage:
+ >>> test = ['foobar','foo',['bar','baz']]
+ >>> paren_enclose(test)
+ 'foobar foo ( bar baz )'
+
@param mylist: The list
@type mylist: List
@rtype: String
raise portage_exception.InvalidDependString(deparray[x]+" missing atom list in \""+paren_enclose(deparray)+"\"")
if deparray and deparray[-1] and deparray[-1][-1] == "?":
raise portage_exception.InvalidDependString("Conditional without target in \""+paren_enclose(deparray)+"\"")
-
+
mydeparray = deparray[:]
rlist = []
while mydeparray:
list of deps that follows..
Example usage:
- >>> test = ["blah", "||", ["foo", "bar", "baz"]]
- >>> dep_opconvert(test)
- ['blah', ['||', 'foo', 'bar', 'baz']]
+ >>> test = ["blah", "||", ["foo", "bar", "baz"]]
+ >>> dep_opconvert(test)
+ ['blah', ['||', 'foo', 'bar', 'baz']]
@param deplist: A list of deps to format
@type mydep: List
Return the operator used in a depstring.
Example usage:
- >>> from portage_dep import *
- >>> get_operator(">=test-1.0")
- '>='
+ >>> from portage_dep import *
+ >>> get_operator(">=test-1.0")
+ '>='
@param mydep: The dep string to check
@type mydep: String
@rtype: String
- @return:
- The operator. One of: '~', '=', '>', '<', '=*', '>=', or '<='
+ @return: The operator. One of:
+ '~', '=', '>', '<', '=*', '>=', or '<='
"""
if mydep[0] == "~":
operator = "~"
return operator
def dep_getcpv(mydep):
+ """
+ Return the category-package-version with any operators/slot specifications stripped off
+
+ Example usage:
+ >>> dep_getcpv('>=media-libs/test-3.0')
+ 'media-libs/test-3.0'
+
+ @param mydep: The depstring
+ @type mydep: String
+ @rtype: String
+ @return: The depstring with the operator removed
+ """
if mydep and mydep[0] == "*":
mydep = mydep[1:]
if mydep and mydep[-1] == "*":
return mydep
def dep_getslot(mydep):
+ """
+ Retrieve the slot on a depend.
+
+ Example usage:
+ >>> dep_getslot('app-misc/test:3')
+ '3'
+
+ @param mydep: The depstring to retrieve the slot of
+ @type mydep: String
+ @rtype: String
+ @return: The slot
+ """
colon = mydep.rfind(":")
if colon != -1:
return mydep[colon+1:]
return None
def isvalidatom(atom):
+ """
+ Check to see if a depend atom is valid
+
+ Example usage:
+ >>> isvalidatom('media-libs/test-3.0')
+ 0
+ >>> isvalidatom('>=media-libs/test-3.0')
+ 1
+
+ @param atom: The depend atom to check against
+ @type atom: String
+ @rtype: Integer
+ @return: One of the following:
+ 1) 0 if the atom is invalid
+ 2) 1 if the atom is valid
+ """
mycpv_cps = catpkgsplit(dep_getcpv(atom))
operator = get_operator(atom)
if operator:
return 0
def isjustname(mypkg):
+ """
+ Checks to see if the depstring is only the package name
+
+ Example usage:
+ >>> isjustname('media-libs/test-3.0')
+ 0
+ >>> isjustname('test')
+ 1
+ >>> isjustname('media-libs/test')
+ 1
+
+ @param mypkg: The package atom to check
+ @param mypkg: String
+ @rtype: Integer
+ @return: One of the following:
+ 1) 0 if the package string is not just the package name
+ 2) 1 if it is
+ """
myparts = mypkg.split('-')
for x in myparts:
if ververify(x):
iscache = {}
def isspecific(mypkg):
- "now supports packages with no category"
+ """
+ Checks to see if a package is in category/package-version or package-version format,
+ possibly returning a cached result.
+
+ Example usage:
+ >>> isspecific('media-libs/test')
+ 0
+ >>> isspecific('media-libs/test-3.0')
+ 1
+
+ @param mypkg: The package depstring to check against
+ @type mypkg: String
+ @rtype: Integer
+ @return: One of the following:
+ 1) 0 if the package string is not specific
+ 2) 1 if it is
+ """
try:
return iscache[mypkg]
except KeyError:
return 0
def dep_getkey(mydep):
+ """
+ Return the category/package-name of a depstring.
+
+ Example usage:
+ >>> dep_getkey('media-libs/test-3.0')
+ 'media-libs/test'
+
+ @param mydep: The depstring to retrieve the category/package-name of
+ @type mydep: String
+ @rtype: String
+ @return: The package category/package-version
+ """
mydep = dep_getcpv(mydep)
if mydep and isspecific(mydep):
mysplit = catpkgsplit(mydep)
return mydep
def match_to_list(mypkg, mylist):
- """(pkgname, list)
+ """
Searches list for entries that matches the package.
+
+ @param mypkg: The package atom to match
+ @type mypkg: String
+ @param mylist: The list of package atoms to compare against
+ @param mylist: List
+ @rtype: List
+ @return: A unique list of package atoms that match the given package atom
"""
matches = []
for x in mylist:
return matches
def best_match_to_list(mypkg, mylist):
- """(pkgname, list)
+ """
Returns the most specific entry that matches the package given.
- Type Value
- =cpv 6
- ~cpv 5
- =cpv* 4
- cp:slot 3
- >cpv 2
- <cpv 2
- >=cpv 2
- <=cpv 2
- cp 1
+
+ @param mypkg: The package atom to check
+ @type mypkg: String
+ @param mylist: The list of package atoms to check against
+ @type mylist: List
+ @rtype: String
+ @return: The package atom which best matches given the following ordering:
+ - =cpv 6
+ - ~cpv 5
+ - =cpv* 4
+ - cp:slot 3
+ - >cpv 2
+ - <cpv 2
+ - >=cpv 2
+ - <=cpv 2
+ - cp 1
"""
operator_values = {'=':6, '~':5, '=*':4,
'>':2, '<':2, '>=':2, '<=':2, None:1}
return bestm
def match_from_list(mydep, candidate_list):
+ """
+ Searches list for entries that matches the package.
+
+ @param mydep: The package atom to match
+ @type mydep: String
+ @param candidate_list: The list of package atoms to compare against
+ @param candidate_list: List
+ @rtype: List
+ @return: A list of package atoms that match the given package atom
+ """
+
from portage_util import writemsg
if mydep[0] == "!":
mydep = mydep[1:]
-#!/bin/bash
+#!/usr/bin/env bash
# $Id: $
if [ -z "$1" ]; then