/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
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
    )
3577.4.1 by Andrew Bennetts
Make 'bzr upgrade' work over HPSS.
30
from bzrlib.remote import RemoteBzrDir
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
31
32
33
class Convert(object):
34
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
35
    def __init__(self, url=None, format=None, control_dir=None):
36
        """Convert a Bazaar control directory to a given format.
37
38
        Either the url or control_dir parameter must be given.
39
40
        :param url: the URL of the control directory or None if the
41
          control_dir is explicitly given instead
42
        :param format: the format to convert to or None for the default
4360.10.10 by Ian Clatworthy
minor clean-ups
43
        :param control_dir: the control directory or None if it is
44
          specified via the URL parameter instead
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
45
        """
1534.5.13 by Robert Collins
Correct buggy test.
46
        self.format = format
4634.144.9 by Martin Pool
Suppress user warnings about cross-format fetch during upgrade
47
        # XXX: Change to cleanup
48
        warning_id = 'cross_format_fetch'
4634.144.11 by Martin Pool
Rename squelched to suppressed
49
        saved_warning = warning_id in ui.ui_factory.suppressed_warnings
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
50
        if url is None and control_dir is None:
51
            raise AssertionError(
52
                "either the url or control_dir parameter must be set.")
53
        if control_dir is not None:
54
            self.bzrdir = control_dir
55
        else:
56
            self.bzrdir = BzrDir.open_unsupported(url)
3577.4.1 by Andrew Bennetts
Make 'bzr upgrade' work over HPSS.
57
        if isinstance(self.bzrdir, RemoteBzrDir):
58
            self.bzrdir._ensure_real()
59
            self.bzrdir = self.bzrdir._real_bzrdir
1534.5.7 by Robert Collins
Start factoring out the upgrade policy logic.
60
        if self.bzrdir.root_transport.is_readonly():
61
            raise errors.UpgradeReadonly
62
        self.transport = self.bzrdir.root_transport
4634.144.11 by Martin Pool
Rename squelched to suppressed
63
        ui.ui_factory.suppressed_warnings.add(warning_id)
1594.1.3 by Robert Collins
Fixup pb usage to use nested_progress_bar.
64
        try:
65
            self.convert()
66
        finally:
4634.144.9 by Martin Pool
Suppress user warnings about cross-format fetch during upgrade
67
            if not saved_warning:
4634.144.11 by Martin Pool
Rename squelched to suppressed
68
                ui.ui_factory.suppressed_warnings.remove(warning_id)
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
69
70
    def convert(self):
1558.7.2 by Aaron Bentley
Upgrade works in repositories
71
        try:
72
            branch = self.bzrdir.open_branch()
5158.6.9 by Martin Pool
Simplify various code to use user_url
73
            if branch.user_url != self.bzrdir.user_url:
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.
74
                ui.ui_factory.note(
75
                    'This is a checkout. The branch (%s) needs to be upgraded'
6072.3.1 by Jelmer Vernooij
Format URLs in ``bzr upgrade`` before display.
76
                    ' separately.' % (urlutils.unescape_for_display(
6072.3.2 by Jelmer Vernooij
Use utf8 as encoding for urls passed to note().
77
                        branch.user_url, 'utf-8')))
3602.2.1 by Martin Pool
Fix and test for problem upgrading stacked branches
78
            del branch
79
        except (errors.NotBranchError, errors.IncompatibleRepositories):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
80
            # 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
81
            # https://bugs.launchpad.net/bzr/+bug/253891
1558.7.2 by Aaron Bentley
Upgrade works in repositories
82
            pass
4119.7.1 by Jelmer Vernooij
Make upgrade default to a rich-root-capable format if the source format uses rich roots.
83
        if self.format is None:
4170.3.5 by Jelmer Vernooij
Fix upgrade if there is no local repository present.
84
            try:
85
                rich_root = self.bzrdir.find_repository()._format.rich_root_data
86
            except errors.NoRepositoryPresent:
87
                rich_root = False # assume no rich roots
88
            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.
89
                format_name = "default-rich-root"
90
            else:
91
                format_name = "default"
92
            format = format_registry.make_bzrdir(format_name)
93
        else:
94
            format = self.format
95
        if not self.bzrdir.needs_format_conversion(format):
1534.5.10 by Robert Collins
Make upgrade driver unaware of the specific formats in play.
96
            raise errors.UpToDateFormat(self.bzrdir._format)
1534.5.16 by Robert Collins
Review feedback.
97
        if not self.bzrdir.can_convert_format():
