/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
27
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
28
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
29
import sys
30
import os
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
31
from warnings import warn
32
from inspect import getdoc
1 by mbp at sourcefrog
import from baz patch-364
33
34
import bzrlib
1112 by Martin Pool
- disable standard logging to .bzr.log and stderr while running
35
import bzrlib.trace
897 by Martin Pool
- merge john's revision-naming code
36
from bzrlib.trace import mutter, note, log_error, warning
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
37
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError
800 by Martin Pool
Merge John's import-speedup branch:
38
from bzrlib.branch import find_branch
39
from bzrlib import BZRDIR
1 by mbp at sourcefrog
import from baz patch-364
40
731 by Martin Pool
- merge plugin patch from john
41
plugin_cmds = {}
42
43
759 by Martin Pool
- fix up register_command() names
44
def register_command(cmd):
731 by Martin Pool
- merge plugin patch from john
45
    "Utility function to help register a command"
46
    global plugin_cmds
47
    k = cmd.__name__
48
    if k.startswith("cmd_"):
49
        k_unsquished = _unsquish_command_name(k)
50
    else:
51
        k_unsquished = k
52
    if not plugin_cmds.has_key(k_unsquished):
53
        plugin_cmds[k_unsquished] = cmd
1137 by Martin Pool
- additional trace messages for plugins
54
        mutter('registered plugin command %s', k_unsquished)      
731 by Martin Pool
- merge plugin patch from john
55
    else:
56
        log_error('Two plugins defined the same command: %r' % k)
57
        log_error('Not loading the one in %r' % sys.modules[cmd.__module__])
58
59
350 by Martin Pool
- refactor command aliases into command classes
60
def _squish_command_name(cmd):
61
    return 'cmd_' + cmd.replace('-', '_')
62
63
64
def _unsquish_command_name(cmd):
65
    assert cmd.startswith("cmd_")
66
    return cmd[4:].replace('_','-')
67
914 by Martin Pool
- fix up breakage of 'bzr log -v' by root_id patch
68
567 by Martin Pool
- New form 'bzr log -r FROM:TO'
69
def _parse_revision_str(revstr):
914 by Martin Pool
- fix up breakage of 'bzr log -v' by root_id patch
70
    """This handles a revision string -> revno.
71
1185.2.5 by Lalo Martins
moving the 'revision spec' stuff out of the Branch class and into a new
72
    This always returns a list.  The list will have one element for
73
    each revision.
567 by Martin Pool
- New form 'bzr log -r FROM:TO'
74
897 by Martin Pool
- merge john's revision-naming code
75
    It supports integers directly, but everything else it
1185.2.6 by Lalo Martins
turned get_revision_info into a RevisionSpec class
76
    defers for passing to RevisionSpec.
897 by Martin Pool
- merge john's revision-naming code
77
78
    >>> _parse_revision_str('234')
79
    [234]
80
    >>> _parse_revision_str('234..567')
81
    [234, 567]
82
    >>> _parse_revision_str('..')
83
    [None, None]
84
    >>> _parse_revision_str('..234')
85
    [None, 234]
86
    >>> _parse_revision_str('234..')
87
    [234, None]
88
    >>> _parse_revision_str('234..456..789') # Maybe this should be an error
89
    [234, 456, 789]
90
    >>> _parse_revision_str('234....789') # Error?
91
    [234, None, 789]
92
    >>> _parse_revision_str('revid:test@other.com-234234')
93
    ['revid:test@other.com-234234']
94
    >>> _parse_revision_str('revid:test@other.com-234234..revid:test@other.com-234235')
95
    ['revid:test@other.com-234234', 'revid:test@other.com-234235']
96
    >>> _parse_revision_str('revid:test@other.com-234234..23')
97
    ['revid:test@other.com-234234', 23]
98
    >>> _parse_revision_str('date:2005-04-12')
99
    ['date:2005-04-12']
100
    >>> _parse_revision_str('date:2005-04-12 12:24:33')
101
    ['date:2005-04-12 12:24:33']
102
    >>> _parse_revision_str('date:2005-04-12T12:24:33')
103
    ['date:2005-04-12T12:24:33']
104
    >>> _parse_revision_str('date:2005-04-12,12:24:33')
105
    ['date:2005-04-12,12:24:33']
106
    >>> _parse_revision_str('-5..23')
107
    [-5, 23]
108
    >>> _parse_revision_str('-5')
109
    [-5]
110
    >>> _parse_revision_str('123a')
111
    ['123a']
112
    >>> _parse_revision_str('abc')
113
    ['abc']
567 by Martin Pool
- New form 'bzr log -r FROM:TO'
114
    """
