~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,
43
                           NotBranchError)
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
44
from bzrlib.revisionspec import RevisionSpec
800 by Martin Pool
Merge John's import-speedup branch:
45
from bzrlib import BZRDIR
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
46
from bzrlib.option import Option
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
1185.37.4 by Jamie Wilkinson
add some examples to the documentation for Command.takes_args
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
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
211
    def run_argv(self, argv):
212
        """Parse command line and run."""
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
213
        args, opts = parse_args(self, argv)
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
214
        if 'help' in opts:  # e.g. bzr add --help
215
            from bzrlib.help import help_on_command
216
            help_on_command(self.name())
217
            return 0
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
218
        # XXX: This should be handled by the parser
1185.16.43 by Martin Pool
- clean up handling of option objects
219
        allowed_names = self.options().keys()
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
220
        for oname in opts:
1185.16.43 by Martin Pool
- clean up handling of option objects
221
            if oname not in allowed_names:
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
222
                raise BzrCommandError("option '--%s' is not allowed for command %r"
223
                                      % (oname, self.name()))
224
        # mix arguments and options into one dictionary
225
        cmdargs = _match_argform(self.name(), self.takes_args, args)
226
        cmdopts = {}
227
        for k, v in opts.items():
228
            cmdopts[k.replace('-', '_')] = v
229
230
        all_cmd_args = cmdargs.copy()
231
        all_cmd_args.update(cmdopts)
232
233
        return self.run(**all_cmd_args)
329 by Martin Pool
- refactor command functions into command classes
234
    
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
235
    def run(self):
236
        """Actually run the command.
329 by Martin Pool
- refactor command functions into command classes
237
238
        This is invoked with the options and arguments bound to
239
        keyword parameters.
240
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
241
        Return 0 or None if the command was successful, or a non-zero
242
        shell error code if not.  It's OK for this method to allow
243
        an exception to raise up.
329 by Martin Pool
- refactor command functions into command classes
244
        """
1147 by Martin Pool
- split builtin commands into separate module bzrlib.builtins;
245
        raise NotImplementedError()
329 by Martin Pool
- refactor command functions into command classes
246
247
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
248
    def help(self):
249
        """Return help message for this class."""
250
        if self.__doc__ is Command.__doc__:
251
            return None
252
        return getdoc(self)
253
254
    def name(self):
255
        return _unsquish_command_name(self.__class__.__name__)
256
257
493 by Martin Pool
- Merge aaron's merge command
258
def parse_spec(spec):
622 by Martin Pool
Updated merge patch from Aaron
259
    """
260
    >>> parse_spec(None)
261
    [None, None]
262
    >>> parse_spec("./")
263
    ['./', None]
264
    >>> parse_spec("../@")
265
    ['..', -1]
266
    >>> parse_spec("../f/@35")
267
    ['../f', 35]
897 by Martin Pool
- merge john's revision-naming code
268
    >>> parse_spec('./@revid:john@arbash-meinel.com-20050711044610-3ca0327c6a222f67')
269
    ['.', 'revid:john@arbash-meinel.com-20050711044610-3ca0327c6a222f67']
622 by Martin Pool
Updated merge patch from Aaron
270
    """
271
    if spec is None:
272
        return [None, None]
493 by Martin Pool
- Merge aaron's merge command
273
    if '/@' in spec:
274
        parsed = spec.split('/@')
275
        assert len(parsed) == 2
276
        if parsed[1] == "":
277
            parsed[1] = -1
278
        else:
897 by Martin Pool
- merge john's revision-naming code
279
            try:
280
                parsed[1] = int(parsed[1])
281
            except ValueError:
282
                pass # We can allow stuff like ./@revid:blahblahblah
283
            else:
284
                assert parsed[1] >=0
493 by Martin Pool
- Merge aaron's merge command
285
    else:
286
        parsed = [spec, None]
287
    return parsed
288
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
289
def parse_args(command, argv):
1 by mbp at sourcefrog
import from baz patch-364
290
    """Parse command line.
291
    
292
    Arguments and options are parsed at this level before being passed
293
    down to specific command handlers.  This routine knows, from a
294
    lookup table, something about the available options, what optargs
295
    they take, and which commands will accept them.
296
    """
