/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

  • Committer: Richard Wilbur
  • Date: 2016-02-04 19:07:28 UTC
  • mto: This revision was merged to the branch mainline in revision 6618.
  • Revision ID: richard.wilbur@gmail.com-20160204190728-p0zvfii6zase0fw7
Update COPYING.txt from the original http://www.gnu.org/licenses/gpl-2.0.txt  (Only differences were in whitespace.)  Thanks to Petr Stodulka for pointing out the discrepancy.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
import os
27
27
import sys
28
28
 
29
 
from .lazy_import import lazy_import
 
29
from bzrlib.lazy_import import lazy_import
30
30
lazy_import(globals(), """
31
31
import errno
32
32
import threading
33
33
 
34
 
import breezy
35
 
from breezy import (
 
34
import bzrlib
 
35
from bzrlib import (
36
36
    config,
37
37
    cleanup,
38
38
    cmdline,
39
39
    debug,
 
40
    errors,
40
41
    i18n,
41
42
    option,
42
43
    osutils,
45
46
    )
46
47
""")
47
48
 
48
 
from .hooks import Hooks
49
 
from .i18n import gettext
 
49
from bzrlib.hooks import Hooks
 
50
from bzrlib.i18n import gettext
50
51
# Compatibility - Option used to be in commands.
51
 
from .option import Option
52
 
from .plugin import disable_plugins, load_plugins, plugin_name
53
 
from . import errors, registry
54
 
from .sixish import (
55
 
    string_types,
56
 
    text_type,
57
 
    )
58
 
 
59
 
 
60
 
class BzrOptionError(errors.BzrCommandError):
61
 
 
62
 
    _fmt = "Error in command line options"
63
 
 
64
 
 
65
 
class CommandAvailableInPlugin(Exception):
66
 
 
67
 
    internal_error = False
68
 
 
69
 
    def __init__(self, cmd_name, plugin_metadata, provider):
70
 
 
71
 
        self.plugin_metadata = plugin_metadata
72
 
        self.cmd_name = cmd_name
73
 
        self.provider = provider
74
 
 
75
 
    def __str__(self):
76
 
 
77
 
        _fmt = ('"%s" is not a standard brz command. \n'
78
 
                'However, the following official plugin provides this command: %s\n'
79
 
                'You can install it by going to: %s'
80
 
                % (self.cmd_name, self.plugin_metadata['name'],
81
 
                    self.plugin_metadata['url']))
82
 
 
83
 
        return _fmt
 
52
from bzrlib.option import Option
 
53
from bzrlib.plugin import disable_plugins, load_plugins
 
54
from bzrlib import registry
84
55
 
85
56
 
86
57
class CommandInfo(object):
187
158
 
188
159
 
189
160
def _unsquish_command_name(cmd):
190
 
    return cmd[4:].replace('_', '-')
 
161
    return cmd[4:].replace('_','-')
191
162
 
192
163
 
193
164
def _register_builtin_commands():
194
165
    if builtin_command_registry.keys():
195
166
        # only load once
196
167
        return
197
 
    import breezy.builtins
198
 
    for cmd_class in _scan_module_for_commands(breezy.builtins):
 
168
    import bzrlib.builtins
 
169
    for cmd_class in _scan_module_for_commands(bzrlib.builtins).values():
199
170
        builtin_command_registry.register(cmd_class)
200
 
    breezy.builtins._register_lazy_builtins()
 
171
    bzrlib.builtins._register_lazy_builtins()
201
172
 
202
173
 
203
174
def _scan_module_for_commands(module):
204
 
    module_dict = module.__dict__
205
 
    for name in module_dict:
 
175
    r = {}
 
176
    for name, obj in module.__dict__.iteritems():
206
177
        if name.startswith("cmd_"):
207
 
            yield module_dict[name]
 
178
            real_name = _unsquish_command_name(name)
 
179
            r[real_name] = obj
 
180
    return r
208
181
 
209
182
 
210
183
def _list_bzr_commands(names):
244
217
    return plugin_cmds.keys()
245
218
 
246
219
 
247
 
# Overrides for common mispellings that heuristics get wrong
248
 