897 by Martin Pool
- merge john's revision-naming code
115
    import re
116
    old_format_re = re.compile('\d*:\d*')
117
    m = old_format_re.match(revstr)
118
    if m:
119
        warning('Colon separator for revision numbers is deprecated.'
120
                ' Use .. instead')
121
        revs = []
122
        for rev in revstr.split(':'):
123
            if rev:
124
                revs.append(int(rev))
125
            else:
126
                revs.append(None)
127
        return revs
128
    revs = []
129
    for x in revstr.split('..'):
130
        if not x:
131
            revs.append(None)
132
        else:
133
            try:
134
                revs.append(int(x))
135
            except ValueError:
136
                revs.append(x)
567 by Martin Pool
- New form 'bzr log -r FROM:TO'
137
    return revs
138
731 by Martin Pool
- merge plugin patch from john
139
974.1.9 by Aaron Bentley
Added merge-type parameter to merge.
140
def get_merge_type(typestring):
141
    """Attempt to find the merge class/factory associated with a string."""
142
    from merge import merge_types
143
    try:
144
        return merge_types[typestring][0]
145
    except KeyError:
146
        templ = '%s%%7s: %%s' % (' '*12)
147
        lines = [templ % (f[0], f[1][1]) for f in merge_types.iteritems()]
148
        type_list = '\n'.join(lines)
149
        msg = "No known merge type %s. Supported types are:\n%s" %\
150
            (typestring, type_list)
151
        raise BzrCommandError(msg)
152
    
153
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
154
def get_merge_type(typestring):
155
    """Attempt to find the merge class/factory associated with a string."""
156
    from merge import merge_types
157
    try:
158
        return merge_types[typestring][0]
159
    except KeyError:
160
        templ = '%s%%7s: %%s' % (' '*12)
161
        lines = [templ % (f[0], f[1][1]) for f in merge_types.iteritems()]
162
        type_list = '\n'.join(lines)
163
        msg = "No known merge type %s. Supported types are:\n%s" %\
164
            (typestring, type_list)
165
        raise BzrCommandError(msg)
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
166
167
168
def _builtin_commands():
1147 by Martin Pool
- split builtin commands into separate module bzrlib.builtins;
169
    import bzrlib.builtins
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
170
    r = {}
1147 by Martin Pool
- split builtin commands into separate module bzrlib.builtins;
171
    builtins = bzrlib.builtins.__dict__
172
    for name in builtins:
173
        if name.startswith("cmd_"):
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
174
            real_name = _unsquish_command_name(name)        
175
            r[real_name] = builtins[name]
176
    return r
177
178
            
179
180
def builtin_command_names():
181
    """Return list of builtin command names."""
182
    return _builtin_commands().keys()
183
    
184
185
def plugin_command_names():
186
    return plugin_cmds.keys()
187
188
189
def _get_cmd_dict(plugins_override=True):
190
    """Return name->class mapping for all commands."""
191
    d = _builtin_commands()
731 by Martin Pool
- merge plugin patch from john
192
    if plugins_override:
193
        d.update(plugin_cmds)
641 by Martin Pool
- improved external-command patch from john
194
    return d
731 by Martin Pool
- merge plugin patch from john
195
641 by Martin Pool
- improved external-command patch from john
196
    
