/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4763.2.4 by John Arbash Meinel
merge bzr.2.1 in preparation for NEWS entry.
1
# Copyright (C) 2005-2010 Canonical Ltd
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2
#
77 by mbp at sourcefrog
- split info command out into separate file
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.
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
7
#
77 by mbp at sourcefrog
- split info command out into separate file
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.
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
12
#
77 by mbp at sourcefrog
- split info command out into separate file
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
77 by mbp at sourcefrog
- split info command out into separate file
16
1534.5.1 by Robert Collins
Give info some reasonable output and tests.
17
__all__ = ['show_bzrdir_info']
18
4307.3.1 by Jelmer Vernooij
Allow registering hooks that extend the Repository section in 'bzr info -v'.
19
from cStringIO import StringIO
77 by mbp at sourcefrog
- split info command out into separate file
20
import time
1551.15.43 by Aaron Bentley
Provide ways of getting at unicode-clean output
21
import sys
1534.5.1 by Robert Collins
Give info some reasonable output and tests.
22
1551.9.22 by Aaron Bentley
Use urlutils for info. Fixes bug #76229
23
from bzrlib import (
2363.5.5 by Aaron Bentley
add info.describe_format
24
    bzrdir,
1551.15.41 by Aaron Bentley
Make info provide more related brances, and format all branches nicely
25
    errors,
4307.3.1 by Jelmer Vernooij
Allow registering hooks that extend the Repository section in 'bzr info -v'.
26
    hooks as _mod_hooks,
1551.9.22 by Aaron Bentley
Use urlutils for info. Fixes bug #76229
27
    osutils,
28
    urlutils,
29
    )
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
30
from bzrlib.errors import (NoWorkingTree, NotBranchError,
31
                           NoRepositoryPresent, NotLocalUrl)
1587.1.14 by Robert Collins
Make bound branch creation happen via 'checkout'
32
from bzrlib.missing import find_unmerged
77 by mbp at sourcefrog
- split info command out into separate file
33
462 by Martin Pool
- New form 'file_id in tree' to check if the file is present
34
1563.2.28 by Robert Collins
Add total_size to the revision_store api.
35
def plural(n, base='', pl=None):
36
    if n == 1:
37
        return base
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
38
    elif pl is not None:
1563.2.28 by Robert Collins
Add total_size to the revision_store api.
39
        return pl
40
    else:
41
        return 's'
42
43
1551.15.41 by Aaron Bentley
Make info provide more related brances, and format all branches nicely
44
class LocationList(object):
45
46
    def __init__(self, base_path):
1551.15.43 by Aaron Bentley
Provide ways of getting at unicode-clean output
47
        self.locs = []
1551.15.41 by Aaron Bentley
Make info provide more related brances, and format all branches nicely
48
        self.base_path = base_path
49
50
    def add_url(self, label, url):
1551.15.43 by Aaron Bentley
Provide ways of getting at unicode-clean output
51
        """Add a URL to the list, converting it to a path if possible"""
1551.15.41 by Aaron Bentley
Make info provide more related brances, and format all branches nicely
52
        if url is None:
53
            return
1551.15.43 by Aaron Bentley
Provide ways of getting at unicode-clean output
54
        try:
55
            path = urlutils.local_path_from_url(url)
56
        except errors.InvalidURL:
57
            self.locs.append((label, url))
58
        else:
1551.15.41 by Aaron Bentley
Make info provide more related brances, and format all branches nicely
59
            self.add_path(label, path)
2363.5.18 by Aaron Bentley
Get all tests passing
60
61
    def add_path(self, label, path):
1551.15.43 by Aaron Bentley
Provide ways of getting at unicode-clean output
62
        """Add a path, converting it to a relative path if possible"""
1551.15.41 by Aaron Bentley
Make info provide more related brances, and format all branches nicely
63
        try:
64
            path = osutils.relpath(self.base_path, path)
65
        except errors.PathNotChild:
66
            pass
67
        else:
68
            if path == '':
69
                path = '.'
70
        if path != '/':
71
            path = path.rstrip('/')
1551.15.43 by Aaron Bentley
Provide ways of getting at unicode-clean output
72
        self.locs.append((label, path))
2363.5.18 by Aaron Bentley
Get all tests passing
73
1551.15.43 by Aaron Bentley
Provide ways of getting at unicode-clean output
74
    def get_lines(self):
