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