/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-03-09 17:47:28 UTC
  • Revision ID: jelmer@samba.org-20070309174728-gljlmt9b7fu0rrn9
Add simple test for tortoise_bzr

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.16.0'
 
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, 98, 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
 
                           ]
77
 
 
78
 
bzrlib.api.require_any_api(bzrlib, COMPATIBLE_BZR_VERSIONS)
79
 
 
80
 
if __name__ != 'bzrlib.plugins.gtk':
81
 
    from bzrlib.trace import warning
82
 
    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.commands import Command, register_command
 
71
from bzrlib.option import Option
 
72
from bzrlib.bzrdir import BzrDir
 
73
 
 
74
import os.path
83
75
 
84
76
def import_pygtk():
85
77
    try:
91
83
 
92
84
 
93
85
def set_ui_factory():
94
 
    import_pygtk()
 
86
    pygtk = import_pygtk()
95
87
    from ui import GtkUIFactory
96
88
    import bzrlib.ui
97
89
    bzrlib.ui.ui_factory = GtkUIFactory()
98
90
 
99
91
 
100
 
def data_basedirs():
101
 
    return [os.path.dirname(__file__),
102
 
             "/usr/share/bzr-gtk", 
103
 
             "/usr/local/share/bzr-gtk"]
104
 
 
105
 
 
106
 
def data_path(*args):
107
 
    for basedir in data_basedirs():
108
 
        path = os.path.join(basedir, *args)
109
 
        if os.path.exists(path):
110
 
            return path
111
 
    return None
112
 
 
113
 
 
114
 
def icon_path(*args):
115
 
    return data_path(os.path.join('icons', *args))
116
 
 
117
 
 
118
 
def open_display():
119
 
    pygtk = import_pygtk()
120
 
    try:
121
 
        import gtk
122
 
    except RuntimeError, e:
123
 
        if str(e) == "could not open display":
124
 
            raise NoDisplayError
125
 
    set_ui_factory()
126
 
    return gtk
127
 
 
128
 
 
129
 
commands = {
130
 
    "gannotate": ["gblame", "gpraise"],
131
 
    "gbranch": [],
132
 
    "gcheckout": [],
133
 
    "gcommit": ["gci"],
134
 
    "gconflicts": [],
135
 
    "gdiff": [],
136
 
    "ginit": [],
137
 
    "ginfo": [],
138
 
    "gmerge": [],
139
 
    "gmissing": [],
140
 
    "gpreferences": [],
141
 
    "gpush": [],
142
 
    "gselftest": [],
143
 
    "gsend": [],
144
 
    "gstatus": ["gst"],
145
 
    "gtags": [],
146
 
    "visualise": ["visualize", "vis", "viz"],
147
 
    }
148
 
 
149
 
try:
150
 
    from bzrlib.plugins import loom
151
 
except ImportError:
152
 
    pass # Loom plugin doesn't appear to be present
153
 
else:
154
 
    commands["gloom"] = []
155
 
 
156
 
for cmd, aliases in commands.iteritems():
157
 
    plugin_cmds.register_lazy("cmd_%s" % cmd, aliases,
158
 
                              "bzrlib.plugins.gtk.commands")
159
 
 
160
 
def save_commit_messages(*args):
161
 
    from bzrlib.plugins.gtk import commit
162
 
    commit.save_commit_messages(*args)
163
 
 
164
 
branch.Branch.hooks.install_named_hook('post_uncommit',
165
 
                                       save_commit_messages,
166
 
                                       "Saving commit messages for gcommit")
 
92
class cmd_gbranch(Command):
 
93
    """GTK+ branching.
 
94
    
 
95
    """
 
96
 
 
97
    def run(self):
 
98
        pygtk = import_pygtk()
 
99
        try:
 
100
            import gtk
 
101
        except RuntimeError, e:
 
102
            if str(e) == "could not open display":
 
103
                raise NoDisplayError
 
104
 
 
105
        from bzrlib.plugins.gtk.branch import BranchDialog
 
106
 
 
107
        set_ui_factory()
 
108
        dialog = BranchDialog(os.path.abspath('.'))
 
109
        dialog.run()
 
110
 
 
111
register_command(cmd_gbranch)
 
112
 
 
113
class cmd_gcheckout(Command):
 
114
    """ GTK+ checkout.
 
115
    
 
116
    """
 
117
    
 
118
    def run(self):
 
119
        pygtk = import_pygtk()
 
120
        try:
 
