Rev 2599: Add test for and documentation of option style, fix up existing options to comply in http://sourcefrog.net/bzr/check-options

Martin Pool mbp at sourcefrog.net
Tue Jul 10 11:20:29 BST 2007


At http://sourcefrog.net/bzr/check-options

------------------------------------------------------------
revno: 2599
revision-id: mbp at sourcefrog.net-20070710102027-2os88re33c57m522
parent: pqm at pqm.ubuntu.com-20070710021221-8o98e4q8vcpaarnk
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: check-options
timestamp: Tue 2007-07-10 20:20:27 +1000
message:
  Add test for and documentation of option style, fix up existing options to comply
modified:
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/bundle/commands.py      __init__.py-20050617152058-1b6530d9ab85c11c
  bzrlib/cmd_version_info.py     __init__.py-20051228204928-697d01fdca29c99b
  bzrlib/conflicts.py            conflicts.py-20051001061850-78ef952ba63d2b42
  bzrlib/option.py               option.py-20051014052914-661fb36e76e7362f
  bzrlib/plugins/launchpad/__init__.py __init__.py-20060315182712-2d5feebd2a1032dc
  bzrlib/tests/test_options.py   testoptions.py-20051014093702-96457cfc86319a8f
  doc/developers/HACKING         HACKING-20050805200004-2a5dc975d870f78c
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2007-07-06 17:21:57 +0000
+++ b/bzrlib/builtins.py	2007-07-10 10:20:27 +0000
@@ -168,8 +168,8 @@
     
     takes_args = ['file*']
     takes_options = ['show-ids', 'revision',
-                     Option('short', help='Give short SVN-style status lines'),
-                     Option('versioned', help='Only show versioned files')]
+                     Option('short', help='Give short SVN-style status lines.'),
+                     Option('versioned', help='Only show versioned files.')]
     aliases = ['st', 'stat']
 
     encoding_type = 'replace'
@@ -340,7 +340,7 @@
     takes_args = ['file*']
     takes_options = ['no-recurse', 'dry-run', 'verbose',
                      Option('file-ids-from', type=unicode,
-                            help='Lookup file ids from here')]
+                            help='Lookup file ids from this tree.')]
     encoding_type = 'replace'
     _see_also = ['remove']
 
