]> git.decadent.org.uk Git - dak.git/blobdiff - katie.py
two bug fixes in source_exists changes
[dak.git] / katie.py
index 996ae0283fef263e5bacc98c27031e7032adc7a0..bee2c03e63b431a4ac00cf85403244d36f52f6df 100644 (file)
--- a/katie.py
+++ b/katie.py
@@ -1,8 +1,8 @@
 #!/usr/bin/env python
 
 # Utility functions for katie
-# Copyright (C) 2001, 2002  James Troup <james@nocrew.org>
-# $Id: katie.py,v 1.27 2002-10-16 02:47:32 troup Exp $
+# Copyright (C) 2001, 2002, 2003  James Troup <james@nocrew.org>
+# $Id: katie.py,v 1.36 2003-07-29 14:57:03 ajt 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
@@ -308,7 +308,7 @@ distribution.""";
                     else:
                         Subst["__STABLE_WARNING__"] = "";
                     mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/jennifer.bug-close");
-                    utils.send_mail (mail_message, "");
+                    utils.send_mail (mail_message);
             if action:
                 self.Logger.log(["closing bugs"]+bugs);
         else:                     # NMU
@@ -320,7 +320,7 @@ distribution.""";
             if action and control_message != "":
                 Subst["__CONTROL_MESSAGE__"] = control_message;
                 mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/jennifer.bug-nmu-fixed");
-                utils.send_mail (mail_message, "");
+                utils.send_mail (mail_message);
             if action:
                 self.Logger.log(["setting bugs to fixed"]+bugs);
         summary += "\n";
@@ -353,7 +353,7 @@ distribution.""";
                 if Cnf.get("Dinstall::TrackingServer") and changes["architecture"].has_key("source"):
                     Subst["__ANNOUNCE_LIST_ADDRESS__"] = Subst["__ANNOUNCE_LIST_ADDRESS__"] + "\nBcc: %s@%s" % (changes["source"], Cnf["Dinstall::TrackingServer"]);
                 mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/jennifer.announce");
-                utils.send_mail (mail_message, "");
+                utils.send_mail (mail_message);
 
         if Cnf.FindB("Dinstall::CloseBugs"):
             summary = self.close_bugs(summary, action);
@@ -386,7 +386,7 @@ distribution.""";
             Subst["__SUITE__"] = "";
             Subst["__SUMMARY__"] = summary;
             mail_message = utils.TemplateSubst(Subst,Cnf["Dir::Templates"]+"/jennifer.accepted");
-            utils.send_mail(mail_message, "")
+            utils.send_mail(mail_message)
             self.announce(short_summary, 1)
 
         # Special support to enable clean auto-building of accepted packages
@@ -460,25 +460,26 @@ distribution.""";
                     # Ignore this; it's a common mistake and not worth whining about
                     if section.lower() == "non-us/main" and override_section.lower() == "non-us":
                         continue;
-                    summary += "%s: section is overridden from %s to %s.\n" % (file, section, override_section);
+                    summary += "%s: package says section is %s, override says %s.\n" % (file, section, override_section);
                 priority = files[file]["priority"];
                 override_priority = files[file]["override priority"];
                 if priority != override_priority and priority != "-":
-                    summary += "%s: priority is overridden from %s to %s.\n" % (file, priority, override_priority);
+                    summary += "%s: package says priority is %s, override says %s.\n" % (file, priority, override_priority);
 
         if summary == "":
             return;
 
         Subst["__SUMMARY__"] = summary;
         mail_message = utils.TemplateSubst(Subst,self.Cnf["Dir::Templates"]+"/jennifer.override-disparity");
-        utils.send_mail (mail_message, "");
+        utils.send_mail(mail_message);
 
     ###########################################################################
 
-    def force_move (self, files):
-        """Forcefully move files from the current directory to the reject
-           directory.  If any file already exists it will be moved to the
-           morgue to make way for the new file."""
+    def force_reject (self, files):
+        """Forcefully move files from the current directory to the
+           reject directory.  If any file already exists in the reject
+           directory it will be moved to the morgue to make way for
+           the new file."""
 
         Cnf = self.Cnf
 
@@ -527,10 +528,10 @@ distribution.""";
             while answer == 'E':
                 os.system("%s %s" % (editor, temp_filename))
                 file = utils.open_file(temp_filename);
-                reject_message = " ".join(file.readlines());
+                reject_message = "".join(file.readlines());
                 file.close();
                 print "Reject message:";
-                print utils.prefix_multi_line_string(reject_message,"  ");
+                print utils.prefix_multi_line_string(reject_message,"  ",include_blank_lines=1);
                 prompt = "[R]eject, Edit, Abandon, Quit ?"
                 answer = "XXX";
                 while prompt.find(answer) == -1:
@@ -556,7 +557,7 @@ distribution.""";
 
         # Move all the files into the reject directory
         reject_files = pkg.files.keys() + [pkg.changes_file];
-        self.force_move(reject_files);
+        self.force_reject(reject_files);
 
         # If we fail here someone is probably trying to exploit the race
         # so let's just raise an exception ...
@@ -586,7 +587,7 @@ distribution.""";
 
         # Send the rejection mail if appropriate
         if not Cnf["Dinstall::Options::No-Mail"]:
-            utils.send_mail (reject_mail_message, "");
+            utils.send_mail(reject_mail_message);
 
         self.Logger.log(["rejected", pkg.changes_file]);
         return 0;
