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