/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 commands.py

  • Committer: Vincent Ladeuil
  • Date: 2008-06-10 15:25:47 UTC
  • mto: This revision was merged to the branch mainline in revision 504.
  • Revision ID: v.ladeuil+lp@free.fr-20080610152547-dwmil1p8pd0mfpnl
Fix third failing test (thanks to jam).

* tests/test_commit.py:
(TestPendingRevisions.test_pending_revisions_multi_merge): Fix
provided by jam: bzr we now filter the pending merges so that only
the 'heads()' are included. We just ensure that the pending merges
contain the unique tips for the ancestries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# This program is free software; you can redistribute it and/or modify
2
 
# it under the terms of the GNU General Public License as published by
3
 
# the Free Software Foundation; either version 2 of the License, or
4
 
# (at your option) any later version.
5
 
 
6
 
# This program is distributed in the hope that it will be useful,
7
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
8
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9
 
# GNU General Public License for more details.
10
 
 
11
 
# You should have received a copy of the GNU General Public License
12
 
# along with this program; if not, write to the Free Software
13
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14
 
 
15
 
import os
16
 
 
17
 
from bzrlib import (
18
 
    branch,
19
 
    builtins,
20
 
    workingtree,
21
 
    )
22
 
from bzrlib.commands import (
23
 
    Command,
24
 
    display_command,
25
 
    )
26
 
from bzrlib.errors import (
27
 
    BzrCommandError,
28
 
    NoWorkingTree,
29
 
    NotVersionedError,
30
 
    NoSuchFile,
31
 
    )
32
 
from bzrlib.option import Option
33
 
 
34
 
from bzrlib.plugins.gtk import (
35
 
    _i18n,
36
 
    open_display,
37
 
    import_pygtk,
38
 
    set_ui_factory,
39
 
    )
40
 
 
41
 
class GTKCommand(Command):
42
 
    """Abstract class providing GTK specific run commands."""
43
 
 
44
 
    def run(self):
45
 
        open_display()
46
 
        dialog = self.get_gtk_dialog(os.path.abspath('.'))
47
 
        dialog.run()
48
 
 
49
 
 
50
 
class cmd_gbranch(GTKCommand):
51
 
    """GTK+ branching.
52
 
    
53
 
    """
54
 
 
55
 
    def get_gtk_dialog(self, path):
56
 
        from bzrlib.plugins.gtk.branch import BranchDialog
57
 
        return BranchDialog(path)
58
 
 
59
 
 
60
 
class cmd_gcheckout(GTKCommand):
61
 
    """ GTK+ checkout.
62
 
    
63
 
    """
64
 
    
65
 
    def get_gtk_dialog(self, path):
66
 
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
67
 
        return CheckoutDialog(path)
68
 
 
69
 
 
70
 
 
71
 
class cmd_gpush(GTKCommand):
72
 
    """ GTK+ push.
73
 
    
74
 
    """
75
 
    takes_args = [ "location?" ]
76
 
 
77
 
    def run(self, location="."):
78
 
        (br, path) = branch.Branch.open_containing(location)
79
 
        open_display()
80
 
        from bzrlib.plugins.gtk.push import PushDialog
81
 
        dialog = PushDialog(br.repository, br.last_revision(), br)
82
 
        dialog.run()
83
 
 
84
 
 
85
 
class cmd_gloom(GTKCommand):
86
 
    """ GTK+ loom.
87
 
    
88
 
    """
89
 
    takes_args = [ "location?" ]
90
 
 
91
 
    def run(self, location="."):
92
 
        try:
93
 
            (tree, path) = workingtree.WorkingTree.open_containing(location)
94
 
            br = tree.branch
95
 
        except NoWorkingTree, e:
96
 
            (br, path) = branch.Branch.open_containing(location)
97
 
            tree = None
98
 
        open_display()
99
 
        from bzrlib.plugins.gtk.loom import LoomDialog
100
 
        dialog = LoomDialog(br, tree)
101
 
        dialog.run()
102
 
 
103
 
 
104
 
