/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 breezy/commands.py

  • Committer: Martin
  • Date: 2018-11-16 19:09:31 UTC
  • mfrom: (7175 work)
  • mto: This revision was merged to the branch mainline in revision 7177.
  • Revision ID: gzlist@googlemail.com-20181116190931-rmh7pk2an1zuecby
Merge trunk to resolve conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
 
39
39
import breezy
40
40
from breezy import (
41
 
    config,
42
41
    cleanup,
43
42
    cmdline,
44
43
    debug,
99
98
 
100
99
class CommandRegistry(registry.Registry):
101
100
    """Special registry mapping command names to command classes.
102
 
    
 
101
 
103
102
    :ivar overridden_registry: Look in this registry for commands being
104
103
        overridden by this registry.  This can be used to tell plugin commands
105
104
        about the builtin they're decorating.
148
147
        except KeyError:
149
148
            trace.warning('Two plugins defined the same command: %r' % k)
150
149
            trace.warning('Not loading the one in %r' %
151
 
                sys.modules[cmd.__module__])
 
150
                          sys.modules[cmd.__module__])
152
151
            trace.warning('Previously this command was registered from %r' %
153
 
                sys.modules[previous.__module__])
 
152
                          sys.modules[previous.__module__])
154
153
        for a in cmd.aliases:
155
154
            self._alias_dict[a] = k_unsquished
156
155
        return previous
177
176
def register_command(cmd, decorate=False):
178
177
    """Register a plugin command.
179
178
 
180
 
    Should generally be avoided in favor of lazy registration. 
 
179
    Should generally be avoided in favor of lazy registration.
181
180
    """
182
181
    global plugin_cmds
183
182
    return plugin_cmds.register(cmd, decorate)
210
209
 
211
210
def _list_bzr_commands(names):
212
211
    """Find commands from bzr's core and plugins.
213
 
    
214
 
    This is not the public interface, just the default hook called by all_command_names.
 
212
 
 
213
    This is not the public interface, just the default hook called by
 
214
    all_command_names.
215
215
    """
216
216
    # to eliminate duplicates
217
217
    names.update(builtin_command_names())
232
232
 
233
233
def builtin_command_names():
234
234
    """Return list of builtin command names.
235
 
    
 
235
 
236
236
    Use of all_command_names() is encouraged rather than builtin_command_names
237
237
    and/or plugin_command_names.
238
238
    """
247
247
 
248
248
# Overrides for common mispellings that heuristics get wrong
249
249
_GUESS_OVERRIDES = {
250
 
    'ic': {'ci': 0}, # heuristic finds nick
 
250
    'ic': {'ci': 0},  # heuristic finds nick
251
251
    }
252
252
 
253
253
 
271
271
        opcodes = matcher.get_opcodes()
272
272
        for opcode, l1, l2, r1, r2 in opcodes:
273
273
            if opcode == 'delete':
274
 
                distance += l2-l1
 
274
                distance += l2 - l1
275
275
            elif opcode == 'replace':
276
 
                distance += max(l2-l1, r2-l1)
 
276
                distance += max(l2 - l1, r2 - l1)
277
277
            elif opcode == 'insert':
278
 
                distance += r2-r1
 
278
                distance += r2 - r1
279
279
            elif opcode == 'equal':
280
280
                # Score equal ranges lower, making similar commands of equal
281
281
                # length closer than arbitrary same length commands.
282
 
                distance -= 0.1 * (l2-l1)
 
282
                distance -= 0.1 * (l2 - l1)
283
283
        costs[name] = distance
284
284
    costs.update(_GUESS_OVERRIDES.get(cmd_name, {}))
285
285
    costs = sorted((costs[key], key) for key in costs)
304
304
        candidate = guess_command(cmd_name)
305
305
        if candidate is not None:
306
306
            raise errors.BzrCommandError(
307
 
                    gettext('unknown command "%s". Perhaps you meant "%s"')
308
 
                    % (cmd_name, candidate))
 
307
                gettext('unknown command "%s". Perhaps you meant "%s"')
 
308
                % (cmd_name, candidate))
309
309
        raise errors.BzrCommandError(gettext('unknown command "%s"')
310
 
                % cmd_name)
 
310
                                     % cmd_name)
311
311
 
312
312
 
313
313
def _get_cmd_object(cmd_name, plugins_override=True, check_missing=True):
582
582
        # XXX: optparse implicitly rewraps the help, and not always perfectly,
583
583
        # so we get <https://bugs.launchpad.net/bzr/+bug/249908>.  -- mbp
584
584
        # 20090319
585
 
        parser = option.get_optparser([v for k, v in sorted(self.options().items())])
 
585
        parser = option.get_optparser(
 
586
            [v for k, v in sorted(self.options().items())])
586
587
        options = parser.format_option_help()
587
588
        # FIXME: According to the spec, ReST option lists actually don't
588
589
        # support options like --1.14 so that causes syntax errors (in Sphinx
615
616
                result += '\n'
616
617
        else:
617
618
            result += (gettext("See brz help %s for more details and examples.\n\n")
618
 
                % self.name())
 
619
                       % self.name())
619
620
 
620
621
        # Add the aliases, source (plug-in) and see also links, if any
621
622
        if self.aliases:
636
637
                    else:
637
638
                        # Use a Sphinx link for this entry
638
639
                        link_text = gettext(":doc:`{0} <{1}-help>`").format(
639
 
                                                                    item, item)
 
640
                            item, item)
640
641
                        see_also_links.append(link_text)
641
642
                see_also = see_also_links
642
643
            result += gettext(':See also: %s') % ', '.join(see_also) + '\n'
676
677
            if line.startswith(':') and line.endswith(':') and len(line) > 2:
677
678
                save_section(sections, order, label, section)
678
679
                label, section = line[1:-1], ''
679
 
            elif (label is not None) and len(line) > 1 and not line[0].isspace():
 
680
            elif (label is not None and len(line) > 1 and
 
681
                    not line[0].isspace()):
680
682
                save_section(sections, order, label, section)
681
683
                label, section = None, line
682
684
            else:
773
775
        you can override this method.
774
776
        """
775
777
        class_run = self.run
 
778
 
776
779
        def run(*args, **kwargs):
777
780
            for hook in Command.hooks['pre_command']:
778
781
                hook(self)
795
798
        shell error code if not.  It's OK for this method to allow
796
799
        an exception to raise up.
797
800
 
798
 
        This method is automatically wrapped by Command.__init__ with a 
 
801
        This method is automatically wrapped by Command.__init__ with a
799
802
        cleanup operation, stored as self._operation. This can be used
800
803
        via self.add_cleanup to perform automatic cleanups at the end of
801
804
        run().
827
830
    def name(self):
828
831
        """Return the canonical name for this command.
829
832
 
830
 
        The name under which it was actually invoked is available in invoked_as.
 
833
        The name under which it was actually invoked is available in invoked_as
831
834
        """
832
835
        return _unsquish_command_name(self.__class__.__name__)
833
836
 
849
852
        notified.
850
853
        """
851
854
        Hooks.__init__(self, "breezy.commands", "Command.hooks")
852
 
        self.add_hook('extend_command',
 
855
        self.add_hook(
 
856
            'extend_command',
853
857
            "Called after creating a command object to allow modifications "
854
858
            "such as adding or removing options, docs etc. Called with the "
855
859
            "new breezy.commands.Command object.", (1, 13))
856
 
        self.add_hook('get_command',
 
860
        self.add_hook(
 
861
            'get_command',
857
862
            "Called when creating a single command. Called with "
858
863
            "(cmd_or_None, command_name). get_command should either return "
859
864
            "the cmd_or_None parameter, or a replacement Command object that "
861
866
            "hooks are core infrastructure. Many users will prefer to use "
862
867
            "breezy.commands.register_command or plugin_cmds.register_lazy.",
863
868
            (1, 17))
864
 
        self.add_hook('get_missing_command',
 
869
        self.add_hook(
 
870
            'get_missing_command',
865
871
            "Called when creating a single command if no command could be "
866
872
            "found. Called with (command_name). get_missing_command should "
867
873
            "either return None, or a Command object to be used for the "
868
874
            "command.", (1, 17))
869
 
        self.add_hook('list_commands',
 
875
        self.add_hook(
 
876
            'list_commands',
870
877
            "Called when enumerating commands. Called with a set of "
871
878
            "cmd_name strings for all the commands found so far. This set "
872
879
            " is safe to mutate - e.g. to remove a command. "
873
880
            "list_commands should return the updated set of command names.",
874
881
            (1, 17))
875
 
        self.add_hook('pre_command',
 
882
        self.add_hook(
 
883
            'pre_command',
876
884
            "Called prior to executing a command. Called with the command "
877
885
            "object.", (2, 6))
878
 
        self.add_hook('post_command',
 
886
        self.add_hook(
 
887
            'post_command',
879
888
            "Called after executing a command. Called with the command "
880
889
            "object.", (2, 6))
881
890
 
 
891
 
882
892
Command.hooks = CommandHooks()
883
893
 
884
894
 
892
902
    """
893
903
    # TODO: make it a method of the Command?
894
904
    parser = option.get_optparser(
895
 
            [v for k, v in sorted(command.options().items())])
 
905
        [v for k, v in sorted(command.options().items())])
