/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
1
# Copyright (C) 2005, 2006 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1 by mbp at sourcefrog
import from baz patch-364
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1 by mbp at sourcefrog
import from baz patch-364
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1 by mbp at sourcefrog
import from baz patch-364
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
1 by mbp at sourcefrog
import from baz patch-364
16
1374 by Martin Pool
todo
17
# TODO: Could remember a bias towards whether a particular store is typically
18
# compressed or not.
19
711 by Martin Pool
- store docs
20
"""
1861.2.6 by Alexander Belchenko
branding: change Bazaar-NG to Bazaar
21
Stores are the main data-storage mechanism for Bazaar.
1 by mbp at sourcefrog
import from baz patch-364
22
23
A store is a simple write-once container indexed by a universally
711 by Martin Pool
- store docs
24
unique ID.
25
"""
1 by mbp at sourcefrog
import from baz patch-364
26
6379.6.7 by Jelmer Vernooij
Move importing from future until after doc string, otherwise the doc string will disappear.
27
from __future__ import absolute_import
28
1442.1.51 by Robert Collins
teach iter about suffixes
29
import os
1185.1.41 by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid
30
6686.2.1 by Jelmer Vernooij
Move breezy.store to breezy.plugins.weave_fmt, its only user.
31
from .... import (
1955.3.13 by John Arbash Meinel
Run the full test suite, and fix up any deprecation warnings.
32
    errors,
6670.4.1 by Jelmer Vernooij
Update imports.
33
    )
6670.4.19 by Jelmer Vernooij
Fix import.
34
from ....bzr import (
3350.6.1 by Robert Collins
* New ``versionedfile.KeyMapper`` interface to abstract out the access to
35
    versionedfile,
1955.3.13 by John Arbash Meinel
Run the full test suite, and fix up any deprecation warnings.
36
    )
6686.2.1 by Jelmer Vernooij
Move breezy.store to breezy.plugins.weave_fmt, its only user.
37
from ....errors import BzrError, UnlistableStore
38
from ....trace import mutter
1 by mbp at sourcefrog
import from baz patch-364
39
40
######################################################################
41
# stores
42
7143.15.2 by Jelmer Vernooij
Run autopep8.
43
1 by mbp at sourcefrog
import from baz patch-364
44
class StoreError(Exception):
45
    pass
46
47
1185.11.1 by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet.
48
class Store(object):
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
49
    """This class represents the abstract storage layout for saving information.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
50
1 by mbp at sourcefrog
import from baz patch-364
51
    Files can be added, but not modified once they are in.  Typically
52
    the hash is used as the name, or something else known to be unique,
53
    such as a UUID.
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
54
    """
55
56
    def __len__(self):
57
        raise NotImplementedError('Children should define their length')
58
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
59
    def get(self, fileid, suffix=None):
1442.1.50 by Robert Collins
test get with suffixes
60
        """Returns a file reading from a particular entry.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
61
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
62
        If suffix is present, retrieve the named suffix for fileid.
1442.1.50 by Robert Collins
test get with suffixes
63
        """
64
        raise NotImplementedError
1442.1.35 by Robert Collins
convert all users of __getitem__ into TransportStores to use .get instead
65
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
66
    def __iter__(self):
67
        raise NotImplementedError
68
907.1.43 by John Arbash Meinel
Restoring compatibility for Storage.add(file, fileid), it is a little arbitrary, and compatibility is better
69
    def add(self, f, fileid):
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
70
        """Add a file object f to the store accessible from the given fileid"""
7143.15.2 by Jelmer Vernooij
Run autopep8.
71
        raise NotImplementedError(
72
            'Children of Store must define their method of adding entries.')
907.1.1 by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer.
73
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
74
    def has_id(self, fileid, suffix=None):
75
        """Return True or false for the presence of fileid in the store.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
76
77
        suffix, if present, is a per file suffix, i.e. for digital signature
1442.1.47 by Robert Collins
test for has with suffixed files
78
        data."""
1442.1.45 by Robert Collins
replace __contains__ calls in stores with has_id
79
        raise NotImplementedError
907.1.36 by John Arbash Meinel
Moving the multi-get functionality higher up into the Branch class.
80
1400.1.1 by Robert Collins
implement a basic test for the ui branch command from http servers
81
    def listable(self):
82
        """Return True if this store is able to be listed."""
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
83
        return (getattr(self, "__iter__", None) is not None)
1400.1.1 by Robert Collins
implement a basic test for the ui branch command from http servers
84
1092.2.24 by Robert Collins
merge from martins newformat branch - brings in transport abstraction
85
86
class TransportStore(Store):
87
    """A TransportStore is a Store superclass for Stores that use Transports."""
88
1442.1.33 by Robert Collins
teach TransportStore.add to accept an optional file suffix, which does not alter the fileid.
89
    def add(self, f, fileid, suffix=None):
1442.1.28 by Robert Collins
pull up core TransportStore.add from TextStore.add and CompressedTextStore.add
90
        """Add contents of a file into the store.
91
1955.3.13 by John Arbash Meinel
Run the full test suite, and fix up any deprecation warnings.
92
        f -- A file-like object
1442.1.28 by Robert Collins
pull up core TransportStore.add from TextStore.add and CompressedTextStore.add
93
        """
1185.16.159 by John Arbash Meinel
Updated the stores, all tests pass, and a store doesn't have to be 100% compressed
94
        mutter("add store entry %r", fileid)
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
95
        names = self._id_to_names(fileid, suffix)
96
        if self._transport.has_any(names):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
97
            raise BzrError("store %r already contains id %r"
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
98
                           % (self._transport.base, fileid))
1442.1.28 by Robert Collins
pull up core TransportStore.add from TextStore.add and CompressedTextStore.add
99
1185.16.159 by John Arbash Meinel
Updated the stores, all tests pass, and a store doesn't have to be 100% compressed
100
        # Most of the time, just adding the file will work
101
        # if we find a time where it fails, (because the dir
102
        # doesn't exist), then create the dir, and try again
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
103
        self._add(names[0], f)
104
105
    def _add(self, relpath, f):
106
        """Actually add the file to the given location.
107
        This should be overridden by children.
108
        """
109
        raise NotImplementedError('children need to implement this function.')
1442.1.28 by Robert Collins
pull up core TransportStore.add from TextStore.add and CompressedTextStore.add
110
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
111
    def _check_fileid(self, fileid):
6963.2.10 by Jelmer Vernooij
Fix a bunch of tests.
112
        if not isinstance(fileid, bytes):
3350.6.1 by Robert Collins
* New ``versionedfile.KeyMapper`` interface to abstract out the access to
113
            raise TypeError('Fileids should be bytestrings: %s %r' % (
114
                type(fileid), fileid))
6963.2.6 by Jelmer Vernooij
Fix some more tests.
115
        if b'\\' in fileid or b'/' in fileid:
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
116
            raise ValueError("invalid store id %r" % fileid)
117
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
118
    def _id_to_names(self, fileid, suffix):
119
        """Return the names in the expected order"""
1442.1.47 by Robert Collins
test for has with suffixed files
120
        if suffix is not None:
121
            fn = self._relpath(fileid, [suffix])
122
        else:
123
            fn = self._relpath(fileid)
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
124
1185.65.13 by Robert Collins
Merge from integration
125
        # FIXME RBC 20051128 this belongs in TextStore.
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
126
        fn_gz = fn + '.gz'
127
        if self._compressed:
128
            return fn_gz, fn
129
        else:
130
            return fn, fn_gz
131
132
    def has_id(self, fileid, suffix=None):
133
        """See Store.has_id."""
1651.1.5 by Martin Pool
Review cleanup of TransportStore.has_id
134
        return self._transport.has_any(self._id_to_names(fileid, suffix))
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
135
136
    def _get_name(self, fileid, suffix=None):
137
        """A special check, which returns the name of an existing file.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
138
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
139
        This is similar in spirit to 'has_id', but it is designed
140
        to return information about which file the store has.
141
        """
142
        for name in self._id_to_names(fileid, suffix=suffix):
143
            if self._transport.has(name):
144
                return name
145
        return None
1442.1.38 by Robert Collins
unify __contains__ for TransportStore classes
146
1442.1.36 by Robert Collins
convert get() in TextStore and CompressedTextStore into a template method
147
    def _get(self, filename):
148
        """Return an vanilla file stream for clients to read from.
149
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
150
        This is the body of a template method on 'get', and should be
1442.1.36 by Robert Collins
convert get() in TextStore and CompressedTextStore into a template method
151
        implemented by subclasses.
152
        """
153
        raise NotImplementedError
154
1442.1.50 by Robert Collins
test get with suffixes
155
    def get(self, fileid, suffix=None):
156
        """See Store.get()."""
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
157
        names = self._id_to_names(fileid, suffix)
158
        for name in names:
159
            try:
160
                return self._get(name)
161
            except errors.NoSuchFile:
162
                pass
163
        raise KeyError(fileid)
1433 by Robert Collins
merge in and make incremental Gustavo Niemeyers nested log patch, and remove all bare exceptions in store and transport packages.
164
1185.58.4 by John Arbash Meinel
Added permission checking to Branch, and propogated that change into the stores.
165
    def __init__(self, a_transport, prefixed=False, compressed=False,
1185.80.1 by John Arbash Meinel
Text store and weave store both allow escaping fileid paths.
166
                 dir_mode=None, file_mode=None,
167
                 escaped=False):
1092.2.24 by Robert Collins
merge from martins newformat branch - brings in transport abstraction
168
        super(TransportStore, self).__init__()
1442.1.44 by Robert Collins
Many transport related tweaks:
169
        self._transport = a_transport
1442.1.25 by Robert Collins
Test TransportStore._relpath for simple cases: pull up _prefixed attribute as a result.
170
        self._prefixed = prefixed
1185.65.13 by Robert Collins
Merge from integration
171
        # FIXME RBC 20051128 this belongs in TextStore.
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
172
        self._compressed = compressed
1442.1.43 by Robert Collins
add registration of suffixes, in preparation for ensuring iteration is regular
173
        self._suffixes = set()
1185.80.1 by John Arbash Meinel
Text store and weave store both allow escaping fileid paths.
174
        self._escaped = escaped
1092.2.24 by Robert Collins
merge from martins newformat branch - brings in transport abstraction
175
1185.58.6 by John Arbash Meinel
Stores don't have to have a dir_mode or file_mode set
176
        # It is okay for these to be None, it just means they
177
        # will just use the filesystem defaults
178
        self._dir_mode = dir_mode
179
        self._file_mode = file_mode
3350.6.1 by Robert Collins
* New ``versionedfile.KeyMapper`` interface to abstract out the access to
180
        # Create a key mapper to use
181
        if escaped and prefixed:
182
            self._mapper = versionedfile.HashEscapedPrefixMapper()
183
        elif not escaped and prefixed:
184
            self._mapper = versionedfile.HashPrefixMapper()
185
        elif self._escaped:
3350.6.8 by Martin Pool
Change stray pdb calls to exceptions
186
            raise ValueError(
187
                "%r: escaped unprefixed stores are not permitted."
188
                % (self,))
1608.2.1 by Martin Pool
[merge] Storage filename escaping
189
        else:
3350.6.1 by Robert Collins
* New ``versionedfile.KeyMapper`` interface to abstract out the access to
190
            self._mapper = versionedfile.PrefixMapper()
1608.2.1 by Martin Pool
[merge] Storage filename escaping
191
1479 by Robert Collins
More quoting at the transport layer bugfixes.
192
    def _iter_files_recursive(self):
193
        """Iterate through the files in the transport."""
194
        for quoted_relpath in self._transport.iter_files_recursive():
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
195
            yield quoted_relpath
1479 by Robert Collins
More quoting at the transport layer bugfixes.
196
1442.1.51 by Robert Collins
teach iter about suffixes
197
    def __iter__(self):
1479 by Robert Collins
More quoting at the transport layer bugfixes.
198
        for relpath in self._iter_files_recursive():
1442.1.51 by Robert Collins
teach iter about suffixes
199
            # worst case is one of each suffix.
200
            name = os.path.basename(relpath)
201
            if name.endswith('.gz'):
202
                name = name[:-3]
203
            skip = False
204
            for count in range(len(self._suffixes)):
205
                for suffix in self._suffixes:
206
                    if name.endswith('.' + suffix):
207
                        skip = True
208
            if not skip:
3350.6.1 by Robert Collins
* New ``versionedfile.KeyMapper`` interface to abstract out the access to
209
                yield self._mapper.unmap(name)[0]
1442.1.51 by Robert Collins
teach iter about suffixes
210
1442.1.40 by Robert Collins
unify __len__() implementations for TransportStore classes
211
    def __len__(self):
1442.1.50 by Robert Collins
test get with suffixes
212
        return len(list(self.__iter__()))
1442.1.40 by Robert Collins
unify __len__() implementations for TransportStore classes
213
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
214
    def _relpath(self, fileid, suffixes=None):
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
215
        self._check_fileid(fileid)
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
216
        if suffixes:
217
            for suffix in suffixes:
7183.3.1 by Martin
Fix E71* lint errors
218
                if suffix not in self._suffixes:
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
219
                    raise ValueError("Unregistered suffix %r" % suffix)
6963.2.10 by Jelmer Vernooij
Fix a bunch of tests.
220
                self._check_fileid(suffix.encode('utf-8'))
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
221
        else:
222
            suffixes = []
3350.6.1 by Robert Collins
* New ``versionedfile.KeyMapper`` interface to abstract out the access to
223
        path = self._mapper.map((fileid,))
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
224
        full_path = '.'.join([path] + suffixes)
225
        return full_path
1442.1.24 by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore
226
1092.2.24 by Robert Collins
merge from martins newformat branch - brings in transport abstraction
227
    def __repr__(self):
228
        if self._transport is None:
229
            return "%s(None)" % (self.__class__.__name__)
230
        else:
231
            return "%s(%r)" % (self.__class__.__name__, self._transport.base)
232
233
    __str__ = __repr__
1185.10.1 by Aaron Bentley
Added --basis option to bzr branch
234
1400.1.1 by Robert Collins
implement a basic test for the ui branch command from http servers
235
    def listable(self):
236
        """Return True if this store is able to be listed."""
237
        return self._transport.listable()
238
1442.1.43 by Robert Collins
add registration of suffixes, in preparation for ensuring iteration is regular
239
    def register_suffix(self, suffix):
240
        """Register a suffix as being expected in this store."""
6963.2.10 by Jelmer Vernooij
Fix a bunch of tests.
241
        self._check_fileid(suffix.encode('utf-8'))
1185.16.157 by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first
242
        if suffix == 'gz':
243
            raise ValueError('You cannot register the "gz" suffix.')
1442.1.43 by Robert Collins
add registration of suffixes, in preparation for ensuring iteration is regular
244
        self._suffixes.add(suffix)
245
1442.1.37 by Robert Collins
pull up total_size into TransportStore
246
    def total_size(self):
247
        """Return (count, bytes)
248
249
        This is the (compressed) size stored on disk, not the size of
250
        the content."""
251
        total = 0
252
        count = 0
1442.1.44 by Robert Collins
Many transport related tweaks:
253
        for relpath in self._transport.iter_files_recursive():
1442.1.37 by Robert Collins
pull up total_size into TransportStore
254
            count += 1
1442.1.44 by Robert Collins
Many transport related tweaks:
255
            total += self._transport.stat(relpath).st_size
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
256
1442.1.37 by Robert Collins
pull up total_size into TransportStore
257
        return count, total