~bzr-pqm/bzr/bzr.dev

5557.1.7 by John Arbash Meinel
Merge in the bzr.dev 5582
1
# Copyright (C) 2005, 2006, 2008-2011 Canonical Ltd
1267 by Martin Pool
- notes on conversion of existing history to weaves
2
#
1080 by Martin Pool
- test tool for converting history to weave files
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1267 by Martin Pool
- notes on conversion of existing history to weaves
7
#
1080 by Martin Pool
- test tool for converting history to weave files
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1267 by Martin Pool
- notes on conversion of existing history to weaves
12
#
1080 by Martin Pool
- test tool for converting history to weave files
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1080 by Martin Pool
- test tool for converting history to weave files
16
1534.4.34 by Robert Collins
Fix remaining uses of deprecated apis within bzrlib.
17
"""bzr upgrade logic."""
18
3943.2.1 by Martin Pool
doc/import cleanups
19
4360.10.40 by Vincent Ladeuil
Fix imports ;)
20
from bzrlib import (
21
    errors,
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
22
    trace,
4360.10.40 by Vincent Ladeuil
Fix imports ;)
23
    ui,
6072.3.1 by Jelmer Vernooij
Format URLs in ``bzr upgrade`` before display.
24
    urlutils,
4360.10.40 by Vincent Ladeuil
Fix imports ;)
25
    )
5582.10.8 by Jelmer Vernooij
More fixes.
26
from bzrlib.bzrdir import (
27
    BzrDir,
28
    format_registry,
29
    )
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
30
from bzrlib.i18n import gettext
3577.4.1 by Andrew Bennetts
Make 'bzr upgrade' work over HPSS.
31
from bzrlib.remote import RemoteBzrDir
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
32
33
34
class Convert(object):
35
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
36
    def __init__(self, url=None, format=None, control_dir=None):
37
        """Convert a Bazaar control directory to a given format.
38
39
        Either the url or control_dir parameter must be given.
40
41
        :param url: the URL of the control directory or None if the
42
          control_dir is explicitly given instead
43
        :param format: the format to convert to or None for the default
4360.10.10 by Ian Clatworthy
minor clean-ups
44
        :param control_dir: the control directory or None if it is
45
          specified via the URL parameter instead
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
46
        """
1534.5.13 by Robert Collins
Correct buggy test.
47
        self.format = format
4634.144.9 by Martin Pool
Suppress user warnings about cross-format fetch during upgrade
48
        # XXX: Change to cleanup
49
        warning_id = 'cross_format_fetch'
4634.144.11 by Martin Pool
Rename squelched to suppressed
50
        saved_warning = warning_id in ui.ui_factory.suppressed_warnings
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
51
        if url is None and control_dir is None:
52
            raise AssertionError(
53
                "either the url or control_dir parameter must be set.")
54
        if control_dir is not None:
55
            self.bzrdir = control_dir
56
        else:
57
            self.bzrdir = BzrDir.open_unsupported(url)
3577.4.1 by Andrew Bennetts
Make 'bzr upgrade' work over HPSS.
58
        if isinstance(self.bzrdir, RemoteBzrDir):
59
            self.bzrdir._ensure_real()
60
            self.bzrdir = self.bzrdir._real_bzrdir
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
61
        if self.bzrdir.root_transport.is_readonly():
62
            raise errors.UpgradeReadonly
63
        self.transport = self.bzrdir.root_transport
4634.144.11 by Martin Pool
Rename squelched to suppressed
64
        ui.ui_factory.suppressed_warnings.add(warning_id)
1594.1.3 by Robert Collins
Fixup pb usage to use nested_progress_bar.
65
        try:
66
            self.convert()
67
        finally:
4634.144.9 by Martin Pool
Suppress user warnings about cross-format fetch during upgrade
68
            if not saved_warning:
4634.144.11 by Martin Pool
Rename squelched to suppressed
69
                ui.ui_factory.suppressed_warnings.remove(warning_id)
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
70
71
    def convert(self):
1558.7.2 by Aaron Bentley
Upgrade works in repositories
72
        try:
73
            branch = self.bzrdir.open_branch()
5158.6.9 by Martin Pool
Simplify various code to use user_url
74
            if branch.user_url != self.bzrdir.user_url:
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
75
                ui.ui_factory.note(gettext(
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
76
                    'This is a checkout. The branch (%s) needs to be upgraded'
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
77
                    ' separately.') % (urlutils.unescape_for_display(
6072.3.2 by Jelmer Vernooij
Use utf8 as encoding for urls passed to note().
78
                        branch.user_url, 'utf-8')))
