/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-08-26 02:01:46 UTC
  • mto: This revision was merged to the branch mainline in revision 7087.
  • Revision ID: jelmer@jelmer.uk-20180826020146-owq7fxsr6ermorlh
Fix remaining warnings on Python 3.

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