1185.16.49 by mbp at sourcefrog
- more refactoring and tests of commandline
297
    # TODO: chop up this beast; make it a method of the Command
1 by mbp at sourcefrog
import from baz patch-364
298
    args = []
299
    opts = {}
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
26 by mbp at sourcefrog
fix StopIteration error on python2.3(?)
303
    while argv:
304
        a = argv.pop(0)
1185.16.49 by mbp at sourcefrog
- more refactoring and tests of commandline
305
        if argsover:
306
            args.append(a)
307
            continue
308
        elif a == '--':
309
            # We've received a standalone -- No more flags
310
            argsover = True
311
            continue
312
        if a[0] == '-':
264 by Martin Pool
parse_args: option names must be ascii
313
            # option names must not be unicode
314
            a = str(a)
17 by mbp at sourcefrog
allow --option=ARG syntax
315
            optarg = None
1 by mbp at sourcefrog
import from baz patch-364
316
            if a[1] == '-':
1185.31.4 by John Arbash Meinel
Fixing mutter() calls to not have to do string processing.
317
                mutter("  got option %r", a)
17 by mbp at sourcefrog
allow --option=ARG syntax
318
                if '=' in a:
319
                    optname, optarg = a[2:].split('=', 1)
320
                else:
321
                    optname = a[2:]
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
322
                if optname not in cmd_options:
1495 by Robert Collins
Add a --create-prefix to the new push command.
323
                    raise BzrOptionError('unknown long option %r for command %s'
324
                        % (a, command.name()))
1 by mbp at sourcefrog
import from baz patch-364
325
            else:
326
                shortopt = a[1:]
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
327
                if shortopt in Option.SHORT_OPTIONS:
683 by Martin Pool
- short option stacking patch from John A Meinel
328
                    # Multi-character options must have a space to delimit
329
                    # their value
1185.16.44 by Martin Pool
doc
330
                    # ^^^ what does this mean? mbp 20051014
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
331
                    optname = Option.SHORT_OPTIONS[shortopt].name
683 by Martin Pool
- short option stacking patch from John A Meinel
332
                else:
333
                    # Single character short options, can be chained,
334
                    # and have their value appended to their name
335
                    shortopt = a[1:2]
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
336
                    if shortopt not in Option.SHORT_OPTIONS:
683 by Martin Pool
- short option stacking patch from John A Meinel
337
                        # We didn't find the multi-character name, and we
338
                        # didn't find the single char name
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
339
                        raise BzrError('unknown short option %r' % a)
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
340
                    optname = Option.SHORT_OPTIONS[shortopt].name
683 by Martin Pool
- short option stacking patch from John A Meinel
341
342
                    if a[2:]:
343
                        # There are extra things on this option
344
                        # see if it is the value, or if it is another
345
                        # short option
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
346
                        optargfn = Option.OPTIONS[optname].type
683 by Martin Pool
- short option stacking patch from John A Meinel
347
                        if optargfn is None:
348
                            # This option does not take an argument, so the
349
                            # next entry is another short option, pack it back
350
                            # into the list
351
                            argv.insert(0, '-' + a[2:])
352
                        else:
353
                            # This option takes an argument, so pack it
354
                            # into the array
355
                            optarg = a[2:]
1 by mbp at sourcefrog
import from baz patch-364
356
            
1185.35.24 by Aaron Bentley
Fixed handling of short options not accepted by the command
357
                if optname not in cmd_options:
358
                    raise BzrOptionError('unknown short option %r for command'
359
                        ' %s' % (shortopt, command.name()))
1 by mbp at sourcefrog
import from baz patch-364
360
            if optname in opts:
361
                # XXX: Do we ever want to support this, e.g. for -r?
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
362
                raise BzrError('repeated option %r' % a)
17 by mbp at sourcefrog
allow --option=ARG syntax
363
                
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
364
            option_obj = cmd_options[optname]
365
            optargfn = option_obj.type
1 by mbp at sourcefrog
import from baz patch-364
366
            if optargfn:
