/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz

« back to all changes in this revision

Viewing changes to __init__.py

  • Committer: Jelmer Vernooij
  • Date: 2007-04-03 17:16:07 UTC
  • mfrom: (187 trunk)
  • mto: This revision was merged to the branch mainline in revision 188.
  • Revision ID: jelmer@samba.org-20070403171607-0zaskazouokrm4cq
Tags: bzr-gtk-0.15.2
PrepareĀ forĀ 0.15.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
# along with this program; if not, write to the Free Software
13
13
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14
14
 
15
 
"""Graphical support for Bazaar using GTK.
16
 
 
17
 
This plugin includes:
18
 
gannotate         GTK+ annotate. 
19
 
gbranch           GTK+ branching. 
20
 
gcheckout         GTK+ checkout. 
21
 
gcommit           GTK+ commit dialog.
22
 
gconflicts        GTK+ conflicts. 
23
 
gdiff             Show differences in working tree in a GTK+ Window. 
24
 
ginit             Initialise a new branch.
25
 
ginfo             GTK+ branch info dialog
26
 
gloom             GTK+ loom browse dialog
27
 
gmerge            GTK+ merge dialog
28
 
gmissing          GTK+ missing revisions dialog. 
29
 
gpreferences      GTK+ preferences dialog. 
30
 
gpush             GTK+ push.
31
 
gsend             GTK+ send merge directive.
32
 
gstatus           GTK+ status dialog.
33
 
gtags             Manage branch tags.
34
 
visualise         Graphically visualise this branch. 
35
 
"""
36
 
 
37
 
import os
38
 
import sys
39
 
 
40
 
if getattr(sys, "frozen", None) is not None: # we run bzr.exe
41
 
 
42
 
    # FIXME: Unless a better packaging solution is found, the following
43
 
    # provides a workaround for https://bugs.launchpad.net/bzr/+bug/388790 Also
44
 
    # see https://code.edge.launchpad.net/~vila/bzr-gtk/388790-windows-setup
45
 
    # for more details about while it's needed.
46
 
 
47
 
    # NOTE: _lib must be ahead of bzrlib or sax.saxutils (in olive) fails
48
 
    here = os.path.dirname(__file__)
49
 
    sys.path.insert(0, os.path.join(here, '_lib'))
50
 
    sys.path.append(os.path.join(here, '_lib/gtk-2.0'))
51
 
 
 
15
"""GTK+ frontends to Bazaar commands """
52
16
 
53
17
import bzrlib
54
 
import bzrlib.api
 
18
 
 
19
__version__ = '0.15.2'
 
20
version_info = tuple(int(n) for n in __version__.split('.'))
 
21
 
 
22
 
 
23
def check_bzrlib_version(desired):
 
24
    """Check that bzrlib is compatible.
 
25
 
 
26
    If version is < bzr-gtk version, assume incompatible.
 
27
    If version == bzr-gtk version, assume completely compatible
 
28
    If version == bzr-gtk version + 1, assume compatible, with deprecations
 
29
    Otherwise, assume incompatible.
 
30
    """
 
31
    desired_plus = (desired[0], desired[1]+1)
 
32
    bzrlib_version = bzrlib.version_info[:2]
 
33
    if bzrlib_version == desired:
 
34
        return
 
35
    try:
 
36
        from bzrlib.trace import warning
 
37
    except ImportError:
 
38
        # get the message out any way we can
 
39
        from warnings import warn as warning
 
40
    if bzrlib_version < desired:
 
41
        warning('Installed bzr version %s is too old to be used with bzr-gtk'
 
42
                ' %s.' % (bzrlib.__version__, __version__))
 
43
        # Not using BzrNewError, because it may not exist.
 
44
        raise Exception, ('Version mismatch', version_info)
 
45
    else:
 
46
        warning('bzr-gtk is not up to date with installed bzr version %s.'
 
47
                ' \nThere should be a newer version available, e.g. %i.%i.' 
 
48
                % (bzrlib.__version__, bzrlib_version[0], bzrlib_version[1]))
 
49
        if bzrlib_version != desired_plus:
 
50
            raise Exception, 'Version mismatch'
 
51
 
 
52
 
 
53
check_bzrlib_version(version_info[:2])
 
54
 
 
55
from bzrlib.trace import warning
 
56
if __name__ != 'bzrlib.plugins.gtk':
 
