~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Jonathan Lange
  • Date: 2007-04-23 06:55:58 UTC
  • mfrom: (2444 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2446.
  • Revision ID: jml@canonical.com-20070423065558-wbkypy8qlhzrxugz
Merge from mainline, resolving conflict in help_topics

Show diffs side-by-side

added added

removed removed

Lines of Context:
137
137
    plugins_override
138
138
        If true, plugin commands can override builtins.
139
139
    """
 
140
    try:
 
141
        return _get_cmd_object(cmd_name, plugins_override)
 
142
    except KeyError:
 
143
        raise errors.BzrCommandError('unknown command "%s"' % cmd_name)
 
144
 
 
145
 
 
146
def _get_cmd_object(cmd_name, plugins_override=True):
 
147
    """Worker for get_cmd_object which raises KeyError rather than BzrCommandError."""
140
148
    from bzrlib.externalcommand import ExternalCommand
141
149
 
142
150
    # We want only 'ascii' command names, but the user may have typed
159
167
    cmd_obj = ExternalCommand.find_command(cmd_name)
160
168
    if cmd_obj:
161
169
        return cmd_obj
162
 
 
163
 
    raise errors.BzrCommandError('unknown command "%s"' % cmd_name)
 
170
    raise KeyError
164
171
 
165
172
 
166
173
class Command(object):
233
240
        if self.__doc__ == Command.__doc__:
234
241
            warn("No help message set for %r" % self)
235
242
 
236
 
    def get_see_also(self):
 
243
    def _usage(self):
 
244
        """Return single-line grammar for this command.
 
245
 
 
246
        Only describes arguments, not options.
 
247
        """
 
248
        s = 'bzr ' + self.name() + ' '
 
249
        for aname in self.takes_args:
 
250
            aname = aname.upper()
 
251
            if aname[-1] in ['$', '+']:
 
252
                aname = aname[:-1] + '...'
 
253
            elif aname[-1] == '?':
 
254
                aname = '[' + aname[:-1] + ']'
 
255
            elif aname[-1] == '*':
 
256
                aname = '[' + aname[:-1] + '...]'
 
257
            s += aname + ' '
 
258
                
 
259
        assert s[-1] == ' '
 
260
        s = s[:-1]
 
261
        return s
 
262
 
 
263
    def get_help_text(self, additional_see_also=None):
 
264
        """Return a text string with help for this command.
 
265
        
 
266
        :param additional_see_also: Additional help topics to be
 
267
            cross-referenced.
 
268
        """
 
269
        doc = self.help()
 
270
        if doc is None:
 
271
            raise NotImplementedError("sorry, no detailed help yet for %r" % self.name())
 
272
 
 
273
        result = ""
 
274
        result += 'usage: %s\n' % self._usage()
 
275
 
 
276
        if self.aliases:
 
277
            result += 'aliases:\n'
 
278
            result += ', '.join(self.aliases) + '\n'
 
279
 
 
280
        result += '\n'
 
281
 
 
282
        plugin_name = self.plugin_name()
 
283
        if plugin_name is not None:
 
284
            result += '(From plugin "%s")' % plugin_name
 
285
            result += '\n\n'
 
286
 
 
287
        result += doc
 
288
        if result[-1] != '\n':
 
289
            result += '\n'
 
290
        result += '\n'
 
291
        result += option.get_optparser(self.options()).format_option_help()
 
292
        see_also = self.get_see_also(additional_see_also)
 
293
        if see_also:
 
294
            result += '\nSee also: '
 
295
            result += ', '.join(see_also)
 
296
            result += '\n'
 
297
        return result
 
298
 
 
299
    def get_help_topic(self):
 
300
        """Return the commands help topic - its name."""
 
301
        return self.name()
 
302
 
 
303
    def get_see_also(self, additional_terms=None):
237
304
        """Return a list of help topics that are related to this ommand.
238
305
        
239
306
        The list is derived from the content of the _see_also attribute. Any
240
307
        duplicates are removed and the result is in lexical order.
 
308
        :param additional_terms: Additional help topics to cross-reference.
241
309
        :return: A list of help topics.
242
310
        """
243
 
        return sorted(set(getattr(self, '_see_also', [])))
 
311
        see_also = set(getattr(self, '_see_also', []))
 
312
        if additional_terms:
 
313
            see_also.update(additional_terms)
 
314
        return sorted(see_also)
244
315
 
245
316
    def options(self):
246
317
        """Return dict of valid options for this command.
288
359
            argv = []
289
360
        args, opts = parse_args(self, argv, alias_argv)
290
361
        if 'help' in opts:  # e.g. bzr add --help
291
 
            from bzrlib.help import help_on_command
292
 
            help_on_command(self.name())
 
362
            sys.stdout.write(self.get_help_text())
293
363
            return 0
294
364
        # mix arguments and options into one dictionary
295
365
        cmdargs = _match_argform(self.name(), self.takes_args, args)
657
727
            pdb.post_mortem(sys.exc_traceback)
658
728
        return 3
659
729
 
 
730
 
 
731
class HelpCommandIndex(object):
 
732
    """A index for bzr help that returns commands."""
 
733
 
 
734
    def __init__(self):
 
735
        self.prefix = 'commands/'
 
736
 
 
737
    def get_topics(self, topic):
 
738
        """Search for topic amongst commands.
 
739
 
 
740
        :param topic: A topic to search for.
 
741
        :return: A list which is either empty or contains a single
 
742
            Command entry.
 
743
        """
 
744
        if topic and topic.startswith(self.prefix):
 
745
            topic = topic[len(self.prefix):]
 
746
        try:
 
747
            cmd = _get_cmd_object(topic)
 
748
        except KeyError:
 
749
            return []
 
750
        else:
 
751
            return [cmd]
 
752
 
 
753
 
660
754
if __name__ == '__main__':
661
755
    sys.exit(main(sys.argv))