/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: Robert Collins
  • Date: 2007-03-23 12:46:47 UTC
  • mto: This revision was merged to the branch mainline in revision 182.
  • Revision ID: robertc@robertcollins.net-20070323124647-207i76uksk65l622
Add new command 'commit-notify' to listen for commits on dbus and show them via pynotify.

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
 
commit-notify     Start the graphical notifier of commits.
19
 
gannotate         GTK+ annotate. 
20
 
gbranch           GTK+ branching. 
21
 
gcheckout         GTK+ checkout. 
22
 
gcommit           GTK+ commit dialog.
23
 
gconflicts        GTK+ conflicts. 
24
 
gdiff             Show differences in working tree in a GTK+ Window. 
25
 
ginit             Initialise a new branch.
26
 
gmissing          GTK+ missing revisions dialog. 
27
 
gpreferences      GTK+ preferences dialog. 
28
 
gpush             GTK+ push.
29
 
gsend             GTK+ send merge directive.
30
 
gstatus           GTK+ status dialog.
31
 
gtags             Manage branch tags.
32
 
visualise         Graphically visualise this branch. 
33
 
"""
34
 
 
35
 
import sys
 
15
"""GTK+ frontends to Bazaar commands """
36
16
 
37
17
import bzrlib
38
18
 
39
 
version_info = (0, 95, 0, 'dev', 1)
40
 
 
41
 
if version_info[3] == 'final':
42
 
    version_string = '%d.%d.%d' % version_info[:3]
43
 
else:
44
 
    version_string = '%d.%d.%d%s%d' % version_info
45
 
__version__ = version_string
46
 
 
47
 
required_bzrlib = (1, 3)
 
19
__version__ = '0.16.0'
 
20
version_info = tuple(int(n) for n in __version__.split('.'))
 
21
 
48
22
 
49
23
def check_bzrlib_version(desired):
50
24
    """Check that bzrlib is compatible.
51
25
 
52
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.
53
30
    """
 
31
    desired_plus = (desired[0], desired[1]+1)
54
32
    bzrlib_version = bzrlib.version_info[:2]
 
33
    if bzrlib_version == desired:
 
34
        return
55
35
    try:
56
36
        from bzrlib.trace import warning
57
37
    except ImportError:
58
38
        # get the message out any way we can
59
39
        from warnings import warn as warning
60
40
    if bzrlib_version < desired:
61
 
        from bzrlib.errors import BzrError
62
 
        warning('Installed Bazaar version %s is too old to be used with bzr-gtk'
 
41
        warning('Installed bzr version %s is too old to be used with bzr-gtk'
63
42
                ' %s.' % (bzrlib.__version__, __version__))
64
 
        raise BzrError('Version mismatch: %r, %r' % (version_info, bzrlib.version_info) )
65
 
 
66
 
 
67
 
if version_info[2] == "final":
68
 
    check_bzrlib_version(required_bzrlib)
 
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])
69
54
 
70
55
from bzrlib.trace import warning
71
56
if __name__ != 'bzrlib.plugins.gtk':
75
60
lazy_import(globals(), """
76
61
from bzrlib import (
77
62
    branch,
78
 
    builtins,
79
63
    errors,
80
 
    merge_directive,
81
64
    workingtree,
82
65
    )
