~bzr-pqm/bzr/bzr.dev

329 by Martin Pool
- refactor command functions into command classes
1
# Copyright (C) 2004, 2005 by Canonical Ltd
1 by mbp at sourcefrog
import from baz patch-364
2
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
18
# TODO: probably should say which arguments are candidates for glob
19
# expansion on windows and do that at the command level.
20
1095 by Martin Pool
todo
21
# TODO: Help messages for options.
22
23
# TODO: Define arguments by objects, rather than just using names.
24
# Those objects can specify the expected type of the argument, which
25
# would help with validation and shell completion.
26
1393.1.27 by Martin Pool
- clean up profile code and change default sort order
27
# TODO: "--profile=cum", to change sort order.  Is there any value in leaving
28
# the profile output behind so it can be interactively examined?
29
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
30
import sys
31
import os
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
32
from warnings import warn
33
from inspect import getdoc
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
34
import errno
1 by mbp at sourcefrog
import from baz patch-364
35
36
import bzrlib
1112 by Martin Pool
- disable standard logging to .bzr.log and stderr while running
37
import bzrlib.trace
1185.33.42 by Martin Pool
[patch] make --quiet a global option (robey)
38
from bzrlib.trace import mutter, note, log_error, warning, be_quiet
1495 by Robert Collins
Add a --create-prefix to the new push command.
39
from bzrlib.errors import (BzrError, 
40
                           BzrCheckError,
41
                           BzrCommandError,
42
                           BzrOptionError,
1534.7.154 by Aaron Bentley
Removed changes from bzr.ab 1529..1536
43
                           NotBranchError)
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
44
from bzrlib.revisionspec import RevisionSpec
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
45
from bzrlib.option import Option
1 by mbp at sourcefrog
import from baz patch-364
46
731 by Martin Pool
- merge plugin patch from john
47
plugin_cmds = {}
48
49
1492 by Robert Collins
Support decoration of commands.
50
def register_command(cmd, decorate=False):
731 by Martin Pool
- merge plugin patch from john
51
    "Utility function to help register a command"
52
    global plugin_cmds
53
    k = cmd.__name__
54
    if k.startswith("cmd_"):
55
        k_unsquished = _unsquish_command_name(k)
56
    else:
57
        k_unsquished = k
58
    if not plugin_cmds.has_key(k_unsquished):
59
        plugin_cmds[k_unsquished] = cmd
1137 by Martin Pool
- additional trace messages for plugins
60
        mutter('registered plugin command %s', k_unsquished)      
1492 by Robert Collins
Support decoration of commands.
61
        if decorate and k_unsquished in builtin_command_names():
62
            return _builtin_commands()[k_unsquished]
63
    elif decorate:
64
        result = plugin_cmds[k_unsquished]
65
        plugin_cmds[k_unsquished] = cmd
66
        return result
731 by Martin Pool
- merge plugin patch from john
67
    else:
68
        log_error('Two plugins defined the same command: %r' % k)
69
        log_error('Not loading the one in %r' % sys.modules[cmd.__module__])
70
71
350 by Martin Pool
- refactor command aliases into command classes
72
def _squish_command_name(cmd):
73
    return 'cmd_' + cmd.replace('-', '_')
74
75
76
def _unsquish_command_name(cmd):
77
    assert cmd.startswith("cmd_")
78
    return cmd[4:].replace('_','-')
79
914 by Martin Pool
- fix up breakage of 'bzr log -v' by root_id patch
80
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
81
def _builtin_commands():
1147 by Martin Pool
- split builtin commands into separate module bzrlib.builtins;
82
    import bzrlib.builtins
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
83
    r = {}
1147 by Martin Pool
- split builtin commands into separate module bzrlib.builtins;
84
    builtins = bzrlib.builtins.__dict__
85
    for name in builtins:
86
        if name.startswith("cmd_"):
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
87
            real_name = _unsquish_command_name(name)        
88
            r[real_name] = builtins[name]
89
    return r
90
91
            
92
93
def builtin_command_names():
94
    """Return list of builtin command names."""
95
    return _builtin_commands().keys()
96
    
97
98
def plugin_command_names():
99
    return plugin_cmds.keys()
100
101
102
def _get_cmd_dict(plugins_override=True):
103
    """Return name->class mapping for all commands."""