_GUESS_OVERRIDES = {
249
 
    'ic': {'ci': 0}, # heuristic finds nick
250
 
    }
251
 
 
252
 
 
253
 
def guess_command(cmd_name):
254
 
    """Guess what command a user typoed.
255
 
 
256
 
    :param cmd_name: Command to search for
257
 
    :return: None if no command was found, name of a command otherwise
258
 
    """
259
 
    names = set()
260
 
    for name in all_command_names():
261
 
        names.add(name)
262
 
        cmd = get_cmd_object(name)
263
 
        names.update(cmd.aliases)
264
 
    # candidate: modified levenshtein distance against cmd_name.
265
 
    costs = {}
266
 
    from . import patiencediff
267
 
    for name in sorted(names):
268
 
        matcher = patiencediff.PatienceSequenceMatcher(None, cmd_name, name)
269
 
        distance = 0.0
270
 
        opcodes = matcher.get_opcodes()
271
 
        for opcode, l1, l2, r1, r2 in opcodes:
272
 
            if opcode == 'delete':
273
 
                distance += l2-l1
274
 
            elif opcode == 'replace':
275
 
                distance += max(l2-l1, r2-l1)
276
 
            elif opcode == 'insert':
277
 
                distance += r2-r1
278
 
            elif opcode == 'equal':
279
 
                # Score equal ranges lower, making similar commands of equal
280
 
                # length closer than arbitrary same length commands.
281
 
                distance -= 0.1 * (l2-l1)
282
 
        costs[name] = distance
283
 
    costs.update(_GUESS_OVERRIDES.get(cmd_name, {}))
284
 
    costs = sorted((costs[key], key) for key in costs)
285
 
    if not costs:
286
 
        return
287
 
    if costs[0][0] > 4:
288
 
        return
289
 
    candidate = costs[0][1]
290
 
    return candidate
291
 
 
292
 
 
293
220
def get_cmd_object(cmd_name, plugins_override=True):
294
221
    """Return the command object for a command.
295
222
 
299
226
    try:
300
227
        return _get_cmd_object(cmd_name, plugins_override)
301
228
    except KeyError:
302
 
        # No command found, see if this was a typo
303
 
        candidate = guess_command(cmd_name)
304
 
        if candidate is not None:
305
 
            raise errors.BzrCommandError(
306
 
                    gettext('unknown command "%s". Perhaps you meant "%s"')
307
 
                    % (cmd_name, candidate))
308
 
        raise errors.BzrCommandError(gettext('unknown command "%s"')
309
 
                % cmd_name)
 
229
        raise errors.BzrCommandError(gettext('unknown command "%s"') % cmd_name)
310
230
 
311
231
 
312
232
def _get_cmd_object(cmd_name, plugins_override=True, check_missing=True):
347
267
    return cmd
348
268
 
349
269
 
350
 
class NoPluginAvailable(errors.BzrError):
351
 
    pass
352
 
 
353
 
 
354
270
def _try_plugin_provider(cmd_name):
355
271
    """Probe for a plugin provider having cmd_name."""
356
272
    try:
357
273
        plugin_metadata, provider = probe_for_provider(cmd_name)
358
 
        raise CommandAvailableInPlugin(cmd_name, plugin_metadata, provider)
359
 
    except NoPluginAvailable:
 
274
        raise errors.CommandAvailableInPlugin(cmd_name,
 
275
            plugin_metadata, provider)
 
276
    except errors.NoPluginAvailable:
360
277
        pass
361
278
 
362
279
 
371
288
    for provider in command_providers_registry:
372
289
        try:
373
290
            return provider.plugin_for_command(cmd_name), provider
374
 
        except NoPluginAvailable:
 
291
        except errors.NoPluginAvailable:
375
292
            pass
376
 
    raise NoPluginAvailable(cmd_name)
 
293
    raise errors.NoPluginAvailable(cmd_name)
377
294
 
378
295
 
379
296
def _get_bzr_command(cmd_or_None, cmd_name):
392
309
    # Only do external command lookups when no command is found so far.
393
310
    if cmd_or_None is not None:
394
311
        return cmd_or_None
395
 
    from breezy.externalcommand import ExternalCommand
 
312
    from bzrlib.externalcommand import ExternalCommand
396
313
    cmd_obj = ExternalCommand.find_command(cmd_name)
397
314
    if cmd_obj:
398
315
        return cmd_obj
399
316
 
400
317
 
401
318
def _get_plugin_command(cmd_or_None, cmd_name):
402
 
    """Get a command from brz's plugins."""
 
