/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/info.py

  • Committer: Martin
  • Date: 2017-08-26 16:16:11 UTC
  • mto: This revision was merged to the branch mainline in revision 6763.
  • Revision ID: gzlist@googlemail.com-20170826161611-gzjgbcvq03u9vr38
One last dict.iteritems() in hooks tests

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
16
16
 
 
17
from __future__ import absolute_import
 
18
 
17
19
__all__ = ['show_bzrdir_info']
18
20
 
19
 
from cStringIO import StringIO
20
21
import time
21
22
import sys
22
23
 
23
 
from bzrlib import (
24
 
    bzrdir,
 
24
from . import (
 
25
    branch as _mod_branch,
 
26
    controldir,
25
27
    errors,
26
28
    hooks as _mod_hooks,
27
29
    osutils,
28
30
    urlutils,
29
31
    )
30
 
from bzrlib.errors import (NoWorkingTree, NotBranchError,
 
32
from .bzr import (
 
33
    bzrdir,
 
34
    )
 
35
from .errors import (NoWorkingTree, NotBranchError,
31
36
                           NoRepositoryPresent, NotLocalUrl)
32
 
from bzrlib.missing import find_unmerged
 
37
from .missing import find_unmerged
 
38
from .sixish import (
 
39
    BytesIO,
 
40
    )
33
41
 
34
42
 
35
43
def plural(n, base='', pl=None):
53
61
            return
54
62
        try:
55
63
            path = urlutils.local_path_from_url(url)
56
 
        except errors.InvalidURL:
 
64
        except urlutils.InvalidURL:
57
65
            self.locs.append((label, url))
58
66
        else:
59
67
            self.add_path(label, path)
76
84
        return ["  %*s: %s\n" % (max_len, l, u) for l, u in self.locs ]
77
85
 
78
86
 
79
 
def gather_location_info(repository, branch=None, working=None):
 
87
def gather_location_info(repository=None, branch=None, working=None,
 
88
        control=None):
80
89
    locs = {}
81
 
    repository_path = repository.user_url
82
90
    if branch is not None:
83
91
        branch_path = branch.user_url
84
92
        master_path = branch.get_bound_location()
87
95
    else:
88
96
        branch_path = None
89
97
        master_path = None
 
98
        try:
 
99
            if control is not None and control.get_branch_reference():
 
100
                locs['checkout of branch'] = control.get_branch_reference()
 
101
        except NotBranchError:
 
102
            pass
90
103
    if working:
91
104
        working_path = working.user_url
92
105
        if working_path != branch_path:
105
118
            locs['branch root'] = branch_path
106
119
    else:
107
120
        working_path = None
108
 
        if repository.is_shared():
 
121
        if repository is not None and repository.is_shared():
109
122
            # lightweight checkout of branch in shared repository
110
123
            if branch_path is not None:
111
124
                locs['repository branch'] = branch_path
112
125
        elif branch_path is not None:
113
126
            # standalone
114
127
            locs['branch root'] = branch_path
115
 
            if master_path != branch_path:
116
 
                locs['bound to branch'] = master_path
 
128
        elif repository is not None:
 
129
            locs['repository'] = repository.user_url
 
130
        elif control is not None:
 
131
            locs['control directory'] = control.user_url
117
132
        else:
118
 
            locs['repository'] = repository_path
119
 
    if repository.is_shared():
 
133
            # Really, at least a control directory should be
 
134
            # passed in for this method to be useful.
 
135
            pass
 
136
        if master_path != branch_path:
 
137
            locs['bound to branch'] = master_path
 
138
    if repository is not None and repository.is_shared():
120
139
        # lightweight checkout of branch in shared repository
121
 
        locs['shared repository'] = repository_path
122
 
    order = ['light checkout root', 'repository checkout root',
123
 
             'checkout root', 'checkout of branch', 'shared repository',
 
140
        locs['shared repository'] = repository.user_url
 
141
    order = ['control directory', 'light checkout root',
 
142
             'repository checkout root', 'checkout root',
 
143
             'checkout of branch', 'shared repository',
124
144
             'repository', 'repository branch', 'branch root',
125
145
             'bound to branch']
126
146
    return [(n, locs[n]) for n in order if n in locs]
143
163
    locs.add_url('submit branch', branch.get_submit_branch())
144
164
    try:
145
165
        locs.add_url('stacked on', branch.get_stacked_on_url())
146
 
    except (errors.UnstackableBranchFormat, errors.UnstackableRepositoryFormat,
 
166
    except (_mod_branch.UnstackableBranchFormat, errors.UnstackableRepositoryFormat,
147
167
        errors.NotStacked):
148
168
        pass
149
169
    return locs
158
178
        outfile.writelines(locs.get_lines())
159
179
 
160
180
 
 
181
def _show_control_dir_info(control, outfile):
 
182
    """Show control dir information."""
 
183
    if control._format.colocated_branches:
 
184
        outfile.write('\n')
 
185
        outfile.write('Control directory:\n')
 
186
        outfile.write('         %d branches\n' % len(control.list_branches()))
 
187
 
 
188
 
161
189
def _show_format_info(control=None, repository=None, branch=None,
162
190
                      working=None, outfile=None):
163
191
    """Show known formats for control, working, branch and repository."""
177
205
            repository._format.get_format_description())
178
206
 
179
207
 
180
 
def _show_locking_info(repository, branch=None, working=None, outfile=None):
 
208
def _show_locking_info(repository=None, branch=None, working=None,
 
209
        outfile=None):
181
210
    """Show locking status of working, branch and repository."""
182
 
    if (repository.get_physical_lock_status() or
 
211
    if (repository and repository.get_physical_lock_status() or
183
212
        (branch and branch.get_physical_lock_status()) or
184
213
        (working and working.get_physical_lock_status())):
185
214
        outfile.write('\n')
221
250
    """Show missing revisions in working tree."""
222
251
    branch = working.branch
223
252
    basis = working.basis_tree()
224
 
    work_inv = working.inventory
225
 
    branch_revno, branch_last_revision = branch.last_revision_info()
 
253
    try:
 
254
        branch_revno, branch_last_revision = branch.last_revision_info()
 
255
    except errors.UnsupportedOperation:
 
256
        return
226
257
    try:
227
258
        tree_last_id = working.get_parent_ids()[0]
228
259
    except IndexError:
239
270
def _show_working_stats(working, outfile):
240
271
    """Show statistics about a working tree."""
241
272
    basis = working.basis_tree()
242
 
    work_inv = working.inventory
243
273
    delta = working.changes_from(basis, want_unchanged=True)
244
274
 
245
275
    outfile.write('\n')
260
290
    outfile.write('  %8d ignored\n' % ignore_cnt)
261
291
 
262
292
    dir_cnt = 0
263
 
    for file_id in work_inv:
264
 
        if (work_inv.get_file_kind(file_id) == 'directory' and
265
 
            not work_inv.is_root(file_id)):
 
293
    root_id = working.get_root_id()
 
294
    for path, entry in working.iter_entries_by_dir():
 
295
        if entry.kind == 'directory' and entry.file_id != root_id:
266
296
            dir_cnt += 1
267
297
    outfile.write('  %8d versioned %s\n' % (dir_cnt,
268
298
        plural(dir_cnt, 'subdirectory', 'subdirectories')))
270
300
 
271
301
def _show_branch_stats(branch, verbose, outfile):
272
302
    """Show statistics about a branch."""
273
 
    revno, head = branch.last_revision_info()
 
303
    try:
 
304
        revno, head = branch.last_revision_info()
 
305
    except errors.UnsupportedOperation:
 
306
        return {}
274
307
    outfile.write('\n')
275
308
    outfile.write('Branch history:\n')
276
309
    outfile.write('  %8d revision%s\n' % (revno, plural(revno)))
301
334
 
302
335
def _show_repository_stats(repository, stats, outfile):
303
336
    """Show statistics about a repository."""
304
 
    f = StringIO()
 
337
    f = BytesIO()
305
338
    if 'revisions' in stats:
306
339
        revisions = stats['revisions']
307
340
        f.write('  %8d revision%s\n' % (revisions, plural(revisions)))
315
348
        outfile.write(f.getvalue())
316
349
 
317
350
 
318
 
def show_bzrdir_info(a_bzrdir, verbose=False, outfile=None):
319
 
    """Output to stdout the 'info' for a_bzrdir."""
 
351
def show_bzrdir_info(a_controldir, verbose=False, outfile=None):
 
352
    """Output to stdout the 'info' for a_controldir."""
320
353
    if outfile is None:
321
354
        outfile = sys.stdout
322
355
    try:
323
 
        tree = a_bzrdir.open_workingtree(
 
356
        tree = a_controldir.open_workingtree(
324
357
            recommend_upgrade=False)
325
 
    except (NoWorkingTree, NotLocalUrl):
 
358
    except (NoWorkingTree, NotLocalUrl, NotBranchError):
326
359
        tree = None
327
360
        try:
328
 
            branch = a_bzrdir.open_branch()
 
361
            branch = a_controldir.open_branch(name="")
329
362
        except NotBranchError:
330
363
            branch = None
331
364
            try:
332
 
                repository = a_bzrdir.open_repository()
 
365
                repository = a_controldir.open_repository()
333
366
            except NoRepositoryPresent:
334
 
                # Return silently; cmd_info already returned NotBranchError
335
 
                # if no bzrdir could be opened.
336
 
                return
 
367
                lockable = None
 
368
                repository = None
337
369
            else:
338
370
                lockable = repository
339
371
        else:
344
376
        repository = branch.repository
345
377
        lockable = tree
346
378
 
347
 
    lockable.lock_read()
 
379
    if lockable is not None:
 
380
        lockable.lock_read()
348
381
    try:
349
 
        show_component_info(a_bzrdir, repository, branch, tree, verbose,
 
382
        show_component_info(a_controldir, repository, branch, tree, verbose,
350
383
                            outfile)
351
384
    finally:
352
 
        lockable.unlock()
 
385
        if lockable is not None:
 
386
            lockable.unlock()
353
387
 
354
388
 
355
389
def show_component_info(control, repository, branch=None, working=None,
361
395
        verbose = 1
362
396
    if verbose is True:
363
397
        verbose = 2
364
 
    layout = describe_layout(repository, branch, working)
 
398
    layout = describe_layout(repository, branch, working, control)
365
399
    format = describe_format(control, repository, branch, working)
366
400
    outfile.write("%s (format: %s)\n" % (layout, format))
367
 
    _show_location_info(gather_location_info(repository, branch, working),
368
 
                        outfile)
 
401
    _show_location_info(
 
402
        gather_location_info(control=control, repository=repository,
 
403
            branch=branch, working=working),
 
404
        outfile)
369
405
    if branch is not None:
370
406
        _show_related_info(branch, outfile)
371
407
    if verbose == 0:
372
408
        return
373
409
    _show_format_info(control, repository, branch, working, outfile)
374
410
    _show_locking_info(repository, branch, working, outfile)
 
411
    _show_control_dir_info(control, outfile)
375
412
    if branch is not None:
376
413
        _show_missing_revisions_branch(branch, outfile)
377
414
    if working is not None:
382
419
    if branch is not None:
383
420
        show_committers = verbose >= 2
384
421
        stats = _show_branch_stats(branch, show_committers, outfile)
385
 
    else:
 
422
    elif repository is not None:
386
423
        stats = repository.gather_stats()
387
 
    if branch is None and working is None:
 
424
    if branch is None and working is None and repository is not None:
388
425
        _show_repository_info(repository, outfile)
389
 
    _show_repository_stats(repository, stats, outfile)
390
 
 
391
 
 
392
 
def describe_layout(repository=None, branch=None, tree=None):
 
426
    if repository is not None:
 
427
        _show_repository_stats(repository, stats, outfile)
 
428
 
 
429
 
 
430
def describe_layout(repository=None, branch=None, tree=None, control=None):
393
431
    """Convert a control directory layout into a user-understandable term
394
432
 
395
433
    Common outputs include "Standalone tree", "Repository branch" and
396
434
    "Checkout".  Uncommon outputs include "Unshared repository with trees"
397
435
    and "Empty control directory"
398
436
    """
 
437
    if branch is None and control is not None:
 
438
        try:
 
439
            branch_reference = control.get_branch_reference()
 
440
        except NotBranchError:
 
441
            pass
 
442
        else:
 
443
            if branch_reference is not None:
 
444
                return "Dangling branch reference"
399
445
    if repository is None:
400
446
        return 'Empty control directory'
401
447
    if branch is None and tree is None:
403
449
            phrase = 'Shared repository'
404
450
        else:
405
451
            phrase = 'Unshared repository'
 
452
        extra = []
406
453
        if repository.make_working_trees():
407
 
            phrase += ' with trees'
 
454
            extra.append('trees')
 
455
        if len(control.get_branches()) > 0:
 
456
            extra.append('colocated branches')
 
457
        if extra:
 
458
            phrase += ' with ' + " and ".join(extra)
408
459
        return phrase
409
460
    else:
410
461
        if repository.is_shared():
447
498
        branch.user_url != tree.user_url):
448
499
        branch = None
449
500
        repository = None
450
 
    non_aliases = set(bzrdir.format_registry.keys())
451
 
    non_aliases.difference_update(bzrdir.format_registry.aliases())
 
501
    non_aliases = set(controldir.format_registry.keys())
 
502
    non_aliases.difference_update(controldir.format_registry.aliases())
452
503
    for key in non_aliases:
453
 
        format = bzrdir.format_registry.make_bzrdir(key)
 
504
        format = controldir.format_registry.make_controldir(key)
454
505
        if isinstance(format, bzrdir.BzrDirMetaFormat1):
455
506
            if (tree and format.workingtree_format !=
456
507
                tree._format):
468
519
        return 'unnamed'
469
520
    candidates.sort()
470
521
    new_candidates = [c for c in candidates if not
471
 
        bzrdir.format_registry.get_info(c).hidden]
 
522
        controldir.format_registry.get_info(c).hidden]
472
523
    if len(new_candidates) > 0:
473
524
        # If there are any non-hidden formats that match, only return those to
474
525
        # avoid listing hidden formats except when only a hidden format will
481
532
    """Hooks for the info command."""
482
533
 
483
534
    def __init__(self):
484
 
        super(InfoHooks, self).__init__()
485
 
        self.create_hook(_mod_hooks.HookPoint('repository',
 
535
        super(InfoHooks, self).__init__("breezy.info", "hooks")
 
536
        self.add_hook('repository',
486
537
            "Invoked when displaying the statistics for a repository. "
487
538
            "repository is called with a statistics dictionary as returned "
488
 
            "by the repository and a file-like object to write to.", (1, 15), 
489
 
            None))
 
539
            "by the repository and a file-like object to write to.", (1, 15))
490
540
 
491
541
 
492
542
hooks = InfoHooks()