Rev 2783: (Ian Clatworthy) Verbosity levels and standard options in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Mon Sep 3 08:34:27 BST 2007
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 2783
revision-id: pqm at pqm.ubuntu.com-20070903073425-ouk9qod51gqk18nn
parent: pqm at pqm.ubuntu.com-20070903070212-g8basoqekm8c489k
parent: ian.clatworthy at internode.on.net-20070903054111-xyba0ihklpfs73gc
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2007-09-03 08:34:25 +0100
message:
(Ian Clatworthy) Verbosity levels and standard options
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/builtins.py builtins.py-20050830033751-fc01482b9ca23183
bzrlib/commands.py bzr.py-20050309040720-d10f4714595cf8c3
bzrlib/help_topics.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
bzrlib/option.py option.py-20051014052914-661fb36e76e7362f
bzrlib/tests/blackbox/test_locale.py test_lang.py-20060824204205-80v50j25qkuop7yn-1
bzrlib/tests/test_help.py test_help.py-20070419045354-6q6rq15j9e2n5fna-1
bzrlib/tests/test_options.py testoptions.py-20051014093702-96457cfc86319a8f
bzrlib/tests/test_trace.py testtrace.py-20051110225523-a21117fc7a07eeff
bzrlib/trace.py trace.py-20050309040759-c8ed824bdcd4748a
------------------------------------------------------------
revno: 2779.1.1
merged: ian.clatworthy at internode.on.net-20070903054111-xyba0ihklpfs73gc
parent: pqm at pqm.ubuntu.com-20070903051736-tnjjdk1ii0258an0
parent: ian.clatworthy at internode.on.net-20070903034749-op16cqnb8fi0jmde
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: ianc-integration
timestamp: Mon 2007-09-03 15:41:11 +1000
message:
(Ian Clatworthy) Verbosity levels and standard options
------------------------------------------------------------
revno: 2768.1.16
merged: ian.clatworthy at internode.on.net-20070903034749-op16cqnb8fi0jmde
parent: ian.clatworthy at internode.on.net-20070903015029-dmi0iqcqkejp27p3
parent: pqm at pqm.ubuntu.com-20070903031921-8msn0bmzubicv5b1
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Mon 2007-09-03 13:47:49 +1000
message:
merge bzr.dev
------------------------------------------------------------
revno: 2768.1.15
merged: ian.clatworthy at internode.on.net-20070903015029-dmi0iqcqkejp27p3
parent: ian.clatworthy at internode.on.net-20070903013349-o37wm1bxe04pctrm
parent: pqm at pqm.ubuntu.com-20070902233606-wb062d366w5c83uc
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Mon 2007-09-03 11:50:29 +1000
message:
Merge bzr.dev
------------------------------------------------------------
revno: 2768.1.14
merged: ian.clatworthy at internode.on.net-20070903013349-o37wm1bxe04pctrm
parent: ian.clatworthy at internode.on.net-20070831042259-9bal2zqm5kvgu5hl
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Mon 2007-09-03 11:33:49 +1000
message:
Incorporate feedback from poolie
------------------------------------------------------------
revno: 2768.1.13
merged: ian.clatworthy at internode.on.net-20070831042259-9bal2zqm5kvgu5hl
parent: ian.clatworthy at internode.on.net-20070831041239-onw9xs8s142qqt1m
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Fri 2007-08-31 14:22:59 +1000
message:
Minor fixes to help
------------------------------------------------------------
revno: 2768.1.12
merged: ian.clatworthy at internode.on.net-20070831041239-onw9xs8s142qqt1m
parent: ian.clatworthy at internode.on.net-20070831040757-30bmwliqsxd7zn6a
parent: pqm at pqm.ubuntu.com-20070831020510-emrlta5dk6ta95zp
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Fri 2007-08-31 14:12:39 +1000
message:
merge bzr.dev
------------------------------------------------------------
revno: 2768.1.11
merged: ian.clatworthy at internode.on.net-20070831040757-30bmwliqsxd7zn6a
parent: ian.clatworthy at internode.on.net-20070831020037-6drt2nnbu38907s5
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Fri 2007-08-31 14:07:57 +1000
message:
Add new option tests for custom help, callbacks and verbose/quiet linkage
------------------------------------------------------------
revno: 2768.1.10
merged: ian.clatworthy at internode.on.net-20070831020037-6drt2nnbu38907s5
parent: ian.clatworthy at internode.on.net-20070831014737-79wyvq0fwat06alc
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Fri 2007-08-31 12:00:37 +1000
message:
Add tests for new methods in trace.py
------------------------------------------------------------
revno: 2768.1.9
merged: ian.clatworthy at internode.on.net-20070831014737-79wyvq0fwat06alc
parent: ian.clatworthy at internode.on.net-20070831003537-29b1erv58zwb0kh7
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Fri 2007-08-31 11:47:37 +1000
message:
Update NEWS
------------------------------------------------------------
revno: 2768.1.8
merged: ian.clatworthy at internode.on.net-20070831003537-29b1erv58zwb0kh7
parent: ian.clatworthy at internode.on.net-20070831003508-8r26w7ydnzfh5bbg
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Fri 2007-08-31 10:35:37 +1000
message:
Get test suite fully working again
------------------------------------------------------------
revno: 2768.1.7
merged: ian.clatworthy at internode.on.net-20070831003508-8r26w7ydnzfh5bbg
parent: ian.clatworthy at internode.on.net-20070830135357-dqr7saq6ciipx09d
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Fri 2007-08-31 10:35:08 +1000
message:
Fix reset of verbosity levels
------------------------------------------------------------
revno: 2768.1.6
merged: ian.clatworthy at internode.on.net-20070830135357-dqr7saq6ciipx09d
parent: ian.clatworthy at internode.on.net-20070830135258-t146laed1vd0nqx0
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Thu 2007-08-30 23:53:57 +1000
message:
Fix existing option and help tests
------------------------------------------------------------
revno: 2768.1.5
merged: ian.clatworthy at internode.on.net-20070830135258-t146laed1vd0nqx0
parent: ian.clatworthy at internode.on.net-20070830134140-mjd6zw41nobxy51f
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Thu 2007-08-30 23:52:58 +1000
message:
Wrap new std verbose option with new help instead of declaring a new one
------------------------------------------------------------
revno: 2768.1.4
merged: ian.clatworthy at internode.on.net-20070830134140-mjd6zw41nobxy51f
parent: ian.clatworthy at internode.on.net-20070830134041-y6wd24dz52fpkthx
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Thu 2007-08-30 23:41:40 +1000
message:
Process --verbose and --quiet standard options
------------------------------------------------------------
revno: 2768.1.3
merged: ian.clatworthy at internode.on.net-20070830134041-y6wd24dz52fpkthx
parent: ian.clatworthy at internode.on.net-20070830133731-b2251gmd4zrlv4or
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Thu 2007-08-30 23:40:41 +1000
message:
Support custom help for commonly used options and standard option definition
------------------------------------------------------------
revno: 2768.1.2
merged: ian.clatworthy at internode.on.net-20070830133731-b2251gmd4zrlv4or
parent: ian.clatworthy at internode.on.net-20070830060751-bsphtblostbmheh4
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Thu 2007-08-30 23:37:31 +1000
message:
Make noise levels a scale, not just a boolean in trace.py
------------------------------------------------------------
revno: 2768.1.1
merged: ian.clatworthy at internode.on.net-20070830060751-bsphtblostbmheh4
parent: pqm at pqm.ubuntu.com-20070829235511-o6ftd800xa245p9h
committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
branch nick: bzr.std-options
timestamp: Thu 2007-08-30 16:07:51 +1000
message:
Document standard options
=== modified file 'NEWS'
--- a/NEWS 2007-09-03 07:02:12 +0000
+++ b/NEWS 2007-09-03 07:34:25 +0000
@@ -14,6 +14,11 @@
This format is compatible with Bazaar 0.15 and later.
(Martin Pool)
+ * ``--quiet`` or ``-q`` is no longer a global option. If present, it
+ must now appear after the command name. Scripts doing things like
+ ``bzr -q missing`` need to be rewritten as ``bzr missing -q``.
+ (Ian Clatworthy)
+
FEATURES:
* New option ``--author`` in ``bzr commit`` to specify the author of the
@@ -21,6 +26,28 @@
``bzr annotate`` display the author instead of the committer.
(Lukáš Lalinský)
+ * In addition to global options and command specific options, a set of
+ standard options are now supported. Standard options are legal for
+ all commands. The initial set of standard options are:
+
+ * ``--help`` or ``-h`` - display help message
+ * ``--verbose`` or ``-v`` - display additional information
+ * ``--quiet`` or ``-q`` - only output warnings and errors.
+
+ Unlike global options, standard options can be used in aliases and
+ may have command-specific help. (Ian Clatworthy)
+
+ * Verbosity level processing has now been unified. If ``--verbose``
+ or ``-v`` is specified on the command line multiple times, the
+ verbosity level is made positive the first time then increased.
+ If ``--quiet`` or ``-q`` is specified on the command line
+ multiple times, the verbosity level is made negative the first
+ time then decreased. To get the default verbosity level of zero,
+ either specify none of the above , ``--no-verbose`` or ``--no-quiet``.
+ Note that most commands currently ignore the magnitude of the
+ verbosity level but do respect *quiet vs normal vs verbose* when
+ generating output. (Ian Clatworthy)
+
BUG FIXES:
* ``bzr plugins`` now lists the version number for each plugin in square
@@ -187,6 +214,26 @@
* Knits with no annotation cache still produce correct annotations.
(Aaron Bentley)
+ * Three new methods have been added to ``bzrlib.trace``:
+ ``set_verbosity_level``, ``get_verbosity_level`` and ``is_verbose``.
+ ``set_verbosity_level`` expects a numeric value: negative for quiet,
+ zero for normal, positive for verbose. The size of the number can be
+ used to determine just how quiet or verbose the application should be.
+ The existing ``be_quiet`` and ``is_quiet`` routines have been
+ integrated into this new scheme. (Ian Clatworthy)
+
+ * Options can now be delcared with a ``custom_callback`` parameter. If
+ set, this routine is called after the option is processed. This feature
+ is now used by the standard options ``verbose`` and ``quiet`` so that
+ setting one implicitly resets the other. (Ian Clatworthy)
+
+ * Rather than declaring a new option from scratch in order to provide
+ custom help, a centrally registered option can be decorated using the
+ new ``bzrlib.Option.custom_help`` routine. In particular, this routine
+ is useful when declaring better help for the ``verbose`` and ``quiet``
+ standard options as the base definition of these is now more complex
+ than before thanks to their use of a custom callback. (Ian Clatworthy)
+
bzr 0.90 2007-08-28
===================
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py 2007-09-03 05:53:11 +0000
+++ b/bzrlib/builtins.py 2007-09-03 07:34:25 +0000
@@ -60,7 +60,7 @@
""")
from bzrlib.commands import Command, display_command
-from bzrlib.option import ListOption, Option, RegistryOption
+from bzrlib.option import ListOption, Option, RegistryOption, custom_help
from bzrlib.progress import DummyProgress, ProgressPhase
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
@@ -573,7 +573,7 @@
_see_also = ['push', 'update', 'status-flags']
takes_options = ['remember', 'overwrite', 'revision',
- Option('verbose', short_name='v',
+ custom_help('verbose',
help='Show logs of pulled revisions.'),
Option('directory',
help='Branch to pull into, '
@@ -1058,10 +1058,14 @@
takes_options = ['verbose']
@display_command
- def run(self, location=None, verbose=0):
+ def run(self, location=None, verbose=False):
+ if verbose:
+ noise_level = 2
+ else:
+ noise_level = 0
from bzrlib.info import show_bzrdir_info
show_bzrdir_info(bzrdir.BzrDir.open_containing(location)[0],
- verbose=verbose)
+ verbose=noise_level)
class cmd_remove(Command):
@@ -1626,8 +1630,7 @@
Option('timezone',
type=str,
help='Display timezone as local, original, or utc.'),
- Option('verbose',
- short_name='v',
+ custom_help('verbose',
help='Show files changed in each revision.'),
'show-ids',
'revision',
@@ -2227,7 +2230,7 @@
properties.append('%s fixed' % bug_url)
return '\n'.join(properties)
- def run(self, message=None, file=None, verbose=True, selected_list=None,
+ def run(self, message=None, file=None, verbose=False, selected_list=None,
unchanged=False, strict=False, local=False, fixes=None,
author=None, show_diff=False):
from bzrlib.commit import (
@@ -2287,7 +2290,7 @@
raise errors.BzrCommandError("empty commit message specified")
return my_message
- if verbose:
+ if verbose or not is_quiet():
reporter = ReportCommitToLog()
else:
reporter = NullCommitReporter()
=== modified file 'bzrlib/commands.py'
--- a/bzrlib/commands.py 2007-08-21 12:32:42 +0000
+++ b/bzrlib/commands.py 2007-08-31 00:35:08 +0000
@@ -238,6 +238,8 @@
"""Construct an instance of this command."""
if self.__doc__ == Command.__doc__:
warn("No help message set for %r" % self)
+ # List of standard options directly supported
+ self.supported_std_options = []
def _maybe_expand_globs(self, file_list):
"""Glob expand file_list if the platform does not do that itself.
@@ -417,12 +419,14 @@
"""Return dict of valid options for this command.
Maps from long option name to option object."""
- r = dict()
- r['help'] = option._help_option
+ r = Option.STD_OPTIONS.copy()
+ std_names = r.keys()
for o in self.takes_options:
if isinstance(o, basestring):
o = option.Option.OPTIONS[o]
r[o.name] = o
+ if o.name in std_names:
+ self.supported_std_options.append(o.name)
return r
def _setup_outf(self):
@@ -458,9 +462,21 @@
DeprecationWarning, stacklevel=2)
argv = []
args, opts = parse_args(self, argv, alias_argv)
+
+ # Process the standard options
if 'help' in opts: # e.g. bzr add --help
sys.stdout.write(self.get_help_text())
return 0
+ trace.set_verbosity_level(option._verbosity_level)
+ if 'verbose' in self.supported_std_options:
+ opts['verbose'] = trace.is_verbose()
+ elif opts.has_key('verbose'):
+ del opts['verbose']
+ if 'quiet' in self.supported_std_options:
+ opts['quiet'] = trace.is_quiet()
+ elif opts.has_key('quiet'):
+ del opts['quiet']
+
# mix arguments and options into one dictionary
cmdargs = _match_argform(self.name(), self.takes_args, args)
cmdopts = {}
@@ -691,8 +707,6 @@
opt_no_aliases = True
elif a == '--builtin':
opt_builtin = True
- elif a in ('--quiet', '-q'):
- trace.be_quiet()
elif a.startswith('-D'):
debug.debug_flags.add(a[2:])
else:
@@ -744,7 +758,7 @@
return ret or 0
finally:
# reset, in case we may do other commands later within the same process
- trace.be_quiet(False)
+ option._verbosity_level = 0
def display_command(func):
"""Decorator that suppresses pipe/interrupt errors."""
=== modified file 'bzrlib/help_topics.py'
--- a/bzrlib/help_topics.py 2007-08-28 00:49:10 +0000
+++ b/bzrlib/help_topics.py 2007-09-03 01:33:49 +0000
@@ -240,24 +240,14 @@
"""Global Options
These options may be used with any command, and may appear in front of any
-command. (e.g. "bzr --quiet help").
-
---quiet Suppress informational output; only print errors and warnings.
---version Print the version number.
-
+command. (e.g. "bzr --profile help").
+
+--version Print the version number. Must be supplied before the command.
--no-aliases Do not process command aliases when running this command.
--builtin Use the built-in version of a command, not the plugin version.
This does not suppress other plugin effects.
--no-plugins Do not process any plugins.
--Devil Capture call sites that do expensive or badly-scaling
- operations.
--Derror Instead of normal error handling, always print a traceback on
- error.
--Dhooks Trace hook execution.
--Dhpss Trace smart protocol requests and responses.
--Dindex Trace major index operations.
--Dlock Trace when lockdir locks are taken or released.
--profile Profile execution using the hotshot profiler.
--lsprof Profile execution using the lsprof profiler.
--lsprof-file Profile execution using the lsprof profiler, and write the
@@ -268,9 +258,31 @@
will be a pickle.
See doc/developers/profiling.txt for more information on profiling.
-
-Note: --version must be supplied before any command.
-"""
+A number of debug flags are also available to assist troubleshooting and
+development.
+
+-Derror Instead of normal error handling, always print a traceback on
+ error.
+-Devil Capture call sites that do expensive or badly-scaling
+ operations.
+-Dhooks Trace hook execution.
+-Dhpss Trace smart protocol requests and responses.
+-Dindex Trace major index operations.
+-Dlock Trace when lockdir locks are taken or released.
+"""
+
+_standard_options = \
+"""Standard Options
+
+Standard options are legal for all commands.
+
+--help, -h Show help message.
+--verbose, -v Display more information.
+--quiet, -q Only display errors and warnings.
+
+Unlike global options, standard options can be used in aliases.
+"""
+
_checkouts = \
"""Checkouts
@@ -512,8 +524,10 @@
from bzrlib import bzrdir
return "Storage Formats\n\n" + bzrdir.format_registry.help_topic(topic)
topic_registry.register('formats', get_format_topic, 'Directory formats')
+topic_registry.register('standard-options', _standard_options,
+ 'Options that can be used with any command')
topic_registry.register('global-options', _global_options,
- 'Options that can be used with any command')
+ 'Options that control how Bazaar runs')
topic_registry.register('checkouts', _checkouts,
'Information on what a checkout is', SECT_CONCEPT)
topic_registry.register('urlspec', _help_on_transport,
=== modified file 'bzrlib/option.py'
--- a/bzrlib/option.py 2007-09-01 16:04:44 +0000
+++ b/bzrlib/option.py 2007-09-03 01:50:29 +0000
@@ -142,27 +142,38 @@
Otherwise None.
"""
- # TODO: Some way to show in help a description of the option argument
+ # The dictionary of standard options. These are always legal.
+ STD_OPTIONS = {}
+ # The dictionary of commonly used options. these are only legal
+ # if a command explicitly references them by name in the list
+ # of supported options.
OPTIONS = {}
def __init__(self, name, help='', type=None, argname=None,
- short_name=None, param_name=None):
+ short_name=None, param_name=None, custom_callback=None):
"""Make a new command option.
- name -- regular name of the command, used in the double-dash
+ :param name: regular name of the command, used in the double-dash
form and also as the parameter to the command's run()
method (unless param_name is specified).
- help -- help message displayed in command help
+ :param help: help message displayed in command help
- type -- function called to parse the option argument, or
+ :param type: function called to parse the option argument, or
None (default) if this option doesn't take an argument.
- argname -- name of option argument, if any
-
- param_name -- name of the parameter which will be passed to
+ :param argname: name of option argument, if any
+
+ :param short_name: short option code for use with a single -, e.g.
+ short_name="v" to enable parsing of -v.
+
+ :param param_name: name of the parameter which will be passed to
the command's run() method.
+
+ :param custom_callback: a callback routine to be called after normal
+ processing. The signature of the callback routine is
+ (option, name, new_value, parser).
"""
self.name = name
self.help = help
@@ -177,6 +188,7 @@
self._param_name = self.name
else:
self._param_name = param_name
+ self.custom_callback = custom_callback
def short_name(self):
if self._short_name:
@@ -198,12 +210,15 @@
option_strings.append('-%s' % short_name)
optargfn = self.type
if optargfn is None:
- parser.add_option(action='store_true', dest=self.name,
+ parser.add_option(action='callback',
+ callback=self._optparse_bool_callback,
+ callback_args=(True,),
help=self.help,
- default=OptionParser.DEFAULT_VALUE,
*option_strings)
negation_strings = ['--%s' % self.get_negation_name()]
- parser.add_option(action='store_false', dest=self.name,
+ parser.add_option(action='callback',
+ callback=self._optparse_bool_callback,
+ callback_args=(False,),
help=optparse.SUPPRESS_HELP, *negation_strings)
else:
parser.add_option(action='callback',
@@ -213,8 +228,16 @@
default=OptionParser.DEFAULT_VALUE,
*option_strings)
+ def _optparse_bool_callback(self, option, opt_str, value, parser, bool_v):
+ setattr(parser.values, self._param_name, bool_v)
+ if self.custom_callback is not None:
+ self.custom_callback(option, self._param_name, bool_v, parser)
+
def _optparse_callback(self, option, opt, value, parser):
- setattr(parser.values, self._param_name, self.type(value))
+ v = self.type(value)
+ setattr(parser.values, self._param_name, v)
+ if self.custom_callback is not None:
+ self.custom_callback(option, self.name, v, parser)
def iter_switches(self):
"""Iterate through the list of switches provided by the option
@@ -253,11 +276,13 @@
*option_strings)
def _optparse_callback(self, option, opt, value, parser):
- values = getattr(parser.values, self.name)
+ values = getattr(parser.values, self._param_name)
if value == '-':
del values[:]
else:
values.append(self.type(value))
+ if self.custom_callback is not None:
+ self.custom_callback(option, self._param_name, values, parser)
class RegistryOption(Option):
@@ -343,7 +368,10 @@
def _optparse_value_callback(self, cb_value):
def cb(option, opt, value, parser):
- setattr(parser.values, self.name, self.type(cb_value))
+ v = self.type(cb_value)
+ setattr(parser.values, self._param_name, v)
+ if self.custom_callback is not None:
+ self.custom_callback(option, self._param_name, v, parser)
return cb
def iter_switches(self):
@@ -382,8 +410,23 @@
return parser
+def custom_help(name, help):
+ """Clone a common option overriding the help."""
+ import copy
+ o = copy.copy(Option.OPTIONS[name])
+ o.help = help
+ return o
+
+
+def _standard_option(name, **kwargs):
+ """Register a standard option."""
+ # All standard options are implicitly 'global' ones
+ Option.STD_OPTIONS[name] = Option(name, **kwargs)
+ Option.OPTIONS[name] = Option.STD_OPTIONS[name]
+
+
def _global_option(name, **kwargs):
- """Register o as a global option."""
+ """Register a global option."""
Option.OPTIONS[name] = Option(name, **kwargs)
@@ -396,6 +439,34 @@
pass
+# This is the verbosity level detected during command line parsing.
+# Note that the final value is dependent on the order in which the
+# various flags (verbose, quiet, no-verbose, no-quiet) are given.
+# The final value will be one of the following:
+#
+# * -ve for quiet
+# * 0 for normal
+# * +ve for verbose
+_verbosity_level = 0
+
+
+def _verbosity_level_callback(option, opt_str, value, parser):
+ global _verbosity_level
+ if not value:
+ # Either --no-verbose or --no-quiet was specified
+ _verbosity_level = 0
+ elif opt_str == "verbose":
+ if _verbosity_level > 0:
+ _verbosity_level += 1
+ else:
+ _verbosity_level = 1
+ else:
+ if _verbosity_level < 0:
+ _verbosity_level -= 1
+ else:
+ _verbosity_level = -1
+
+
_merge_type_registry = MergeTypeRegistry()
_merge_type_registry.register_lazy('merge3', 'bzrlib.merge', 'Merge3Merger',
"Native diff3-style merge")
@@ -404,6 +475,17 @@
_merge_type_registry.register_lazy('weave', 'bzrlib.merge', 'WeaveMerger',
"Weave-based merge")
+# Declare the standard options
+_standard_option('help', short_name='h',
+ help='Show help message.')
+_standard_option('verbose', short_name='v',
+ help='Display more information.',
+ custom_callback=_verbosity_level_callback)
+_standard_option('quiet', short_name='q',
+ help="Only display errors and warnings.",
+ custom_callback=_verbosity_level_callback)
+
+# Declare commonly used options
_global_option('all')
_global_option('overwrite', help='Ignore differences between branches and '
'overwrite unconditionally.')
@@ -435,9 +517,6 @@
type=str,
help='display timezone as local, original, or utc')
_global_option('unbound')
-_global_option('verbose',
- help='Display more information.',
- short_name='v')
_global_option('version')
_global_option('email')
_global_option('update')
@@ -454,7 +533,6 @@
_merge_type_registry, value_switches=True,
title='Merge algorithm')
_global_option('pattern', type=str)
-_global_option('quiet', short_name='q')
_global_option('remember', help='Remember the specified location as a'
' default.')
_global_option('reprocess', help='Reprocess to reduce spurious conflicts.')
@@ -462,7 +540,3 @@
_global_option('dry-run',
help="Show what would be done, but don't actually do anything.")
_global_option('name-from-revision', help='The path name in the old tree.')
-
-_help_option = Option('help',
- help='Show help message.',
- short_name='h')
=== modified file 'bzrlib/tests/blackbox/test_locale.py'
--- a/bzrlib/tests/blackbox/test_locale.py 2007-08-16 18:50:22 +0000
+++ b/bzrlib/tests/blackbox/test_locale.py 2007-08-31 00:35:37 +0000
@@ -42,7 +42,7 @@
def test_log_C(self):
out, err = self.run_bzr_subprocess(
- '--no-aliases --no-plugins -q log --log-format=long tree',
+ '--no-aliases --no-plugins log -q --log-format=long tree',
env_changes={'LANG':'C', 'BZR_PROGRESS_BAR':'none',
'LC_ALL':None, 'LC_CTYPE':None, 'LANGUAGE':None})
self.assertEqual('', err)
@@ -58,7 +58,7 @@
def test_log_BOGUS(self):
out, err = self.run_bzr_subprocess(
- '--no-aliases --no-plugins -q log --log-format=long tree',
+ '--no-aliases --no-plugins log -q --log-format=long tree',
env_changes={'LANG':'BOGUS', 'BZR_PROGRESS_BAR':'none',
'LC_ALL':None, 'LC_CTYPE':None, 'LANGUAGE':None})
# XXX: This depends on the exact formatting of a locale.Error
=== modified file 'bzrlib/tests/test_help.py'
--- a/bzrlib/tests/test_help.py 2007-08-06 10:02:13 +0000
+++ b/bzrlib/tests/test_help.py 2007-08-30 13:53:57 +0000
@@ -40,7 +40,9 @@
helptext = cmd.get_help_text()
self.assertEndsWith(
helptext,
- ' -h, --help Show help message.\n'
+ ' -v, --verbose Display more information.\n'
+ ' -q, --quiet Only display errors and warnings.\n'
+ ' -h, --help Show help message.\n'
'\n'
'See also: bar, foo\n')
@@ -53,7 +55,8 @@
self.assertStartsWith(helptext,
'Purpose: A sample command.\n'
'Usage: bzr Demo')
- self.assertEndsWith(helptext, 'Show help message.\n\n')
+ self.assertEndsWith(helptext,
+ ' -h, --help Show help message.\n\n')
def test_command_with_additional_see_also(self):
class cmd_WithSeeAlso(commands.Command):
@@ -63,7 +66,9 @@
helptext = cmd.get_help_text(['gam'])
self.assertEndsWith(
helptext,
- ' -h, --help Show help message.\n'
+ ' -v, --verbose Display more information.\n'
+ ' -q, --quiet Only display errors and warnings.\n'
+ ' -h, --help Show help message.\n'
'\n'
'See also: bar, foo, gam\n')
@@ -74,7 +79,9 @@
helptext = cmd.get_help_text(['gam'])
self.assertEndsWith(
helptext,
- ' -h, --help Show help message.\n'
+ ' -v, --verbose Display more information.\n'
+ ' -q, --quiet Only display errors and warnings.\n'
+ ' -h, --help Show help message.\n'
'\n'
'See also: gam\n')
@@ -107,7 +114,9 @@
'Usage: bzr Demo\n'
'\n'
'Options:\n'
- ' -h, --help Show help message.\n'
+ ' -v, --verbose Display more information.\n'
+ ' -q, --quiet Only display errors and warnings.\n'
+ ' -h, --help Show help message.\n'
'\n'
'Examples:\n'
' Example 1:\n'
@@ -124,7 +133,9 @@
':Usage: bzr Demo\n'
'\n'
':Options:\n'
- ' -h, --help Show help message.\n'
+ ' -v, --verbose Display more information.\n'
+ ' -q, --quiet Only display errors and warnings.\n'
+ ' -h, --help Show help message.\n'
'\n'
':Examples:\n'
' Example 1::\n'
@@ -159,7 +170,9 @@
'\n'
'\n'
'Options:\n'
- ' -h, --help Show help message.\n'
+ ' -v, --verbose Display more information.\n'
+ ' -q, --quiet Only display errors and warnings.\n'
+ ' -h, --help Show help message.\n'
'\n'
'Description:\n'
' Blah blah blah.\n\n')
=== modified file 'bzrlib/tests/test_options.py'
--- a/bzrlib/tests/test_options.py 2007-09-01 16:04:44 +0000
+++ b/bzrlib/tests/test_options.py 2007-09-03 01:50:29 +0000
@@ -93,7 +93,7 @@
opts, args = self.parse(options, ['--no-hello', '--hello'])
self.assertEqual(True, opts.hello)
opts, args = self.parse(options, [])
- self.assertEqual(option.OptionParser.DEFAULT_VALUE, opts.hello)
+ self.assertFalse(hasattr(opts, 'hello'))
opts, args = self.parse(options, ['--hello', '--no-hello'])
self.assertEqual(False, opts.hello)
options = [option.Option('number', type=int)]
@@ -214,6 +214,37 @@
('two', None, None, 'two help'),
])
+ def test_option_callback_bool(self):
+ "Test booleans get True and False passed correctly to a callback."""
+ cb_calls = []
+ def cb(option, name, value, parser):
+ cb_calls.append((option,name,value,parser))
+ options = [option.Option('hello', custom_callback=cb)]
+ opts, args = self.parse(options, ['--hello', '--no-hello'])
+ self.assertEqual(2, len(cb_calls))
+ opt,name,value,parser = cb_calls[0]
+ self.assertEqual('hello', name)
+ self.assertTrue(value)
+ opt,name,value,parser = cb_calls[1]
+ self.assertEqual('hello', name)
+ self.assertFalse(value)
+
+ def test_option_callback_str(self):
+ """Test callbacks work for string options both long and short."""
+ cb_calls = []
+ def cb(option, name, value, parser):
+ cb_calls.append((option,name,value,parser))
+ options = [option.Option('hello', type=str, custom_callback=cb,
+ short_name='h')]
+ opts, args = self.parse(options, ['--hello', 'world', '-h', 'mars'])
+ self.assertEqual(2, len(cb_calls))
+ opt,name,value,parser = cb_calls[0]
+ self.assertEqual('hello', name)
+ self.assertEqual('world', value)
+ opt,name,value,parser = cb_calls[1]
+ self.assertEqual('hello', name)
+ self.assertEqual('mars', value)
+
class TestListOptions(TestCase):
"""Tests for ListOption, used to specify lists on the command-line."""
@@ -250,6 +281,26 @@
options, ['--hello=a', '--hello=b', '--hello=-', '--hello=c'])
self.assertEqual(['c'], opts.hello)
+ def test_option_callback_list(self):
+ """Test callbacks work for list options."""
+ cb_calls = []
+ def cb(option, name, value, parser):
+ # Note that the value is a reference so copy to keep it
+ cb_calls.append((option,name,value[:],parser))
+ options = [option.ListOption('hello', type=str, custom_callback=cb)]
+ opts, args = self.parse(options, ['--hello=world', '--hello=mars',
+ '--hello=-'])
+ self.assertEqual(3, len(cb_calls))
+ opt,name,value,parser = cb_calls[0]
+ self.assertEqual('hello', name)
+ self.assertEqual(['world'], value)
+ opt,name,value,parser = cb_calls[1]
+ self.assertEqual('hello', name)
+ self.assertEqual(['world', 'mars'], value)
+ opt,name,value,parser = cb_calls[2]
+ self.assertEqual('hello', name)
+ self.assertEqual([], value)
+
class TestOptionDefinitions(TestCase):
"""Tests for options in the Bazaar codebase."""
@@ -318,3 +369,31 @@
format = option.RegistryOption('format', '', registry, str)
self.assertTrue(format.is_hidden('hidden'))
self.assertFalse(format.is_hidden('visible'))
+
+ def test_option_custom_help(self):
+ the_opt = option.Option.OPTIONS['help']
+ orig_help = the_opt.help[:]
+ my_opt = option.custom_help('help', 'suggest lottery numbers')
+ # Confirm that my_opt has my help and the original is unchanged
+ self.assertEqual('suggest lottery numbers', my_opt.help)
+ self.assertEqual(orig_help, the_opt.help)
+
+
+class TestVerboseQuietLinkage(TestCase):
+
+ def check(self, parser, level, args):
+ option._verbosity_level = 0
+ opts, args = parser.parse_args(args)
+ self.assertEqual(level, option._verbosity_level)
+
+ def test_verbose_quiet_linkage(self):
+ parser = option.get_optparser(option.Option.STD_OPTIONS)
+ self.check(parser, 0, [])
+ self.check(parser, 1, ['-v'])
+ self.check(parser, 2, ['-v', '-v'])
+ self.check(parser, -1, ['-q'])
+ self.check(parser, -2, ['-qq'])
+ self.check(parser, -1, ['-v', '-v', '-q'])
+ self.check(parser, 2, ['-q', '-v', '-v'])
+ self.check(parser, 0, ['--no-verbose'])
+ self.check(parser, 0, ['-v', '-q', '--no-quiet'])
=== modified file 'bzrlib/tests/test_trace.py'
--- a/bzrlib/tests/test_trace.py 2007-08-23 14:10:48 +0000
+++ b/bzrlib/tests/test_trace.py 2007-08-31 02:00:37 +0000
@@ -27,7 +27,10 @@
errors,
)
from bzrlib.tests import TestCaseInTempDir, TestCase
-from bzrlib.trace import mutter, mutter_callsite, report_exception
+from bzrlib.trace import (
+ mutter, mutter_callsite, report_exception,
+ set_verbosity_level, get_verbosity_level, is_quiet, is_verbose, be_quiet,
+ )
def _format_exception():
@@ -148,3 +151,26 @@
self.assertContainsRe(log, "But fails in an ascii string")
self.assertContainsRe(log, u"ascii argument: \xb5")
+
+class TestVerbosityLevel(TestCase):
+
+ def test_verbosity_level(self):
+ set_verbosity_level(1)
+ self.assertEqual(1, get_verbosity_level())
+ self.assertTrue(is_verbose())
+ self.assertFalse(is_quiet())
+ set_verbosity_level(-1)
+ self.assertEqual(-1, get_verbosity_level())
+ self.assertFalse(is_verbose())
+ self.assertTrue(is_quiet())
+ set_verbosity_level(0)
+ self.assertEqual(0, get_verbosity_level())
+ self.assertFalse(is_verbose())
+ self.assertFalse(is_quiet())
+
+ def test_be_quiet(self):
+ # Confirm the old API still works
+ be_quiet(True)
+ self.assertEqual(-1, get_verbosity_level())
+ be_quiet(False)
+ self.assertEqual(0, get_verbosity_level())
=== modified file 'bzrlib/trace.py'
--- a/bzrlib/trace.py 2007-08-20 03:43:40 +0000
+++ b/bzrlib/trace.py 2007-08-31 02:00:37 +0000
@@ -70,7 +70,7 @@
_file_handler = None
_stderr_handler = None
-_stderr_quiet = False
+_verbosity_level = 0
_trace_file = None
_trace_depth = 0
_bzr_log_file = None
@@ -218,10 +218,34 @@
_bzr_logger.setLevel(logging.DEBUG)
+def set_verbosity_level(level):
+ """Set the verbosity level.
+
+ :param level: -ve for quiet, 0 for normal, +ve for verbose
+ """
+ global _verbosity_level
+ _verbosity_level = level
+ _update_logging_level(level < 0)
+
+
+def get_verbosity_level():
+ """Get the verbosity level.
+
+ See set_verbosity_level() for values.
+ """
+ return _verbosity_level
+
+
def be_quiet(quiet=True):
- global _stderr_handler, _stderr_quiet
-
- _stderr_quiet = quiet
+ # Perhaps this could be deprecated now ...
+ if quiet:
+ set_verbosity_level(-1)
+ else:
+ set_verbosity_level(0)
+
+
+def _update_logging_level(quiet=True):
+ """Hide INFO messages if quiet."""
if quiet:
_stderr_handler.setLevel(logging.WARNING)
else:
@@ -229,8 +253,13 @@
def is_quiet():
- global _stderr_quiet
- return _stderr_quiet
+ """Is the verbosity level negative?"""
+ return _verbosity_level < 0
+
+
+def is_verbose():
+ """Is the verbosity level positive?"""
+ return _verbosity_level > 0
def disable_default_logging():
More information about the bazaar-commits
mailing list