57
    warning("Not running as bzrlib.plugins.gtk, things may break.")
 
58
 
 
59
from bzrlib.lazy_import import lazy_import
 
60
lazy_import(globals(), """
55
61
from bzrlib import (
56
62
    branch,
57
 
    config,
58
63
    errors,
 
64
    workingtree,
59
65
    )
60
 
from bzrlib.commands import plugin_cmds
61
 
 
62
 
 
63
 
version_info = (0, 99, 0, 'dev', 1)
64
 
 
65
 
if version_info[3] == 'final':
66
 
    version_string = '%d.%d.%d' % version_info[:3]
67
 
else:
68
 
    version_string = '%d.%d.%d%s%d' % version_info
69
 
__version__ = version_string
70
 
 
71
 
COMPATIBLE_BZR_VERSIONS = [(1, 6, 0), (1, 7, 0), (1, 8, 0), (1, 9, 0),
72
 
                           (1, 10, 0), (1, 11, 0), (1, 12, 0), (1, 13, 0),
73
 
                           (1, 15, 0),
74
 
                           (1, 17, 0),
75
 
                           (2, 1, 0),
76
 
                           (2, 2, 0),
77
 
                           ]
78
 
 
79
 
bzrlib.api.require_any_api(bzrlib, COMPATIBLE_BZR_VERSIONS)
80
 
 
81
 
if __name__ != 'bzrlib.plugins.gtk':
82
 
    from bzrlib.trace import warning
83
 
    warning("Not running as bzrlib.plugins.gtk, things may break.")
 
66
""")
 
67
 
 
68
from bzrlib.commands import Command, register_command, display_command
 
69
from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
 
70
from bzrlib.option import Option
 
71
 
 
72
import os.path
84
73
 
85
74
def import_pygtk():
86
75
    try:
98
87
    bzrlib.ui.ui_factory = GtkUIFactory()
99
88
 
100
89
 
101
 
def data_basedirs():
102
 
    return [os.path.dirname(__file__),
103
 
             "/usr/share/bzr-gtk", 
104
 
             "/usr/local/share/bzr-gtk"]
105
 
 
106
 
 
107
 
def data_path(*args):
108
 
    for basedir in data_basedirs():
109
 
        path = os.path.join(basedir, *args)
110
 
        if os.path.exists(path):
111
 
            return path
112
 
    return None
113
 
 
114
 
 
115
 
def icon_path(*args):
116
 
    return data_path(os.path.join('icons', *args))
117
 
 
118
 
 
119
 
def open_display():
120
 
    pygtk = import_pygtk()
121
 
    try:
122
 
        import gtk
123
 
    except RuntimeError, e:
124
 
        if str(e) == "could not open display":
125
 
            raise NoDisplayError
126
 
    set_ui_factory()
127
 
    return gtk
128
 
 
129
 
 
130
 
commands = {
131
 
    "gannotate": ["gblame", "gpraise"],
132
 
    "gbranch": [],
133
 
    "gcheckout": [],
134
 
    "gcommit": ["gci"],
135
 
    "gconflicts": [],
136
 
    "gdiff": [],
137
 
    "ginit": [],
138
 
    "ginfo": [],
139
 
    "gmerge": [],
140
 
    "gmissing": [],
141
 
    "gpreferences": [],
142
 
    "gpush": [],
143
 
    "gselftest": [],
144
 
    "gsend": [],
145
 
    "gstatus": ["gst"],
146
 
    "gtags": [],
147
 
    "visualise": ["visualize", "vis", "viz", 'glog'],
148
 
    }
149
 
 
150
 
try:
151
 
    from bzrlib.plugins import loom
152
 
except ImportError:
153
 
    pass # Loom plugin doesn't appear to be present
154
 
else:
155
 
    commands["gloom"] = []
156
 
 
157
 
for cmd, aliases in commands.iteritems():
158
 
    plugin_cmds.register_lazy("cmd_%s" % cmd, aliases,
159
 
                              "bzrlib.plugins.gtk.commands")
160
 
 
161
 
def save_commit_messages(*args):
162
 
    from bzrlib.plugins.gtk import commit
163
 
    commit.save_commit_messages(*args)
164
 
 
165
 
branch.Branch.hooks.install_named_hook('post_uncommit',
166
 
                                       save_commit_messages,
167
 
                                       "Saving commit messages for gcommit")
 
