diff options
Diffstat (limited to 'gbp/config.py')
-rw-r--r-- | gbp/config.py | 739 |
1 files changed, 426 insertions, 313 deletions
diff --git a/gbp/config.py b/gbp/config.py index 3d254eee..f1f71767 100644 --- a/gbp/config.py +++ b/gbp/config.py @@ -1,6 +1,6 @@ -# vim: set fileencoding=utf-8 : +# vim: set fileencoding=utf-8: # -# (C) 2006,2007,2010-2012,2015 Guido Guenther <agx@sigxcpu.org> +# (C) 2006,2007,2010-2012,2015,2016 Guido Guenther <agx@sigxcpu.org> # 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 # the Free Software Foundation; either version 2 of the License, or @@ -23,6 +23,7 @@ import errno import os.path import sys +from gbp.errors import GbpError try: from gbp.version import gbp_version @@ -38,10 +39,12 @@ file:///usr/share/doc/git-buildpackage/manual-html/gbp.import.html#GBP.IMPORT.CO on howto create it otherwise use --upstream-branch to specify it. """ + def expand_path(option, opt, value): value = os.path.expandvars(value) return os.path.expanduser(value) + def check_tristate(option, opt, value): try: val = gbp.tristate.Tristate(value) @@ -52,14 +55,16 @@ def check_tristate(option, opt, value): return val -def safe_option(f): +def save_option(f): + """save options on the underlying parser""" def _decorator(self, *args, **kwargs): obj = self option_name = kwargs.get('option_name') if not option_name and len(args): option_name = args[0] - # We're decorating GbpOption not GbpOptionParser + # We're decorating GbpOption but store valid_options on + # GbpOptionParser if not hasattr(obj, 'valid_options'): if not hasattr(obj, 'parser'): raise ValueError("Can only decorete GbpOptionParser and GbpOptionGroup not %s" % obj) @@ -78,6 +83,7 @@ class GbpOption(Option): TYPE_CHECKER['path'] = expand_path TYPE_CHECKER['tristate'] = check_tristate + class GbpOptionParser(OptionParser): """ Handles commandline options and parsing of config files @@ -95,248 +101,272 @@ class GbpOptionParser(OptionParser): @cvar def_config_files: config files we parse @type def_config_files: dict (type, path) """ - defaults = { 'debian-branch' : 'master', - 'upstream-branch' : 'upstream', - 'upstream-tree' : 'TAG', - 'pristine-tar' : 'False', - 'pristine-tar-commit': 'False', - 'filter-pristine-tar' : 'False', - 'sign-tags' : 'False', - 'force-create' : 'False', - 'no-create-orig' : 'False', - 'cleaner' : '/bin/true', - 'keyid' : '', - 'posttag' : '', - 'postbuild' : '', - 'prebuild' : '', - 'postexport' : '', - 'postimport' : '', - 'hooks' : 'True', - 'debian-tag' : 'debian/%(version)s', - 'debian-tag-msg' : '%(pkg)s Debian release %(version)s', - 'upstream-tag' : 'upstream/%(version)s', - 'import-msg' : 'Imported Upstream version %(version)s', - 'commit-msg' : 'Update changelog for %(version)s release', - 'filter' : [], - 'snapshot-number' : 'snapshot + 1', - 'git-log' : '--no-merges', - 'export' : 'HEAD', - 'export-dir' : '', - 'overlay' : 'False', - 'tarball-dir' : '', - 'ignore-new' : 'False', - 'ignore-branch' : 'False', - 'meta' : 'True', - 'meta-closes' : 'Closes|LP', - 'meta-closes-bugnum' : r'(?:bug|issue)?\#?\s?\d+', - 'full' : 'False', - 'id-length' : '0', - 'git-author' : 'False', - 'ignore-regex' : '', - 'compression' : 'auto', - 'compression-level': '9', - 'remote-url-pattern' : 'ssh://git.debian.org/git/collab-maint/%(pkg)s.git', - 'multimaint' : 'True', - 'multimaint-merge': 'False', - 'pbuilder' : 'False', - 'qemubuilder' : 'False', - 'dist' : 'sid', - 'arch' : '', - 'interactive' : 'True', - 'color' : 'auto', - 'color-scheme' : '', - 'customizations' : '', - 'spawn-editor' : 'release', - 'patch-numbers' : 'True', - 'patch-num-format': '%04d-', - 'renumber' : 'False', - 'notify' : 'auto', - 'merge' : 'True', - 'merge-mode' : 'merge', - 'track' : 'True', - 'author-is-committer': 'False', - 'author-date-is-committer-date': 'False', - 'create-missing-branches': 'False', - 'submodules' : 'False', - 'time-machine' : 1, - 'pbuilder-autoconf' : 'True', - 'pbuilder-options': '', - 'template-dir': '', - 'remote-config': '', - 'allow-unauthenticated': 'False', - 'symlink-orig': 'True', - 'purge': 'True', - 'drop': 'False', - 'commit': 'False', - 'upstream-vcs-tag': '', - } + defaults = {'debian-branch': 'master', + 'upstream-branch': 'upstream', + 'upstream-tree': 'TAG', + 'pq-from': 'DEBIAN', + 'pristine-tar': 'False', + 'pristine-tar-commit': 'False', + 'filter-pristine-tar': 'False', + 'sign-tags': 'False', + 'force-create': 'False', + 'no-create-orig': 'False', + 'cleaner': '/bin/true', + 'keyid': '', + 'posttag': '', + 'postbuild': '', + 'prebuild': '', + 'postclone': '', + 'postexport': '', + 'postimport': '', + 'hooks': 'True', + 'debian-tag': 'debian/%(version)s', + 'debian-tag-msg': '%(pkg)s Debian release %(version)s', + 'upstream-tag': 'upstream/%(version)s', + 'import-msg': 'New upstream version %(version)s', + 'commit-msg': 'Update changelog for %(version)s release', + 'filter': [], + 'snapshot-number': 'snapshot + 1', + 'git-log': '--no-merges', + 'export': 'HEAD', + 'export-dir': '', + 'overlay': 'False', + 'tarball-dir': '', + 'ignore-new': 'False', + 'ignore-branch': 'False', + 'meta': 'True', + 'meta-closes': 'Closes|LP', + 'meta-closes-bugnum': r'(?:bug|issue)?\#?\s?\d+', + 'full': 'False', + 'id-length': '0', + 'git-author': 'False', + 'ignore-regex': '', + 'compression': 'auto', + 'compression-level': '9', + 'remote-url-pattern': 'ssh://git.debian.org/git/collab-maint/%(pkg)s.git', + 'multimaint': 'True', + 'multimaint-merge': 'False', + 'pbuilder': 'False', + 'qemubuilder': 'False', + 'dist': 'sid', + 'arch': '', + 'interactive': 'True', + 'color': 'auto', + 'color-scheme': '', + 'customizations': '', + 'spawn-editor': 'release', + 'patch-numbers': 'True', + 'patch-num-format': '%04d-', + 'renumber': 'False', + 'notify': 'auto', + 'merge': 'True', + 'merge-mode': 'merge', + 'track': 'True', + 'author-is-committer': 'False', + 'author-date-is-committer-date': 'False', + 'create-missing-branches': 'False', + 'submodules': 'False', + 'time-machine': 1, + 'pbuilder-autoconf': 'True', + 'pbuilder-options': '', + 'template-dir': '', + 'remote-config': '', + 'allow-unauthenticated': 'False', + 'symlink-orig': 'True', + 'purge': 'True', + 'drop': 'False', + 'commit': 'False', + 'upstream-vcs-tag': '', + 'rollback': 'True', + 'component': [], + 'bare': 'True', + 'urgency': 'medium', + } help = { - 'debian-branch': - ("Branch the Debian package is being developed on, " - "default is '%(debian-branch)s'"), - 'upstream-branch': - "Upstream branch, default is '%(upstream-branch)s'", - 'upstream-tree': - ("Where to generate the upstream tarball from " - "(tag or branch), default is '%(upstream-tree)s'"), - 'debian-tag': - ("Format string for debian tags, " - "default is '%(debian-tag)s'"), - 'debian-tag-msg': - ("Format string for signed debian-tag messages, " - "default is '%(debian-tag-msg)s'"), - 'upstream-tag': - ("Format string for upstream tags, " - "default is '%(upstream-tag)s'"), - 'sign-tags': - "Whether to sign tags, default is '%(sign-tags)s'", - 'keyid': - "GPG keyid to sign tags with, default is '%(keyid)s'", - 'import-msg': - ("Format string for commit message used to commit " - "the upstream tarball, default is '%(import-msg)s'"), - 'commit-msg': - ("Format string for commit messag used to commit, " - "the changelog, default is '%(commit-msg)s'"), - 'pristine-tar': - ("Use pristine-tar to create orig tarball, " - "default is '%(pristine-tar)s'"), - 'pristine-tar-commit': - ("When generating a tarball commit it to the pristine-tar branch '%(pristine-tar-commit)s' " - "default is '%(pristine-tar-commit)s'"), - 'filter-pristine-tar': - "Filter pristine-tar when filter option is used, default is '%(filter-pristine-tar)s'", - 'filter': - "Files to filter out during import (can be given multiple times), default is %(filter)s", - 'git-author': - "Use name and email from git-config for changelog trailer, default is '%(git-author)s'", - 'full': - "Include the full commit message instead of only the first line, default is '%(full)s'", - 'meta': - "Parse meta tags in commit messages, default is '%(meta)s'", - 'meta-closes': - "Meta tags for the bts close commands, default is '%(meta-closes)s'", - 'meta-closes-bugnum': - "Meta bug number format, default is '%(meta-closes-bugnum)s'", - 'ignore-new': - "Build with uncommited changes in the source tree, default is '%(ignore-new)s'", - 'ignore-branch': - ("Build although debian-branch != current branch, " - "default is '%(ignore-branch)s'"), - 'overlay': - ("extract orig tarball when using export-dir option, " - "default is '%(overlay)s'"), - 'remote-url-pattern': - ("Remote url pattern to create the repo at, " - "default is '%(remote-url-pattern)s'"), - 'multimaint': - "Note multiple maintainers, default is '%(multimaint)s'", - 'multimaint-merge': - ("Merge commits by maintainer, " - "default is '%(multimaint-merge)s'"), - 'pbuilder': - ("Invoke git-pbuilder for building, " - "default is '%(pbuilder)s'"), - 'dist': - ("Build for this distribution when using git-pbuilder, " - "default is '%(dist)s'"), - 'arch': - ("Build for this architecture when using git-pbuilder, " - "default is '%(arch)s'"), - 'qemubuilder': - ("Invoke git-pbuilder with qemubuilder for building, " - "default is '%(qemubuilder)s'"), - 'interactive': - "Run command interactively, default is '%(interactive)s'", - 'color': - "Whether to use colored output, default is '%(color)s'", - 'color-scheme': - ("Colors to use in output (when color is enabled), format " - "is '<debug>:<info>:<warning>:<error>', e.g. " - "'cyan:34::'. Numerical values and color names are " - "accepted, empty fields indicate using the default."), - 'spawn-editor': - ("Whether to spawn an editor after adding the " - "changelog entry, default is '%(spawn-editor)s'"), - 'patch-numbers': - ("Whether to number patch files, " - "default is %(patch-numbers)s"), - 'patch-num-format': - ("The format specifier for patch number prefixes, " - "default is %(patch-num-format)s"), - 'renumber': - ("Whether to renumber patches exported from patch queues, " - "instead of preserving the number specified in " - "'Gbp-Pq: Name' tags, default is %(renumber)s"), - 'notify': - ("Whether to send a desktop notification after the build, " - "default is '%(notify)s'"), - 'merge': - ("After the import merge the result to the debian branch, " - "default is '%(merge)s'"), - 'merge-mode': - ("Howto merge the new upstream sources onto the debian branch" - "default is '%(merge-mode)s'"), - 'track': - ("Set up tracking for remote branches, " - "default is '%(track)s'"), - 'author-is-committer': - ("Use the authors's name also as the committer's name, " - "default is '%(author-is-committer)s'"), - 'author-date-is-committer-date': - ("Use the authors's date as the committer's date, " - "default is '%(author-date-is-committer-date)s'"), - 'create-missing-branches': - ("Create missing branches automatically, " - "default is '%(create-missing-branches)s'"), - 'submodules': - ("Transparently handle submodules in the upstream tree, " - "default is '%(submodules)s'"), - 'postimport': - ("hook run after a successful import, " - "default is '%(postimport)s'"), - 'hooks': - ("Enable running all hooks, default is %(hooks)s"), - 'time-machine': - ("don't try head commit only to apply the patch queue " - "but look TIME_MACHINE commits back, " - "default is '%(time-machine)d'"), - 'pbuilder-autoconf': - ("Wheter to configure pbuilder automatically, " - "default is '%(pbuilder-autoconf)s'"), - 'pbuilder-options': - ("Options to pass to pbuilder, " - "default is '%(pbuilder-options)s'"), - 'template-dir': - ("Template directory used by git init, " - "default is '%(template-dir)s'"), - 'remote-config': - ("Remote defintion in gbp.conf used to create the remote " - "repository, default is '%(remote-config)s'"), - 'allow-unauthenticated': - ("Don't verify integrity of downloaded source, " - "default is '%(allow-unauthenticated)s'"), - 'symlink-orig': - ("Whether to creat a symlink from the upstream tarball " - "to the orig.tar.gz if needed, default is " - "'%(symlink-orig)s'"), - 'purge': - "Purge exported package build directory. Default is '%(purge)s'", - 'drop': - ("In case of 'export' drop the patch-queue branch " - "after export. Default is '%(drop)s'"), - 'commit': - "commit changes after export, Default is '%(commit)s'", - } - - def_config_files = {'/etc/git-buildpackage/gbp.conf': 'system', - '~/.gbp.conf': 'global', - '%(top_dir)s/.gbp.conf': None, - '%(top_dir)s/debian/gbp.conf': 'debian', - '%(git_dir)s/gbp.conf': None} + 'debian-branch': + "Branch the Debian package is being developed on, " + "default is '%(debian-branch)s'", + 'upstream-branch': + "Upstream branch, default is '%(upstream-branch)s'", + 'upstream-tree': + "Where to generate the upstream tarball from " + "(tag or branch), default is '%(upstream-tree)s'", + 'pq-from': + "How to find the patch queue base. DEBIAN or TAG, " + "the default is '%(pq-from)s'", + 'debian-tag': + "Format string for debian tags, " + "default is '%(debian-tag)s'", + 'debian-tag-msg': + "Format string for signed debian-tag messages, " + "default is '%(debian-tag-msg)s'", + 'upstream-tag': + "Format string for upstream tags, " + "default is '%(upstream-tag)s'", + 'sign-tags': + "Whether to sign tags, default is '%(sign-tags)s'", + 'keyid': + "GPG keyid to sign tags with, default is '%(keyid)s'", + 'import-msg': + "Format string for commit message used to commit " + "the upstream tarball, default is '%(import-msg)s'", + 'commit-msg': + "Format string for commit messag used to commit, " + "the changelog, default is '%(commit-msg)s'", + 'pristine-tar': + "Use pristine-tar to create orig tarball, " + "default is '%(pristine-tar)s'", + 'pristine-tar-commit': + "When generating a tarball commit it to the pristine-tar branch '%(pristine-tar-commit)s' " + "default is '%(pristine-tar-commit)s'", + 'filter-pristine-tar': + "Filter pristine-tar when filter option is used, default is '%(filter-pristine-tar)s'", + 'filter': + "Files to filter out during import (can be given multiple times), default is %(filter)s", + 'git-author': + "Use name and email from git-config for changelog trailer, default is '%(git-author)s'", + 'full': + "Include the full commit message instead of only the first line, default is '%(full)s'", + 'meta': + "Parse meta tags in commit messages, default is '%(meta)s'", + 'meta-closes': + "Meta tags for the bts close commands, default is '%(meta-closes)s'", + 'meta-closes-bugnum': + "Meta bug number format, default is '%(meta-closes-bugnum)s'", + 'ignore-new': + "Build with uncommitted changes in the source tree, default is '%(ignore-new)s'", + 'ignore-branch': + "Build although debian-branch != current branch, " + "default is '%(ignore-branch)s'", + 'overlay': + "extract orig tarball when using export-dir option, " + "default is '%(overlay)s'", + 'remote-url-pattern': + "Remote url pattern to create the repo at, " + "default is '%(remote-url-pattern)s'", + 'multimaint': + "Note multiple maintainers, default is '%(multimaint)s'", + 'multimaint-merge': + "Merge commits by maintainer, " + "default is '%(multimaint-merge)s'", + 'pbuilder': + "Invoke git-pbuilder for building, " + "default is '%(pbuilder)s'", + 'dist': + "Build for this distribution when using git-pbuilder, " + "default is '%(dist)s'", + 'arch': + "Build for this architecture when using git-pbuilder, " + "default is '%(arch)s'", + 'qemubuilder': + "Invoke git-pbuilder with qemubuilder for building, " + "default is '%(qemubuilder)s'", + 'interactive': + "Run command interactively, default is '%(interactive)s'", + 'color': + "Whether to use colored output, default is '%(color)s'", + 'color-scheme': + "Colors to use in output (when color is enabled), format " + "is '<debug>:<info>:<warning>:<error>', e.g. " + "'cyan:34::'. Numerical values and color names are " + "accepted, empty fields indicate using the default.", + 'spawn-editor': + "Whether to spawn an editor after adding the " + "changelog entry, default is '%(spawn-editor)s'", + 'patch-numbers': + "Whether to number patch files, " + "default is %(patch-numbers)s", + 'patch-num-format': + "The format specifier for patch number prefixes, " + "default is %(patch-num-format)s", + 'renumber': + "Whether to renumber patches exported from patch queues, " + "instead of preserving the number specified in " + "'Gbp-Pq: Name' tags, default is %(renumber)s", + 'notify': + "Whether to send a desktop notification after the build, " + "default is '%(notify)s'", + 'merge': + "After the import merge the result to the debian branch, " + "default is '%(merge)s'", + 'merge-mode': + "Howto merge the new upstream sources onto the debian branch" + "default is '%(merge-mode)s'", + 'track': + "Set up tracking for remote branches, " + "default is '%(track)s'", + 'author-is-committer': + "Use the authors's name also as the committer's name, " + "default is '%(author-is-committer)s'", + 'author-date-is-committer-date': + "Use the authors's date as the committer's date, " + "default is '%(author-date-is-committer-date)s'", + 'create-missing-branches': + "Create missing branches automatically, " + "default is '%(create-missing-branches)s'", + 'submodules': + "Transparently handle submodules in the upstream tree, " + "default is '%(submodules)s'", + 'postimport': + "hook run after a successful import, " + "default is '%(postimport)s'", + 'hooks': + "Enable running all hooks, default is %(hooks)s", + 'time-machine': + "don't try head commit only to apply the patch queue " + "but look TIME_MACHINE commits back, " + "default is '%(time-machine)d'", + 'pbuilder-autoconf': + "Whether to configure pbuilder automatically, " + "default is '%(pbuilder-autoconf)s'", + 'pbuilder-options': + "Options to pass to pbuilder, " + "default is '%(pbuilder-options)s'", + 'template-dir': + "Template directory used by git init, " + "default is '%(template-dir)s'", + 'remote-config': + "Remote defintion in gbp.conf used to create the remote " + "repository, default is '%(remote-config)s'", + 'allow-unauthenticated': + "Don't verify integrity of downloaded source, " + "default is '%(allow-unauthenticated)s'", + 'symlink-orig': + "Whether to creat a symlink from the upstream tarball " + "to the orig.tar.gz if needed, default is " + "'%(symlink-orig)s'", + 'purge': + "Purge exported package build directory. Default is '%(purge)s'", + 'drop': + "In case of 'export' drop the patch-queue branch " + "after export. Default is '%(drop)s'", + 'commit': + "commit changes after export, Default is '%(commit)s'", + 'rollback': + "Rollback repository changes when encountering an error", + 'component': + 'component name for additional tarballs', + 'bare': + "wether to create a bare repository on the remote side. " + "'Default is '%(bare)s'.", + 'urgency': + "Set urgency level, default is '%(urgency)s'" + } + + short_opts = { + 'urgency': '-U', + } + + def_config_files = [('/etc/git-buildpackage/gbp.conf', 'system'), + ('~/.gbp.conf', 'global'), + ('%(top_dir)s/.gbp.conf', None), + ('%(top_dir)s/debian/gbp.conf', 'debian'), + ('%(git_dir)s/gbp.conf', None)] + + list_opts = ['filter', 'component'] @classmethod - def get_config_files(klass, no_local=False): + def get_config_files(cls, no_local=False): """ Get list of config files from the I{GBP_CONF_FILES} environment variable. @@ -364,7 +394,7 @@ class GbpOptionParser(OptionParser): >>> if conf_backup is not None: os.environ['GBP_CONF_FILES'] = conf_backup """ envvar = os.environ.get('GBP_CONF_FILES') - files = envvar.split(':') if envvar else klass.def_config_files.keys() + files = envvar.split(':') if envvar else [f for (f, _) in cls.def_config_files] files = [os.path.expanduser(fname) for fname in files] if no_local: files = [fname for fname in files if fname.startswith('/')] @@ -382,6 +412,10 @@ class GbpOptionParser(OptionParser): except KeyError: # Skip if filename wasn't expanded, i.e. we're not in git repo return + if (repo and + filename == os.path.join(repo.path, '.gbp.conf') and + os.path.exists(filename)): + self._warn_old_gbp_conf(filename) parser.read(filename) def _warn_old_config_section(self, oldcmd, cmd): @@ -389,6 +423,57 @@ class GbpOptionParser(OptionParser): gbp.log.warn("Old style config section [%s] found " "please rename to [%s]" % (oldcmd, cmd)) + def _warn_old_gbp_conf(self, gbp_conf): + if (not os.getenv("GBP_DISABLE_GBP_CONF_DEPRECTATION") and + not self._warned_old_gbp_conf): + gbp.log.warn("Deprecated configuration file found at %s, " + "check gbp.conf(5) for alternatives" % gbp_conf) + self._warned_old_gbp_conf = True + + @staticmethod + def _listify(value): + """ + >>> GbpOptionParser._listify(None) + [] + >>> GbpOptionParser._listify('string') + ['string'] + >>> GbpOptionParser._listify('["q", "e", "d"] ') + ['q', 'e', 'd'] + >>> GbpOptionParser._listify('[') + Traceback (most recent call last): + ... + Error: [ is not a proper list + """ + # filter can be either a list or a string, always build a list: + if value: + if value.startswith('['): + try: + return eval(value) + except SyntaxError: + raise configparser.Error("%s is not a proper list" % value) + else: + return [value] + else: + return [] + + def parse_lists(self): + """ + Parse options that can be given as lists + + Since they take multiple arguments they can also be given in plural form + e.g. components instead of component. + """ + for opt in self.list_opts: + try: + plural_opt = opt + 's' + valp = self._listify(self.config.get(plural_opt, None)) + vals = self._listify(self.config[opt]) + if valp and vals: + raise configparser.Error("Found %s and %s - use only one" % (valp, vals)) + self.config[opt] = valp or vals + except ValueError: + raise configparser.Error("Failed to parse %s: %s" % (opt, self.config[opt])) + def parse_config_files(self): """ Parse the possible config files and set appropriate values @@ -412,7 +497,7 @@ class GbpOptionParser(OptionParser): # Make sure we read any legacy sections prior to the real subcommands # section i.e. read [gbp-pull] prior to [pull] if (self.command.startswith('gbp-') or - self.command.startswith('git-')): + self.command.startswith('git-')): cmd = self.command[4:] oldcmd = self.command if parser.has_section(oldcmd): @@ -437,16 +522,9 @@ class GbpOptionParser(OptionParser): self.config.update(dict(parser._sections[section].items())) else: raise configparser.NoSectionError( - "Mandatory section [%s] does not exist." % section) + "Mandatory section [%s] does not exist." % section) - # filter can be either a list or a string, always build a list: - if self.config['filter']: - if self.config['filter'].startswith('['): - self.config['filter'] = eval(self.config['filter']) - else: - self.config['filter'] = [ self.config['filter'] ] - else: - self.config['filter'] = [] + self.parse_lists() def __init__(self, command, prefix='', usage=None, sections=[]): """ @@ -464,15 +542,16 @@ class GbpOptionParser(OptionParser): self.sections = sections self.prefix = prefix self.config = {} - self.parse_config_files() self.valid_options = [] + self._warned_old_gbp_conf = False + + try: + self.parse_config_files() + except configparser.ParsingError as err: + raise GbpError(str(err) + "\nSee 'man gbp.conf' for the format.") - if self.command.startswith('git-') or self.command.startswith('gbp-'): - prog = self.command - else: - prog = "gbp %s" % self.command OptionParser.__init__(self, option_class=GbpOption, - prog=prog, + prog="gbp %s" % self.command, usage=usage, version='%s %s' % (self.command, gbp_version)) @@ -480,10 +559,10 @@ class GbpOptionParser(OptionParser): """is option_name a boolean option""" ret = False try: - if kwargs['action'] in [ 'store_true', 'store_false' ]: - ret=True + if kwargs['action'] in ['store_true', 'store_false']: + ret = True except KeyError: - ret=False + ret = False return ret def _get_bool_default(self, option_name): @@ -503,9 +582,9 @@ class GbpOptionParser(OptionParser): except KeyError: default = self.config[neg] - if default.lower() in ["true", "1" ]: + if default.lower() in ["true", "1"]: val = 'True' - elif default.lower() in ["false", "0" ]: + elif default.lower() in ["false", "0"]: val = 'False' else: raise ValueError("Boolean options must be True or False") @@ -519,7 +598,15 @@ class GbpOptionParser(OptionParser): default = self.config[option_name] return default - @safe_option + def get_opt_names(self, option_name): + names = ["--%s%s" % (self.prefix, option_name)] + if option_name in self.short_opts: + if self.prefix: + raise ValueError("Options with prefix cannot have a short option") + names.insert(0, self.short_opts[option_name]) + return names + + @save_option def add_config_file_option(self, option_name, dest, help=None, **kwargs): """ set a option for the command line parser, the default is read from the config file @@ -532,7 +619,8 @@ class GbpOptionParser(OptionParser): """ if not help: help = self.help[option_name] - OptionParser.add_option(self, "--%s%s" % (self.prefix, option_name), dest=dest, + opt_names = self.get_opt_names(option_name) + OptionParser.add_option(self, *opt_names, dest=dest, default=self.get_default(option_name, **kwargs), help=help % self.config, **kwargs) @@ -579,7 +667,7 @@ class GbpOptionParser(OptionParser): >>> GbpOptionParser._name_to_filename('debian') '%(top_dir)s/debian/gbp.conf' """ - for k, v in cls.def_config_files.items(): + for k, v in cls.def_config_files: if name == v: return k else: @@ -608,7 +696,7 @@ class GbpOptionParser(OptionParser): class GbpOptionGroup(OptionGroup): - @safe_option + @save_option def add_config_file_option(self, option_name, dest, help=None, **kwargs): """ set a option for the command line parser, the default is read from the config file @@ -621,9 +709,10 @@ class GbpOptionGroup(OptionGroup): """ if not help: help = self.parser.help[option_name] - OptionGroup.add_option(self, "--%s%s" % (self.parser.prefix, option_name), dest=dest, - default=self.parser.get_default(option_name, **kwargs), - help=help % self.parser.config, **kwargs) + opt_names = self.parser.get_opt_names(option_name) + OptionGroup.add_option(self, *opt_names, dest=dest, + default=self.parser.get_default(option_name, **kwargs), + help=help % self.parser.config, **kwargs) def add_boolean_config_file_option(self, option_name, dest): self.add_config_file_option(option_name=option_name, dest=dest, action="store_true") @@ -636,9 +725,13 @@ class GbpOptionParserDebian(GbpOptionParser): Handles commandline options and parsing of config files for Debian tools """ defaults = dict(GbpOptionParser.defaults) - defaults.update( { - 'builder' : 'debuild -i -I', - } ) + defaults.update({ + 'builder': 'debuild -i -I', + }) + + def _warn_old_gbp_conf(self, gbp_conf): + if os.path.exists("debian/control"): + GbpOptionParser._warn_old_gbp_conf(self, gbp_conf) class GbpOptionParserRpm(GbpOptionParser): @@ -647,28 +740,32 @@ class GbpOptionParserRpm(GbpOptionParser): """ defaults = dict(GbpOptionParser.defaults) defaults.update({ - 'tmp-dir' : '/var/tmp/gbp/', - 'vendor' : 'Downstream', - 'packaging-branch' : 'master', - 'packaging-dir' : '', - 'packaging-tag-msg' : ('%(pkg)s (vendor)s release ' - '%(version)s'), - 'packaging-tag' : 'packaging/%(version)s', - 'export-sourcedir' : 'SOURCES', - 'export-specdir' : 'SPECS', - 'export-dir' : '../rpmbuild', - 'builder' : 'rpmbuild', - 'spec-file' : '', - 'mock' : 'False', - 'dist' : '', - 'arch' : '', - 'mock-root' : '', - 'mock-options' : '', - 'native' : 'auto', - }) + 'tmp-dir': '/var/tmp/gbp/', + 'vendor': 'Downstream', + 'packaging-branch': 'master', + 'packaging-dir': '', + 'packaging-tag-msg': '%(pkg)s (vendor)s release %(version)s', + 'packaging-tag': 'packaging/%(version)s', + 'export-sourcedir': 'SOURCES', + 'export-specdir': 'SPECS', + 'export-dir': '../rpmbuild', + 'builder': 'rpmbuild', + 'spec-file': '', + 'mock': 'False', + 'dist': '', + 'arch': '', + 'mock-root': '', + 'mock-options': '', + 'native': 'auto', + 'changelog-file': 'auto', + 'changelog-revision': '', + 'spawn-editor': 'always', + 'editor-cmd': 'vim', + }) help = dict(GbpOptionParser.help) - help.update({ + help.update( + { 'tmp-dir': "Base directory under which temporary directories are " "created, default is '%(tmp-dir)s'", @@ -685,8 +782,8 @@ class GbpOptionParserRpm(GbpOptionParser): "Format string for packaging tags, RPM counterpart of the " "'debian-tag' option, default is '%(packaging-tag)s'", 'packaging-tag-msg': - ("Format string for packaging tag messages, " - "default is '%(packaging-tag-msg)s'"), + "Format string for packaging tag messages, " + "default is '%(packaging-tag-msg)s'", 'spec-file': "Spec file to use, causes the packaging-dir option to be " "ignored, default is '%(spec-file)s'", @@ -697,23 +794,39 @@ class GbpOptionParserRpm(GbpOptionParser): 'export-specdir': "Subdir (under EXPORT_DIR) where package spec file is " "exported default is '%(export-specdir)s'", - 'mock': - ("Invoke mock for building using gbp-builder-mock, " - "default is '%(mock)s'"), - 'dist': - ("Build for this distribution when using mock. E.g.: epel-6, " - "default is '%(dist)s'"), - 'arch': - ("Build for this architecture when using mock, " - "default is '%(arch)s'"), - 'mock-root': - ("The mock root (-r) name for building with mock: <dist>-<arch>, " - "default is '%(mock-root)s'"), - 'mock-options': - ("Options to pass to mock, " - "default is '%(mock-options)s'"), + 'mock': + "Invoke mock for building using gbp-builder-mock, " + "default is '%(mock)s'", + 'dist': + "Build for this distribution when using mock. E.g.: epel-6, " + "default is '%(dist)s'", + 'arch': + "Build for this architecture when using mock, " + "default is '%(arch)s'", + 'mock-root': + "The mock root (-r) name for building with mock: <dist>-<arch>, " + "default is '%(mock-root)s'", + 'mock-options': + "Options to pass to mock, " + "default is '%(mock-options)s'", 'native': "Treat this package as native, default is '%(native)s'", - }) + 'changelog-file': + "Changelog file to be used, default is '%(changelog-file)s'", + 'changelog-revision': + "Format string for the revision field in the changelog header. " + "If empty or not defined the default from packaging policy is " + "used.", + 'editor-cmd': + "Editor command to use", + 'git-author': + "Use name and email from git-config for the changelog header, " + "default is '%(git-author)s'", + }) + + def _warn_old_gbp_conf(self, gbp_conf): + # The rpm based tools use $repo/.gbp.conf a lot, don't + # warn there yet + pass # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·: |