~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

add a clean target

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
# Those objects can specify the expected type of the argument, which
25
25
# would help with validation and shell completion.
26
26
 
27
 
# TODO: "--profile=cum", to change sort order.  Is there any value in leaving
28
 
# the profile output behind so it can be interactively examined?
 
27
 
 
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
 
29
35
 
30
36
import sys
31
37
import os
36
42
import bzrlib.trace
37
43
from bzrlib.trace import mutter, note, log_error, warning
38
44
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError, NotBranchError
39
 
from bzrlib.revisionspec import RevisionSpec
 
45
from bzrlib.branch import find_branch
40
46
from bzrlib import BZRDIR
41
47
 
42
48
plugin_cmds = {}
70
76
def _parse_revision_str(revstr):
71
77
    """This handles a revision string -> revno.
72
78
 
73
 
    This always returns a list.  The list will have one element for
74
 
    each revision.
 
79
    This always returns a list.  The list will have one element for 
 
80
 
 
81
    It supports integers directly, but everything else it
 
82
    defers for passing to Branch.get_revision_info()
75
83
 
76
84
    >>> _parse_revision_str('234')
77
 
    [<RevisionSpec_int 234>]
 
85
    [234]
78
86
    >>> _parse_revision_str('234..567')
79
 
    [<RevisionSpec_int 234>, <RevisionSpec_int 567>]
 
87
    [234, 567]
80
88
    >>> _parse_revision_str('..')
81
 
    [<RevisionSpec None>, <RevisionSpec None>]
 
89
    [None, None]
82
90
    >>> _parse_revision_str('..234')
83
 
    [<RevisionSpec None>, <RevisionSpec_int 234>]
 
91
    [None, 234]
84
92
    >>> _parse_revision_str('234..')
85
 
    [<RevisionSpec_int 234>, <RevisionSpec None>]
 
93
    [234, None]
86
94
    >>> _parse_revision_str('234..456..789') # Maybe this should be an error
87
 
    [<RevisionSpec_int 234>, <RevisionSpec_int 456>, <RevisionSpec_int 789>]
 
95
    [234, 456, 789]
88
96
    >>> _parse_revision_str('234....789') # Error?
89
 
    [<RevisionSpec_int 234>, <RevisionSpec None>, <RevisionSpec_int 789>]
 
97
    [234, None, 789]
90
98
    >>> _parse_revision_str('revid:test@other.com-234234')
91
 
    [<RevisionSpec_revid revid:test@other.com-234234>]
 
99
    ['revid:test@other.com-234234']
92
100
    >>> _parse_revision_str('revid:test@other.com-234234..revid:test@other.com-234235')
93
 
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_revid revid:test@other.com-234235>]
 
101
    ['revid:test@other.com-234234', 'revid:test@other.com-234235']
94
102
    >>> _parse_revision_str('revid:test@other.com-234234..23')
95
 
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_int 23>]
 
103
    ['revid:test@other.com-234234', 23]
96
104
    >>> _parse_revision_str('date:2005-04-12')
97
 
    [<RevisionSpec_date date:2005-04-12>]
 
105
    ['date:2005-04-12']
98
106
    >>> _parse_revision_str('date:2005-04-12 12:24:33')
99
 
    [<RevisionSpec_date date:2005-04-12 12:24:33>]
 
107
    ['date:2005-04-12 12:24:33']
100
108
    >>> _parse_revision_str('date:2005-04-12T12:24:33')
101
 
    [<RevisionSpec_date date:2005-04-12T12:24:33>]
 
109
    ['date:2005-04-12T12:24:33']
102
110
    >>> _parse_revision_str('date:2005-04-12,12:24:33')
103
 
    [<RevisionSpec_date date:2005-04-12,12:24:33>]
 
111
    ['date:2005-04-12,12:24:33']
104
112
    >>> _parse_revision_str('-5..23')
105
 
    [<RevisionSpec_int -5>, <RevisionSpec_int 23>]
 
113
    [-5, 23]
106
114
    >>> _parse_revision_str('-5')
107
 
    [<RevisionSpec_int -5>]
 
115
    [-5]
108
116
    >>> _parse_revision_str('123a')
109
 
    Traceback (most recent call last):
110
 
      ...
111
 
    BzrError: No namespace registered for string: '123a'
 
117
    ['123a']
112
118
    >>> _parse_revision_str('abc')
113
 
    Traceback (most recent call last):
114
 
      ...
115
 
    BzrError: No namespace registered for string: 'abc'
 
119
    ['abc']
116
120
    """
117
121
    import re
118
122
    old_format_re = re.compile('\d*:\d*')
119
123
    m = old_format_re.match(revstr)
120
 
    revs = []
121
124
    if m:
122
125
        warning('Colon separator for revision numbers is deprecated.'
123
126
                ' Use .. instead')
 
127
        revs = []
124
128
        for rev in revstr.split(':'):
125
129
            if rev:
126
 
                revs.append(RevisionSpec(int(rev)))
127
 
            else:
128
 
                revs.append(RevisionSpec(None))
129
 
    else:
130
 
        for x in revstr.split('..'):
131
 
            if not x:
132
 
                revs.append(RevisionSpec(None))
133
 
            else:
134
 
                revs.append(RevisionSpec(x))
 
130
                revs.append(int(rev))
 
131
            else:
 
132
                revs.append(None)
 
133
        return revs
 
134
    revs = []
 
135
    for x in revstr.split('..'):
 