121
            import gtk
 
122
        except RuntimeError, e:
 
123
            if str(e) == "could not open display":
 
124
                raise NoDisplayError
 
125
 
 
126
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
 
127
 
 
128
        set_ui_factory()
 
129
        dialog = CheckoutDialog(os.path.abspath('.'))
 
130
        dialog.run()
 
131
 
 
132
register_command(cmd_gcheckout)
 
133
 
 
134
class cmd_gpush(Command):
 
135
    """ GTK+ push.
 
136
    
 
137
    """
 
138
    takes_args = [ "location?" ]
 
139
 
 
140
    def run(self, location="."):
 
141
        (br, path) = branch.Branch.open_containing(location)
 
142
 
 
143
        pygtk = import_pygtk()
 
144
        try:
 
145
            import gtk
 
146
        except RuntimeError, e:
 
147
            if str(e) == "could not open display":
 
148
                raise NoDisplayError
 
149
 
 
150
        from push import PushDialog
 
151
 
 
152
        set_ui_factory()
 
153
        dialog = PushDialog(br)
 
154
        dialog.run()
 
155
 
 
156
register_command(cmd_gpush)
 
157
 
 
158
class cmd_gdiff(Command):
 
159
    """Show differences in working tree in a GTK+ Window.
 
160
    
 
161
    Otherwise, all changes for the tree are listed.
 
162
    """
 
163
    takes_args = ['filename?']
 
164
    takes_options = ['revision']
 
165
 
 
166
    @display_command
 
167
    def run(self, revision=None, filename=None):
 
168
        set_ui_factory()
 
169
        wt = workingtree.WorkingTree.open_containing(".")[0]
 
170
        wt.lock_read()
 
171
        try:
 
172
            branch = wt.branch
 
173
            if revision is not None:
 
174
                if len(revision) == 1:
 
175
                    tree1 = wt
 
176
                    revision_id = revision[0].in_history(branch).rev_id
 
177
                    tree2 = branch.repository.revision_tree(revision_id)
 
178
                elif len(revision) == 2:
 
179
                    revision_id_0 = revision[0].in_history(branch).rev_id
 
180
                    tree2 = branch.repository.revision_tree(revision_id_0)
 
181
                    revision_id_1 = revision[1].in_history(branch).rev_id
 
182
                    tree1 = branch.repository.revision_tree(revision_id_1)
 
183
            else:
 
184
                tree1 = wt
 
185
                tree2 = tree1.basis_tree()
 
186
 
 
187
            from diff import DiffWindow
 
188
            import gtk
 
189
            window = DiffWindow()
 
190
            window.connect("destroy", gtk.main_quit)
 
191
            window.set_diff("Working Tree", tree1, tree2)
 
192
            if filename is not None:
 
193
                tree_filename = wt.relpath(filename)
 
194
                try:
 
195
                    window.set_file(tree_filename)
 
196
                except NoSuchFile:
 
197
                    if (tree1.inventory.path2id(tree_filename) is None and 
 
198
                        tree2.inventory.path2id(tree_filename) is None):
 
199
                        raise NotVersionedError(filename)
 
200
                    raise BzrCommandError('No changes found for file "%s"' % 
 
201
                                          filename)
 
202
            window.show()
 
203
 
 
204
            gtk.main()
 
205
        finally:
 
206
            wt.unlock()
 
207
 
 
208
register_command(cmd_gdiff)
 
209
 
 
210
class cmd_visualise(Command):
 
211
    """Graphically visualise this branch.
 
212
 
 
213
    Opens a graphical window to allow you to see the history of the branch
 
214
    and relationships between revisions in a visual manner,
 
215
 
 
216
    The default starting point is latest revision on the branch, you can
 
217
    specify a starting point with -r revision.
 
218
    """
 
219
    takes_options = [
 
220
        "revision",
 
221
        Option('limit', "maximum number of revisions to display",
 
222
               int, 'count')]
 
223
    takes_args = [ "location?" ]
 
224
    aliases = [ "visualize", "vis", "viz" ]
 
225
 
 
226
    def run(self, location=".", revision=None, limit=None):
 
227
        set_ui_factory()
 
228
        (br, path) = branch.Branch.open_containing(location)
 
229
        br.lock_read()
 
230
        br.repository.lock_read()
 
231
        try:
 
232
            if revision is None:
 
233
                revid = br.last_revision()
 
234
                if revid is None:
 
235
                    return
 