class cmd_gdiff(GTKCommand):
105
 
    """Show differences in working tree in a GTK+ Window.
106
 
    
107
 
    Otherwise, all changes for the tree are listed.
108
 
    """
109
 
    takes_args = ['filename?']
110
 
    takes_options = ['revision']
111
 
 
112
 
    @display_command
113
 
    def run(self, revision=None, filename=None):
114
 
        set_ui_factory()
115
 
        wt = workingtree.WorkingTree.open_containing(".")[0]
116
 
        wt.lock_read()
117
 
        try:
118
 
            branch = wt.branch
119
 
            if revision is not None:
120
 
                if len(revision) == 1:
121
 
                    tree1 = wt
122
 
                    revision_id = revision[0].as_revision_id(tree1.branch)
123
 
                    tree2 = branch.repository.revision_tree(revision_id)
124
 
                elif len(revision) == 2:
125
 
                    revision_id_0 = revision[0].as_revision_id(branch)
126
 
                    tree2 = branch.repository.revision_tree(revision_id_0)
127
 
                    revision_id_1 = revision[1].as_revision_id(branch)
128
 
                    tree1 = branch.repository.revision_tree(revision_id_1)
129
 
            else:
130
 
                tree1 = wt
131
 
                tree2 = tree1.basis_tree()
132
 
 
133
 
            from diff import DiffWindow
134
 
            import gtk
135
 
            window = DiffWindow()
136
 
            window.connect("destroy", gtk.main_quit)
137
 
            window.set_diff("Working Tree", tree1, tree2)
138
 
            if filename is not None:
139
 
                tree_filename = wt.relpath(filename)
140
 
                try:
141
 
                    window.set_file(tree_filename)
142
 
                except NoSuchFile:
143
 
                    if (tree1.path2id(tree_filename) is None and 
144
 
                        tree2.path2id(tree_filename) is None):
145
 
                        raise NotVersionedError(filename)
146
 
                    raise BzrCommandError('No changes found for file "%s"' % 
147
 
                                          filename)
148
 
            window.show()
149
 
 
150
 
            gtk.main()
151
 
        finally:
152
 
            wt.unlock()
153
 
 
154
 
 
155
 
def start_viz_window(branch, revisions, limit=None):
156
 
    """Start viz on branch with revision revision.
157
 
    
158
 
    :return: The viz window object.
159
 
    """
160
 
    from bzrlib.plugins.gtk.viz import BranchWindow
161
 
    return BranchWindow(branch, revisions, limit)
162
 
 
163
 
 
164
 
class cmd_visualise(Command):
165
 
    """Graphically visualise this branch.
166
 
 
167
 
    Opens a graphical window to allow you to see the history of the branch
168
 
    and relationships between revisions in a visual manner,
169
 
 
170
 
    The default starting point is latest revision on the branch, you can
171
 
    specify a starting point with -r revision.
172
 
    """
173
 
    takes_options = [
174
 
        "revision",
175
 
        Option('limit', "Maximum number of revisions to display.",
176
 
               int, 'count')]
177
 
    takes_args = [ "locations*" ]
178
 
    aliases = [ "visualize", "vis", "viz" ]
179
 
 
180
 
    def run(self, locations_list, revision=None, limit=None):
181
 
        set_ui_factory()
182
 
        if locations_list is None:
183
 
            locations_list = ["."]
184
 
        revids = []
185
 
        for location in locations_list:
186
 
            (br, path) = branch.Branch.open_containing(location)
187
 
            if revision is None:
188
 
                revids.append(br.last_revision())
189
 
            else:
190
 
                revids.append(revision[0].as_revision_id(br))
191
 
        import gtk
192
 
        pp = start_viz_window(br, revids, limit)
193
 
        pp.connect("destroy", lambda w: gtk.main_quit())
194
 
        pp.show()
195
 
        gtk.main()
196
 
 
197
 
 
198
 
class cmd_gannotate(GTKCommand):
199
 
    """GTK+ annotate.
200
 
    
201
 
    Browse changes to FILENAME line by line in a GTK+ window.
202
 
 
203
 
    Within the annotate window, you can use Ctrl-F to search for text, and 
204
 
    Ctrl-G to jump to a line by number.
205
 
    """