90
class GTKCommand(Command):
 
91
    """Abstract class providing GTK specific run commands."""
 
92
 
 
93
    def open_display(self):
 
94
        pygtk = import_pygtk()
 
95
        try:
 
96
            import gtk
 
97
        except RuntimeError, e:
 
98
            if str(e) == "could not open display":
 
99
                raise NoDisplayError
 
100
        set_ui_factory()
 
101
        return gtk
 
102
 
 
103
    def run(self):
 
104
        self.open_display()
 
105
        dialog = self.get_gtk_dialog(os.path.abspath('.'))
 
106
        dialog.run()
 
107
 
 
108
 
 
109
class cmd_gbranch(GTKCommand):
 
110
    """GTK+ branching.
 
111
    
 
112
    """
 
113
 
 
114
    def get_gtk_dialog(self, path):
 
115
        from bzrlib.plugins.gtk.branch import BranchDialog
 
116
        return BranchDialog(path)
 
117
 
 
118
 
 
119
class cmd_gcheckout(GTKCommand):
 
120
    """ GTK+ checkout.
 
121
    
 
122
    """
 
123
    
 
124
    def get_gtk_dialog(self, path):
 
125
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
 
126
        return CheckoutDialog(path)
 
127
 
 
128
 
 
129
 
 
130
class cmd_gpush(GTKCommand):
 
131
    """ GTK+ push.
 
132
    
 
133
    """
 
134
    takes_args = [ "location?" ]
 
135
 
 
136
    def run(self, location="."):
 
137
        (br, path) = branch.Branch.open_containing(location)
 
138
        self.open_display()
 
139
        from push import PushDialog
 
140
        dialog = PushDialog(br)
 
141
        dialog.run()
 
142
 
 
143
 
 
144
 
 
145
class cmd_gdiff(GTKCommand):
 
146
    """Show differences in working tree in a GTK+ Window.
 
147
    
 
148
    Otherwise, all changes for the tree are listed.
 
149
    """
 
150
    takes_args = ['filename?']
 
151
    takes_options = ['revision']
 
152
 
 
153
    @display_command
 
154
    def run(self, revision=None, filename=None):
 
155
        set_ui_factory()
 
156
        wt = workingtree.WorkingTree.open_containing(".")[0]
 
157
        wt.lock_read()
 
158
        try:
 
159
            branch = wt.branch
 
160
            if revision is not None:
 
161
                if len(revision) == 1:
 
162
                    tree1 = wt
 
163
                    revision_id = revision[0].in_history(branch).rev_id
 
164
                    tree2 = branch.repository.revision_tree(revision_id)
 
165
                elif len(revision) == 2:
 
166
                    revision_id_0 = revision[0].in_history(branch).rev_id
 
167
                    tree2 = branch.repository.revision_tree(revision_id_0)
 
168
                    revision_id_1 = revision[1].in_history(branch).rev_id
 
169
                    tree1 = branch.repository.revision_tree(revision_id_1)
 
170
            else:
 
171
                tree1 = wt
 
172
                tree2 = tree1.basis_tree()
 
173
 
 
174
            from diff import DiffWindow
 
175
            import gtk
 
176
            window = DiffWindow()
 
177
            window.connect("destroy", gtk.main_quit)
 
178
            window.set_diff("Working Tree", tree1, tree2)
 
179
            if filename is not None:
 
180
                tree_filename = wt.relpath(filename)
 
181
                try:
 
182
                    window.set_file(tree_filename)
 
183
                except NoSuchFile:
 
184
                    if (tree1.inventory.path2id(tree_filename) is None and 
 
185
                        tree2.inventory.path2id(tree_filename) is None):
 
186
                        raise NotVersionedError(filename)
 
187
                    raise BzrCommandError('No changes found for file "%s"' % 
 
188
                                          filename)
 
189
            window.show()
 
190
 
 
191
            gtk.main()
 
192
        finally:
 
193
            wt.unlock()
 
194
 
 
195
 
 
196
class cmd_visualise(Command):
 
197
    """Graphically visualise this branch.
 
198
 
 
199
    Opens a graphical window to allow you to see the history of the branch
 
200
    and relationships between revisions in a visual manner,
 
201
 
 
202
    The default starting point is latest revision on the branch, you can
 
203
    specify a starting point with -r revision.
 
204
    """
 
