14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
"""brz upgrade logic."""
17
"""bzr upgrade logic."""
19
from __future__ import absolute_import
25
from .controldir import (
27
from bzrlib.controldir import (
29
from .i18n import gettext
30
from .bzr.remote import RemoteBzrDir
31
from bzrlib.i18n import gettext
32
from bzrlib.remote import RemoteBzrDir
33
35
class Convert(object):
51
53
raise AssertionError(
52
54
"either the url or control_dir parameter must be set.")
53
55
if control_dir is not None:
54
self.controldir = control_dir
56
self.bzrdir = control_dir
56
self.controldir = ControlDir.open_unsupported(url)
57
if isinstance(self.controldir, RemoteBzrDir):
58
self.controldir._ensure_real()
59
self.controldir = self.controldir._real_bzrdir
60
if self.controldir.root_transport.is_readonly():
58
self.bzrdir = ControlDir.open_unsupported(url)
59
if isinstance(self.bzrdir, RemoteBzrDir):
60
self.bzrdir._ensure_real()
61
self.bzrdir = self.bzrdir._real_bzrdir
62
if self.bzrdir.root_transport.is_readonly():
61
63
raise errors.UpgradeReadonly
62
self.transport = self.controldir.root_transport
64
self.transport = self.bzrdir.root_transport
63
65
ui.ui_factory.suppressed_warnings.add(warning_id)
72
branch = self.controldir.open_branch()
73
if branch.user_url != self.controldir.user_url:
74
branch = self.bzrdir.open_branch()
75
if branch.user_url != self.bzrdir.user_url:
74
76
ui.ui_factory.note(gettext(
75
77
'This is a checkout. The branch (%s) needs to be upgraded'
76
78
' separately.') % (urlutils.unescape_for_display(
83
85
if self.format is None:
85
rich_root = self.controldir.find_repository()._format.rich_root_data
87
rich_root = self.bzrdir.find_repository()._format.rich_root_data
86
88
except errors.NoRepositoryPresent:
87
rich_root = False # assume no rich roots
89
rich_root = False # assume no rich roots
89
91
format_name = "default-rich-root"
91
93
format_name = "default"
92
format = format_registry.make_controldir(format_name)
94
format = format_registry.make_bzrdir(format_name)
94
96
format = self.format
95
if not self.controldir.needs_format_conversion(format):
96
raise errors.UpToDateFormat(self.controldir._format)
97
if not self.controldir.can_convert_format():
97
if not self.bzrdir.needs_format_conversion(format):
98
raise errors.UpToDateFormat(self.bzrdir._format)
99
if not self.bzrdir.can_convert_format():
98
100
raise errors.BzrError(gettext("cannot upgrade from bzrdir format %s") %
99
self.controldir._format)
100
self.controldir.check_conversion_target(format)
101
ui.ui_factory.note(gettext('starting upgrade of %s') %
102
urlutils.unescape_for_display(self.transport.base, 'utf-8'))
102
self.bzrdir.check_conversion_target(format)
103
ui.ui_factory.note(gettext('starting upgrade of %s') %
104
urlutils.unescape_for_display(self.transport.base, 'utf-8'))
104
self.backup_oldpath, self.backup_newpath = self.controldir.backup_bzrdir()
105
while self.controldir.needs_format_conversion(format):
106
converter = self.controldir._format.get_converter(format)
107
self.controldir = converter.convert(self.controldir, None)
106
self.backup_oldpath, self.backup_newpath = self.bzrdir.backup_bzrdir()
107
while self.bzrdir.needs_format_conversion(format):
108
converter = self.bzrdir._format.get_converter(format)
109
self.bzrdir = converter.convert(self.bzrdir, None)
108
110
ui.ui_factory.note(gettext('finished'))
110
112
def clean_up(self):
115
117
transport = self.transport
116
118
backup_relpath = transport.relpath(self.backup_newpath)
117
with ui.ui_factory.nested_progress_bar() as child_pb:
118
child_pb.update(gettext('Deleting backup.bzr'))
119
child_pb = ui.ui_factory.nested_progress_bar()
120
child_pb.update(gettext('Deleting backup.bzr'))
119
122
transport.delete_tree(backup_relpath)
122
127
def upgrade(url, format=None, clean_up=False, dry_run=False):
123
128
"""Upgrade locations to format.
125
130
This routine wraps the smart_upgrade() routine with a nicer UI.
126
131
In particular, it ensures all URLs can be opened before starting
127
132
and reports a summary at the end if more than one upgrade was attempted.
128
This routine is useful for command line tools. Other breezy clients
133
This routine is useful for command line tools. Other bzrlib clients
129
134
probably ought to use smart_upgrade() instead.
131
136
:param url: a URL of the locations to upgrade.
138
143
control_dirs = [ControlDir.open_unsupported(url)]
139
144
attempted, succeeded, exceptions = smart_upgrade(control_dirs,
140
format, clean_up=clean_up, dry_run=dry_run)
145
format, clean_up=clean_up, dry_run=dry_run)
141
146
if len(attempted) > 1:
142
147
attempted_count = len(attempted)
143
148
succeeded_count = len(succeeded)
144
149
failed_count = attempted_count - succeeded_count
145
150
ui.ui_factory.note(
146
gettext('\nSUMMARY: {0} upgrades attempted, {1} succeeded,'
151
gettext('\nSUMMARY: {0} upgrades attempted, {1} succeeded,'\
147
152
' {2} failed').format(
148
attempted_count, succeeded_count, failed_count))
153
attempted_count, succeeded_count, failed_count))
149
154
return exceptions
152
157
def smart_upgrade(control_dirs, format, clean_up=False,
154
159
"""Convert control directories to a new format intelligently.
156
161
If the control directory is a shared repository, dependent branches
169
174
all_exceptions = []
170
175
for control_dir in control_dirs:
171
176
attempted, succeeded, exceptions = _smart_upgrade_one(control_dir,
172
format, clean_up=clean_up, dry_run=dry_run)
177
format, clean_up=clean_up, dry_run=dry_run)
173
178
all_attempted.extend(attempted)
174
179
all_succeeded.extend(succeeded)
175
180
all_exceptions.extend(exceptions)
203
208
ui.ui_factory.note(gettext('Found %d dependent branches - upgrading ...')
204
209
% (len(dependents),))
205
210
# Convert dependent branches
206
branch_cdirs = [b.controldir for b in dependents]
211
branch_cdirs = [b.bzrdir for b in dependents]
207
212
successes, problems = _convert_items(branch_cdirs, format, clean_up,
208
dry_run, label="branch")
213
dry_run, label="branch")
209
214
attempted.extend(branch_cdirs)
210
215
succeeded.extend(successes)
211
216
exceptions.extend(problems)
259
262
def _convert_items(items, format, clean_up, dry_run, label=None):
260
263
"""Convert a sequence of control directories to the given format.
262
265
:param items: the control directories to upgrade
263
266
:param format: the format to convert to or None for the best default
264
267
:param clean-up: if True, the backup.bzr directory is removed if the
272
with ui.ui_factory.nested_progress_bar() as child_pb:
273
child_pb.update(gettext('Upgrading bzrdirs'), 0, len(items))
274
for i, control_dir in enumerate(items):
276
location = control_dir.root_transport.base
277
bzr_object, bzr_label = _get_object_and_label(control_dir)
278
type_label = label or bzr_label
279
child_pb.update(gettext("Upgrading %s") %
280
(type_label), i + 1, len(items))
281
ui.ui_factory.note(gettext('Upgrading {0} {1} ...').format(type_label,
282
urlutils.unescape_for_display(location, 'utf-8'),))
275
child_pb = ui.ui_factory.nested_progress_bar()
276
child_pb.update(gettext('Upgrading bzrdirs'), 0, len(items))
277
for i, control_dir in enumerate(items):
279
location = control_dir.root_transport.base
280
bzr_object, bzr_label = _get_object_and_label(control_dir)
281
type_label = label or bzr_label
282
child_pb.update(gettext("Upgrading %s") % (type_label), i+1, len(items))
283
ui.ui_factory.note(gettext('Upgrading {0} {1} ...').format(type_label,
284
urlutils.unescape_for_display(location, 'utf-8'),))
287
cv = Convert(control_dir=control_dir, format=format)
288
except errors.UpToDateFormat, ex:
289
ui.ui_factory.note(str(ex))
290
succeeded.append(control_dir)
292
except Exception, ex:
293
trace.warning('conversion error: %s' % ex)
294
exceptions.append(ex)
297
# Do any required post processing
298
succeeded.append(control_dir)
301
ui.ui_factory.note(gettext('Removing backup ...'))
285
cv = Convert(control_dir=control_dir, format=format)
286
except errors.UpToDateFormat as ex:
287
ui.ui_factory.note(str(ex))
288
succeeded.append(control_dir)
290
except Exception as ex:
291
trace.warning('conversion error: %s' % ex)
304
except Exception, ex:
305
trace.warning(gettext('failed to clean-up {0}: {1}') % (location, ex))
292
306
exceptions.append(ex)
295
# Do any required post processing
296
succeeded.append(control_dir)
299
ui.ui_factory.note(gettext('Removing backup ...'))
302
except Exception as ex:
304
gettext('failed to clean-up {0}: {1}') % (location, ex))
305
exceptions.append(ex)
307
310
# Return the result
308
311
return succeeded, exceptions