From 9747704c3468d10a66a0bd20a489ee800815dacf Mon Sep 17 00:00:00 2001 From: James Troup Date: Thu, 24 May 2001 18:56:23 +0000 Subject: [PATCH] compiled regexes; source-must-exist; obsoleted-by-unstable check for experimental. --- TODO | 9 ++++++ katie | 54 ++++++++++++++++++++++++++-------- rene | 17 ++++++++++- utils.py | 90 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 144 insertions(+), 26 deletions(-) diff --git a/TODO b/TODO index 7081d22b..301235de 100644 --- a/TODO +++ b/TODO @@ -12,6 +12,15 @@ Urgent files from p-u when removing stuff superseded by newer versions. o experimental needs to auto clean (relative to unstable) + [' + SELECT s.source, s.version AS experimental, s2.version AS unstable + FROM src_associations sa, source s, source s2, src_associations sa2 + WHERE sa.suite = 1 AND sa2.suite = 5 AND sa.source = s.id + AND sa2.source = s2.id AND s.source = s2.source + AND versioncmp(s.version, s2.version) < 0; + '] + [ but, needs to hook into melanie ... ] + [ and, err, fix the gay hardcoding of suites in rene ... ] o jenna doesn't handle arch: any -> arch: all transitions [aj worked around; need to revisit] diff --git a/katie b/katie index 9efaa0be..49ffacc9 100755 --- a/katie +++ b/katie @@ -2,7 +2,7 @@ # Installs Debian packaes # Copyright (C) 2000, 2001 James Troup -# $Id: katie,v 1.41 2001-05-17 01:21:40 troup Exp $ +# $Id: katie,v 1.42 2001-05-24 18:56:23 troup Exp $ # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -38,11 +38,12 @@ import utils, db_access ############################################################################### -re_isanum = re.compile (r'^\d+$'); -re_changes = re.compile (r'changes$'); +re_isanum = re.compile (r"^\d+$"); +re_changes = re.compile (r"changes$"); re_default_answer = re.compile(r"\[(.*)\]"); re_fdnic = re.compile("\n\n"); re_bad_diff = re.compile("^[\-\+][\-\+][\-\+] /dev/null"); +re_bin_only_nmu = re.compile("\.\d+\.\d+$"); ######################################################################################### @@ -327,6 +328,18 @@ def check_files(): files[file]["source"] = control.Find("Source", ""); if files[file]["source"] == "": files[file]["source"] = files[file]["package"]; + # Get the source version + source = files[file]["source"]; + source_version = "" + if string.find(source, "(") != -1: + m = utils.re_extract_src_version.match(source) + source = m.group(1) + source_version = m.group(2) + if not source_version: + source_version = files[file]["version"]; + files[file]["source package"] = source; + files[file]["source version"] = source_version; + # Checks for a source package... else: m = utils.re_issource.match(file) @@ -376,8 +389,8 @@ def check_files(): if not in_override_p(files[file]["package"], files[file]["component"], suite, files[file].get("dbtype",""), file): files[file]["new"] = 1 - # Find any old binary packages if files[file]["type"] == "deb": + # Find any old binary packages q = projectB.query("SELECT b.id, b.version, f.filename, l.path, c.name FROM binaries b, bin_associations ba, suite s, location l, component c, architecture a, files f WHERE b.package = '%s' AND s.suite_name = '%s' AND a.arch_string = '%s' AND ba.bin = b.id AND ba.suite = s.id AND b.architecture = a.id AND f.location = l.id AND l.component = c.id AND b.file = f.id" % (files[file]["package"], suite, files[file]["architecture"])) oldfiles = q.dictresult() @@ -392,6 +405,24 @@ def check_files(): if q.getresult() != []: reject_message = reject_message + "Rejected: can not overwrite existing copy of '%s' already in the archive.\n" % (file) + # Check for existent source + # FIXME: this is no longer per suite + if changes["architecture"].has_key("source"): + source_version = files[file]["source version"]; + if source_version != changes["version"]: + reject_message = reject_message + "Rejected: source version (%s) for %s doesn't match changes version %s.\n" % (files[file]["sourceversion"], file, changes["version"]); + else: + q = projectB.query("SELECT s.version FROM source s WHERE s.source = '%s'" % (files[file]["source package"])); + ql = map(lambda x: x[0], q.getresult()); + if ql.count(source_version) == 0: + # Maybe it's a binary only NMU ? + if re_bin_only_nmu.search(source_version): + orig_source_version = re_bin_only_nmu.sub('', source_version); + if ql.count(orig_source_version) == 0: + reject_message = reject_message + "Rejected: no source version (%s [or %s]) found in %s for %s (%s).\n" % (source_version, orig_source_version, suite, files[file]["source package"], file); + else: + reject_message = reject_message + "Rejected: no source version (%s) found in %s for %s (%s).\n" % (source_version, suite, files[file]["source package"], file); + # Find any old .dsc files elif files[file]["type"] == "dsc": q = projectB.query("SELECT s.id, s.version, f.filename, l.path, c.name FROM source s, src_associations sa, suite su, location l, component c, files f WHERE s.source = '%s' AND su.suite_name = '%s' AND sa.source = s.id AND sa.suite = su.id AND f.location = l.id AND l.component = c.id AND f.id = s.file" @@ -803,14 +834,8 @@ def install (changes_filename, summary, short_summary): architecture_id = db_access.get_architecture_id (architecture); type = files[file]["dbtype"]; dsc_component = files[file]["component"] - source = files[file]["source"] - source_version = "" - if string.find(source, "(") != -1: - m = utils.re_extract_src_version.match(source) - source = m.group(1) - source_version = m.group(2) - if not source_version: - source_version = version + source = files[file]["source package"] + source_version = files[file]["source version"]; filename = files[file]["pool name"] + file; if not files[file]["files id"]: files[file]["files id"] = db_access.set_files_id (filename, files[file]["size"], files[file]["md5sum"], files[file]["location id"]) @@ -1243,7 +1268,7 @@ def main(): Subst = {} Subst["__ADMIN_ADDRESS__"] = Cnf["Dinstall::MyAdminAddress"]; Subst["__BUG_SERVER__"] = Cnf["Dinstall::BugServer"]; - bcc = "X-Katie: $Revision: 1.41 $" + bcc = "X-Katie: $Revision: 1.42 $" if Cnf.has_key("Dinstall::Bcc"): Subst["__BCC__"] = bcc + "\nBcc: %s" % (Cnf["Dinstall::Bcc"]); else: @@ -1251,6 +1276,9 @@ def main(): Subst["__DISTRO__"] = Cnf["Dinstall::MyDistribution"]; Subst["__KATIE_ADDRESS__"] = Cnf["Dinstall::MyEmailAddress"]; + # Sort the .changes files so that we process sourceful ones first + changes_files.sort(utils.changes_compare); + # Process the changes files for changes_file in changes_files: print "\n" + changes_file; diff --git a/rene b/rene index 69672910..efac5ac7 100755 --- a/rene +++ b/rene @@ -2,7 +2,7 @@ # Check for obsolete binary packages # Copyright (C) 2000, 2001 James Troup -# $Id: rene,v 1.4 2001-05-21 02:25:08 troup Exp $ +# $Id: rene,v 1.5 2001-05-24 18:56:23 troup Exp $ # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -151,6 +151,21 @@ def main (): print " %s has no source [%s: %s]" % (package, source, source_binaries.get(source, "(source does not exist)")); packages.close(); + # Check for packages in experimental obsoleted by versions in unstable + # + # [If melanie was callable from python, we could auto-remove these + # packages...] + + q = projectB.query(""" +SELECT s.source, s.version AS experimental, s2.version AS unstable + FROM src_associations sa, source s, source s2, src_associations sa2 + WHERE sa.suite = 1 AND sa2.suite = 5 AND sa.source = s.id + AND sa2.source = s2.id AND s.source = s2.source + AND versioncmp(s.version, s2.version) < 0"""); + ql = q.getresult(); + if ql != []: + print + print q #################################################################################################### diff --git a/utils.py b/utils.py index 33b77805..95a08826 100644 --- a/utils.py +++ b/utils.py @@ -1,6 +1,6 @@ # Utility functions # Copyright (C) 2000 James Troup -# $Id: utils.py,v 1.22 2001-05-17 01:17:54 troup Exp $ +# $Id: utils.py,v 1.23 2001-05-24 18:56:23 troup Exp $ # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,14 +17,23 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import commands, os, pwd, re, socket, shutil, stat, string, sys, tempfile +import apt_pkg re_comments = re.compile(r"\#.*") re_no_epoch = re.compile(r"^\d*\:") re_no_revision = re.compile(r"\-[^-]*$") re_arch_from_filename = re.compile(r"/binary-[^/]+/") re_extract_src_version = re.compile (r"(\S+)\s*\((.*)\)") -re_isadeb = re.compile (r'.*\.u?deb$'); -re_issource = re.compile (r'(.+)_(.+?)\.(orig\.tar\.gz|diff\.gz|tar\.gz|dsc)'); +re_isadeb = re.compile (r".*\.u?deb$"); +re_issource = re.compile (r"(.+)_(.+?)\.(orig\.tar\.gz|diff\.gz|tar\.gz|dsc)"); + +re_begin_pgp_signature = re.compile("^-----BEGIN PGP SIGNATURE"); +re_begin_pgp_signed_msg = re.compile("^-----BEGIN PGP SIGNED MESSAGE"); +re_single_line_field = re.compile(r"^(\S*)\s*:\s*(.*)"); +re_multi_line_description = re.compile(r"^ \.$"); +re_multi_line_field = re.compile(r"^\s(.*)"); + +re_parse_maintainer = re.compile(r"^\s*(\S.*\S)\s*\<([^\> \t]+)\>"); changes_parse_error_exc = "Can't parse line in .changes file"; invalid_dsc_format_exc = "Invalid .dsc file"; @@ -131,30 +140,30 @@ def parse_changes(filename, dsc_whitespace_rules): if index > max(indices): raise invalid_dsc_format_exc, index; line = indexed_lines[index]; - if not re.match('^-----BEGIN PGP SIGNATURE', line): + if not re_begin_pgp_signature.match(line): raise invalid_dsc_format_exc, index; inside_signature = 0; break; - if re.match('^-----BEGIN PGP SIGNATURE', line): + if re_begin_pgp_signature.match(line): break; - if re.match(r'^-----BEGIN PGP SIGNED MESSAGE', line): + if re_begin_pgp_signed_msg.match(line): if dsc_whitespace_rules: inside_signature = 1; while index < max(indices) and line != "": index = index + 1; line = indexed_lines[index]; continue; - slf = re.match(r'^(\S*)\s*:\s*(.*)', line); + slf = re_single_line_field.match(line); if slf: field = string.lower(slf.groups()[0]); changes[field] = slf.groups()[1]; first = 1; continue; - mld = re.match(r'^ \.$', line); + mld = re_multi_line_description.match(line); if mld: changes[field] = changes[field] + '\n'; continue; - mlf = re.match(r'^\s(.*)', line); + mlf = re_multi_line_field.match(line); if mlf: if first == 1 and changes[field] != "": changes[field] = changes[field] + '\n'; @@ -226,15 +235,15 @@ def build_file_list(changes, dsc): # and make things incompatible!' def fix_maintainer (maintainer): - m = re.match(r"^\s*(\S.*\S)\s*\<([^\> \t]+)\>", maintainer) + m = re_parse_maintainer.match(maintainer); rfc822 = maintainer name = "" email = "" if m != None and len(m.groups()) == 2: name = m.group(1) email = m.group(2) - if re.search(r'[,.]', name) != None: - rfc822 = re.sub(r"^\s*(\S.*\S)\s*\<([^\> \t]+)\>", r"\2 (\1)", maintainer) + if string.find(name, ',') != -1 or string.find(name, '.') != -1: + rfc822 = re_parse_maintainer.sub(r"\2 (\1)", maintainer) return (rfc822, name, email) ###################################################################################### @@ -398,3 +407,60 @@ def size_type (c): c = c / 1000; t = " Mb"; return ("%d%s" % (c, t)) + +################################################################################ + +def cc_fix_changes (changes): + o = changes.get("architecture", "") + if o != "": + del changes["architecture"] + changes["architecture"] = {} + for j in string.split(o): + changes["architecture"][j] = 1 + +# Sort by 'have source', by source name, by source version number, by filename + +def changes_compare (a, b): + try: + a_changes = parse_changes(a, 0) + except changes_parse_error_exc, line: + return -1; + + try: + b_changes = parse_changes(b, 0) + except changes_parse_error_exc, line: + return 1; + + cc_fix_changes (a_changes); + cc_fix_changes (b_changes); + + # Sort by 'have source' + + a_has_source = a_changes["architecture"].get("source") + b_has_source = b_changes["architecture"].get("source") + if a_has_source and not b_has_source: + return -1; + elif b_has_source and not a_has_source: + return 1; + + # Sort by source name + + a_source = a_changes.get("source"); + b_source = b_changes.get("source"); + q = cmp (a_source, b_source); + if q: + return q; + + # Sort by source version + + a_version = a_changes.get("version"); + b_version = b_changes.get("version"); + q = apt_pkg.VersionCompare(a_version, b_version); + if q: + return q + + # Fall back to sort by filename + + return cmp(a, b); + +################################################################################ -- 2.39.5