~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to __init__.py

  • Committer: Aaron Bentley
  • Date: 2007-11-23 15:13:59 UTC
  • Revision ID: abentley@panoramicfeedback.com-20071123151359-yrjc6ta2fkbtu9ht
Remove switch (now in bzr itself)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Aaron Bentley <aaron.bentley@utoronto.ca>
 
1
# Copyright (C) 2005, 2006, 2007 Aaron Bentley <aaron.bentley@utoronto.ca>
2
2
# Copyright (C) 2005, 2006 Canonical Limited.
3
3
# Copyright (C) 2006 Michael Ellerman.
4
4
#
22
22
 
23
23
import bzrlib
24
24
 
25
 
 
26
 
__version__ = '0.14.0'
27
 
 
28
 
 
29
 
version_info = tuple(int(n) for n in __version__.split('.'))
30
 
 
31
 
 
32
 
def check_bzrlib_version(desired):
33
 
    """Check that bzrlib is compatible.
34
 
 
35
 
    If version is < bzrtools version, assume incompatible.
36
 
    If version == bzrtools version, assume completely compatible
37
 
    If version == bzrtools version + 1, assume compatible, with deprecations
38
 
    Otherwise, assume incompatible.
39
 
    """
40
 
    desired_plus = (desired[0], desired[1]+1)
41
 
    bzrlib_version = bzrlib.version_info[:2]
42
 
    if bzrlib_version == desired:
43
 
        return
44
 
    try:
45
 
        from bzrlib.trace import warning
46
 
    except ImportError:
47
 
        # get the message out any way we can
48
 
        from warnings import warn as warning
49
 
    if bzrlib_version < desired:
50
 
        warning('Installed bzr version %s is too old to be used with bzrtools'
51
 
                ' %s.' % (bzrlib.__version__, __version__))
52
 
        # Not using BzrNewError, because it may not exist.
53
 
        raise Exception, ('Version mismatch', version_info)
54
 
    else:
55
 
        warning('Bzrtools is not up to date with installed bzr version %s.'
56
 
                ' \nThere should be a newer version available, e.g. %i.%i.' 
57
 
                % (bzrlib.__version__, bzrlib_version[0], bzrlib_version[1]))
58
 
        if bzrlib_version != desired_plus:
59
 
            raise Exception, 'Version mismatch'
60
 
 
61
 
 
62
 
check_bzrlib_version(version_info[:2])
63
 
 
64
 
 
 
25
from bzrlib.lazy_import import lazy_import
 
26
lazy_import(globals(), """
 
27
from bzrlib import help, urlutils
 
28
import shelf
 
29
""")
 
30
 
 
31
from version import version_info, __version__
 
32
from command import BzrToolsCommand
65
33
from errors import CommandError, NoPyBaz
66
34
from patchsource import BzrPatchSource
67
 
from shelf import Shelf
68
35
import sys
69
36
import os.path
70
37
 
71
38
import bzrlib.builtins
72
39
import bzrlib.commands
 
40
from bzrlib.branch import Branch
 
41
from bzrlib.bzrdir import BzrDir
73
42
from bzrlib.commands import get_cmd_object
74
43
from bzrlib.errors import BzrCommandError
75
 
from bzrlib.help import command_usage
76
44
import bzrlib.ignores
 
45
from bzrlib.trace import note
77
46
from bzrlib.option import Option
78
 
sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), 
 
47
sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__),
79
48
                                                 "external")))
80
49
 
81
50
import show_paths
 
51
from command import BzrToolsCommand
82
52
 
83
53
bzrlib.ignores.add_runtime_ignores(['./.shelf'])
84
54
 
85
55
 
86
 
class cmd_clean_tree(bzrlib.commands.Command):
 
56
class cmd_clean_tree(BzrToolsCommand):
87
57
    """Remove unwanted files from working tree.
88
58
 
89
59
    By default, only unknown files, not ignored files, are deleted.  Versioned
98
68
 
99
69
    To check what clean-tree will do, use --dry-run.
100
70
    """