205
    takes_options = [
 
206
        "revision",
 
207
        Option('limit', "maximum number of revisions to display",
 
208
               int, 'count')]
 
209
    takes_args = [ "location?" ]
 
210
    aliases = [ "visualize", "vis", "viz" ]
 
211
 
 
212
    def run(self, location=".", revision=None, limit=None):
 
213
        set_ui_factory()
 
214
        (br, path) = branch.Branch.open_containing(location)
 
215
        br.lock_read()
 
216
        br.repository.lock_read()
 
217
        try:
 
218
            if revision is None:
 
219
                revid = br.last_revision()
 
220
                if revid is None:
 
221
                    return
 
222
            else:
 
223
                (revno, revid) = revision[0].in_history(br)
 
224
 
 
225
            from viz.branchwin import BranchWindow
 
226
            import gtk
 
227
                
 
228
            pp = BranchWindow()
 
229
            pp.set_branch(br, revid, limit)
 
230
            pp.connect("destroy", lambda w: gtk.main_quit())
 
231
            pp.show()
 
232
            gtk.main()
 
233
        finally:
 
234
            br.repository.unlock()
 
235
            br.unlock()
 
236
 
 
237
 
 
238
class cmd_gannotate(GTKCommand):
 
239
    """GTK+ annotate.
 
240
    
 
241
    Browse changes to FILENAME line by line in a GTK+ window.
 
242
    """
 
243
 
 
244
    takes_args = ["filename", "line?"]
 
245
    takes_options = [
 
246
        Option("all", help="show annotations on all lines"),
 
247
        Option("plain", help="don't highlight annotation lines"),
 
248
        Option("line", type=int, argname="lineno",
 
249
               help="jump to specified line number"),
 
250
        "revision",
 
251
    ]
 
252
    aliases = ["gblame", "gpraise"]
 
253
    
 
254
    def run(self, filename, all=False, plain=False, line='1', revision=None):
 
255
        gtk = self.open_display()
 
256
 
 
257
        try:
 
258
            line = int(line)
 
259
        except ValueError:
 
260
            raise BzrCommandError('Line argument ("%s") is not a number.' % 
 
261
                                  line)
 
262
 
 
263
        from annotate.gannotate import GAnnotateWindow
 
264
        from annotate.config import GAnnotateConfig
 
265
        from bzrlib.bzrdir import BzrDir
 
266
 
 
267
        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
 
268
        if wt is not None:
 
269
            tree = wt
 
270
        else:
 
271
            tree = br.basis_tree()
 
272
 
 
273
        file_id = tree.path2id(path)
 
274
 
 
275
        if file_id is None:
 
276
            raise NotVersionedError(filename)
 
277
        if revision is not None:
 
278
            if len(revision) != 1:
 
279
                raise BzrCommandError("Only 1 revion may be specified.")
 
280
            revision_id = revision[0].in_history(br).rev_id
 
281
            tree = br.repository.revision_tree(revision_id)
 
282
        else:
 
283
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
 
284
 
 
285
        window = GAnnotateWindow(all, plain)
 
286
        window.connect("destroy", lambda w: gtk.main_quit())
 
287
        window.set_title(path + " - gannotate")
 
288
        config = GAnnotateConfig(window)
 
289
        window.show()
 
290
        br.lock_read()
 
291
        if wt is not None:
 
292
            wt.lock_read()
 
293
        try:
 
294
            window.annotate(tree, br, file_id)
 
295
            window.jump_to_line(line)
 
296
            gtk.main()
 
297
        finally:
 
298
            br.unlock()
 
299
            if wt is not None:
 
300
                wt.unlock()
 
301
 
 
302
 
 
303
 
 
304
class cmd_gcommit(GTKCommand):
 
305
    """GTK+ commit dialog
 
306
 
 
307
    Graphical user interface for committing revisions"""
 
308
    
 
309
    aliases = [ "gci" ]
 
310
    takes_args = []
 
311
    takes_options = []
 
312
 
 
313
    def run(self, filename=None):
 
314
        import os
 
315
        self.open_display()
 
316
        from commit import CommitDialog
 
317
        from bzrlib.errors import (BzrCommandError,
 
318
                                   NotBranchError,
 
319
                                   NoWorkingTree)
 
320
 
 
321
        wt = None
 
322
        br = None
 