17 by mbp at sourcefrog
allow --option=ARG syntax
367
                if optarg == None:
26 by mbp at sourcefrog
fix StopIteration error on python2.3(?)
368
                    if not argv:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
369
                        raise BzrError('option %r needs an argument' % a)
17 by mbp at sourcefrog
allow --option=ARG syntax
370
                    else:
26 by mbp at sourcefrog
fix StopIteration error on python2.3(?)
371
                        optarg = argv.pop(0)
17 by mbp at sourcefrog
allow --option=ARG syntax
372
                opts[optname] = optargfn(optarg)
1 by mbp at sourcefrog
import from baz patch-364
373
            else:
17 by mbp at sourcefrog
allow --option=ARG syntax
374
                if optarg != None:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
375
                    raise BzrError('option %r takes no argument' % optname)
1 by mbp at sourcefrog
import from baz patch-364
376
                opts[optname] = True
377
        else:
378
            args.append(a)
379
    return args, opts
380
381
329 by Martin Pool
- refactor command functions into command classes
382
def _match_argform(cmd, takes_args, args):
1 by mbp at sourcefrog
import from baz patch-364
383
    argdict = {}
26 by mbp at sourcefrog
fix StopIteration error on python2.3(?)
384
329 by Martin Pool
- refactor command functions into command classes
385
    # step through args and takes_args, allowing appropriate 0-many matches
386
    for ap in takes_args:
1 by mbp at sourcefrog
import from baz patch-364
387
        argname = ap[:-1]
388
        if ap[-1] == '?':
62 by mbp at sourcefrog
- new find_branch_root function; based on suggestion from aaron
389
            if args:
390
                argdict[argname] = args.pop(0)
196 by mbp at sourcefrog
selected-file diff
391
        elif ap[-1] == '*': # all remaining arguments
392
            if args:
393
                argdict[argname + '_list'] = args[:]
394
                args = []
395
            else:
396
                argdict[argname + '_list'] = None
1 by mbp at sourcefrog
import from baz patch-364
397
        elif ap[-1] == '+':
398
            if not args:
329 by Martin Pool
- refactor command functions into command classes
399
                raise BzrCommandError("command %r needs one or more %s"
1 by mbp at sourcefrog
import from baz patch-364
400
                        % (cmd, argname.upper()))
401
            else:
402
                argdict[argname + '_list'] = args[:]
403
                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
404
        elif ap[-1] == '$': # all but one
405
            if len(args) < 2:
329 by Martin Pool
- refactor command functions into command classes
406
                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
407
                        % (cmd, argname.upper()))
408
            argdict[argname + '_list'] = args[:-1]
409
            args[:-1] = []                
1 by mbp at sourcefrog
import from baz patch-364
410
        else:
411
            # just a plain arg
412
            argname = ap
413
            if not args:
329 by Martin Pool
- refactor command functions into command classes
414
                raise BzrCommandError("command %r requires argument %s"
1 by mbp at sourcefrog
import from baz patch-364
415
                        % (cmd, argname.upper()))
416
            else:
417
                argdict[argname] = args.pop(0)
418
            
419
    if args:
329 by Martin Pool
- refactor command functions into command classes
420
        raise BzrCommandError("extra argument to command %s: %s"
421
                              % (cmd, args[0]))
1 by mbp at sourcefrog
import from baz patch-364
422
423
    return argdict
424
425
426
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
427
def apply_profiled(the_callable, *args, **kwargs):
428
    import hotshot
429
    import tempfile
1393.1.27 by Martin Pool
- clean up profile code and change default sort order
430
    import hotshot.stats
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
431
    pffileno, pfname = tempfile.mkstemp()
432
    try:
433
        prof = hotshot.Profile(pfname)
434
        try:
435
            ret = prof.runcall(the_callable, *args, **kwargs) or 0
436
        finally:
437
            prof.close()
438
        stats = hotshot.stats.load(pfname)
1393.1.27 by Martin Pool
- clean up profile code and change default sort order
439
        stats.strip_dirs()
440
        stats.sort_stats('cum')   # 'time'
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
441
        ## XXX: Might like to write to stderr or the trace file instead but
