~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to __init__.py

  • Committer: Charlie Shepherd
  • Date: 2007-04-04 18:12:00 UTC
  • mto: This revision was merged to the branch mainline in revision 538.
  • Revision ID: masterdriverz@gentoo.org-20070404181200-wqiwytdor9srux2v
Remove all trailing whitespace

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 Aaron Bentley <aaron@aaronbentley.com>
 
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.16.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 Bazaar version %s is too old to be used with'
 
51
                ' plugin \n'
 
52
                '"Bzrtools" %s.' % (bzrlib.__version__, __version__))
 
53
        # Not using BzrNewError, because it may not exist.
 
54
        raise Exception, ('Version mismatch', version_info)
 
55
    else:
 
56
        warning('Plugin "Bzrtools" is not up to date with installed Bazaar'
 
57
                ' version %s.\n'
 
58
                ' There should be a newer version of Bzrtools available, e.g.'
 
59
                ' %i.%i.'
 
60
                % (bzrlib.__version__, bzrlib_version[0], bzrlib_version[1]))
 
61
        if bzrlib_version != desired_plus:
 
62
            raise Exception, 'Version mismatch'
 
63
 
 
64
 
 
65
check_bzrlib_version(version_info[:2])
 
66
 
25
67
from bzrlib.lazy_import import lazy_import
26
68
lazy_import(globals(), """
27
 
from bzrlib import help, urlutils
 
69
from bzrlib import help
28
70
import shelf
29
71
""")
30
72
 
31
 
from version import version_info, __version__
32
 
from command import BzrToolsCommand
33
 
from errors import CommandError
 
73
from errors import CommandError, NoPyBaz
34
74
from patchsource import BzrPatchSource
35
75
import sys
36
76
import os.path
37
77
 
38
78
import bzrlib.builtins
39
79
import bzrlib.commands
40
 
from bzrlib.branch import Branch
41
 
from bzrlib.bzrdir import BzrDir
42
80
from bzrlib.commands import get_cmd_object
43
81
from bzrlib.errors import BzrCommandError
44
82
import bzrlib.ignores
45
 
from bzrlib.trace import note
46
83
from bzrlib.option import Option
47
84
sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__),
48
85
                                                 "external")))
49
86
 
50
87
import show_paths
51
 
from command import BzrToolsCommand
52
88
 
53
89
bzrlib.ignores.add_runtime_ignores(['./.shelf'])
54
90
 
55
91
 
56
 
class cmd_clean_tree(BzrToolsCommand):
 
92
class cmd_clean_tree(bzrlib.commands.Command):
57
93
    """Remove unwanted files from working tree.
58
94
 
59
95
    By default, only unknown files, not ignored files, are deleted.  Versioned
68
104
 
69
105
    To check what clean-tree will do, use --dry-run.
70
106
    """
71
 
    takes_options = [Option('ignored', help='Delete all ignored files.'),
72
 
                     Option('detritus', help='Delete conflict files, merge'
 
107
    takes_options = [Option('ignored', help='delete all ignored files.'),
 
108
                     Option('detritus', help='delete conflict files, merge'
73
109
                            ' backups, and failed selftest dirs.'),
74
110
                     Option('unknown',
75
 
                            help='Delete files unknown to bzr (default).'),
76
 
                     Option('dry-run', help='Show files to delete instead of'
 
111
                            help='delete files unknown to bzr.  (default)'),
 
112
                     Option('dry-run', help='show files to delete instead of'
77
113
                            ' deleting them.')]
78
114
    def run(self, unknown=False, ignored=False, detritus=False, dry_run=False):
79
115
        from clean_tree import clean_tree
80
116
        if not (unknown or ignored or detritus):
81
117
            unknown = True
82
 
        clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus, 
83
 
                   dry_run=dry_run)
84
 
 
85
 
 
86
 
class cmd_graph_ancestry(BzrToolsCommand):
 
118
        clean_tree('.', out=self.outf, unknown=unknown, ignored=ignored,
 
119
                   detritus=detritus, dry_run=dry_run)
 
120
 
 
121
 
 
122
class cmd_graph_ancestry(bzrlib.commands.Command):
87
123
    """Produce ancestry graphs using dot.
88
 
    
 
124
 
89
125
    Output format is detected according to file extension.  Some of the more
90
126
    common output formats are html, png, gif, svg, ps.  An extension of '.dot'
91
127
    will cause a dot graph file to be produced.  HTML output has mouseovers
118
154
    If available, rsvg is used to antialias PNG and JPEG output, but this can
119
155
    be disabled with --no-antialias.
120
156
    """
121
 
    takes_args = ['file', 'merge_branch?']
122
 
    takes_options = [Option('no-collapse', help="Do not skip simple nodes."),
 
157
    takes_args = ['branch', 'file']
 
158
    takes_options = [Option('no-collapse', help="Do not skip simple nodes"),
123
159
                     Option('no-antialias',
124
 
                     help="Do not use rsvg to produce antialiased output."),
 
160
                     help="Do not use rsvg to produce antialiased output"),
125
161
                     Option('merge-branch', type=str,
126
 
                     help="Use this branch to calcuate a merge base."),
 
162
                     help="Use this branch to calcuate a merge base"),
127
163
                     Option('cluster', help="Use clustered output."),
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
 
164
                     Option('max-distance', help="Show no nodes farther than this",
 
165
                            type=int)]
 
