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

  • Committer: Jelmer Vernooij
  • Date: 2008-06-29 18:31:29 UTC
  • mto: This revision was merged to the branch mainline in revision 518.
  • Revision ID: jelmer@samba.org-20080629183129-syqvz3xm5gqagzsx
Fix use of smart_add.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
 
2
# Copyright (C) 2007 by Jelmer Vernooij <jelmer@samba.org>
2
3
#
3
4
# This program is free software; you can redistribute it and/or modify
4
5
# it under the terms of the GNU General Public License as published by
22
23
    
23
24
import gtk
24
25
 
25
 
from olive import delimiter
26
26
from errors import show_bzr_error
27
27
 
 
28
# FIXME: This needs to be public JRV 20070714
 
29
from bzrlib.builtins import _create_prefix
28
30
from bzrlib.config import LocationConfig
29
31
import bzrlib.errors as errors
30
32
 
31
 
from olive.dialog import error_dialog, info_dialog, question_dialog
 
33
from bzrlib.plugins.gtk import _i18n
 
34
from dialog import error_dialog, info_dialog, question_dialog
32
35
 
 
36
from history import UrlHistory
33
37
 
34
38
class PushDialog(gtk.Dialog):
35
39
    """ New implementation of the Push dialog. """
36
 
    def __init__(self, branch, parent=None):
 
40
    def __init__(self, repository, revid, branch=None, parent=None):
37
41
        """ Initialize the Push dialog. """