319
    """Get a command from bzr's plugins."""
403
320
    try:
404
321
        return plugin_cmds.get(cmd_name)()
405
322
    except KeyError:
414
331
class Command(object):
415
332
    """Base class for commands.
416
333
 
417
 
    Commands are the heart of the command-line brz interface.
 
334
    Commands are the heart of the command-line bzr interface.
418
335
 
419
336
    The command object mostly handles the mapping of command-line
420
 
    parameters into one or more breezy operations, and of the results
 
337
    parameters into one or more bzrlib operations, and of the results
421
338
    into textual output.
422
339
 
423
340
    Commands normally don't have any state.  All their arguments are
468
385
 
469
386
    :cvar hooks: An instance of CommandHooks.
470
387
 
471
 
    :cvar __doc__: The help shown by 'brz help command' for this command.
 
388
    :cvar __doc__: The help shown by 'bzr help command' for this command.
472
389
        This is set by assigning explicitly to __doc__ so that -OO can
473
390
        be used::
474
391
 
517
434
 
518
435
        Only describes arguments, not options.
519
436
        """
520
 
        s = 'brz ' + self.name() + ' '
 
437
        s = 'bzr ' + self.name() + ' '
521
438
        for aname in self.takes_args:
522
439
            aname = aname.upper()
523
440
            if aname[-1] in ['$', '+']:
552
469
            # Note: If self.gettext() translates ':Usage:\n', the section will
553
470
            # be shown after "Description" section and we don't want to
554
471
            # translate the usage string.
555
 
            # Though, brz export-pot don't exports :Usage: section and it must
 
472
            # Though, bzr export-pot don't exports :Usage: section and it must
556
473
            # not be translated.
557
474
            doc = self.gettext(doc)
558
475
        else:
559
476
            doc = gettext("No help for this command.")
560
477
 
561
478
        # Extract the summary (purpose) and sections out from the text
562
 
        purpose, sections, order = self._get_help_parts(doc)
 
479
        purpose,sections,order = self._get_help_parts(doc)
563
480
 
564
481
        # If a custom usage section was provided, use it
565
 
        if 'Usage' in sections:
 
482
        if sections.has_key('Usage'):
566
483
            usage = sections.pop('Usage')
567
484
        else:
568
485
            usage = self._usage()
600
517
        if verbose:
601
518
            # Add the description, indenting it 2 spaces
602
519
            # to match the indentation of the options
603
 
            if None in sections:
 
520
            if sections.has_key(None):
604
521
                text = sections.pop(None)
605
522
                text = '\n  '.join(text.splitlines())
606
523
                result += gettext(':Description:\n  %s\n\n') % (text,)
613
530
                        result += ':%s:\n%s\n' % (label, sections[label])
614
531
                result += '\n'
615
532
        else:
