Merge lp:~vila/bzr/747050-config-help into lp:bzr

Proposed by Vincent Ladeuil
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: 6061
Merged at revision: 6072
Proposed branch: lp:~vila/bzr/747050-config-help
Merge into: lp:bzr
Diff against target: 323 lines (+103/-45)
8 files modified
bzrlib/config.py (+16/-8)
bzrlib/help.py (+2/-1)
bzrlib/help_topics/__init__.py (+39/-14)
bzrlib/help_topics/en/configuration.txt (+2/-2)
bzrlib/plugin.py (+3/-12)
bzrlib/tests/test_help.py (+34/-5)
bzrlib/tests/test_plugins.py (+4/-3)
doc/en/release-notes/bzr-2.5.txt (+3/-0)
To merge this branch: bzr merge lp:~vila/bzr/747050-config-help
Reviewer Review Type Date Requested Status
Jelmer Vernooij (community) Needs Fixing
Review via email: mp+70929@code.launchpad.net

Commit message

Implement per-config option help

Description of the change

This implements help topics for registered configuration options.

I refrained from refactoring too much (still reducing the code
duplication a bit) but some love seems to be needed in this area.

I haven't deleted the text from help_topics/configuration.txt
yet, that would be better addressed when fixing bug #746993.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

TestConfigOptiondIndex seems like it has an extra 'd' :)

TestConfigOptionHelp seems unused.

review: Needs Fixing
lp:~vila/bzr/747050-config-help updated
6062. By Vincent Ladeuil

Fix typos caught by Jelmer.

Revision history for this message
Vincent Ladeuil (vila) wrote :

sent to pqm by email

Revision history for this message
Vincent Ladeuil (vila) wrote :

sent to pqm by email

lp:~vila/bzr/747050-config-help updated
6063. By Vincent Ladeuil

Fix forgotten renaming.

6064. By Vincent Ladeuil

Merge trunk to resolve conflicts

Revision history for this message
Vincent Ladeuil (vila) wrote :

sent to pqm by email

Revision history for this message
Vincent Ladeuil (vila) wrote :

sent to pqm by email

lp:~vila/bzr/747050-config-help updated
6065. By Vincent Ladeuil

