~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Robert Collins
  • Date: 2007-09-05 05:51:34 UTC
  • mto: (2592.3.126 repository)
  • mto: This revision was merged to the branch mainline in revision 2879.
  • Revision ID: robertc@robertcollins.net-20070905055134-pwbueao0qq6krf9u
nuke _read_tree_state and snapshot from inventory, moving responsibility into the commit builder.

Show diffs side-by-side

added added

removed removed

Lines of Context:
43
43
    errors,
44
44
    option,
45
45
    osutils,
46
 
    registry,
47
46
    trace,
48
47
    win32utils,
49
48
    )
95
94
 
96
95
 
97
96
def _unsquish_command_name(cmd):
 
97
    assert cmd.startswith("cmd_")
98
98
    return cmd[4:].replace('_','-')
99
99
 
100
100
 
168
168
    cmd_obj = ExternalCommand.find_command(cmd_name)
169
169
    if cmd_obj:
170
170
        return cmd_obj
171
 
 
172
 
    # look for plugins that provide this command but aren't installed
173
 
    for provider in command_providers_registry:
174
 
        try:
175
 
            plugin_metadata = provider.plugin_for_command(cmd_name)
176
 
        except errors.NoPluginAvailable:
177
 
            pass
178
 
        else:
179
 
            raise errors.CommandAvailableInPlugin(cmd_name, 
180
 
                                                  plugin_metadata, provider)
181
 
 
182
171
    raise KeyError
183
172
 
184
173
 
282
271
            elif aname[-1] == '*':
283
272
                aname = '[' + aname[:-1] + '...]'
284
273
            s += aname + ' '
285
 
        s = s[:-1]      # remove last space
 
274
                
 
275
        assert s[-1] == ' '
 
276
        s = s[:-1]
286
277
        return s
287
278
 