@@ -506,9 +506,9 @@
     """
 
     takes_args = ['names*']
-    takes_options = [Option("after", help="move only the bzr identifier"
-        " of the file (file has already been moved). Use this flag if"
-        " bzr is not able to detect this itself.")]
+    takes_options = [Option("after", help="Move only the bzr identifier"
+        " of the file, because the file has already been moved."),
+        ]
     aliases = ['move', 'rename']
     encoding_type = 'replace'
 
@@ -556,8 +556,8 @@
     _see_also = ['push', 'update', 'status-flags']
     takes_options = ['remember', 'overwrite', 'revision', 'verbose',
         Option('directory',
-            help='branch to pull into, '
-                 'rather than the one containing the working directory',
+            help='Branch to pull into, '
+                 'rather than the one containing the working directory.',
             short_name='d',
             type=unicode,
             ),
@@ -664,17 +664,17 @@
     takes_options = ['remember', 'overwrite', 'verbose',
         Option('create-prefix',
                help='Create the path leading up to the branch '
-                    'if it does not already exist'),
+                    'if it does not already exist.'),
         Option('directory',
-            help='branch to push from, '
-                 'rather than the one containing the working directory',
+            help='Branch to push from, '
+                 'rather than the one containing the working directory.',
             short_name='d',
             type=unicode,
             ),
         Option('use-existing-dir',
                help='By default push will fail if the target'
                     ' directory exists, but does not already'
-                    ' have a control directory. This flag will'
+                    ' have a control directory.  This flag will'
                     ' allow push to proceed.'),
         ]
     takes_args = ['location?']
@@ -907,9 +907,9 @@
     takes_args = ['branch_location?', 'to_location?']
     takes_options = ['revision',
                      Option('lightweight',
-                            help="perform a lightweight checkout. Lightweight "
+                            help="Perform a lightweight checkout.  Lightweight "
                                  "checkouts depend on access to the branch for "
-                                 "every operation. Normal checkouts can perform "
+                                 "every operation.  Normal checkouts can perform "
                                  "common operations like diff and status without "
                                  "such access, and also support local commits."
                             ),
@@ -1066,7 +1066,7 @@
     """
     takes_args = ['file*']
     takes_options = ['verbose',
-        Option('new', help='remove newly-added files'),
+        Option('new', help='Remove newly-added files.'),
         RegistryOption.from_kwargs('file-deletion-strategy',
             'The file deletion mode to be used',
             title='Deletion Strategy', value_switches=True, enum_switch=False,
@@ -1240,7 +1240,7 @@
     takes_options = [
         Option('create-prefix',
                help='Create the path leading up to the branch '
-                    'if it does not already exist'),
+                    'if it does not already exist.'),
          RegistryOption('format',
                 help='Specify a format for this branch. '
                 'See "help formats".',
@@ -1325,13 +1325,13 @@
     takes_args = ["location"]
     takes_options = [RegistryOption('format',
                             help='Specify a format for this repository. See'
-                                 ' "bzr help formats" for details',
+                                 ' "bzr help formats" for details.',
                             registry=bzrdir.format_registry,
                             converter=bzrdir.format_registry.make_bzrdir,
                             value_switches=True, title='Repository format'),
                      Option('no-trees',
                              help='Branches in the repository will default to'
-                                  ' not having a working tree'),
+                                  ' not having a working tree.'),
                     ]
     aliases = ["init-repo"]
 
@@ -1390,7 +1390,7 @@
         Option('prefix', type=str,
                short_name='p',
                help='Set prefixes to added to old and new filenames, as '
-                    'two values separated by a colon. (eg "old/:new/")'),
+                    'two values separated by a colon. (eg "old/:new/").'),
         ]
     aliases = ['di', 'dif']
     encoding_type = 'exact'
@@ -1581,20 +1581,20 @@
     # TODO: Make --revision support uuid: and hash: [future tag:] notation.
 
     takes_args = ['location?']