236
            else:
 
237
                (revno, revid) = revision[0].in_history(br)
 
238
 
 
239
            from viz.branchwin import BranchWindow
 
240
            import gtk
 
241
                
 
242
            pp = BranchWindow()
 
243
            pp.set_branch(br, revid, limit)
 
244
            pp.connect("destroy", lambda w: gtk.main_quit())
 
245
            pp.show()
 
246
            gtk.main()
 
247
        finally:
 
248
            br.repository.unlock()
 
249
            br.unlock()
 
250
 
 
251
 
 
252
register_command(cmd_visualise)
 
253
 
 
254
class cmd_gannotate(Command):
 
255
    """GTK+ annotate.
 
256
    
 
257
    Browse changes to FILENAME line by line in a GTK+ window.
 
258
    """
 
259
 
 
260
    takes_args = ["filename", "line?"]
 
261
    takes_options = [
 
262
        Option("all", help="show annotations on all lines"),
 
263
        Option("plain", help="don't highlight annotation lines"),
 
264
        Option("line", type=int, argname="lineno",
 
265
               help="jump to specified line number"),
 
266
        "revision",
 
267
    ]
 
268
    aliases = ["gblame", "gpraise"]
 
269
    
 
270
    def run(self, filename, all=False, plain=False, line='1', revision=None):
 
271
        pygtk = import_pygtk()
 
272
 
 
273
        try:
 
274
            import gtk
 
275
        except RuntimeError, e:
 
276
            if str(e) == "could not open display":
 
277
                raise NoDisplayError
 
278
        set_ui_factory()
 
279
 
 
280
        try:
 
281
            line = int(line)
 
282
        except ValueError:
 
283
            raise BzrCommandError('Line argument ("%s") is not a number.' % 
 
284
                                  line)
 
285
 
 
286
        from annotate.gannotate import GAnnotateWindow
 
287
        from annotate.config import GAnnotateConfig
 
288
 
 
289
        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
 
290
        if wt is not None:
 
291
            tree = wt
 
292
        else:
 
293
            tree = br.basis_tree()
 
294
 
 
295
        file_id = tree.path2id(path)
 
296
 
 
297
        if file_id is None:
 
298
            raise NotVersionedError(filename)
 
299
        if revision is not None:
 
300
            if len(revision) != 1:
 
301
                raise BzrCommandError("Only 1 revion may be specified.")
 
302
            revision_id = revision[0].in_history(br).rev_id
 
303
            tree = br.repository.revision_tree(revision_id)
 
304
        else:
 
305
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
 
306
 
 
307
        window = GAnnotateWindow(all, plain)
 
308
        window.connect("destroy", lambda w: gtk.main_quit())
 
309
        window.set_title(path + " - gannotate")
 
310
        config = GAnnotateConfig(window)
 
311
        window.show()
 
312
        br.lock_read()
 
313
        if wt is not None:
 
314
            wt.lock_read()
 
315
        try:
 
316
            window.annotate(tree, br, file_id)
 
317
            window.jump_to_line(line)
 
318
            gtk.main()
 
319
        finally:
 
320
            br.unlock()
 
321
            if wt is not None:
 
322
                wt.unlock()
 
323
 
 
324
register_command(cmd_gannotate)
 
325
 
 
326
class cmd_gcommit(Command):
 
327
    """GTK+ commit dialog
 
328
 
 
329
    Graphical user interface for committing revisions"""
 
330
    
 
331
    aliases = [ "gci" ]
 
332
    takes_args = []
 
333
    takes_options = []
 
334
 
 
335
    def run(self, filename=None):
 
336
        import os
 
337
        pygtk = import_pygtk()
 
338
 
 
339
        try:
 
340
            import gtk
 
341
        except RuntimeError, e:
 
342
            if str(e) == "could not open display":
 
343
                raise NoDisplayError
 
344
 
 
345
        set_ui_factory()
 
346
        from commit import CommitDialog
 
347
        from bzrlib.commit import Commit
 
348
        from bzrlib.errors import (BzrCommandError,
 
349
                                   NotBranchError,
 
350
                                   NoWorkingTree,
 
351
                                   PointlessCommit,
 
352
                                   ConflictsInTree,
 
353
                                   StrictCommitFailed)
 
354
 
 
355
        wt = None
 
356
        br = None
 
357
        try:
 
358
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
 
359
            br = wt.branch
 
360
        except NotBranchError, e:
 
361
            path = e.path
 