288
279
    def get_help_text(self, additional_see_also=None, plain=True,
366
357
            result += ':See also: '
367
358
            result += ', '.join(see_also) + '\n'
368
359
 
369
 
        # If this will be rendered as plain text, convert it
 
360
        # If this will be rendered as plan text, convert it
370
361
        if plain:
371
362
            import bzrlib.help_topics
372
363
            result = bzrlib.help_topics.help_as_plain_text(result)
389
380
                    sections[label] += '\n' + section
390
381
                else:
391
382
                    sections[label] = section
392
 
 
 
383
            
393
384
        lines = text.rstrip().splitlines()
394
385
        summary = lines.pop(0)
395
386
        sections = {}
398
389
            if line.startswith(':') and line.endswith(':') and len(line) > 2:
399
390
                save_section(sections, label, section)
400
391
                label,section = line[1:-1],''
401
 
            elif (label is not None) and len(line) > 1 and not line[0].isspace():
 
392
            elif label != None and len(line) > 1 and not line[0].isspace():
402
393
                save_section(sections, label, section)
403
394
                label,section = None,line
404
395
            else:
442
433
 
443
434
    def _setup_outf(self):
444
435
        """Return a file linked to stdout, which has proper encoding."""
 
436
        assert self.encoding_type in ['strict', 'exact', 'replace']
 
437
 
445
438
        # Originally I was using self.stdout, but that looks
446
439
        # *way* too much like sys.stdout
447
440
        if self.encoding_type == 'exact':
456
449
 
457
450
        output_encoding = osutils.get_terminal_encoding()
458
451
 
459
 
        self.outf = codecs.getwriter(output_encoding)(sys.stdout,
460
 
                        errors=self.encoding_type)
 
452
        # use 'replace' so that we don't abort if trying to write out
 
453
        # in e.g. the default C locale.
 
454
        self.outf = codecs.getwriter(output_encoding)(sys.stdout, errors=self.encoding_type)
461
455
        # For whatever reason codecs.getwriter() does not advertise its encoding
462
456
        # it just returns the encoding of the wrapped file, which is completely
463
457
        # bogus. So set the attribute, so we can find the correct encoding later.
497
491
        self._setup_outf()
498
492
 
499
493
        return self.run(**all_cmd_args)
500
 
 
 
494
    
501
495
    def run(self):
502
496
        """Actually run the command.
503
497
 
597
591
 
598
592
    return argdict
599
593
 
600
 
def apply_coveraged(dirname, the_callable, *args, **kwargs):
601
 
    # Cannot use "import trace", as that would import bzrlib.trace instead of
602
 
    # the standard library's trace.
603
 
    trace = __import__('trace')
604
 
 
605
 
    tracer = trace.Trace(count=1, trace=0)
606
 
    sys.settrace(tracer.globaltrace)
607
 
 
608
 
    ret = the_callable(*args, **kwargs)
609
 
 
610
 
    sys.settrace(None)
611
 
    results = tracer.results()
612
 
    results.write_results(show_missing=1, summary=False,
613
 
                          coverdir=dirname)
614
594
 
615
595
 
616
596
def apply_profiled(the_callable, *args, **kwargs):
648
628
    return ret
649
629
 
650
630
 
651
 
def shlex_split_unicode(unsplit):
652
 
    import shlex
653
 
    return [u.decode('utf-8') for u in shlex.split(unsplit.encode('utf-8'))]
654
 
 
655
 
 
656
631
def get_alias(cmd, config=None):
657
632
    """Return an expanded alias, or None if no alias exists.
658
633
 
668
643
        config = bzrlib.config.GlobalConfig()
669
644
    alias = config.get_alias(cmd)
670
645
    if (alias):
671
 
        return shlex_split_unicode(alias)
 
646
        import shlex
 
647
        return [a.decode('utf-8') for a in shlex.split(alias.encode('utf-8'))]
672
648
    return None
673
649
 
674
650
 
703
679
 
704
680
    --lsprof
705
681
        Run under the Python lsprof profiler.
706
 
 
707
 
    --coverage
708
 
        Generate line coverage report in the specified directory.
709
682
    """
710
683
    argv = list(argv)
711
684
    trace.mutter("bzr arguments: %r", argv)
712
685
 
713
686
    opt_lsprof = opt_profile = opt_no_plugins = opt_builtin =  \
714
687
                opt_no_aliases = False
715
 
    opt_lsprof_file = opt_coverage_dir = None
 
688
    opt_lsprof_file = None
716
689
 
717
690
    # --no-plugins is handled specially at a very early stage. We need
718
691
    # to load plugins before doing other command parsing so that they
736
709
            opt_no_aliases = True
737
710
        elif a == '--builtin':
738
711
            opt_builtin = True
739
 
        elif a == '--coverage':
740
 
            opt_coverage_dir = argv[i + 1]
741
 
            i += 1
742
712
        elif a.startswith('-D'):
743
713
            debug.debug_flags.add(a[2:])
744
714
        else:
752
722
        return 0
753
723
 
754
724
    if argv[0] == '--version':
755
 
        from bzrlib.builtins import cmd_version
756
 
        cmd_version().run_argv_aliases([])
 
725
        from bzrlib.version import show_version
 
726
        show_version()
757
727
        return 0
758
728
        
759
729
    if not opt_no_plugins:
782
752
 
783
753
    try:
784
754
        if opt_lsprof:
785
 
            if opt_coverage_dir:
786
 
                trace.warning(
787
 
                    '--coverage ignored, because --lsprof is in use.')
788
755
            ret = apply_lsprofiled(opt_lsprof_file, run, *run_argv)
789
756
        elif opt_profile:
790
 
            if opt_coverage_dir:
791
 
                trace.warning(
792
 
                    '--coverage ignored, because --profile is in use.')
793
757
            ret = apply_profiled(run, *run_argv)
794
 
        elif opt_coverage_dir:
795
 
            ret = apply_coveraged(opt_coverage_dir, run, *run_argv)
796
758
        else:
797
759
            ret = run(*run_argv)
798
 
        if 'memory' in debug.debug_flags:
799
 
            try:
800
 
                status_file = file('/proc/%s/status' % os.getpid(), 'rb')
801
 
            except IOError:
802
 
                pass
803
 
            else:
804
 
                status = status_file.read()
805
 
                status_file.close()
806
 
                trace.note("Process status after command:")
807
 
                for line in status.splitlines():
808
 
                    trace.note(line)
809
760
        return ret or 0
810
761
    finally:
811
762
        # reset, in case we may do other commands later within the same process
835
786
    import bzrlib.ui
836
787
    from bzrlib.ui.text import TextUIFactory
837
788
    bzrlib.ui.ui_factory = TextUIFactory()
838
 
     
839
 
    # Is this a final release version? If so, we should suppress warnings
840
 
    if bzrlib.version_info[3] == 'final':
841
 
        from bzrlib import symbol_versioning
842
 
        symbol_versioning.suppress_deprecation_warnings(override=False)
843
789
    try:
844
790
        argv = [a.decode(bzrlib.user_encoding) for a in argv[1:]]
845
791
    except UnicodeDecodeError:
851
797
 
852
798
 
853
799
def run_bzr_catch_errors(argv):
854
 
    # Note: The except clause logic below should be kept in sync with the
855
 
    # profile() routine in lsprof.py.
856
800
    try:
857
801
        return run_bzr(argv)
858
802
    except (KeyboardInterrupt, Exception), e:
859
803
        # used to handle AssertionError and KeyboardInterrupt
860
804
        # specially here, but hopefully they're handled ok by the logger now
861
 
        exitcode = trace.report_exception(sys.exc_info(), sys.stderr)
 
805
        trace.report_exception(sys.exc_info(), sys.stderr)
862
806
        if os.environ.get('BZR_PDB'):
863
807
            print '**** entering debugger'
864
808
            import pdb
865
809
            pdb.post_mortem(sys.exc_traceback)
866
 
        return exitcode
867
 
 
868
 
 
869
 
def run_bzr_catch_user_errors(argv):
870
 
    """Run bzr and report user errors, but let internal errors propagate.
871
 
 
872
 
    This is used for the test suite, and might be useful for other programs
873
 
    that want to wrap the commandline interface.
874
 
    """
875
 
    try:
876
 
        return run_bzr(argv)
877
 
    except Exception, e:
878
 
        if (isinstance(e, (OSError, IOError))
879
 
            or not getattr(e, 'internal_error', True)):
880
 
            trace.report_exception(sys.exc_info(), sys.stderr)
881
 
            return 3
882
 
        else:
883
 
            raise
 
810
        return 3
884
811
 
885
812
 
886
813
class HelpCommandIndex(object):
906
833
            return [cmd]
907
834
 
908
835
 
909
 
class Provider(object):
910
 
    '''Generic class to be overriden by plugins'''
911
 
 
912
 
    def plugin_for_command(self, cmd_name):
913
 
        '''Takes a command and returns the information for that plugin
914
 
        
915
 
        :return: A dictionary with all the available information 
916
 
        for the requested plugin
917
 
        '''
918
 
        raise NotImplementedError
919
 
 
920
 
 
921
 
class ProvidersRegistry(registry.Registry):
922
 
    '''This registry exists to allow other providers to exist'''
923
 
 
924
 
    def __iter__(self):
925
 
        for key, provider in self.iteritems():
926
 
            yield provider
927
 
 
928
 
command_providers_registry = ProvidersRegistry()
929
 
 
930
 
 
931
836
if __name__ == '__main__':
932
837
    sys.exit(main(sys.argv))