~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Ian Clatworthy
  • Date: 2009-09-09 00:49:50 UTC
  • mto: (4634.37.2 prepare-2.0)
  • mto: This revision was merged to the branch mainline in revision 4689.
  • Revision ID: ian.clatworthy@canonical.com-20090909004950-43z4zdicb5u91iet
tweak quick reference naming to make it consistent with other PDFs

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2006, 2008 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
40
40
 
41
41
import bzrlib
42
42
from bzrlib import (
43
 
    cleanup,
44
43
    debug,
45
44
    errors,
46
45
    option,
47
46
    osutils,
48
47
    trace,
49
 
    ui,
50
48
    win32utils,
51
49
    )
52
50
""")
58
56
from bzrlib.symbol_versioning import (
59
57
    deprecated_function,
60
58
    deprecated_in,
61
 
    deprecated_method,
 
59
    suppress_deprecation_warnings,
62
60
    )
63
61
 
64
62
 
103
101
            registry.Registry.register(self, k_unsquished, cmd,
104
102
                                       override_existing=decorate, info=info)
105
103
        except KeyError:
106
 
            trace.warning('Two plugins defined the same command: %r' % k)
107
 
            trace.warning('Not loading the one in %r' %
108
 
                sys.modules[cmd.__module__])
109
 
            trace.warning('Previously this command was registered from %r' %
110
 
                sys.modules[previous.__module__])
 
104
            trace.log_error('Two plugins defined the same command: %r' % k)
 
105
            trace.log_error('Not loading the one in %r' %
 
106
                            sys.modules[cmd.__module__])
 
107
            trace.log_error('Previously this command was registered from %r' %
 
108
                            sys.modules[previous.__module__])
111
109
        return previous
112
110
 
113
111
    def register_lazy(self, command_name, aliases, module_name):
185
183
    return plugin_cmds.keys()
186
184
 
187
185
 
 
186
@deprecated_function(deprecated_in((1, 17, 0)))
 
187
def get_all_cmds(plugins_override=False):
 
188
    """Return canonical name and class for most commands.
 
189
    
 
190
    NB: This does not return all commands since the introduction of
 
191
    command hooks, and returning the class is not sufficient to 
 
192
    get correctly setup commands, which is why it is deprecated.
 
193
 
 
194
    Use 'all_command_names' + 'get_cmd_object' instead.
 
195
    """
 
196
    d = _builtin_commands()
 
197
    if plugins_override:
 
198
        d.update(plugin_cmds.iteritems())
 
199
    for k, v in d.iteritems():
 
200
        yield k,v
 
201
 
 
202
 
188
203
def get_cmd_object(cmd_name, plugins_override=True):
189
204
    """Return the command object for a command.
190
205
 
367
382
            warn("No help message set for %r" % self)
368
383
        # List of standard options directly supported
369
384
        self.supported_std_options = []
370
 
        self._operation = cleanup.OperationWithCleanups(self.run)
371
 
    
372
 
    def add_cleanup(self, cleanup_func, *args, **kwargs):
373
 
        """Register a function to call after self.run returns or raises.
374
 
 
375
 
        Functions will be called in LIFO order.
376
 
        """
377
 
        self._operation.add_cleanup(cleanup_func, *args, **kwargs)
378
 
 
379
 
    def cleanup_now(self):
380
 
        """Execute and empty pending cleanup functions immediately.
381
 
 
382
 
        After cleanup_now all registered cleanups are forgotten.  add_cleanup
383
 
        may be called again after cleanup_now; these cleanups will be called
384
 
        after self.run returns or raises (or when cleanup_now is next called).
385
 
 
386
 
        This is useful for releasing expensive or contentious resources (such
387
 
        as write locks) before doing further work that does not require those
388
 
        resources (such as writing results to self.outf).
389
 
        """
390
 
        self._operation.cleanup_now()
391
 
        
392
 
    @deprecated_method(deprecated_in((2, 1, 0)))
 
385
 
393
386
    def _maybe_expand_globs(self, file_list):
394
387
        """Glob expand file_list if the platform does not do that itself.
395
388
 
396
 
        Not used anymore, now that the bzr command-line parser globs on
397
 
        Windows.
398
 
 
399
389
        :return: A possibly empty list of unicode paths.
400
390
 
401
391
        Introduced in bzrlib 0.18.
402
392
        """
403
 
        return file_list
 
393
        if not file_list:
 
394
            file_list = []
 