3602.2.1 by Martin Pool
Fix and test for problem upgrading stacked branches
79
            del branch
80
        except (errors.NotBranchError, errors.IncompatibleRepositories):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
81
            # might not be a format we can open without upgrading; see e.g.
3602.2.1 by Martin Pool
Fix and test for problem upgrading stacked branches
82
            # https://bugs.launchpad.net/bzr/+bug/253891
1558.7.2 by Aaron Bentley
Upgrade works in repositories
83
            pass
4119.7.1 by Jelmer Vernooij
Make upgrade default to a rich-root-capable format if the source format uses rich roots.
84
        if self.format is None:
4170.3.5 by Jelmer Vernooij
Fix upgrade if there is no local repository present.
85
            try:
86
                rich_root = self.bzrdir.find_repository()._format.rich_root_data
87
            except errors.NoRepositoryPresent:
88
                rich_root = False # assume no rich roots
89
            if rich_root:
4119.7.1 by Jelmer Vernooij
Make upgrade default to a rich-root-capable format if the source format uses rich roots.
90
                format_name = "default-rich-root"
91
            else:
92
                format_name = "default"
93
            format = format_registry.make_bzrdir(format_name)
94
        else:
95
            format = self.format
96
        if not self.bzrdir.needs_format_conversion(format):
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
97
            raise errors.UpToDateFormat(self.bzrdir._format)
1534.5.16 by Robert Collins
Review feedback.
98
        if not self.bzrdir.can_convert_format():
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
99
            raise errors.BzrError(gettext("cannot upgrade from bzrdir format %s") %
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
100
                           self.bzrdir._format)
4119.7.1 by Jelmer Vernooij
Make upgrade default to a rich-root-capable format if the source format uses rich roots.
101
        self.bzrdir.check_conversion_target(format)
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
102
        ui.ui_factory.note(gettext('starting upgrade of %s') % 
6072.3.2 by Jelmer Vernooij
Use utf8 as encoding for urls passed to note().
103
            urlutils.unescape_for_display(self.transport.base, 'utf-8'))
4471.2.2 by Martin Pool
Deprecate ProgressTask.note
104
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
105
        self.backup_oldpath, self.backup_newpath = self.bzrdir.backup_bzrdir()
4119.7.1 by Jelmer Vernooij
Make upgrade default to a rich-root-capable format if the source format uses rich roots.
106
        while self.bzrdir.needs_format_conversion(format):
107
            converter = self.bzrdir._format.get_converter(format)
4961.2.15 by Martin Pool
Remove more pb-passing
108
            self.bzrdir = converter.convert(self.bzrdir, None)
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
109
        ui.ui_factory.note(gettext('finished'))
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
110
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
111
    def clean_up(self):
112
        """Clean-up after a conversion.
113
114
        This removes the backup.bzr directory.
115
        """
4360.10.12 by Ian Clatworthy
use transport.delete_tree() instead of osutils.rmtree() for clean-up
116
        transport = self.transport
117
        backup_relpath = transport.relpath(self.backup_newpath)
4360.10.27 by Matthew Fuller
Wrap a progress bar around removing the backup dir; it may take a
118
        child_pb = ui.ui_factory.nested_progress_bar()
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
119
        child_pb.update(gettext('Deleting backup.bzr'))
4360.10.27 by Matthew Fuller
Wrap a progress bar around removing the backup dir; it may take a
120
        try:
121
            transport.delete_tree(backup_relpath)
122
        finally:
123
            child_pb.finished()
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
124
125
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
126
def upgrade(url, format=None, clean_up=False, dry_run=False):
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
127
    """Upgrade locations to format.
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
128
 
129
    This routine wraps the smart_upgrade() routine with a nicer UI.
130
    In particular, it ensures all URLs can be opened before starting
131
    and reports a summary at the end if more than one upgrade was attempted.
132
    This routine is useful for command line tools. Other bzrlib clients
133
    probably ought to use smart_upgrade() instead.
134
4360.10.28 by Matthew Fuller
Revert upgrade() to taking only a single URL. Other code attempting
135
    :param url: a URL of the locations to upgrade.
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
136
    :param format: the format to convert to or None for the best default
137
    :param clean-up: if True, the backup.bzr directory is removed if the
138
      upgrade succeeded for a given repo/branch/tree
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
139
    :param dry_run: show what would happen but don't actually do any upgrades
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
140
    :return: the list of exceptions encountered
141
    """