896
906
    if alias_argv is not None:
897
907
        args = alias_argv + argv
898
908
    else:
902
912
    # option name is given.  See http://bugs.python.org/issue2931
903
913
    try:
904
914
        options, args = parser.parse_args(args)
905
 
    except UnicodeEncodeError as e:
 
915
    except UnicodeEncodeError:
906
916
        raise errors.BzrCommandError(
907
917
            gettext('Only ASCII permitted in option names'))
908
918
 
920
930
        if ap[-1] == '?':
921
931
            if args:
922
932
                argdict[argname] = args.pop(0)
923
 
        elif ap[-1] == '*': # all remaining arguments
 
933
        elif ap[-1] == '*':  # all remaining arguments
924
934
            if args:
925
935
                argdict[argname + '_list'] = args[:]
926
936
                args = []
929
939
        elif ap[-1] == '+':
930
940
            if not args:
931
941
                raise errors.BzrCommandError(gettext(
932
 
                      "command {0!r} needs one or more {1}").format(
933
 
                      cmd, argname.upper()))
 
942
                    "command {0!r} needs one or more {1}").format(
 
943
                    cmd, argname.upper()))
934
944
            else:
935
945
                argdict[argname + '_list'] = args[:]
936
946
                args = []
937
 
        elif ap[-1] == '$': # all but one
 