731 by Martin Pool
- merge plugin patch from john
197
def get_all_cmds(plugins_override=True):
641 by Martin Pool
- improved external-command patch from john
198
    """Return canonical name and class for all registered commands."""
731 by Martin Pool
- merge plugin patch from john
199
    for k, v in _get_cmd_dict(plugins_override=plugins_override).iteritems():
641 by Martin Pool
- improved external-command patch from john
200
        yield k,v
201
202
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
203
def get_cmd_object(cmd_name, plugins_override=True):
350 by Martin Pool
- refactor command aliases into command classes
204
    """Return the canonical name and command class for a command.
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
205
206
    plugins_override
207
        If true, plugin commands can override builtins.
350 by Martin Pool
- refactor command aliases into command classes
208
    """
1163 by Martin Pool
- split ExternalCommand class into its own file
209
    from bzrlib.externalcommand import ExternalCommand
210
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
211
    cmd_name = str(cmd_name)            # not unicode
350 by Martin Pool
- refactor command aliases into command classes
212
213
    # first look up this command under the specified name
731 by Martin Pool
- merge plugin patch from john
214
    cmds = _get_cmd_dict(plugins_override=plugins_override)
272 by Martin Pool
- Add command aliases
215
    try:
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
216
        return cmds[cmd_name]()
272 by Martin Pool
- Add command aliases
217
    except KeyError:
350 by Martin Pool
- refactor command aliases into command classes
218
        pass
219
220
    # look for any command which claims this as an alias
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
221
    for real_cmd_name, cmd_class in cmds.iteritems():
222
        if cmd_name in cmd_class.aliases:
223
            return cmd_class()
224
225
    cmd_obj = ExternalCommand.find_command(cmd_name)
226
    if cmd_obj:
227
        return cmd_obj
228
229
    raise BzrCommandError("unknown command %r" % cmd_name)
272 by Martin Pool
- Add command aliases
230
329 by Martin Pool
- refactor command functions into command classes
231
558 by Martin Pool
- All top-level classes inherit from object
232
class Command(object):
329 by Martin Pool
- refactor command functions into command classes
233
    """Base class for commands.
234
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
235
    Commands are the heart of the command-line bzr interface.
236
237
    The command object mostly handles the mapping of command-line
238
    parameters into one or more bzrlib operations, and of the results
239
    into textual output.
240
241
    Commands normally don't have any state.  All their arguments are
242
    passed in to the run method.  (Subclasses may take a different
243
    policy if the behaviour of the instance needs to depend on e.g. a
244
    shell plugin and not just its Python class.)
245
329 by Martin Pool
- refactor command functions into command classes
246
    The docstring for an actual command should give a single-line
247
    summary, then a complete description of the command.  A grammar
248
    description will be inserted.
249
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
250
    aliases
251
        Other accepted names for this command.
252
329 by Martin Pool
- refactor command functions into command classes
253
    takes_args
254
        List of argument forms, marked with whether they are optional,
255
        repeated, etc.
256
257
    takes_options
258
        List of options that may be given for this command.
259
260
    hidden
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
261
        If true, this command isn't advertised.  This is typically
262
        for commands intended for expert users.
329 by Martin Pool
- refactor command functions into command classes
263
    """
264
    aliases = []
265
    
266
    takes_args = []
267
    takes_options = []
268
269
    hidden = False
270
    
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
271
    def __init__(self):
272
        """Construct an instance of this command."""
973 by Martin Pool
- various refactorings of command interpreter
273
        if self.__doc__ == Command.__doc__:
274
            warn("No help message set for %r" % self)
329 by Martin Pool
- refactor command functions into command classes
275
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
276
277
    def run_argv(self, argv):
278
        """Parse command line and run."""
279
        args, opts = parse_args(argv)
280
281
        if 'help' in opts:  # e.g. bzr add --help
282
            from bzrlib.help import help_on_command
283
            help_on_command(self.name())
284
            return 0
285
286
        # check options are reasonable
287
        allowed = self.takes_options
288
        for oname in opts:
289
            if oname not in allowed:
290
                raise BzrCommandError("option '--%s' is not allowed for command %r"
291
                                      % (oname, self.name()))
292
293
        # mix arguments and options into one dictionary
294
        cmdargs = _match_argform(self.name(), self.takes_args, args)
295
        cmdopts = {}
296
        for k, v in opts.items():
297
            cmdopts[k.replace('-', '_')] = v
298
299
        all_cmd_args = cmdargs.copy()
300
        all_cmd_args.update(cmdopts)
301
302
        return self.run(**all_cmd_args)
303
329 by Martin Pool
- refactor command functions into command classes
304
    
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
305
    def run(self):
306
        """Actually run the command.
329 by Martin Pool
- refactor command functions into command classes
307
308
        This is invoked with the options and arguments bound to
309
        keyword parameters.
310
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
311
        Return 0 or None if the command was successful, or a non-zero
312
        shell error code if not.  It's OK for this method to allow
313
        an exception to raise up.
329 by Martin Pool
- refactor command functions into command classes
314
        """
1147 by Martin Pool
- split builtin commands into separate module bzrlib.builtins;
315
        raise NotImplementedError()
329 by Martin Pool
- refactor command functions into command classes
316
317
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
318
    def help(self):
319
        """Return help message for this class."""
320
        if self.__doc__ is Command.__doc__:
321
            return None
322
        return getdoc(self)
323
324
    def name(self):
325
        return _unsquish_command_name(self.__class__.__name__)
326
327
493 by Martin Pool
- Merge aaron's merge command
328
def parse_spec(spec):
622 by Martin Pool
Updated merge patch from Aaron
329
    """
330
    >>> parse_spec(None)
331
    [None, None]
332
    >>> parse_spec("./")
333
    ['./', None]
334
    >>> parse_spec("../@")
335
    ['..', -1]
336
    >>> parse_spec("../f/@35")
337
    ['../f', 35]
897 by Martin Pool
- merge john's revision-naming code
338
    >>> parse_spec('./@revid:john@arbash-meinel.com-20050711044610-3ca0327c6a222f67')
339
    ['.', 'revid:john@arbash-meinel.com-20050711044610-3ca0327c6a222f67']
622 by Martin Pool
Updated merge patch from Aaron
340
    """
341
    if spec is None:
342
        return [None, None]
493 by Martin Pool
- Merge aaron's merge command
343
    if '/@' in spec:
344
        parsed = spec.split('/@')
345
        assert len(parsed) == 2
346
        if parsed[1] == "":
347
            parsed[1] = -1
348
        else:
897 by Martin Pool
- merge john's revision-naming code
349
            try:
350
                parsed[1] = int(parsed[1])
351
            except ValueError:
352
                pass # We can allow stuff like ./@revid:blahblahblah
353
            else:
354
                assert parsed[1] >=0
493 by Martin Pool
- Merge aaron's merge command
355
    else:
356
        parsed = [spec, None]
357
    return parsed
