ALCConfig.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. # vim:set fileencoding=utf-8 et ts=4 sts=4 sw=4:
  2. #
  3. # apt-listchanges - Show changelog entries between the installed versions
  4. # of a set of packages and the versions contained in
  5. # corresponding .deb files
  6. #
  7. # Copyright (C) 2000-2006 Matt Zimmerman <mdz@debian.org>
  8. # Copyright (C) 2006 Pierre Habouzit <madcoder@debian.org>
  9. #
  10. # This program is free software; you can redistribute it and/or modify
  11. # it under the terms of the GNU General Public License as published by
  12. # the Free Software Foundation; either version 2 of the License, or
  13. # (at your option) any later version.
  14. #
  15. # This program is distributed in the hope that it will be useful,
  16. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. # GNU General Public License for more details.
  19. #
  20. # You should have received a copy of the GNU General Public
  21. # License along with this program; if not, write to the Free
  22. # Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23. # MA 02111-1307 USA
  24. #
  25. import configparser
  26. import getopt
  27. import sys, os
  28. import re
  29. import ALCLog
  30. from ALChacks import *
  31. class ALCConfig:
  32. def __init__(self):
  33. # Defaults
  34. self.frontend = 'pager'
  35. self.email_address = None
  36. self.email_format = 'text'
  37. self.allowed_email_formats = ('text', 'html')
  38. self.verbose = False
  39. self.quiet = 0
  40. self.show_all = False
  41. self.confirm = False
  42. self.headers = False
  43. self.debug = False
  44. self.save_seen = None
  45. self.dump_seen = False
  46. self.apt_mode = False
  47. self.profile = None
  48. self.which = 'both'
  49. self.allowed_which = ('both', 'news', 'changelogs')
  50. self.since = None
  51. self.reverse = False
  52. self.select_frontend = False
  53. self.ignore_apt_assume = False
  54. self.ignore_debian_frontend = False
  55. # Config file options, used also for command line parameters
  56. # (after replacing '_' with '-', and adding trailing '=' if needed)
  57. self._bool_opts = ['confirm', 'debug', 'show_all', 'headers', 'verbose', 'reverse',
  58. 'dump_seen', 'select_frontend',
  59. 'ignore_apt_assume', 'ignore_debian_frontend']
  60. self._value_opts = ['frontend', 'email_address', 'email_format', 'save_seen', 'since', 'which']
  61. self._cfgfile_only_opts = ['browser', 'pager', 'xterm']
  62. def read(self, file):
  63. self.parser = configparser.ConfigParser()
  64. self.parser.read(file)
  65. def expose(self):
  66. if self.parser.has_section(self.profile):
  67. for option in self.parser.options(self.profile):
  68. value = None
  69. if self.parser.has_option(self.profile, option):
  70. if option in self._bool_opts:
  71. value = self.parser.getboolean(self.profile, option)
  72. elif option in self._value_opts or option in self._cfgfile_only_opts:
  73. value = self.parser.get(self.profile, option)
  74. else:
  75. ALCLog.warning(_("Unknown configuration file option: %s") % option)
  76. continue
  77. setattr(self, option, value)
  78. def get(self, option, defvalue=None):
  79. return getattr(self, option, defvalue)
  80. def usage(self, exitcode):
  81. if exitcode == 0:
  82. fh = sys.stdout
  83. else:
  84. fh = sys.stderr
  85. fh.write(_("Usage: apt-listchanges [options] {--apt | filename.deb ...}\n"))
  86. sys.exit(exitcode)
  87. def _check_allowed(self, arg, opt, allowed):
  88. if arg in allowed:
  89. return arg
  90. ALCLog.error((_('Unknown argument %(arg)s for option %(opt)s. Allowed are: %(allowed)s.') %
  91. {'arg': arg, 'opt': opt, 'allowed': ', '.join(allowed)}))
  92. sys.exit(1)
  93. def _check_debs(self, debs):
  94. if self.apt_mode or self.dump_seen:
  95. return
  96. if (debs == None or len(debs) == 0):
  97. self.usage(1);
  98. for deb in debs:
  99. ext = os.path.splitext(deb)[1]
  100. if ext != ".deb":
  101. ALCLog.error(_("%(deb)s does not have '.deb' extension") % {'deb': deb})
  102. sys.exit(1)
  103. if not os.path.isfile(deb):
  104. ALCLog.error(_('%(deb)s does not exist or is not a file') % {'deb': deb})
  105. sys.exit(1)
  106. if not os.access(deb, os.R_OK):
  107. ALCLog.error(_('%(deb)s is not readable') % {'deb' : deb})
  108. sys.exit(1)
  109. def getopt(self, argv):
  110. try:
  111. (optlist, args) = getopt.getopt(argv[1:], 'vf:s:cah', [
  112. # command line only
  113. "apt", "profile=", "help",
  114. # deprecated options for backward compatibility
  115. "all", "save_seen=" ]
  116. # boolean options
  117. + [ x.replace('_', '-') for x in self._bool_opts ]
  118. # with value options
  119. + [ x.replace('_', '-')+'=' for x in self._value_opts ]
  120. )
  121. except getopt.GetoptError as err:
  122. ALCLog.error(str(err))
  123. sys.exit(1)
  124. # Determine mode and profile before processing other options
  125. for opt, arg in optlist:
  126. if opt == '--profile':
  127. self.profile = arg
  128. elif opt == '--apt':
  129. self.apt_mode = True
  130. # Provide a default profile if none has been specified
  131. if self.profile is None:
  132. if self.apt_mode:
  133. self.profile = 'apt'
  134. else:
  135. self.profile = 'cmdline'
  136. # Expose defaults from config file
  137. self.expose()
  138. # Environment variables override config file
  139. if 'APT_LISTCHANGES_FRONTEND' in os.environ:
  140. self.frontend = os.getenv('APT_LISTCHANGES_FRONTEND')
  141. # Prefer APT_LISTCHANGES_FRONTEND over DEBIAN_FRONTEND
  142. self.ignore_debian_frontend = True
  143. # Command-line options override environment and config file
  144. for opt, arg in optlist:
  145. if opt == '--help':
  146. self.usage(0)
  147. elif opt in ('-v', '--verbose'):
  148. self.verbose = True
  149. elif opt in ('-f', '--frontend'):
  150. self.frontend = arg
  151. elif opt == '--email-address':
  152. self.email_address = arg
  153. elif opt == '--email-format':
  154. self.email_format = self._check_allowed(arg, opt, self.allowed_email_formats)
  155. elif opt in ('-c', '--confirm'):
  156. self.confirm = True
  157. elif opt in ('--since'):
  158. self.since = arg
  159. elif opt in ('-a', '--show-all', '--all'):
  160. self.show_all = True
  161. elif opt in ('-h', '--headers'):
  162. self.headers = True
  163. elif opt in ('--save-seen', '--save_seen'):
  164. self.save_seen = arg
  165. elif opt == '--dump-seen':
  166. self.dump_seen = True
  167. elif opt == '--which':
  168. self.which = self._check_allowed(arg, opt, self.allowed_which)
  169. elif opt == '--debug':
  170. self.debug = True
  171. elif opt == '--reverse':
  172. self.reverse = True
  173. elif opt == '--select-frontend':
  174. self.select_frontend = True
  175. elif opt == '--ignore-apt-assume':
  176. self.ignore_apt_assume = True
  177. elif opt == '--ignore-debian-frontend':
  178. self.ignore_debian_frontend = True
  179. if self.email_address == 'none':
  180. self.email_address = None
  181. if self.save_seen == 'none':
  182. self.save_seen = None
  183. if self.since is not None:
  184. if len(args) is not 1:
  185. self.stderr.write(_('--since=<version> expects a only path to a .deb') + "\n")
  186. sys.exit(1)
  187. self.save_seen = None
  188. if (self.apt_mode and not self.ignore_debian_frontend and
  189. os.getenv('DEBIAN_FRONTEND', '') == 'noninteractive'):
  190. # Force non-interactive usage
  191. self.quiet = 1
  192. self.confirm = False
  193. self._check_debs(args)
  194. return args
  195. __all__ = [ 'ALCConfig' ]