101
 
    takes_options = [Option('ignored', help='delete all ignored files.'), 
102
 
                     Option('detritus', help='delete conflict files, merge'
103
 
                            ' backups, and failed selftest dirs.'), 
104
 
                     Option('unknown', 
105
 
                            help='delete files unknown to bzr.  (default)'),
106
 
                     Option('dry-run', help='show files to delete instead of'
 
71
    takes_options = [Option('ignored', help='Delete all ignored files.'),
 
72
                     Option('detritus', help='Delete conflict files, merge'
 
73
                            ' backups, and failed selftest dirs.'),
 
74
                     Option('unknown',
 
75
                            help='Delete files unknown to bzr (default).'),
 
76
                     Option('dry-run', help='Show files to delete instead of'
107
77
                            ' deleting them.')]
108
78
    def run(self, unknown=False, ignored=False, detritus=False, dry_run=False):
109
79
        from clean_tree import clean_tree
113
83
                   dry_run=dry_run)
114
84
 
115
85
 
116
 
class cmd_graph_ancestry(bzrlib.commands.Command):
 
86
class cmd_graph_ancestry(BzrToolsCommand):
117
87
    """Produce ancestry graphs using dot.
118
88
    
119
89
    Output format is detected according to file extension.  Some of the more
125
95
    with the last 5 characters of their revision identifier are used instead.
126
96
 
127
97
    The value starting with d is "(maximum) distance from the null revision".
128
 
    
 
98
 
129
99
    If --merge-branch is specified, the two branches are compared and a merge
130
100
    base is selected.
131
 
    
 
101
 
132
102
    Legend:
133
103
    white    normal revision
134
104
    yellow   THIS  history
148
118
    If available, rsvg is used to antialias PNG and JPEG output, but this can
149
119
    be disabled with --no-antialias.
150
120
    """
151
 
    takes_args = ['branch', 'file']
152
 
    takes_options = [Option('no-collapse', help="Do not skip simple nodes"), 
 
121
    takes_args = ['file', 'merge_branch?']
 
122
    takes_options = [Option('no-collapse', help="Do not skip simple nodes."),
153
123
                     Option('no-antialias',
154
 
                     help="Do not use rsvg to produce antialiased output"), 
155
 
                     Option('merge-branch', type=str, 
156
 
                     help="Use this branch to calcuate a merge base"), 
 
124
                     help="Do not use rsvg to produce antialiased output."),
 
125
                     Option('merge-branch', type=str,
 
126
                     help="Use this branch to calcuate a merge base."),
157
127
                     Option('cluster', help="Use clustered output."),
158
 
                     Option('max-distance', help="Show no nodes farther than this",
159
 
                            type=int)]
160
 
    def run(self, branch, file, no_collapse=False, no_antialias=False,
161
 
        merge_branch=None, cluster=False, max_distance=None):
 
128
                     Option('max-distance',
 
129
                            help="Show no nodes farther than this.", type=int),
 
130
                     Option('directory',
 
131
                            help='Source branch to use (default is current'
 
132
                            ' directory).',
 
133
                            short_name='d',
 
134
                            type=unicode),
 
135
                    ]
 
136
    def run(self, file, merge_branch=None, no_collapse=False,
 
137
            no_antialias=False, cluster=False, max_distance=100,
 
138
            directory='.'):
 
139
        if max_distance == -1:
 
140
            max_distance = None
162
141
        import graph
163
142
        if cluster:
164
143
            ranking = "cluster"
165
144
        else:
166
145
            ranking = "forced"
