From 360778208e003d0644bab8b769e6ba02b82f2190 Mon Sep 17 00:00:00 2001 From: Sebastian Luther Date: Mon, 4 Oct 2010 20:41:28 +0200 Subject: egencache: Sort file names for ChangeLog --- bin/egencache | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 6 deletions(-) diff --git a/bin/egencache b/bin/egencache index b2f208fce..bf4b6d567 100755 --- a/bin/egencache +++ b/bin/egencache @@ -38,10 +38,11 @@ except ImportError: from portage import os, _encodings, _unicode_encode, _unicode_decode from _emerge.MetadataRegen import MetadataRegen from portage.cache.cache_errors import CacheError, StatCollision +from portage.manifest import guessManifestFileType from portage.util import cmp_sort_key, writemsg_level from portage import cpv_getkey from portage.dep import Atom, isjustname -from portage.versions import pkgcmp, pkgsplit +from portage.versions import pkgcmp, pkgsplit, vercmp try: import xml.etree.ElementTree @@ -463,6 +464,71 @@ class GenUseLocalDesc(object): output.close() +if sys.hexversion < 0x3000000: + _filename_base = unicode +else: + _filename_base = str + +class _special_filename(_filename_base): + """ + Helps to sort file names by file type and other criteria. + """ + def __new__(cls, status_change, file_name): + return _filename_base.__new__(cls, status_change + file_name) + + def __init__(self, status_change, file_name): + _filename_base.__init__(status_change + file_name) + self.status_change = status_change + self.file_name = file_name + self.file_type = guessManifestFileType(file_name) + + def file_type_lt(self, a, b): + """ + Defines an ordering between file types. + """ + first = a.file_type + second = b.file_type + if first == second: + return False + + if first == "EBUILD": + return True + elif first == "MISC": + return second in ("EBUILD",) + elif first == "AUX": + return second in ("EBUILD", "MISC") + elif first == "DIST": + return second in ("EBUILD", "MISC", "AUX") + elif first is None: + return False + else: + raise ValueError("Unknown file type '%s'" % first) + + def __lt__(self, other): + """ + Compare different file names, first by file type and then + for ebuilds by version and lexicographically for others. + EBUILD < MISC < AUX < DIST < None + """ + if self.__class__ != other.__class__: + raise NotImplementedError + + # Sort by file type as defined by file_type_lt(). + if self.file_type_lt(self, other): + return True + elif self.file_type_lt(other, self): + return False + + # Files have the same type. + if self.file_type == "EBUILD": + # Sort by version. Lowest first. + ver = "-".join(pkgsplit(self.file_name[:-7])[1:3]) + other_ver = "-".join(pkgsplit(other.file_name[:-7])[1:3]) + return vercmp(ver, other_ver) < 0 + else: + # Sort lexicographically. + return self.file_name < other.file_name + class GenChangeLogs(object): def __init__(self, portdb): self.returncode = os.EX_OK @@ -537,11 +603,11 @@ class GenChangeLogs(object): elif f[1] == 'ChangeLog': pass elif f[0].startswith('A'): - changed.append('+%s' % f[1]) + changed.append(_special_filename("+", f[1])) elif f[0].startswith('D'): - changed.append('-%s' % f[1]) + changed.append(_special_filename("-", f[1])) elif f[0].startswith('M'): - changed.append(f[1]) + changed.append(_special_filename("", f[1])) else: writemsg_level( "ERROR: unexpected git file status for %s: %s\n" % (cp,f,), @@ -554,7 +620,7 @@ class GenChangeLogs(object): (ts, author) = cinfo[0].split(' ', 1) date = time.strftime('%d %b %Y', time.gmtime(float(ts))) - # XXX: sort changes (ebuilds should go by PV) + changed = [str(x) for x in sorted(changed)] wroteheader = False for c in changed: @@ -592,6 +658,7 @@ class GenChangeLogs(object): def run(self): repo_path = self._portdb.porttrees[0] os.chdir(repo_path) + if 'git' not in FindVCS(): writemsg_level( "ERROR: --update-changelogs supported only in git repos\n", @@ -601,10 +668,13 @@ class GenChangeLogs(object): for cp in self._portdb.cp_all(): os.chdir(os.path.join(repo_path, cp)) - # Determine whether ChangeLog is up-to-date by comparing # the newest commit timestamp with the ChangeLog timestamp. lmod = self.grab(['git', 'log', '--format=%ct', '-1', '.']) + if not lmod: + # This cp has not been added to the repo. + continue + try: cmod = os.stat('ChangeLog').st_mtime except OSError: -- cgit v1.2.3-1-g7c22