323
        try:
 
324
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
 
325
            br = wt.branch
 
326
        except NotBranchError, e:
 
327
            path = e.path
 
328
        except NoWorkingTree, e:
 
329
            path = e.base
 
330
            try:
 
331
                (br, path) = branch.Branch.open_containing(path)
 
332
            except NotBranchError, e:
 
333
                path = e.path
 
334
 
 
335
        commit = CommitDialog(wt, path, not br)
 
336
        commit.run()
 
337
 
 
338
 
 
339
 
 
340
class cmd_gstatus(GTKCommand):
 
341
    """GTK+ status dialog
 
342
 
 
343
    Graphical user interface for showing status 
 
344
    information."""
 
345
    
 
346
    aliases = [ "gst" ]
 
347
    takes_args = ['PATH?']
 
348
    takes_options = []
 
349
 
 
350
    def run(self, path='.'):
 
351
        import os
 
352
        gtk = self.open_display()
 
353
        from status import StatusDialog
 
354
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
 
355
        status = StatusDialog(wt, wt_path)
 
356
        status.connect("destroy", gtk.main_quit)
 
357
        status.run()
 
358
 
 
359
 
 
360
 
 
361
class cmd_gconflicts(GTKCommand):
 
362
    """ GTK+ push.
 
363
    
 
364
    """
 
365
    def run(self):
 
366
        (wt, path) = workingtree.WorkingTree.open_containing('.')
 
367
        self.open_display()
 
368
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
 
369
        dialog = ConflictsDialog(wt)
 
370
        dialog.run()
 
371
 
 
372
 
 
373
 
 
374
class cmd_gpreferences(GTKCommand):
 
375
    """ GTK+ preferences dialog.
 
376
 
 
377
    """
 
378
    def run(self):
 
379
        self.open_display()
 
380
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
 
381
        dialog = PreferencesWindow()
 
382
        dialog.run()
 
383
 
 
384
 
 
385
 
 
386
class cmd_gmissing(Command):
 
387
    """ GTK+ missing revisions dialog.
 
388
 
 
389
    """
 
390
    takes_args = ["other_branch?"]
 
391
    def run(self, other_branch=None):
 
392
        pygtk = import_pygtk()
 
393
        try:
 
394
            import gtk
 
395
        except RuntimeError, e:
 
396
            if str(e) == "could not open display":
 
397
                raise NoDisplayError
 
398
 
 
399
        from bzrlib.plugins.gtk.missing import MissingWindow
 
400
        from bzrlib.branch import Branch
 
401
 
 
402
        local_branch = Branch.open_containing(".")[0]
 
403
        if other_branch is None:
 
404
            other_branch = local_branch.get_parent()
 
405
            
 
406
            if other_branch is None:
 
407
                raise errors.BzrCommandError("No peer location known or specified.")
 
408
        remote_branch = Branch.open_containing(other_branch)[0]
 
409
        set_ui_factory()
 
410
        local_branch.lock_read()
 
411
        try:
 
412
            remote_branch.lock_read()
 
413
            try:
 
414
                dialog = MissingWindow(local_branch, remote_branch)
 
415
                dialog.run()
 
416
            finally:
 
417
                remote_branch.unlock()
 
418
        finally:
 
419
            local_branch.unlock()
 
420
 
 
421
 
 
422
commands = [
 
423
    cmd_gmissing, 
 
424
    cmd_gpreferences, 
 
425
    cmd_gconflicts, 
 
426
    cmd_gstatus,
 
427
    cmd_gcommit, 
 
428
    cmd_gannotate, 
 
429
    cmd_visualise, 
 
430
    cmd_gdiff,
 
431
    cmd_gpush, 
 
432
    cmd_gcheckout, 
 
433
    cmd_gbranch 
 
434
    ]
 
435
 
 
436
for cmd in commands:
 
437
    register_command(cmd)
 
438
 
 
439
 
 
440
class cmd_commit_notify(GTKCommand):
 
441
    """Run the bzr commit notifier.
 
442
 
 
443
    This is a background program which will pop up a notification on the users
 
444
    screen when a commit occurs.
 
445
    """
 
446
 
 
447
    def run(self):
 
448
        gtk = self.open_display()
 
449
        import cgi
 
450
        import dbus
 
451
        import dbus.service
 
452
        import pynotify
 
453
        from bzrlib.bzrdir import BzrDir
 