166
    def run(self, branch, file, no_collapse=False, no_antialias=False,
 
167
        merge_branch=None, cluster=False, max_distance=None):
141
168
        import graph
142
169
        if cluster:
143
170
            ranking = "cluster"
144
171
        else:
145
172
            ranking = "forced"
146
 
        graph.write_ancestry_file(directory, file, not no_collapse,
 
173
        graph.write_ancestry_file(branch, file, not no_collapse,
147
174
                                  not no_antialias, merge_branch, ranking,
148
175
                                  max_distance=max_distance)
149
176
 
150
177
 
151
 
class cmd_fetch_ghosts(BzrToolsCommand):
 
178
class cmd_fetch_ghosts(bzrlib.commands.Command):
152
179
    """Attempt to retrieve ghosts from another branch.
153
180
    If the other branch is not supplied, the last-pulled branch is used.
154
181
    """
155
182
    aliases = ['fetch-missing']
156
183
    takes_args = ['branch?']
157
 
    takes_options = [Option('no-fix', help="Skip additional synchonization.")]
 
184
    takes_options = [Option('no-fix')]
158
185
    def run(self, branch=None, no_fix=False):
159
186
        from fetch_ghosts import fetch_ghosts
160
187
        fetch_ghosts(branch, no_fix)
163
190
each file name found in the patch file."""
164
191
 
165
192
 
166
 
class cmd_patch(BzrToolsCommand):
 
193
class cmd_patch(bzrlib.commands.Command):
167
194
    """Apply a named patch to the current tree.
168
195
    """
169
196
    takes_args = ['filename?']
170
197
    takes_options = [Option('strip', type=int, help=strip_help),
171
 
                     Option('silent', help='Suppress chatter.')]
 
198
                     Option('silent', help='Suppress chatter')]
172
199
    def run(self, filename=None, strip=None, silent=False):
173
200
        from patch import patch
174
201
        from bzrlib.workingtree import WorkingTree
178
205
        return patch(wt, filename, strip, silent)
179
206
 
180
207
 
181
 
class cmd_shelve(BzrToolsCommand):
 
208
class cmd_shelve(bzrlib.commands.Command):
182
209
    """Temporarily set aside some changes from the current tree.
183
210
 
184
211
    Shelve allows you to temporarily put changes you've made "on the shelf",
209
236
    """
210
237
 
211
238
    takes_args = ['file*']
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.')]
 
239
    takes_options = ['message', 'revision',
 
240
            Option('all', help='Shelve all changes without prompting'),
 
241
            Option('no-color', help='Never display changes in color')]
218
242
 
219
243
    def run(self, all=False, file_list=None, message=None, revision=None,
220
244
            no_color=False):
273
297
        self.shelf.upgrade()
274
298
 
275
299
 
276
 
class cmd_shelf(BzrToolsCommand):
 
300
class cmd_shelf(bzrlib.commands.Command):
277
301
    """Perform various operations on your shelved patches. See also shelve."""
278
302
    takes_args = ['subcommand', 'args*']
279
303
 
314
338
        cmd_obj = cmd_class()
315
339
        indent = 2 * ' '
316
340
 
317
 
        usage = cmd_obj._usage()
 
341
        usage = help.command_usage(cmd_obj)
318
342
        usage = usage.replace('bzr shelf-', '')
319
343
        text.append('%s%s\n' % (indent, usage))
320
344
 
339
363
        return text
340
364
 
341
365
 
342
 
class cmd_unshelve(BzrToolsCommand):
 
366
class cmd_unshelve(bzrlib.commands.Command):
343
367
    """Restore shelved changes.
344
368
 
345
369
    By default the most recently shelved changes are restored. However if you
348
372
    See 'shelve' for more information.
349
373
    """
350
374
    takes_options = [
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.')
 
375
            Option('all', help='Unshelve all changes without prompting'),
 
376
            Option('force', help='Force unshelving even if errors occur'),
 
377
            Option('no-color', help='Never display changes in color')
354
378
        ]
355
379
    takes_args = ['patch?']
356
380
    def run(self, patch=None, all=False, force=False, no_color=False):
360
384
        return 0
361
385
 
362
386
 
363
 
class cmd_shell(BzrToolsCommand):
 
387
class cmd_shell(bzrlib.commands.Command):
364
388
    """Begin an interactive shell tailored for bzr.
365
389
    Bzr commands can be used without typing bzr first, and will be run natively
366
390
    when possible.  Tab completion is tailored for bzr.  The shell prompt shows
383
407
        return shell.run_shell()
384
408
 
385
409
 
386
 
class cmd_branch_history(BzrToolsCommand):
 
410
class cmd_branch_history(bzrlib.commands.Command):
387
411
    """\
388
412
    Display the development history of a branch.
389
413
 
397
421
        return branch_history(branch)
398
422
 
399
423
 
400
 
class cmd_zap(BzrToolsCommand):
 
424
class cmd_zap(bzrlib.commands.Command):
401
425
    """\
402
426
    Remove a lightweight checkout, if it can be done safely.
403
427
 
408
432
    If --branch is specified, the branch will be deleted too, but only if the
409
433
    the branch has no new commits (relative to its parent).
410
434
    """
411
 
    takes_options = [Option("branch", help="Remove associated branch from"
412
 
                                           " repository."),
413
 
                     Option('force', help='Delete tree even if contents are'
414
 
                     ' modified.')]
 
435
    takes_options = [Option("branch", help="Remove associtated branch from"
 
436
                                           " repository")]
415
437
    takes_args = ["checkout"]
416
 
    def run(self, checkout, branch=False, force=False):
 
438
    def run(self, checkout, branch=False):
417
439
        from zap import zap
418
 
        return zap(checkout, remove_branch=branch, allow_modified=force)
419
 
 
420
 
 
421
 
class cmd_cbranch(BzrToolsCommand):
 
440
        return zap(checkout, remove_branch=branch)
 
441
 
 
442
 
 
443
class cmd_cbranch(bzrlib.commands.Command):
422
444
    """
423
445
    Create a new checkout, associated with a new repository branch.
424
446
 
438
460
    deprecated.
439
461
    """
440
462
    takes_options = [Option("lightweight",
441
 
                            help="Create a lightweight checkout."), 'revision',
442
 
                     Option('files-from', type=unicode,
443
 
                            help='Accelerate checkout using files from this'
444
 
                                 ' tree.'),
445
 
                     Option('hardlink',
446
 
                            help='Hard-link files from source/files-from tree'
447
 
                            ' where posible.')]
 
463
                            help="Create a lightweight checkout"), 'revision']
448
464
    takes_args = ["source", "target?"]
449
 
    def run(self, source, target=None, lightweight=False, revision=None,
450
 
            files_from=None, hardlink=False):
 
465
    def run(self, source, target=None, lightweight=False, revision=None):
451
466
        from cbranch import cbranch
452
467
        return cbranch(source, target, lightweight=lightweight,
453
 
                       revision=revision, files_from=files_from,
454
 
                       hardlink=hardlink)
455
 
 
456
 
 
457
 
class cmd_branches(BzrToolsCommand):
 
468
                       revision=revision)
 
469
 
 
470
 
 
471
class cmd_branches(bzrlib.commands.Command):
458
472
    """Scan a location for branches"""
459
473
    takes_args = ["location?"]
460
474
    def run(self, location=None):
461
475
        from branches import branches
462
476
        return branches(location)
463
477
 
464
 
class cmd_trees(BzrToolsCommand):
465
 
    """Scan a location for trees"""
466
 
    takes_args = ['location?']
467
 
    def run(self, location='.'):
468
 
        from bzrlib.workingtree import WorkingTree
469
 
        from bzrlib.transport import get_transport
470
 
        t = get_transport(location)
471
 
        for tree in WorkingTree.find_trees(location):
472
 
            self.outf.write('%s\n' % t.relpath(
473
 
                tree.bzrdir.root_transport.base))
474
478
 
475
 
class cmd_multi_pull(BzrToolsCommand):
 
479
class cmd_multi_pull(bzrlib.commands.Command):
476
480
    """Pull all the branches under a location, e.g. a repository.
477
481
 
478
482
    Both branches present in the directory and the branches of checkouts are
480
484
    """
481
485
    takes_args = ["location?"]
482
486
    def run(self, location=None):
 
487
        from bzrlib.branch import Branch
483
488
        from bzrlib.transport import get_transport
484
489
        from bzrtools import iter_branch_tree
485
490
        if location is None:
486
491
            location = '.'
487
492
        t = get_transport(location)
488
 
        possible_transports = []
489
493
        if not t.listable():
490
494
            print "Can't list this type of location."
491
495
            return 3
507
511
                relpath = base
508
512
            print "Pulling %s from %s" % (relpath, parent)
509
513
            try:
510
 
                branch_t = get_transport(parent, possible_transports)
511
 
                pullable.pull(Branch.open_from_transport(branch_t))
 
514
                pullable.pull(Branch.open(parent))
512
515
            except Exception, e:
513
516
                print e
514
517
 
515
518
 
516
 
 
517
 
class cmd_import(BzrToolsCommand):
 
519
class cmd_branch_mark(bzrlib.commands.Command):
 
520
    """
 
521
    Add, view or list branch markers <EXPERIMENTAL>
 
522
 
 
523
    To add a mark, do 'bzr branch-mark MARK'.
 
524
    To list marks, do 'bzr branch-mark' (this lists all marks for the branch's
 
525
    repository).
 
526
    To delete a mark, do 'bzr branch-mark --delete MARK'
 
527
 
 
528
    These marks can be used to track a branch's status.
 
529
    """
 
530
    takes_args = ['mark?', 'branch?']
 
531
    takes_options = [Option('delete', help='Delete this mark')]
 
532
    def run(self, mark=None, branch=None, delete=False):
 
533
        from branch_mark import branch_mark
 
534
        branch_mark(mark, branch, delete)
 
535
 
 
536
 
 
537
class cmd_import(bzrlib.commands.Command):
518
538
    """Import sources from a directory, tarball or zip file
519
539
 
520
540
    This command will import a directory, tarball or zip file into a bzr
534
554
        do_import(source, tree)
535
555
 
536
556
 
537
 
class cmd_cdiff(BzrToolsCommand):
 
557
class cmd_cdiff(bzrlib.commands.Command):
538
558
    """A color version of bzr's diff"""
539
559
    takes_args = property(lambda x: get_cmd_object('diff').takes_args)
540
 
    takes_options = list(get_cmd_object('diff').takes_options) + [
541
 
        Option('check-style',
 
560
 
 
561
    def _takes_options(self):
 
562
        options = list(get_cmd_object('diff').takes_options)
 
563
        options.append(Option('check-style',
542
564
            help='Warn if trailing whitespace or spurious changes have been'
543
 
                 ' added.')]
 
565
                 ' added.'))
 
566
        return options
 
567
 
 
568
    takes_options = property(_takes_options)
544
569
 
545
570
    def run(self, check_style=False, *args, **kwargs):
546
571
        from colordiff import colordiff
547
572
        colordiff(check_style, *args, **kwargs)
548
573
 
549
574
 
550
 
class cmd_rspush(BzrToolsCommand):
 
575
class cmd_baz_import(bzrlib.commands.Command):
 
576
    """Import an Arch or Baz archive into a bzr repository.
 
577
 
 
578
    This command should be used on local archives (or mirrors) only.  It is
 
579
    quite slow on remote archives.
 
580
 
 
581
    reuse_history allows you to specify any previous imports you
 
582
    have done of different archives, which this archive has branches
 
583
    tagged from. This will dramatically reduce the time to convert
 
584
    the archive as it will not have to convert the history already
 
585
    converted in that other branch.
 
586
 
 
587
    If you specify prefixes, only branches whose names start with that prefix
 
588
    will be imported.  Skipped branches will be listed, so you can import any
 
589
    branches you missed by accident.  Here's an example of doing a partial
 
590
    import from thelove@canonical.com:
 
591
    bzr baz-import thelove thelove@canonical.com --prefixes dists:talloc-except
 
592
 
 
593
    WARNING: Encoding should not be specified unless necessary, because if you
 
594
    specify an encoding, your converted branch will not interoperate with
 
595
    independently-converted branches, unless the other branches were converted
 
596
    with exactly the same encoding.  Any encoding recognized by Python may
 
597
    be specified.  Aliases are not detected, so 'utf_8', 'U8', 'UTF' and 'utf8'
 
598
    are incompatible.
 
599
    """
 
600
    takes_args = ['to_root_dir', 'from_archive', 'reuse_history*']
 
601
    takes_options = ['verbose', Option('prefixes', type=str,
 
602
                     help="Prefixes of branches to import, colon-separated"),
 
603
                     Option('encoding', type=str,
 
604
                     help='Force encoding to specified value.  See WARNING.')]
 
605
 
 
606
    def run(self, to_root_dir, from_archive, encoding=None, verbose=False,
 
607
            reuse_history_list=[], prefixes=None):
 
608
        from errors import NoPyBaz
 
609
        try:
 
610
            import baz_import
 
611
            baz_import.baz_import(to_root_dir, from_archive, encoding,
 
612
                                  verbose, reuse_history_list, prefixes)
 
613
        except NoPyBaz:
 
614
            print "This command is disabled.  Please install PyBaz."
 
615
 
 
616
 
 
617
class cmd_baz_import_branch(bzrlib.commands.Command):
 
618
    """Import an Arch or Baz branch into a bzr branch.
 
619
 
 
620
    WARNING: Encoding should not be specified unless necessary, because if you
 
621
    specify an encoding, your converted branch will not interoperate with
 
622
    independently-converted branches, unless the other branches were converted
 
623
    with exactly the same encoding.  Any encoding recognized by Python may
 
624
    be specified.  Aliases are not detected, so 'utf_8', 'U8', 'UTF' and 'utf8'
 
625
    are incompatible.
 
626
    """
 
627
    takes_args = ['to_location', 'from_branch?', 'reuse_history*']
 
628
    takes_options = ['verbose', Option('max-count', type=int),
 
629
                     Option('encoding', type=str,
 
630
                     help='Force encoding to specified value.  See WARNING.')]
 
631
 
 
632
    def run(self, to_location, from_branch=None, fast=False, max_count=None,
 
633
            encoding=None, verbose=False, dry_run=False,
 
634
            reuse_history_list=[]):
 
635
        from errors import NoPyBaz
 
636
        try:
 
637
            import baz_import
 
638
            baz_import.baz_import_branch(to_location, from_branch, fast,
 
639
                                         max_count, verbose, encoding, dry_run,
 
640
                                         reuse_history_list)
 
641
        except NoPyBaz:
 
642
            print "This command is disabled.  Please install PyBaz."
 
643
 
 
644
 
 
645
class cmd_rspush(bzrlib.commands.Command):
551
646
    """Upload this branch to another location using rsync.
552
647
 
553
648
    If no location is specified, the last-used location will be used.  To
557
652
    """
558
653
    takes_args = ['location?']
559
654
    takes_options = [Option('overwrite', help='Ignore differences between'
560
 
                            ' branches and overwrite unconditionally.'),
 
655
                            ' branches and overwrite unconditionally'),
561
656
                     Option('no-tree', help='Do not push the working tree,'
562
657
                            ' just the .bzr.')]