442
        ## print_stats seems hardcoded to stdout
443
        stats.print_stats(20)
444
        return ret
445
    finally:
446
        os.close(pffileno)
447
        os.remove(pfname)
448
449
1185.33.85 by Martin Pool
New --lsprof option from Denys Duchier
450
def apply_lsprofiled(the_callable, *args, **kwargs):
451
    from bzrlib.lsprof import profile
452
    ret,stats = profile(the_callable,*args,**kwargs)
453
    stats.sort()
454
    stats.pprint()
455
    return ret
456
1 by mbp at sourcefrog
import from baz patch-364
457
def run_bzr(argv):
458
    """Execute a command.
459
460
    This is similar to main(), but without all the trappings for
245 by mbp at sourcefrog
- control files always in utf-8-unix format
461
    logging and error handling.  
973 by Martin Pool
- various refactorings of command interpreter
462
    
463
    argv
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
464
       The command-line arguments, without the program name from argv[0]
973 by Martin Pool
- various refactorings of command interpreter
465
    
466
    Returns a command status or raises an exception.
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
467
468
    Special master options: these must come before the command because
469
    they control how the command is interpreted.
470
471
    --no-plugins
472
        Do not load plugin modules at all
473
474
    --builtin
475
        Only use builtin commands.  (Plugins are still allowed to change
476
        other behaviour.)
477
478
    --profile
1185.33.85 by Martin Pool
New --lsprof option from Denys Duchier
479
        Run under the Python hotshot profiler.
480
481
    --lsprof
482
        Run under the Python lsprof profiler.
1 by mbp at sourcefrog
import from baz patch-364
483
    """
251 by mbp at sourcefrog
- factor out locale.getpreferredencoding()
484
    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.
485
1185.33.85 by Martin Pool
New --lsprof option from Denys Duchier
486
    opt_lsprof = opt_profile = opt_no_plugins = opt_builtin = False
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
487
488
    # --no-plugins is handled specially at a very early stage. We need
489
    # to load plugins before doing other command parsing so that they
490
    # can override commands, but this needs to happen first.
491
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
492
    for a in argv:
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
493
        if a == '--profile':
494
            opt_profile = True
1185.33.85 by Martin Pool
New --lsprof option from Denys Duchier
495
        elif a == '--lsprof':
496
            opt_lsprof = True
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
497
        elif a == '--no-plugins':
498
            opt_no_plugins = True
499
        elif a == '--builtin':
500
            opt_builtin = True
1185.33.42 by Martin Pool
[patch] make --quiet a global option (robey)
501
        elif a in ('--quiet', '-q'):
502
            be_quiet()
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
503
        else:
1185.33.42 by Martin Pool
[patch] make --quiet a global option (robey)
504
            continue
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
505
        argv.remove(a)
506
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
507
    if (not argv) or (argv[0] == '--help'):
508
        from bzrlib.help import help
509
        if len(argv) > 1:
510
            help(argv[1])
511
        else:
512
            help()
513
        return 0
514
515
    if argv[0] == '--version':
516
        from bzrlib.builtins import show_version
517
        show_version()
518
        return 0
519
        
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
520
    if not opt_no_plugins:
973 by Martin Pool
- various refactorings of command interpreter
521
        from bzrlib.plugin import load_plugins
522
        load_plugins()
523
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
524
    cmd = str(argv.pop(0))
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
525
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
526
    cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
1 by mbp at sourcefrog
import from baz patch-364
527
1185.33.42 by Martin Pool
[patch] make --quiet a global option (robey)
528
    try:
1185.33.85 by Martin Pool
New --lsprof option from Denys Duchier
529
        if opt_lsprof:
530
            ret = apply_lsprofiled(cmd_obj.run_argv, argv)
531
        elif opt_profile:
1185.33.42 by Martin Pool
[patch] make --quiet a global option (robey)
532
            ret = apply_profiled(cmd_obj.run_argv, argv)
533
        else:
534
            ret = cmd_obj.run_argv(argv)
535
        return ret or 0
536
    finally:
537
        # reset, in case we may do other commands later within the same process
