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