3602.2.1 by Martin Pool
Fix and test for problem upgrading stacked branches
98
            raise errors.BzrError("cannot upgrade from bzrdir format %s" %
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
99
                           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.
100
        self.bzrdir.check_conversion_target(format)
6072.3.1 by Jelmer Vernooij
Format URLs in ``bzr upgrade`` before display.
101
        ui.ui_factory.note('starting upgrade of %s' % 
6072.3.2 by Jelmer Vernooij
Use utf8 as encoding for urls passed to note().
102
            urlutils.unescape_for_display(self.transport.base, 'utf-8'))
4471.2.2 by Martin Pool
Deprecate ProgressTask.note
103
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
104
        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.
105
        while self.bzrdir.needs_format_conversion(format):
106
            converter = self.bzrdir._format.get_converter(format)
4961.2.15 by Martin Pool
Remove more pb-passing
107
            self.bzrdir = converter.convert(self.bzrdir, None)
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.
108
        ui.ui_factory.note('finished')
1534.5.6 by Robert Collins
split out converter logic into per-format objects.
109
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
110
    def clean_up(self):
111
        """Clean-up after a conversion.
112
113
        This removes the backup.bzr directory.
114
        """
4360.10.12 by Ian Clatworthy
use transport.delete_tree() instead of osutils.rmtree() for clean-up
115
        transport = self.transport
116
        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
117
        child_pb = ui.ui_factory.nested_progress_bar()
118
        child_pb.update('Deleting backup.bzr')
119
        try:
120
            transport.delete_tree(backup_relpath)
121
        finally:
122
            child_pb.finished()
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
123
124
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
125
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
126
    """Upgrade locations to format.
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
127
 
128
    This routine wraps the smart_upgrade() routine with a nicer UI.
129
    In particular, it ensures all URLs can be opened before starting
130
    and reports a summary at the end if more than one upgrade was attempted.
131
    This routine is useful for command line tools. Other bzrlib clients
132
    probably ought to use smart_upgrade() instead.
133
4360.10.28 by Matthew Fuller
Revert upgrade() to taking only a single URL. Other code attempting
134
    :param url: a URL of the locations to upgrade.
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
135
    :param format: the format to convert to or None for the best default
136
    :param clean-up: if True, the backup.bzr directory is removed if the
137
      upgrade succeeded for a given repo/branch/tree
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
138
    :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
139
    :return: the list of exceptions encountered
140
    """
4360.10.28 by Matthew Fuller
Revert upgrade() to taking only a single URL. Other code attempting
141
    control_dirs = [BzrDir.open_unsupported(url)]
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
142
    attempted, succeeded, exceptions = smart_upgrade(control_dirs,
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
143
        format, clean_up=clean_up, dry_run=dry_run)
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
144
    if len(attempted) > 1:
145
        attempted_count = len(attempted)
146
        succeeded_count = len(succeeded)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
147
        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.
148
        ui.ui_factory.note(
149
            '\nSUMMARY: %d upgrades attempted, %d succeeded, %d failed'
150
            % (attempted_count, succeeded_count, failed_count))
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
151
    return exceptions
152
153
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
154
def smart_upgrade(control_dirs, format, clean_up=False,
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
155
    dry_run=False):
156
    """Convert control directories to a new format intelligently.
157
158
    If the control directory is a shared repository, dependent branches
159
    are also converted provided the repository converted successfully.
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
160
    If the conversion of a branch fails, remaining branches are still tried.
161
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
162
    :param control_dirs: the BzrDirs to upgrade
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
163
    :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.
164
    :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
165
      upgrade succeeded for a given repo/branch/tree
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
166
    :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
167
    :return: attempted-control-dirs, succeeded-control-dirs, exceptions
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
168
    """
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
169
    all_attempted = []
170
    all_succeeded = []
171
    all_exceptions = []
172
    for control_dir in control_dirs:
173
        attempted, succeeded, exceptions = _smart_upgrade_one(control_dir,
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
174
            format, clean_up=clean_up, dry_run=dry_run)
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
175
        all_attempted.extend(attempted)
176
        all_succeeded.extend(succeeded)
177
        all_exceptions.extend(exceptions)
178
    return all_attempted, all_succeeded, all_exceptions
179
180
4360.10.30 by Matthew Fuller
The various repository formats that do packing, pack themselves as
181
def _smart_upgrade_one(control_dir, format, clean_up=False,
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
182
    dry_run=False):
183
    """Convert a control directory to a new format intelligently.
184
4360.10.10 by Ian Clatworthy
minor clean-ups
185
    See smart_upgrade for parameter details.
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
186
    """
4360.10.11 by Ian Clatworthy
for a repo, just do dependent branches (not lw checkouts) for now
187
    # 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
188
    dependents = None
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
189
    try:
190
        repo = control_dir.open_repository()
191
    except errors.NoRepositoryPresent:
192
        # A branch or checkout using a shared repository higher up
193
        pass
194
    else:
195
        # 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
196
        # then upgrade the dependent branches as well.
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
197
        if repo.is_shared():
4360.10.17 by Ian Clatworthy
review feedback from abentley
198
            dependents = repo.find_branches(using=True)
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
199
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
200
    # Do the conversions
4360.10.1 by Ian Clatworthy
initial cut at smarter upgrades
201
    attempted = [control_dir]
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
202
    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.
203
                                           dry_run)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
