X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=katie;h=cf26804343ea59c541b53fb202d2016e36a89a6b;hb=e0115df14432cea904226f806269fa83bdc9051e;hp=7d725a23c0ddcb207008736ece3708cc2083f8e7;hpb=f5839dcdc13733d59352f0044061d2482e2bd766;p=dak.git diff --git a/katie b/katie index 7d725a23..cf268043 100755 --- a/katie +++ b/katie @@ -2,7 +2,7 @@ # Installs Debian packaes # Copyright (C) 2000, 2001 James Troup -# $Id: katie,v 1.51 2001-07-07 04:01:08 troup Exp $ +# $Id: katie,v 1.56 2001-07-28 18:07:58 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 @@ -36,6 +36,8 @@ import FCNTL, commands, fcntl, getopt, gzip, os, pg, pwd, re, shutil, stat, stri import apt_inst, apt_pkg import utils, db_access, logging +from types import *; + ############################################################################### re_isanum = re.compile (r"^\d+$"); @@ -232,9 +234,12 @@ def check_changes(filename): files = utils.build_file_list(changes, ""); except utils.changes_parse_error_exc, line: reject_message = reject_message + "Rejected: error parsing changes file '%s', can't grok: %s.\n" % (filename, line); + except utils.nk_format_exc, format: + reject_message = reject_message + "Rejected: unknown format '%s' of changes file '%s'.\n" % (format, filename); + return 0; # Check for mandatory fields - for i in ("source", "binary", "architecture", "version", "distribution","maintainer", "files"): + for i in ("source", "binary", "architecture", "version", "distribution", "maintainer", "files"): if not changes.has_key(i): reject_message = reject_message + "Rejected: Missing field `%s' in changes file.\n" % (i) return 0 # Avoid errors during later tests @@ -265,6 +270,10 @@ def check_changes(filename): if re_isanum.match (i) == None: reject_message = reject_message + "Rejected: `%s' from Closes field isn't a number.\n" % (i) + # Ensure there _is_ a target distribution + if changes["distribution"].keys() == []: + reject_message = reject_message + "Rejected: huh? Distribution field is empty in changes file.\n"; + # Map frozen to unstable if frozen doesn't exist if changes["distribution"].has_key("frozen") and not Cnf.has_key("Suite::Frozen"): del changes["distribution"]["frozen"] @@ -273,19 +282,17 @@ def check_changes(filename): # Map testing to unstable if changes["distribution"].has_key("testing"): - del changes["distribution"]["testing"] - changes["distribution"]["unstable"] = 1; - reject_message = reject_message + "Mapping testing to unstable.\n" + if len(changes["distribution"].keys()) > 1: + del changes["distribution"]["testing"]; + reject_message = reject_message + "Warning: Ignoring testing as a target suite.\n"; + else: + reject_message = reject_message + "Rejected: invalid distribution 'testing'.\n"; # Ensure target distributions exist for i in changes["distribution"].keys(): if not Cnf.has_key("Suite::%s" % (i)): reject_message = reject_message + "Rejected: Unknown distribution `%s'.\n" % (i) - # Ensure there _is_ a target distribution - if changes["distribution"].keys() == []: - reject_message = reject_message + "Rejected: huh? Distribution field is empty in changes file.\n"; - # Map unreleased arches from stable to unstable if changes["distribution"].has_key("stable"): for i in changes["architecture"].keys(): @@ -423,7 +430,7 @@ def check_files(): files[file]["package"] = m.group(1) files[file]["version"] = m.group(2) files[file]["type"] = m.group(3) - + # Ensure the source package name matches the Source filed in the .changes if changes["source"] != files[file]["package"]: reject_message = reject_message + "Rejected: %s: changes file doesn't say %s for Source\n" % (file, files[file]["package"]) @@ -468,7 +475,7 @@ def check_files(): 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" + 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' OR a.arch_string = 'all') 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() for oldfile in oldfiles: @@ -560,6 +567,11 @@ def check_dsc (): reject_message = reject_message + "Rejected: error parsing .dsc file '%s', can't grok: %s.\n" % (file, line); continue; + # Enforce mandatory fields + for i in ("format", "source", "version", "binary", "maintainer", "architecture", "files"): + if not dsc.has_key(i): + reject_message = reject_message + "Rejected: Missing field `%s' in dsc file.\n" % (i) + # The dpkg maintainer from hell strikes again! Bumping the # version number of the .dsc breaks extraction by stable's # dpkg-source. @@ -569,6 +581,23 @@ def check_dsc (): installed. """; + # Ensure the version number in the .dsc matches the version number in the .changes + epochless_dsc_version = utils.re_no_epoch.sub('', dsc.get("version")); + changes_version = files[file]["version"]; + if epochless_dsc_version != files[file]["version"]: + reject_message = reject_message + "Rejected: version ('%s') in .dsc does not match version ('%s') in .changes\n" % (epochless_dsc_version, changes_version); + + # Ensure source is newer than existing source in target suites + package = dsc.get("source"); + new_version = dsc.get("version"); + for suite in changes["distribution"].keys(): + q = projectB.query("SELECT s.version FROM source s, src_associations sa, suite su WHERE s.source = '%s' AND su.suite_name = '%s' AND sa.source = s.id AND sa.suite = su.id" + % (package, suite)); + ql = map(lambda x: x[0], q.getresult()); + for old_version in ql: + if apt_pkg.VersionCompare(new_version, old_version) != 1: + reject_message = reject_message + "Rejected: %s Old version `%s' >= new version `%s'.\n" % (file, old_version, new_version) + # Try and find all files mentioned in the .dsc. This has # to work harder to cope with the multiple possible # locations of an .orig.tar.gz. @@ -733,10 +762,14 @@ def check_override (): def update_subst (changes_filename): global Subst; - if changes.has_key("architecture"): - Subst["__ARCHITECTURE__"] = string.join(changes["architecture"].keys(), ' ' ); - else: - Subst["__ARCHITECTURE__"] = "Unknown"; + # If katie crashed out in the right place, architecture may still be a string. + if not changes.has_key("architecture") or not isinstance(changes["architecture"], DictType): + changes["architecture"] = { "Unknown" : "" }; + # and maintainer822 may not exist. + if not changes.has_key("maintainer822"): + changes["maintainer822"] = Cnf["Dinstall::MyEmailAddress"]; + + Subst["__ARCHITECTURE__"] = string.join(changes["architecture"].keys(), ' ' ); Subst["__CHANGES_FILENAME__"] = os.path.basename(changes_filename); Subst["__FILE_CONTENTS__"] = changes.get("filecontents", ""); @@ -761,7 +794,7 @@ def action (changes_filename): # changes["distribution"] may not exist in corner cases # (e.g. unreadable changes files) - if not changes.has_key("distribution"): + if not changes.has_key("distribution") or not isinstance(changes["distribution"], DictType): changes["distribution"] = {}; for suite in changes["distribution"].keys(): @@ -1219,7 +1252,8 @@ distribution.""" Subst["__STABLE_WARNING__"] = ""; mail_message = utils.TemplateSubst(Subst,open(Cnf["Dir::TemplatesDir"]+"/katie.bug-close","r").read()); utils.send_mail (mail_message, "") - Logger.log(["closing bugs"]+bugs); + if action: + Logger.log(["closing bugs"]+bugs); else: # NMU summary = summary + "Setting bugs to severity fixed: " control_message = "" @@ -1230,7 +1264,8 @@ distribution.""" Subst["__CONTROL_MESSAGE__"] = control_message; mail_message = utils.TemplateSubst(Subst,open(Cnf["Dir::TemplatesDir"]+"/katie.bug-nmu-fixed","r").read()); utils.send_mail (mail_message, "") - Logger.log(["setting bugs to fixed"]+bugs); + if action: + Logger.log(["setting bugs to fixed"]+bugs); summary = summary + "\n" return summary @@ -1353,7 +1388,7 @@ def main(): Subst = {} Subst["__ADMIN_ADDRESS__"] = Cnf["Dinstall::MyAdminAddress"]; Subst["__BUG_SERVER__"] = Cnf["Dinstall::BugServer"]; - bcc = "X-Katie: $Revision: 1.51 $" + bcc = "X-Katie: $Revision: 1.56 $" if Cnf.has_key("Dinstall::Bcc"): Subst["__BCC__"] = bcc + "\nBcc: %s" % (Cnf["Dinstall::Bcc"]); else: