~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/help_topics.py

  • Committer: Robert Collins
  • Date: 2007-07-19 06:34:09 UTC
  • mto: (2592.3.46 repository)
  • mto: This revision was merged to the branch mainline in revision 2651.
  • Revision ID: robertc@robertcollins.net-20070719063409-stu9sckrxp8wp3mo
LIBRARY API BREAKS:

  * KnitIndex.get_parents now returns tuples. (Robert Collins)

INTERNALS:

  * Unused functions on the private interface KnitIndex have been removed.
    (Robert Collins)

  * New ``knit.KnitGraphIndex`` which provides a ``KnitIndex`` layered on top
    of a ``index.GraphIndex``. (Robert Collins)

  * New ``knit.KnitVersionedFile.iter_parents`` method that allows querying
    the parents of many knit nodes at once, reducing round trips to the 
    underlying index. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
Help topics are meant to be help for items that aren't commands, but will
20
20
help bzr become fully learnable without referring to a tutorial.
21
 
 
22
 
Limited formatting of help text is permitted to make the text useful
23
 
both within the reference manual (reStructuredText) and on the screen.
24
 
The help text should be reStructuredText with formatting kept to a
25
 
minimum and, in particular, no headings. The onscreen renderer applies
26
 
the following simple rules before rendering the text:
27
 
 
28
 
    1. A '::' appearing on the end of a line is replaced with ':'.
29
 
    2. Lines starting with a ':' have it stripped.
30
 
 
31
 
These rules mean that literal blocks and field lists respectively can
32
 
be used in the help text, producing sensible input to a manual while
33
 
rendering on the screen naturally.
34
21
"""
35
22
 
36
23
from bzrlib import registry
37
24
 
38
25
 
39
 
# Section identifiers (map topics to the right place in the manual)
40
 
SECT_COMMAND = "command"
41
 
SECT_CONCEPT = "concept"
42
 
SECT_HIDDEN =  "hidden"
43
 
SECT_LIST    = "list"
44
 
SECT_PLUGIN  = "plugin"
45
 
 
46
 
 
47
26
class HelpTopicRegistry(registry.Registry):
48
27
    """A Registry customized for handling help topics."""
49
28
 
50
 
    def register(self, topic, detail, summary, section=SECT_LIST):
 
29
    def register(self, topic, detail, summary):
51
30
        """Register a new help topic.
52
31
 
53
32
        :param topic: Name of documentation entry
54
33
        :param detail: Function or string object providing detailed
55
34
            documentation for topic.  Function interface is detail(topic).
56
35
            This should return a text string of the detailed information.
57
 
            See the module documentation for details on help text formatting.
58
36
        :param summary: String providing single-line documentation for topic.
59
 
        :param section: Section in reference manual - see SECT_* identifiers.
60
37
        """
61
 
        # The detail is stored as the 'object' and the metadata as the info
62
 
        info=(summary,section)
63
 
        super(HelpTopicRegistry, self).register(topic, detail, info=info)
 
38
        # The detail is stored as the 'object' and the 
 
39
        super(HelpTopicRegistry, self).register(topic, detail, info=summary)
64
40
 
65
 
    def register_lazy(self, topic, module_name, member_name, summary,
66
 
                      section=SECT_LIST):
 
41
    def register_lazy(self, topic, module_name, member_name, summary):
67
42
        """Register a new help topic, and import the details on demand.
68
43
 
69
44
        :param topic: Name of documentation entry
70
45
        :param module_name: The module to find the detailed help.
71
46
        :param member_name: The member of the module to use for detailed help.
72
47
        :param summary: String providing single-line documentation for topic.
73
 
        :param section: Section in reference manual - see SECT_* identifiers.
74
48
        """
75
 
        # The detail is stored as the 'object' and the metadata as the info
76
 
        info=(summary,section)
77
49
        super(HelpTopicRegistry, self).register_lazy(topic, module_name,
78
 
                                                     member_name, info=info)
 
50
                                                     member_name, info=summary)
79
51
 
80
52
    def get_detail(self, topic):
81
53
        """Get the detailed help on a given topic."""
87
59
 
88
60
    def get_summary(self, topic):
89
61
        """Get the single line summary for the topic."""
90
 
        info = self.get_info(topic)
91
 
        if info is None:
92
 
            return None
93
 
        else:
94
 
            return info[0]
95
 
 
96
 
    def get_section(self, topic):
97
 
        """Get the section for the topic."""
98
 
        info = self.get_info(topic)
99
 
        if info is None:
100
 
            return None
101
 
        else:
102
 
            return info[1]
103
 
 
104
 
    def get_topics_for_section(self, section):
105
 
        """Get the set of topics in a section."""
106
 
        result = set()
107
 
        for topic in self.keys():
108
 
            if section == self.get_section(topic):
109
 
                result.add(topic)
110
 
        return result
 
62
        return self.get_info(topic)
111
63
 
112
64
 
113
65
topic_registry = HelpTopicRegistry()
129
81
 
130
82
 
131
83
def _help_on_revisionspec(name):
132
 
    """Generate the help for revision specs."""
133
 
    import re
 
84
    """Write the summary help for all documented topics to outfile."""
134
85
    import bzrlib.revisionspec
135
86
 
136
87
    out = []
137
 
    out.append("Revision Identifiers\n")
138
 
    out.append("A revision, or a range bound, can be one of the following.\n")
139
 
    details = []
140
 
    details.append("\nFurther details are given below.\n")
 
88
    out.append("\nRevision prefix specifier:"
 
89
               "\n--------------------------\n")
141
90
 
142
 
    # The help text is indented 4 spaces - this re cleans that up below
143
 
    indent_re = re.compile(r'^    ', re.MULTILINE)
144
91
    for i in bzrlib.revisionspec.SPEC_TYPES:
145
92
        doc = i.help_txt
146
93
        if doc == bzrlib.revisionspec.RevisionSpec.help_txt:
147
 
            summary = "N/A"
148
 
            doc = summary + "\n"
149
 
        else:
150
 
            # Extract out the top line summary from the body and
151
 
            # clean-up the unwanted whitespace
152
 
            summary,doc = doc.split("\n", 1)
153
 
            #doc = indent_re.sub('', doc)
154
 
            while (doc[-2:] == '\n\n' or doc[-1:] == ' '):
155
 
                doc = doc[:-1]
156
 
        
157
 
        # Note: The leading : here are HACKs to get reStructuredText
158
 
        # 'field' formatting - we know that the prefix ends in a ':'.
159
 
        out.append(":%s\n\t%s" % (i.prefix, summary))
160
 
        details.append(":%s\n%s" % (i.prefix, doc))
161
 
 
162
 
    return '\n'.join(out + details)
 
94
            doc = "N/A\n"
 
95
        while (doc[-2:] == '\n\n' or doc[-1:] == ' '):
 
96
            doc = doc[:-1]
 
97
 
 
98
        out.append("  %s %s\n\n" % (i.prefix, doc))
 
99
 
 
100
    return ''.join(out)
163
101
 
164
102
 
165
103
def _help_on_transport(name):
184
122
        else:
185
123
            return 0
186
124
 
 
125
    out = []
187
126
    protl = []
188
127
    decl = []
189
128
    protos = transport_list_registry.keys( )
193
132
        if not shorthelp:
194
133
            continue
195
134
        if proto.endswith("://"):
196
 
            protl.append(add_string(proto, shorthelp, 79))
 
135
            protl.extend(add_string(proto, shorthelp, 79))
197
136
        else:
198
 
            decl.append(add_string(proto, shorthelp, 79))
199
 
 
200
 
 
201
 
    out = "URL Identifiers\n\n" + \
202
 
            "Supported URL prefixes::\n\n  " + \
203
 
            '  '.join(protl)
 
137
            decl.extend(add_string(proto, shorthelp, 79))
 
138
 
 
139
 
 
140
    out = "\nSupported URL prefix\n--------------------\n" + \
 
141
            ''.join(protl)
204
142
 
205
143
    if len(decl):
206
 
        out += "\nSupported modifiers::\n\n  " + \
207
 
            '  '.join(decl)
 
144
        out += "\nSupported modifiers\n-------------------\n" + \
 
145
            ''.join(decl)
208
146
 
209
147
    return out
210
148
 
211
149
 
212
 
_basic_help = \
 
150
_basic_help= \
213
151
"""Bazaar -- a free distributed version-control tool
214
152
http://bazaar-vcs.org/
215
153
 
236
174
"""
237
175
 
238
176
 
239
 
_global_options = \
 
177
_global_options =\
240
178
"""Global Options
241
179
 
242
180
These options may be used with any command, and may appear in front of any
243
181
command.  (e.g. "bzr --quiet help").
244
182
 
245
 
--quiet        Suppress informational output; only print errors and warnings.
246
 
--version      Print the version number.
 
183
--quiet        Suppress informational output; only print errors and warnings
 
184
--version      Print the version number
247
185
 
248
 
--no-aliases   Do not process command aliases when running this command.
 
186
--no-aliases   Do not process command aliases when running this command
249
187
--builtin      Use the built-in version of a command, not the plugin version.
250
 
               This does not suppress other plugin effects.
251
 
--no-plugins   Do not process any plugins.
 
188
               This does not suppress other plugin effects
 
189
--no-plugins   Do not process any plugins
252
190
 
253
 
-Devil         Capture call sites that do expensive or badly-scaling
254
 
               operations.
255
191
-Derror        Instead of normal error handling, always print a traceback on
256
192
               error.
257
 
-Dhooks        Trace hook execution.
258
 
-Dhpss         Trace smart protocol requests and responses.
259
 
-Dindex        Trace major index operations.
260
 
-Dlock         Trace when lockdir locks are taken or released.
261
 
--profile      Profile execution using the hotshot profiler.
262
 
--lsprof       Profile execution using the lsprof profiler.
 
193
--profile      Profile execution using the hotshot profiler
 
194
--lsprof       Profile execution using the lsprof profiler
263
195
--lsprof-file  Profile execution using the lsprof profiler, and write the
264
196
               results to a specified file.  If the filename ends with ".txt",
265
 
               text format will be used.  If the filename either starts with
266
 
               "callgrind.out" or end with ".callgrind", the output will be
267
 
               formatted for use with KCacheGrind. Otherwise, the output
268
 
               will be a pickle.
 
197
               text format will be used.  If the filename ends with
 
198
               ".callgrind", output will be formatted for use with KCacheGrind.
 
199
               Otherwise, the output will be a pickle.
269
200
 
270
201
See doc/developers/profiling.txt for more information on profiling.
271
202
 
336
267
would like to convert your heavy checkout into a normal branch so that every
337
268
commit is local, you can use the "unbind" command.
338
269
 
339
 
Related commands::
 
270
Related commands:
340
271
 
341
272
  checkout    Create a checkout. Pass --lightweight to get a lightweight
342
273
              checkout
386
317
the branches will not have working trees pass the '--no-trees' option to
387
318
'init-repository'.
388
319
 
389
 
Related commands::
 
320
Related commands:
390
321
 
391
322
  init-repository   Create a shared repository. Use --no-trees to create one
392
323
                    in which new branches won't get a working tree.
426
357
is also a 'push-and-update' plugin that automates running 'bzr update' via SSH
427
358
after each push.
428
359
 
429
 
Useful commands::
 
360
Useful commands:
430
361
 
431
362
  checkout     Create a working tree when a branch does not have one.
432
363
  remove-tree  Removes the working tree from a branch when it is safe to do so.
438
369
"""Status Flags
439
370
 
440
371
Status flags are used to summarise changes to the working tree in a concise
441
 
manner.  They are in the form::
442
 
 
 
372
manner.  They are in the form:
443
373
   xxx   <filename>
444
 
 
445
374
where the columns' meanings are as follows.
446
375
 
447
 
Column 1 - versioning/renames::
448
 
 
 
376
Column 1: versioning / renames
449
377
  + File versioned
450
378
  - File unversioned
451
379
  R File renamed
453
381
  C File has conflicts
454
382
  P Entry for a pending merge (not a file)
455
383
 
456
 
Column 2 - contents::
457
 
 
 
384
Column 2: Contents
458
385
  N File created
459
386
  D File deleted
460
387
  K File kind changed
461
388
  M File modified
462
389
 
463
 
Column 3 - execute::
464
 
 
 
390
Column 3: Execute
465
391
  * The execute bit was changed
466
392
"""
467
393
 
468
394
 
469
 
_env_variables = \
470
 
"""Environment Variables
471
 
 
472
 
================ =================================================================
473
 
BZRPATH          Path where bzr is to look for shell plugin external commands.
474
 
BZR_EMAIL        E-Mail address of the user. Overrides EMAIL.
475
 
EMAIL            E-Mail address of the user.
476
 
BZR_EDITOR       Editor for editing commit messages. Overrides EDITOR.
477
 
EDITOR           Editor for editing commit messages.
478
 
BZR_PLUGIN_PATH  Paths where bzr should look for plugins.
479
 
BZR_HOME         Directory holding .bazaar config dir. Overrides HOME.
480
 
BZR_HOME (Win32) Directory holding bazaar config dir. Overrides APPDATA and HOME.
481
 
================ =================================================================
482
 
"""
483
 
 
484
 
 
485
 
_files = \
486
 
r"""Files
487
 
 
488
 
:On Linux:   ~/.bazaar/bazaar.conf
489
 
:On Windows: C:\\Documents and Settings\\username\\Application Data\\bazaar\\2.0\\bazaar.conf
490
 
 
491
 
Contains the user's default configuration. The section ``[DEFAULT]`` is
492
 
used to define general configuration that will be applied everywhere.
493
 
The section ``[ALIASES]`` can be used to create command aliases for
494
 
commonly used options.
495
 
 
496
 
A typical config file might look something like::
497
 
 
498
 
  [DEFAULT]
499
 
  email=John Doe <jdoe@isp.com>
500
 
 
501
 
  [ALIASES]
502
 
  commit = commit --strict
503
 
  log10 = log --short -r -10..-1
504
 
"""
505
 
 
506
 
 
507
395
topic_registry.register("revisionspec", _help_on_revisionspec,
508
396
                        "Explain how to use --revision")
509
 
topic_registry.register('basic', _basic_help, "Basic commands", SECT_HIDDEN)
510
 
topic_registry.register('topics', _help_on_topics, "Topics list", SECT_HIDDEN)
 
397
topic_registry.register('basic', _basic_help, "Basic commands")
 
398
topic_registry.register('topics', _help_on_topics, "Topics list")
511
399
def get_format_topic(topic):
512
400
    from bzrlib import bzrdir
513
 
    return "Storage Formats\n\n" + bzrdir.format_registry.help_topic(topic)
 
401
    return bzrdir.format_registry.help_topic(topic)
514
402
topic_registry.register('formats', get_format_topic, 'Directory formats')
515
403
topic_registry.register('global-options', _global_options,
516
404
                        'Options that can be used with any command')
517
405
topic_registry.register('checkouts', _checkouts,
518
 
                        'Information on what a checkout is', SECT_CONCEPT)
 
406
                        'Information on what a checkout is')
519
407
topic_registry.register('urlspec', _help_on_transport,
520
408
                        "Supported transport protocols")
521
409
topic_registry.register('status-flags', _status_flags,
522
410
                        "Help on status flags")
523
411
def get_bugs_topic(topic):
524
412
    from bzrlib import bugtracker
525
 
    return "Bug Trackers\n\n" + bugtracker.tracker_registry.help_topic(topic)
 
413
    return bugtracker.tracker_registry.help_topic(topic)
526
414
topic_registry.register('bugs', get_bugs_topic, 'Bug tracker support')
527
415
topic_registry.register('repositories', _repositories,
528
 
                        'Basic information on shared repositories.',
529
 
                        SECT_CONCEPT)
 
416
                        'Basic information on shared repositories.')
530
417
topic_registry.register('working-trees', _working_trees,
531
 
                        'Information on working trees', SECT_CONCEPT)
532
 
topic_registry.register('env-variables', _env_variables,
533
 
                        'Environment variable names and values')
534
 
topic_registry.register('files', _files,
535
 
                        'Information on configuration and log files')
 
418
                        'Information on working trees')
536
419
 
537
420
 
538
421
class HelpTopicIndex(object):
570
453
        """
571
454
        self.topic = topic
572
455
 
573
 
    def get_help_text(self, additional_see_also=None, plain=True):
 
456
    def get_help_text(self, additional_see_also=None):
574
457
        """Return a string with the help for this topic.
575
458
 
576
459
        :param additional_see_also: Additional help topics to be
577
460
            cross-referenced.
578
 
        :param plain: if False, raw help (reStructuredText) is
579
 
            returned instead of plain text.
580
461
        """
581
462
        result = topic_registry.get_detail(self.topic)
582
463
        # there is code duplicated here and in bzrlib/plugin.py's 
587
468
        else:
588
469
            see_also = None
589
470
        if see_also:
590
 
            result += '\n:See also: '
 
471
            result += '\nSee also: '
591
472
            result += ', '.join(see_also)
592
473
            result += '\n'
593
 
        if plain:
594
 
            result = help_as_plain_text(result)
595
474
        return result
596
475
 
597
476
    def get_help_topic(self):
598
477
        """Return the help topic this can be found under."""
599
478
        return self.topic
600
479
 
601
 
 
602
 
def help_as_plain_text(text):
603
 
    """Minimal converter of reStructuredText to plain text."""
604
 
    lines = text.splitlines()
605
 
    result = []
606
 
    for line in lines:
607
 
        if line.startswith(':'):
608
 
            line = line[1:]
609
 
        elif line.endswith('::'):
610
 
            line = line[:-1]
611
 
        result.append(line)
612
 
    return "\n".join(result) + "\n"