104
    d = _builtin_commands()
731 by Martin Pool
- merge plugin patch from john
105
    if plugins_override:
106
        d.update(plugin_cmds)
641 by Martin Pool
- improved external-command patch from john
107
    return d
731 by Martin Pool
- merge plugin patch from john
108
641 by Martin Pool
- improved external-command patch from john
109
    
731 by Martin Pool
- merge plugin patch from john
110
def get_all_cmds(plugins_override=True):
641 by Martin Pool
- improved external-command patch from john
111
    """Return canonical name and class for all registered commands."""
731 by Martin Pool
- merge plugin patch from john
112
    for k, v in _get_cmd_dict(plugins_override=plugins_override).iteritems():
641 by Martin Pool
- improved external-command patch from john
113
        yield k,v
114
115
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
116
def get_cmd_object(cmd_name, plugins_override=True):
350 by Martin Pool
- refactor command aliases into command classes
117
    """Return the canonical name and command class for a command.
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
118
119
    plugins_override
120
        If true, plugin commands can override builtins.
350 by Martin Pool
- refactor command aliases into command classes
121
    """
1163 by Martin Pool
- split ExternalCommand class into its own file
122
    from bzrlib.externalcommand import ExternalCommand
123
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
124
    cmd_name = str(cmd_name)            # not unicode
350 by Martin Pool
- refactor command aliases into command classes
125
126
    # first look up this command under the specified name
731 by Martin Pool
- merge plugin patch from john
127
    cmds = _get_cmd_dict(plugins_override=plugins_override)
272 by Martin Pool
- Add command aliases
128
    try:
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
129
        return cmds[cmd_name]()
272 by Martin Pool
- Add command aliases
130
    except KeyError:
350 by Martin Pool
- refactor command aliases into command classes
131
        pass
132
133
    # look for any command which claims this as an alias
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
134
    for real_cmd_name, cmd_class in cmds.iteritems():
135
        if cmd_name in cmd_class.aliases:
136
            return cmd_class()
137
138
    cmd_obj = ExternalCommand.find_command(cmd_name)
139
    if cmd_obj:
140
        return cmd_obj
141
142
    raise BzrCommandError("unknown command %r" % cmd_name)
272 by Martin Pool
- Add command aliases
143
329 by Martin Pool
- refactor command functions into command classes
144
558 by Martin Pool
- All top-level classes inherit from object
145
class Command(object):
329 by Martin Pool
- refactor command functions into command classes
146
    """Base class for commands.
147
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
148
    Commands are the heart of the command-line bzr interface.
149
150
    The command object mostly handles the mapping of command-line
151
    parameters into one or more bzrlib operations, and of the results
152
    into textual output.
153
154
    Commands normally don't have any state.  All their arguments are
155
    passed in to the run method.  (Subclasses may take a different
156
    policy if the behaviour of the instance needs to depend on e.g. a
157
    shell plugin and not just its Python class.)
158
329 by Martin Pool
- refactor command functions into command classes
159
    The docstring for an actual command should give a single-line
160
    summary, then a complete description of the command.  A grammar
161
    description will be inserted.
162
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
163
    aliases
164
        Other accepted names for this command.
165
329 by Martin Pool
- refactor command functions into command classes
166
    takes_args
167
        List of argument forms, marked with whether they are optional,
168
        repeated, etc.
169
1534.4.25 by Robert Collins
Add a --transport parameter to the test suite to set the default transport to be used in the test suite.
170
                Examples:
171
172
                ['to_location', 'from_branch?', 'file*']
173
174
                'to_location' is required
175
                'from_branch' is optional
176
                'file' can be specified 0 or more times
1185.37.4 by Jamie Wilkinson
add some examples to the documentation for Command.takes_args
177
329 by Martin Pool
- refactor command functions into command classes
178
    takes_options
1185.16.43 by Martin Pool
- clean up handling of option objects
179
        List of options that may be given for this command.  These can
180
        be either strings, referring to globally-defined options,
181
        or option objects.  Retrieve through options().
329 by Martin Pool
- refactor command functions into command classes
182
183
    hidden
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
184
        If true, this command isn't advertised.  This is typically
185
        for commands intended for expert users.
329 by Martin Pool
- refactor command functions into command classes
186
    """
187
    aliases = []
188
    takes_args = []
