~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
897 by Martin Pool
- merge john's revision-naming code
38
from bzrlib.trace import mutter, note, log_error, warning
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
1 by mbp at sourcefrog
import from baz patch-364
450
def run_bzr(argv):
451
    """Execute a command.
452
453
    This is similar to main(), but without all the trappings for
245 by mbp at sourcefrog
- control files always in utf-8-unix format
454
    logging and error handling.  
973 by Martin Pool
- various refactorings of command interpreter
455
    
456
    argv
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
457
       The command-line arguments, without the program name from argv[0]
973 by Martin Pool
- various refactorings of command interpreter
458
    
459
    Returns a command status or raises an exception.
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
460
461
    Special master options: these must come before the command because
462
    they control how the command is interpreted.
463
464
    --no-plugins
465
        Do not load plugin modules at all
466
467
    --builtin
468
        Only use builtin commands.  (Plugins are still allowed to change
469
        other behaviour.)
470
471
    --profile
472
        Run under the Python profiler.
1 by mbp at sourcefrog
import from baz patch-364
473
    """
251 by mbp at sourcefrog
- factor out locale.getpreferredencoding()
474
    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.
475
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
476
    opt_profile = opt_no_plugins = opt_builtin = False
477
478
    # --no-plugins is handled specially at a very early stage. We need
479
    # to load plugins before doing other command parsing so that they
480
    # can override commands, but this needs to happen first.
481
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
482
    for a in argv:
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
483
        if a == '--profile':
484
            opt_profile = True
485
        elif a == '--no-plugins':
486
            opt_no_plugins = True
487
        elif a == '--builtin':
488
            opt_builtin = True
489
        else:
490
            break
491
        argv.remove(a)
492
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
493
    if (not argv) or (argv[0] == '--help'):
494
        from bzrlib.help import help
495
        if len(argv) > 1:
496
            help(argv[1])
497
        else:
498
            help()
499
        return 0
500
501
    if argv[0] == '--version':
502
        from bzrlib.builtins import show_version
503
        show_version()
504
        return 0
505
        
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
506
    if not opt_no_plugins:
973 by Martin Pool
- various refactorings of command interpreter
507
        from bzrlib.plugin import load_plugins
508
        load_plugins()
509
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
510
    cmd = str(argv.pop(0))
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
511
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
512
    cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
1 by mbp at sourcefrog
import from baz patch-364
513
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
514
    if opt_profile:
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
515
        ret = apply_profiled(cmd_obj.run_argv, argv)
137 by mbp at sourcefrog
new --profile option
516
    else:
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
517
        ret = cmd_obj.run_argv(argv)
518
    return ret or 0
267 by Martin Pool
- better reporting of errors
519
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
520
def display_command(func):
1185.33.18 by Martin Pool
[patch] handle bad IOError subclass raised by urlopen
521
    """Decorator that suppresses pipe/interrupt errors."""
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
522
    def ignore_pipe(*args, **kwargs):
523
        try:
1185.35.22 by Aaron Bentley
Handled more pipe errors for display commands.
524
            result = func(*args, **kwargs)
525
            sys.stdout.flush()
526
            return result
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
527
        except IOError, e:
1185.33.18 by Martin Pool
[patch] handle bad IOError subclass raised by urlopen
528
            if not hasattr(e, 'errno'):
529
                raise
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
530
            if e.errno != errno.EPIPE:
531
                raise
1185.33.18 by Martin Pool
[patch] handle bad IOError subclass raised by urlopen
532
            pass
1185.12.69 by Aaron Bentley
Ignored ^C in display commands
533
        except KeyboardInterrupt:
1490 by Robert Collins
Implement a 'bzr push' command, with saved locations; update diff to return 1.
534
            pass
1185.12.56 by Aaron Bentley
Prevented display commands from printing broken pipe errors
535
    return ignore_pipe
267 by Martin Pool
- better reporting of errors
536
1 by mbp at sourcefrog
import from baz patch-364
537
def main(argv):
1104 by Martin Pool
- Add a simple UIFactory
538
    import bzrlib.ui
1111 by Martin Pool
- add functions to enable and disable default logging, so that we can
539
    bzrlib.trace.log_startup(argv)
1104 by Martin Pool
- Add a simple UIFactory
540
    bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
541
1185.3.20 by Martin Pool
- run_bzr_captured also includes logged errors in
542
    return run_bzr_catch_errors(argv[1:])
1185.3.19 by Martin Pool
- split out commandline error reporting for ease of testing
543
544
545
def run_bzr_catch_errors(argv):
1 by mbp at sourcefrog
import from baz patch-364
546
    try:
260 by Martin Pool
- remove atexit() dependency for writing out execution times
547
        try:
1393.1.64 by Martin Pool
- improved display of some errors, including NotBranchError
548
            return run_bzr(argv)
549
        finally:
550
            # do this here inside the exception wrappers to catch EPIPE
551
            sys.stdout.flush()
1097 by Martin Pool
- send trace messages out through python logging module
552
    except Exception, e:
1185.33.19 by Martin Pool
Run postmortem debugger if BZR_PDB is set
553
        # used to handle AssertionError and KeyboardInterrupt
554
        # specially here, but hopefully they're handled ok by the logger now
1097 by Martin Pool
- send trace messages out through python logging module
555
        import errno
556
        if (isinstance(e, IOError) 
557
            and hasattr(e, 'errno')
558
            and e.errno == errno.EPIPE):
559
            bzrlib.trace.note('broken pipe')
1185.35.21 by Aaron Bentley
Changed error status to 3
560
            return 3
1097 by Martin Pool
- send trace messages out through python logging module
561
        else:
1185.33.20 by Martin Pool
Really enter the debugger on failure
562
            bzrlib.trace.log_exception()
1185.33.19 by Martin Pool
Run postmortem debugger if BZR_PDB is set
563
            if os.environ.get('BZR_PDB'):
1185.33.20 by Martin Pool
Really enter the debugger on failure
564
                print '**** entering debugger'
1185.33.19 by Martin Pool
Run postmortem debugger if BZR_PDB is set
565
                import pdb
1185.33.20 by Martin Pool
Really enter the debugger on failure
566
                pdb.post_mortem(sys.exc_traceback)
1185.35.21 by Aaron Bentley
Changed error status to 3
567
            return 3
1 by mbp at sourcefrog
import from baz patch-364
568
569
if __name__ == '__main__':
570
    sys.exit(main(sys.argv))