4360.10.28 by Matthew Fuller
Revert upgrade() to taking only a single URL. Other code attempting
142
    control_dirs = [BzrDir.open_unsupported(url)]
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
143
    attempted, succeeded, exceptions = smart_upgrade(control_dirs,
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
144
        format, clean_up=clean_up, dry_run=dry_run)
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
145
    if len(attempted) > 1:
146
        attempted_count = len(attempted)
147
        succeeded_count = len(succeeded)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
148
        failed_count = attempted_count - succeeded_count
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
149
        ui.ui_factory.note(
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
150
            gettext('\nSUMMARY: {0} upgrades attempted, {1} succeeded,'\
151
                    ' {2} failed').format(
152
                     attempted_count, succeeded_count, failed_count))
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
153
    return exceptions
154
155
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
156
def smart_upgrade(control_dirs, format, clean_up=False,
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
157
    dry_run=False):
158
    """Convert control directories to a new format intelligently.
159
160
    If the control directory is a shared repository, dependent branches
161
    are also converted provided the repository converted successfully.
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
162
    If the conversion of a branch fails, remaining branches are still tried.
163
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
164
    :param control_dirs: the BzrDirs to upgrade
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
165
    :param format: the format to convert to or None for the best default
4360.10.29 by Matthew Fuller
The param is clean_up, not clean-up.
166
    :param clean_up: if True, the backup.bzr directory is removed if the
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
167
      upgrade succeeded for a given repo/branch/tree
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
168
    :param dry_run: show what would happen but don't actually do any upgrades
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
169
    :return: attempted-control-dirs, succeeded-control-dirs, exceptions
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
170
    """
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
171
    all_attempted = []
172
    all_succeeded = []
173
    all_exceptions = []
174
    for control_dir in control_dirs:
175
        attempted, succeeded, exceptions = _smart_upgrade_one(control_dir,
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
176
            format, clean_up=clean_up, dry_run=dry_run)
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
177
        all_attempted.extend(attempted)
178
        all_succeeded.extend(succeeded)
179
        all_exceptions.extend(exceptions)
180
    return all_attempted, all_succeeded, all_exceptions
181
182
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
183
def _smart_upgrade_one(control_dir, format, clean_up=False,
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
184
    dry_run=False):
185
    """Convert a control directory to a new format intelligently.
186
4360.10.10 by Ian Clatworthy
minor clean-ups
187
    See smart_upgrade for parameter details.
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
188
    """
4360.10.11 by Ian Clatworthy
for a repo, just do dependent branches (not lw checkouts) for now
189
    # If the URL is a shared repository, find the dependent branches
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
190
    dependents = None
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
191
    try:
192
        repo = control_dir.open_repository()
193
    except errors.NoRepositoryPresent:
194
        # A branch or checkout using a shared repository higher up
195
        pass
196
    else:
197
        # The URL is a repository. If it successfully upgrades,
4360.10.11 by Ian Clatworthy
for a repo, just do dependent branches (not lw checkouts) for now
198
        # then upgrade the dependent branches as well.
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
199
        if repo.is_shared():
4360.10.17 by Ian Clatworthy
review feedback from abentley
200
            dependents = repo.find_branches(using=True)
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
201
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
202
    # Do the conversions
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
203
    attempted = [control_dir]
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
204
    succeeded, exceptions = _convert_items([control_dir], format, clean_up,
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
205
                                           dry_run)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
206
    if succeeded and dependents:
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
207
        ui.ui_factory.note(gettext('Found %d dependent branches - upgrading ...')
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
208
                           % (len(dependents),))
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
209
        # Convert dependent branches
4360.10.11 by Ian Clatworthy
for a repo, just do dependent branches (not lw checkouts) for now
210
        branch_cdirs = [b.bzrdir for b in dependents]
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
211
        successes, problems = _convert_items(branch_cdirs, format, clean_up,
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
212
            dry_run, label="branch")
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
213
        attempted.extend(branch_cdirs)
4360.10.3 by Ian Clatworthy
fix tests
214
        succeeded.extend(successes)
215
        exceptions.extend(problems)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
216
217
    # Return the result
218
    return attempted, succeeded, exceptions
