/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

merge bzr.dev r4042

Show diffs side-by-side

added added

removed removed

Lines of Context:
50
50
 
51
51
from bzrlib import registry
52
52
# Compatibility
 
53
from bzrlib.hooks import Hooks
53
54
from bzrlib.option import Option
54
55
 
55
56
 
138
139
            real_name = _unsquish_command_name(name)
139
140
            r[real_name] = builtins[name]
140
141
    return r
141
 
            
 
142
 
142
143
 
143
144
def builtin_command_names():
144
145
    """Return list of builtin command names."""
145
146
    return _builtin_commands().keys()
146
 
    
 
147
 
147
148
 
148
149
def plugin_command_names():
149
150
    return plugin_cmds.keys()
156
157
        d.update(plugin_cmds.iteritems())
157
158
    return d
158
159
 
159
 
    
 
160
 
160
161
def get_all_cmds(plugins_override=True):
161
162
    """Return canonical name and class for all registered commands."""
162
163
    for k, v in _get_cmd_dict(plugins_override=plugins_override).iteritems():
170
171
        If true, plugin commands can override builtins.
171
172
    """
172
173
    try:
173
 
        return _get_cmd_object(cmd_name, plugins_override)
 
174
        cmd = _get_cmd_object(cmd_name, plugins_override)
 
175
        # Allow plugins to extend commands
 
176
        for hook in Command.hooks['extend_command']:
 
177
            hook(cmd)
 
178
        return cmd
174
179
    except KeyError:
175
180
        raise errors.BzrCommandError('unknown command "%s"' % cmd_name)
176
181
 
216
221
        except errors.NoPluginAvailable:
217
222
            pass
218
223
        else:
219
 
            raise errors.CommandAvailableInPlugin(cmd_name, 
 
224
            raise errors.CommandAvailableInPlugin(cmd_name,
220
225
                                                  plugin_metadata, provider)
221
 
 
222
226
    raise KeyError
223
227
 
224
228
 
279
283
            sys.stdout is forced to be a binary stream, and line-endings
280
284
            will not mangled.
281
285
 
 
286
    :cvar hooks: An instance of CommandHooks.
282
287
    """
283
288
    aliases = []
284
289
    takes_args = []
286
291
    encoding_type = 'strict'
287
292
 
288
293
    hidden = False
289
 
    
 
294
 
290
295
    def __init__(self):
291
296
        """Construct an instance of this command."""
292
297
        if self.__doc__ == Command.__doc__:
296
301
 
297
302
    def _maybe_expand_globs(self, file_list):
298
303
        """Glob expand file_list if the platform does not do that itself.
299
 
        
 
304
 
300
305
        :return: A possibly empty list of unicode paths.
301
306
 
302
307
        Introduced in bzrlib 0.18.
328
333
    def get_help_text(self, additional_see_also=None, plain=True,
329
334
                      see_also_as_links=False):
330
335
        """Return a text string with help for this command.
331
 
        
 
336
 
332
337
        :param additional_see_also: Additional help topics to be
333
338
            cross-referenced.
334
339
        :param plain: if False, raw help (reStructuredText) is
341
346
            raise NotImplementedError("sorry, no detailed help yet for %r" % self.name())
342
347
 
343
348
        # Extract the summary (purpose) and sections out from the text
344
 
        purpose,sections = self._get_help_parts(doc)
 
349
        purpose,sections,order = self._get_help_parts(doc)
345
350
 
346
351
        # If a custom usage section was provided, use it
347
352
        if sections.has_key('Usage'):
379
384
        # Add the custom sections (e.g. Examples). Note that there's no need
380
385
        # to indent these as they must be indented already in the source.
381
386
        if sections:
382
 
            labels = sorted(sections.keys())
383
 
            for label in labels:
384
 
                result += ':%s:\n%s\n\n' % (label,sections[label])
 
387
            for label in order:
 
388
                if sections.has_key(label):
 
389
                    result += ':%s:\n%s\n\n' % (label,sections[label])
385
390
 
386
391
        # Add the aliases, source (plug-in) and see also links, if any
387
392
        if self.aliases:
416
421
    def _get_help_parts(text):
417
422
        """Split help text into a summary and named sections.
418
423
 
419
 
        :return: (summary,sections) where summary is the top line and
 
424
        :return: (summary,sections,order) where summary is the top line and
420
425
            sections is a dictionary of the rest indexed by section name.
 
426
            order is the order the section appear in the text.
421
427
            A section starts with a heading line of the form ":xxx:".
422
428
            Indented text on following lines is the section value.
423
429
            All text found outside a named section is assigned to the
424
430
            default section which is given the key of None.
425
431
        """
426
 
        def save_section(sections, label, section):
 
432
        def save_section(sections, order, label, section):
427
433
            if len(section) > 0:
428
434
                if sections.has_key(label):
429
435
                    sections[label] += '\n' + section
430
436
                else:
 
437
                    order.append(label)
431
438
                    sections[label] = section
432
439
 
433
440
        lines = text.rstrip().splitlines()
434
441
        summary = lines.pop(0)
435
442
        sections = {}
 
443
        order = []
436
444
        label,section = None,''
437
445
        for line in lines:
438
446
            if line.startswith(':') and line.endswith(':') and len(line) > 2:
439
 
                save_section(sections, label, section)
 
447
                save_section(sections, order, label, section)
440
448
                label,section = line[1:-1],''