-    takes_options = [Option('forward', 
-                            help='show from oldest to newest'),
-                     'timezone', 
-                     Option('verbose', 
+    takes_options = [Option('forward',
+                            help='Show from oldest to newest.'),
+                     'timezone',
+                     Option('verbose',
                              short_name='v',
-                             help='show files changed in each revision'),
+                             help='Show files changed in each revision.'),
                      'show-ids', 'revision',
                      'log-format',
                      Option('message',
                             short_name='m',
-                            help='show revisions whose message matches this regexp',
+                            help='Show revisions whose message matches this regexp.',
                             type=str),
-                     Option('limit', 
-                            help='limit the output to the first N revisions',
+                     Option('limit',
+                            help='Limit the output to the first N revisions.',
                             type=_parse_limit),
                      ]
     encoding_type = 'replace'
@@ -1717,15 +1717,17 @@
     # TODO: Take a revision or remote path and list that tree instead.
     takes_options = ['verbose', 'revision',
                      Option('non-recursive',
-                            help='don\'t recurse into sub-directories'),
+                            help='Don\'t recurse into subdirectories.'),
                      Option('from-root',
                             help='Print all paths from the root of the branch.'),
                      Option('unknown', help='Print unknown files'),
                      Option('versioned', help='Print versioned files'),
                      Option('ignored', help='Print ignored files'),
-
-                     Option('null', help='Null separate the files'),
-                     'kind', 'show-ids'
+                     Option('null',
+                            help='Write an ascii NUL (\\0) separator '
+                            'between files rather than a newline.'),
+                     'kind',
+                     'show-ids',
                     ]
     @display_command
     def run(self, revision=None, verbose=False, 
@@ -1850,9 +1852,9 @@
     _see_also = ['status', 'ignored']
     takes_args = ['name_pattern*']
     takes_options = [
-                     Option('old-default-rules',
-                            help='Out the ignore rules bzr < 0.9 always used.')
-                     ]
+        Option('old-default-rules',
+               help='Write out the ignore rules bzr < 0.9 always used.')
+        ]
     
     def run(self, name_pattern_list=None, old_default_rules=None):
         from bzrlib.atomicfile import AtomicFile
@@ -2094,26 +2096,27 @@
 
     _see_also = ['bugs', 'uncommit']
     takes_args = ['selected*']
-    takes_options = ['message', 'verbose', 
-                     Option('unchanged',
-                            help='commit even if nothing has changed'),
-                     Option('file', type=str, 
-                            short_name='F',
-                            argname='msgfile',
-                            help='file containing commit message'),
-                     Option('strict',
-                            help="refuse to commit if there are unknown "
-                            "files in the working tree."),
-                     ListOption('fixes', type=str,
-                                help="mark a bug as being fixed by this "
-                                     "revision."),
-                     Option('local',
-                            help="perform a local only commit in a bound "
-                                 "branch. Such commits are not pushed to "
-                                 "the master branch until a normal commit "
-                                 "is performed."
-                            ),
-                     ]
+    takes_options = [
+            'message',
+            'verbose',
+             Option('unchanged',
+                    help='Commit even if nothing has changed.'),
+             Option('file', type=str,
+                    short_name='F',
+                    argname='msgfile',
+                    help='Take commit message from this file.'),
+             Option('strict',
+                    help="Refuse to commit if there are unknown "
+                    "files in the working tree."),
+             ListOption('fixes', type=str,
+                    help="Mark a bug as being fixed by this revision."),
+             Option('local',
+                    help="Perform a local commit in a bound "
+                         "branch.  Local commits are not pushed to "
+                         "the master branch until a normal commit "
+                         "is performed."
+                    ),
+             ]
     aliases = ['ci', 'checkin']
 
     def _get_bug_fix_properties(self, fixes, branch):
@@ -2250,7 +2253,7 @@
     takes_options = [
                     RegistryOption('format',
                         help='Upgrade to a specific format.  See "bzr help'
-                             ' formats" for details',
+                             ' formats" for details.',
                         registry=bzrdir.format_registry,
                         converter=bzrdir.format_registry.make_bzrdir,
                         value_switches=True, title='Branch format'),
@@ -2271,10 +2274,10 @@
         bzr whoami 'Frank Chu <fchu at example.com>'
     """
     takes_options = [ Option('email',
-                             help='display email address only'),
+                             help='Display email address only.'),
                       Option('branch',
-                             help='set identity for the current branch instead of '
-                                  'globally'),
+                             help='Set identity for the current branch instead of '
+                                  'globally.'),
                     ]
     takes_args = ['name?']
     encoding_type = 'replace'
@@ -2394,40 +2397,41 @@
     takes_args = ['testspecs*']
     takes_options = ['verbose',
                      Option('one',
-                             help='stop when one test fails',
+                             help='Stop when one test fails.',
                              short_name='1',
                              ),
                      Option('keep-output',
-                            help='keep output directories when tests fail'),
+                            help='Keep output directories when tests fail.'),
                      Option('transport',
                             help='Use a different transport by default '
                                  'throughout the test suite.',
                             type=get_transport_type),
-                     Option('benchmark', help='run the bzr benchmarks.'),
+                     Option('benchmark',
+                            help='Run the benchmarks rather than selftests.'),
                      Option('lsprof-timed',
-                            help='generate lsprof output for benchmarked'
+                            help='Generate lsprof output for benchmarked'
                                  ' sections of code.'),
                      Option('cache-dir', type=str,
-                            help='a directory to cache intermediate'
-                                 ' benchmark steps'),
+                            help='Cache intermediate benchmark output in this '
+                                 'directory.'),
                      Option('clean-output',
-                            help='clean temporary tests directories'
-                                 ' without running tests'),
+                            help='Clean temporary tests directories'
+                                 ' without running tests.'),
                      Option('first',
-                            help='run all tests, but run specified tests first',
+                            help='Run all tests, but run specified tests first.',
                             short_name='f',
                             ),
                      Option('numbered-dirs',
-                            help='use numbered dirs for TestCaseInTempDir'),
+                            help='Use numbered dirs for TestCaseInTempDir.'),
                      Option('list-only',
-                            help='list the tests instead of running them'),
+                            help='List the tests instead of running them.'),
                      Option('randomize', type=str, argname="SEED",
-                            help='randomize the order of tests using the given'
-                                 ' seed or "now" for the current time'),
+                            help='Randomize the order of tests using the given'
+                                 ' seed or "now" for the current time.'),
                      Option('exclude', type=str, argname="PATTERN",
                             short_name='x',
-                            help='exclude tests that match this regular'
-                                 ' expression'),
+                            help='Exclude tests that match this regular'
+                                 ' expression.'),
                      ]
     encoding_type = 'replace'
 
@@ -2587,16 +2591,16 @@
     takes_args = ['branch?']
     takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
         Option('show-base', help="Show base revision text in "
-               "conflicts"),
+               "conflicts."),
         Option('uncommitted', help='Apply uncommitted changes'
-               ' from a working copy, instead of branch changes'),
+               ' from a working copy, instead of branch changes.'),
         Option('pull', help='If the destination is already'
                 ' completely merged into the source, pull from the'
-                ' source rather than merging. When this happens,'
+                ' source rather than merging.  When this happens,'
                 ' you do not need to commit the result.'),
         Option('directory',
             help='Branch to merge into, '
-                 'rather than the one containing the working directory',
+                 'rather than the one containing the working directory.',
             short_name='d',
             type=unicode,
             ),
@@ -2761,9 +2765,12 @@
         additional processing to reduce the size of conflict regions.
     """
     takes_args = ['file*']
-    takes_options = ['merge-type', 'reprocess',
-                     Option('show-base', help="Show base revision text in "
-                            "conflicts")]
+    takes_options = [
+            'merge-type',
+            'reprocess',
+            Option('show-base',
+                   help="Show base revision text in conflicts."),
+            ]
 
     def run(self, file_list=None, merge_type=None, show_base=False,
             reprocess=False):
@@ -2893,7 +2900,9 @@
     """
 
     _see_also = ['topics']
-    takes_options = [Option('long', 'show help on all commands')]
+    takes_options = [
+            Option('long', 'Show help on all commands.'),
+            ]
     takes_args = ['topic?']
     aliases = ['?', '--help', '-?', '-h']
     
@@ -2942,17 +2951,18 @@
 
     _see_also = ['merge', 'pull']
     takes_args = ['other_branch?']
-    takes_options = [Option('reverse', 'Reverse the order of revisions'),
-                     Option('mine-only', 
-                            'Display changes in the local branch only'),
-                     Option('this' , 'same as --mine-only'),
-                     Option('theirs-only', 
-                            'Display changes in the remote branch only'),
-                     Option('other', 'same as --theirs-only'),
-                     'log-format',
-                     'show-ids',
-                     'verbose'
-                     ]
+    takes_options = [
+            Option('reverse', 'Reverse the order of revisions.'),
+            Option('mine-only',
+                   'Display changes in the local branch only.'),
+            Option('this' , 'Same as --mine-only.'),
+            Option('theirs-only',
+                   'Display changes in the remote branch only.'),
+            Option('other', 'Same as --theirs-only.'),
+            'log-format',
+            'show-ids',
+            'verbose'
+            ]
     encoding_type = 'replace'
 
     @display_command
@@ -3053,10 +3063,11 @@
 
 class cmd_testament(Command):
     """Show testament (signing-form) of a revision."""
-    takes_options = ['revision',
-                     Option('long', help='Produce long-format testament'), 
-                     Option('strict', help='Produce a strict-format'
-                            ' testament')]
+    takes_options = [
+            'revision',
+            Option('long', help='Produce long-format testament.'),
+            Option('strict',
+                   help='Produce a strict-format testament.')]
     takes_args = ['branch?']
     @display_command
     def run(self, branch=u'.', revision=None, long=False, strict=False):
@@ -3095,8 +3106,8 @@
     #       with new uncommitted lines marked
     aliases = ['ann', 'blame', 'praise']
     takes_args = ['filename']
-    takes_options = [Option('all', help='show annotations on all lines'),
-                     Option('long', help='show date in annotations'),
+    takes_options = [Option('all', help='Show annotations on all lines.'),
+                     Option('long', help='Show commit date in annotations.'),
                      'revision',
                      'show-ids',
                      ]
@@ -3232,7 +3243,7 @@
     # information in shared branches as well.
     _see_also = ['commit']
     takes_options = ['verbose', 'revision',
-                    Option('dry-run', help='Don\'t actually make changes'),
+                    Option('dry-run', help='Don\'t actually make changes.'),
                     Option('force', help='Say yes to all questions.')]
     takes_args = ['location?']
     aliases = []
@@ -3342,20 +3353,20 @@
 
     takes_options = [
         Option('inet',
-               help='serve on stdin/out for use from inetd or sshd'),
+               help='Serve on stdin/out for use from inetd or sshd.'),
         Option('port',
-               help='listen for connections on nominated port of the form '
-                    '[hostname:]portnumber. Passing 0 as the port number will '
-                    'result in a dynamically allocated port. Default port is '
+               help='Listen for connections on nominated port of the form '
+                    '[hostname:]portnumber.  Passing 0 as the port number will '
+                    'result in a dynamically allocated port.  The default port is '
                     '4155.',
                type=str),
         Option('directory',
-               help='serve contents of directory',
+               help='Serve contents of this directory.',
                type=unicode),
         Option('allow-writes',
-               help='By default the server is a readonly server. Supplying '
+               help='By default the server is a readonly server.  Supplying '
                     '--allow-writes enables write access to the contents of '
-                    'the served directory and below. '
+                    'the served directory and below.'
                 ),
         ]
 
@@ -3421,7 +3432,9 @@
 
     _see_also = ['split']
     takes_args = ['tree']
-    takes_options = [Option('reference', 'join by reference')]
+    takes_options = [
+            Option('reference', help='Join by reference.'),
+            ]
     hidden = True
 
     def run(self, tree, reference=False):

=== modified file 'bzrlib/bundle/commands.py'
--- a/bzrlib/bundle/commands.py	2007-06-19 14:49:06 +0000
+++ b/bzrlib/bundle/commands.py	2007-07-10 10:20:27 +0000
@@ -97,8 +97,10 @@
         - Bundle to transform A into B
     """
     takes_options = ['revision', 'remember',
-                     Option("output", help="write bundle to specified file",
-                            type=unicode)]
+                     Option("output",
+                            help="Write bundle to specified file.",
+                            type=unicode),
+                     ]
     takes_args = ['base?']
     aliases = ['bundle']
     encoding_type = 'exact'

=== modified file 'bzrlib/cmd_version_info.py'
--- a/bzrlib/cmd_version_info.py	2007-03-26 09:59:49 +0000
+++ b/bzrlib/cmd_version_info.py	2007-07-10 10:20:27 +0000
@@ -48,13 +48,13 @@
     """Show version information about this tree."""
 
     takes_options = [Option('format', type=_parse_version_info_format,
-                            help='Select the output format'),
-                     Option('all', help='include all possible information'),
-                     Option('check-clean', help='check if tree is clean'),
+                            help='Select the output format.'),
+                     Option('all', help='Include all possible information.'),
+                     Option('check-clean', help='Check if tree is clean.'),
                      Option('include-history',
-                            help='Include the revision-history'),
+                            help='Include the revision-history.'),
                      Option('include-file-revisions',
-                            help='Include the last revision for each file')
+                            help='Include the last revision for each file.')
                      ]
     takes_args = ['location?']
 