616
 
            result += (gettext("See brz help %s for more details and examples.\n\n")
 
533
            result += (gettext("See bzr help %s for more details and examples.\n\n")
617
534
                % self.name())
618
535
 
619
536
        # Add the aliases, source (plug-in) and see also links, if any
642
559
 
643
560
        # If this will be rendered as plain text, convert it
644
561
        if plain:
645
 
            import breezy.help_topics
646
 
            result = breezy.help_topics.help_as_plain_text(result)
 
562
            import bzrlib.help_topics
 
563
            result = bzrlib.help_topics.help_as_plain_text(result)
647
564
        return result
648
565
 
649
566
    @staticmethod
660
577
        """
661
578
        def save_section(sections, order, label, section):
662
579
            if len(section) > 0:
663
 
                if label in sections:
 
580
                if sections.has_key(label):
664
581
                    sections[label] += '\n' + section
665
582
                else:
666
583
                    order.append(label)
670
587
        summary = lines.pop(0)
671
588
        sections = {}
672
589
        order = []
673
 
        label, section = None, ''
 
590
        label,section = None,''
674
591
        for line in lines:
675
592
            if line.startswith(':') and line.endswith(':') and len(line) > 2:
676
593
                save_section(sections, order, label, section)
677
 
                label, section = line[1:-1], ''
 
594
                label,section = line[1:-1],''
678
595
            elif (label is not None) and len(line) > 1 and not line[0].isspace():
679
596
                save_section(sections, order, label, section)
680
 
                label, section = None, line
 
597
                label,section = None,line
681
598
            else:
682
599
                if len(section) > 0:
683
600
                    section += '\n' + line
708
625
 
709
626
        Maps from long option name to option object."""
710
627
        r = Option.STD_OPTIONS.copy()
711
 
        std_names = set(r)
 
628
        std_names = r.keys()
712
629
        for o in self.takes_options:
713
 
            if isinstance(o, string_types):
 
630
            if isinstance(o, basestring):
714
631
                o = option.Option.OPTIONS[o]
715
632
            r[o.name] = o
716
633
            if o.name in std_names:
728
645
        self._setup_outf()
729
646
 
730
647
        # Process the standard options
731
 
        if 'help' in opts:  # e.g. brz add --help
 
648
        if 'help' in opts:  # e.g. bzr add --help
732
649
            self.outf.write(self.get_help_text())
733
650
            return 0
734
 
        if 'usage' in opts:  # e.g. brz add --usage
 
651
        if 'usage' in opts:  # e.g. bzr add --usage
735
652
            self.outf.write(self.get_help_text(verbose=False))
736
653
            return 0
737
654
        trace.set_verbosity_level(option._verbosity_level)
738
655
        if 'verbose' in self.supported_std_options:
739
656
            opts['verbose'] = trace.is_verbose()
740
 
        elif 'verbose' in opts:
 
657
        elif opts.has_key('verbose'):
741
658
            del opts['verbose']
742
659
        if 'quiet' in self.supported_std_options:
743
660
            opts['quiet'] = trace.is_quiet()
744
 
        elif 'quiet' in opts:
 
661
        elif opts.has_key('quiet'):
745
662
            del opts['quiet']
746
663
        # mix arguments and options into one dictionary
747
664
        cmdargs = _match_argform(self.name(), self.takes_args, args)
835
752
 
836
753
        :return: The name of the plugin or None if the command is builtin.
837
754
        """
838
 
        return plugin_name(self.__module__)
 
755
        mod_parts = self.__module__.split('.')
 
756
        if len(mod_parts) >= 3 and mod_parts[1] == 'plugins':
 
757
            return mod_parts[2]
 
758
        else:
 
759
            return None
839
760
 
840
761
 
841
762
class CommandHooks(Hooks):
847
768
        These are all empty initially, because by default nothing should get
848
769
        notified.
849
770
        """
850
 
        Hooks.__init__(self, "breezy.commands", "Command.hooks")
 
771
        Hooks.__init__(self, "bzrlib.commands", "Command.hooks")
851
772
        self.add_hook('extend_command',
852
773
            "Called after creating a command object to allow modifications "
853
774
            "such as adding or removing options, docs etc. Called with the "
854
 
            "new breezy.commands.Command object.", (1, 13))
 
775
            "new bzrlib.commands.Command object.", (1, 13))
855
776
        self.add_hook('get_command',
856
777
            "Called when creating a single command. Called with "
857
778
            "(cmd_or_None, command_name). get_command should either return "
858
779
            "the cmd_or_None parameter, or a replacement Command object that "
859
780
            "should be used for the command. Note that the Command.hooks "
860
781
            "hooks are core infrastructure. Many users will prefer to use "
861
 
            "breezy.commands.register_command or plugin_cmds.register_lazy.",
 
782
            "bzrlib.commands.register_command or plugin_cmds.register_lazy.",
862
783
            (1, 17))