206
 
 
207
 
    takes_args = ["filename", "line?"]
208
 
    takes_options = [
209
 
        Option("all", help="Show annotations on all lines."),
210
 
        Option("plain", help="Don't highlight annotation lines."),
211
 
        Option("line", type=int, argname="lineno",
212
 
               help="Jump to specified line number."),
213
 
        "revision",
214
 
    ]
215
 
    aliases = ["gblame", "gpraise"]
216
 
    
217
 
    def run(self, filename, all=False, plain=False, line='1', revision=None):
218
 
        gtk = open_display()
219
 
 
220
 
        try:
221
 
            line = int(line)
222
 
        except ValueError:
223
 
            raise BzrCommandError('Line argument ("%s") is not a number.' % 
224
 
                                  line)
225
 
 
226
 
        from annotate.gannotate import GAnnotateWindow
227
 
        from annotate.config import GAnnotateConfig
228
 
        from bzrlib.bzrdir import BzrDir
229
 
 
230
 
        wt, br, path = BzrDir.open_containing_tree_or_branch(filename)
231
 
        if wt is not None:
232
 
            tree = wt
233
 
        else:
234
 
            tree = br.basis_tree()
235
 
 
236
 
        file_id = tree.path2id(path)
237
 
 
238
 
        if file_id is None:
239
 
            raise NotVersionedError(filename)
240
 
        if revision is not None:
241
 
            if len(revision) != 1:
242
 
                raise BzrCommandError("Only 1 revion may be specified.")
243
 
            revision_id = revision[0].as_revision_id(br)
244
 
            tree = br.repository.revision_tree(revision_id)
245
 
        else:
246
 
            revision_id = getattr(tree, 'get_revision_id', lambda: None)()
247
 
 
248
 
        window = GAnnotateWindow(all, plain, branch=br)
249
 
        window.connect("destroy", lambda w: gtk.main_quit())
250
 
        config = GAnnotateConfig(window)
251
 
        window.show()
252
 
        br.lock_read()
253
 
        if wt is not None:
254
 
            wt.lock_read()
255
 
        try:
256
 
            window.annotate(tree, br, file_id)
257
 
            window.jump_to_line(line)
258
 
            gtk.main()
259
 
        finally:
260
 
            br.unlock()
261
 
            if wt is not None:
262
 
                wt.unlock()
263
 
 
264
 
 
265
 
 
266
 
class cmd_gcommit(GTKCommand):
267
 
    """GTK+ commit dialog
268
 
 
269
 
    Graphical user interface for committing revisions"""
270
 
 
271
 
    aliases = [ "gci" ]
272
 
    takes_args = []
273
 
    takes_options = []
274
 
 
275
 
    def run(self, filename=None):
276
 
        open_display()
277
 
        from commit import CommitDialog
278
 
 
279
 
        wt = None
280
 
        br = None
281
 
        try:
282
 
            (wt, path) = workingtree.WorkingTree.open_containing(filename)
283
 
            br = wt.branch
284
 
        except NoWorkingTree, e:
285
 
            from dialog import error_dialog
286
 
            error_dialog(_i18n('Directory does not have a working tree'),
287
 
                         _i18n('Operation aborted.'))
288
 
            return 1 # should this be retval=3?
289
 
 
290
 
        # It is a good habit to keep things locked for the duration, but it
291
 
        # could cause difficulties if someone wants to do things in another
292
 
        # window... We could lock_read() until we actually go to commit
293
 
        # changes... Just a thought.
294
 
        wt.lock_write()
295
 
        try:
296
 
            dlg = CommitDialog(wt)
297
 
            return dlg.run()
298
 
        finally:
299
 
            wt.unlock()
300
 
 
301
 
 
302
 
class cmd_gstatus(GTKCommand):
303
 
    """GTK+ status dialog
304
 
 
305
 
    Graphical user interface for showing status 
306
 
    information."""
307
 
 
308
 
    aliases = [ "gst" ]