563
658
 
569
664
                      working_tree=not no_tree)
570
665
 
571
666
 
572
 
class cmd_link_tree(BzrToolsCommand):
573
 
    """Hardlink matching files to another tree.
574
 
 
575
 
    Only files with identical content and execute bit will be linked.
576
 
    """
577
 
    takes_args = ['location']
578
 
 
579
 
    def run(self, location):
580
 
        from bzrlib import workingtree
581
 
        from bzrlib.plugins.bzrtools.link_tree import link_tree
582
 
        target_tree = workingtree.WorkingTree.open_containing(".")[0]
583
 
        source_tree = workingtree.WorkingTree.open(location)
584
 
        target_tree.lock_write()
585
 
        try:
586
 
            source_tree.lock_read()
587
 
            try:
588
 
                link_tree(target_tree, source_tree)
589
 
            finally:
590
 
                source_tree.unlock()
591
 
        finally:
592
 
            target_tree.unlock()
593
 
 
594
 
from heads import cmd_heads
 
667
class cmd_switch(bzrlib.commands.Command):
 
668
    """Set the branch of a lightweight checkout and update."""
 
669
 
 
670
    takes_args = ['to_location']
 
671
 
 
672
    def run(self, to_location):
 
673
        from switch import cmd_switch
 
674
        cmd_switch().run(to_location)
 