83
66
""")
84
67
 
85
68
from bzrlib.commands import Command, register_command, display_command
86
69
from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
 
70
from bzrlib.commands import Command, register_command
87
71
from bzrlib.option import Option
 
72
from bzrlib.bzrdir import BzrDir
88
73
 
89
74
import os.path
90
75
 
98
83
 
99
84
 
100
85
def set_ui_factory():
101
 
    import_pygtk()
 
86
    pygtk = import_pygtk()
102
87
    from ui import GtkUIFactory
103
88
    import bzrlib.ui
104
89
    bzrlib.ui.ui_factory = GtkUIFactory()
105
90
 
106
91
 
107
 
def data_path():
108
 
    return os.path.dirname(__file__)
109
 
 
110
 
 
111
 
def icon_path(*args):
112
 
    basedirs = [os.path.join(data_path()),
113
 
             "/usr/share/bzr-gtk", 
114
 
             "/usr/local/share/bzr-gtk"]
115
 
    for basedir in basedirs:
116
 
        path = os.path.join(basedir, 'icons', *args)
117
 
        if os.path.exists(path):
118
 
            return path
119
 
    return None
120
 
 
121
 
 
122
 
def open_display():
123
 
    pygtk = import_pygtk()
124
 
    try:
125
 
        import gtk
126
 
    except RuntimeError, e:
127
 
        if str(e) == "could not open display":
128
 
            raise NoDisplayError
129
 
    set_ui_factory()
130
 
    return gtk
131
 
 
132
 
 
133
92
class GTKCommand(Command):
134
93
    """Abstract class providing GTK specific run commands."""
135
94
 
 
95
    def open_display(self):
 
96
        pygtk = import_pygtk()
 
97
        try:
 
98
            import gtk
 
99
        except RuntimeError, e:
 
100
            if str(e) == "could not open display":
 
101
                raise NoDisplayError
 
102
        set_ui_factory()
 
103
        return gtk
 
104
 
136
105
    def run(self):
137
 
        open_display()
 
106
        self.open_display()
138
107
        dialog = self.get_gtk_dialog(os.path.abspath('.'))
139
108
        dialog.run()
140
109
 
149
118
        return BranchDialog(path)
150
119
 
151
120
 
 
121
register_command(cmd_gbranch)
 
122
 
152
123
class cmd_gcheckout(GTKCommand):
153
124
    """ GTK+ checkout.
154
125
    
158
129
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
159
130
        return CheckoutDialog(path)
160
131
 
 
132
register_command(cmd_gcheckout)
161
133
 
162
134
 
163
135
class cmd_gpush(GTKCommand):
168
140
 
169
141
    def run(self, location="."):
170
142
        (br, path) = branch.Branch.open_containing(location)
171
 
        open_display()
 
143
        self.open_display()
172
144
        from push import PushDialog
173
 
        dialog = PushDialog(br.repository, br.last_revision(), br)
 
145
        dialog = PushDialog(br)
174
146
        dialog.run()
175
147
 
 
148
register_command(cmd_gpush)
176
149
 
177
150
 
178
151
class cmd_gdiff(GTKCommand):
193
166
            if revision is not None:
194
167
                if len(revision) == 1:
195
168
                    tree1 = wt
196
 
                    revision_id = revision[0].as_revision_id(tree1.branch)
 
169
                    revision_id = revision[0].in_history(branch).rev_id
197
170
                    tree2 = branch.repository.revision_tree(revision_id)
198
171
                elif len(revision) == 2:
199
 
                    revision_id_0 = revision[0].as_revision_id(branch)
 
172
                    revision_id_0 = revision[0].in_history(branch).rev_id
200
173
                    tree2 = branch.repository.revision_tree(revision_id_0)
201
 
                    revision_id_1 = revision[1].as_revision_id(branch)
 
174
                    revision_id_1 = revision[1].in_history(branch).rev_id
202
175
                    tree1 = branch.repository.revision_tree(revision_id_1)
203
176
            else:
204
177
                tree1 = wt
214
187
                try:
215
188
                    window.set_file(tree_filename)
216
189
                except NoSuchFile:
217
 
                    if (tree1.path2id(tree_filename) is None and 
218
 
                        tree2.path2id(tree_filename) is None):
 
190
                    if (tree1.inventory.path2id(tree_filename) is None and 
 
191
                        tree2.inventory.path2id(tree_filename) is None):
219
192
                        raise NotVersionedError(filename)
220
193
                    raise BzrCommandError('No changes found for file "%s"' % 
221
194
                                          filename)
225
198
        finally:
226
199
            wt.unlock()
227
200
 
228
 
 
229
 
def start_viz_window(branch, revisions, limit=None):
230
 
    """Start viz on branch with revision revision.
231
 
    
232
 
    :return: The viz window object.
233
 
    """
234
 
    from viz import BranchWindow