@@ -600,28 +601,37 @@ distribution.""";
     # (2) Bin-only NMU of an MU            => 1.0-3.0.1
     # (3) Bin-only NMU of a sourceful-NMU  => 1.0-3.1.1
 
-    def source_exists (self, package, source_version):
-        q = self.projectB.query("SELECT s.version FROM source s WHERE s.source = '%s'" % (package));
-
-        # Reduce the query results to a list of version numbers
-        ql = map(lambda x: x[0], q.getresult());
-
-        # Try (1)
-        if ql.count(source_version):
-            return 1;
-
-        # Try (2)
-        orig_source_version = re_bin_only_nmu_of_mu.sub('', source_version);
-        if ql.count(orig_source_version):
-            return 1;
-
-        # Try (3)
-        orig_source_version = re_bin_only_nmu_of_nmu.sub('', source_version);
-        if ql.count(orig_source_version):
-            return 1;
-
-        # No source found...
-        return 0;
+    def source_exists (self, package, source_version, suites = ["any"]):
+       okay = 1
+       for suite in suites:
+           if suite == "any":
+               que = "SELECT s.version FROM source s WHERE s.source = '%s'" % \
+                   (package)
+           else:
+               suite_id = db_access.get_suite_id(suite);
+               que = "SELECT s.version FROM source s JOIN src_associations sa ON (s.id = sa.source) WHERE sa.suite = %d AND s.source = '%s'" % (suite_id, package)
+            q = self.projectB.query(que)
+
+            # Reduce the query results to a list of version numbers
+            ql = map(lambda x: x[0], q.getresult());
+
+            # Try (1)
+            if ql.count(source_version):
+                continue
+
+            # Try (2)
+            orig_source_version = re_bin_only_nmu_of_mu.sub('', source_version)
+            if ql.count(orig_source_version):
+                continue
+
+            # Try (3)
+            orig_source_version = re_bin_only_nmu_of_nmu.sub('', source_version)
+            if ql.count(orig_source_version):
+                continue
+
+            # No source found...
+            okay = 0
+       return okay
 
     ################################################################################
 
@@ -745,6 +755,14 @@ SELECT s.version, su.suite_name FROM source s, src_associations sa, suite su
 
     ################################################################################
 
+    # **WARNING**
+    # NB: this function can remove entries from the 'files' index [if
+    # the .orig.tar.gz is a duplicate of the one in the archive]; if
+    # you're iterating over 'files' and call this function as part of
+    # the loop, be sure to add a check to the top of the loop to
+    # ensure you haven't just tried to derefernece the deleted entry.
+    # **WARNING**
+
     def check_dsc_against_db(self, file):
         self.reject_message = "";
         files = self.pkg.files;
@@ -762,9 +780,16 @@ SELECT s.version, su.suite_name FROM source s, src_associations sa, suite su
                 actual_size = int(files[dsc_file]["size"]);
                 found = "%s in incoming" % (dsc_file)
                 # Check the file does not already exist in the archive
-                q = self.projectB.query("SELECT f.size, f.md5sum FROM files f, location l WHERE (f.filename ~ '/%s$' OR f.filename = '%s') AND l.id = f.location" % (utils.regex_safe(dsc_file), dsc_file));
+                q = self.projectB.query("SELECT size, md5sum, filename FROM files WHERE filename LIKE '%%%s%%'" % (dsc_file));
 
-                # "It has not broken them.  It has fixed a
+                ql = q.getresult();
+                # Strip out anything that isn't '%s' or '/%s$'
+                for i in ql:
+                    if i[2] != dsc_file and i[2][-(len(dsc_file)+1):] != '/'+dsc_file:
+                        self.Logger.log(["check_dsc_against_db",i[2],dsc_file]);
+                        ql.remove(i);
+
+                # "[katie] has not broken them.  [katie] has fixed a
                 # brokenness.  Your crappy hack exploited a bug in
                 # the old dinstall.
                 #
@@ -773,7 +798,6 @@ SELECT s.version, su.suite_name FROM source s, src_associations sa, suite su
                 # the same name and version.)"
                 #                        -- ajk@ on d-devel@l.d.o
 
-                ql = q.getresult();
                 if ql:
                     # Ignore exact matches for .orig.tar.gz
                     match = 0;
@@ -790,8 +814,13 @@ SELECT s.version, su.suite_name FROM source s, src_associations sa, suite su
                         self.reject("can not overwrite existing copy of '%s' already in the archive." % (dsc_file));
             elif dsc_file.endswith(".orig.tar.gz"):
                 # Check in the pool
-                q = self.projectB.query("SELECT l.path, f.filename, l.type, f.id, l.id FROM files f, location l WHERE (f.filename ~ '/%s$' OR f.filename = '%s') AND l.id = f.location" % (utils.regex_safe(dsc_file), dsc_file));
+                q = self.projectB.query("SELECT l.path, f.filename, l.type, f.id, l.id FROM files f, location l WHERE f.filename LIKE '%%%s%%' AND l.id = f.location" % (dsc_file));
                 ql = q.getresult();
+                # Strip out anything that isn't '%s' or '/%s$'
+                for i in ql:
+                    if i[1] != dsc_file and i[1][-(len(dsc_file)+1):] != '/'+dsc_file:
+                        self.Logger.log(["check_dsc_against_db",i[1],dsc_file]);
+                        ql.remove(i);
 
                 if ql:
                     # Unfortunately, we make get more than one