362
        except NoWorkingTree, e:
 
363
            path = e.base
 
364
            try:
 
365
                (br, path) = branch.Branch.open_containing(path)
 
366
            except NotBranchError, e:
 
367
                path = e.path
 
368
 
 
369
 
 
370
        commit = CommitDialog(wt, path, not br)
 
371
        commit.run()
 
372
 
 
373
register_command(cmd_gcommit)
 
374
 
 
375
class cmd_gstatus(Command):
 
376
    """GTK+ status dialog
 
377
 
 
378
    Graphical user interface for showing status 
 
379
    information."""
 
380
    
 
381
    aliases = [ "gst" ]
 
382
    takes_args = ['PATH?']
 
383
    takes_options = []
 
384
 
 
385
    def run(self, path='.'):
 
386
        import os
 
387
        pygtk = import_pygtk()
 
388
 
 
389
        try:
 
390
            import gtk
 
391
        except RuntimeError, e:
 
392
            if str(e) == "could not open display":
 
393
                raise NoDisplayError
 
394
 
 
395
        set_ui_factory()
 
396
        from status import StatusDialog
 
397
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
 
398
        status = StatusDialog(wt, wt_path)
 
399
        status.connect("destroy", gtk.main_quit)
 
400
        status.run()
 
401
 
 
402
register_command(cmd_gstatus)
 
403
 
 
404
class cmd_gconflicts(Command):
 
405
    """ GTK+ push.
 
406
    
 
407
    """
 
408
    def run(self):
 
409
        (wt, path) = workingtree.WorkingTree.open_containing('.')
 
410
        
 
411
        pygtk = import_pygtk()
 
412
        try:
 
413
            import gtk
 
414
        except RuntimeError, e:
 
415
            if str(e) == "could not open display":
 
416
                raise NoDisplayError
 
417
 
 
418
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
 
419
 
 
420
        set_ui_factory()
 
421
        dialog = ConflictsDialog(wt)
 
422
        dialog.run()
 
423
 
 
424
register_command(cmd_gconflicts)
167
425
 
168
426
import gettext
169
427
gettext.install('olive-gtk')
170
428
 
171
 
# Let's create a specialized alias to protect '_' from being erased by other
172
 
# uses of '_' as an anonymous variable (think pdb for one).
173
 
_i18n = gettext.gettext
174
 
 
175
 
class NoDisplayError(errors.BzrCommandError):
 
429
class NoDisplayError(BzrCommandError):
176
430
    """gtk could not find a proper display"""
177
431
 
178
432
    def __str__(self):
179
433
        return "No DISPLAY. Unable to run GTK+ application."
180
434
 
181
 
 
182
 
credential_store_registry = getattr(config, "credential_store_registry", None)
183
 
if credential_store_registry is not None:
184
 
    try:
185
 
        credential_store_registry.register_lazy(
186
 
            "gnome-keyring", "bzrlib.plugins.gtk.keyring", "GnomeKeyringCredentialStore",
187
 
            help="The GNOME Keyring.", fallback=True)
188
 
    except TypeError:
189
 
    # Fallback credentials stores were introduced in Bazaar 1.15
190
 
        credential_store_registry.register_lazy(
191
 
            "gnome-keyring", "bzrlib.plugins.gtk.keyring", "GnomeKeyringCredentialStore",
192
 
            help="The GNOME Keyring.")
193
 
 
194
 
 
195
 
def load_tests(basic_tests, module, loader):
196
 
    testmod_names = [
197
 
        'tests',
198
 
        ]
 
435
def test_suite():
 
436
    from unittest import TestSuite
 
437
    import tests
199
438
    import sys
200
439
    default_encoding = sys.getdefaultencoding()
201
440
    try:
202
 
        result = basic_tests
203
 
        try:
204
 
            import_pygtk()
205
 
        except errors.BzrCommandError:
206
 
            return basic_tests
207
 
        basic_tests.addTest(loader.loadTestsFromModuleNames(
208
 
                ["%s.%s" % (__name__, tmn) for tmn in testmod_names]))
 
441
        result = TestSuite()
 
442
        result.addTest(tests.test_suite())
209
443
    finally:
210
 
        if sys.getdefaultencoding() != default_encoding:
211
 
            reload(sys)
212
 
            sys.setdefaultencoding(default_encoding)
213
 
    return basic_tests
 
444
        reload(sys)
 
445
        sys.setdefaultencoding(default_encoding)
 
446
    return result