/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/bzr/debug_commands.py

  • Committer: Jelmer Vernooij
  • Date: 2018-07-08 10:56:06 UTC
  • mto: This revision was merged to the branch mainline in revision 7030.
  • Revision ID: jelmer@jelmer.uk-20180708105606-d53hkks89qq88twu
Use separate .as_bytes method rather than __bytes__.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005-2012 Canonical Ltd
 
2
#
 
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.
 
7
#
 
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.
 
12
#
 
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
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
"""Debug commands for the bzr formats."""
 
18
 
 
19
from __future__ import absolute_import
 
20
 
 
21
from io import BytesIO
 
22
 
 
23
from .. import (
 
24
    errors,
 
25
    osutils,
 
26
    static_tuple,
 
27
    transport,
 
28
    )
 
29
from ..commands import Command
 
30
from ..option import Option
 
31
from . import (
 
32
    btree_index,
 
33
    )
 
34
 
 
35
 
 
36
class cmd_dump_btree(Command):
 
37
    __doc__ = """Dump the contents of a btree index file to stdout.
 
38
 
 
39
    PATH is a btree index file, it can be any URL. This includes things like
 
40
    .bzr/repository/pack-names, or .bzr/repository/indices/a34b3a...ca4a4.iix
 
41
 
 
42
    By default, the tuples stored in the index file will be displayed. With
 
43
    --raw, we will uncompress the pages, but otherwise display the raw bytes
 
44
    stored in the index.
 
45
    """
 
46
 
 
47
    # TODO: Do we want to dump the internal nodes as well?
 
48
    # TODO: It would be nice to be able to dump the un-parsed information,
 
49
    #       rather than only going through iter_all_entries. However, this is
 
50
    #       good enough for a start
 
51
    hidden = True
 
52
    encoding_type = 'exact'
 
53
    takes_args = ['path']
 
54
    takes_options = [Option('raw', help='Write the uncompressed bytes out,'
 
55
                                        ' rather than the parsed tuples.'),
 
56
                    ]
 
57
 
 
58
    def run(self, path, raw=False):
 
59
        dirname, basename = osutils.split(path)
 
60
        t = transport.get_transport(dirname)
 
61
        if raw:
 
62
            self._dump_raw_bytes(t, basename)
 
63
        else:
 
64
            self._dump_entries(t, basename)
 
65
 
 
66
    def _get_index_and_bytes(self, trans, basename):
 
67
        """Create a BTreeGraphIndex and raw bytes."""
 
68
        bt = btree_index.BTreeGraphIndex(trans, basename, None)
 
69
        bytes = trans.get_bytes(basename)
 
70
        bt._file = BytesIO(bytes)
 
71
        bt._size = len(bytes)
 
72
        return bt, bytes
 
73
 
 
74
    def _dump_raw_bytes(self, trans, basename):
 
75
        import zlib
 
76
 
 
77
        # We need to parse at least the root node.
 
78
        # This is because the first page of every row starts with an
 
79
        # uncompressed header.
 
80
        bt, bytes = self._get_index_and_bytes(trans, basename)
 
81
        for page_idx, page_start in enumerate(range(0, len(bytes),
 
82
                                                    btree_index._PAGE_SIZE)):
 
83
            page_end = min(page_start + btree_index._PAGE_SIZE, len(bytes))
 
84
            page_bytes = bytes[page_start:page_end]
 
85
            if page_idx == 0:
 
86
                self.outf.write('Root node:\n')
 
87
                header_end, data = bt._parse_header_from_bytes(page_bytes)
 
88
                self.outf.write(page_bytes[:header_end])
 
89
                page_bytes = data
 
90
            self.outf.write('\nPage %d\n' % (page_idx,))
 
91
            if len(page_bytes) == 0:
 
92
                self.outf.write('(empty)\n');
 
93
            else:
 
94
                decomp_bytes = zlib.decompress(page_bytes)
 
95
                self.outf.write(decomp_bytes)
 
96
                self.outf.write('\n')
 
97
 
 
98
    def _dump_entries(self, trans, basename):
 
99
        try:
 
100
            st = trans.stat(basename)
 
101
        except errors.TransportNotPossible:
 
102
            # We can't stat, so we'll fake it because we have to do the 'get()'
 
103
            # anyway.
 
104
            bt, _ = self._get_index_and_bytes(trans, basename)
 
105
        else:
 
106
            bt = btree_index.BTreeGraphIndex(trans, basename, st.st_size)
 
107
        for node in bt.iter_all_entries():
 
108
            # Node is made up of:
 
109
            # (index, key, value, [references])
 
110
            try:
 
111
                refs = node[3]
 
112
            except IndexError:
 
113
                refs_as_tuples = None
 
114
            else:
 
115
                refs_as_tuples = static_tuple.as_tuples(refs)
 
116
            as_tuple = (tuple(node[1]), node[2], refs_as_tuples)
 
117
            self.outf.write('%s\n' % (as_tuple,))