358
628 by Martin Pool
- merge aaron's updated merge/pull code
359
360
755 by Martin Pool
- new 'plugins' command
361
1 by mbp at sourcefrog
import from baz patch-364
362
# list of all available options; the rhs can be either None for an
363
# option that takes no argument, or a constructor function that checks
364
# the type.
365
OPTIONS = {
366
    'all':                    None,
571 by Martin Pool
- new --diff-options to pass options through to external
367
    'diff-options':           str,
1 by mbp at sourcefrog
import from baz patch-364
368
    'help':                   None,
389 by Martin Pool
- new commit --file option!
369
    'file':                   unicode,
628 by Martin Pool
- merge aaron's updated merge/pull code
370
    'force':                  None,
678 by Martin Pool
- export to tarballs
371
    'format':                 unicode,
545 by Martin Pool
- --forward option for log
372
    'forward':                None,
1 by mbp at sourcefrog
import from baz patch-364
373
    'message':                unicode,
594 by Martin Pool
- add --no-recurse option for add command
374
    'no-recurse':             None,
137 by mbp at sourcefrog
new --profile option
375
    'profile':                None,
567 by Martin Pool
- New form 'bzr log -r FROM:TO'
376
    'revision':               _parse_revision_str,
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
377
    'short':                  None,
1 by mbp at sourcefrog
import from baz patch-364
378
    'show-ids':               None,
12 by mbp at sourcefrog
new --timezone option for bzr log
379
    'timezone':               str,
1 by mbp at sourcefrog
import from baz patch-364
380
    'verbose':                None,
381
    'version':                None,
286 by Martin Pool
- New bzr whoami --email option
382
    'email':                  None,
885 by Martin Pool
- commit command refuses unless something is changed or --unchanged is given
383
    'unchanged':              None,
674 by Martin Pool
- check command now also checks new inventory_sha1 and
384
    'update':                 None,
807 by Martin Pool
- New log --long option
385
    'long':                   None,
849 by Martin Pool
- Put files inside an exported tarball into a top-level directory rather than
386
    'root':                   str,
974.1.8 by Aaron Bentley
Added default backups for merge-revert
387
    'no-backup':              None,
974.1.9 by Aaron Bentley
Added merge-type parameter to merge.
388
    'merge-type':             get_merge_type,
1092.1.20 by Robert Collins
import and use TestUtil to do regex based partial test runs
389
    'pattern':                str,
1 by mbp at sourcefrog
import from baz patch-364
390
    }
391
392
SHORT_OPTIONS = {
583 by Martin Pool
- add -h as short name for --help
393
    'F':                      'file', 
394
    'h':                      'help',
1 by mbp at sourcefrog
import from baz patch-364
395
    'm':                      'message',
396
    'r':                      'revision',
397
    'v':                      'verbose',
807 by Martin Pool
- New log --long option
398
    'l':                      'long',
1 by mbp at sourcefrog
import from baz patch-364
399
}
400
401
402
def parse_args(argv):
403
    """Parse command line.
404
    
405
    Arguments and options are parsed at this level before being passed
406
    down to specific command handlers.  This routine knows, from a
407
    lookup table, something about the available options, what optargs
408
    they take, and which commands will accept them.
409
31 by Martin Pool
fix up parse_args doctest
410
    >>> parse_args('--help'.split())
1 by mbp at sourcefrog
import from baz patch-364
411
    ([], {'help': True})
1144 by Martin Pool
- accept -- to terminate options
412
    >>> parse_args('help -- --invalidcmd'.split())
413
    (['help', '--invalidcmd'], {})
31 by Martin Pool
fix up parse_args doctest
414
    >>> parse_args('--version'.split())
1 by mbp at sourcefrog
import from baz patch-364
415
    ([], {'version': True})
31 by Martin Pool
fix up parse_args doctest
416
    >>> parse_args('status --all'.split())
1 by mbp at sourcefrog
import from baz patch-364
417
    (['status'], {'all': True})
31 by Martin Pool
fix up parse_args doctest
418
    >>> parse_args('commit --message=biter'.split())
17 by mbp at sourcefrog
allow --option=ARG syntax
419
    (['commit'], {'message': u'biter'})
683 by Martin Pool
- short option stacking patch from John A Meinel
420
    >>> parse_args('log -r 500'.split())
897 by Martin Pool
- merge john's revision-naming code
421
    (['log'], {'revision': [500]})
422
    >>> parse_args('log -r500..600'.split())
683 by Martin Pool
- short option stacking patch from John A Meinel
423
    (['log'], {'revision': [500, 600]})
897 by Martin Pool
- merge john's revision-naming code
424
    >>> parse_args('log -vr500..600'.split())
683 by Martin Pool
- short option stacking patch from John A Meinel
425
    (['log'], {'verbose': True, 'revision': [500, 600]})
897 by Martin Pool
- merge john's revision-naming code
426
    >>> parse_args('log -rv500..600'.split()) #the r takes an argument
427
    (['log'], {'revision': ['v500', 600]})
1 by mbp at sourcefrog
import from baz patch-364
428
    """