395
        if sys.platform == 'win32':
 
396
            file_list = win32utils.glob_expand(file_list)
 
397
        return list(file_list)
404
398
 
405
399
    def _usage(self):
406
400
        """Return single-line grammar for this command.
463
457
        # so we get <https://bugs.launchpad.net/bzr/+bug/249908>.  -- mbp
464
458
        # 20090319
465
459
        options = option.get_optparser(self.options()).format_option_help()
466
 
        # XXX: According to the spec, ReST option lists actually don't support 
467
 
        # options like --1.9 so that causes syntax errors (in Sphinx at least).
468
 
        # As that pattern always appears in the commands that break, we trap
469
 
        # on that and then format that block of 'format' options as a literal
470
 
        # block.
471
 
        if not plain and options.find('  --1.9  ') != -1:
472
 
            options = options.replace(' format:\n', ' format::\n\n', 1)
473
460
        if options.startswith('Options:'):
474
461
            result += ':' + options
475
462
        elif options.startswith('options:'):
515
502
                        # so don't create a real link
516
503
                        see_also_links.append(item)
517
504
                    else:
518
 
                        # Use a Sphinx link for this entry
519
 
                        link_text = ":doc:`%s <%s-help>`" % (item, item)
520
 
                        see_also_links.append(link_text)
 
505
                        # Use a reST link for this entry
 
506
                        see_also_links.append("`%s`_" % (item,))
521
507
                see_also = see_also_links
522
508
            result += ':See also: '
523
509
            result += ', '.join(see_also) + '\n'
601
587
 
602
588
    def _setup_outf(self):
603
589
        """Return a file linked to stdout, which has proper encoding."""
604
 
        self.outf = ui.ui_factory.make_output_stream(
605
 
            encoding_type=self.encoding_type)
 
590
        # Originally I was using self.stdout, but that looks
 
591
        # *way* too much like sys.stdout
 
592
        if self.encoding_type == 'exact':
 
593
            # force sys.stdout to be binary stream on win32
 
594
            if sys.platform == 'win32':
 
595
                fileno = getattr(sys.stdout, 'fileno', None)
 
596
                if fileno:
 
597
                    import msvcrt
 
598
                    msvcrt.setmode(fileno(), os.O_BINARY)
 
599
            self.outf = sys.stdout
 
600
            return
 
601
 
 
602
        output_encoding = osutils.get_terminal_encoding()
 
603
 
 
604
        self.outf = codecs.getwriter(output_encoding)(sys.stdout,
 
605
                        errors=self.encoding_type)
 
606
        # For whatever reason codecs.getwriter() does not advertise its encoding
 
607
        # it just returns the encoding of the wrapped file, which is completely
 
608
        # bogus. So set the attribute, so we can find the correct encoding later.
 
609
        self.outf.encoding = output_encoding
606
610
 
607
611
    def run_argv_aliases(self, argv, alias_argv=None):
608
612
        """Parse the command line and run with extra aliases in alias_argv."""
 
613
        if argv is None:
 
614
            warn("Passing None for [] is deprecated from bzrlib 0.10",
 
615
                 DeprecationWarning, stacklevel=2)
 
616
            argv = []
609
617
        args, opts = parse_args(self, argv, alias_argv)
610
618
 
611
619
        # Process the standard options
636
644
 
637
645
        self._setup_outf()
638
646
 
639
 
        return self.run_direct(**all_cmd_args)
640
 
 
641
 
    def run_direct(self, *args, **kwargs):
642
 
        """Call run directly with objects (without parsing an argv list)."""
643
 
        return self._operation.run_simple(*args, **kwargs)
 
647
        return self.run(**all_cmd_args)
644
648
 
645
649
    def run(self):
646
650
        """Actually run the command.
928
932
 
929
933
    --coverage
930
934
        Generate line coverage report in the specified directory.
931
 
 
932
 
    --concurrency
933
 
        Specify the number of processes that can be run concurrently (selftest).
