/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-02-03 13:01:12 UTC
  • Revision ID: jelmer@samba.org-20070203130112-m1stbo29f1ahthzs
Move diff to top-level directory as well.

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
55
 
from bzrlib import (
56
 
    branch,
57
 
    config,
58
 
    errors,
59
 
    )
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
 
 
 
18
 
 
19
__version__ = '0.15.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
81
56
if __name__ != 'bzrlib.plugins.gtk':
82
 
    from bzrlib.trace import warning
83
57
    warning("Not running as bzrlib.plugins.gtk, things may break.")
84
58
 
 
59
from bzrlib import errors
 
60
from bzrlib.commands import Command, register_command, display_command
 
61
from bzrlib.errors import NotVersionedError, BzrCommandError, NoSuchFile
 
62
from bzrlib.commands import Command, register_command
 
63
from bzrlib.option import Option
 
64
from bzrlib.branch import Branch
 
65
from bzrlib.workingtree import WorkingTree
 
66
from bzrlib.bzrdir import BzrDir
 
67
 
 
68
import os.path
 
69
 
85
70
def import_pygtk():
86
71
    try:
87
72
        import pygtk
92
77
 
93
78
 
94
79
def set_ui_factory():
95
 
    import_pygtk()
 
80
    pygtk = import_pygtk()
96
81
    from ui import GtkUIFactory
97
82
    import bzrlib.ui
98
83
    bzrlib.ui.ui_factory = GtkUIFactory()
99
84
 
100
85
 
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:
 
86
class cmd_gbranch(Command):
 
87
    """GTK+ branching.
 
88
    
 
89
    """
 
90
 
 
91
    def run(self):
 
92
        pygtk = import_pygtk()
 
93
        try:
 
94
            import gtk
 
95
        except RuntimeError, e:
 
96
            if str(e) == "could not open display":
 
97
                raise NoDisplayError
 
98
 
 
99
        from bzrlib.plugins.gtk.branch import BranchDialog
 
100
 
 
101
        set_ui_factory()
 
102
        dialog = BranchDialog(os.path.abspath('.'))
 
103
        dialog.run()
 
104
 
 
105
register_command(cmd_gbranch)
 
106
 
 
107
class cmd_gcheckout(Command):
 
108
    """ GTK+ checkout.
 
109
    
 
110
    """
 
111
    
 
112
    def run(self):
 
113
        pygtk = import_pygtk()
 
114
        try:
 
115
            import gtk
 
116
        except RuntimeError, e:
 
117
            if str(e) == "could not open display":
 
118
                raise NoDisplayError
 
119
 
 
120
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
 
121
 
 
122
        set_ui_factory()
 
123
        dialog = CheckoutDialog(os.path.abspath('.'))
 
124
        dialog.run()
 
125
 
 
126
register_command(cmd_gcheckout)
 
127
 
 
128
class cmd_gpush(Command):
 
129
    """ GTK+ push.
 
130
    
 
131
    """
 
132
    takes_args = [ "location?" ]
 
133
    
 
134
    def run(self, location="."):
 
135
        (branch, path) = Branch.open_containing(location)
 
136
        
 
137
        pygtk = import_pygtk()
 
138
        try:
 
139
            import gtk
 
140
        except RuntimeError, e:
 
141
            if str(e) == "could not open display":
 
142
                raise NoDisplayError
 
143
 
 
144
        from push import PushDialog
 
145
 
 
146
        set_ui_factory()
 
147
        dialog = PushDialog(branch)
 
148
        dialog.run()
 
149
 
 
150
register_command(cmd_gpush)
 
151
 
 
152
class cmd_gdiff(Command):
 
153
    """Show differences in working tree in a GTK+ Window.
 
154
    
 
155
    Otherwise, all changes for the tree are listed.
 
156
    """
 
157
    takes_args = ['filename?']
 
158
    takes_options = ['revision']
 
159
 
 
160
    @display_command
 
161
    def run(self, revision=None, filename=None):
 
162
        set_ui_factory()
 
163
        wt = WorkingTree.open_containing(".")[0]
 
164
        branch = wt.branch
 
165
        if revision is not None:
 
166
            if len(revision) == 1:
 
