]> git.decadent.org.uk Git - dak.git/commitdiff
Merge commit 'djpig/djpig' into merge
authorJoerg Jaspert <joerg@debian.org>
Tue, 27 Oct 2009 20:48:13 +0000 (21:48 +0100)
committerJoerg Jaspert <joerg@debian.org>
Tue, 27 Oct 2009 20:48:13 +0000 (21:48 +0100)
* commit 'djpig/djpig':
  clean-queues: Add proper logging
  use the id, not the object
  add regex import
  file -> f
  we're already in the changes object
  use isinstance
  fixup

Signed-off-by: Joerg Jaspert <joerg@debian.org>
config/debian/dak.conf
config/debian/lintian.tags [new file with mode: 0644]
dak/process_unchecked.py
daklib/queue.py
daklib/regexes.py
tests/test_regexes.py

index 474a4f3db0af4e24b43516b021075d7694d48984..b254a7ad5ad8a4243887065934c5325a1efd991b 100644 (file)
@@ -26,6 +26,7 @@ Dinstall
    CloseBugs "true";
    OverrideDisparityCheck "true";
    DefaultSuite "unstable";
+   LintianTags "/srv/ftp.debian.org/dak/config/debian/lintian.tags";
    QueueBuildSuites
    {
      unstable;
diff --git a/config/debian/lintian.tags b/config/debian/lintian.tags
new file mode 100644 (file)
index 0000000..1c05410
--- /dev/null
@@ -0,0 +1,76 @@
+lintian:
+  warning:
+    - statically-linked-binary
+    - arch-independent-package-contains-binary-or-object
+    - arch-dependent-file-in-usr-share
+    - missing-build-dependency
+    - arch-dependent-file-in-usr-share
+    - missing-dependency-on-libc
+    - usr-share-doc-symlink-without-dependency
+    - binary-with-bad-dynamic-table
+    - usr-share-doc-symlink-without-dependency
+    - mknod-in-maintainer-script
+  error:
+    - binary-in-etc
+    - missing-dependency-on-perlapi
+    - copyright-lists-upstream-authors-with-dh_make-boilerplate
+    - section-is-dh_make-template
+    - package-installs-python-pyc
+    - library-in-debug-or-profile-should-not-be-stripped
+    - binary-file-compressed-with-upx
+    - html-changelog-without-text-version
+    - file-in-usr-marked-as-conffile
+    - build-info-in-binary-control-file-section
+    - debian-control-with-duplicate-fields
+    - not-allowed-control-file
+    - control-file-has-bad-permissions
+    - control-file-has-bad-owner
+    - no-copyright-file
+    - copyright-refers-to-old-directory
+    - copyright-file-compressed
+    - copyright-file-is-symlink
+    - usr-share-doc-symlink-to-foreign-package
+    - old-style-copyright-file
+    - copyright-refers-to-incorrect-directory
+    - package-has-no-description
+    - description-synopsis-is-empty
+    - extended-description-is-empty
+    - description-is-dh_make-template
+    - file-in-etc-not-marked-as-conffile
+    - no-package-name
+    - bad-package-name
+    - package-not-lowercase
+    - no-version-field
+    - bad-version-number
+    - upstream-version-not-numeric
+    - no-architecture-field
+    - magic-arch-in-arch-list
+    - too-many-architectures
+    - arch-any-in-binary-pkg
+    - no-maintainer-field
+    - maintainer-name-missing
+    - maintainer-address-missing
+    - maintainer-address-malformed
+    - maintainer-address-is-on-localhost
+    - uploader-name-missing
+    - uploader-address-malformed
+    - uploader-address-is-on-localhost
+    - no-source-field
+    - source-field-does-not-match-pkg-name
+    - section-is-dh_make-template
+    - build-depends-on-essential-package-without-using-version
+    - depends-on-build-essential-package-without-using-version
+    - build-depends-on-build-essential
+    - executable-in-usr-share-doc
+    - symlink-has-too-many-up-segments
+    - debian-rules-is-symlink
+    - debian-rules-not-a-makefile
+    - debian-rules-missing-required-target
+    - maintainer-script-removes-device-files
+    - no-standards-version-field
+    - invalid-standards-version
+    - dir-or-file-in-var-www
+    - dir-or-file-in-tmp
+    - dir-or-file-in-mnt
+    - dir-or-file-in-opt
+    - dir-or-file-in-srv
index 856c1dfa190283488ae138209c20421f71079317..0645dd9f86d9fd45e633326c1626a8855aac46d8 100755 (executable)
@@ -499,6 +499,7 @@ def process_it(changes_file):
                 valid_dsc_p = u.check_dsc(not Options["No-Action"])
                 if valid_dsc_p:
                     u.check_source()
+                    # u.check_lintian()
                 u.check_hashes()
                 u.check_urgency()
                 u.check_timestamps()
index daaa3c6e03936f6364e2cd851602dd946dad2dcd..d217d7e4c39a836f7a0530eb402653e4a1e0b2e6 100755 (executable)
@@ -39,6 +39,7 @@ import utils
 import commands
 import shutil
 import textwrap
+import tempfile
 from types import *
 
 import yaml
@@ -1200,6 +1201,91 @@ class Upload(object):
 
         self.ensure_hashes()
 
+    ###########################################################################
+    def check_lintian(self):
+        # Only check some distributions
+        valid_dist = False
+        for dist in ('unstable', 'experimental'):
+            if dist in self.pkg.changes['distribution']:
+                valid_dist = True
+                break
+
+        if not valid_dist:
+            return
+
+        cnf = Config()
+        tagfile = cnf("Dinstall::LintianTags")
+        # Parse the yaml file
+        sourcefile = file(tagfile, 'r')
+        sourcecontent = sourcefile.read()
+        sourcefile.close()
+        try:
+            lintiantags = yaml.load(sourcecontent)['lintian']
+        except yaml.YAMLError, msg:
+            utils.fubar("Can not read the lintian tags file %s, YAML error: %s." % (tagfile, msg))
+            return
+
+        # Now setup the input file for lintian. lintian wants "one tag per line" only,
+        # so put it together like it. We put all types of tags in one file and then sort
+        # through lintians output later to see if its a fatal tag we detected, or not.
+        # So we only run lintian once on all tags, even if we might reject on some, but not
+        # reject on others.
+        # Additionally build up a set of tags
+        tags = set()
+        (fd, temp_filename) = utils.temp_filename()
+        temptagfile = os.fdopen(fd, 'w')
+        for tagtype in lintiantags:
+            for tag in lintiantags[tagtype]:
+                temptagfile.write("%s\n" % tag)
+                tags.add(tag)
+        temptagfile.close()
+
+        # So now we should look at running lintian at the .changes file, capturing output
+        # to then parse it.
+        command = "lintian --show-overrides --tags-from-file %s %s" % (temp_filename, self.pkg.changes_file)
+        (result, output) = commands.getstatusoutput(cmd)
+        # We are done with lintian, remove our tempfile
+        os.unlink(temp_filename)
+        if (result != 0):
+            self.rejects.append("lintian failed for %s [return code: %s]." % (self.pkg.changes_file, result))
+            self.rejects.append(utils.prefix_multi_line_string(output, " [possible output:] "), "")
+            return
+
+        if len(output) == 0:
+            return
+
+        # We have output of lintian, this package isn't clean. Lets parse it and see if we
+        # are having a victim for a reject.
+        # W: tzdata: binary-without-manpage usr/sbin/tzconfig
+        for line in output.split('\n'):
+            m = re_parse_lintian.match(line)
+            if m is None:
+                continue
+
+            etype = m.group(1)
+            epackage = m.group(2)
+            etag = m.group(3)
+            etext = m.group(4)
+
+            # So lets check if we know the tag at all.
+            if etag not in tags:
+                continue
+
+            if etype == 'O':
+                # We know it and it is overriden. Check that override is allowed.
+                if etag in lintiantags['warning']:
+                    # The tag is overriden, and it is allowed to be overriden.
+                    # Don't add a reject message.
+                elif etag in lintiantags['error']:
+                    # The tag is overriden - but is not allowed to be
+                    self.rejects.append("%s: Overriden tag %s found, but this tag may not be overwritten." % (epackage, etag))
+            else:
+                # Tag is known, it is not overriden, direct reject.
+                self.rejects.append("%s: Found lintian output: '%s %s', automatically rejected package." % (epackage, etag, etext))
+                # Now tell if they *might* override it.
+                if etag in lintiantags['warning']:
+                    self.rejects.append("%s: If you have a good reason, you may override this lintian tag. Laziness to fix your crap is NOT A GOOD REASON, sod off" % (epackage))
+
     ###########################################################################
     def check_urgency(self):
         cnf = Config()
index 00896243e025152bde31f8faeed3b98d4aac061c..cc5d1be6873de251852e92b0e85d8e1a7900f3e1 100755 (executable)
@@ -112,3 +112,4 @@ re_user_mails = re.compile(r"^(pub|uid):[^rdin].*<(.*@.*)>.*$", re.MULTILINE);
 re_user_name = re.compile(r"^pub:.*:(.*)<.*$", re.MULTILINE);
 re_re_mark = re.compile(r'^RE:')
 
+re_parse_lintian = re.compile(r"^(W|E|O): (.*?): (.*?) (.*)$")
index 32fd4c1d9e69604903f47b50bc5a3260e0c9d987..2f8fed1e87af2076b065e5e7c4c40f94d3243153 100755 (executable)
@@ -32,5 +32,14 @@ class re_single_line_field(unittest.TestCase):
         self.assertEqual(self.MATCH('Foo::bar').groups(), ('Foo', ':bar'))
         self.assertEqual(self.MATCH('Foo: :bar').groups(), ('Foo', ':bar'))
 
+class re_parse_lintian(unittest.TestCase):
+    MATCH = regexes.re_parse_lintian.match
+
+    def testSimple(self):
+        self.assertEqual(
+            self.MATCH('W: tzdata: binary-without-manpage usr/sbin/tzconfig').groups(),
+            ('W', 'tzdata', 'binary-without-manpage', 'usr/sbin/tzconfig')
+        )
+
 if __name__ == '__main__':
     unittest.main()