=== modified file 'bzrlib/conflicts.py'
--- a/bzrlib/conflicts.py	2007-03-06 15:36:36 +0000
+++ b/bzrlib/conflicts.py	2007-07-10 10:20:27 +0000
@@ -56,7 +56,10 @@
 
     See also bzr resolve.
     """
-    takes_options = [Option('text', help='list text conflicts by pathname')]
+    takes_options = [
+            Option('text',
+                   help='List paths of files with text conflicts.'),
+        ]
 
     def run(self, text=False):
         from bzrlib.workingtree import WorkingTree

=== modified file 'bzrlib/option.py'
--- a/bzrlib/option.py	2007-04-17 07:59:42 +0000
+++ b/bzrlib/option.py	2007-07-10 10:20:27 +0000
@@ -376,12 +376,12 @@
 
 _global_option('all')
 _global_option('overwrite', help='Ignore differences between branches and '
-               'overwrite unconditionally')
+               'overwrite unconditionally.')
 _global_option('basis', type=str)
 _global_option('bound')
 _global_option('diff-options', type=str)
 _global_option('help',
-               help='show help message',
+               help='Show help message.',
                short_name='h')
 _global_option('file', type=unicode, short_name='F')
 _global_option('force')
@@ -391,43 +391,43 @@
                short_name='m')
 _global_option('no-recurse')
 _global_option('profile',
-               help='show performance profiling information')
+               help='Show performance profiling information.')
 _global_option('revision',
                type=_parse_revision_str,
                short_name='r',
                help='See \'help revisionspec\' for details')
-_global_option('show-ids', 
-               help='show internal object ids')
-_global_option('timezone', 
+_global_option('show-ids',
+               help='Show internal object ids.')
+_global_option('timezone',
                type=str,
-               help='display timezone as local, original, or utc')
+               help='Display timezone as local, original, or utc.')
 _global_option('unbound')
 _global_option('verbose',
-               help='display more information',
+               help='Display more information.',
                short_name='v')
 _global_option('version')
 _global_option('email')
 _global_option('update')
-_global_registry_option('log-format', "Use this log format",
+_global_registry_option('log-format', "Use specified log format.",
                         log.log_formatter_registry, value_switches=True,
                         title='Log format')
 _global_option('long', help='Use detailed log format. Same as --log-format long',
                short_name='l')
 _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('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_registry_option('merge-type', 'Select a particular merge algorithm',
+_global_registry_option('merge-type', 'Select a particular merge algorithm.',
                         _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')
+_global_option('reprocess', help='Reprocess to reduce spurious conflicts.')
 _global_option('kind', type=str)
 _global_option('dry-run',
-               help="show what would be done, but don't actually do anything")
+               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.')
 
 

=== modified file 'bzrlib/plugins/launchpad/__init__.py'
--- a/bzrlib/plugins/launchpad/__init__.py	2007-04-20 07:38:20 +0000
+++ b/bzrlib/plugins/launchpad/__init__.py	2007-07-10 10:20:27 +0000
@@ -50,28 +50,28 @@
                 --product fooproduct
     """
     takes_args = ['branch_url']