863
784
        self.add_hook('get_missing_command',
864
785
            "Called when creating a single command if no command could be "
900
821
    # option name is given.  See http://bugs.python.org/issue2931
901
822
    try:
902
823
        options, args = parser.parse_args(args)
903
 
    except UnicodeEncodeError as e:
 
824
    except UnicodeEncodeError,e:
904
825
        raise errors.BzrCommandError(
905
826
            gettext('Only ASCII permitted in option names'))
906
827
 
907
 
    opts = dict((k, v) for k, v in options.__dict__.items() if
908
 
                v is not option.OptionParser.DEFAULT_VALUE)
 
828
    opts = dict([(k, v) for k, v in options.__dict__.iteritems() if
 
829
                 v is not option.OptionParser.DEFAULT_VALUE])
909
830
    return args, opts
910
831
 
911
832
 
956
877
 
957
878
    return argdict
958
879
 
959
 
 
960
880
def apply_coveraged(dirname, the_callable, *args, **kwargs):
961
 
    import trace
 
881
    # Cannot use "import trace", as that would import bzrlib.trace instead of
 
882
    # the standard library's trace.
 
883
    trace = __import__('trace')
 
884
 
962
885
    tracer = trace.Trace(count=1, trace=0)
963
886
    sys.settrace(tracer.globaltrace)
964
887
    threading.settrace(tracer.globaltrace)
1005
928
    """
1006
929
    try:
1007
930
        return the_callable(*args, **kwargs)
1008
 
    except (KeyboardInterrupt, Exception) as e:
 
931
    except (KeyboardInterrupt, Exception), e:
1009
932
        # used to handle AssertionError and KeyboardInterrupt
1010
933
        # specially here, but hopefully they're handled ok by the logger now
1011
934
        exc_info = sys.exc_info()
1012
935
        exitcode = trace.report_exception(exc_info, sys.stderr)
1013
 
        if os.environ.get('BRZ_PDB'):
1014
 
            print('**** entering debugger')
 
936
        if os.environ.get('BZR_PDB'):
 
937
            print '**** entering debugger'
1015
938
            import pdb
1016
939
            pdb.post_mortem(exc_info[2])
1017
940
        return exitcode
1018
941
 
1019
942
 
1020
943
def apply_lsprofiled(filename, the_callable, *args, **kwargs):
1021
 
    from breezy.lsprof import profile
 
944
    from bzrlib.lsprof import profile
1022
945
    ret, stats = profile(exception_to_return_code, the_callable,
1023
946
                         *args, **kwargs)
1024
947
    stats.sort()
1041
964
        If it is unspecified, the global config will be used.
1042
965
    """
1043
966
    if config is None:
1044
 
        import breezy.config
1045
 
        config = breezy.config.GlobalConfig()
 
967
        import bzrlib.config
 
968
        config = bzrlib.config.GlobalConfig()
1046
969
    alias = config.get_alias(cmd)
1047
970
    if (alias):
1048
971
        return cmdline.split(alias)
1090
1013
    --concurrency
1091
1014
        Specify the number of processes that can be run concurrently (selftest).
1092
1015
    """
1093
 
    trace.mutter("breezy version: " + breezy.__version__)
 
1016
    trace.mutter("bazaar version: " + bzrlib.__version__)
1094
1017
    argv = _specified_or_unicode_argv(argv)
1095
 
    trace.mutter("brz arguments: %r", argv)
 
1018
    trace.mutter("bzr arguments: %r", argv)
1096
1019
 
1097
1020
    opt_lsprof = opt_profile = opt_no_plugins = opt_builtin = \
1098
1021
            opt_no_l10n = opt_no_aliases = False
1124
1047
        elif a == '--builtin':
1125
1048
            opt_builtin = True
1126
1049
        elif a == '--concurrency':
1127
 
            os.environ['BRZ_CONCURRENCY'] = argv[i + 1]
 
1050
            os.environ['BZR_CONCURRENCY'] = argv[i + 1]
1128
1051
            i += 1
1129
1052
        elif a == '--coverage':
1130
1053
            opt_coverage_dir = argv[i + 1]
1139
1062
            argv_copy.append(a)
1140
1063
        i += 1
1141
1064
 
1142
 
    cmdline_overrides = breezy.get_global_state().cmdline_overrides
 
1065
    if bzrlib.global_state is None:
 
1066
        # FIXME: Workaround for users that imported bzrlib but didn't call
 
1067
        # bzrlib.initialize -- vila 2012-01-19
 
1068
        cmdline_overrides = config.CommandLineStore()
 
1069
    else:
 
1070
        cmdline_overrides = bzrlib.global_state.cmdline_overrides
1143
1071
    cmdline_overrides._from_cmdline(override_config)
1144
1072
 
1145
1073
    debug.set_debug_flags_from_config()
1168
1096
    cmd = argv.pop(0)
1169
1097
    cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
1170
1098
    if opt_no_l10n:
1171
 
        cmd_obj.l10n = False
 
1099
        cmd.l10n = False
1172
1100
    run = cmd_obj.run_argv_aliases
1173
1101
    run_argv = [argv, alias_argv]
1174
1102
 
1210
1138
            result = func(*args, **kwargs)
1211
1139
            sys.stdout.flush()
1212
1140
            return result
1213
 
        except IOError as e:
 
1141
        except IOError, e:
1214
1142
            if getattr(e, 'errno', None) is None:
1215
1143
                raise
1216
1144
            if e.errno != errno.EPIPE:
1246
1174
    # the process arguments in a unicode-safe way.
1247
1175
    if argv is None:
1248
1176
        return osutils.get_unicode_argv()
1249
 
    new_argv = []
1250
 
    try:
1251
 
        # ensure all arguments are unicode strings
1252
 
        for a in argv:
1253
 
            if not isinstance(a, string_types):
1254
 
                raise ValueError('not native str or unicode: %r' % (a,))
1255
 
            if isinstance(a, bytes):
1256
 
                # For Python 2 only allow ascii native strings
1257
 
                a = a.decode('ascii')
1258
 
            new_argv.append(a)
1259
 
    except (ValueError, UnicodeDecodeError):
1260
 
        raise errors.BzrError("argv should be list of unicode strings.")
1261
 
    return new_argv
 
1177
    else:
 
1178
        new_argv = []
 
1179
        try:
 
1180
            # ensure all arguments are unicode strings
 
1181
            for a in argv:
 
1182
                if isinstance(a, unicode):
 
1183
                    new_argv.append(a)
 
1184
                else:
 
1185
                    new_argv.append(a.decode('ascii'))
 
1186
        except UnicodeDecodeError:
 
1187
            raise errors.BzrError("argv should be list of unicode strings.")
 
1188
        return new_argv
1262
1189
 
1263
1190
 
1264
1191
def main(argv=None):
1265
1192
    """Main entry point of command-line interface.
1266
1193
 
1267
 
    Typically `breezy.initialize` should be called first.
 
1194
    Typically `bzrlib.initialize` should be called first.
1268
1195
 
1269
1196
    :param argv: list of unicode command-line arguments similar to sys.argv.
1270
1197
        argv[0] is script name usually, it will be ignored.
1271
1198
        Don't pass here sys.argv because this list contains plain strings
1272
1199
        and not unicode; pass None instead.
1273
1200
 
1274
 
    :return: exit code of brz command.
 
1201
    :return: exit code of bzr command.
1275
1202
    """
1276
1203
    if argv is not None:
1277
1204
        argv = argv[1:]
1293
1220
 
1294
1221
 
1295
1222
def run_bzr_catch_user_errors(argv):
1296
 
    """Run brz and report user errors, but let internal errors propagate.
 
1223
    """Run bzr and report user errors, but let internal errors propagate.
1297
1224
 
1298
1225
    This is used for the test suite, and might be useful for other programs
1299
1226
    that want to wrap the commandline interface.
1302
1229
    install_bzr_command_hooks()
1303
1230
    try:
1304
1231
        return run_bzr(argv)
1305
 
    except Exception as e:
 
1232
    except Exception, e:
1306
1233
        if (isinstance(e, (OSError, IOError))
1307
1234
            or not getattr(e, 'internal_error', True)):
1308
1235
            trace.report_exception(sys.exc_info(), sys.stderr)
1350
1277
    """This registry exists to allow other providers to exist"""
1351
1278
 
1352
1279
    def __iter__(self):
1353
 
        for key, provider in self.items():
 
1280
        for key, provider in self.iteritems():
1354
1281
            yield provider
1355
1282
 
1356
1283
command_providers_registry = ProvidersRegistry()