309
 
    takes_args = ['PATH?']
310
 
    takes_options = ['revision']
311
 
 
312
 
    def run(self, path='.', revision=None):
313
 
        gtk = open_display()
314
 
        from bzrlib.plugins.gtk.status import StatusWindow
315
 
        (wt, wt_path) = workingtree.WorkingTree.open_containing(path)
316
 
 
317
 
        if revision is not None:
318
 
            try:
319
 
                revision_id = revision[0].as_revision_id(wt.branch)
320
 
            except:
321
 
                from bzrlib.errors import BzrError
322
 
                raise BzrError('Revision %r doesn\'t exist'
323
 
                               % revision[0].user_spec )
324
 
        else:
325
 
            revision_id = None
326
 
 
327
 
        status = StatusWindow(wt, wt_path, revision_id)
328
 
        status.connect("destroy", gtk.main_quit)
329
 
        status.show()
330
 
        gtk.main()
331
 
 
332
 
 
333
 
class cmd_gsend(GTKCommand):
334
 
    """GTK+ send merge directive.
335
 
 
336
 
    """
337
 
    def run(self):
338
 
        (br, path) = branch.Branch.open_containing(".")
339
 
        gtk = open_display()
340
 
        from bzrlib.plugins.gtk.mergedirective import SendMergeDirectiveDialog
341
 
        from StringIO import StringIO
342
 
        dialog = SendMergeDirectiveDialog(br)
343
 
        if dialog.run() == gtk.RESPONSE_OK:
344
 
            outf = StringIO()
345
 
            outf.writelines(dialog.get_merge_directive().to_lines())
346
 
            mail_client = br.get_config().get_mail_client()
347
 
            mail_client.compose_merge_request(dialog.get_mail_to(), "[MERGE]", 
348
 
                outf.getvalue())
349
 
 
350
 
            
351
 
 
352
 
 
353
 
class cmd_gconflicts(GTKCommand):
354
 
    """GTK+ conflicts.
355
 
    
356
 
    Select files from the list of conflicts and run an external utility to
357
 
    resolve them.
358
 
    """
359
 
    def run(self):
360
 
        (wt, path) = workingtree.WorkingTree.open_containing('.')
361
 
        open_display()
362
 
        from bzrlib.plugins.gtk.conflicts import ConflictsDialog
363
 
        dialog = ConflictsDialog(wt)
364
 
        dialog.run()
365
 
 
366
 
 
367
 
class cmd_gpreferences(GTKCommand):
368
 
    """ GTK+ preferences dialog.
369
 
 
370
 
    """
371
 
    def run(self):
372
 
        open_display()
373
 
        from bzrlib.plugins.gtk.preferences import PreferencesWindow
374
 
        dialog = PreferencesWindow()
375
 
        dialog.run()
376
 
 
377
 
 
378
 
class cmd_ginfo(Command):
379
 
    """ GTK+ info dialog
380
 
    
381
 
    """
382
 
    def run(self):
383
 
        from bzrlib import workingtree
384
 
        from bzrlib.plugins.gtk.olive.info import InfoDialog
385
 
        wt = workingtree.WorkingTree.open_containing('.')[0]
386
 
        info = InfoDialog(wt.branch)
387
 
        info.display()
388
 
        info.window.run()
389
 
 
390
 
 
391
 
class cmd_gmerge(Command):
392
 
    """ GTK+ merge dialog
393
 
    
394
 
    """
395
 
    takes_args = ["merge_from_path?"]
396
 
    def run(self, merge_from_path=None):
397
 
        from bzrlib.plugins.gtk.dialog import error_dialog
398
 
        from bzrlib.plugins.gtk.merge import MergeDialog
399
 
        
400
 
        (wt, path) = workingtree.WorkingTree.open_containing('.')
401
 
        old_tree = wt.branch.repository.revision_tree(wt.branch.last_revision())
402
 
        delta = wt.changes_from(old_tree)
403
 
        if len(delta.added) or len(delta.removed) or len(delta.renamed) or len(delta.modified):