167
 
        graph.write_ancestry_file(branch, file, not no_collapse, 
168
 
                                  not no_antialias, merge_branch, ranking, 
 
146
        graph.write_ancestry_file(directory, file, not no_collapse,
 
147
                                  not no_antialias, merge_branch, ranking,
169
148
                                  max_distance=max_distance)
170
149
 
171
150
 
172
 
class cmd_fetch_ghosts(bzrlib.commands.Command):
 
151
class cmd_fetch_ghosts(BzrToolsCommand):
173
152
    """Attempt to retrieve ghosts from another branch.
174
153
    If the other branch is not supplied, the last-pulled branch is used.
175
154
    """
176
155
    aliases = ['fetch-missing']
177
156
    takes_args = ['branch?']
178
 
    takes_options = [Option('no-fix')]
 
157
    takes_options = [Option('no-fix', help="Skip additional synchonization.")]
179
158
    def run(self, branch=None, no_fix=False):
180
159
        from fetch_ghosts import fetch_ghosts
181
160
        fetch_ghosts(branch, no_fix)
184
163
each file name found in the patch file."""
185
164
 
186
165
 
187
 
class cmd_patch(bzrlib.commands.Command):
 
166
class cmd_patch(BzrToolsCommand):
188
167
    """Apply a named patch to the current tree.
189
168
    """
190
169
    takes_args = ['filename?']
191
 
    takes_options = [Option('strip', type=int, help=strip_help)]
192
 
    def run(self, filename=None, strip=None):
 
170
    takes_options = [Option('strip', type=int, help=strip_help),
 
171
                     Option('silent', help='Suppress chatter.')]
 
172
    def run(self, filename=None, strip=None, silent=False):
193
173
        from patch import patch
194
174
        from bzrlib.workingtree import WorkingTree
195
175
        wt = WorkingTree.open_containing('.')[0]
196
176
        if strip is None:
197
177
            strip = 0
198
 
        return patch(wt, filename, strip)
199
 
 
200
 
 
201
 
class cmd_shelve(bzrlib.commands.Command):
 
178
        return patch(wt, filename, strip, silent)
 
179
 
 
180
 
 
181
class cmd_shelve(BzrToolsCommand):
202
182
    """Temporarily set aside some changes from the current tree.
203
183
 
204
184
    Shelve allows you to temporarily put changes you've made "on the shelf",
229
209
    """
230
210
 
231
211
    takes_args = ['file*']
232
 
    takes_options = ['message', 'revision',
233
 
            Option('all', help='Shelve all changes without prompting'), 
234
 
            Option('no-color', help='Never display changes in color')]
 
212
    takes_options = [Option('message',
 
213
            help='A message to associate with the shelved changes.',
 
214
            short_name='m', type=unicode),
 
215
            'revision',
 
216
            Option('all', help='Shelve all changes without prompting.'),
 
217
            Option('no-color', help='Never display changes in color.')]
235
218
 
236
219
    def run(self, all=False, file_list=None, message=None, revision=None,
237
220
            no_color=False):
243
226
                                  "parameter.")
244
227
 
245
228
        source = BzrPatchSource(revision, file_list)
246
 
        s = Shelf(source.base)
 
229
        s = shelf.Shelf(source.base)
247
230
        s.shelve(source, all, message, no_color)
248
231
        return 0
249
232
 
271
254
    aliases = ['switch']
272
255
    takes_args = ['othershelf']
273
256
    def run(self, othershelf):
274
 
        s = Shelf(self.shelf.base, othershelf)
 
257
        s = shelf.Shelf(self.shelf.base, othershelf)
275
258
        s.make_default()
276
259
 
277
260
 
290
273
        self.shelf.upgrade()
291
274
 
292
275
 
293
 
class cmd_shelf(bzrlib.commands.Command):
 
276
class cmd_shelf(BzrToolsCommand):
294
277
    """Perform various operations on your shelved patches. See also shelve."""
295
278
    takes_args = ['subcommand', 'args*']
296
279
 
304
287
            args_list = []
305
288
        cmd = self._get_cmd_object(subcommand)
306
289
        source = BzrPatchSource()
307
 
        s = Shelf(source.base)
 
290
        s = shelf.Shelf(source.base)
308
291
        cmd.shelf = s
 
292
 
 
293
        if args_list is None:
 
294
            args_list = []
309
295
        return cmd.run_argv_aliases(args_list)
310
296
 
311
297
    def _get_cmd_object(self, cmd_name):
328
314
        cmd_obj = cmd_class()
329
315
        indent = 2 * ' '
330
316
 
331
 
        usage = command_usage(cmd_obj)
 
317
        usage = cmd_obj._usage()
332
318
        usage = usage.replace('bzr shelf-', '')
333
319
        text.append('%s%s\n' % (indent, usage))
334
320
 
353
339
        return text
354
340
 
355
341
 
356
 
class cmd_unshelve(bzrlib.commands.Command):
 
342
class cmd_unshelve(BzrToolsCommand):
357
343
    """Restore shelved changes.
358
344
 
359
345
    By default the most recently shelved changes are restored. However if you
362
348
    See 'shelve' for more information.
363
349
    """
364
350
    takes_options = [
365
 
            Option('all', help='Unshelve all changes without prompting'),
366
 
            Option('force', help='Force unshelving even if errors occur'),
367
 
            Option('no-color', help='Never display changes in color')
 
351
            Option('all', help='Unshelve all changes without prompting.'),
 
352
            Option('force', help='Force unshelving even if errors occur.'),
 
353
            Option('no-color', help='Never display changes in color.')
368
354
        ]
369
355
    takes_args = ['patch?']
370
356
    def run(self, patch=None, all=False, force=False, no_color=False):
371
357
        source = BzrPatchSource()
372
 
        s = Shelf(source.base)
 
358
        s = shelf.Shelf(source.base)
373
359
        s.unshelve(source, patch, all, force, no_color)
374
360
        return 0
375
361
 
376
362
 
377
 
class cmd_shell(bzrlib.commands.Command):
 
363
class cmd_shell(BzrToolsCommand):
378
364
    """Begin an interactive shell tailored for bzr.
379
365
    Bzr commands can be used without typing bzr first, and will be run natively
380
366
    when possible.  Tab completion is tailored for bzr.  The shell prompt shows
397
383
        return shell.run_shell()
398
384
 
399
385
 
400
 
class cmd_branch_history(bzrlib.commands.Command):
 
386
class cmd_branch_history(BzrToolsCommand):
401
387
    """\
402
388
    Display the development history of a branch.
403
389
 
407
393
    """
408
394
    takes_args = ["branch?"]
409
395
    def run(self, branch=None):
410
 
        from branchhistory import branch_history 
 
396
        from branchhistory import branch_history
411
397
        return branch_history(branch)
412
398
 
413
399
 
414
 
class cmd_zap(bzrlib.commands.Command):
 
400
class cmd_zap(BzrToolsCommand):
415
401
    """\
416
402
    Remove a lightweight checkout, if it can be done safely.
417
403
 
422
408
    If --branch is specified, the branch will be deleted too, but only if the
423
409
    the branch has no new commits (relative to its parent).
424
410
    """
425
 
    takes_options = [Option("branch", help="Remove associtated branch from"
426
 
                                           " repository")]
 
411
    takes_options = [Option("branch", help="Remove associated branch from"
 
412
                                           " repository."),
 
413
                     Option('force', help='Delete tree even if contents are'
 
414
                     ' modified.')]
427
415
    takes_args = ["checkout"]
428
 
    def run(self, checkout, branch=False):
 
416
    def run(self, checkout, branch=False, force=False):
429
417
        from zap import zap
430
 
        return zap(checkout, remove_branch=branch)
431
 
 
432
 
 
433
 
class cmd_cbranch(bzrlib.commands.Command):
 
418
        return zap(checkout, remove_branch=branch, allow_modified=force)
 
419
 
 
420
 
 
421
class cmd_cbranch(BzrToolsCommand):
434
422
    """
435
423
    Create a new checkout, associated with a new repository branch.
436
 
    
 
424
 
437
425
    When you cbranch, bzr looks up a target location in locations.conf, and
438
426
    creates the branch there.
439
427
 
443
431
    cbranch_target:policy = appendpath
444
432
 
445
433
    This will mean that if you run "bzr cbranch foo/bar foo/baz" in the
446
 
    working directory root, the branch will be created in 
 
434
    working directory root, the branch will be created in
447
435
    "/branch_root/foo/baz"
448
436
 
449
437
    NOTE: cbranch also supports "cbranch_root", but that behaviour is
450
438
    deprecated.
451
439
    """
452
 
    takes_options = [Option("lightweight", 
453
 
                            help="Create a lightweight checkout"), 'revision']
 
440
    takes_options = [Option("lightweight",
 
441
                            help="Create a lightweight checkout."), 'revision']
454
442
    takes_args = ["source", "target?"]
455
443
    def run(self, source, target=None, lightweight=False, revision=None):
456
444
        from cbranch import cbranch
457
 
        return cbranch(source, target, lightweight=lightweight, 
 
445
        return cbranch(source, target, lightweight=lightweight,
458
446
                       revision=revision)
459
447
 
460
448
 
461
 
class cmd_branches(bzrlib.commands.Command):
 
449
class cmd_branches(BzrToolsCommand):
462
450
    """Scan a location for branches"""
463
451
    takes_args = ["location?"]
464
452
    def run(self, location=None):
466
454
        return branches(location)
467
455
 
468
456
 
469
 
class cmd_multi_pull(bzrlib.commands.Command):
 
457
class cmd_multi_pull(BzrToolsCommand):
470
458
    """Pull all the branches under a location, e.g. a repository.
471
 
    
 
459
 
472
460
    Both branches present in the directory and the branches of checkouts are
473
461
    pulled.
474
462
    """
475
463
    takes_args = ["location?"]
476
464
    def run(self, location=None):
477
 
        from bzrlib.branch import Branch
478
465
        from bzrlib.transport import get_transport
479
466
        from bzrtools import iter_branch_tree
480
467
        if location is None:
481
468
            location = '.'
482
469
        t = get_transport(location)
 
470
        possible_transports = []
483
471
        if not t.listable():
484
472
            print "Can't list this type of location."
485
473
            return 3
501
489
                relpath = base
502
490
            print "Pulling %s from %s" % (relpath, parent)
503
491
            try:
504
 
                pullable.pull(Branch.open(parent))
 
492
                branch_t = get_transport(parent, possible_transports)
 
493
                pullable.pull(Branch.open_from_transport(branch_t))
505
494
            except Exception, e:
506
495
                print e
507
496
 
508
497
 
509
 
class cmd_branch_mark(bzrlib.commands.Command):
510
 
    """
511
 
    Add, view or list branch markers <EXPERIMENTAL>
512
 
 
513
 
    To add a mark, do 'bzr branch-mark MARK'.
514
 
    To list marks, do 'bzr branch-mark' (this lists all marks for the branch's
515
 
    repository).
516
 
    To delete a mark, do 'bzr branch-mark --delete MARK'
517
 
 
518
 
    These marks can be used to track a branch's status.
519
 
    """
520
 
    takes_args = ['mark?', 'branch?']
521
 
    takes_options = [Option('delete', help='Delete this mark')]
522
 
    def run(self, mark=None, branch=None, delete=False):
523
 
        from branch_mark import branch_mark
524
 
        branch_mark(mark, branch, delete)
525
 
 
526
 
 
527
 
class cmd_import(bzrlib.commands.Command):
 
498
class cmd_import(BzrToolsCommand):
528
499
    """Import sources from a directory, tarball or zip file
529
 
    
 
500
 
530
501
    This command will import a directory, tarball or zip file into a bzr
531
502
    tree, replacing any versioned files already present.  If a directory is
532
503
    specified, it is used as the target.  If the directory does not exist, or
537
508
    If the tarball or zip has a single root directory, that directory is
538
509
    stripped when extracting the tarball.  This is not done for directories.
539
510
    """
540
 
    
 
511
 
541
512
    takes_args = ['source', 'tree?']
542
513
    def run(self, source, tree=None):
543
514
        from upstream_import import do_import
544
515
        do_import(source, tree)
545
516
 
546
517
 
547
 
class cmd_cdiff(bzrlib.commands.Command):
 
518
class cmd_cdiff(BzrToolsCommand):
548
519
    """A color version of bzr's diff"""
549
520
    takes_args = property(lambda x: get_cmd_object('diff').takes_args)
550
 
    takes_options = property(lambda x: get_cmd_object('diff').takes_options)
551
 
    def run(*args, **kwargs):
 
521
    takes_options = list(get_cmd_object('diff').takes_options) + [
 
522
        Option('check-style',
 
523
            help='Warn if trailing whitespace or spurious changes have been'
 
524
                 ' added.')]
 
525
 
 
526
    def run(self, check_style=False, *args, **kwargs):
552
527
        from colordiff import colordiff
553
 
        colordiff(*args, **kwargs)
554
 
 
555
 
 
556
 
class cmd_baz_import(bzrlib.commands.Command):
 
528
        colordiff(check_style, *args, **kwargs)
 
529
 
 
530
 
 
531
class cmd_baz_import(BzrToolsCommand):
557
532
    """Import an Arch or Baz archive into a bzr repository.
558
533
 
559
534
    This command should be used on local archives (or mirrors) only.  It is
560
535
    quite slow on remote archives.
561
 
    
562
 
    reuse_history allows you to specify any previous imports you 
 
536
 
 
537
    reuse_history allows you to specify any previous imports you
563
538
    have done of different archives, which this archive has branches
564
 
    tagged from. This will dramatically reduce the time to convert 
 
539
    tagged from. This will dramatically reduce the time to convert
565
540
    the archive as it will not have to convert the history already
566
541
    converted in that other branch.
567
542
 
580
555
    """
581
556
    takes_args = ['to_root_dir', 'from_archive', 'reuse_history*']
582
557
    takes_options = ['verbose', Option('prefixes', type=str,
583
 
                     help="Prefixes of branches to import, colon-separated"),
584
 
                     Option('encoding', type=str, 
 
558
                     help="Prefixes of branches to import, colon-separated."),
 
559
                     Option('encoding', type=str,
585
560
                     help='Force encoding to specified value.  See WARNING.')]
586
561
 
587
562
    def run(self, to_root_dir, from_archive, encoding=None, verbose=False,
595
570
            print "This command is disabled.  Please install PyBaz."
596
571
 
597
572
 
598
 
class cmd_baz_import_branch(bzrlib.commands.Command):
 
573
class cmd_baz_import_branch(BzrToolsCommand):
599
574
    """Import an Arch or Baz branch into a bzr branch.
600
575
 
601
576
    WARNING: Encoding should not be specified unless necessary, because if you
606
581
    are incompatible.
607
582
    """
608
583
    takes_args = ['to_location', 'from_branch?', 'reuse_history*']
609
 
    takes_options = ['verbose', Option('max-count', type=int),
610
 
                     Option('encoding', type=str, 
 
584
    takes_options = ['verbose', 
 
585
                     Option('max-count', type=int, 
 
586
                     help='Maximim revisions to import at once.'),
 
587
                     Option('encoding', type=str,
611
588
                     help='Force encoding to specified value.  See WARNING.')]
612
589
 
613
590
    def run(self, to_location, from_branch=None, fast=False, max_count=None,
616
593
        from errors import NoPyBaz
617
594
        try:
618
595
            import baz_import
619
 
            baz_import.baz_import_branch(to_location, from_branch, fast, 
 
596
            baz_import.baz_import_branch(to_location, from_branch, fast,
620
597
                                         max_count, verbose, encoding, dry_run,
621
598
                                         reuse_history_list)
622
599
        except NoPyBaz:
623
600
            print "This command is disabled.  Please install PyBaz."
624
601
 
625
602
 
626
 
class cmd_rspush(bzrlib.commands.Command):
 
603
class cmd_rspush(BzrToolsCommand):
627
604
    """Upload this branch to another location using rsync.
628
605
 
629
 
    If no location is specified, the last-used location will be used.  To 
630
 
    prevent dirty trees from being uploaded, rspush will error out if there are 
631
 
    unknown files or local changes.  It will also error out if the upstream 
632
 
    directory is non-empty and not an earlier version of the branch. 
 
606
    If no location is specified, the last-used location will be used.  To
 
607
    prevent dirty trees from being uploaded, rspush will error out if there are
 
608
    unknown files or local changes.  It will also error out if the upstream
 
609
    directory is non-empty and not an earlier version of the branch.
633
610
    """
634
611
    takes_args = ['location?']
635
612
    takes_options = [Option('overwrite', help='Ignore differences between'
636
 
                            ' branches and overwrite unconditionally'),
 
613
                            ' branches and overwrite unconditionally.'),
637
614
                     Option('no-tree', help='Do not push the working tree,'
638
615
                            ' just the .bzr.')]
639
616
 
641
618
        from bzrlib import workingtree
642
619
        import bzrtools
643
620
        cur_branch = workingtree.WorkingTree.open_containing(".")[0]
644
 
        bzrtools.rspush(cur_branch, location, overwrite=overwrite, 
 
621
        bzrtools.rspush(cur_branch, location, overwrite=overwrite,
645
622
                      working_tree=not no_tree)
646
623
 
647
624
 
648
 
class cmd_switch(bzrlib.commands.Command):
649
 
    """Set the branch of a lightweight checkout and update."""
650
 
 
651
 
    takes_args = ['to_location']
652
 
 
653
 
    def run(self, to_location):
654
 
        from switch import cmd_switch
655
 
        cmd_switch().run(to_location)
656
 
 
657
 
 
658
625
commands = [
659
626
            cmd_baz_import,
660
627
            cmd_baz_import_branch,
661
628
            cmd_branches,
662
629
            cmd_branch_history,
663
 
            cmd_branch_mark,
664
 
            cmd_cbranch,  
 
630
            cmd_cbranch,
665
631
            cmd_cdiff,
666
632
            cmd_clean_tree,
667
633
            cmd_fetch_ghosts,
670
636
            cmd_multi_pull,
671
637
            cmd_patch,
672
638
            cmd_rspush,
673
 
            cmd_shelf, 
 
639
            cmd_shelf,
674
640
            cmd_shell,
675
 
            cmd_shelve, 
676
 
            cmd_switch,
677
 
            cmd_unshelve, 
678
 
            cmd_zap,            
 
641
            cmd_shelve,
 
642
            cmd_unshelve,
 
643
            cmd_zap,
679
644
            ]
680
645
 
681
646
 
691
656
    from unittest import TestSuite
692
657
    import bzrtools
693
658
    import tests.clean_tree
 
659
    import tests.is_clean
 
660
    import tests.test_rspush
694
661
    import tests.upstream_import
695
662
    import zap
696
663
    import tests.blackbox
708
675
    result.addTest(tests.blackbox.test_suite())
709
676
    result.addTest(tests.upstream_import.test_suite())
710
677
    result.addTest(zap.test_suite())
 
678
    result.addTest(TestLoader().loadTestsFromModule(tests.is_clean))
 
679
    result.addTest(TestLoader().loadTestsFromModule(tests.test_rspush))
711
680
    return result