219
4360.10.49 by Vincent Ladeuil
Make _get_object_and_label() private to upgrade.py, its inmplementation is both incomplete and returning info that are not used.
220
# FIXME: There are several problems below:
221
# - RemoteRepository doesn't support _unsupported (really ?)
222
# - raising AssertionError is rude and may not be necessary
223
# - no tests
224
# - the only caller uses only the label
225
def _get_object_and_label(control_dir):
226
    """Return the primary object and type label for a control directory.
227
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
228
    :return: object, label where:
229
      * object is a Branch, Repository or WorkingTree and
230
      * label is one of:
231
        * branch            - a branch
232
        * repository        - a repository
233
        * tree              - a lightweight checkout
4360.10.49 by Vincent Ladeuil
Make _get_object_and_label() private to upgrade.py, its inmplementation is both incomplete and returning info that are not used.
234
    """
235
    try:
236
        try:
237
            br = control_dir.open_branch(unsupported=True,
238
                                         ignore_fallbacks=True)
239
        except NotImplementedError:
240
            # RemoteRepository doesn't support the unsupported parameter
241
            br = control_dir.open_branch(ignore_fallbacks=True)
242
    except errors.NotBranchError:
243
        pass
244
    else:
245
        return br, "branch"
246
    try:
247
        repo = control_dir.open_repository()
248
    except errors.NoRepositoryPresent:
249
        pass
250
    else:
251
        return repo, "repository"
252
    try:
253
        wt = control_dir.open_workingtree()
254
    except (errors.NoWorkingTree, errors.NotLocalUrl):
255
        pass
256
    else:
257
        return wt, "tree"
258
    raise AssertionError("unknown type of control directory %s", control_dir)
259
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
260
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
261
def _convert_items(items, format, clean_up, dry_run, label=None):
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
262
    """Convert a sequence of control directories to the given format.
263
 
264
    :param items: the control directories to upgrade
265
    :param format: the format to convert to or None for the best default
266
    :param clean-up: if True, the backup.bzr directory is removed if the
267
      upgrade succeeded for a given repo/branch/tree
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
268
    :param dry_run: show what would happen but don't actually do any upgrades
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
269
    :param label: the label for these items or None to calculate one
270
    :return: items successfully upgraded, exceptions
271
    """
272
    succeeded = []
273
    exceptions = []
4360.10.31 by Matthew Fuller
Wrap a progress bar around the iteration of entries to upgrade.
274
    child_pb = ui.ui_factory.nested_progress_bar()
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
275
    child_pb.update(gettext('Upgrading bzrdirs'), 0, len(items))
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
276
    for i, control_dir in enumerate(items):
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
277
        # Do the conversion
4360.10.12 by Ian Clatworthy
use transport.delete_tree() instead of osutils.rmtree() for clean-up
278
        location = control_dir.root_transport.base
4360.10.49 by Vincent Ladeuil
Make _get_object_and_label() private to upgrade.py, its inmplementation is both incomplete and returning info that are not used.
279
        bzr_object, bzr_label = _get_object_and_label(control_dir)
4360.10.31 by Matthew Fuller
Wrap a progress bar around the iteration of entries to upgrade.
280
        type_label = label or bzr_label
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
281
        child_pb.update(gettext("Upgrading %s") % (type_label), i+1, len(items))
282
        ui.ui_factory.note(gettext('Upgrading {0} {1} ...').format(type_label, 
6072.3.2 by Jelmer Vernooij
Use utf8 as encoding for urls passed to note().
283
            urlutils.unescape_for_display(location, 'utf-8'),))
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
284
        try:
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
285
            if not dry_run:
286
                cv = Convert(control_dir=control_dir, format=format)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
287
        except Exception, ex:
4360.10.46 by Vincent Ladeuil
Get rid of _verbose_warning and rework the messages overall display (revealing some incoherences) and fixing the tests accordingly.
288
            trace.warning('conversion error: %s' % ex)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
289
            exceptions.append(ex)
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
290
            continue
291
292
        # Do any required post processing
293
        succeeded.append(control_dir)
294
        if clean_up:
295
            try:
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
296
                ui.ui_factory.note(gettext('Removing backup ...'))
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
297
                if not dry_run:
298
                    cv.clean_up()
299
            except Exception, ex:
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
300
                trace.warning(gettext('failed to clean-up {0}: {1}') % (location, ex))
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
301
                exceptions.append(ex)
302
4360.10.31 by Matthew Fuller
Wrap a progress bar around the iteration of entries to upgrade.
303
    child_pb.finished()
304
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
305
    # Return the result
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
306
    return succeeded, exceptions