235
 
    return BranchWindow(branch, revisions, limit)
236
 
 
 
201
register_command(cmd_gdiff)
237
202
 
238
203
class cmd_visualise(Command):
239
204
    """Graphically visualise this branch.
246
211
    """
247
212
    takes_options = [
248
213
        "revision",
249
 
        Option('limit', "Maximum number of revisions to display.",
 
214
        Option('limit', "maximum number of revisions to display",
250
215
               int, 'count')]
251
 
    takes_args = [ "locations*" ]
 
216
    takes_args = [ "location?" ]
252
217
    aliases = [ "visualize", "vis", "viz" ]
253
218
 
254
 
    def run(self, locations_list, revision=None, limit=None):
 
219
    def run(self, location=".", revision=None, limit=None):
255
220
        set_ui_factory()
256
 
        if locations_list is None:
257
 
            locations_list = ["."]
258
 
        revids = []
259
 
        for location in locations_list:
260
 
            (br, path) = branch.Branch.open_containing(location)
 
221
        (br, path) = branch.Branch.open_containing(location)
 
222
        br.lock_read()
 
223
        br.repository.lock_read()
 
224
        try:
261
225
            if revision is None:
262
 
                revids.append(br.last_revision())
 
226
                revid = br.last_revision()
 
227
                if revid is None:
 
228
                    return
263
229
            else:
264
 
                revids.append(revision[0].as_revision_id(br))
265
 
        import gtk
266
 
        pp = start_viz_window(br, revids, limit)
267
 
        pp.connect("destroy", lambda w: gtk.main_quit())
268
 
        pp.show()
269
 
        gtk.main()
 
230
                (revno, revid) = revision[0].in_history(br)
 
231
 
 
232
            from viz.branchwin import BranchWindow
 
233
            import gtk
 
234
                
 
235
            pp = BranchWindow()
 
236
            pp.set_branch(br, revid, limit)
 
237
            pp.connect("destroy", lambda w: gtk.main_quit())
 
238
            pp.show()
 
239
            gtk.main()
 
240
        finally:
 
241
            br.repository.unlock()
 
242
            br.unlock()
 
243
 
 
244
 
 
245
register_command(cmd_visualise)
270
246
 
271
247
 
272
248
class cmd_gannotate(GTKCommand):
277
253
 
278
254
    takes_args = ["filename", "line?"]
279
255
    takes_options = [
280
 
        Option("all", help="Show annotations on all lines."),
281
 
        Option("plain", help="Don't highlight annotation lines."),
 
256
        Option("all", help="show annotations on all lines"),
 
257
        Option("plain", help="don't highlight annotation lines"),
282
258
        Option("line", type=int, argname="lineno",
283
 
               help="Jump to specified line number."),
 
259
               help="jump to specified line number"),
284
260
        "revision",
285
261
    ]
286
262
    aliases = ["gblame", "gpraise"]
287
263
    
288
264
    def run(self, filename, all=False, plain=False, line='1', revision=None):
289
 
        gtk = open_display()
 
265
        self.open_display()
290
266
 
291
267
        try:
292
268
            line = int(line)
296
272
 
297
273
        from annotate.gannotate import GAnnotateWindow
298
274
        from annotate.config import GAnnotateConfig
299
 
        from bzrlib.bzrdir import BzrDir
300
275
 
301
276
        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
302
277
        if wt is not None:
311
286
        if revision is not None:
312
287
            if len(revision) != 1:
313
288
                raise BzrCommandError("Only 1 revion may be specified.")
314
 
            revision_id = revision[0].as_revision_id(br)
 
289
            revision_id = revision[0].in_history(br).rev_id
315
290
            tree = br.repository.revision_tree(revision_id)
316
291
        else:
317
292
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
318
293
 
319
 
        window = GAnnotateWindow(all, plain, branch=br)
 
294
        window = GAnnotateWindow(all, plain)
320
295
        window.connect("destroy", lambda w: gtk.main_quit())
 
296
        window.set_title(path + " - gannotate")
321
297
        config = GAnnotateConfig(window)
322
298
        window.show()
