From 2bf520bf28d34e4d2336ba96525e63ae22bc21fd Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Wed, 1 Dec 2010 19:56:44 -0800 Subject: [PATCH] add new cpv_sort_key() function --- .../tests/versions/test_cpv_sort_key.py | 16 +++++++ pym/portage/versions.py | 44 ++++++++++++++++++- 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 pym/portage/tests/versions/test_cpv_sort_key.py diff --git a/pym/portage/tests/versions/test_cpv_sort_key.py b/pym/portage/tests/versions/test_cpv_sort_key.py new file mode 100644 index 000000000..857af1701 --- /dev/null +++ b/pym/portage/tests/versions/test_cpv_sort_key.py @@ -0,0 +1,16 @@ +# Copyright 2010 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +from portage.tests import TestCase +from portage.versions import cpv_sort_key + +class CpvSortKeyTestCase(TestCase): + + def testCpvSortKey(self): + + tests = [ (( "a", "b", "a/b-2", "a/a-1", "a/b-1"), + ( "a", "a/a-1", "a/b-1", "a/b-2", "b")), + ] + + for test in tests: + self.assertEqual( tuple(sorted(test[0], key=cpv_sort_key())), test[1] ) diff --git a/pym/portage/versions.py b/pym/portage/versions.py index 8ac32eb24..d3271a762 100644 --- a/pym/portage/versions.py +++ b/pym/portage/versions.py @@ -4,13 +4,17 @@ __all__ = [ 'best', 'catpkgsplit', 'catsplit', - 'cpv_getkey', 'cpv_getversion', 'pkgcmp', 'pkgsplit', + 'cpv_getkey', 'cpv_getversion', 'cpv_sort_key', 'pkgcmp', 'pkgsplit', 'ververify', 'vercmp' ] import re import warnings +import portage +portage.proxy.lazyimport.lazyimport(globals(), + 'portage.util:cmp_sort_key' +) from portage.localization import _ # \w is [a-zA-Z0-9_] @@ -342,6 +346,44 @@ def cpv_getversion(mycpv): return None return mycpv[len(cp+"-"):] +def cpv_sort_key(): + """ + Create an object for sorting cpvs, to be useed as the 'key' parameter + in places like list.sort() or sorted(). This calls catpkgsplit() once for + each cpv and caches the result. If a given cpv is invalid or two cpvs + have different category/package names, then plain string (> and <) + comparison is used. + + @rtype: key object for sorting + @return: object for use as the 'key' parameter in places like + list.sort() or sorted() + """ + + split_cache = {} + + def cmp_cpv(cpv1, cpv2): + + split1 = split_cache.get(cpv1, False) + if split1 is False: + split1 = catpkgsplit(cpv1) + if split1 is not None: + split1 = (split1[:2], '-'.join(split1[2:])) + split_cache[cpv1] = split1 + + split2 = split_cache.get(cpv2, False) + if split2 is False: + split2 = catpkgsplit(cpv2) + if split2 is not None: + split2 = (split2[:2], '-'.join(split2[2:])) + split_cache[cpv2] = split2 + + if split1 is None or split2 is None or split1[0] != split2[0]: + return (cpv1 > cpv2) - (cpv1 < cpv2) + + return vercmp(split1[1], split2[1]) + + return cmp_sort_key(cmp_cpv) + def catsplit(mydep): return mydep.split("/", 1) -- 2.26.2