136
        if not x:
 
137
            revs.append(None)
 
138
        else:
 
139
            try:
 
140
                revs.append(int(x))
 
141
            except ValueError:
 
142
                revs.append(x)
135
143
    return revs
136
144
 
137
145
 
 
146
def get_merge_type(typestring):
 
147
    """Attempt to find the merge class/factory associated with a string."""
 
148
    from merge import merge_types
 
149
    try:
 
150
        return merge_types[typestring][0]
 
151
    except KeyError:
 
152
        templ = '%s%%7s: %%s' % (' '*12)
 
153
        lines = [templ % (f[0], f[1][1]) for f in merge_types.iteritems()]
 
154
        type_list = '\n'.join(lines)
 
155
        msg = "No known merge type %s. Supported types are:\n%s" %\
 
156
            (typestring, type_list)
 
157
        raise BzrCommandError(msg)
 
158
 
 
159
 
138
160
def _builtin_commands():
139
161
    import bzrlib.builtins
140
162
    r = {}
332
354
# the type.
333
355
OPTIONS = {
334
356
    'all':                    None,
335
 
    'basis':                  str,
336
357
    'diff-options':           str,
337
358
    'help':                   None,
338
359
    'file':                   unicode,
354
375
    'long':                   None,
355
376
    'root':                   str,
356
377
    'no-backup':              None,
 
378
    'merge-type':             get_merge_type,
357
379
    'pattern':                str,
358
380
    }
359
381
 
386
408
    >>> parse_args('commit --message=biter'.split())
387
409
    (['commit'], {'message': u'biter'})
388
410
    >>> parse_args('log -r 500'.split())
389
 
    (['log'], {'revision': [<RevisionSpec_int 500>]})
 
411
    (['log'], {'revision': [500]})
390
412
    >>> parse_args('log -r500..600'.split())
391
 
    (['log'], {'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
 
413
    (['log'], {'revision': [500, 600]})
392
414
    >>> parse_args('log -vr500..600'.split())
393
 
    (['log'], {'verbose': True, 'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
394
 
    >>> parse_args('log -rrevno:500..600'.split()) #the r takes an argument
395
 
    (['log'], {'revision': [<RevisionSpec_revno revno:500>, <RevisionSpec_int 600>]})
 
415
    (['log'], {'verbose': True, 'revision': [500, 600]})
 
416
    >>> parse_args('log -rv500..600'.split()) #the r takes an argument
 
417
    (['log'], {'revision': ['v500', 600]})
396
418
    """
397
419
    args = []
398
420
    opts = {}
519
541
def apply_profiled(the_callable, *args, **kwargs):
520
542
    import hotshot
521
543
    import tempfile
522
 
    import hotshot.stats
523
544
    pffileno, pfname = tempfile.mkstemp()
524
545
    try:
525
546
        prof = hotshot.Profile(pfname)
527
548
            ret = prof.runcall(the_callable, *args, **kwargs) or 0
528
549
        finally:
529
550
            prof.close()
 
551
 
 
552
        import hotshot.stats
530
553
        stats = hotshot.stats.load(pfname)
531
 
        stats.strip_dirs()
532
 
        stats.sort_stats('cum')   # 'time'
 
554
        #stats.strip_dirs()
 
555
        stats.sort_stats('time')
533
556
        ## XXX: Might like to write to stderr or the trace file instead but
534
557
        ## print_stats seems hardcoded to stdout
535
558
        stats.print_stats(20)
 
559
 
536
560
        return ret
537
561
    finally:
538
562
        os.close(pffileno)
563
587
    --profile
564
588
        Run under the Python profiler.
565
589
    """
566
 
    # Load all of the transport methods
567
 
    import bzrlib.transport.local, bzrlib.transport.http
568
590
    
569
591
    argv = [a.decode(bzrlib.user_encoding) for a in argv]
570
592
 
618
640
    bzrlib.trace.log_startup(argv)
619
641
    bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
620
642
 
621
 
    return run_bzr_catch_errors(argv[1:])
622
 
 
623
 
 
624
 
def run_bzr_catch_errors(argv):
625
643
    try:
626
644
        try:
627
 
            return run_bzr(argv)
628
 
        finally:
629
 
            # do this here inside the exception wrappers to catch EPIPE
630
 
            sys.stdout.flush()
 
645
            try:
 
646
                return run_bzr(argv[1:])
 
647
            finally:
 
648
                # do this here inside the exception wrappers to catch EPIPE
 
649
                sys.stdout.flush()
 
650
        #wrap common errors as CommandErrors.
 
651
        except (NotBranchError,), e:
 
652
            raise BzrCommandError(str(e))
631
653
    except BzrCommandError, e:
632
654
        # command line syntax error, etc
633
655
        log_error(str(e))
639
661
        bzrlib.trace.log_exception('assertion failed: ' + str(e))
640
662
        return 3
641
663
    except KeyboardInterrupt, e:
642
 
        bzrlib.trace.log_exception('interrupted')
 
664
        bzrlib.trace.note('interrupted')
643
665
        return 2
644
666
    except Exception, e:
645
667
        import errno
649
671
            bzrlib.trace.note('broken pipe')
650
672
            return 2
651
673
        else:
652
 
            ## import pdb
653
 
            ## pdb.pm()
654
674
            bzrlib.trace.log_exception()
655
675
            return 2
656
676
 
 
677
 
657
678
if __name__ == '__main__':
658
679
    sys.exit(main(sys.argv))