167
                tree1 = wt
 
168
                revision_id = revision[0].in_history(branch).rev_id
 
169
                tree2 = branch.repository.revision_tree(revision_id)
 
170
            elif len(revision) == 2:
 
171
                revision_id_0 = revision[0].in_history(branch).rev_id
 
172
                tree2 = branch.repository.revision_tree(revision_id_0)
 
173
                revision_id_1 = revision[1].in_history(branch).rev_id
 
174
                tree1 = branch.repository.revision_tree(revision_id_1)
 
175
        else:
 
176
            tree1 = wt
 
177
            tree2 = tree1.basis_tree()
 
178
 
 
179
        from viz.diff import DiffWindow
122
180
        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")
168
 
 
169
 
import gettext
170
 
gettext.install('olive-gtk')
171
 
 
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
 
 
176
 
class NoDisplayError(errors.BzrCommandError):
 
181
        window = DiffWindow()
 
182
        window.connect("destroy", lambda w: gtk.main_quit())
 
183
        window.set_diff("Working Tree", tree1, tree2)
 
184
        if filename is not None:
 
185
            tree_filename = wt.relpath(filename)
 
186
            try:
 
187
                window.set_file(tree_filename)
 
188
            except NoSuchFile:
 
189
                if (tree1.inventory.path2id(tree_filename) is None and 
 
190
                    tree2.inventory.path2id(tree_filename) is None):
 
191
                    raise NotVersionedError(filename)
 
192
                raise BzrCommandError('No changes found for file "%s"' % 
 
193
                                      filename)
 
194
        window.show()
 
195
 
 
196
        gtk.main()
 
197
 
 
198
register_command(cmd_gdiff)
 
199
 
 
200
class cmd_visualise(Command):
 
201
    """Graphically visualise this branch.
 
202
 
 
203
    Opens a graphical window to allow you to see the history of the branch
 
204
    and relationships between revisions in a visual manner,
 
205
 
 
206
    The default starting point is latest revision on the branch, you can
 
207
    specify a starting point with -r revision.
 
208
    """
 
209
    takes_options = [
 
210
        "revision",
 
211
        Option('limit', "maximum number of revisions to display",
 
212
               int, 'count')]
 
213
    takes_args = [ "location?" ]
 
214
    aliases = [ "visualize", "vis", "viz" ]
 
215
 
 
216
    def run(self, location=".", revision=None, limit=None):
 
217
        set_ui_factory()
 
218
        (branch, path) = Branch.open_containing(location)
 
219
        branch.lock_read()
 
220
        branch.repository.lock_read()
 
221
        try:
 
222
            if revision is None:
 
223
                revid = branch.last_revision()
 
224
                if revid is None:
 
225
                    return
 
226
            else:
 
227
                (revno, revid) = revision[0].in_history(branch)
 
228
 
 
229
            from viz.bzrkapp import BzrkApp
 
230
                
 
231
            app = BzrkApp()
 
232
            app.show(branch, revid, limit)
 
233
        finally:
 
234
            branch.repository.unlock()
 
235
            branch.unlock()
 
236
        app.main()
 
237
 
 
238
 
 
239
register_command(cmd_visualise)
 
240
 
 
241
class cmd_gannotate(Command):
 
242
    """GTK+ annotate.
 
243
    
 
244
    Browse changes to FILENAME line by line in a GTK+ window.
 
245
    """
 
246
 
 
247
    takes_args = ["filename", "line?"]
 
248
    takes_options = [
 
249
        Option("all", help="show annotations on all lines"),
 
250
        Option("plain", help="don't highlight annotation lines"),
 
251
        Option("line", type=int, argname="lineno",
 
252
               help="jump to specified line number"),
 
253
        "revision",
 
254
    ]
 
255
    aliases = ["gblame", "gpraise"]
 
256
    
 
257
    def run(self, filename, all=False, plain=False, line='1', revision=None):
 
258
        pygtk = import_pygtk()
 
259
 
 
260
        try:
 
261
            import gtk
 
262
        except RuntimeError, e:
 
263
            if str(e) == "could not open display":
 
264
                raise NoDisplayError
 
265
        set_ui_factory()
 