934
935
    """
935
 
    trace.mutter("bazaar version: " + bzrlib.__version__)
936
936
    argv = list(argv)
937
937
    trace.mutter("bzr arguments: %r", argv)
938
938
 
962
962
            opt_no_aliases = True
963
963
        elif a == '--builtin':
964
964
            opt_builtin = True
965
 
        elif a == '--concurrency':
966
 
            os.environ['BZR_CONCURRENCY'] = argv[i + 1]
967
 
            i += 1
968
965
        elif a == '--coverage':
969
966
            opt_coverage_dir = argv[i + 1]
970
967
            i += 1
1031
1028
            ret = apply_coveraged(opt_coverage_dir, run, *run_argv)
1032
1029
        else:
1033
1030
            ret = run(*run_argv)
 
1031
        if 'memory' in debug.debug_flags:
 
1032
            trace.debug_memory('Process status after command:', short=False)
1034
1033
        return ret or 0
1035
1034
    finally:
1036
1035
        # reset, in case we may do other commands later within the same
1037
1036
        # process. Commands that want to execute sub-commands must propagate
1038
1037
        # --verbose in their own way.
1039
 
        if 'memory' in debug.debug_flags:
1040
 
            trace.debug_memory('Process status after command:', short=False)
1041
1038
        option._verbosity_level = saved_verbosity_level
1042
1039
 
1043
1040
 
1077
1074
        "bzr plugin-provider-db check")
1078
1075
 
1079
1076
 
1080
 
 
1081
 
def _specified_or_unicode_argv(argv):
1082
 
    # For internal or testing use, argv can be passed.  Otherwise, get it from
1083
 
    # the process arguments in a unicode-safe way.
 
1077
def main(argv=None):
 
1078
    """Main entry point of command-line interface.
 
1079
 
 
1080
    :param argv: list of unicode command-line arguments similar to sys.argv.
 
1081
        argv[0] is script name usually, it will be ignored.
 
1082
        Don't pass here sys.argv because this list contains plain strings
 
1083
        and not unicode; pass None instead.
 
1084
 
 
1085
    :return: exit code of bzr command.
 
1086
    """
 
1087
    import bzrlib.ui
 
1088
    bzrlib.ui.ui_factory = bzrlib.ui.make_ui_for_terminal(
 
1089
        sys.stdin, sys.stdout, sys.stderr)
 
1090
 
 
1091
    # Is this a final release version? If so, we should suppress warnings
 
1092
    if bzrlib.version_info[3] == 'final':
 
1093
        suppress_deprecation_warnings(override=False)
1084
1094
    if argv is None:
1085
 
        return osutils.get_unicode_argv()
 
1095
        argv = osutils.get_unicode_argv()
1086
1096
    else:
1087
1097
        new_argv = []
1088
1098
        try:
1094
1104
                    new_argv.append(a.decode('ascii'))
1095
1105
        except UnicodeDecodeError:
1096
1106
            raise errors.BzrError("argv should be list of unicode strings.")
1097
 
        return new_argv
1098
 
 
1099
 
 
1100
 
def main(argv=None):
1101
 
    """Main entry point of command-line interface.
1102
 
 
1103
 
    Typically `bzrlib.initialize` should be called first.
1104
 
 
1105
 
    :param argv: list of unicode command-line arguments similar to sys.argv.
1106
 
        argv[0] is script name usually, it will be ignored.
1107
 
        Don't pass here sys.argv because this list contains plain strings
1108
 
        and not unicode; pass None instead.
1109
 
 
1110
 
    :return: exit code of bzr command.
1111
 
    """
1112
 
    argv = _specified_or_unicode_argv(argv)
 
1107
        argv = new_argv
1113
1108
    ret = run_bzr_catch_errors(argv)
1114
 
    bzrlib.ui.ui_factory.log_transport_activity(
1115
 
        display=('bytes' in debug.debug_flags))
1116
1109
    trace.mutter("return code %d", ret)
1117
1110
    return ret
1118
1111
 
1123
1116
    This function assumed that that UI layer is setup, that symbol deprecations
1124
1117
    are already applied, and that unicode decoding has already been performed on argv.
1125
1118
    """
1126
 
    # done here so that they're covered for every test run
1127
1119
    install_bzr_command_hooks()
1128
1120
    return exception_to_return_code(run_bzr, argv)
1129
1121
 
1134
1126
    This is used for the test suite, and might be useful for other programs
1135
1127
    that want to wrap the commandline interface.
1136
1128
    """
1137
 
    # done here so that they're covered for every test run
1138
1129
    install_bzr_command_hooks()
1139
1130
    try:
1140
1131
        return run_bzr(argv)
1190
1181
            yield provider
1191
1182
 
1192
1183
command_providers_registry = ProvidersRegistry()
 
1184
 
 
1185
 
 
1186
if __name__ == '__main__':
 
1187
    sys.exit(main(sys.argv))