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
|
|
15 |
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
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 |
|
1442.1.51
by Robert Collins
teach iter about suffixes |
27 |
import os |
1092.2.24
by Robert Collins
merge from martins newformat branch - brings in transport abstraction |
28 |
from cStringIO import StringIO |
1479
by Robert Collins
More quoting at the transport layer bugfixes. |
29 |
import urllib |
1429
by Robert Collins
merge in niemeyers prefixed-store patch |
30 |
from zlib import adler32 |
1185.1.41
by Robert Collins
massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid |
31 |
|
1442.1.44
by Robert Collins
Many transport related tweaks: |
32 |
import bzrlib |
1955.3.13
by John Arbash Meinel
Run the full test suite, and fix up any deprecation warnings. |
33 |
from bzrlib import ( |
34 |
errors, |
|
2294.1.10
by John Arbash Meinel
Switch all apis over to utf8 file ids. All tests pass |
35 |
osutils, |
1955.3.13
by John Arbash Meinel
Run the full test suite, and fix up any deprecation warnings. |
36 |
symbol_versioning, |
37 |
urlutils, |
|
38 |
)
|
|
1393.2.3
by John Arbash Meinel
Fixing typos, updating stores, getting tests to pass. |
39 |
from bzrlib.errors import BzrError, UnlistableStore, TransportNotPossible |
1955.3.13
by John Arbash Meinel
Run the full test suite, and fix up any deprecation warnings. |
40 |
from bzrlib.symbol_versioning import ( |
41 |
deprecated_function, |
|
42 |
zero_eight, |
|
43 |
zero_eleven, |
|
44 |
)
|
|
1104
by Martin Pool
- Add a simple UIFactory |
45 |
from bzrlib.trace import mutter |
1685.1.45
by John Arbash Meinel
Moved url functions into bzrlib.urlutils |
46 |
from bzrlib.transport import Transport |
1092.2.24
by Robert Collins
merge from martins newformat branch - brings in transport abstraction |
47 |
from bzrlib.transport.local import LocalTransport |
1
by mbp at sourcefrog
import from baz patch-364 |
48 |
|
49 |
######################################################################
|
|
50 |
# stores
|
|
51 |
||
52 |
class StoreError(Exception): |
|
53 |
pass
|
|
54 |
||
55 |
||
1185.11.1
by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet. |
56 |
class Store(object): |
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
57 |
"""This class represents the abstract storage layout for saving information.
|
1092.2.24
by Robert Collins
merge from martins newformat branch - brings in transport abstraction |
58 |
|
1
by mbp at sourcefrog
import from baz patch-364 |
59 |
Files can be added, but not modified once they are in. Typically
|
60 |
the hash is used as the name, or something else known to be unique,
|
|
61 |
such as a UUID.
|
|
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
62 |
"""
|
63 |
||
64 |
def __len__(self): |
|
65 |
raise NotImplementedError('Children should define their length') |
|
66 |
||
1185.16.157
by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first |
67 |
def get(self, fileid, suffix=None): |
1442.1.50
by Robert Collins
test get with suffixes |
68 |
"""Returns a file reading from a particular entry.
|
69 |
|
|
1185.16.157
by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first |
70 |
If suffix is present, retrieve the named suffix for fileid.
|
1442.1.50
by Robert Collins
test get with suffixes |
71 |
"""
|
72 |
raise NotImplementedError |
|
1442.1.35
by Robert Collins
convert all users of __getitem__ into TransportStores to use .get instead |
73 |
|
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
74 |
def __getitem__(self, 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 |
75 |
"""DEPRECATED. Please use .get(fileid) instead."""
|
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
76 |
raise NotImplementedError |
77 |
||
1442.1.45
by Robert Collins
replace __contains__ calls in stores with has_id |
78 |
#def __contains__(self, fileid):
|
79 |
# """Deprecated, please use has_id"""
|
|
80 |
# raise NotImplementedError
|
|
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
81 |
|
82 |
def __iter__(self): |
|
83 |
raise NotImplementedError |
|
84 |
||
907.1.43
by John Arbash Meinel
Restoring compatibility for Storage.add(file, fileid), it is a little arbitrary, and compatibility is better |
85 |
def add(self, f, fileid): |
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
86 |
"""Add a file object f to the store accessible from the given fileid"""
|
1185.11.1
by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet. |
87 |
raise NotImplementedError('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. |
88 |
|
1185.16.157
by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first |
89 |
def has_id(self, fileid, suffix=None): |
90 |
"""Return True or false for the presence of fileid in the store.
|
|
1442.1.47
by Robert Collins
test for has with suffixed files |
91 |
|
92 |
suffix, if present, is a per file suffix, i.e. for digital signature
|
|
93 |
data."""
|
|
1442.1.45
by Robert Collins
replace __contains__ calls in stores with has_id |
94 |
raise NotImplementedError |
907.1.36
by John Arbash Meinel
Moving the multi-get functionality higher up into the Branch class. |
95 |
|
1400.1.1
by Robert Collins
implement a basic test for the ui branch command from http servers |
96 |
def listable(self): |
97 |
"""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'. |
98 |
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 |
99 |
|
1563.2.14
by Robert Collins
Prepare weave store to delegate copy details to the versioned file. |
100 |
def copy_all_ids(self, store_from, pb=None): |
101 |
"""Copy all the file ids from store_from into self."""
|
|
102 |
if not store_from.listable(): |
|
103 |
raise UnlistableStore(store_from) |
|
104 |
ids = [] |
|
105 |
for count, file_id in enumerate(store_from): |
|
106 |
if pb: |
|
107 |
pb.update('listing files', count, count) |
|
108 |
ids.append(file_id) |
|
109 |
if pb: |
|
110 |
pb.clear() |
|
111 |
mutter('copy_all ids: %r', ids) |
|
112 |
self.copy_multi(store_from, ids, pb=pb) |
|
113 |
||
1185.11.1
by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet. |
114 |
def copy_multi(self, other, ids, pb=None, permit_failure=False): |
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
115 |
"""Copy texts for ids from other into self.
|
116 |
||
117 |
If an id is present in self, it is skipped. A count of copied
|
|
118 |
ids is returned, which may be less than len(ids).
|
|
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
119 |
|
1185.11.1
by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet. |
120 |
:param other: Another Store object
|
907.1.2
by John Arbash Meinel
Working on making Branch() do all of it's work over a Transport. |
121 |
:param ids: A list of entry ids to be copied
|
1185.11.1
by John Arbash Meinel
(broken) Transport work is merged in. Tests do not pass yet. |
122 |
:param pb: A ProgressBar object, if none is given, the default will be created.
|
123 |
:param permit_failure: Allow missing entries to be ignored
|
|
124 |
:return: (n_copied, [failed]) The number of entries copied successfully,
|
|
125 |
followed by a list of entries which could not be copied (because they
|
|
126 |
were missing)
|
|
907.1.1
by John Arbash Meinel
Reworking the Branch and Store code to support an abstracted filesystem layer. |
127 |
"""
|
1185.79.2
by John Arbash Meinel
Adding progress bars to copy_all and copy_multi, fixing ordering of repository.clone() to pull inventories after weaves. |
128 |
if pb: |
129 |
pb.update('preparing to copy') |
|
974.2.7
by aaron.bentley at utoronto
Merged from bzr.24 |
130 |
failed = set() |
1442.1.53
by Robert Collins
Unroll the multiple-copy logic enough to remove the duplicate iteration and yet retain the optimised gzip->gzip copy. |
131 |
count = 0 |
2294.1.10
by John Arbash Meinel
Switch all apis over to utf8 file ids. All tests pass |
132 |
ids = [osutils.safe_file_id(i) for i in ids] # get the list for showing a length. |
1442.1.53
by Robert Collins
Unroll the multiple-copy logic enough to remove the duplicate iteration and yet retain the optimised gzip->gzip copy. |
133 |
for fileid in ids: |
134 |
count += 1 |
|
135 |
if self.has_id(fileid): |
|
136 |
continue
|
|
137 |
try: |
|
1442.1.54
by Robert Collins
Teach store.copy_all about fileid suffixes |
138 |
self._copy_one(fileid, None, other, pb) |
139 |
for suffix in self._suffixes: |
|
140 |
try: |
|
141 |
self._copy_one(fileid, suffix, other, pb) |
|
142 |
except KeyError: |
|
143 |
pass
|
|
1185.79.2
by John Arbash Meinel
Adding progress bars to copy_all and copy_multi, fixing ordering of repository.clone() to pull inventories after weaves. |
144 |
if pb: |
145 |
pb.update('copy', count, len(ids)) |
|
1442.1.53
by Robert Collins
Unroll the multiple-copy logic enough to remove the duplicate iteration and yet retain the optimised gzip->gzip copy. |
146 |
except KeyError: |
147 |
if permit_failure: |
|
148 |
failed.add(fileid) |
|
149 |
else: |
|
150 |
raise
|
|
151 |
assert count == len(ids) |
|
1185.79.2
by John Arbash Meinel
Adding progress bars to copy_all and copy_multi, fixing ordering of repository.clone() to pull inventories after weaves. |
152 |
if pb: |
153 |
pb.clear() |
|
1442.1.53
by Robert Collins
Unroll the multiple-copy logic enough to remove the duplicate iteration and yet retain the optimised gzip->gzip copy. |
154 |
return count, failed |
155 |
||
1442.1.54
by Robert Collins
Teach store.copy_all about fileid suffixes |
156 |
def _copy_one(self, fileid, suffix, other, pb): |
1442.1.53
by Robert Collins
Unroll the multiple-copy logic enough to remove the duplicate iteration and yet retain the optimised gzip->gzip copy. |
157 |
"""Most generic copy-one object routine.
|
158 |
|
|
159 |
Subclasses can override this to provide an optimised
|
|
160 |
copy between their own instances. Such overriden routines
|
|
161 |
should call this if they have no optimised facility for a
|
|
162 |
specific 'other'.
|
|
163 |
"""
|
|
1185.16.159
by John Arbash Meinel
Updated the stores, all tests pass, and a store doesn't have to be 100% compressed |
164 |
mutter('Store._copy_one: %r', fileid) |
1442.1.54
by Robert Collins
Teach store.copy_all about fileid suffixes |
165 |
f = other.get(fileid, suffix) |
166 |
self.add(f, fileid, suffix) |
|
1185.10.1
by Aaron Bentley
Added --basis option to bzr branch |
167 |
|
1092.2.24
by Robert Collins
merge from martins newformat branch - brings in transport abstraction |
168 |
|
169 |
class TransportStore(Store): |
|
170 |
"""A TransportStore is a Store superclass for Stores that use Transports."""
|
|
171 |
||
1442.1.33
by Robert Collins
teach TransportStore.add to accept an optional file suffix, which does not alter the fileid. |
172 |
def add(self, f, fileid, suffix=None): |
1442.1.28
by Robert Collins
pull up core TransportStore.add from TextStore.add and CompressedTextStore.add |
173 |
"""Add contents of a file into the store.
|
174 |
||
1955.3.13
by John Arbash Meinel
Run the full test suite, and fix up any deprecation warnings. |
175 |
f -- A file-like object
|
1442.1.28
by Robert Collins
pull up core TransportStore.add from TextStore.add and CompressedTextStore.add |
176 |
"""
|
2294.1.10
by John Arbash Meinel
Switch all apis over to utf8 file ids. All tests pass |
177 |
fileid = osutils.safe_file_id(fileid) |
1185.16.159
by John Arbash Meinel
Updated the stores, all tests pass, and a store doesn't have to be 100% compressed |
178 |
mutter("add store entry %r", fileid) |
1955.3.13
by John Arbash Meinel
Run the full test suite, and fix up any deprecation warnings. |
179 |
if isinstance(f, str): |
180 |
symbol_versioning.warn(zero_eleven % 'Passing a string to Store.add', |
|
181 |
DeprecationWarning, stacklevel=2) |
|
182 |
f = StringIO(f) |
|
1442.1.33
by Robert Collins
teach TransportStore.add to accept an optional file suffix, which does not alter the fileid. |
183 |
|
1185.16.157
by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first |
184 |
names = self._id_to_names(fileid, suffix) |
185 |
if self._transport.has_any(names): |
|
186 |
raise BzrError("store %r already contains id %r" |
|
187 |
% (self._transport.base, fileid)) |
|
1442.1.28
by Robert Collins
pull up core TransportStore.add from TextStore.add and CompressedTextStore.add |
188 |
|
1185.16.159
by John Arbash Meinel
Updated the stores, all tests pass, and a store doesn't have to be 100% compressed |
189 |
# Most of the time, just adding the file will work
|
190 |
# if we find a time where it fails, (because the dir
|
|
191 |
# 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 |
192 |
self._add(names[0], f) |
193 |
||
194 |
def _add(self, relpath, f): |
|
195 |
"""Actually add the file to the given location.
|
|
196 |
This should be overridden by children.
|
|
197 |
"""
|
|
198 |
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 |
199 |
|
1442.1.24
by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore |
200 |
def _check_fileid(self, fileid): |
201 |
if not isinstance(fileid, basestring): |
|
202 |
raise TypeError('Fileids should be a string type: %s %r' % (type(fileid), fileid)) |
|
203 |
if '\\' in fileid or '/' in fileid: |
|
204 |
raise ValueError("invalid store id %r" % fileid) |
|
205 |
||
1185.16.157
by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first |
206 |
def _id_to_names(self, fileid, suffix): |
207 |
"""Return the names in the expected order"""
|
|
1442.1.47
by Robert Collins
test for has with suffixed files |
208 |
if suffix is not None: |
209 |
fn = self._relpath(fileid, [suffix]) |
|
210 |
else: |
|
211 |
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 |
212 |
|
1185.65.13
by Robert Collins
Merge from integration |
213 |
# 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 |
214 |
fn_gz = fn + '.gz' |
215 |
if self._compressed: |
|
216 |
return fn_gz, fn |
|
217 |
else: |
|
218 |
return fn, fn_gz |
|
219 |
||
220 |
def has_id(self, fileid, suffix=None): |
|
221 |
"""See Store.has_id."""
|
|
2294.1.10
by John Arbash Meinel
Switch all apis over to utf8 file ids. All tests pass |
222 |
fileid = osutils.safe_file_id(fileid) |
1651.1.5
by Martin Pool
Review cleanup of TransportStore.has_id |
223 |
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 |
224 |
|
225 |
def _get_name(self, fileid, suffix=None): |
|
226 |
"""A special check, which returns the name of an existing file.
|
|
227 |
|
|
228 |
This is similar in spirit to 'has_id', but it is designed
|
|
229 |
to return information about which file the store has.
|
|
230 |
"""
|
|
231 |
for name in self._id_to_names(fileid, suffix=suffix): |
|
232 |
if self._transport.has(name): |
|
233 |
return name |
|
234 |
return None |
|
1442.1.38
by Robert Collins
unify __contains__ for TransportStore classes |
235 |
|
1442.1.36
by Robert Collins
convert get() in TextStore and CompressedTextStore into a template method |
236 |
def _get(self, filename): |
237 |
"""Return an vanilla file stream for clients to read from.
|
|
238 |
||
239 |
This is the body of a template method on 'get', and should be
|
|
240 |
implemented by subclasses.
|
|
241 |
"""
|
|
242 |
raise NotImplementedError |
|
243 |
||
1442.1.50
by Robert Collins
test get with suffixes |
244 |
def get(self, fileid, suffix=None): |
245 |
"""See Store.get()."""
|
|
2294.1.10
by John Arbash Meinel
Switch all apis over to utf8 file ids. All tests pass |
246 |
fileid = osutils.safe_file_id(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 |
247 |
names = self._id_to_names(fileid, suffix) |
248 |
for name in names: |
|
249 |
try: |
|
250 |
return self._get(name) |
|
251 |
except errors.NoSuchFile: |
|
252 |
pass
|
|
253 |
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. |
254 |
|
1185.58.4
by John Arbash Meinel
Added permission checking to Branch, and propogated that change into the stores. |
255 |
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. |
256 |
dir_mode=None, file_mode=None, |
257 |
escaped=False): |
|
1651.1.7
by Martin Pool
Move small ImmutableMemoryStore class into test module, |
258 |
assert isinstance(a_transport, Transport) |
1092.2.24
by Robert Collins
merge from martins newformat branch - brings in transport abstraction |
259 |
super(TransportStore, self).__init__() |
1442.1.44
by Robert Collins
Many transport related tweaks: |
260 |
self._transport = a_transport |
1442.1.25
by Robert Collins
Test TransportStore._relpath for simple cases: pull up _prefixed attribute as a result. |
261 |
self._prefixed = prefixed |
1185.65.13
by Robert Collins
Merge from integration |
262 |
# 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 |
263 |
self._compressed = compressed |
1442.1.43
by Robert Collins
add registration of suffixes, in preparation for ensuring iteration is regular |
264 |
self._suffixes = set() |
1185.80.1
by John Arbash Meinel
Text store and weave store both allow escaping fileid paths. |
265 |
self._escaped = escaped |
1092.2.24
by Robert Collins
merge from martins newformat branch - brings in transport abstraction |
266 |
|
1185.58.6
by John Arbash Meinel
Stores don't have to have a dir_mode or file_mode set |
267 |
# It is okay for these to be None, it just means they
|
268 |
# will just use the filesystem defaults
|
|
269 |
self._dir_mode = dir_mode |
|
270 |
self._file_mode = file_mode |
|
1185.58.4
by John Arbash Meinel
Added permission checking to Branch, and propogated that change into the stores. |
271 |
|
1608.2.1
by Martin Pool
[merge] Storage filename escaping |
272 |
def _unescape(self, file_id): |
273 |
"""If filename escaping is enabled for this store, unescape and return the filename."""
|
|
274 |
if self._escaped: |
|
275 |
return urllib.unquote(file_id) |
|
276 |
else: |
|
277 |
return file_id |
|
278 |
||
1479
by Robert Collins
More quoting at the transport layer bugfixes. |
279 |
def _iter_files_recursive(self): |
280 |
"""Iterate through the files in the transport."""
|
|
281 |
for quoted_relpath in self._transport.iter_files_recursive(): |
|
1608.2.1
by Martin Pool
[merge] Storage filename escaping |
282 |
# transport iterator always returns quoted paths, regardless of
|
283 |
# escaping
|
|
1479
by Robert Collins
More quoting at the transport layer bugfixes. |
284 |
yield urllib.unquote(quoted_relpath) |
285 |
||
1442.1.51
by Robert Collins
teach iter about suffixes |
286 |
def __iter__(self): |
1479
by Robert Collins
More quoting at the transport layer bugfixes. |
287 |
for relpath in self._iter_files_recursive(): |
1442.1.51
by Robert Collins
teach iter about suffixes |
288 |
# worst case is one of each suffix.
|
289 |
name = os.path.basename(relpath) |
|
290 |
if name.endswith('.gz'): |
|
291 |
name = name[:-3] |
|
292 |
skip = False |
|
293 |
for count in range(len(self._suffixes)): |
|
294 |
for suffix in self._suffixes: |
|
295 |
if name.endswith('.' + suffix): |
|
296 |
skip = True |
|
297 |
if not skip: |
|
1608.2.1
by Martin Pool
[merge] Storage filename escaping |
298 |
yield self._unescape(name) |
1442.1.51
by Robert Collins
teach iter about suffixes |
299 |
|
1442.1.40
by Robert Collins
unify __len__() implementations for TransportStore classes |
300 |
def __len__(self): |
1442.1.50
by Robert Collins
test get with suffixes |
301 |
return len(list(self.__iter__())) |
1442.1.40
by Robert Collins
unify __len__() implementations for TransportStore classes |
302 |
|
1185.16.157
by John Arbash Meinel
Added ability for TextStore to handle both compressed and uncompressed, it just looks for one type first |
303 |
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 |
304 |
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 |
305 |
if suffixes: |
306 |
for suffix in suffixes: |
|
307 |
if not suffix in self._suffixes: |
|
308 |
raise ValueError("Unregistered suffix %r" % suffix) |
|
309 |
self._check_fileid(suffix) |
|
310 |
else: |
|
311 |
suffixes = [] |
|
1725.2.2
by Robert Collins
reduce file path escaping calls during commit. |
312 |
fileid = self._escape_file_id(fileid) |
1442.1.24
by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore |
313 |
if self._prefixed: |
1185.80.5
by John Arbash Meinel
Changing the escaping just a little bit. Now we can handle unicode characters. |
314 |
# hash_prefix adds the '/' separator
|
1725.2.2
by Robert Collins
reduce file path escaping calls during commit. |
315 |
prefix = self.hash_prefix(fileid, escaped=True) |
1442.1.24
by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore |
316 |
else: |
1608.2.1
by Martin Pool
[merge] Storage filename escaping |
317 |
prefix = '' |
318 |
path = prefix + fileid |
|
1185.80.5
by John Arbash Meinel
Changing the escaping just a little bit. Now we can handle unicode characters. |
319 |
full_path = u'.'.join([path] + suffixes) |
1685.1.45
by John Arbash Meinel
Moved url functions into bzrlib.urlutils |
320 |
return urlutils.escape(full_path) |
1442.1.24
by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore |
321 |
|
1608.2.1
by Martin Pool
[merge] Storage filename escaping |
322 |
def _escape_file_id(self, file_id): |
323 |
"""Turn a file id into a filesystem safe string.
|
|
324 |
||
325 |
This is similar to a plain urllib.quote, except
|
|
326 |
it uses specific safe characters, so that it doesn't
|
|
327 |
have to translate a lot of valid file ids.
|
|
328 |
"""
|
|
329 |
if not self._escaped: |
|
330 |
return file_id |
|
1608.2.12
by Martin Pool
Store-escaping must quote uppercase characters too, so that they're safely |
331 |
if isinstance(file_id, unicode): |
332 |
file_id = file_id.encode('utf-8') |
|
1608.2.1
by Martin Pool
[merge] Storage filename escaping |
333 |
# @ does not get escaped. This is because it is a valid
|
334 |
# filesystem character we use all the time, and it looks
|
|
335 |
# a lot better than seeing %40 all the time.
|
|
1608.2.12
by Martin Pool
Store-escaping must quote uppercase characters too, so that they're safely |
336 |
safe = "abcdefghijklmnopqrstuvwxyz0123456789-_@,." |
337 |
r = [((c in safe) and c or ('%%%02x' % ord(c))) |
|
338 |
for c in file_id] |
|
339 |
return ''.join(r) |
|
1608.2.1
by Martin Pool
[merge] Storage filename escaping |
340 |
|
1725.2.2
by Robert Collins
reduce file path escaping calls during commit. |
341 |
def hash_prefix(self, fileid, escaped=False): |
1608.2.1
by Martin Pool
[merge] Storage filename escaping |
342 |
# fileid should be unescaped
|
1725.2.2
by Robert Collins
reduce file path escaping calls during commit. |
343 |
if not escaped and self._escaped: |
1608.2.1
by Martin Pool
[merge] Storage filename escaping |
344 |
fileid = self._escape_file_id(fileid) |
345 |
return "%02x/" % (adler32(fileid) & 0xff) |
|
1442.1.24
by Robert Collins
Pull up _check_id and _relpath from Text and CompressedText stores into TransportStore |
346 |
|
1092.2.24
by Robert Collins
merge from martins newformat branch - brings in transport abstraction |
347 |
def __repr__(self): |
348 |
if self._transport is None: |
|
349 |
return "%s(None)" % (self.__class__.__name__) |
|
350 |
else: |
|
351 |
return "%s(%r)" % (self.__class__.__name__, self._transport.base) |
|
352 |
||
353 |
__str__ = __repr__ |
|
1185.10.1
by Aaron Bentley
Added --basis option to bzr branch |
354 |
|
1400.1.1
by Robert Collins
implement a basic test for the ui branch command from http servers |
355 |
def listable(self): |
356 |
"""Return True if this store is able to be listed."""
|
|
357 |
return self._transport.listable() |
|
358 |
||
1442.1.43
by Robert Collins
add registration of suffixes, in preparation for ensuring iteration is regular |
359 |
def register_suffix(self, suffix): |
360 |
"""Register a suffix as being expected in this store."""
|
|
361 |
self._check_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 |
362 |
if suffix == 'gz': |
363 |
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 |
364 |
self._suffixes.add(suffix) |
365 |
||
1442.1.37
by Robert Collins
pull up total_size into TransportStore |
366 |
def total_size(self): |
367 |
"""Return (count, bytes)
|
|
368 |
||
369 |
This is the (compressed) size stored on disk, not the size of
|
|
370 |
the content."""
|
|
371 |
total = 0 |
|
372 |
count = 0 |
|
1442.1.44
by Robert Collins
Many transport related tweaks: |
373 |
for relpath in self._transport.iter_files_recursive(): |
1442.1.37
by Robert Collins
pull up total_size into TransportStore |
374 |
count += 1 |
1442.1.44
by Robert Collins
Many transport related tweaks: |
375 |
total += self._transport.stat(relpath).st_size |
1442.1.37
by Robert Collins
pull up total_size into TransportStore |
376 |
|
377 |
return count, total |
|
378 |
||
1092.2.1
by Robert Collins
minor refactors to store, create an ImmutableMemoryStore for testing or other such operations |
379 |
|
1563.2.14
by Robert Collins
Prepare weave store to delegate copy details to the versioned file. |
380 |
@deprecated_function(zero_eight) |
1185.79.2
by John Arbash Meinel
Adding progress bars to copy_all and copy_multi, fixing ordering of repository.clone() to pull inventories after weaves. |
381 |
def copy_all(store_from, store_to, pb=None): |
1185.10.1
by Aaron Bentley
Added --basis option to bzr branch |
382 |
"""Copy all ids from one store to another."""
|
1563.2.14
by Robert Collins
Prepare weave store to delegate copy details to the versioned file. |
383 |
store_to.copy_all_ids(store_from, pb) |