/brz/remove-bazaar

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