lintian.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. """ Utility functions for lintian checks in dak
  2. @contact: Debian FTPMaster <ftpmaster@debian.org>
  3. @copyright: 2009, 2010 Joerg Jaspert <joerg@debian.org>
  4. @copyright: 2009 Chris Lamb <lamby@debian.org>
  5. @license: GNU General Public License version 2 or later
  6. """
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. ################################################################################
  19. # <mhy> I often wonder if we should use NSA bot or something instead and get dinstall
  20. # to send emails telling us about its progress :-)
  21. # <mhy> dinstall: I'm processing openoffice
  22. # <mhy> dinstall: I'm choking, please help me
  23. # <Ganneff> yeah. get floods in here, for 600 accepted packages.
  24. # <mhy> hehe
  25. # <Ganneff> im not sure the other opers will like it if i oper up the bot, just so it
  26. # can flood faster
  27. # <mhy> flood all debian related channels
  28. # <mhy> just to be safe
  29. # <Ganneff> /msg #debian-* dinstall: starting
  30. # <Ganneff> more interesting would be the first message in #debian, the next in
  31. # #d-devel, then #d-qa
  32. # <Ganneff> and expect people to monitor all.
  33. # <Ganneff> i bet we have enough debian channels to at least put the timestamps in
  34. # seperate channels each
  35. # <Ganneff> and if not - we can make it go multi-network
  36. # <Ganneff> first oftc, then opn, then ircnet, then - we will find some. quakenet anyone?
  37. # <mhy> I should know better than to give you ideas
  38. ################################################################################
  39. from collections.abc import Iterable
  40. from .regexes import re_parse_lintian
  41. def parse_lintian_output(output: str) -> Iterable[dict]:
  42. """
  43. Parses Lintian output and returns a generator with the data.
  44. >>> list(parse_lintian_output('W: pkgname: some-tag path/to/file'))
  45. [('W', 'pkgname', 'some-tag', 'path/to/file')]
  46. :param output: The output from lintian
  47. """
  48. return (
  49. m.groupdict()
  50. for line in output.split('\n')
  51. if (m := re_parse_lintian.match(line))
  52. )
  53. def generate_reject_messages(parsed_tags, tag_definitions, log=lambda *args: args) -> Iterable[str]:
  54. """
  55. Generates package reject messages by comparing parsed lintian output with
  56. tag definitions. Returns a generator containing the reject messages.
  57. :param parsed_tags: Parsed lintian tags as returned by :func:`parse_lintian_output`
  58. :param tag_definitions: YAML.load lintian tag definitions to reject on
  59. :return: Reject message(s), if any
  60. """
  61. tags = set()
  62. for values in tag_definitions.values():
  63. for tag_name in values:
  64. tags.add(tag_name)
  65. for tag in parsed_tags:
  66. tag_name = tag['tag']
  67. if tag_name not in tags:
  68. continue
  69. # Was tag overridden?
  70. if tag['level'] == 'O':
  71. if tag_name in tag_definitions['nonfatal']:
  72. # Overriding this tag is allowed.
  73. pass
  74. elif tag_name in tag_definitions['fatal']:
  75. # Overriding this tag is NOT allowed.
  76. log('ftpmaster does not allow tag to be overridable', tag_name)
  77. yield "%(package)s: Overriden tag %(tag)s found, but this " \
  78. "tag may not be overridden." % tag
  79. else:
  80. # Tag is known and not overridden; reject
  81. yield "%(package)s: lintian output: '%(tag)s %(description)s', " \
  82. "automatically rejected package." % tag
  83. # Now tell if they *might* override it.
  84. if tag_name in tag_definitions['nonfatal']:
  85. log("auto rejecting", "overridable", tag_name)
  86. yield "%(package)s: If you have a good reason, you may " \
  87. "override this lintian tag." % tag
  88. else:
  89. log("auto rejecting", "not overridable", tag_name)