75
        max_len = max(len(l) for l, u in self.locs)
76
        return ["  %*s: %s\n" % (max_len, l, u) for l, u in self.locs ]
2363.5.18 by Aaron Bentley
Get all tests passing
77
78
79
def gather_location_info(repository, branch=None, working=None):
80
    locs = {}
5158.6.6 by Martin Pool
Change info code to use user_url etc
81
    repository_path = repository.user_url
2363.5.18 by Aaron Bentley
Get all tests passing
82
    if branch is not None:
5158.6.6 by Martin Pool
Change info code to use user_url etc
83
        branch_path = branch.user_url
2363.5.18 by Aaron Bentley
Get all tests passing
84
        master_path = branch.get_bound_location()
85
        if master_path is None:
86
            master_path = branch_path
87
    else:
88
        branch_path = None
89
        master_path = None
90
    if working:
5158.6.6 by Martin Pool
Change info code to use user_url etc
91
        working_path = working.user_url
1694.2.6 by Martin Pool
[merge] bzr.dev
92
        if working_path != branch_path:
2363.5.18 by Aaron Bentley
Get all tests passing
93
            locs['light checkout root'] = working_path
94
        if master_path != branch_path:
1694.2.6 by Martin Pool
[merge] bzr.dev
95
            if repository.is_shared():
2363.5.18 by Aaron Bentley
Get all tests passing
96
                locs['repository checkout root'] = branch_path
1694.2.6 by Martin Pool
[merge] bzr.dev
97
            else:
2363.5.18 by Aaron Bentley
Get all tests passing
98
                locs['checkout root'] = branch_path
99
        if working_path != master_path:
100
            locs['checkout of branch'] = master_path
1694.2.6 by Martin Pool
[merge] bzr.dev
101
        elif repository.is_shared():
1551.15.41 by Aaron Bentley
Make info provide more related brances, and format all branches nicely
102
            locs['repository branch'] = branch_path
2363.5.18 by Aaron Bentley
Get all tests passing
103
        elif branch_path is not None:
1694.2.6 by Martin Pool
[merge] bzr.dev
104
            # standalone
2363.5.18 by Aaron Bentley
Get all tests passing
105
            locs['branch root'] = branch_path
106
    else:
107
        working_path = None
1624.3.48 by Olaf Conradi
Add info on standalone branches without a working tree.
108
        if repository.is_shared():
2363.5.18 by Aaron Bentley
Get all tests passing
109
            # lightweight checkout of branch in shared repository
110
            if branch_path is not None:
1551.15.41 by Aaron Bentley
Make info provide more related brances, and format all branches nicely
111
                locs['repository branch'] = branch_path
2363.5.18 by Aaron Bentley
Get all tests passing
112
        elif branch_path is not None:
113
            # standalone
114
            locs['branch root'] = branch_path
2363.5.19 by Aaron Bentley
Add support for bound branches
115
            if master_path != branch_path:
116
                locs['bound to branch'] = master_path
1624.3.48 by Olaf Conradi
Add info on standalone branches without a working tree.
117
        else:
2363.5.18 by Aaron Bentley
Get all tests passing
118
            locs['repository'] = repository_path
119
    if repository.is_shared():
120
        # lightweight checkout of branch in shared repository
121
        locs['shared repository'] = repository_path
2363.5.23 by Aaron Bentley
Output 2-tuples from gather_locations
122
    order = ['light checkout root', 'repository checkout root',
123
             'checkout root', 'checkout of branch', 'shared repository',
124
             'repository', 'repository branch', 'branch root',
125
             'bound to branch']
126
    return [(n, locs[n]) for n in order if n in locs]
2363.5.18 by Aaron Bentley
Get all tests passing
127
128
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
129
def _show_location_info(locs, outfile):
2363.5.18 by Aaron Bentley
Get all tests passing
130
    """Show known locations for working, branch and repository."""
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
131
    outfile.write('Location:\n')
2804.4.3 by Alexander Belchenko
fix for test_info-tests: using osutils.getcwd instead of os.getcwd (sigh)
132
    path_list = LocationList(osutils.getcwd())
2363.5.23 by Aaron Bentley
Output 2-tuples from gather_locations
133
    for name, loc in locs:
134
        path_list.add_url(name, loc)
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
135
    outfile.writelines(path_list.get_lines())
136
1694.2.6 by Martin Pool
[merge] bzr.dev
137
1551.15.41 by Aaron Bentley
Make info provide more related brances, and format all branches nicely
138
def _gather_related_branches(branch):
2804.4.3 by Alexander Belchenko
fix for test_info-tests: using osutils.getcwd instead of os.getcwd (sigh)
139
    locs = LocationList(osutils.getcwd())
1551.15.41 by Aaron Bentley
Make info provide more related brances, and format all branches nicely
140
    locs.add_url('public branch', branch.get_public_branch())
141
    locs.add_url('push branch', branch.get_push_location())
142
    locs.add_url('parent branch', branch.get_parent())
143
    locs.add_url('submit branch', branch.get_submit_branch())
3221.11.21 by Robert Collins
Have info report on stacked branches.
144
    try:
3537.3.1 by Martin Pool
Rename branch.get_stacked_on to get_stacked_on_url
145
        locs.add_url('stacked on', branch.get_stacked_on_url())
3221.11.21 by Robert Collins
Have info report on stacked branches.
146
    except (errors.UnstackableBranchFormat, errors.UnstackableRepositoryFormat,
147
        errors.NotStacked):
148
        pass
1551.15.41 by Aaron Bentley
Make info provide more related brances, and format all branches nicely
149
    return locs
1694.2.6 by Martin Pool
[merge] bzr.dev
150
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
151
1551.15.43 by Aaron Bentley
Provide ways of getting at unicode-clean output
152
def _show_related_info(branch, outfile):
1694.2.6 by Martin Pool
[merge] bzr.dev
153
    """Show parent and push location of branch."""
1551.15.41 by Aaron Bentley
Make info provide more related brances, and format all branches nicely
154
    locs = _gather_related_branches(branch)
1551.15.43 by Aaron Bentley
Provide ways of getting at unicode-clean output
155
    if len(locs.locs) > 0:
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
156
        outfile.write('\n')
157
        outfile.write('Related branches:\n')
1551.15.43 by Aaron Bentley
Provide ways of getting at unicode-clean output
158
        outfile.writelines(locs.get_lines())
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
159
160
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
161
def _show_format_info(control=None, repository=None, branch=None,
162
                      working=None, outfile=None):
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
163
    """Show known formats for control, working, branch and repository."""
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
164
    outfile.write('\n')
165
    outfile.write('Format:\n')
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
166
    if control:
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
167
        outfile.write('       control: %s\n' %
168
            control._format.get_format_description())
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
169
    if working:
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
170
        outfile.write('  working tree: %s\n' %
171
            working._format.get_format_description())
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
172
    if branch:
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
173
        outfile.write('        branch: %s\n' %
174
            branch._format.get_format_description())
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
175
    if repository:
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
176
        outfile.write('    repository: %s\n' %
177
            repository._format.get_format_description())
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
178
179
180
def _show_locking_info(repository, branch=None, working=None, outfile=None):
1694.2.6 by Martin Pool
[merge] bzr.dev
181
    """Show locking status of working, branch and repository."""
182
    if (repository.get_physical_lock_status() or
183
        (branch and branch.get_physical_lock_status()) or
184
        (working and working.get_physical_lock_status())):
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
185
        outfile.write('\n')
186
        outfile.write('Lock status:\n')
1694.2.6 by Martin Pool
[merge] bzr.dev
187
        if working:
188
            if working.get_physical_lock_status():
189
                status = 'locked'
190
            else:
191
                status = 'unlocked'
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
192
            outfile.write('  working tree: %s\n' % status)
1694.2.6 by Martin Pool
[merge] bzr.dev
193
        if branch:
194
            if branch.get_physical_lock_status():
195
                status = 'locked'
196
            else:
197
                status = 'unlocked'
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
198
            outfile.write('        branch: %s\n' % status)
1694.2.6 by Martin Pool
[merge] bzr.dev
199
        if repository:
200
            if repository.get_physical_lock_status():
201
                status = 'locked'
202
            else:
203
                status = 'unlocked'
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
204
            outfile.write('    repository: %s\n' % status)
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
205
206
207
def _show_missing_revisions_branch(branch, outfile):
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
208
    """Show missing master revisions in branch."""
1587.1.14 by Robert Collins
Make bound branch creation happen via 'checkout'
209
    # Try with inaccessible branch ?
1624.3.2 by Olaf Conradi
Implemented table of constructs from BzrInfo specification.
210
    master = branch.get_master_branch()
1587.1.14 by Robert Collins
Make bound branch creation happen via 'checkout'
211
    if master:
1624.3.2 by Olaf Conradi
Implemented table of constructs from BzrInfo specification.
212
        local_extra, remote_extra = find_unmerged(branch, master)
1587.1.14 by Robert Collins
Make bound branch creation happen via 'checkout'
213
        if remote_extra:
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
214
            outfile.write('\n')
215
            outfile.write(('Branch is out of date: missing %d '
216
                'revision%s.\n') % (len(remote_extra),
217
                plural(len(remote_extra))))
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
218
219
220
def _show_missing_revisions_working(working, outfile):
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
221
    """Show missing revisions in working tree."""
222
    branch = working.branch
223
    basis = working.basis_tree()
6181.1.1 by Jelmer Vernooij
If the branch doesn't support last_revision_info, don't display
224
    try:
225
        branch_revno, branch_last_revision = branch.last_revision_info()
226
    except errors.UnsupportedOperation:
227
        return
1908.7.6 by Robert Collins
Deprecate WorkingTree.last_revision.
228
    try:
229
        tree_last_id = working.get_parent_ids()[0]
230
    except IndexError:
231
        tree_last_id = None
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
232
2249.4.2 by Wouter van Heyst
Convert callers of Branch.revision_history() to Branch.last_revision_info() where sensible.
233
    if branch_revno and tree_last_id != branch_last_revision:
1624.3.11 by Olaf Conradi
Test cases exposed a bug in missing revisions count of working tree. It
234
        tree_last_revno = branch.revision_id_to_revno(tree_last_id)
2249.4.2 by Wouter van Heyst
Convert callers of Branch.revision_history() to Branch.last_revision_info() where sensible.
235
        missing_count = branch_revno - tree_last_revno
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
236
        outfile.write('\n')
237
        outfile.write(('Working tree is out of date: missing %d '
238
            'revision%s.\n') % (missing_count, plural(missing_count)))
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
239
240
241
def _show_working_stats(working, outfile):
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
242
    """Show statistics about a working tree."""
243
    basis = working.basis_tree()
1852.10.3 by Robert Collins
Remove all uses of compare_trees and replace with Tree.changes_from throughout bzrlib.
244
    delta = working.changes_from(basis, want_unchanged=True)
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
245
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
246
    outfile.write('\n')
247
    outfile.write('In the working tree:\n')
248
    outfile.write('  %8s unchanged\n' % len(delta.unchanged))
249
    outfile.write('  %8d modified\n' % len(delta.modified))
250
    outfile.write('  %8d added\n' % len(delta.added))
251
    outfile.write('  %8d removed\n' % len(delta.removed))
252
    outfile.write('  %8d renamed\n' % len(delta.renamed))
462 by Martin Pool
- New form 'file_id in tree' to check if the file is present
253
254
    ignore_cnt = unknown_cnt = 0
255
    for path in working.extras():
256
        if working.is_ignored(path):
257
            ignore_cnt += 1
258
        else:
259
            unknown_cnt += 1
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
260
    outfile.write('  %8d unknown\n' % unknown_cnt)
261
    outfile.write('  %8d ignored\n' % ignore_cnt)
462 by Martin Pool
- New form 'file_id in tree' to check if the file is present
262
263
    dir_cnt = 0
5777.5.4 by Jelmer Vernooij
Avoid the use of inventory in 'bzr info'.
264
    root_id = working.get_root_id()
5777.5.5 by Jelmer Vernooij
Use working.iter_entries_by_dir.
265
    for path, entry in working.iter_entries_by_dir():
266
        if entry.kind == 'directory' and entry.file_id != root_id:
1731.1.39 by Aaron Bentley
Reject removing is_root
267
            dir_cnt += 1
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
268
    outfile.write('  %8d versioned %s\n' % (dir_cnt,
269
        plural(dir_cnt, 'subdirectory', 'subdirectories')))
77 by mbp at sourcefrog
- split info command out into separate file
270
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
271
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
272
def _show_branch_stats(branch, verbose, outfile):
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
273
    """Show statistics about a branch."""
6181.1.1 by Jelmer Vernooij
If the branch doesn't support last_revision_info, don't display
274
    try:
275
        revno, head = branch.last_revision_info()
276
    except errors.UnsupportedOperation:
277
        return {}
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
278
    outfile.write('\n')
279
    outfile.write('Branch history:\n')
280
    outfile.write('  %8d revision%s\n' % (revno, plural(revno)))
2258.1.1 by Robert Collins
Move info branch statistics gathering into the repository to allow smart server optimisation (Robert Collins).
281
    stats = branch.repository.gather_stats(head, committers=verbose)
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
282
    if verbose:
2258.1.1 by Robert Collins
Move info branch statistics gathering into the repository to allow smart server optimisation (Robert Collins).
283
        committers = stats['committers']
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
284
        outfile.write('  %8d committer%s\n' % (committers,
285
            plural(committers)))
2258.1.1 by Robert Collins
Move info branch statistics gathering into the repository to allow smart server optimisation (Robert Collins).
286
    if revno:
287
        timestamp, timezone = stats['firstrev']
288
        age = int((time.time() - timestamp) / 3600 / 24)
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
289
        outfile.write('  %8d day%s old\n' % (age, plural(age)))
290
        outfile.write('   first revision: %s\n' %
291
            osutils.format_date(timestamp, timezone))
2258.1.1 by Robert Collins
Move info branch statistics gathering into the repository to allow smart server optimisation (Robert Collins).
292
        timestamp, timezone = stats['latestrev']
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
293
        outfile.write('  latest revision: %s\n' %
294
            osutils.format_date(timestamp, timezone))
2258.1.2 by Robert Collins
New version of gather_stats which gathers aggregate data too.
295
    return stats
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
296
297
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
298
def _show_repository_info(repository, outfile):
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
299
    """Show settings of a repository."""
300
    if repository.make_working_trees():
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
301
        outfile.write('\n')
302
        outfile.write('Create working tree for new branches inside '
303
            'the repository.\n')
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
304
305
4307.3.3 by Jelmer Vernooij
Add repository argument to 'repository' info hook, per Roberts review.
306
def _show_repository_stats(repository, stats, outfile):
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
307
    """Show statistics about a repository."""
4307.3.1 by Jelmer Vernooij
Allow registering hooks that extend the Repository section in 'bzr info -v'.
308
    f = StringIO()
2258.1.2 by Robert Collins
New version of gather_stats which gathers aggregate data too.
309
    if 'revisions' in stats:
310
        revisions = stats['revisions']
4307.3.1 by Jelmer Vernooij
Allow registering hooks that extend the Repository section in 'bzr info -v'.
311
        f.write('  %8d revision%s\n' % (revisions, plural(revisions)))
2258.1.2 by Robert Collins
New version of gather_stats which gathers aggregate data too.
312
    if 'size' in stats:
4307.3.1 by Jelmer Vernooij
Allow registering hooks that extend the Repository section in 'bzr info -v'.
313
        f.write('  %8d KiB\n' % (stats['size']/1024))
314
    for hook in hooks['repository']:
4307.3.3 by Jelmer Vernooij
Add repository argument to 'repository' info hook, per Roberts review.
315
        hook(repository, stats, f)
4307.3.1 by Jelmer Vernooij
Allow registering hooks that extend the Repository section in 'bzr info -v'.
316
    if f.getvalue() != "":
317
        outfile.write('\n')
318
        outfile.write('Repository:\n')
319
        outfile.write(f.getvalue())
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
320
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
321
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
322
def show_bzrdir_info(a_bzrdir, verbose=False, outfile=None):
2363.5.1 by Aaron Bentley
Unify info display into show_component_info
323
    """Output to stdout the 'info' for a_bzrdir."""
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
324
    if outfile is None:
325
        outfile = sys.stdout
2363.5.1 by Aaron Bentley
Unify info display into show_component_info
326
    try:
2363.5.9 by Aaron Bentley
Merge from bzr.dev
327
        tree = a_bzrdir.open_workingtree(
328
            recommend_upgrade=False)
2363.5.1 by Aaron Bentley
Unify info display into show_component_info
329
    except (NoWorkingTree, NotLocalUrl):
330
        tree = None
331
        try:
332
            branch = a_bzrdir.open_branch()
333
        except NotBranchError:
334
            branch = None
335
            try:
336
                repository = a_bzrdir.open_repository()
337
            except NoRepositoryPresent:
338
                # Return silently; cmd_info already returned NotBranchError
339
                # if no bzrdir could be opened.
340
                return
341
            else:
342
                lockable = repository
343
        else:
344
            repository = branch.repository
345
            lockable = branch
346
    else:
347
        branch = tree.branch
348
        repository = branch.repository
349
        lockable = tree
350
351
    lockable.lock_read()
352
    try:
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
353
        show_component_info(a_bzrdir, repository, branch, tree, verbose,
354
                            outfile)
2363.5.1 by Aaron Bentley
Unify info display into show_component_info
355
    finally:
356
        lockable.unlock()
357
358
359
def show_component_info(control, repository, branch=None, working=None,
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
360
    verbose=1, outfile=None):
2363.5.1 by Aaron Bentley
Unify info display into show_component_info
361
    """Write info about all bzrdir components to stdout"""
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
362
    if outfile is None:
363
        outfile = sys.stdout
2363.5.7 by Aaron Bentley
Make verbose mean what I want
364
    if verbose is False:
365
        verbose = 1
366
    if verbose is True:
367
        verbose = 2
2363.5.6 by Aaron Bentley
Add short format description
368
    layout = describe_layout(repository, branch, working)
369
    format = describe_format(control, repository, branch, working)
2968.2.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``
370
    outfile.write("%s (format: %s)\n" % (layout, format))
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
371
    _show_location_info(gather_location_info(repository, branch, working),
372
                        outfile)
2584.2.1 by Adeodato Simó
Make `bzr info` show related branches in non-verbose mode.
373
    if branch is not None:
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
374
        _show_related_info(branch, outfile)
2363.5.7 by Aaron Bentley
Make verbose mean what I want
375
    if verbose == 0:
376
        return
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
377
    _show_format_info(control, repository, branch, working, outfile)
378
    _show_locking_info(repository, branch, working, outfile)
2363.5.1 by Aaron Bentley
Unify info display into show_component_info
379
    if branch is not None:
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
380
        _show_missing_revisions_branch(branch, outfile)
2363.5.1 by Aaron Bentley
Unify info display into show_component_info
381
    if working is not None:
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
382
        _show_missing_revisions_working(working, outfile)
383
        _show_working_stats(working, outfile)
2363.5.1 by Aaron Bentley
Unify info display into show_component_info
384
    elif branch is not None:
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
385
        _show_missing_revisions_branch(branch, outfile)
2363.5.1 by Aaron Bentley
Unify info display into show_component_info
386
    if branch is not None:
4032.2.1 by Ian Clatworthy
omit branch committers from info -v (now requires -vv)
387
        show_committers = verbose >= 2
388
        stats = _show_branch_stats(branch, show_committers, outfile)
2363.5.1 by Aaron Bentley
Unify info display into show_component_info
389
    else:
390
        stats = repository.gather_stats()
391
    if branch is None and working is None:
2904.3.1 by Lukáš Lalinský
Unicode-safe output from ``bzr info``.
392
        _show_repository_info(repository, outfile)
4307.3.3 by Jelmer Vernooij
Add repository argument to 'repository' info hook, per Roberts review.
393
    _show_repository_stats(repository, stats, outfile)
2363.5.1 by Aaron Bentley
Unify info display into show_component_info
394
395
2363.5.2 by Aaron Bentley
Implement layout description
396
def describe_layout(repository=None, branch=None, tree=None):
397
    """Convert a control directory layout into a user-understandable term
398
399
    Common outputs include "Standalone tree", "Repository branch" and
400
    "Checkout".  Uncommon outputs include "Unshared repository with trees"
401
    and "Empty control directory"
402
    """
403
    if repository is None:
404
        return 'Empty control directory'
405
    if branch is None and tree is None:
406
        if repository.is_shared():
407
            phrase = 'Shared repository'
408
        else:
409
            phrase = 'Unshared repository'
410
        if repository.make_working_trees():
411
            phrase += ' with trees'
412
        return phrase
413
    else:
414
        if repository.is_shared():
415
            independence = "Repository "
416
        else:
417
            independence = "Standalone "
418
        if tree is not None:
419
            phrase = "tree"
420
        else:
421
            phrase = "branch"
422
        if branch is None and tree is not None:
423
            phrase = "branchless tree"
424
        else:
5158.6.6 by Martin Pool
Change info code to use user_url etc
425
            if (tree is not None and tree.user_url !=
426
                branch.user_url):
2363.5.4 by Aaron Bentley
Eliminate the concept of a 'repository lightweight checkout'
427
                independence = ''
2363.5.2 by Aaron Bentley
Implement layout description
428
                phrase = "Lightweight checkout"
429
            elif branch.get_bound_location() is not None:
430
                if independence == 'Standalone ':
431
                    independence = ''
432
                if tree is None:
433
                    phrase = "Bound branch"
434
                else:
435
                    phrase = "Checkout"
436
        if independence != "":
437
            phrase = phrase.lower()
438
        return "%s%s" % (independence, phrase)
439
440
2363.5.5 by Aaron Bentley
add info.describe_format
441
def describe_format(control, repository, branch, tree):
442
    """Determine the format of an existing control directory
443
444
    Several candidates may be found.  If so, the names are returned as a
2363.5.17 by Aaron Bentley
Change separator from '/' to 'or'
445
    single string, separated by ' or '.
2363.5.5 by Aaron Bentley
add info.describe_format
446
447
    If no matching candidate is found, "unnamed" is returned.
448
    """
449
    candidates  = []
2363.5.6 by Aaron Bentley
Add short format description
450
    if (branch is not None and tree is not None and
5158.6.6 by Martin Pool
Change info code to use user_url etc
451
        branch.user_url != tree.user_url):
2363.5.6 by Aaron Bentley
Add short format description
452
        branch = None
453
        repository = None
3152.2.2 by Robert Collins
The bzrdir format registry now accepts an ``alias`` keyword to
454
    non_aliases = set(bzrdir.format_registry.keys())
455
    non_aliases.difference_update(bzrdir.format_registry.aliases())
456
    for key in non_aliases:
2363.5.5 by Aaron Bentley
add info.describe_format
457
        format = bzrdir.format_registry.make_bzrdir(key)
458
        if isinstance(format, bzrdir.BzrDirMetaFormat1):
459
            if (tree and format.workingtree_format !=
460
                tree._format):
461
                continue
462
            if (branch and format.get_branch_format() !=
463
                branch._format):
464
                continue
465
            if (repository and format.repository_format !=
466
                repository._format):
467
                continue
468
        if format.__class__ is not control._format.__class__:
469
            continue
470
        candidates.append(key)
471
    if len(candidates) == 0:
472
        return 'unnamed'
3152.2.2 by Robert Collins
The bzrdir format registry now accepts an ``alias`` keyword to
473
    candidates.sort()
2363.5.6 by Aaron Bentley
Add short format description
474
    new_candidates = [c for c in candidates if not
475
        bzrdir.format_registry.get_info(c).hidden]
476
    if len(new_candidates) > 0:
3152.2.2 by Robert Collins
The bzrdir format registry now accepts an ``alias`` keyword to
477
        # If there are any non-hidden formats that match, only return those to
478
        # avoid listing hidden formats except when only a hidden format will
479
        # do.
2363.5.6 by Aaron Bentley
Add short format description
480
        candidates = new_candidates
2363.5.17 by Aaron Bentley
Change separator from '/' to 'or'
481
    return ' or '.join(candidates)
4307.3.1 by Jelmer Vernooij
Allow registering hooks that extend the Repository section in 'bzr info -v'.
482
483
484
class InfoHooks(_mod_hooks.Hooks):
485
    """Hooks for the info command."""
486
5622.3.10 by Jelmer Vernooij
Don't require arguments to hooks.
487
    def __init__(self):
488
        super(InfoHooks, self).__init__("bzrlib.info", "hooks")
5622.3.2 by Jelmer Vernooij
Add more lazily usable hook points.
489
        self.add_hook('repository',
4307.3.1 by Jelmer Vernooij
Allow registering hooks that extend the Repository section in 'bzr info -v'.
490
            "Invoked when displaying the statistics for a repository. "
491
            "repository is called with a statistics dictionary as returned "
5622.3.2 by Jelmer Vernooij
Add more lazily usable hook points.
492
            "by the repository and a file-like object to write to.", (1, 15))
493
494
5622.3.10 by Jelmer Vernooij
Don't require arguments to hooks.
495
hooks = InfoHooks()