266
 
 
267
        try:
 
268
            line = int(line)
 
269
        except ValueError:
 
270
            raise BzrCommandError('Line argument ("%s") is not a number.' % 
 
271
                                  line)
 
272
 
 
273
        from annotate.gannotate import GAnnotateWindow
 
274
        from annotate.config import GAnnotateConfig
 
275
 
 
276
        try:
 
277
            (tree, path) = WorkingTree.open_containing(filename)
 
278
            branch = tree.branch
 
279
        except errors.NoWorkingTree:
 
280
            (branch, path) = Branch.open_containing(filename)
 
281
            tree = branch.basis_tree()
 
282
 
 
283
        file_id = tree.path2id(path)
 
284
 
 
285
        if file_id is None:
 
286
            raise NotVersionedError(filename)
 
287
        if revision is not None:
 
288
            if len(revision) != 1:
 
289
                raise BzrCommandError("Only 1 revion may be specified.")
 
290
            revision_id = revision[0].in_history(branch).rev_id
 
291
            tree = branch.repository.revision_tree(revision_id)
 
292
        else:
 
293
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
 
294
 
 
295
        window = GAnnotateWindow(all, plain)
 
296
        window.connect("destroy", lambda w: gtk.main_quit())
 
297
        window.set_title(path + " - gannotate")
 
298
        config = GAnnotateConfig(window)
 
299
        window.show()
 
300
        branch.lock_read()
 
301
        try:
 
302
            window.annotate(tree, branch, file_id)
 
303
        finally:
 
304
            branch.unlock()
 
305
        window.jump_to_line(line)
 
306
        
 
307
        gtk.main()
 
308
 
 
309
register_command(cmd_gannotate)
 
310
 
 
311
class cmd_gcommit(Command):
 
312
    """GTK+ commit dialog
 
313
 
 
314
    Graphical user interface for committing revisions"""
 
315
    
 
316
    aliases = [ "gci" ]
 
317
    takes_args = []
 
318
    takes_options = []
 
319
 
 
320
    def run(self, filename=None):
 
321
        import os
 
322
        pygtk = import_pygtk()
 
323
 
 
324
        try:
 
325
            import gtk
 
326
        except RuntimeError, e:
 
327
            if str(e) == "could not open display":
 
328
                raise NoDisplayError
 
329
 
 
330
        set_ui_factory()
 
331
        from commit import CommitDialog
 
332
        from bzrlib.commit import Commit
 
333
        from bzrlib.errors import (BzrCommandError,
 
334
                                   NotBranchError,
 
335
                                   NoWorkingTree,
 
336
                                   PointlessCommit,
 
337
                                   ConflictsInTree,
 
338
                                   StrictCommitFailed)
 
339
 
 
340
        wt = None
 
341
        branch = None
 
342
        try:
 
343
            (wt, path) = WorkingTree.open_containing(filename)
 
344
            branch = wt.branch
 
345
        except NotBranchError, e:
 
346
            path = e.path
 
347
        except NoWorkingTree, e:
 
348
            path = e.base
 
349
            try:
 
350
                (branch, path) = Branch.open_containing(path)
 
351
            except NotBranchError, e:
 
352
                path = e.path
 
353
 
 
354
 
 
355
        commit = CommitDialog(wt, path, not branch)
 
356
        commit.run()
 
357
 
 
358
register_command(cmd_gcommit)
 
359
 
 
360
class NoDisplayError(BzrCommandError):
177
361
    """gtk could not find a proper display"""
178
362
 
179
363
    def __str__(self):
180
364
        return "No DISPLAY. Unable to run GTK+ application."
181
365
 
182
 
 
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
 
        ]
200
 
    import sys
201
 
    default_encoding = sys.getdefaultencoding()
202
 
    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]))
210
 
    finally:
211
 
        if sys.getdefaultencoding() != default_encoding:
212
 
            reload(sys)
213
 
            sys.setdefaultencoding(default_encoding)
214
 
    return basic_tests
 
366
def test_suite():
 
367
    from unittest import TestSuite
 
368
    import tests
 
369
    result = TestSuite()
 
370
    result.addTest(tests.test_suite())
 
371
    return result