429
    args = []
430
    opts = {}
431
1144 by Martin Pool
- accept -- to terminate options
432
    argsover = False
26 by mbp at sourcefrog
fix StopIteration error on python2.3(?)
433
    while argv:
434
        a = argv.pop(0)
1144 by Martin Pool
- accept -- to terminate options
435
        if not argsover and a[0] == '-':
264 by Martin Pool
parse_args: option names must be ascii
436
            # option names must not be unicode
437
            a = str(a)
17 by mbp at sourcefrog
allow --option=ARG syntax
438
            optarg = None
1 by mbp at sourcefrog
import from baz patch-364
439
            if a[1] == '-':
1144 by Martin Pool
- accept -- to terminate options
440
                if a == '--':
441
                    # We've received a standalone -- No more flags
442
                    argsover = True
443
                    continue
1 by mbp at sourcefrog
import from baz patch-364
444
                mutter("  got option %r" % a)
17 by mbp at sourcefrog
allow --option=ARG syntax
445
                if '=' in a:
446
                    optname, optarg = a[2:].split('=', 1)
447
                else:
448
                    optname = a[2:]
1 by mbp at sourcefrog
import from baz patch-364
449
                if optname not in OPTIONS:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
450
                    raise BzrError('unknown long option %r' % a)
1 by mbp at sourcefrog
import from baz patch-364
451
            else:
452
                shortopt = a[1:]
683 by Martin Pool
- short option stacking patch from John A Meinel
453
                if shortopt in SHORT_OPTIONS:
454
                    # Multi-character options must have a space to delimit
455
                    # their value
456
                    optname = SHORT_OPTIONS[shortopt]
457
                else:
458
                    # Single character short options, can be chained,
459
                    # and have their value appended to their name
460
                    shortopt = a[1:2]
461
                    if shortopt not in SHORT_OPTIONS:
462
                        # We didn't find the multi-character name, and we
463
                        # didn't find the single char name
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
464
                        raise BzrError('unknown short option %r' % a)
683 by Martin Pool
- short option stacking patch from John A Meinel
465
                    optname = SHORT_OPTIONS[shortopt]
466
467
                    if a[2:]:
468
                        # There are extra things on this option
469
                        # see if it is the value, or if it is another
470
                        # short option
471
                        optargfn = OPTIONS[optname]
472
                        if optargfn is None:
473
                            # This option does not take an argument, so the
474
                            # next entry is another short option, pack it back
475
                            # into the list
476
                            argv.insert(0, '-' + a[2:])
477
                        else:
478
                            # This option takes an argument, so pack it
479
                            # into the array
480
                            optarg = a[2:]
1 by mbp at sourcefrog
import from baz patch-364
481
            
482
            if optname in opts:
483
                # 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
484
                raise BzrError('repeated option %r' % a)
17 by mbp at sourcefrog
allow --option=ARG syntax
485
                
1 by mbp at sourcefrog
import from baz patch-364
486
            optargfn = OPTIONS[optname]
487
            if optargfn:
17 by mbp at sourcefrog
allow --option=ARG syntax
488
                if optarg == None:
26 by mbp at sourcefrog
fix StopIteration error on python2.3(?)
489
                    if not argv:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
490
                        raise BzrError('option %r needs an argument' % a)
17 by mbp at sourcefrog
allow --option=ARG syntax
491
                    else:
26 by mbp at sourcefrog
fix StopIteration error on python2.3(?)
492
                        optarg = argv.pop(0)
17 by mbp at sourcefrog
allow --option=ARG syntax
493
                opts[optname] = optargfn(optarg)
1 by mbp at sourcefrog
import from baz patch-364
494
            else:
17 by mbp at sourcefrog
allow --option=ARG syntax
495
                if optarg != None:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
496
                    raise BzrError('option %r takes no argument' % optname)
1 by mbp at sourcefrog
import from baz patch-364
497
                opts[optname] = True
