From: Joerg Jaspert Date: Tue, 27 Oct 2009 20:46:42 +0000 (+0100) Subject: Merge branch 'merge' X-Git-Url: https://git.decadent.org.uk/gitweb/?a=commitdiff_plain;h=33ea37c1644023626800361a2bf76972c8d9da11;hp=3dce096cd80a3f2b0535523490afc4360b4b9983;p=dak.git Merge branch 'merge' * merge: Disable check_lintian for now. Only lintian reject uploads to unstable or experimental Fix use of "wayout" name. dict[k] raises IndexError if does not exist - check with infix 'in' instead. Actually add a seperator to our --tags-from-file input. lintian YAML has a "lintian" root element. Close sourcefile. Dedent again by returning if lintian doesn't return any content. Return all the lintian-related rejections, not just the first one. It's called 'next', not 'continue'. =) Dedent again by using continue. Remove one level of indentation by using continue Simple check for lintian regex Use set() instead of Perlesque hash[key] = 1 autoreject Add lintian tags file --- diff --git a/config/debian/dak.conf b/config/debian/dak.conf index 474a4f3d..b254a7ad 100644 --- a/config/debian/dak.conf +++ b/config/debian/dak.conf @@ -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 index 00000000..1c05410c --- /dev/null +++ b/config/debian/lintian.tags @@ -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 diff --git a/dak/process_unchecked.py b/dak/process_unchecked.py index 856c1dfa..0645dd9f 100755 --- a/dak/process_unchecked.py +++ b/dak/process_unchecked.py @@ -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() diff --git a/daklib/queue.py b/daklib/queue.py index 9540ee16..b3247ee1 100755 --- a/daklib/queue.py +++ b/daklib/queue.py @@ -39,6 +39,7 @@ import utils import commands import shutil import textwrap +import tempfile from types import * import yaml @@ -1195,6 +1196,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() diff --git a/daklib/regexes.py b/daklib/regexes.py index 00896243..cc5d1be6 100755 --- a/daklib/regexes.py +++ b/daklib/regexes.py @@ -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): (.*?): (.*?) (.*)$") diff --git a/tests/test_regexes.py b/tests/test_regexes.py index 32fd4c1d..2f8fed1e 100755 --- a/tests/test_regexes.py +++ b/tests/test_regexes.py @@ -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()