204
    if succeeded and dependents:
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
        ui.ui_factory.note('Found %d dependent branches - upgrading ...'
206
                           % (len(dependents),))
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
207
        # Convert dependent branches
4360.10.11 by Ian Clatworthy
for a repo, just do dependent branches (not lw checkouts) for now
208
        branch_cdirs = [b.bzrdir for b in dependents]
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
209
        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
210
            dry_run, label="branch")
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
211
        attempted.extend(branch_cdirs)
4360.10.3 by Ian Clatworthy
fix tests
212
        succeeded.extend(successes)
213
        exceptions.extend(problems)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
214
215
    # Return the result
216
    return attempted, succeeded, exceptions
217
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.
218
# FIXME: There are several problems below:
219
# - RemoteRepository doesn't support _unsupported (really ?)
220
# - raising AssertionError is rude and may not be necessary
221
# - no tests
222
# - the only caller uses only the label
223
def _get_object_and_label(control_dir):
224
    """Return the primary object and type label for a control directory.
225
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
226
    :return: object, label where:
227
      * object is a Branch, Repository or WorkingTree and
228
      * label is one of:
229
        * branch            - a branch
230
        * repository        - a repository
231
        * 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.
232
    """
233
    try:
234
        try:
235
            br = control_dir.open_branch(unsupported=True,
236
                                         ignore_fallbacks=True)
237
        except NotImplementedError:
238
            # RemoteRepository doesn't support the unsupported parameter
239
            br = control_dir.open_branch(ignore_fallbacks=True)
240
    except errors.NotBranchError:
241
        pass
242
    else:
243
        return br, "branch"
244
    try:
245
        repo = control_dir.open_repository()
246
    except errors.NoRepositoryPresent:
247
        pass
248
    else:
249
        return repo, "repository"
250
    try:
251
        wt = control_dir.open_workingtree()
252
    except (errors.NoWorkingTree, errors.NotLocalUrl):
253
        pass
254
    else:
255
        return wt, "tree"
256
    raise AssertionError("unknown type of control directory %s", control_dir)
257
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
258
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.
259
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
260
    """Convert a sequence of control directories to the given format.
261
 
262
    :param items: the control directories to upgrade
263
    :param format: the format to convert to or None for the best default
264
    :param clean-up: if True, the backup.bzr directory is removed if the
265
      upgrade succeeded for a given repo/branch/tree
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
266
    :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
267
    :param label: the label for these items or None to calculate one
268
    :return: items successfully upgraded, exceptions
269
    """
270
    succeeded = []
271
    exceptions = []
4360.10.31 by Matthew Fuller
Wrap a progress bar around the iteration of entries to upgrade.
272
    child_pb = ui.ui_factory.nested_progress_bar()
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.
273
    child_pb.update('Upgrading bzrdirs', 0, len(items))
274
    for i, control_dir in enumerate(items):
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
275
        # Do the conversion
4360.10.12 by Ian Clatworthy
use transport.delete_tree() instead of osutils.rmtree() for clean-up
276
        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.
277
        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.
278
        type_label = label or bzr_label
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.
279
        child_pb.update("Upgrading %s" % (type_label), i+1, len(items))
6072.3.1 by Jelmer Vernooij
Format URLs in ``bzr upgrade`` before display.
280
        ui.ui_factory.note('Upgrading %s %s ...' % (type_label, 
6072.3.2 by Jelmer Vernooij
Use utf8 as encoding for urls passed to note().
281
            urlutils.unescape_for_display(location, 'utf-8'),))
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
282
        try:
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
283
            if not dry_run:
284
                cv = Convert(control_dir=control_dir, format=format)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
285
        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.
286
            trace.warning('conversion error: %s' % ex)
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
287
            exceptions.append(ex)
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
288
            continue
289
290
        # Do any required post processing
291
        succeeded.append(control_dir)
292
        if clean_up:
293
            try:
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.
294
                ui.ui_factory.note('Removing backup ...')
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
295
                if not dry_run:
296
                    cv.clean_up()
297
            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.
298
                trace.warning('failed to clean-up %s: %s' % (location, ex))
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
299
                exceptions.append(ex)
300
4360.10.31 by Matthew Fuller
Wrap a progress bar around the iteration of entries to upgrade.
301
    child_pb.finished()
302
4360.10.4 by Ian Clatworthy
support multiple urls, --pack and --dry-run
303
    # Return the result
4360.10.2 by Ian Clatworthy
drop stacked vs unstacked logic; support multiple URLs
304
    return succeeded, exceptions