323
299
        br.lock_read()
332
308
            if wt is not None:
333
309
                wt.unlock()
334
310
 
 
311
register_command(cmd_gannotate)
335
312
 
336
313
 
337
314
class cmd_gcommit(GTKCommand):
338
315
    """GTK+ commit dialog
339
316
 
340
317
    Graphical user interface for committing revisions"""
341
 
 
 
318
    
342
319
    aliases = [ "gci" ]
343
320
    takes_args = []
344
321
    takes_options = []
345
322
 
346
323
    def run(self, filename=None):
347
324
        import os
348
 
        open_display()
 
325
        self.open_display()
349
326
        from commit import CommitDialog
 
327
        from bzrlib.commit import Commit
350
328
        from bzrlib.errors import (BzrCommandError,
351
329
                                   NotBranchError,
352
 
                                   NoWorkingTree)
 
330
                                   NoWorkingTree,
 
331
                                   PointlessCommit,
 
332
                                   ConflictsInTree,
 
333
                                   StrictCommitFailed)
353
334
 
354
335
        wt = None
355
336
        br = None
356
337
        try:
357
338
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
358
339
            br = wt.branch
 
340
        except NotBranchError, e:
 
341
            path = e.path
359
342
        except NoWorkingTree, e:
360
 
            from dialog import error_dialog
361
 
            error_dialog(_i18n('Directory does not have a working tree'),
362
 
                         _i18n('Operation aborted.'))
363
 
            return 1 # should this be retval=3?
364
 
 
365
 
        # It is a good habit to keep things locked for the duration, but it
366
 
        # could cause difficulties if someone wants to do things in another
367
 
        # window... We could lock_read() until we actually go to commit
368
 
        # changes... Just a thought.
369
 
        wt.lock_write()
370
 
        try:
371
 
            dlg = CommitDialog(wt)
372
 
            return dlg.run()
373
 
        finally:
374
 
            wt.unlock()
 
343
            path = e.base
 
344
            try:
 
345
                (br, path) = branch.Branch.open_containing(path)
 
346
            except NotBranchError, e:
 
347
                path = e.path
 
348
 
 
349
 
 
350
        commit = CommitDialog(wt, path, not br)
 
351
        commit.run()
 
352
 
 
353
register_command(cmd_gcommit)
375
354
 
376
355
 
377
356
class cmd_gstatus(GTKCommand):
382
361
    
383
362
    aliases = [ "gst" ]
384
363
    takes_args = ['PATH?']
385
 
    takes_options = ['revision']
 
364
    takes_options = []
386
365
 
387
 
    def run(self, path='.', revision=None):
 
366
    def run(self, path='.'):
388
367
        import os
389
 
        gtk = open_display()
 
368
        self.open_display()
390
369
        from status import StatusDialog
391
370
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
392
 
        
393
 
        if revision is not None:
394
 
            try:
395
 
                revision_id = revision[0].as_revision_id(wt.branch)
396
 
            except:
397
 
                from bzrlib.errors import BzrError
398
 
                raise BzrError('Revision %r doesn\'t exist' % revision[0].user_spec )
399
 
        else:
400
 
            revision_id = None
401
 
 
402
 
        status = StatusDialog(wt, wt_path, revision_id)
 
371
        status = StatusDialog(wt, wt_path)
403
372
        status.connect("destroy", gtk.main_quit)
404
373
        status.run()
405
374
 
406
 
 
407
 
class cmd_gsend(GTKCommand):
408
 
    """GTK+ send merge directive.
409
 
 
410
 
    """
411
 
    def run(self):
412
 
        (br, path) = branch.Branch.open_containing(".")
413
 
        gtk = open_display()
414
 
        from bzrlib.plugins.gtk.mergedirective import SendMergeDirectiveDialog
415
 
        from StringIO import StringIO
416
 
        dialog = SendMergeDirectiveDialog(br)
417
 
        if dialog.run() == gtk.RESPONSE_OK:
418
 
            outf = StringIO()
419
 
            outf.writelines(dialog.get_merge_directive().to_lines())
