From 35c1c1cce7ab647849fea452774255e549e9e048 Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Sun, 13 Sep 2009 19:03:52 +0000 Subject: [PATCH] Merged from trunk -r14229:14239 | 14230 | Make parse_updates() and update_dbentry() use Atom | | zmedico | instances. | | 14231 | Add missing InvalidAtom import. | | zmedico | | | 14232 | Make dbapi.move_ent() take advantage of Atom instances when | | zmedico | validating arguments. | | 14233 | In config.getvirtuals(), save Atom instances in order to | | zmedico | avoid revalidation. Also, fix cpv_expand() to handle Atom | | | instances from config.getvirtuals(). | | 14234 | Reimplement isjustname() using the Atom class. Thanks to | | zmedico | Marat Radchenko for the suggestion. | | 14235 | Fix isjustname docstring to have a valid atom in the | | zmedico | example. | | 14236 | Use isjustname() where appropriate. | | zmedico | | | 14237 | Fix bug in _expand_new_virtuals() reported by Arfrever: | | zmedico | TypeError: coercing to Unicode: need string or buffer, Atom | | | found | | 14238 | Add tests for the Atom class. | | zmedico | | | 14239 | Add backward compatibility to isjustname(), so the tests | | zmedico | don't fail. | svn path=/main/branches/prefix/; revision=14246 --- bin/egencache | 3 +- pym/portage/__init__.py | 57 +++++++++++++++++++++---------- pym/portage/dbapi/bintree.py | 8 ++--- pym/portage/dbapi/vartree.py | 9 +++-- pym/portage/dep.py | 26 ++++++++------ pym/portage/tests/dep/testAtom.py | 42 +++++++++++++++++++++++ pym/portage/update.py | 39 +++++++++++++++------ 7 files changed, 135 insertions(+), 49 deletions(-) create mode 100644 pym/portage/tests/dep/testAtom.py diff --git a/bin/egencache b/bin/egencache index 223428e07..566e09efa 100755 --- a/bin/egencache +++ b/bin/egencache @@ -34,6 +34,7 @@ from _emerge.MetadataRegen import MetadataRegen from portage.cache.cache_errors import CacheError, StatCollision from portage.util import writemsg_level from portage import cpv_getkey +from portage.dep import isjustname def parse_args(args): usage = "egencache [options] --update [atom] ..." @@ -112,7 +113,7 @@ def parse_args(args): except portage.exception.InvalidAtom: parser.error('Invalid atom: %s' % (atom,)) - if str(atom) != atom.cp: + if not isjustname(atom): parser.error('Atom is too specific: %s' % (atom,)) return parser, options, args diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index fb16e5dc7..3d7b2dd38 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -3459,26 +3459,47 @@ class config(object): 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: + atoms_dict = {} + for k, v in virtuals_dict.iteritems(): + try: + virt_atom = portage.dep.Atom(k) + except portage.exception.InvalidAtom: + virt_atom = None + else: + if virt_atom.blocker or \ + str(virt_atom) != str(virt_atom.cp): + virt_atom = None + if virt_atom is None: 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: - myatom = x - if x.startswith("-"): + providers = [] + for atom in v: + atom_orig = atom + if atom[:1] == '-': # allow incrementals - myatom = x[1:] - if not isvalidatom(myatom): + atom = atom[1:] + try: + atom = portage.dep.Atom(atom) + except portage.exception.InvalidAtom: + atom = None + else: + if atom.blocker: + atom = None + if atom is None: 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) + (virtuals_file, myatom), noiselevel=-1) + else: + if atom_orig == str(atom): + # normal atom, so return as Atom instance + providers.append(atom) + else: + # atom has special prefix, so return as string + providers.append(atom_orig) + if providers: + atoms_dict[virt_atom] = providers + if atoms_dict: + virtuals_list.append(atoms_dict) self.dirVirtuals = stack_dictlist(virtuals_list, incremental=True) del virtuals_list @@ -7565,7 +7586,7 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/", if repoman: # TODO: Add PROVIDE check for repoman. for y in mychoices: - a.append(portage.dep.Atom(x.replace(mykey, y, 1))) + a.append(portage.dep.Atom(x.replace(mykey, str(y.cp), 1))) else: for y in mychoices: new_atom = portage.dep.Atom( @@ -8063,11 +8084,11 @@ def cpv_expand(mycpv, mydb=None, use_cache=1, settings=None): # version from the atom before it is passed into # dbapi.cp_list(). if mydb.cp_list(dep_getkey(vkey), use_cache=use_cache): - mykey = vkey + mykey = str(vkey) writemsg(_("virts chosen: %s\n") % (mykey), 1) break if mykey == mykey_orig: - mykey=virts[mykey][0] + mykey = str(virts[mykey][0]) writemsg(_("virts defaulted: %s\n") % (mykey), 1) #we only perform virtual expansion if we are passed a dbapi else: diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py index 57fc62794..f291e0425 100644 --- a/pym/portage/dbapi/bintree.py +++ b/pym/portage/dbapi/bintree.py @@ -6,7 +6,7 @@ __all__ = ["bindbapi", "binarytree"] import portage portage.proxy.lazyimport.lazyimport(globals(), - 'portage.dep:dep_getkey,isjustname,isvalidatom,match_from_list', + 'portage.dep:dep_getkey,isjustname,match_from_list', 'portage.output:EOutput,colorize', 'portage.update:update_dbentries', 'portage.util:ensure_dirs,normalize_path,writemsg,writemsg_stdout', @@ -233,9 +233,9 @@ class binarytree(object): origcp = mylist[1] newcp = mylist[2] # sanity check - for cp in [origcp, newcp]: - if not (isvalidatom(cp) and isjustname(cp)): - raise InvalidPackageName(cp) + for atom in (origcp, newcp): + if not isjustname(atom): + raise InvalidPackageName(str(atom)) origcat = origcp.split("/")[0] mynewcat = newcp.split("/")[0] origmatches=self.dbapi.cp_list(origcp) diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index 42b51e337..2d30b16d6 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -10,7 +10,7 @@ __all__ = ["PreservedLibsRegistry", "LinkageMap", import portage portage.proxy.lazyimport.lazyimport(globals(), 'portage.checksum:_perform_md5_merge@perform_md5', - 'portage.dep:dep_getkey,isjustname,isvalidatom,match_from_list,' + \ + 'portage.dep:dep_getkey,isjustname,match_from_list,' + \ 'use_reduce,paren_reduce', 'portage.elog:elog_process', 'portage.elog.filtering:filter_mergephases,filter_unmergephases', @@ -1589,9 +1589,9 @@ class vardbapi(dbapi): newcp = mylist[2] # sanity check - for cp in [origcp, newcp]: - if not (isvalidatom(cp) and isjustname(cp)): - raise InvalidPackageName(cp) + for atom in (origcp, newcp): + if not isjustname(atom): + raise InvalidPackageName(str(atom)) origmatches = self.match(origcp, use_cache=0) moves = 0 if not origmatches: @@ -2483,7 +2483,6 @@ class vartree(object): returnme.append(appendme) return returnme - def getslot(self, mycatpkg): "Get a slot for a catpkg; assume it exists." try: diff --git a/pym/portage/dep.py b/pym/portage/dep.py index cf06eca7f..f2c11b239 100644 --- a/pym/portage/dep.py +++ b/pym/portage/dep.py @@ -918,28 +918,32 @@ def isvalidatom(atom, allow_blockers=False): def isjustname(mypkg): """ - Checks to see if the depstring is only the package name (no version parts) + Checks to see if the atom is only the package name (no version parts). + Raises InvalidAtom if the input is invalid. Example usage: - >>> isjustname('media-libs/test-3.0') - 0 - >>> isjustname('test') - 1 + >>> isjustname('=media-libs/test-3.0') + False >>> isjustname('media-libs/test') - 1 + True @param mypkg: The package atom to check - @param mypkg: String + @param mypkg: String or Atom @rtype: Integer @return: One of the following: - 1) 0 if the package string is not just the package name - 2) 1 if it is + 1) False if the package string is not just the package name + 2) True if it is """ + try: + return mypkg == Atom(mypkg).cp + except InvalidAtom: + pass + myparts = mypkg.split('-') for x in myparts: if ververify(x): - return 0 - return 1 + return False + return True iscache = {} diff --git a/pym/portage/tests/dep/testAtom.py b/pym/portage/tests/dep/testAtom.py new file mode 100644 index 000000000..c527bb7d2 --- /dev/null +++ b/pym/portage/tests/dep/testAtom.py @@ -0,0 +1,42 @@ +# test_isvalidatom.py -- Portage Unit Testing Functionality +# Copyright 2006 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +from portage.tests import TestCase +from portage.dep import Atom +import portage.dep +portage.dep._dep_check_strict = True + +class TestAtom(TestCase): + """ A simple testcase for isvalidatom + """ + + def testAtom(self): + + tests = [ + ( "=sys-apps/portage-2.1-r1:0[doc]", + ('=', 'sys-apps/portage', '2.1-r1', '0', '[doc]') ), + ( "=sys-apps/portage-2.1-r1*:0[doc]", + ('=*', 'sys-apps/portage', '2.1-r1', '0', '[doc]') ), + ( "sys-apps/portage:0[doc]", + (None, 'sys-apps/portage', None, '0', '[doc]') ), + ] + + for atom, parts in tests: + a = Atom(atom) + op, cp, ver, slot, use = parts + self.assertEqual( op, a.operator, + msg="Atom('%s').operator == '%s'" % ( atom, a.operator ) ) + self.assertEqual( cp, a.cp, + msg="Atom('%s').cp == '%s'" % ( atom, a.cp ) ) + if ver is not None: + cpv = "%s-%s" % (cp, ver) + else: + cpv = cp + self.assertEqual( cpv, a.cpv, + msg="Atom('%s').cpv == '%s'" % ( atom, a.cpv ) ) + self.assertEqual( slot, a.slot, + msg="Atom('%s').slot == '%s'" % ( atom, a.slot ) ) + self.assertEqual( use, str(a.use), + msg="Atom('%s').use == '%s'" % ( atom, a.use ) ) diff --git a/pym/portage/update.py b/pym/portage/update.py index 56e6709c0..251da88a4 100644 --- a/pym/portage/update.py +++ b/pym/portage/update.py @@ -13,22 +13,24 @@ from portage import _unicode_decode from portage import _unicode_encode import portage portage.proxy.lazyimport.lazyimport(globals(), - 'portage.dep:dep_getkey,get_operator,isvalidatom,isjustname,remove_slot', + 'portage.dep:Atom,dep_getkey,get_operator,isjustname,isvalidatom,' + \ + 'remove_slot', 'portage.util:ConfigProtect,grabfile,new_protect_filename,' + \ 'normalize_path,write_atomic,writemsg', 'portage.versions:ververify' ) from portage.const import USER_CONFIG_PATH -from portage.exception import DirectoryNotFound, PortageException +from portage.exception import DirectoryNotFound, InvalidAtom, PortageException from portage.localization import _ ignored_dbentries = ("CONTENTS", "environment.bz2") def update_dbentry(update_cmd, mycontent): if update_cmd[0] == "move": - old_value, new_value = update_cmd[1], update_cmd[2] + old_value = str(update_cmd[1]) if old_value in mycontent: + new_value = str(update_cmd[2]) old_value = re.escape(old_value); mycontent = re.sub(old_value+"(:|$|\\s)", new_value+"\\1", mycontent) def myreplace(matchobj): @@ -41,7 +43,7 @@ def update_dbentry(update_cmd, mycontent): else: return "".join(matchobj.groups()) mycontent = re.sub("(%s-)(\\S*)" % old_value, myreplace, mycontent) - elif update_cmd[0] == "slotmove" and get_operator(update_cmd[1]) is None: + elif update_cmd[0] == "slotmove" and update_cmd[1].operator is None: pkg, origslot, newslot = update_cmd[1:] old_value = "%s:%s" % (pkg, origslot) if old_value in mycontent: @@ -137,21 +139,38 @@ def parse_updates(mycontent): if len(mysplit) != 3: errors.append(_("ERROR: Update command invalid '%s'") % myline) continue - orig_value, new_value = mysplit[1], mysplit[2] - for cp in (orig_value, new_value): - if not (isvalidatom(cp) and isjustname(cp)): + for i in (1, 2): + try: + atom = Atom(mysplit[i]) + except InvalidAtom: + atom = None + else: + if atom.blocker or atom != atom.cp: + atom = None + if atom is not None: + mysplit[i] = atom + else: errors.append( _("ERROR: Malformed update entry '%s'") % myline) - continue + break if mysplit[0] == "slotmove": if len(mysplit)!=4: errors.append(_("ERROR: Update command invalid '%s'") % myline) continue pkg, origslot, newslot = mysplit[1], mysplit[2], mysplit[3] - if not isvalidatom(pkg): + try: + atom = Atom(pkg) + except InvalidAtom: + atom = None + else: + if atom.blocker: + atom = None + if atom is not None: + mysplit[1] = atom + else: errors.append(_("ERROR: Malformed update entry '%s'") % myline) continue - + # The list of valid updates is filtered by continue statements above. myupd.append(mysplit) return myupd, errors -- 2.26.2