498
        else:
499
            args.append(a)
500
501
    return args, opts
502
503
504
505
329 by Martin Pool
- refactor command functions into command classes
506
def _match_argform(cmd, takes_args, args):
1 by mbp at sourcefrog
import from baz patch-364
507
    argdict = {}
26 by mbp at sourcefrog
fix StopIteration error on python2.3(?)
508
329 by Martin Pool
- refactor command functions into command classes
509
    # step through args and takes_args, allowing appropriate 0-many matches
510
    for ap in takes_args:
1 by mbp at sourcefrog
import from baz patch-364
511
        argname = ap[:-1]
512
        if ap[-1] == '?':
62 by mbp at sourcefrog
- new find_branch_root function; based on suggestion from aaron
513
            if args:
514
                argdict[argname] = args.pop(0)
196 by mbp at sourcefrog
selected-file diff
515
        elif ap[-1] == '*': # all remaining arguments
516
            if args:
517
                argdict[argname + '_list'] = args[:]
518
                args = []
519
            else:
520
                argdict[argname + '_list'] = None
1 by mbp at sourcefrog
import from baz patch-364
521
        elif ap[-1] == '+':
522
            if not args:
329 by Martin Pool
- refactor command functions into command classes
523
                raise BzrCommandError("command %r needs one or more %s"
1 by mbp at sourcefrog
import from baz patch-364
524
                        % (cmd, argname.upper()))
525
            else:
526
                argdict[argname + '_list'] = args[:]
527
                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
528
        elif ap[-1] == '$': # all but one
529
            if len(args) < 2:
329 by Martin Pool
- refactor command functions into command classes
530
                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
531
                        % (cmd, argname.upper()))
532
            argdict[argname + '_list'] = args[:-1]
533
            args[:-1] = []                
1 by mbp at sourcefrog
import from baz patch-364
534
        else:
535
            # just a plain arg
536
            argname = ap
537
            if not args:
329 by Martin Pool
- refactor command functions into command classes
538
                raise BzrCommandError("command %r requires argument %s"
1 by mbp at sourcefrog
import from baz patch-364
539
                        % (cmd, argname.upper()))
540
            else:
541
                argdict[argname] = args.pop(0)
542
            
543
    if args:
329 by Martin Pool
- refactor command functions into command classes
544
        raise BzrCommandError("extra argument to command %s: %s"
545
                              % (cmd, args[0]))
1 by mbp at sourcefrog
import from baz patch-364
546
547
    return argdict
548
549
550
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
551
def apply_profiled(the_callable, *args, **kwargs):
552
    import hotshot
553
    import tempfile
554
    pffileno, pfname = tempfile.mkstemp()
555
    try:
556
        prof = hotshot.Profile(pfname)
557
        try:
558
            ret = prof.runcall(the_callable, *args, **kwargs) or 0
559
        finally:
560
            prof.close()
561
562
        import hotshot.stats
563
        stats = hotshot.stats.load(pfname)
564
        #stats.strip_dirs()
565
        stats.sort_stats('time')
566
        ## XXX: Might like to write to stderr or the trace file instead but
567
        ## print_stats seems hardcoded to stdout
568
        stats.print_stats(20)
569
570
        return ret
571
    finally:
572
        os.close(pffileno)
573
        os.remove(pfname)
574
575
1 by mbp at sourcefrog
import from baz patch-364
576
def run_bzr(argv):
577
    """Execute a command.
578
579
    This is similar to main(), but without all the trappings for
245 by mbp at sourcefrog
- control files always in utf-8-unix format
580
    logging and error handling.  
973 by Martin Pool
- various refactorings of command interpreter
581
    
582
    argv
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
583
       The command-line arguments, without the program name from argv[0]
973 by Martin Pool
- various refactorings of command interpreter
584
    
585
    Returns a command status or raises an exception.
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
586
587
    Special master options: these must come before the command because
588
    they control how the command is interpreted.
589
590
    --no-plugins
591
        Do not load plugin modules at all
592
593
    --builtin
594
        Only use builtin commands.  (Plugins are still allowed to change
595
        other behaviour.)
596
597
    --profile
598
        Run under the Python profiler.
1 by mbp at sourcefrog
import from baz patch-364
599
    """
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
600
    
