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