454
        from bzrlib import errors
 
455
        from bzrlib.osutils import format_date
 
456
        from bzrlib.transport import get_transport
 
457
        if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
 
458
            import dbus.glib
 
459
        from bzrlib.plugins.dbus import activity
 
460
        bus = dbus.SessionBus()
 
461
        # get the object so we can subscribe to callbacks from it.
 
462
        broadcast_service = bus.get_object(
 
463
            activity.Broadcast.DBUS_NAME,
 
464
            activity.Broadcast.DBUS_PATH)
 
465
        def catch_branch(revision_id, urls):
 
466
            # TODO: show all the urls, or perhaps choose the 'best'.
 
467
            url = urls[0]
 
468
            try:
 
469
                if isinstance(revision_id, unicode):
 
470
                    revision_id = revision_id.encode('utf8')
 
471
                transport = get_transport(url)
 
472
                a_dir = BzrDir.open_from_transport(transport)
 
473
                branch = a_dir.open_branch()
 
474
                revno = branch.revision_id_to_revno(revision_id)
 
475
                revision = branch.repository.get_revision(revision_id)
 
476
                summary = 'New revision %d in %s' % (revno, url)
 
477
                body  = 'Committer: %s\n' % revision.committer
 
478
                body += 'Date: %s\n' % format_date(revision.timestamp,
 
479
                    revision.timezone)
 
480
                body += '\n'
 
481
                body += revision.message
 
482
                body = cgi.escape(body)
 
483
                nw = pynotify.Notification(summary, body)
 
484
                nw.set_timeout(5000)
 
485
                nw.show()
 
486
            except Exception, e:
 
487
                print e
 
488
                raise
 
489
        broadcast_service.connect_to_signal("Revision", catch_branch,
 
490
            dbus_interface=activity.Broadcast.DBUS_INTERFACE)
 
491
        pynotify.init("bzr commit-notify")
 
492
        gtk.main()
 
493
 
 
494
register_command(cmd_commit_notify)
 
495
 
168
496
 
169
497
import gettext
170
498
gettext.install('olive-gtk')
171
499
 
172
 
# Let's create a specialized alias to protect '_' from being erased by other
173
 
# uses of '_' as an anonymous variable (think pdb for one).
174
 
_i18n = gettext.gettext
175
500
 
176
 
class NoDisplayError(errors.BzrCommandError):
 
501
class NoDisplayError(BzrCommandError):
177
502
    """gtk could not find a proper display"""
178
503
 
179
504
    def __str__(self):
180
505
        return "No DISPLAY. Unable to run GTK+ application."
181
506
 
182
507
 
183
 
credential_store_registry = getattr(config, "credential_store_registry", None)
184
 
if credential_store_registry is not None:
185
 
    try:
186
 
        credential_store_registry.register_lazy(
187
 
            "gnome-keyring", "bzrlib.plugins.gtk.keyring", "GnomeKeyringCredentialStore",
188
 
            help="The GNOME Keyring.", fallback=True)
189
 
    except TypeError:
190
 
    # Fallback credentials stores were introduced in Bazaar 1.15
191
 
        credential_store_registry.register_lazy(
192
 
            "gnome-keyring", "bzrlib.plugins.gtk.keyring", "GnomeKeyringCredentialStore",
193
 
            help="The GNOME Keyring.")
194
 
 
195
 
 
196
 
def load_tests(basic_tests, module, loader):
197
 
    testmod_names = [
198
 
        'tests',
199
 
        ]
 
508
def test_suite():
 
509
    from unittest import TestSuite
 
510
    import tests
200
511
    import sys
201
512
    default_encoding = sys.getdefaultencoding()
202
513
    try:
203
 
        result = basic_tests
204
 
        try:
205
 
            import_pygtk()
206
 
        except errors.BzrCommandError:
207
 
            return basic_tests
208
 
        basic_tests.addTest(loader.loadTestsFromModuleNames(
209
 
                ["%s.%s" % (__name__, tmn) for tmn in testmod_names]))
 
514
        result = TestSuite()
 
515
        result.addTest(tests.test_suite())
210
516
    finally:
211
517
        if sys.getdefaultencoding() != default_encoding:
212
518
            reload(sys)
213
519
            sys.setdefaultencoding(default_encoding)
214
 
    return basic_tests
 
520
    return result