538
        be_quiet(False)
267 by Martin Pool
- better reporting of errors
539
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
540
def display_command(func):
1185.33.18 by Martin Pool
[patch] handle bad IOError subclass raised by urlopen
541
    """Decorator that suppresses pipe/interrupt errors."""
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
542
    def ignore_pipe(*args, **kwargs):
543
        try:
1185.35.22 by Aaron Bentley
Handled more pipe errors for display commands.
544
            result = func(*args, **kwargs)
545
            sys.stdout.flush()
546
            return result
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
547
        except IOError, e:
1185.33.18 by Martin Pool
[patch] handle bad IOError subclass raised by urlopen
548
            if not hasattr(e, 'errno'):
549
                raise
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
550
            if e.errno != errno.EPIPE:
551
                raise
1185.33.18 by Martin Pool
[patch] handle bad IOError subclass raised by urlopen
552
            pass
1185.12.69 by Aaron Bentley
Ignored ^C in display commands
553
        except KeyboardInterrupt:
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
554
            pass
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
555
    return ignore_pipe
267 by Martin Pool
- better reporting of errors
556
1185.43.6 by Martin Pool
Enable logging early enough to save argv
557
1 by mbp at sourcefrog
import from baz patch-364
558
def main(argv):
1104 by Martin Pool
- Add a simple UIFactory
559
    import bzrlib.ui
1185.49.21 by John Arbash Meinel
Refactored bzrlib/ui.py into a module with the possibility for multiple ui forms.
560
    from bzrlib.ui.text import TextUIFactory
1185.43.8 by Martin Pool
Don't enable default logging twice
561
    ## bzrlib.trace.enable_default_logging()
1111 by Martin Pool
- add functions to enable and disable default logging, so that we can
562
    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.
563
    bzrlib.ui.ui_factory = TextUIFactory()
1185.43.6 by Martin Pool
Enable logging early enough to save argv
564
    ret = run_bzr_catch_errors(argv[1:])
565
    mutter("return code %d", ret)
566
    return ret
1185.3.19 by Martin Pool
- split out commandline error reporting for ease of testing
567
568
569
def run_bzr_catch_errors(argv):
1 by mbp at sourcefrog
import from baz patch-364
570
    try:
260 by Martin Pool
- remove atexit() dependency for writing out execution times
571
        try:
1393.1.64 by Martin Pool
- improved display of some errors, including NotBranchError
572
            return run_bzr(argv)
573
        finally:
574
            # do this here inside the exception wrappers to catch EPIPE
575
            sys.stdout.flush()
1097 by Martin Pool
- send trace messages out through python logging module
576
    except Exception, e:
1185.33.19 by Martin Pool
Run postmortem debugger if BZR_PDB is set
577
        # used to handle AssertionError and KeyboardInterrupt
578
        # specially here, but hopefully they're handled ok by the logger now
1097 by Martin Pool
- send trace messages out through python logging module
579
        import errno
580
        if (isinstance(e, IOError) 
581
            and hasattr(e, 'errno')
582
            and e.errno == errno.EPIPE):
583
            bzrlib.trace.note('broken pipe')
1185.35.21 by Aaron Bentley
Changed error status to 3
584
            return 3
1097 by Martin Pool
- send trace messages out through python logging module
585
        else:
1185.33.20 by Martin Pool
Really enter the debugger on failure
586
            bzrlib.trace.log_exception()
1185.33.19 by Martin Pool
Run postmortem debugger if BZR_PDB is set
587
            if os.environ.get('BZR_PDB'):
1185.33.20 by Martin Pool
Really enter the debugger on failure
588
                print '**** entering debugger'
1185.33.19 by Martin Pool
Run postmortem debugger if BZR_PDB is set
589
                import pdb
1185.33.20 by Martin Pool
Really enter the debugger on failure
590
                pdb.post_mortem(sys.exc_traceback)
1185.35.21 by Aaron Bentley
Changed error status to 3
591
            return 3
1 by mbp at sourcefrog
import from baz patch-364
592
593
if __name__ == '__main__':
594
    sys.exit(main(sys.argv))