675
 
 
676
 
595
677
commands = [
 
678
            cmd_baz_import,
 
679
            cmd_baz_import_branch,
596
680
            cmd_branches,
597
681
            cmd_branch_history,
 
682
            cmd_branch_mark,
598
683
            cmd_cbranch,
599
684
            cmd_cdiff,
600
685
            cmd_clean_tree,
601
686
            cmd_fetch_ghosts,
602
687
            cmd_graph_ancestry,
603
 
            cmd_heads,
604
688
            cmd_import,
605
 
            cmd_link_tree,
606
689
            cmd_multi_pull,
607
690
            cmd_patch,
608
691
            cmd_rspush,
609
692
            cmd_shelf,
610
693
            cmd_shell,
611
694
            cmd_shelve,
612
 
            cmd_trees,
 
695
            cmd_switch,
613
696
            cmd_unshelve,
614
697
            cmd_zap,
615
698
            ]
627
710
    from unittest import TestSuite
628
711
    import bzrtools
629
712
    import tests.clean_tree
630
 
    import tests.test_dotgraph
631
713
    import tests.is_clean
632
 
    import tests.test_cbranch
633
 
    import tests.test_link_tree
634
 
    import tests.test_patch
635
 
    import tests.test_rspush
636
714
    import tests.upstream_import
