PING: [RFC] Optparse option handling
Aaron Bentley
aaron.bentley at utoronto.ca
Tue Aug 8 18:29:22 BST 2006
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I've had no feedback on this. Does anyone want to comment?
Aaron
Aaron Bentley wrote:
> Hi all,
>
> I've updated the optparse branch, added unit tests and the like. The
> branch now
>
> * uses optparse to parse options, and to generate help
>
> * auto-supplies negations of all booleans. That is, --strict implies
> --no-strict, and --no-recurse implies --recurse.
>
> * provides enumerated options. These are options where several switches
> affect the same variable. These replace options like --merge-type and
> --short. The last value is always used.
>
> * updates log, merge, remerge, init-repo, init, upgrade to use EnumOptions
>
> * Uses polymorphism to provide different behavior for Option and EnumOption
>
> * Groups enumerations in the help output, provides textual descriptions
> of all options.
>
> The downside is that the old parameters have been removed, instead of
> being deprecated. Supporting looks looks like pain, but if it's felt
> that we must support e.g. --merge-type as a deprecated option for 0.10,
> then I will figure out how to support it.
>
> So can I get some comments on where to go from here?
>
> Aaron
> p.s. Here's the help output of init-repository, for an example:
>
> help:usage: bzr init-repository LOCATION
> aliases: init-repo
>
> Create a shared repository to hold branches.
>
> New branches created under the repository directory will store their
> revisions
> in the repository, not in the branch directory, if the branch format
> supports
> shared storage.
>
> example:
> bzr init-repo repo
> bzr init repo/trunk
> bzr checkout --lightweight repo/trunk trunk-checkout
> cd trunk-checkout
> (add files here)
>
> options:
> -h, --help show help message
> --trees Allows branches in repository to have a working tree
>
> Repository Format:
> --default The current best format (knit)
> --knit 0.8+ append-only format
> --metaweave 0.8 transitional format
- ------------------------------------------------------------------------
=== modified file 'bzrlib/builtins.py'
- --- bzrlib/builtins.py 2006-08-01 19:09:18 +0000
+++ bzrlib/builtins.py 2006-08-04 02:49:18 +0000
@@ -48,7 +48,7 @@
NoSuchFile, NoWorkingTree, FileInWrongBranch,
NotVersionedError, NotABundle)
from bzrlib.merge import Merge3Merger
- -from bzrlib.option import Option
+from bzrlib.option import Option, EnumOption
from bzrlib.progress import DummyProgress, ProgressPhase
from bzrlib.revision import common_ancestor
from bzrlib.revisionspec import RevisionSpec
@@ -993,6 +993,20 @@
for revision_id in revision_ids:
self.outf.write(revision_id + '\n')
+branch_format_option = EnumOption('Branch Format', get_format_type,
+ [('default',
+ 'The current best format (knit)'),
+ ('knit', '0.8+ append-only format'),
+ ('metaweave', '0.8 transitional
format'),
+ ('weave', '0.1+ format')
+ ])
+
+repo_format_option = EnumOption('Repository Format', get_format_type,
+ [('default',
+ 'The current best format (knit)'),
+ ('knit', '0.8+ append-only format'),
+ ('metaweave', '0.8 transitional format'),
+ ])
class cmd_init(Command):
"""Make a directory into a versioned branch.
@@ -1016,17 +1030,10 @@
bzr commit -m 'imported project'
"""
takes_args = ['location?']
- - takes_options = [
- - Option('format',
- - help='Specify a format for this branch.
Current'
- - ' formats are: default, knit,
metaweave and'
- - ' weave. Default is knit; metaweave and'
- - ' weave are deprecated',
- - type=get_format_type),
- - ]
- - def run(self, location=None, format=None):
- - if format is None:
- - format = get_format_type('default')
+ takes_options = [branch_format_option]
+ def run(self, location=None, branch_format=None):
+ if branch_format is None:
+ branch_format = get_format_type('default')
if location is None:
location = u'.'
@@ -1047,7 +1054,8 @@
existing_bzrdir = bzrdir.BzrDir.open(location)
except NotBranchError:
# really a NotBzrDir error...
- - bzrdir.BzrDir.create_branch_convenience(location,
format=format)
+ bzrdir.BzrDir.create_branch_convenience(location,
+ format=branch_format)
else:
if existing_bzrdir.has_branch():
if (isinstance(to_transport, LocalTransport)
@@ -1074,30 +1082,21 @@
(add files here)
"""
takes_args = ["location"]
- - takes_options = [Option('format',
- - help='Specify a format for this repository.'
- - ' Current formats are: default, knit,'
- - ' metaweave and weave. Default is knit;'
- - ' metaweave and weave are deprecated',
- - type=get_format_type),
+ takes_options = [repo_format_option,
Option('trees',
help='Allows branches in repository to have'
' a working tree')]
aliases = ["init-repo"]
- - def run(self, location, format=None, trees=False):
- - if format is None:
- - format = get_format_type('default')
- -
- - if location is None:
- - location = '.'
- -
+ def run(self, location, repository_format=None, trees=False):
+ if repository_format is None:
+ repository_format = get_format_type('default')
to_transport = transport.get_transport(location)
try:
to_transport.mkdir('.')
except errors.FileExists:
pass
- - newdir = format.initialize_on_transport(to_transport)
+ newdir = repository_format.initialize_on_transport(to_transport)
repo = newdir.create_repository(shared=True)
repo.set_make_working_trees(trees)
@@ -1296,11 +1295,9 @@
help='show files changed in each revision'),
'show-ids', 'revision',
'log-format',
- - 'line', 'long',
Option('message',
help='show revisions whose message matches
this regexp',
type=str),
- - 'short',
]
encoding_type = 'replace'
@@ -1311,10 +1308,7 @@
forward=False,
revision=None,
log_format=None,
- - message=None,
- - long=False,
- - short=False,
- - line=False):
+ message=None):
from bzrlib.log import log_formatter, show_log
assert message is None or isinstance(message, basestring), \
"invalid message argument %r" % message
@@ -1368,9 +1362,7 @@
(rev2, rev1) = (rev1, rev2)
if (log_format == None):
- - default = b.get_config().log_format()
- - log_format = get_log_format(long=long, short=short,
line=line,
- - default=default)
+ log_format = b.get_config().log_format()
lf = log_formatter(log_format,
show_ids=show_ids,
to_file=self.outf,
@@ -1386,17 +1378,6 @@
search=message)
- -def get_log_format(long=False, short=False, line=False, default='long'):
- - log_format = default
- - if long:
- - log_format = 'long'
- - if short:
- - log_format = 'short'
- - if line:
- - log_format = 'line'
- - return log_format
- -
- -
class cmd_touching_revisions(Command):
"""Return revision-ids which affected a particular file.
@@ -1810,21 +1791,13 @@
during other operations to upgrade.
"""
takes_args = ['url?']
- - takes_options = [
- - Option('format',
- - help='Upgrade to a specific format. Current
formats'
- - ' are: default, knit, metaweave and
weave.'
- - ' Default is knit; metaweave and weave
are'
- - ' deprecated',
- - type=get_format_type),
- - ]
- -
- -
- - def run(self, url='.', format=None):
+ takes_options = [ branch_format_option ]
+
+ def run(self, url='.', branch_format=None):
from bzrlib.upgrade import upgrade
- - if format is None:
- - format = get_format_type('default')
- - upgrade(url, format)
+ if branch_format is None:
+ branch_format = get_format_type('default')
+ upgrade(url, branch_format)
class cmd_whoami(Command):
@@ -2406,9 +2379,6 @@
Option('theirs-only',
'Display changes in the remote branch only'),
'log-format',
- - 'line',
- - 'long',
- - 'short',
'show-ids',
'verbose'
]
@@ -2416,7 +2386,7 @@
@display_command
def run(self, other_branch=None, reverse=False, mine_only=False,
- - theirs_only=False, log_format=None, long=False,
short=False, line=False,
+ theirs_only=False, log_format=None,
show_ids=False, verbose=False):
from bzrlib.missing import find_unmerged, iter_log_data
from bzrlib.log import log_formatter
@@ -2435,10 +2405,8 @@
remote_branch.lock_read()
try:
local_extra, remote_extra = find_unmerged(local_branch,
remote_branch)
- - if (log_format == None):
- - default = local_branch.get_config().log_format()
- - log_format = get_log_format(long=long, short=short,
- - line=line,
default=default)
+ if (log_format is None):
+ log_format = local_branch.get_config().log_format()
lf = log_formatter(log_format,
to_file=self.outf,
show_ids=show_ids,
@@ -2503,7 +2471,8 @@
class cmd_testament(Command):
"""Show testament (signing-form) of a revision."""
- - takes_options = ['revision', 'long',
+ takes_options = ['revision',
+ Option('long', help='Produce long-format testament'),
Option('strict', help='Produce a strict-format'
' testament')]
takes_args = ['branch?']
=== modified file 'bzrlib/commands.py'
- --- bzrlib/commands.py 2006-07-15 14:29:03 +0000
+++ bzrlib/commands.py 2006-08-03 05:21:02 +0000
@@ -28,18 +28,18 @@
# TODO: "--profile=cum", to change sort order. Is there any value in
leaving
# the profile output behind so it can be interactively examined?
- -import sys
+import codecs
+import errno
import os
from warnings import warn
- -import errno
- -import codecs
+import sys
import bzrlib
import bzrlib.errors as errors
from bzrlib.errors import (BzrError,
- - BzrCommandError,
- - BzrCheckError,
+ BzrCommandError, BzrCheckError,
NotBranchError)
+from bzrlib import option
from bzrlib.option import Option
import bzrlib.osutils
from bzrlib.revisionspec import RevisionSpec
@@ -221,7 +221,7 @@
r = dict()
r['help'] = Option.OPTIONS['help']
for o in self.takes_options:
- - if not isinstance(o, Option):
+ if isinstance(o, basestring):
o = Option.OPTIONS[o]
r[o.name] = o
return r
@@ -261,12 +261,6 @@
from bzrlib.help import help_on_command
help_on_command(self.name())
return 0
- - # XXX: This should be handled by the parser
- - allowed_names = self.options().keys()
- - for oname in opts:
- - if oname not in allowed_names:
- - raise BzrOptionError("option '--%s' is not allowed for"
- - " command %r" % (oname, self.name()))
# mix arguments and options into one dictionary
cmdargs = _match_argform(self.name(), self.takes_args, args)
cmdopts = {}
@@ -346,6 +340,7 @@
parsed = [spec, None]
return parsed
+
def parse_args(command, argv, alias_argv=None):
"""Parse command line.
@@ -354,106 +349,16 @@
lookup table, something about the available options, what optargs
they take, and which commands will accept them.
"""
- - # TODO: chop up this beast; make it a method of the Command
- - args = []
- - opts = {}
- - alias_opts = {}
- -
- - cmd_options = command.options()
- - argsover = False
- - proc_aliasarg = True # Are we processing alias_argv now?
- - for proc_argv in alias_argv, argv:
- - while proc_argv:
- - a = proc_argv.pop(0)
- - if argsover:
- - args.append(a)
- - continue
- - elif a == '-':
- - args.append(a)
- - continue
- - elif a == '--':
- - # We've received a standalone -- No more flags
- - argsover = True
- - continue
- - if a[0] == '-':
- - # option names must not be unicode
- - a = str(a)
- - optarg = None
- - if a[1] == '-':
- - mutter(" got option %r", a)
- - if '=' in a:
- - optname, optarg = a[2:].split('=', 1)
- - else:
- - optname = a[2:]
- - if optname not in cmd_options:
- - raise BzrCommandError('unknown option "%s"' % a)
- - else:
- - shortopt = a[1:]
- - if shortopt in Option.SHORT_OPTIONS:
- - # Multi-character options must have a space to
delimit
- - # their value
- - # ^^^ what does this mean? mbp 20051014
- - optname = Option.SHORT_OPTIONS[shortopt].name
- - else:
- - # Single character short options, can be chained,
- - # and have their value appended to their name
- - shortopt = a[1:2]
- - if shortopt not in Option.SHORT_OPTIONS:
- - # We didn't find the multi-character name,
and we
- - # didn't find the single char name
- - raise BzrCommandError('unknown option "%s"'
% a)
- - optname = Option.SHORT_OPTIONS[shortopt].name
- -
- - if a[2:]:
- - # There are extra things on this option
- - # see if it is the value, or if it is another
- - # short option
- - optargfn = Option.OPTIONS[optname].type
- - if optargfn is None:
- - # This option does not take an
argument, so the
- - # next entry is another short option,
pack it
- - # back into the list
- - proc_argv.insert(0, '-' + a[2:])
- - else:
- - # This option takes an argument, so
pack it
- - # into the array
- - optarg = a[2:]
- - if optname not in cmd_options:
- - raise BzrCommandError('unknown option "%s"' %
shortopt)
- - if optname in opts:
- - # XXX: Do we ever want to support this, e.g. for -r?
- - if proc_aliasarg:
- - raise BzrCommandError('repeated option %r' % a)
- - elif optname in alias_opts:
- - # Replace what's in the alias with what's in
the real
- - # argument
- - del alias_opts[optname]
- - del opts[optname]
- - proc_argv.insert(0, a)
- - continue
- - else:
- - raise BzrCommandError('repeated option %r' % a)
- -
- - option_obj = cmd_options[optname]
- - optargfn = option_obj.type
- - if optargfn:
- - if optarg == None:
- - if not proc_argv:
- - raise BzrCommandError('option %r needs an
argument' % a)
- - else:
- - optarg = proc_argv.pop(0)
- - opts[optname] = optargfn(optarg)
- - if proc_aliasarg:
- - alias_opts[optname] = optargfn(optarg)
- - else:
- - if optarg != None:
- - raise BzrCommandError('option %r takes no
argument' % optname)
- - opts[optname] = True
- - if proc_aliasarg:
- - alias_opts[optname] = True
- - else:
- - args.append(a)
- - proc_aliasarg = False # Done with alias argv
+ # TODO: make it a method of the Command?
+ parser = option.get_optparser(command.options())
+ if alias_argv is not None:
+ args = alias_argv + argv
+ else:
+ args = argv
+
+ options, args = parser.parse_args(args)
+ opts = dict([(k, v) for k, v in options.__dict__.iteritems() if
+ v is not option.OptionParser.DEFAULT_VALUE])
return args, opts
=== modified file 'bzrlib/help.py'
- --- bzrlib/help.py 2006-07-30 07:02:22 +0000
+++ bzrlib/help.py 2006-08-03 05:21:02 +0000
@@ -128,26 +128,12 @@
def help_on_command_options(cmd, outfile=None):
- - from bzrlib.option import Option
+ from bzrlib.option import Option, get_optparser
+ if outfile is None:
+ outfile = sys.stdout
options = cmd.options()
- - if not options:
- - return
- - if outfile == None:
- - outfile = sys.stdout
- - outfile.write('\noptions:\n')
- - for option_name, option in sorted(options.items()):
- - l = ' --' + option_name
- - if option.type is not None:
- - l += ' ' + option.argname.upper()
- - short_name = option.short_name()
- - if short_name:
- - assert len(short_name) == 1
- - l += ', -' + short_name
- - l += (30 - len(l)) * ' ' + option.help
- - # TODO: split help over multiple lines with correct indenting and
- - # wrapping
- - wrapped = textwrap.fill(l, initial_indent='',
subsequent_indent=30*' ')
- - outfile.write(wrapped + '\n')
+ outfile.write('\n')
+ outfile.write(get_optparser(options).format_option_help())
def help_commands(outfile=None):
=== modified file 'bzrlib/option.py'
- --- bzrlib/option.py 2006-07-28 16:05:23 +0000
+++ bzrlib/option.py 2006-08-04 02:30:29 +0000
@@ -17,6 +17,7 @@
# TODO: For things like --diff-prefix, we want a way to customize the
display
# of the option argument.
+import optparse
import re
from bzrlib.trace import warning
@@ -112,6 +113,44 @@
(typestring, type_list)
raise BzrCommandError(msg)
+class EnumOption(object):
+
+ def __init__(self, name, factory, choices):
+ self.name = name
+ self.factory = factory
+ self.choices = choices
+ self.default = None
+
+ def python_name(self):
+ """Conver a name with spaces and caps to a python variable name"""
+ return self.name.lower().replace(' ', '_')
+
+ def add_option(self, parser, short_name):
+ """Add this option to an Optparse parser"""
+ group = optparse.OptionGroup(parser, self.name)
+ for name, help in self.choices:
+ option_strings = ['--%s' % name]
+ group.add_option(action='callback',
+ callback=self._optparse_callback,
+ callback_args=(name,),
+ metavar=self.name,
+ help=help,
+ default=OptionParser.DEFAULT_VALUE,
+ dest=self.python_name(),
+ *option_strings)
+ parser.add_option_group(group)
+
+ def _optparse_callback(self, option, opt, value, parser, evalue):
+ setattr(parser.values, option.dest, self.factory(evalue))
+
+ def iter_switches(self):
+ """Iterate through the list of switches provided by the option
+
+ :return: an iterator of (name, short_name, argname, help)
+ """
+ return ((n, None, None, h) for n, h in self.choices)
+
+
class Option(object):
"""Description of a command line option"""
# TODO: Some way to show in help a description of the option argument
@@ -153,11 +192,85 @@
if option is self:
return short
+ def get_negation_name(self):
+ if self.name.startswith('no-'):
+ return self.name[3:]
+ else:
+ return 'no-' + self.name
+
+ def add_option(self, parser, short_name):
+ """Add this option to an Optparse parser"""
+ option_strings = ['--%s' % self.name]
+ if short_name is not None:
+ option_strings.append('-%s' % short_name)
+ optargfn = self.type
+ if optargfn is None:
+ parser.add_option(action='store_true', dest=self.name,
+ help=self.help,
+ default=OptionParser.DEFAULT_VALUE,
+ *option_strings)
+ negation_strings = ['--%s' % self.get_negation_name()]
+ parser.add_option(action='store_const', dest=self.name,
+ help=optparse.SUPPRESS_HELP,
+ const=OptionParser.DEFAULT_VALUE,
+ *negation_strings)
+ else:
+ parser.add_option(action='callback',
+ callback=self._optparse_callback,
+ type='string', metavar=self.argname.upper(),
+ help=self.help,
+ default=OptionParser.DEFAULT_VALUE,
+ *option_strings)
+
+ def _optparse_callback(self, option, opt, value, parser):
+ setattr(parser.values, self.name, self.type(value))
+
+ def iter_switches(self):
+ """Iterate through the list of switches provided by the option
+
+ :return: an iterator of (name, short_name, argname, help)
+ """
+ argname = self.argname
+ if argname is not None:
+ argname = argname.upper()
+ yield self.name, self.short_name(), argname, self.help
+
+
+class OptionParser(optparse.OptionParser):
+ """OptionParser that raises exceptions instead of exiting"""
+
+ DEFAULT_VALUE = object()
+
+ def error(self, message):
+ raise BzrCommandError(message)
+
+
+def get_optparser(options):
+ """Generate an optparse parser for bzrlib-style options"""
+
+ parser = OptionParser()
+ parser.remove_option('--help')
+ short_options = dict((k.name, v) for v, k in
+ Option.SHORT_OPTIONS.iteritems())
+ for option in options.itervalues():
+ option.add_option(parser, short_options.get(option.name))
+ return parser
+
def _global_option(name, **kwargs):
"""Register o as a global option."""
Option.OPTIONS[name] = Option(name, **kwargs)
+Option.OPTIONS['merge-type']=EnumOption('Merge type', get_merge_type, [
+ ('merge3', 'Use built-in diff3-style merge'),
+ ('diff3', 'Use external diff3 merge'),
+ ('weave', 'Use knit merge')])
+
+Option.OPTIONS['log-format']=EnumOption('Log format', str, [
+ ('long', 'Multi-line logs with merges shown'),
+ ('short', 'Two-line logs'),
+ ('line', 'One-line logs')])
+
_global_option('all')
_global_option('overwrite', help='Ignore differences between branches and '
'overwrite unconditionally')
@@ -189,14 +302,8 @@
_global_option('version')
_global_option('email')
_global_option('update')
- -_global_option('log-format', type=str, help="Use this log format")
- -_global_option('long', help='Use detailed log format. Same as
- --log-format long')
- -_global_option('short', help='Use moderately short log format. Same as
- --log-format short')
- -_global_option('line', help='Use log format with one line per revision.
Same as --log-format line')
_global_option('root', type=str)
_global_option('no-backup')
- -_global_option('merge-type', type=_parse_merge_type,
- - help='Select a particular merge algorithm')
_global_option('pattern', type=str)
_global_option('quiet')
_global_option('remember', help='Remember the specified location as a'
@@ -217,6 +324,5 @@
Option.SHORT_OPTIONS['m'] = Option.OPTIONS['message']
Option.SHORT_OPTIONS['r'] = Option.OPTIONS['revision']
Option.SHORT_OPTIONS['v'] = Option.OPTIONS['verbose']
- -Option.SHORT_OPTIONS['l'] = Option.OPTIONS['long']
Option.SHORT_OPTIONS['q'] = Option.OPTIONS['quiet']
Option.SHORT_OPTIONS['p'] = Option.OPTIONS['prefix']
=== modified file 'bzrlib/tests/blackbox/test_bound_branches.py'
- --- bzrlib/tests/blackbox/test_bound_branches.py 2006-07-28 16:05:23 +0000
+++ bzrlib/tests/blackbox/test_bound_branches.py 2006-08-03 22:53:19 +0000
@@ -35,7 +35,7 @@
super(TestLegacyFormats, self).setUp()
self.build_tree(['master/', 'child/'])
self.run_bzr('init', 'master')
- - self.run_bzr('init', '--format=weave', 'child')
+ self.run_bzr('init', '--weave', 'child')
os.chdir('child')
def test_bind_format_6_bzrdir(self):
=== modified file 'bzrlib/tests/blackbox/test_init.py'
- --- bzrlib/tests/blackbox/test_init.py 2006-07-28 16:05:23 +0000
+++ bzrlib/tests/blackbox/test_init.py 2006-08-03 22:53:19 +0000
@@ -31,15 +31,15 @@
def test_init_with_format(self):
# Verify bzr init --format constructs something plausible
t = self.get_transport()
- - self.runbzr('init --format default')
+ self.runbzr('init --default')
self.assertIsDirectory('.bzr', t)
self.assertIsDirectory('.bzr/checkout', t)
self.assertIsDirectory('.bzr/checkout/lock', t)
def test_init_weave(self):
- - # --format=weave should be accepted to allow interoperation with
+ # --weave should be accepted to allow interoperation with
# old releases when desired.
- - out, err = self.run_bzr('init', '--format=weave')
+ out, err = self.run_bzr('init', '--weave')
self.assertEqual('', out)
self.assertEqual('', err)
=== modified file 'bzrlib/tests/blackbox/test_logformats.py'
- --- bzrlib/tests/blackbox/test_logformats.py 2006-06-20 03:57:11 +0000
+++ bzrlib/tests/blackbox/test_logformats.py 2006-08-03 22:53:19 +0000
@@ -39,7 +39,7 @@
self.bzr('commit', '-m', '2')
# only the lines formatter is this short
- - self.assertEquals(7, len(self.bzr('log', '--log-format',
'short').split('\n')))
+ self.assertEquals(7, len(self.bzr('log', '--short').split('\n')))
def test_missing_default_format(self):
self.setup_config()
@@ -91,7 +91,7 @@
os.chdir('../b')
- - self.assertEquals(9, len(self.bzr('missing', '--log-format',
'short', retcode=1).split('\n')))
+ self.assertEquals(9, len(self.bzr('missing', '--short',
retcode=1).split('\n')))
os.chdir('..')
=== modified file 'bzrlib/tests/blackbox/test_merge.py'
- --- bzrlib/tests/blackbox/test_merge.py 2006-07-26 07:11:35 +0000
+++ bzrlib/tests/blackbox/test_merge.py 2006-08-03 22:53:19 +0000
@@ -44,7 +44,7 @@
def test_merge_reprocess(self):
d = BzrDir.create_standalone_workingtree('.')
d.commit('h')
- - self.run_bzr('merge', '.', '--reprocess', '--merge-type',
'weave')
+ self.run_bzr('merge', '.', '--reprocess', '--weave')
def test_merge(self):
from bzrlib.branch import Branch
@@ -63,11 +63,11 @@
# We can't merge when there are in-tree changes
self.runbzr('merge ../b', retcode=3)
self.runbzr(['commit', '-m', "Like an epidemic of u's"])
- - self.runbzr('merge ../b -r last:1..last:1 --merge-type blooof',
+ self.runbzr('merge ../b -r last:1..last:1 --blooof',
retcode=3)
- - self.runbzr('merge ../b -r last:1..last:1 --merge-type merge3')
+ self.runbzr('merge ../b -r last:1..last:1 --merge3')
self.runbzr('revert --no-backup')
- - self.runbzr('merge ../b -r last:1..last:1 --merge-type weave')
+ self.runbzr('merge ../b -r last:1..last:1 --weave')
self.runbzr('revert --no-backup')
self.runbzr('merge ../b -r last:1..last:1 --reprocess')
self.runbzr('revert --no-backup')
=== modified file 'bzrlib/tests/blackbox/test_remerge.py'
- --- bzrlib/tests/blackbox/test_remerge.py 2006-07-02 19:31:42 +0000
+++ bzrlib/tests/blackbox/test_remerge.py 2006-08-03 22:53:19 +0000
@@ -69,9 +69,9 @@
os.unlink('question.OTHER')
self.run_bzr_error(['jello is not versioned'],
- - 'remerge', 'jello', '--merge-type', 'weave')
+ 'remerge', 'jello', '--weave')
self.run_bzr_error(['conflicts encountered'],
- - 'remerge', 'hello', '--merge-type', 'weave',
+ 'remerge', 'hello', '--weave',
retcode=1)
self.failUnlessExists('hello.OTHER')
@@ -82,7 +82,7 @@
'file-id', 'hello.THIS')
self.run_bzr_error(['conflicts encountered'],
- - 'remerge', '--merge-type', 'weave', retcode=1)
+ 'remerge', '--weave', retcode=1)
self.failUnlessExists('hello.OTHER')
self.failIfExists('hello.BASE')
@@ -90,11 +90,11 @@
self.assertFalse('hi world' in conflict_text)
self.run_bzr_error(['Showing base is not supported.*Weave'],
- - 'remerge', '.', '--merge-type', 'weave',
'--show-base')
+ 'remerge', '.', '--weave', '--show-base')
self.run_bzr_error(['Can\'t reprocess and show base'],
'remerge', '.', '--show-base', '--reprocess')
self.run_bzr_error(['conflicts encountered'],
- - 'remerge', '.', '--merge-type', 'weave',
'--reprocess',
+ 'remerge', '.', '--weave', '--reprocess',
retcode=1)
self.run_bzr_error(['conflicts encountered'],
'remerge', 'hello', '--show-base',
=== modified file 'bzrlib/tests/blackbox/test_selftest.py'
- --- bzrlib/tests/blackbox/test_selftest.py 2006-07-20 04:04:58 +0000
+++ bzrlib/tests/blackbox/test_selftest.py 2006-08-03 23:20:04 +0000
@@ -152,9 +152,8 @@
result = self.run_bzr_subprocess('--versionn', retcode=3)
result = self.run_bzr_subprocess('--versionn', retcode=None)
self.assertContainsRe(result[1], 'unknown command')
- - err = self.run_bzr_subprocess('merge', '--merge-type', 'magic
merge',
- - retcode=3)[1]
- - self.assertContainsRe(err, 'No known merge type magic merge')
+ err = self.run_bzr_subprocess('merge', '--magic-merge',
retcode=3)[1]
+ self.assertContainsRe(err, 'no such option: --magic-merge')
class TestRunBzrError(ExternalBase):
=== modified file 'bzrlib/tests/blackbox/test_shared_repository.py'
- --- bzrlib/tests/blackbox/test_shared_repository.py 2006-05-05 01:29:34
+0000
+++ bzrlib/tests/blackbox/test_shared_repository.py 2006-08-03 22:53:19
+0000
@@ -45,7 +45,7 @@
def test_init(self):
self.run_bzr("init-repo", "a")
- - self.run_bzr("init", "--format=default", "a/b")
+ self.run_bzr("init", "--default", "a/b")
dir = bzrlib.bzrdir.BzrDir.open('a')
self.assertIs(dir.open_repository().is_shared(), True)
self.assertRaises(errors.NotBranchError, dir.open_branch)
@@ -57,7 +57,7 @@
def test_branch(self):
self.run_bzr("init-repo", "a")
- - self.run_bzr("init", "--format=default", "a/b")
+ self.run_bzr("init", "--default", "a/b")
self.run_bzr('branch', 'a/b', 'a/c')
cdir = bzrlib.bzrdir.BzrDir.open('a/c')
cdir.open_branch()
@@ -66,7 +66,7 @@
def test_branch_tree(self):
self.run_bzr("init-repo", "--trees", "a")
- - self.run_bzr("init", "--format=default", "b")
+ self.run_bzr("init", "--default", "b")
file('b/hello', 'wt').write('bar')
self.run_bzr("add", "b/hello")
self.run_bzr("commit", "-m", "bar", "b/hello")
=== modified file 'bzrlib/tests/blackbox/test_upgrade.py'
- --- bzrlib/tests/blackbox/test_upgrade.py 2006-07-28 16:05:23 +0000
+++ bzrlib/tests/blackbox/test_upgrade.py 2006-08-04 02:46:55 +0000
@@ -110,10 +110,10 @@
def test_upgrade_explicit_metaformat(self):
# users can force an upgrade to metadir format.
url = get_transport(self.get_url('format_5_branch')).base
- - # check --format takes effect
+ # check --metaweave takes effect
bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirFormat5())
(out, err) = self.run_bzr_captured(
- - ['upgrade', '--format=metaweave', url])
+ ['upgrade', '--metaweave', url])
self.assertEqualDiff("""starting upgrade of %s
making backup of tree history
%s.bzr has been backed up to %s.bzr.backup
@@ -134,10 +134,10 @@
# users can force an upgrade to knit format from a metadir weave
# branch
url = get_transport(self.get_url('metadir_weave_branch')).base
- - # check --format takes effect
+ # check --knit takes effect
bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirFormat5())
(out, err) = self.run_bzr_captured(
- - ['upgrade', '--format=knit', url])
+ ['upgrade', '--knit', url])
self.assertEqualDiff("""starting upgrade of %s
making backup of tree history
%s.bzr has been backed up to %s.bzr.backup
@@ -155,8 +155,8 @@
repository.RepositoryFormatKnit1))
def test_upgrade_repo(self):
- - self.run_bzr('init-repository', '--format=metaweave', 'repo')
- - self.run_bzr('upgrade', '--format=knit', 'repo')
+ self.run_bzr('init-repository', '--metaweave', 'repo')
+ self.run_bzr('upgrade', '--knit', 'repo')
class SFTPTests(TestCaseWithSFTPServer):
@@ -173,10 +173,10 @@
ui.ui_factory = self.old_ui_factory
def test_upgrade_url(self):
- - self.run_bzr('init', '--format=weave')
+ self.run_bzr('init', '--weave')
t = get_transport(self.get_url())
url = t.base
- - out, err = self.run_bzr('upgrade', '--format=knit', url)
+ out, err = self.run_bzr('upgrade', '--knit', url)
self.assertEqualDiff("""starting upgrade of %s
making backup of tree history
%s.bzr has been backed up to %s.bzr.backup
=== modified file 'bzrlib/tests/test_options.py'
- --- bzrlib/tests/test_options.py 2006-07-11 21:46:11 +0000
+++ bzrlib/tests/test_options.py 2006-08-04 02:25:40 +0000
@@ -1,8 +1,10 @@
# Copyright (C) 2005, 2006 Canonical Ltd
+from bzrlib.builtins import cmd_commit, cmd_log, cmd_status
+from bzrlib.commands import Command, parse_args
+from bzrlib import errors
+from bzrlib import option
from bzrlib.tests import TestCase
- -from bzrlib.commands import Command, parse_args
- -from bzrlib.builtins import cmd_commit, cmd_log, cmd_status
# TODO: might be nice to just parse them into a structured form and test
# against that, rather than running the whole command.
@@ -28,8 +30,9 @@
def test_option_help(self):
"""Options have help strings."""
out, err = self.run_bzr_captured(['commit', '--help'])
- - self.assertContainsRe(out, r'--file.*file containing commit
message')
- - self.assertContainsRe(out, r'--help.*-h')
+ self.assertContainsRe(out, r'--file(.|\n)*file containing commit'
+ ' message')
+ self.assertContainsRe(out, r'-h.*--help')
def test_option_help_global(self):
"""Global options have help strings."""
@@ -44,12 +47,55 @@
def test_unknown_short_opt(self):
out, err = self.run_bzr_captured(['help', '-r'], retcode=3)
- - self.assertContainsRe(err, r'unknown option')
+ self.assertContainsRe(err, r'no such option')
def test_allow_dash(self):
"""Test that we can pass a plain '-' as an argument."""
self.assertEqual((['-'], {}), parse_args(cmd_commit(), ['-']))
+ def test_conversion(self):
+ def parse(options, args):
+ parser = option.get_optparser(dict((o.name, o) for o in
options))
+ return parser.parse_args(args)
+ options = [option.EnumOption('Lawn mower', str,
+ [('fast', 'mow quickly'), ('careful', 'mow
carefully')])]
+ opts, args = parse(options, ['--fast', '--careful'])
+ self.assertEqual('careful', opts.lawn_mower)
+ options = [option.EnumOption('Number', int, [('11', 'one'),
+ ('22', 'two')])]
+ opts, args = parse(options, ['--22'])
+ self.assertEqual(22, opts.number)
+
+ options = [option.Option('hello')]
+ opts, args = parse(options, ['--no-hello', '--hello'])
+ self.assertEqual(True, opts.hello)
+ opts, args = parse(options, [])
+ self.assertEqual(option.OptionParser.DEFAULT_VALUE, opts.hello)
+ opts, args = parse(options, ['--hello', '--no-hello'])
+ self.assertEqual(option.OptionParser.DEFAULT_VALUE, opts.hello)
+ options = [option.Option('number', type=int)]
+ opts, args = parse(options, ['--number', '6'])
+ self.assertEqual(6, opts.number)
+ self.assertRaises(errors.BzrCommandError, parse, options,
['--number'])
+ self.assertRaises(errors.BzrCommandError, parse, options,
+ ['--no-number'])
+
+ def test_iter_switches(self):
+ opt = option.EnumOption('Lawn mower', str,
+ [('fast', 'mow quickly'),
+ ('careful', 'mow carefully')])
+ self.assertEqual(list(opt.iter_switches()),
+ [('fast', None, None, 'mow quickly'),
+ ('careful', None, None, 'mow carefully')])
+ opt = option.Option('hello', help='fg')
+ self.assertEqual(list(opt.iter_switches()),
+ [('hello', None, None, 'fg')])
+ opt = option.Option('hello', help='fg', type=int)
+ self.assertEqual(list(opt.iter_switches()),
+ [('hello', None, 'ARG', 'fg')])
+ opt = option.Option('hello', help='fg', type=int, argname='gar')
+ self.assertEqual(list(opt.iter_switches()),
+ [('hello', None, 'GAR', 'fg')])
# >>> parse_args('log -r 500'.split())
# (['log'], {'revision': [<RevisionSpec_int 500>]})
=== modified file 'tools/doc_generate/autodoc_man.py'
- --- tools/doc_generate/autodoc_man.py 2006-07-31 06:13:23 +0000
+++ tools/doc_generate/autodoc_man.py 2006-08-03 23:45:50 +0000
@@ -110,19 +110,19 @@
if options:
option_str = "\nOptions:\n"
for option_name, option in sorted(options.items()):
- - l = ' --' + option_name
- - if option.type is not None:
- - l += ' ' + option.argname.upper()
- - short_name = option.short_name()
- - if short_name:
- - assert len(short_name) == 1
- - l += ', -' + short_name
- - l += (30 - len(l)) * ' ' + option.help
- - # TODO: Split help over multiple lines with
- - # correct indenting and wrapping.
- - wrapped = textwrap.fill(l, initial_indent='',
- - subsequent_indent=30*' ')
- - option_str = option_str + wrapped + '\n'
+ for name, short_name, argname, help in option.iter_switches():
+ l = ' --' + name
+ if argname is not None:
+ l += ' ' + argname
+ if short_name:
+ assert len(short_name) == 1
+ l += ', -' + short_name
+ l += (30 - len(l)) * ' ' + help
+ # TODO: Split help over multiple lines with
+ # correct indenting and wrapping.
+ wrapped = textwrap.fill(l, initial_indent='',
+ subsequent_indent=30*' ')
+ option_str = option_str + wrapped + '\n'
aliases_str = ""
if cmd.aliases:
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iD8DBQFE2Mnx0F+nu1YWqI0RAgsoAJ9or16IQdFWUo/HiYBuvBaTMYaDAgCdGveG
5gO/eRJDpWTXwzkVcXBg9hs=
=IRwh
-----END PGP SIGNATURE-----
More information about the bazaar
mailing list