251 by mbp at sourcefrog
- factor out locale.getpreferredencoding()
601
    argv = [a.decode(bzrlib.user_encoding) for a in argv]
973 by Martin Pool
- various refactorings of command interpreter
602
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
603
    opt_profile = opt_no_plugins = opt_builtin = False
604
605
    # --no-plugins is handled specially at a very early stage. We need
606
    # to load plugins before doing other command parsing so that they
607
    # can override commands, but this needs to happen first.
608
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
609
    for a in argv:
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
610
        if a == '--profile':
611
            opt_profile = True
612
        elif a == '--no-plugins':
613
            opt_no_plugins = True
614
        elif a == '--builtin':
615
            opt_builtin = True
616
        else:
617
            break
618
        argv.remove(a)
619
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
620
    if (not argv) or (argv[0] == '--help'):
621
        from bzrlib.help import help
622
        if len(argv) > 1:
623
            help(argv[1])
624
        else:
625
            help()
626
        return 0
627
628
    if argv[0] == '--version':
629
        from bzrlib.builtins import show_version
630
        show_version()
631
        return 0
632
        
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
633
    if not opt_no_plugins:
973 by Martin Pool
- various refactorings of command interpreter
634
        from bzrlib.plugin import load_plugins
635
        load_plugins()
636
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
637
    cmd = str(argv.pop(0))
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
638
1162 by Martin Pool
- change Command infrastructure to use (mostly stateless) objects to
639
    cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
1 by mbp at sourcefrog
import from baz patch-364
640
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
641
    if opt_profile:
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
642
        ret = apply_profiled(cmd_obj.run_argv, argv)
137 by mbp at sourcefrog
new --profile option
643
    else:
1165 by Martin Pool
- move parsing of argv into arguments and options into Command.run_argv
644
        ret = cmd_obj.run_argv(argv)
645
    return ret or 0
1 by mbp at sourcefrog
import from baz patch-364
646
647
648
def main(argv):
1104 by Martin Pool
- Add a simple UIFactory
649
    import bzrlib.ui
1111 by Martin Pool
- add functions to enable and disable default logging, so that we can
650
    bzrlib.trace.log_startup(argv)
1104 by Martin Pool
- Add a simple UIFactory
651
    bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
652
1 by mbp at sourcefrog
import from baz patch-364
653
    try:
260 by Martin Pool
- remove atexit() dependency for writing out execution times
654
        try:
1097 by Martin Pool
- send trace messages out through python logging module
655
            return run_bzr(argv[1:])
656
        finally:
657
            # do this here inside the exception wrappers to catch EPIPE
658
            sys.stdout.flush()
659
    except BzrCommandError, e:
660
        # command line syntax error, etc
661
        log_error(str(e))
662
        return 1
663
    except BzrError, e:
664
        bzrlib.trace.log_exception()
665
        return 1
666
    except AssertionError, e:
667
        bzrlib.trace.log_exception('assertion failed: ' + str(e))
668
        return 3
669
    except KeyboardInterrupt, e:
670
        bzrlib.trace.note('interrupted')
671
        return 2
672
    except Exception, e:
673
        import errno
674
        if (isinstance(e, IOError) 
675
            and hasattr(e, 'errno')
676
            and e.errno == errno.EPIPE):
677
            bzrlib.trace.note('broken pipe')
678
            return 2
679
        else:
1108 by Martin Pool
- more cleanups of error reporting
680
            bzrlib.trace.log_exception()
1097 by Martin Pool
- send trace messages out through python logging module
681
            return 2
1 by mbp at sourcefrog
import from baz patch-364
682
683
684
if __name__ == '__main__':
685
    sys.exit(main(sys.argv))