189
    takes_options = []
190
191
    hidden = False
192
    
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
193
    def __init__(self):
194
        """Construct an instance of this command."""
973 by Martin Pool
- various refactorings of command interpreter
195
        if self.__doc__ == Command.__doc__:
196
            warn("No help message set for %r" % self)
329 by Martin Pool
- refactor command functions into command classes
197
1185.16.43 by Martin Pool
- clean up handling of option objects
198
    def options(self):
199
        """Return dict of valid options for this command.
200
201
        Maps from long option name to option object."""
202
        r = dict()
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
203
        r['help'] = Option.OPTIONS['help']
1185.16.43 by Martin Pool
- clean up handling of option objects
204
        for o in self.takes_options:
205
            if not isinstance(o, Option):
206
                o = Option.OPTIONS[o]
207
            r[o.name] = o
208
        return r
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
209
1553.6.8 by Erik Bågfors
support for overrides
210
    def run_argv(self, argv, alias_argv=None):
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
211
        """Parse command line and run."""
1553.6.8 by Erik Bågfors
support for overrides
212
        args, opts = parse_args(self, argv, alias_argv)
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
213
        if 'help' in opts:  # e.g. bzr add --help
214
            from bzrlib.help import help_on_command
215
            help_on_command(self.name())
216
            return 0
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
217
        # XXX: This should be handled by the parser
1185.16.43 by Martin Pool
- clean up handling of option objects
218
        allowed_names = self.options().keys()
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
219
        for oname in opts:
1185.16.43 by Martin Pool
- clean up handling of option objects
220
            if oname not in allowed_names:
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
221
                raise BzrCommandError("option '--%s' is not allowed for command %r"
222
                                      % (oname, self.name()))
223
        # mix arguments and options into one dictionary
224
        cmdargs = _match_argform(self.name(), self.takes_args, args)
225
        cmdopts = {}
226
        for k, v in opts.items():
227
            cmdopts[k.replace('-', '_')] = v
228
229
        all_cmd_args = cmdargs.copy()
230
        all_cmd_args.update(cmdopts)
231
232
        return self.run(**all_cmd_args)
329 by Martin Pool
- refactor command functions into command classes
233
    
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
234
    def run(self):
235
        """Actually run the command.
329 by Martin Pool
- refactor command functions into command classes
236
237
        This is invoked with the options and arguments bound to
238
        keyword parameters.
239
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
240
        Return 0 or None if the command was successful, or a non-zero
241
        shell error code if not.  It's OK for this method to allow
242
        an exception to raise up.
329 by Martin Pool
- refactor command functions into command classes
243
        """
1147 by Martin Pool
- split builtin commands into separate module bzrlib.builtins;
244
        raise NotImplementedError()
329 by Martin Pool
- refactor command functions into command classes
245
246
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
247
    def help(self):
248
        """Return help message for this class."""
249
        if self.__doc__ is Command.__doc__:
250
            return None
251
        return getdoc(self)
252
253
    def name(self):
254
        return _unsquish_command_name(self.__class__.__name__)
255
256
493 by Martin Pool
- Merge aaron's merge command
257
def parse_spec(spec):
622 by Martin Pool
Updated merge patch from Aaron
258
    """
259
    >>> parse_spec(None)
260
    [None, None]
261
    >>> parse_spec("./")
262
    ['./', None]
263
    >>> parse_spec("../@")
264
    ['..', -1]
265
    >>> parse_spec("../f/@35")
266
    ['../f', 35]
897 by Martin Pool
- merge john's revision-naming code
267
    >>> parse_spec('./@revid:john@arbash-meinel.com-20050711044610-3ca0327c6a222f67')
268
    ['.', 'revid:john@arbash-meinel.com-20050711044610-3ca0327c6a222f67']
622 by Martin Pool
Updated merge patch from Aaron
269
    """
270
    if spec is None:
271
        return [None, None]
493 by Martin Pool
- Merge aaron's merge command
272
    if '/@' in spec:
273
        parsed = spec.split('/@')
274
        assert len(parsed) == 2
275
        if parsed[1] == "":
276
            parsed[1] = -1
277
        else:
897 by Martin Pool
- merge john's revision-naming code
278
            try:
279
                parsed[1] = int(parsed[1])
280
            except ValueError:
281
                pass # We can allow stuff like ./@revid:blahblahblah
282
            else:
283
                assert parsed[1] >=0
493 by Martin Pool
- Merge aaron's merge command
284
    else:
285
        parsed = [spec, None]
286
    return parsed
287
1553.6.11 by Erik Bågfors
small bugfixes, all tests pass now
288
def parse_args(command, argv, alias_argv=None):
1 by mbp at sourcefrog
import from baz patch-364
289
    """Parse command line.
290
    
291
    Arguments and options are parsed at this level before being passed
292
    down to specific command handlers.  This routine knows, from a
293
    lookup table, something about the available options, what optargs
294
    they take, and which commands will accept them.
295
    """
1185.16.49 by mbp at sourcefrog
- more refactoring and tests of commandline
296
    # TODO: chop up this beast; make it a method of the Command
1 by mbp at sourcefrog
import from baz patch-364
297
    args = []
298
    opts = {}
1553.6.8 by Erik Bågfors
support for overrides
299
    alias_opts = {}
1 by mbp at sourcefrog
import from baz patch-364
300
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
301
    cmd_options = command.options()
1144 by Martin Pool
- accept -- to terminate options
302
    argsover = False
1553.6.8 by Erik Bågfors
support for overrides
303
    proc_aliasarg = True # Are we processing alias_argv now?
304
    for proc_argv in alias_argv, argv:
305
        while proc_argv:
306
            a = proc_argv.pop(0)
307
            if argsover:
308
                args.append(a)
309
                continue
310
            elif a == '--':
311
                # We've received a standalone -- No more flags
312
                argsover = True
313
                continue
314
            if a[0] == '-':
315
                # option names must not be unicode
316
                a = str(a)
317
                optarg = None
318
                if a[1] == '-':
319
                    mutter("  got option %r", a)
320
                    if '=' in a:
321
                        optname, optarg = a[2:].split('=', 1)
322
                    else:
323
                        optname = a[2:]
324
                    if optname not in cmd_options:
325
                        raise BzrOptionError('unknown long option %r for command %s'
326
                            % (a, command.name()))
327
                else:
328
                    shortopt = a[1:]
329
                    if shortopt in Option.SHORT_OPTIONS:
330
                        # Multi-character options must have a space to delimit
331
                        # their value
332
                        # ^^^ what does this mean? mbp 20051014
333
                        optname = Option.SHORT_OPTIONS[shortopt].name
334
                    else:
335
                        # Single character short options, can be chained,
336
                        # and have their value appended to their name
337
                        shortopt = a[1:2]
338
                        if shortopt not in Option.SHORT_OPTIONS:
339
                            # We didn't find the multi-character name, and we
340
                            # didn't find the single char name
341
                            raise BzrError('unknown short option %r' % a)
342
                        optname = Option.SHORT_OPTIONS[shortopt].name
683 by Martin Pool
- short option stacking patch from John A Meinel
343
1553.6.8 by Erik Bågfors
support for overrides
344
                        if a[2:]:
345
                            # There are extra things on this option
346
                            # see if it is the value, or if it is another
347
                            # short option
348
                            optargfn = Option.OPTIONS[optname].type
349
                            if optargfn is None:
350
                                # This option does not take an argument, so the
351
                                # next entry is another short option, pack it back
352
                                # into the list
353
                                proc_argv.insert(0, '-' + a[2:])
354
                            else:
355
                                # This option takes an argument, so pack it
356
                                # into the array
357
                                optarg = a[2:]
358
                
359
                    if optname not in cmd_options:
360
                        raise BzrOptionError('unknown short option %r for command'
361
                            ' %s' % (shortopt, command.name()))
362
                if optname in opts:
363
                    # XXX: Do we ever want to support this, e.g. for -r?
364
                    if proc_aliasarg:
365
                        raise BzrError('repeated option %r' % a)
366
                    elif optname in alias_opts:
367
                        # Replace what's in the alias with what's in the real argument
368
                        del alias_opts[optname]
369
                        del opts[optname]
370
                        proc_argv.insert(0, a)
371
                        continue
372
                    else:
373
                        raise BzrError('repeated option %r' % a)
374
                    
375
                option_obj = cmd_options[optname]
376
                optargfn = option_obj.type
377
                if optargfn:
378
                    if optarg == None:
379
                        if not proc_argv:
380
                            raise BzrError('option %r needs an argument' % a)
683 by Martin Pool
- short option stacking patch from John A Meinel
381
                        else:
1553.6.8 by Erik Bågfors
support for overrides
382
                            optarg = proc_argv.pop(0)
383
                    opts[optname] = optargfn(optarg)
384
                    if proc_aliasarg:
385
                        alias_opts[optname] = optargfn(optarg)
386
                else:
387
                    if optarg != None:
388
                        raise BzrError('option %r takes no argument' % optname)
389
                    opts[optname] = True
390
                    if proc_aliasarg:
391
                        alias_opts[optname] = True
1 by mbp at sourcefrog
import from baz patch-364
392
            else:
1553.6.8 by Erik Bågfors
support for overrides
393
                args.append(a)
394
        proc_aliasarg = False # Done with alias argv
1 by mbp at sourcefrog
import from baz patch-364
395
    return args, opts
396
397
329 by Martin Pool
- refactor command functions into command classes
398
def _match_argform(cmd, takes_args, args):
1 by mbp at sourcefrog
import from baz patch-364
399
    argdict = {}
26 by mbp at sourcefrog
fix StopIteration error on python2.3(?)
400
329 by Martin Pool
- refactor command functions into command classes
401
    # step through args and takes_args, allowing appropriate 0-many matches
402
    for ap in takes_args:
1 by mbp at sourcefrog
import from baz patch-364
403
        argname = ap[:-1]
404
        if ap[-1] == '?':
62 by mbp at sourcefrog
- new find_branch_root function; based on suggestion from aaron
405
            if args:
406
                argdict[argname] = args.pop(0)
196 by mbp at sourcefrog
selected-file diff
407
        elif ap[-1] == '*': # all remaining arguments
408
            if args:
409
                argdict[argname + '_list'] = args[:]
410
                args = []
411
            else:
412
                argdict[argname + '_list'] = None
1 by mbp at sourcefrog
import from baz patch-364
413
        elif ap[-1] == '+':
414
            if not args:
329 by Martin Pool
- refactor command functions into command classes
415
                raise BzrCommandError("command %r needs one or more %s"
1 by mbp at sourcefrog
import from baz patch-364
416
                        % (cmd, argname.upper()))
417
            else:
418
                argdict[argname + '_list'] = args[:]
419
                args = []
160 by mbp at sourcefrog
- basic support for moving files to different directories - have not done support for renaming them yet, but should be straightforward - some tests, but many cases are not handled yet i think
420
        elif ap[-1] == '$': # all but one
421
            if len(args) < 2:
329 by Martin Pool
- refactor command functions into command classes
422
                raise BzrCommandError("command %r needs one or more %s"
160 by mbp at sourcefrog
- basic support for moving files to different directories - have not done support for renaming them yet, but should be straightforward - some tests, but many cases are not handled yet i think
423
                        % (cmd, argname.upper()))
424
            argdict[argname + '_list'] = args[:-1]
425
            args[:-1] = []                
1 by mbp at sourcefrog
import from baz patch-364
426
        else:
427
            # just a plain arg
428
            argname = ap
429
            if not args:
329 by Martin Pool
- refactor command functions into command classes
430
                raise BzrCommandError("command %r requires argument %s"
1 by mbp at sourcefrog
import from baz patch-364
431
                        % (cmd, argname.upper()))
432
            else:
433
                argdict[argname] = args.pop(0)
434
            
435
    if args:
329 by Martin Pool
- refactor command functions into command classes
436
        raise BzrCommandError("extra argument to command %s: %s"
437
                              % (cmd, args[0]))
1 by mbp at sourcefrog
import from baz patch-364
438
439
    return argdict
440
441
442
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
443
def apply_profiled(the_callable, *args, **kwargs):
444
    import hotshot
445
    import tempfile
1393.1.27 by Martin Pool
- clean up profile code and change default sort order
446
    import hotshot.stats
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
447
    pffileno, pfname = tempfile.mkstemp()
448
    try:
449
        prof = hotshot.Profile(pfname)
450
        try:
451
            ret = prof.runcall(the_callable, *args, **kwargs) or 0
452
        finally:
453
            prof.close()
454
        stats = hotshot.stats.load(pfname)
1393.1.27 by Martin Pool
- clean up profile code and change default sort order
455
        stats.strip_dirs()
456
        stats.sort_stats('cum')   # 'time'
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
457
        ## XXX: Might like to write to stderr or the trace file instead but
458
        ## print_stats seems hardcoded to stdout
459
        stats.print_stats(20)
460
        return ret
461
    finally:
462
        os.close(pffileno)
463
        os.remove(pfname)
464
465
1540.2.7 by Robey Pointer
add --lsprof-file option to specify a file for writing lsprof data to (instead of dumping a pretty-print to the terminal)
466
def apply_lsprofiled(filename, the_callable, *args, **kwargs):
1185.33.85 by Martin Pool
New --lsprof option from Denys Duchier
467
    from bzrlib.lsprof import profile
1540.2.7 by Robey Pointer
add --lsprof-file option to specify a file for writing lsprof data to (instead of dumping a pretty-print to the terminal)
468
    import cPickle
469
    ret, stats = profile(the_callable, *args, **kwargs)
1185.33.85 by Martin Pool
New --lsprof option from Denys Duchier
470
    stats.sort()
1540.2.7 by Robey Pointer
add --lsprof-file option to specify a file for writing lsprof data to (instead of dumping a pretty-print to the terminal)
471
    if filename is None:
472
        stats.pprint()
473
    else:
474
        stats.freeze()
475
        cPickle.dump(stats, open(filename, 'w'), 2)
476
        print 'Profile data written to %r.' % filename
1185.33.85 by Martin Pool
New --lsprof option from Denys Duchier
477
    return ret
478
1553.6.9 by Erik Bågfors
PEP8-ify
479
1553.6.1 by Erik Bågfors
support for aliases in bazaar.conf
480
def get_alias(cmd):
481
    """if an alias for cmd exists, returns the expanded command
1553.6.8 by Erik Bågfors
support for overrides
482
       else returns None"""
1553.6.1 by Erik Bågfors
support for aliases in bazaar.conf
483
    import bzrlib.config
1553.6.12 by Erik Bågfors
remove AliasConfig, based on input from abentley
484
    alias = bzrlib.config.GlobalConfig().get_alias(cmd)
1553.6.1 by Erik Bågfors
support for aliases in bazaar.conf
485
    if (alias):
486
        return alias.split(' ')
1553.6.8 by Erik Bågfors
support for overrides
487
    return None
1553.6.1 by Erik Bågfors
support for aliases in bazaar.conf
488
1553.6.9 by Erik Bågfors
PEP8-ify
489
1 by mbp at sourcefrog
import from baz patch-364
490
def run_bzr(argv):
491
    """Execute a command.
492
493
    This is similar to main(), but without all the trappings for
245 by mbp at sourcefrog
- control files always in utf-8-unix format
494
    logging and error handling.  
973 by Martin Pool
- various refactorings of command interpreter
495
    
496
    argv
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
497
       The command-line arguments, without the program name from argv[0]
973 by Martin Pool
- various refactorings of command interpreter
498
    
499
    Returns a command status or raises an exception.
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
500
501
    Special master options: these must come before the command because
502
    they control how the command is interpreted.
503
504
    --no-plugins
505
        Do not load plugin modules at all
506
1553.6.1 by Erik Bågfors
support for aliases in bazaar.conf
507
    --no-aliases
508
        Do not allow aliases
509
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
510
    --builtin
511
        Only use builtin commands.  (Plugins are still allowed to change
512
        other behaviour.)
513
514
    --profile
1185.33.85 by Martin Pool
New --lsprof option from Denys Duchier
515
        Run under the Python hotshot profiler.
516
517
    --lsprof
518
        Run under the Python lsprof profiler.
1 by mbp at sourcefrog
import from baz patch-364
519
    """
251 by mbp at sourcefrog
- factor out locale.getpreferredencoding()
520
    argv = [a.decode(bzrlib.user_encoding) for a in argv]
907.1.21 by John Arbash Meinel
Adding http transport as a valid transport protocol.
521
1553.6.1 by Erik Bågfors
support for aliases in bazaar.conf
522
    opt_lsprof = opt_profile = opt_no_plugins = opt_builtin =  \
523
                opt_no_aliases = False
1540.2.7 by Robey Pointer
add --lsprof-file option to specify a file for writing lsprof data to (instead of dumping a pretty-print to the terminal)
524
    opt_lsprof_file = None
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
525
526
    # --no-plugins is handled specially at a very early stage. We need
527
    # to load plugins before doing other command parsing so that they
528
    # can override commands, but this needs to happen first.
529
1540.2.7 by Robey Pointer
add --lsprof-file option to specify a file for writing lsprof data to (instead of dumping a pretty-print to the terminal)
530
    argv_copy = []
531
    i = 0
532
    while i < len(argv):
533
        a = argv[i]
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
534
        if a == '--profile':
535
            opt_profile = True
1185.33.85 by Martin Pool
New --lsprof option from Denys Duchier
536
        elif a == '--lsprof':
537
            opt_lsprof = True
1540.2.7 by Robey Pointer
add --lsprof-file option to specify a file for writing lsprof data to (instead of dumping a pretty-print to the terminal)
538
        elif a == '--lsprof-file':
539
            opt_lsprof_file = argv[i + 1]
540
            i += 1
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
541
        elif a == '--no-plugins':
542
            opt_no_plugins = True
1553.6.1 by Erik Bågfors
support for aliases in bazaar.conf
543
        elif a == '--no-aliases':
544
            opt_no_aliases = True
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
545
        elif a == '--builtin':
546
            opt_builtin = True
1185.33.42 by Martin Pool
[patch] make --quiet a global option (robey)
547
        elif a in ('--quiet', '-q'):
548
            be_quiet()
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
549
        else:
1540.2.7 by Robey Pointer
add --lsprof-file option to specify a file for writing lsprof data to (instead of dumping a pretty-print to the terminal)
550
            argv_copy.append(a)
551
        i += 1
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
552
1540.2.7 by Robey Pointer
add --lsprof-file option to specify a file for writing lsprof data to (instead of dumping a pretty-print to the terminal)
553
    argv = argv_copy
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
554
    if (not argv) or (argv[0] == '--help'):
555
        from bzrlib.help import help
556
        if len(argv) > 1:
557
            help(argv[1])
558
        else:
559
            help()
560
        return 0
561
562
    if argv[0] == '--version':
563
        from bzrlib.builtins import show_version
564
        show_version()
565
        return 0
566
        
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
567
    if not opt_no_plugins:
973 by Martin Pool
- various refactorings of command interpreter
568
        from bzrlib.plugin import load_plugins
569
        load_plugins()
1551.3.11 by Aaron Bentley
Merge from Robert
570
    else:
571
        from bzrlib.plugin import disable_plugins
572
        disable_plugins()
973 by Martin Pool
- various refactorings of command interpreter
573
1553.6.1 by Erik Bågfors
support for aliases in bazaar.conf
574
    if not opt_no_aliases:
1553.6.8 by Erik Bågfors
support for overrides
575
        alias_argv = get_alias(argv[0])
576
        if alias_argv:
577
            alias_argv = [a.decode(bzrlib.user_encoding) for a in alias_argv]
578
            argv[0] = alias_argv.pop(0)
1553.6.1 by Erik Bågfors
support for aliases in bazaar.conf
579
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
580
    cmd = str(argv.pop(0))
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
581
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
582
    cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
1534.7.154 by Aaron Bentley
Removed changes from bzr.ab 1529..1536
583
1185.33.42 by Martin Pool
[patch] make --quiet a global option (robey)
584
    try:
1185.33.85 by Martin Pool
New --lsprof option from Denys Duchier
585
        if opt_lsprof:
1553.6.8 by Erik Bågfors
support for overrides
586
            ret = apply_lsprofiled(opt_lsprof_file, cmd_obj.run_argv, argv, alias_argv)
1185.33.85 by Martin Pool
New --lsprof option from Denys Duchier
587
        elif opt_profile:
1553.6.8 by Erik Bågfors
support for overrides
588
            ret = apply_profiled(cmd_obj.run_argv, argv, alias_argv)
1185.33.42 by Martin Pool
[patch] make --quiet a global option (robey)
589
        else:
1553.6.8 by Erik Bågfors
support for overrides
590
            ret = cmd_obj.run_argv(argv, alias_argv)
1185.33.42 by Martin Pool
[patch] make --quiet a global option (robey)
591
        return ret or 0
592
    finally:
593
        # reset, in case we may do other commands later within the same process
594
        be_quiet(False)
267 by Martin Pool
- better reporting of errors
595
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
596
def display_command(func):
1185.33.18 by Martin Pool
[patch] handle bad IOError subclass raised by urlopen
597
    """Decorator that suppresses pipe/interrupt errors."""
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
598
    def ignore_pipe(*args, **kwargs):
599
        try:
1185.35.22 by Aaron Bentley
Handled more pipe errors for display commands.
600
            result = func(*args, **kwargs)
601
            sys.stdout.flush()
602
            return result
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
603
        except IOError, e:
1185.33.18 by Martin Pool
[patch] handle bad IOError subclass raised by urlopen
604
            if not hasattr(e, 'errno'):
605
                raise
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
606
            if e.errno != errno.EPIPE:
607
                raise
1185.33.18 by Martin Pool
[patch] handle bad IOError subclass raised by urlopen
608
            pass
1185.12.69 by Aaron Bentley
Ignored ^C in display commands
609
        except KeyboardInterrupt:
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
610
            pass
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
611
    return ignore_pipe
267 by Martin Pool
- better reporting of errors
612
1185.43.6 by Martin Pool
Enable logging early enough to save argv
613
1 by mbp at sourcefrog
import from baz patch-364
614
def main(argv):
1104 by Martin Pool
- Add a simple UIFactory
615
    import bzrlib.ui
1185.49.21 by John Arbash Meinel
Refactored bzrlib/ui.py into a module with the possibility for multiple ui forms.
616
    from bzrlib.ui.text import TextUIFactory
1185.43.8 by Martin Pool
Don't enable default logging twice
617
    ## bzrlib.trace.enable_default_logging()
1111 by Martin Pool
- add functions to enable and disable default logging, so that we can
618
    bzrlib.trace.log_startup(argv)
1185.49.21 by John Arbash Meinel
Refactored bzrlib/ui.py into a module with the possibility for multiple ui forms.
619
    bzrlib.ui.ui_factory = TextUIFactory()
1185.43.6 by Martin Pool
Enable logging early enough to save argv
620
    ret = run_bzr_catch_errors(argv[1:])
621
    mutter("return code %d", ret)
622
    return ret
1185.3.19 by Martin Pool
- split out commandline error reporting for ease of testing
623
624
625
def run_bzr_catch_errors(argv):
1 by mbp at sourcefrog
import from baz patch-364
626
    try:
260 by Martin Pool
- remove atexit() dependency for writing out execution times
627
        try:
1393.1.64 by Martin Pool
- improved display of some errors, including NotBranchError
628
            return run_bzr(argv)
629
        finally:
630
            # do this here inside the exception wrappers to catch EPIPE
631
            sys.stdout.flush()
1097 by Martin Pool
- send trace messages out through python logging module
632
    except Exception, e:
1185.33.19 by Martin Pool
Run postmortem debugger if BZR_PDB is set
633
        # used to handle AssertionError and KeyboardInterrupt
634
        # specially here, but hopefully they're handled ok by the logger now
1097 by Martin Pool
- send trace messages out through python logging module
635
        import errno
636
        if (isinstance(e, IOError) 
637
            and hasattr(e, 'errno')
638
            and e.errno == errno.EPIPE):
639
            bzrlib.trace.note('broken pipe')
1185.35.21 by Aaron Bentley
Changed error status to 3
640
            return 3
1097 by Martin Pool
- send trace messages out through python logging module
641
        else:
1185.33.20 by Martin Pool
Really enter the debugger on failure
642
            bzrlib.trace.log_exception()
1185.33.19 by Martin Pool
Run postmortem debugger if BZR_PDB is set
643
            if os.environ.get('BZR_PDB'):
1185.33.20 by Martin Pool
Really enter the debugger on failure
644
                print '**** entering debugger'
1185.33.19 by Martin Pool
Run postmortem debugger if BZR_PDB is set
645
                import pdb
1185.33.20 by Martin Pool
Really enter the debugger on failure
646
                pdb.post_mortem(sys.exc_traceback)
1185.35.21 by Aaron Bentley
Changed error status to 3
647
            return 3
1 by mbp at sourcefrog
import from baz patch-364
648
649
if __name__ == '__main__':
650
    sys.exit(main(sys.argv))