637
715
    import zap
638
716
    import tests.blackbox
640
718
    result = TestSuite()
641
719
    result.addTest(DocTestSuite(bzrtools, optionflags=ELLIPSIS))
642
720
    result.addTest(tests.clean_tree.test_suite())
 
721
    try:
 
722
        import baz_import
 
723
        result.addTest(DocTestSuite(baz_import))
 
724
    except NoPyBaz:
 
725
        pass
643
726
    result.addTest(tests.test_suite())
644
727
    result.addTest(TestLoader().loadTestsFromModule(tests.shelf_tests))
645
728
    result.addTest(tests.blackbox.test_suite())
646
729
    result.addTest(tests.upstream_import.test_suite())
647
730
    result.addTest(zap.test_suite())
648
 
    result.addTest(TestLoader().loadTestsFromModule(tests.test_dotgraph))
649
731
    result.addTest(TestLoader().loadTestsFromModule(tests.is_clean))
650
 
    result.addTest(TestLoader().loadTestsFromModule(tests.test_link_tree))
651
 
    result.addTest(TestLoader().loadTestsFromModule(tests.test_patch))
652
 
    result.addTest(TestLoader().loadTestsFromModule(tests.test_rspush))
653
 
    result.addTest(TestLoader().loadTestsFromModule(tests.test_cbranch))
654
732
    return result