420
 
            mail_client = br.get_config().get_mail_client()
421
 
            mail_client.compose_merge_request(dialog.get_mail_to(), "[MERGE]", 
422
 
                outf.getvalue())
423
 
 
424
 
            
 
375
register_command(cmd_gstatus)
425
376
 
426
377
 
427
378
class cmd_gconflicts(GTKCommand):
428
 
    """GTK+ conflicts.
 
379
    """ GTK+ push.
429
380
    
430
 
    Select files from the list of conflicts and run an external utility to
431
 
    resolve them.
432
381
    """
433
382
    def run(self):
434
383
        (wt, path) = workingtree.WorkingTree.open_containing('.')
435
 
        open_display()
 
384
        self.open_display()
436
385
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
437
386
        dialog = ConflictsDialog(wt)
438
387
        dialog.run()
439
388
 
 
389
register_command(cmd_gconflicts)
 
390
 
440
391
 
441
392
class cmd_gpreferences(GTKCommand):
442
393
    """ GTK+ preferences dialog.
443
394
 
444
395
    """
445
396
    def run(self):
446
 
        open_display()
 
397
        self.open_display()
447
398
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
448
399
        dialog = PreferencesWindow()
449
400
        dialog.run()
450
401
 
451
 
 
452
 
class cmd_gmissing(Command):
453
 
    """ GTK+ missing revisions dialog.
454
 
 
455
 
    """
456
 
    takes_args = ["other_branch?"]
457
 
    def run(self, other_branch=None):
458
 
        pygtk = import_pygtk()
459
 
        try:
460
 
            import gtk
461
 
        except RuntimeError, e:
462
 
            if str(e) == "could not open display":
463
 
                raise NoDisplayError
464
 
 
465
 
        from bzrlib.plugins.gtk.missing import MissingWindow
466
 
        from bzrlib.branch import Branch
467
 
 
468
 
        local_branch = Branch.open_containing(".")[0]
469
 
        if other_branch is None:
470
 
            other_branch = local_branch.get_parent()
471
 
            
472
 
            if other_branch is None:
473
 
                raise errors.BzrCommandError("No peer location known or specified.")
474
 
        remote_branch = Branch.open_containing(other_branch)[0]
475
 
        set_ui_factory()
476
 
        local_branch.lock_read()
477
 
        try:
478
 
            remote_branch.lock_read()
479
 
            try:
480
 
                dialog = MissingWindow(local_branch, remote_branch)
481
 
                dialog.run()
482
 
            finally:
483
 
                remote_branch.unlock()
484
 
        finally:
485
 
            local_branch.unlock()
486
 
 
487
 
 
488
 
class cmd_ginit(GTKCommand):
489
 
    def run(self):
490
 
        open_display()
491
 
        from initialize import InitDialog
492
 
        dialog = InitDialog(os.path.abspath(os.path.curdir))
493
 
        dialog.run()
494
 
 
495
 
 
496
 
class cmd_gtags(GTKCommand):
497
 
    def run(self):
498
 
        br = branch.Branch.open_containing('.')[0]
499
 
        
500
 
        gtk = open_display()
501
 
        from tags import TagsWindow
502
 
        window = TagsWindow(br)
503
 
        window.show()
504
 
        gtk.main()
505
 
 
506
 
 
507
 
commands = [
508
 
    cmd_gannotate, 
509
 
    cmd_gbranch,
510
 
    cmd_gcheckout, 
511
 
    cmd_gcommit, 
512
 
    cmd_gconflicts, 
513
 
    cmd_gdiff,
514
 
    cmd_ginit,
515
 
    cmd_gmissing, 
516
 
    cmd_gpreferences, 
517
 
    cmd_gpush, 
518
 
    cmd_gsend,
519
 
    cmd_gstatus,
520
 
    cmd_gtags,
521
 
    cmd_visualise
522
 
    ]
523
 
 
524
 
for cmd in commands:
525
 
    register_command(cmd)
 
402
register_command(cmd_gpreferences)
526
403
 
527
404
 
528
405
class cmd_commit_notify(GTKCommand):
533
410
    """