-    takes_options = \
-        [Option('product', 
-                'launchpad product short name to associate with the branch',
+    takes_options = [
+         Option('product',
+                'Launchpad product short name to associate with the branch.',
                 unicode),
          Option('branch-name',
-                'short name for the branch; '
-                'by default taken from the last component of the url',
+                'Short name for the branch; '
+                'by default taken from the last component of the url.',
                 unicode),
          Option('branch-title',
-                'one-sentence description of the branch',
+                'One-sentence description of the branch.',
                 unicode),
          Option('branch-description',
-                'longer description of the purpose or contents of the branch',
+                'Longer description of the purpose or contents of the branch',
                 unicode),
-         Option('author', 
-                'email of the branch\'s author, if not yourself',
+         Option('author',
+                "Branch author's email address, if not yourself.",
                 unicode),
          Option('link-bug',
-                'the bug this branch fixes',
+                'The bug this branch fixes.',
                 int),
          Option('dry-run',
-                'prepare the request but don\'t actually send it')
+                'Prepare the request but don\'t actually send it.')
         ]
 
 

=== modified file 'bzrlib/tests/test_options.py'
--- a/bzrlib/tests/test_options.py	2007-06-27 19:13:50 +0000
+++ b/bzrlib/tests/test_options.py	2007-07-10 10:20:27 +0000
@@ -14,9 +14,12 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
+import re
+
 from bzrlib import (
     builtins,
     bzrdir,
+    commands,
     errors,
     option,
     repository,
@@ -267,3 +270,46 @@
         opts, args = self.parse(
             options, ['--hello=a', '--hello=b', '--hello=-', '--hello=c'])
         self.assertEqual(['c'], opts.hello)
+
+
+class TestOptionDefinitions(TestCase):
+    """Tests for options in the Bazaar codebase."""
+
+    def get_all_options(self):
+        """Return a list of all options used by Bazaar, both global and command.
+        
+        The list returned contains elements of (scope, option) where 'scope' 
+        is either None for global options, or a command name.
+
+        This includes options provided by plugins.
+        """
+        g = [(None, opt) for name, opt
+             in sorted(option.Option.OPTIONS.items())]
+        for cmd_name, cmd_class in sorted(commands.get_all_cmds()):
+            cmd = cmd_class()
+            for opt_name, opt in sorted(cmd.options().items()):
+                g.append((cmd_name, opt))
+        return g
+
+    def test_get_all_options(self):
+        all = self.get_all_options()
+        self.assertTrue(len(all) > 100,
+                "too few options found: %r" % all)
+
+    def test_option_grammar(self):
+        msgs = []
+        option_re = re.compile(r'^[A-Z]')
+        for scope, option in self.get_all_options():
+            if not option.help:
+                # TODO: Also complain about options that have no help message?
+                continue
+            if not option_re.match(option.help):
+                msgs.append('%-16s %-16s %s' %
+                        ((scope or 'GLOBAL'), option.name, option.help))
+        if msgs:
+            self.fail("The following options don't match the style guide:\n"
+                    + '\n'.join(msgs))
+
+    # TODO: Scan for global options that aren't used by any command?
+    #
+    # TODO: Check that there are two spaces between sentences.

=== modified file 'doc/developers/HACKING'
--- a/doc/developers/HACKING	2007-06-12 14:57:07 +0000
+++ b/doc/developers/HACKING	2007-07-10 10:20:27 +0000
@@ -693,6 +693,24 @@
 should be only in the command-line tool.
 
 
+
+Displaying help
+===============
+
+Bazaar has online help for various topics through ``bzr help COMMAND`` or
+equivalently ``bzr command -h``.  We also have help on command options,
+and on other help topics.  (See ``help_topics.py``.)
+
+As for python docstrings, the first paragraph should be a single-sentence
+synopsis of the command.
+
+The help for options should be one or more proper sentences, starting with
+a capital letter and finishing with a full stop (period).
+
+All help messages and documentation should have two spaces between
+sentences.
+
+
 Writing tests
 =============
 




More information about the bazaar-commits mailing list