404
 
            error_dialog(_i18n('There are local changes in the branch'),
405
 
                         _i18n('Please commit or revert the changes before merging.'))
406
 
        else:
407
 
            parent_branch_path = wt.branch.get_parent()
408
 
            merge = MergeDialog(wt, path, parent_branch_path)
409
 
            response = merge.run()
410
 
            merge.destroy()
411
 
 
412
 
 
413
 
class cmd_gmissing(Command):
414
 
    """ GTK+ missing revisions dialog.
415
 
 
416
 
    """
417
 
    takes_args = ["other_branch?"]
418
 
    def run(self, other_branch=None):
419
 
        pygtk = import_pygtk()
420
 
        try:
421
 
            import gtk
422
 
        except RuntimeError, e:
423
 
            if str(e) == "could not open display":
424
 
                raise NoDisplayError
425
 
 
426
 
        from bzrlib.plugins.gtk.missing import MissingWindow
427
 
        from bzrlib.branch import Branch
428
 
 
429
 
        local_branch = Branch.open_containing(".")[0]
430
 
        if other_branch is None:
431
 
            other_branch = local_branch.get_parent()
432
 
            
433
 
            if other_branch is None:
434
 
                raise BzrCommandError("No peer location known or specified.")
435
 
        remote_branch = Branch.open_containing(other_branch)[0]
436
 
        set_ui_factory()
437
 
        local_branch.lock_read()
438
 
        try:
439
 
            remote_branch.lock_read()
440
 
            try:
441
 
                dialog = MissingWindow(local_branch, remote_branch)
442
 
                dialog.run()
443
 
            finally:
444
 
                remote_branch.unlock()
445
 
        finally:
446
 
            local_branch.unlock()
447
 
 
448
 
 
449
 
class cmd_ginit(GTKCommand):
450
 
    """ GTK+ init dialog
451
 
 
452
 
    Graphical user interface for initializing new branches.
453
 
 
454
 
    """
455
 
    def run(self):
456
 
        open_display()
457
 
        from initialize import InitDialog
458
 
        dialog = InitDialog(os.path.abspath(os.path.curdir))
459
 
        dialog.run()
460
 
 
461
 
 
462
 
class cmd_gtags(GTKCommand):
463
 
    """ GTK+ tags dialog 
464
 
 
465
 
    Graphical user interface to view, create, or remove tags.
466
 
 
467
 
    """
468
 
    def run(self):
469
 
        br = branch.Branch.open_containing('.')[0]
470
 
        
471
 
        gtk = open_display()
472
 
        from tags import TagsWindow
473
 
        window = TagsWindow(br)
474
 
        window.show()
475
 
        gtk.main()
476
 
 
477
 
 
478
 
class cmd_gselftest(GTKCommand):
479
 
    """Version of selftest that displays a notification at the end"""
480
 
 
481
 
    takes_args = builtins.cmd_selftest.takes_args
482
 
    takes_options = builtins.cmd_selftest.takes_options
483
 
    _see_also = ['selftest']
484
 
 
485
 
    def run(self, *args, **kwargs):
486
 
        import cgi
487
 
        import sys
488
 
        default_encoding = sys.getdefaultencoding()
489
 
        # prevent gtk from blowing up later
490
 
        gtk = import_pygtk()
491
 
        # prevent gtk from messing with default encoding
492
 
        import pynotify
493
 
        if sys.getdefaultencoding() != default_encoding:
494
 
            reload(sys)
495
 
            sys.setdefaultencoding(default_encoding)
496
 
        result = builtins.cmd_selftest().run(*args, **kwargs)
497
 
        if result == 0:
498
 
            summary = 'Success'
499
 
            body = 'Selftest succeeded in "%s"' % os.getcwd()
500
 
        if result == 1:
501
 
            summary = 'Failure'
502
 
            body = 'Selftest failed in "%s"' % os.getcwd()
503
 
        pynotify.init("bzr gselftest")
504
 
        note = pynotify.Notification(cgi.escape(summary), cgi.escape(body))
505
 
        note.set_timeout(pynotify.EXPIRES_NEVER)
506
 
        note.show()