534
411
 
535
412
    def run(self):
536
 
        from notify import NotifyPopupMenu
537
 
        gtk = open_display()
538
 
        menu = NotifyPopupMenu()
539
 
        icon = gtk.status_icon_new_from_file(icon_path("bzr-icon-64.png"))
540
 
        icon.connect('popup-menu', menu.display)
541
 
 
 
413
        gtk = self.open_display()
542
414
        import cgi
543
415
        import dbus
544
416
        import dbus.service
549
421
        from bzrlib.transport import get_transport
550
422
        if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
551
423
            import dbus.glib
552
 
        BROADCAST_INTERFACE = "org.bazaarvcs.plugins.dbus.Broadcast"
 
424
        from bzrlib.plugins.dbus import activity
553
425
        bus = dbus.SessionBus()
554
 
 
555
 
        def catch_branch(revision_id, urls):
556
 
            # TODO: show all the urls, or perhaps choose the 'best'.
557
 
            url = urls[0]
 
426
        # get the object so we can subscribe to callbacks from it.
 
427
        broadcast_service = bus.get_object(
 
428
            activity.Broadcast.DBUS_NAME,
 
429
            activity.Broadcast.DBUS_PATH)
 
430
        def catch_branch(revision_id, url):
558
431
            try:
559
432
                if isinstance(revision_id, unicode):
560
433
                    revision_id = revision_id.encode('utf8')
561
434
                transport = get_transport(url)
 
435
                try:
 
436
                    transport.local_abspath('.')
 
437
                except errors.TransportNotPossible:
 
438
                    # dont show remote urls for now.
 
439
                    return
 
440
                # here we should:
562
441
                a_dir = BzrDir.open_from_transport(transport)
563
442
                branch = a_dir.open_branch()
564
443
                revno = branch.revision_id_to_revno(revision_id)
570
449
                body += '\n'
571
450
                body += revision.message
572
451
                body = cgi.escape(body)
 
452
                #print repr(body)
573
453
                nw = pynotify.Notification(summary, body)
574
 
                def start_viz(notification=None, action=None, data=None):
575
 
                    """Start the viz program."""
576
 
                    pp = start_viz_window(branch, revision_id)
577
 
                    pp.show()
578
 
                def start_branch(notification=None, action=None, data=None):
579
 
                    """Start a Branch dialog"""
580
 
                    from bzrlib.plugins.gtk.branch import BranchDialog
581
 
                    bd = BranchDialog(remote_path=url)
582
 
                    bd.run()
583
 
                nw.add_action("inspect", "Inspect", start_viz, None)
584
 
                nw.add_action("branch", "Branch", start_branch, None)
585
454
                nw.set_timeout(5000)
586
455
                nw.show()
587
456
            except Exception, e:
588
457
                print e
589
458
                raise
590
 
        bus.add_signal_receiver(catch_branch,
591
 
                                dbus_interface=BROADCAST_INTERFACE,
592
 
                                signal_name="Revision")
 
459
        broadcast_service.connect_to_signal("Revision", catch_branch,
 
460
            dbus_interface=activity.Broadcast.DBUS_INTERFACE)
593
461
        pynotify.init("bzr commit-notify")
594
462
        gtk.main()
595
463
 
596
464
register_command(cmd_commit_notify)
597
465
 
598
466
 
599
 
class cmd_gselftest(GTKCommand):
600
 
    """Version of selftest that displays a notification at the end"""
601
 
 
602
 
    takes_args = builtins.cmd_selftest.takes_args
603
 
    takes_options = builtins.cmd_selftest.takes_options
604
 
    _see_also = ['selftest']
605
 
 
606
 
    def run(self, *args, **kwargs):
607
 
        import cgi
608
 
        import sys
609
 
        default_encoding = sys.getdefaultencoding()
610
 
        # prevent gtk from blowing up later
611
 
        gtk = import_pygtk()
612
 
        # prevent gtk from messing with default encoding
613
 
        import pynotify
614
 
        if sys.getdefaultencoding() != default_encoding:
615
 
            reload(sys)