Fix tests failing on pqm.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/config.py'
2--- bzrlib/config.py 2011-08-13 03:39:24 +0000
3+++ bzrlib/config.py 2011-08-16 07:35:26 +0000
4@@ -2307,6 +2307,15 @@
5 def get_default(self):
6 return self.default
7
8+ def get_help_text(self, additional_see_also=None, plain=True):
9+ result = self.help
10+ from bzrlib import help_topics
11+ result += help_topics._format_see_also(additional_see_also)
12+ if plain:
13+ result = help_topics.help_as_plain_text(result)
14+ return result
15+
16+
17 # Predefined converters to get proper values from store
18
19 def bool_from_store(unicode_str):
20@@ -2351,13 +2360,12 @@
21 def register_lazy(self, key, module_name, member_name):
22 """Register a new option to be loaded on request.
23
24- :param key: This is the key to use to request the option later. Since
25- the registration is lazy, it should be provided and match the
26- option name.
27-
28- :param module_name: The python path to the module. Such as 'os.path'.
29-
30- :param member_name: The member of the module to return. If empty or
31+ :param key: the key to request the option later. Since the registration
32+ is lazy, it should be provided and match the option name.
33+
34+ :param module_name: the python path to the module. Such as 'os.path'.
35+
36+ :param member_name: the member of the module to return. If empty or
37 None, get() will return the module itself.
38 """
39 super(OptionRegistry, self).register_lazy(key,
40@@ -2379,7 +2387,7 @@
41
42 option_registry.register(
43 Option('dirstate.fdatasync', default=True, from_unicode=bool_from_store,
44- help='''
45+ help='''\
46 Flush dirstate changes onto physical disk?
47
48 If true (default), working tree metadata changes are flushed through the
49
50=== modified file 'bzrlib/help.py'
51--- bzrlib/help.py 2011-05-18 18:32:22 +0000
52+++ bzrlib/help.py 2011-08-16 07:35:26 +0000
53@@ -1,4 +1,4 @@
54-# Copyright (C) 2005-2010 Canonical Ltd
55+# Copyright (C) 2005-2011 Canonical Ltd
56 #
57 # This program is free software; you can redistribute it and/or modify
58 # it under the terms of the GNU General Public License as published by
59@@ -135,6 +135,7 @@
60 help_topics.HelpTopicIndex(),
61 _mod_commands.HelpCommandIndex(),
62 plugin.PluginsHelpIndex(),
63+ help_topics.ConfigOptionHelpIndex(),
64 ]
65
66 def _check_prefix_uniqueness(self):
67
68=== modified file 'bzrlib/help_topics/__init__.py'
69--- bzrlib/help_topics/__init__.py 2011-06-30 16:47:06 +0000
70+++ bzrlib/help_topics/__init__.py 2011-08-16 07:35:26 +0000
71@@ -1,4 +1,4 @@
72-# Copyright (C) 2006-2010 Canonical Ltd
73+# Copyright (C) 2006-2011 Canonical Ltd
74 #
75 # This program is free software; you can redistribute it and/or modify
76 # it under the terms of the GNU General Public License as published by
77@@ -37,6 +37,7 @@
78
79 import bzrlib
80 from bzrlib import (
81+ config,
82 osutils,
83 registry,
84 )
85@@ -65,7 +66,7 @@
86 :param section: Section in reference manual - see SECT_* identifiers.
87 """
88 # The detail is stored as the 'object' and the metadata as the info
89- info=(summary,section)
90+ info = (summary, section)
91 super(HelpTopicRegistry, self).register(topic, detail, info=info)
92
93 def register_lazy(self, topic, module_name, member_name, summary,
94@@ -79,7 +80,7 @@
95 :param section: Section in reference manual - see SECT_* identifiers.
96 """
97 # The detail is stored as the 'object' and the metadata as the info
98- info=(summary,section)
99+ info = (summary, section)
100 super(HelpTopicRegistry, self).register_lazy(topic, module_name,
101 member_name, info=info)
102
103@@ -844,6 +845,15 @@
104 return []
105
106
107+def _format_see_also(see_also):
108+ result = ''
109+ if see_also:
110+ result += '\n:See also: '
111+ result += ', '.join(sorted(set(see_also)))
112+ result += '\n'
113+ return result
114+
115+
116 class RegisteredTopic(object):
117 """A help topic which has been registered in the HelpTopicRegistry.
118
119@@ -867,17 +877,7 @@
120 returned instead of plain text.
121 """
122 result = topic_registry.get_detail(self.topic)
123- # there is code duplicated here and in bzrlib/plugin.py's
124- # matching Topic code. This should probably be factored in
125- # to a helper function and a common base class.
126- if additional_see_also is not None:
127- see_also = sorted(set(additional_see_also))
128- else:
129- see_also = None
130- if see_also:
131- result += '\n:See also: '
132- result += ', '.join(see_also)
133- result += '\n'
134+ result += _format_see_also(additional_see_also)
135 if plain:
136 result = help_as_plain_text(result)
137 return result
138@@ -903,3 +903,28 @@
139 line = re.sub(":doc:`(.+?)-help`", r'``bzr help \1``', line)
140 result.append(line)
141 return "\n".join(result) + "\n"
142+
143+
144+class ConfigOptionHelpIndex(object):
145+ """A help index that returns help topics for config options."""
146+
147+ def __init__(self):
148+ self.prefix = 'configuration/'
149+
150+ def get_topics(self, topic):
151+ """Search for topic in the registered config options.
152+
153+ :param topic: A topic to search for.
154+ :return: A list which is either empty or contains a single
155+ config.Option entry.
156+ """
157+ if topic is None:
158+ return []
159+ elif topic.startswith(self.prefix):
160+ topic = topic[len(self.prefix):]
161+ if topic in config.option_registry:
162+ return [config.option_registry.get(topic)]
163+ else:
164+ return []
165+
166+
167
168=== modified file 'bzrlib/help_topics/en/configuration.txt'
169--- bzrlib/help_topics/en/configuration.txt 2011-08-02 01:10:27 +0000
170+++ bzrlib/help_topics/en/configuration.txt 2011-08-16 07:35:26 +0000
171@@ -14,7 +14,7 @@
172
173 "John Doe <jdoe@example.com>"
174
175-See also the ``email`` configuration value.
176+See also the ``email`` configuration option.
177
178 BZR_PROGRESS_BAR
179 ~~~~~~~~~~~~~~~~
180@@ -54,7 +54,7 @@
181
182 Path to the Bazaar executable to use when using the bzr+ssh protocol.
183
184-See also the ``bzr_remote_path`` configuration value.
185+See also the ``bzr_remote_path`` configuration option.
186
187 BZR_EDITOR
188 ~~~~~~~~~~
189
190=== modified file 'bzrlib/plugin.py'
191--- bzrlib/plugin.py 2011-05-31 06:15:24 +0000
192+++ bzrlib/plugin.py 2011-08-16 07:35:26 +0000
193@@ -506,21 +506,12 @@
194 result = self.module.__doc__
195 if result[-1] != '\n':
196 result += '\n'
197- # there is code duplicated here and in bzrlib/help_topic.py's
198- # matching Topic code. This should probably be factored in
199- # to a helper function and a common base class.
200- if additional_see_also is not None:
201- see_also = sorted(set(additional_see_also))
202- else:
203- see_also = None
204- if see_also:
205- result += 'See also: '
206- result += ', '.join(see_also)
207- result += '\n'
208+ from bzrlib import help_topics
209+ result += help_topics._format_see_also(additional_see_also)
210 return result
211
212 def get_help_topic(self):
213- """Return the modules help topic - its __name__ after bzrlib.plugins.."""
214+ """Return the module help topic: its basename."""
215 return self.module.__name__[len('bzrlib.plugins.'):]
216
217
218
219=== modified file 'bzrlib/tests/test_help.py'
220--- bzrlib/tests/test_help.py 2011-06-27 15:36:58 +0000
221+++ bzrlib/tests/test_help.py 2011-08-16 07:35:26 +0000
222@@ -21,6 +21,7 @@
223 from bzrlib import (
224 builtins,
225 commands,
226+ config,
227 errors,
228 help,
229 help_topics,
230@@ -561,6 +562,31 @@
231 self.assertEqual('', index.prefix)
232
233
234+class TestConfigOptionIndex(TestHelp):
235+ """Tests for the HelpCommandIndex class."""
236+
237+ def setUp(self):
238+ super(TestConfigOptionIndex, self).setUp()
239+ self.index = help_topics.ConfigOptionHelpIndex()
240+
241+ def test_get_topics_None(self):
242+ """Searching for None returns an empty list."""
243+ self.assertEqual([], self.index.get_topics(None))
244+
245+ def test_get_topics_no_topic(self):
246+ self.assertEqual([], self.index.get_topics('nothing by this name'))
247+
248+ def test_prefix(self):
249+ self.assertEqual('configuration/', self.index.prefix)
250+
251+ def test_get_topic_with_prefix(self):
252+ topics = self.index.get_topics('configuration/default_format')
253+ self.assertLength(1, topics)
254+ opt = topics[0]
255+ self.assertIsInstance(opt, config.Option)
256+ self.assertEquals('default_format', opt.name)
257+
258+
259 class TestCommandIndex(TestHelp):
260 """Tests for the HelpCommandIndex class."""
261
262@@ -603,16 +629,19 @@
263 def test_default_search_path(self):
264 """The default search path should include internal indexs."""
265 indices = help.HelpIndices()
266- self.assertEqual(3, len(indices.search_path))
267+ self.assertEqual(4, len(indices.search_path))
268 # help topics should be searched in first.
269 self.assertIsInstance(indices.search_path[0],
270- help_topics.HelpTopicIndex)
271+ help_topics.HelpTopicIndex)
272 # with commands being search second.
273 self.assertIsInstance(indices.search_path[1],
274- commands.HelpCommandIndex)
275- # and plugins are a third index.
276+ commands.HelpCommandIndex)
277+ # plugins are a third index.
278 self.assertIsInstance(indices.search_path[2],
279- plugin.PluginsHelpIndex)
280+ plugin.PluginsHelpIndex)
281+ # config options are a fourth index
282+ self.assertIsInstance(indices.search_path[3],
283+ help_topics.ConfigOptionHelpIndex)
284
285 def test_search_for_unknown_topic_raises(self):
286 """Searching for an unknown topic should raise NoHelpTopic."""
287
288=== modified file 'bzrlib/tests/test_plugins.py'
289--- bzrlib/tests/test_plugins.py 2011-05-16 13:49:58 +0000
290+++ bzrlib/tests/test_plugins.py 2011-08-16 07:35:26 +0000
291@@ -615,15 +615,16 @@
292 def test_get_help_text_with_additional_see_also(self):
293 mod = FakeModule('two lines of help\nand more', 'demo')
294 topic = plugin.ModuleHelpTopic(mod)
295- self.assertEqual("two lines of help\nand more\nSee also: bar, foo\n",
296- topic.get_help_text(['foo', 'bar']))
297+ self.assertEqual("two lines of help\nand more\n\n:See also: bar, foo\n",
298+ topic.get_help_text(['foo', 'bar']))
299
300 def test_get_help_topic(self):
301 """The help topic for a plugin is its module name."""
302 mod = FakeModule('two lines of help\nand more', 'bzrlib.plugins.demo')
303 topic = plugin.ModuleHelpTopic(mod)
304 self.assertEqual('demo', topic.get_help_topic())
305- mod = FakeModule('two lines of help\nand more', 'bzrlib.plugins.foo_bar')
306+ mod = FakeModule('two lines of help\nand more',
307+ 'bzrlib.plugins.foo_bar')
308 topic = plugin.ModuleHelpTopic(mod)
309 self.assertEqual('foo_bar', topic.get_help_topic())
310
311
312=== modified file 'doc/en/release-notes/bzr-2.5.txt'
313--- doc/en/release-notes/bzr-2.5.txt 2011-08-15 13:49:38 +0000
314+++ doc/en/release-notes/bzr-2.5.txt 2011-08-16 07:35:26 +0000
315@@ -69,6 +69,9 @@
316 while --match-message, --match-author, --match-committer and
317 --match-bugs match each of those fields.
318
319+* ``bzr help configuration/<option>`` display the help for ``option`` for
320+ all registered configuration options. (Vincent Ladeuil, #747050)
321+
322 * Relative local paths can now be specified in URL syntax by using the
323 "file:" prefix. (Jelmer Vernooij)
324