38
42
        gtk.Dialog.__init__(self, title="Push - Olive",
39
43
                                  parent=parent,
41
45
                                  buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
42
46
        
43
47
        # Get arguments
 
48
        self.repository = repository
 
49
        self.revid = revid
44
50
        self.branch = branch
45
51
        
46
52
        # Create the widgets
47
 
        self._label_location = gtk.Label(_("Location:"))
48
 
        self._label_test = gtk.Label(_("(click the Test button to check write access)"))
49
 
        self._check_remember = gtk.CheckButton(_("_Remember as default location"),
50
 
                                               use_underline=True)
51
 
        self._check_prefix = gtk.CheckButton(_("Create the path _leading up to the location"),
52
 
                                             use_underline=True)
53
 
        self._check_overwrite = gtk.CheckButton(_("_Overwrite target if diverged"),
54
 
                                                use_underline=True)
 
53
        self._label_location = gtk.Label(_i18n("Location:"))
55
54
        self._combo = gtk.ComboBoxEntry()
56
 
        self._button_test = gtk.Button(_("_Test"), use_underline=True)
57
 
        self._button_push = gtk.Button(_("_Push"), use_underline=True)
 
55
        self._button_push = gtk.Button(_i18n("_Push"), use_underline=True)
58
56
        self._hbox_location = gtk.HBox()
59
 
        self._hbox_test = gtk.HBox()
60
 
        self._image_test = gtk.Image()
61
57
        
62
58
        # Set callbacks
63
 
        self._button_test.connect('clicked', self._on_test_clicked)
64
59
        self._button_push.connect('clicked', self._on_push_clicked)
65
60
        
66
61
        # Set properties
67
 
        self._image_test.set_from_stock(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_BUTTON)
68
62
        self._label_location.set_alignment(0, 0.5)
69
 
        self._label_test.set_alignment(0, 0.5)
70
63
        self._hbox_location.set_spacing(3)
71
 
        self._hbox_test.set_spacing(3)
72
64
        self.vbox.set_spacing(3)
73
65
        
74
66
        # Pack widgets
75
67
        self._hbox_location.pack_start(self._label_location, False, False)
76
68
        self._hbox_location.pack_start(self._combo, True, True)
77
 
        self._hbox_test.pack_start(self._image_test, False, False)
78
 
        self._hbox_test.pack_start(self._label_test, True, True)
79
69
        self.vbox.pack_start(self._hbox_location)
80
 
        self.vbox.pack_start(self._check_remember)
81
 
        self.vbox.pack_start(self._check_prefix)
82
 
        self.vbox.pack_start(self._check_overwrite)
83
 
        self.vbox.pack_start(self._hbox_test)
84
 
        self.action_area.pack_start(self._button_test)
85
70
        self.action_area.pack_end(self._button_push)
86
71
        
87
72
        # Show the dialog
88
73
        self.vbox.show_all()
89
74
        
90
75
        # Build location history
 
76
        self._history = UrlHistory(self.branch.get_config(), 'push_history')
91
77
        self._build_history()
92
78
        
93
79
    def _build_history(self):
94
80
        """ Build up the location history. """
95
 
        config = LocationConfig(self.branch.base)
96
 
        history = config.get_user_option('gpush_history')
97
 
        if history is not None:
98
 
            self._combo_model = gtk.ListStore(str)
99
 
            for item in history.split(delimiter):
100
 
                self._combo_model.append([ item ])
101
 
            self._combo.set_model(self._combo_model)
102
 
            self._combo.set_text_column(0)
103
 
        
104
 
        location = self.branch.get_push_location()
105
 
        if location:
106
 
            self._combo.get_child().set_text(location)
107
 
    
108
 
    def _add_to_history(self, location):
109
 
        """ Add specified location to the history (if not yet added). """
110
 
        config = LocationConfig(self.branch.base)
111
 
        history = config.get_user_option('gpush_history')
112
 
        if history is None:
113
 
            config.set_user_option('gpush_history', location)
114
 
        else:
115
 
            h = history.split(delimiter)
116
 
            if location not in h:
117
 
                h.append(location)
118
 
            config.set_user_option('gpush_history', delimiter.join(h))
119
 
    
120
 
    def _on_test_clicked(self, widget):
121
 
        """ Test button clicked handler. """
122
 
        import re
123
 
        _urlRE = re.compile(r'^(?P<proto>[^:/\\]+)://(?P<path>.*)$')
124
 
        
125
 
        url = self._combo.get_child().get_text()
126
 
        
127
 
        m = _urlRE.match(url)
128
 
        if m:
129
 
            proto = m.groupdict()['proto']
130
 
            if (proto == 'sftp') or (proto == 'file') or (proto == 'ftp'):
131
 
                # have write acces (most probably)
132
 
                self._image_test.set_from_stock(gtk.STOCK_YES, 4)
133
 
                self._label_test.set_markup(_('<b>Write access is probably available</b>'))
134
 
            else:
135
 
                # no write access
136
 
                self._image_test.set_from_stock(gtk.STOCK_NO, 4)
137
 
                self._label_test.set_markup(_('<b>No write access</b>'))
138
 
        else:
139
 
            # couldn't determine
140
 
            self._image_test.set_from_stock(gtk.STOCK_DIALOG_QUESTION, 4)
141
 
            self._label_test.set_markup(_('<b>Could not determine</b>'))
 
81
        self._combo_model = gtk.ListStore(str)
 
82
        for item in self._history.get_entries():
 
83
            self._combo_model.append([ item ])
 
84
        self._combo.set_model(self._combo_model)
 
85
        self._combo.set_text_column(0)
 
86
        
 
87
        if self.branch is not None:
 
88
            location = self.branch.get_push_location()
 
89
            if location is not None:
 
90
                self._combo.get_child().set_text(location)
142
91
    
143
92
    @show_bzr_error
144
93
    def _on_push_clicked(self, widget):
145
94
        """ Push button clicked handler. """
146
95
        location = self._combo.get_child().get_text()
147
96
        revs = 0
 
97
        if self.branch is not None and self.branch.get_push_location() is None:
 
98
            response = question_dialog(_i18n('Set default push location'),
 
99
                                       _i18n('There is no default push location set.\nSet %r as default now?') % location)
 
100
            if response == gtk.RESPONSE_OK:
 
101
                self.branch.set_push_location(location)
 
102
 
148
103
        try:
149
 
            revs = do_push(self.branch,
150
 
                           location=location,
151
 
                           overwrite=self._check_overwrite.get_active(),
152
 
                           remember=self._check_remember.get_active(),
153
 
                           create_prefix=self._check_prefix.get_active())
 
104
            revs = do_push(self.branch, location=location, overwrite=False)
154
105
        except errors.DivergedBranches:
155
 
            response = question_dialog(_('Branches have been diverged'),
156
 
                                       _('You cannot push if branches have diverged.\nOverwrite?'))
157
 
            if response == gtk.RESPONSE_OK:
158
 
                revs = do_push(self.branch, overwrite=True)
159
 
            return
 
106
            response = question_dialog(_i18n('Branches have been diverged'),
 
107
                                       _i18n('You cannot push if branches have diverged.\nOverwrite?'))
 
108
            if response == gtk.RESPONSE_YES:
 
109
                revs = do_push(self.branch, location=location, overwrite=True)
160
110
        
161
 
        self._add_to_history(location)
162
 
        info_dialog(_('Push successful'),
163
 
                    _("%d revision(s) pushed.") % revs)
 
111
        self._history.add_entry(location)
 
112
        info_dialog(_i18n('Push successful'),
 
113
                    _i18n("%d revision(s) pushed.") % revs)
164
114
        
165
115
        self.response(gtk.RESPONSE_OK)
166
116
 
167
 
def do_push(branch, location=None, remember=False, overwrite=False,
168
 
         create_prefix=False):
 
117
def do_push(br_from, location, overwrite):
169
118
    """ Update a mirror of a branch.
170
119
    
171
 
    :param branch: the source branch
 
120
    :param br_from: the source branch
172
121
    
173
122
    :param location: the location of the branch that you'd like to update
174
123
    
175
 
    :param remember: if set, the location will be stored
176
 
    
177
124
    :param overwrite: overwrite target location if it diverged
178
125
    
179
 
    :param create_prefix: create the path leading up to the branch if it doesn't exist
180
 
    
181
126
    :return: number of revisions pushed
182
127
    """
183
128
    from bzrlib.bzrdir import BzrDir
184
129
    from bzrlib.transport import get_transport
185
130
        
186
 
    br_from = branch
187
 
    
188
 
    stored_loc = br_from.get_push_location()
189
 
    if location is None:
190
 
        if stored_loc is None:
191
 
            error_dialog(_('Push location is unknown'),
192
 
                         _('Please specify a location manually.'))
193
 
            return
194
 
        else:
195
 
            location = stored_loc
196
 
 
197
131
    transport = get_transport(location)
198
132
    location_url = transport.base
199
133
 
200
 
    if br_from.get_push_location() is None or remember:
201
 
        br_from.set_push_location(location_url)
202
 
 
203
134
    old_rh = []
204
135
 
205
136
    try:
208
139
    except errors.NotBranchError:
209
140
        # create a branch.
210
141
        transport = transport.clone('..')
211
 
        if not create_prefix:
212
 
            try:
213
 
                relurl = transport.relpath(location_url)
214
 
                transport.mkdir(relurl)
215
 
            except errors.NoSuchFile:
216
 
                error_dialog(_('Non existing parent directory'),
217
 
                             _("The parent directory (%s)\ndoesn't exist.") % location)
 
142
        try:
 
143
            relurl = transport.relpath(location_url)
 
144
            transport.mkdir(relurl)
 
145
        except errors.NoSuchFile:
 
146
            response = question_dialog(_i18n('Non existing parent directory'),
 
147
                         _i18n("The parent directory (%s)\ndoesn't exist. Create?") % location)
 
148
            if response == gtk.RESPONSE_OK:
 
149
                _create_prefix(transport)
 
150
            else:
218
151
                return
219
 
        else:
220
 
            current = transport.base
221
 
            needed = [(transport, transport.relpath(location_url))]
222
 
            while needed:
223
 
                try:
224
 
                    transport, relpath = needed[-1]
225
 
                    transport.mkdir(relpath)
226
 
                    needed.pop()
227
 
                except errors.NoSuchFile:
228
 
                    new_transport = transport.clone('..')
229
 
                    needed.append((new_transport,
230
 
                                   new_transport.relpath(transport.base)))
231
 
                    if new_transport.base == transport.base:
232
 
                        error_dialog(_('Path prefix not created'),
233
 
                                     _("The path leading up to the specified location couldn't\nbe created."))
234
 
                        return
235
152
        dir_to = br_from.bzrdir.clone(location_url,
236
153
            revision_id=br_from.last_revision())
237
154
        br_to = dir_to.open_branch()
242
159
            tree_to = dir_to.open_workingtree()
243
160
        except errors.NotLocalUrl:
244
161
            # FIXME - what to do here? how should we warn the user?
245
 
            #warning('This transport does not update the working '
246
 
            #        'tree of: %s' % (br_to.base,))
247
162
            count = br_to.pull(br_from, overwrite)
248
163
        except errors.NoWorkingTree:
249
164
            count = br_to.pull(br_from, overwrite)