947
        elif ap[-1] == '$':  # all but one
938
948
            if len(args) < 2:
939
949
                raise errors.BzrCommandError(
940
 
                      gettext("command {0!r} needs one or more {1}").format(
941
 
                                             cmd, argname.upper()))
 
950
                    gettext("command {0!r} needs one or more {1}").format(
 
951
                        cmd, argname.upper()))
942
952
            argdict[argname + '_list'] = args[:-1]
943
953
            args[:-1] = []
944
954
        else:
946
956
            argname = ap
947
957
            if not args:
948
958
                raise errors.BzrCommandError(
949
 
                     gettext("command {0!r} requires argument {1}").format(
950
 
                               cmd, argname.upper()))
 
959
                    gettext("command {0!r} requires argument {1}").format(
 
960
                        cmd, argname.upper()))
951
961
            else:
952
962
                argdict[argname] = args.pop(0)
953
963
 
954
964
    if args:
955
 
        raise errors.BzrCommandError( gettext(
956
 
                              "extra argument to command {0}: {1}").format(
957
 
                                       cmd, args[0]) )
 
965
        raise errors.BzrCommandError(gettext(
 
966
            "extra argument to command {0}: {1}").format(
 
967
            cmd, args[0]))
958
968
 
959
969
    return argdict
960
970
 
980
990
        prof = hotshot.Profile(pfname)
981
991
        try:
982
992
            ret = prof.runcall(exception_to_return_code, the_callable, *args,
983
 
                **kwargs) or 0
 
993
                               **kwargs) or 0
984
994
        finally:
985
995
            prof.close()
986
996
        stats = hotshot.stats.load(pfname)
987
997
        stats.strip_dirs()
988
998
        stats.sort_stats('cum')   # 'time'
989
 
        ## XXX: Might like to write to stderr or the trace file instead but
990
 
        ## print_stats seems hardcoded to stdout
 
999
        # XXX: Might like to write to stderr or the trace file instead but
 
1000
        # print_stats seems hardcoded to stdout
991
1001
        stats.print_stats(20)
992
1002
        return ret
993
1003
    finally:
1004
1014
    """
1005
1015
    try:
1006
1016
        return the_callable(*args, **kwargs)
1007
 
    except (KeyboardInterrupt, Exception) as e:
 
1017
    except (KeyboardInterrupt, Exception):
1008
1018
        # used to handle AssertionError and KeyboardInterrupt
1009
1019
        # specially here, but hopefully they're handled ok by the logger now
1010
1020
        exc_info = sys.exc_info()
1087
1097
        Generate code coverage report
1088
1098
 
1089
1099
    --concurrency
1090
 
        Specify the number of processes that can be run concurrently (selftest).
 
1100
        Specify the number of processes that can be run concurrently
 
1101
        (selftest).
1091
1102
    """
1092
1103
    trace.mutter("breezy version: " + breezy.__version__)
1093
1104
    argv = _specified_or_unicode_argv(argv)
1094
1105
    trace.mutter("brz arguments: %r", argv)
1095
1106
 
1096
1107
    opt_lsprof = opt_profile = opt_no_plugins = opt_builtin = \
1097
 
            opt_coverage = opt_no_l10n = opt_no_aliases = False
 
1108
        opt_coverage = opt_no_l10n = opt_no_aliases = False
1098
1109
    opt_lsprof_file = None
1099
1110
 
1100
1111
    # --no-plugins is handled specially at a very early stage. We need
1128
1139
        elif a == '--coverage':
1129
1140
            opt_coverage = True
1130
1141
        elif a == '--profile-imports':
1131
 
            pass # already handled in startup script Bug #588277
 
1142
            pass  # already handled in startup script Bug #588277
1132
1143
        elif a.startswith('-D'):
1133
1144
            debug.debug_flags.add(a[2:])
1134
1145
        elif a.startswith('-O'):
1197
1208
        if 'memory' in debug.debug_flags:
1198
1209
            trace.debug_memory('Process status after command:', short=False)
1199
1210
        option._verbosity_level = saved_verbosity_level
1200
 
        # Reset the overrides 
 
1211
        # Reset the overrides
1201
1212
        cmdline_overrides._reset()
1202
1213
 
1203
1214
 
1226
1237
    if _list_bzr_commands in Command.hooks["list_commands"]:
1227
1238
        return
1228
1239
    Command.hooks.install_named_hook("list_commands", _list_bzr_commands,
1229
 
        "bzr commands")
 
1240
                                     "bzr commands")
1230
1241
    Command.hooks.install_named_hook("get_command", _get_bzr_command,
1231
 
        "bzr commands")
 
1242
                                     "bzr commands")
1232
1243
    Command.hooks.install_named_hook("get_command", _get_plugin_command,
1233
 
        "bzr plugin commands")
 
1244
                                     "bzr plugin commands")
1234
1245
    Command.hooks.install_named_hook("get_command", _get_external_command,
1235
 
        "bzr external command lookup")
 
1246
                                     "bzr external command lookup")
1236
1247
    Command.hooks.install_named_hook("get_missing_command",
1237
1248
                                     _try_plugin_provider,
1238
1249
                                     "bzr plugin-provider-db check")
1239
1250
 
1240
1251
 
1241
 
 
1242
1252
def _specified_or_unicode_argv(argv):
1243
1253
    # For internal or testing use, argv can be passed.  Otherwise, get it from
1244
1254
    # the process arguments in a unicode-safe way.
1283
1293
    """Run a bzr command with parameters as described by argv.
1284
1294
 
1285
1295
    This function assumed that that UI layer is setup, that symbol deprecations
1286
 
    are already applied, and that unicode decoding has already been performed on argv.
 
1296
    are already applied, and that unicode decoding has already been performed
 
1297
    on argv.
1287
1298
    """
1288
1299
    # done here so that they're covered for every test run
1289
1300
    install_bzr_command_hooks()
1302
1313
        return run_bzr(argv)
1303
1314
    except Exception as e:
1304
1315
        if (isinstance(e, (OSError, IOError))
1305
 
            or not getattr(e, 'internal_error', True)):
 
1316
                or not getattr(e, 'internal_error', True)):
1306
1317
            trace.report_exception(sys.exc_info(), sys.stderr)
1307
1318
            return 3
1308
1319
        else:
1351
1362
        for key, provider in self.items():
1352
1363
            yield provider
1353
1364
 
 
1365
 
1354
1366
command_providers_registry = ProvidersRegistry()