441
449
            elif (label is not None) and len(line) > 1 and not line[0].isspace():
442
 
                save_section(sections, label, section)
 
450
                save_section(sections, order, label, section)
443
451
                label,section = None,line
444
452
            else:
445
453
                if len(section) > 0:
446
454
                    section += '\n' + line
447
455
                else:
448
456
                    section = line
449
 
        save_section(sections, label, section)
450
 
        return summary, sections
 
457
        save_section(sections, order, label, section)
 
458
        return summary, sections, order
451
459
 
452
460
    def get_help_topic(self):
453
461
        """Return the commands help topic - its name."""
455
463
 
456
464
    def get_see_also(self, additional_terms=None):
457
465
        """Return a list of help topics that are related to this command.
458
 
        
 
466
 
459
467
        The list is derived from the content of the _see_also attribute. Any
460
468
        duplicates are removed and the result is in lexical order.
461
469
        :param additional_terms: Additional help topics to cross-reference.
573
581
            return None
574
582
 
575
583
 
 
584
class CommandHooks(Hooks):
 
585
    """Hooks related to Command object creation/enumeration."""
 
586
 
 
587
    def __init__(self):
 
588
        """Create the default hooks.
 
589
 
 
590
        These are all empty initially, because by default nothing should get
 
591
        notified.
 
592
        """
 
593
        Hooks.__init__(self)
 
594
        # Introduced in 1.13:
 
595
        # invoked after creating a command object to allow modifications such
 
596
        # as adding or removing options, docs etc. Invoked with the command
 
597
        # object.
 
598
        self['extend_command'] = []
 
599
 
 
600
Command.hooks = CommandHooks()
 
601
 
 
602
 
576
603
def parse_args(command, argv, alias_argv=None):
577
604
    """Parse command line.
578
 
    
 
605
 
579
606
    Arguments and options are parsed at this level before being passed
580
607
    down to specific command handlers.  This routine knows, from a
581
608
    lookup table, something about the available options, what optargs
630
657
                               % (cmd, argname.upper()))
631
658
            else:
632
659
                argdict[argname] = args.pop(0)
633
 
            
 
660
 
634
661
    if args:
635
662
        raise errors.BzrCommandError("extra argument to command %s: %s"
636
663
                                     % (cmd, args[0]))
719
746
       The command-line arguments, without the program name from argv[0]
720
747
       These should already be decoded. All library/test code calling
721
748
       run_bzr should be passing valid strings (don't need decoding).
722
 
    
 
749
 
723
750
    Returns a command status or raises an exception.
724
751
 
725
752
    Special master options: these must come before the command because
846
873
        # --verbose in their own way.
847
874
        option._verbosity_level = saved_verbosity_level
848
875
 
 
876
 
849
877
def display_command(func):
850
878
    """Decorator that suppresses pipe/interrupt errors."""
851
879
    def ignore_pipe(*args, **kwargs):
868
896
 
869
897
def main(argv):
870
898
    import bzrlib.ui
871
 
    from bzrlib.ui.text import TextUIFactory
872
 
    bzrlib.ui.ui_factory = TextUIFactory()
 
899
    bzrlib.ui.ui_factory = bzrlib.ui.make_ui_for_terminal(
 
900
        sys.stdin, sys.stdout, sys.stderr)
873
901
 
874
902
    # Is this a final release version? If so, we should suppress warnings
875
903
    if bzrlib.version_info[3] == 'final':
894
922
    except (KeyboardInterrupt, Exception), e:
895
923
        # used to handle AssertionError and KeyboardInterrupt
896
924
        # specially here, but hopefully they're handled ok by the logger now
897
 
        exitcode = trace.report_exception(sys.exc_info(), sys.stderr)
 
925
        exc_info = sys.exc_info()
 
926
        exitcode = trace.report_exception(exc_info, sys.stderr)
898
927
        if os.environ.get('BZR_PDB'):
899
928
            print '**** entering debugger'
 
929
            tb = exc_info[2]
900
930
            import pdb
901
 
            pdb.post_mortem(sys.exc_traceback)
 
931
            if sys.version_info[:2] < (2, 6):
 
932
                # XXX: we want to do
 
933
                #    pdb.post_mortem(tb)
 
934
                # but because pdb.post_mortem gives bad results for tracebacks
 
935
                # from inside generators, we do it manually.
 
936
                # (http://bugs.python.org/issue4150, fixed in Python 2.6)
 
937
 
 
938
                # Setup pdb on the traceback
 
939
                p = pdb.Pdb()
 
940
                p.reset()
 
941
                p.setup(tb.tb_frame, tb)
 
942
                # Point the debugger at the deepest frame of the stack
 
943
                p.curindex = len(p.stack) - 1
 
944
                p.curframe = p.stack[p.curindex]
 
945
                # Start the pdb prompt.
 
946
                p.print_stack_entry(p.stack[p.curindex])
 
947
                p.execRcLines()
 
948
                p.cmdloop()
 
949
            else:
 
950
                pdb.post_mortem(tb)
902
951
        return exitcode
903
952
 
904
953
 
947
996
 
948
997
    def plugin_for_command(self, cmd_name):
949
998
        '''Takes a command and returns the information for that plugin
950
 
        
951
 
        :return: A dictionary with all the available information 
 
999
 
 
1000
        :return: A dictionary with all the available information
952
1001
        for the requested plugin
953
1002
        '''
954
1003
        raise NotImplementedError