616
 
            sys.setdefaultencoding(default_encoding)
617
 
        result = builtins.cmd_selftest().run(*args, **kwargs)
618
 
        if result == 0:
619
 
            summary = 'Success'
620
 
            body = 'Selftest succeeded in "%s"' % os.getcwd()
621
 
        if result == 1:
622
 
            summary = 'Failure'
623
 
            body = 'Selftest failed in "%s"' % os.getcwd()
624
 
        pynotify.init("bzr gselftest")
625
 
        note = pynotify.Notification(cgi.escape(summary), cgi.escape(body))
626
 
        note.set_timeout(pynotify.EXPIRES_NEVER)
627
 
        note.show()
628
 
 
629
 
 
630
 
register_command(cmd_gselftest)
631
 
 
632
 
 
633
 
class cmd_test_gtk(GTKCommand):
634
 
    """Version of selftest that just runs the gtk test suite."""
635
 
 
636
 
    takes_options = ['verbose',
637
 
                     Option('one', short_name='1',
638
 
                            help='Stop when one test fails.'),
639
 
                     Option('benchmark', help='Run the benchmarks.'),
640
 
                     Option('lsprof-timed',
641
 
                     help='Generate lsprof output for benchmarked'
642
 
                          ' sections of code.'),
643
 
                     Option('list-only',
644
 
                     help='List the tests instead of running them.'),
645
 
                     Option('randomize', type=str, argname="SEED",
646
 
                     help='Randomize the order of tests using the given'
647
 
                          ' seed or "now" for the current time.'),
648
 
                    ]
649
 
    takes_args = ['testspecs*']
650
 
 
651
 
    def run(self, verbose=None, one=False, benchmark=None,
652
 
            lsprof_timed=None, list_only=False, randomize=None,
653
 
            testspecs_list=None):
654
 
        from bzrlib import __path__ as bzrlib_path
655
 
        from bzrlib.tests import selftest
656
 
 
657
 
        print '%10s: %s' % ('bzrlib', bzrlib_path[0])
658
 
        if benchmark:
659
 
            print 'No benchmarks yet'
660
 
            return 3
661
 
 
662
 
            test_suite_factory = bench_suite
663
 
            if verbose is None:
664
 
                verbose = True
665
 
            # TODO: should possibly lock the history file...
666
 
            benchfile = open(".perf_history", "at", buffering=1)
667
 
        else:
668
 
            test_suite_factory = test_suite
669
 
            if verbose is None:
670
 
                verbose = False
671
 
            benchfile = None
672
 
 
673
 
        if testspecs_list is not None:
674
 
            pattern = '|'.join(testspecs_list)
675
 
        else:
676
 
            pattern = ".*"
677
 
 
678
 
        try:
679
 
            result = selftest(verbose=verbose,
680
 
                              pattern=pattern,
681
 
                              stop_on_failure=one,
682
 
                              test_suite_factory=test_suite_factory,
683
 
                              lsprof_timed=lsprof_timed,
684
 
                              bench_history=benchfile,
685
 
                              list_only=list_only,
686
 
                              random_seed=randomize,
687
 
                             )
688
 
        finally:
689
 
            if benchfile is not None:
690
 
                benchfile.close()
691
 
 
692
 
register_command(cmd_test_gtk)
693
 
 
694
 
 
695
 
 
696
467
import gettext
697
468
gettext.install('olive-gtk')
698
469
 
699
 
# Let's create a specialized alias to protect '_' from being erased by other
700
 
# uses of '_' as an anonymous variable (think pdb for one).
701
 
_i18n = gettext.gettext
702
470
 
703
471
class NoDisplayError(BzrCommandError):
704
472
    """gtk could not find a proper display"""
714
482
    default_encoding = sys.getdefaultencoding()
715
483
    try:
716
484
        result = TestSuite()
717
 
        try:
718
 
            import_pygtk()
719
 
        except errors.BzrCommandError:
720
 
            return result
721
485
        result.addTest(tests.test_suite())
722
486
    finally:
723
487
        if sys.getdefaultencoding() != default_encoding: