/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
#
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
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
#
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
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
#
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
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
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
17
"""Serializer factory for reading and writing bundles.
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
18
"""
19
1185.82.96 by Aaron Bentley
Got first binary test passing
20
import base64
21
from StringIO import StringIO
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
22
import re
23
24
import bzrlib.errors as errors
1185.82.96 by Aaron Bentley
Got first binary test passing
25
from bzrlib.diff import internal_diff
1185.82.58 by Aaron Bentley
Handle empty branches properly
26
from bzrlib.revision import NULL_REVISION
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
27
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
28
# New bundles should try to use this header format
29
BUNDLE_HEADER = '# Bazaar revision bundle v'
1907.2.2 by Hermann Kraus
Detect wrong eol markers.
30
BUNDLE_HEADER_RE = re.compile(
31
    r'^# Bazaar revision bundle v(?P<version>\d+[\w.]*)(?P<lineending>\r?)\n$')
32
CHANGESET_OLD_HEADER_RE = re.compile(
33
    r'^# Bazaar-NG changeset v(?P<version>\d+[\w.]*)(?P<lineending>\r?)\n$')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
34
35
1793.3.16 by John Arbash Meinel
Add tests to ensure that we gracefully handle opening and trailing non-bundle text.
36
_serializers = {}
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
37
38
39
def _get_filename(f):
1963.2.4 by Robey Pointer
remove usage of hasattr
40
    return getattr(f, 'name', '<unknown>')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
41
42
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
43
def read_bundle(f):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
44
    """Read in a bundle from a filelike object.
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
45
46
    :param f: A file-like object
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
47
    :return: A list of Bundle objects
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
48
    """
49
    version = None
50
    for line in f:
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
51
        m = BUNDLE_HEADER_RE.match(line)
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
52
        if m:
1907.2.2 by Hermann Kraus
Detect wrong eol markers.
53
            if m.group('lineending') != '':
54
                raise errors.UnsupportedEOLMarker()
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
55
            version = m.group('version')
56
            break
1793.2.7 by Aaron Bentley
Fix reporting of malformed, (especially, crlf) bundles
57
        elif line.startswith(BUNDLE_HEADER):
1907.2.1 by Hermann Kraus
Convert bundle errors from Exception to BzrNewError.
58
            raise errors.MalformedHeader(
59
                'Extra characters after version number')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
60
        m = CHANGESET_OLD_HEADER_RE.match(line)
61
        if m:
62
            version = m.group('version')
1907.2.1 by Hermann Kraus
Convert bundle errors from Exception to BzrNewError.
63
            raise errors.BundleNotSupported(version, 
64
                'old format bundles not supported')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
65
66
    if version is None:
1793.2.2 by Aaron Bentley
Move BundleReader into v07 serializer
67
        raise errors.NotABundle('Did not find an opening header')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
68
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
69
    # Now we have a version, to figure out how to read the bundle 
1963.2.1 by Robey Pointer
remove usage of has_key()
70
    if version not in _serializers:
1907.2.1 by Hermann Kraus
Convert bundle errors from Exception to BzrNewError.
71
        raise errors.BundleNotSupported(version, 
72
            'version not listed in known versions')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
73
74
    serializer = _serializers[version](version)
75
76
    return serializer.read(f)
77
78
1185.82.74 by Aaron Bentley
Allow custom base for any revision
79
def write(source, revision_ids, f, version=None, forced_bases={}):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
80
    """Serialize a list of bundles to a filelike object.
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
81
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
82
    :param source: A source for revision information
83
    :param revision_ids: The list of revision ids to serialize
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
84
    :param f: The file to output to
85
    :param version: [optional] target serialization version
86
    """
87
1963.2.1 by Robey Pointer
remove usage of has_key()
88
    if version not in _serializers:
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
89
        raise errors.BundleNotSupported(version, 'unknown bundle format')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
90
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
91
    serializer = _serializers[version](version)
1927.1.1 by John Arbash Meinel
Lock the repository more often
92
    source.lock_read()
93
    try:
94
        return serializer.write(source, revision_ids, forced_bases, f)
95
    finally:
96
        source.unlock()
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
97
98
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
99
def write_bundle(repository, revision_id, base_revision_id, out, format=None):
1185.82.53 by Aaron Bentley
Factored out write_changeset to select revisions
100
    """"""
1927.1.1 by John Arbash Meinel
Lock the repository more often
101
    repository.lock_read()
102
    try:
1910.2.64 by Aaron Bentley
Changes from review
103
        return _write_bundle(repository, revision_id, base_revision_id, out,
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
104
                             format)
1927.1.1 by John Arbash Meinel
Lock the repository more often
105
    finally:
106
        repository.unlock()
107
108
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
109
def _write_bundle(repository, revision_id, base_revision_id, out, format):
1910.7.17 by Andrew Bennetts
Various cosmetic changes.
110
    """Write a bundle of revisions.
111
112
    :param repository: Repository containing revisions to serialize.
113
    :param revision_id: Head revision_id of the bundle.
114
    :param base_revision_id: Revision assumed to be present in repositories
115
         applying the bundle.
116
    :param out: Output file.
117
    """
1185.82.58 by Aaron Bentley
Handle empty branches properly
118
    if base_revision_id is NULL_REVISION:
119
        base_revision_id = None
1185.82.53 by Aaron Bentley
Factored out write_changeset to select revisions
120
    base_ancestry = set(repository.get_ancestry(base_revision_id))
121
    revision_ids = [r for r in repository.get_ancestry(revision_id) if r
122
                    not in base_ancestry]
123
    revision_ids = list(reversed(revision_ids))
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
124
    write(repository, revision_ids, out, format,
1185.82.74 by Aaron Bentley
Allow custom base for any revision
125
          forced_bases = {revision_id:base_revision_id})
1185.82.53 by Aaron Bentley
Factored out write_changeset to select revisions
126
    return revision_ids
127
128
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
129
def format_highres_date(t, offset=0):
130
    """Format a date, such that it includes higher precision in the
131
    seconds field.
132
133
    :param t:   The local time in fractional seconds since the epoch
134
    :type t: float
135
    :param offset:  The timezone offset in integer seconds
136
    :type offset: int
137
138
    Example: format_highres_date(time.time(), -time.timezone)
139
    this will return a date stamp for right now,
140
    formatted for the local timezone.
141
142
    >>> from bzrlib.osutils import format_date
143
    >>> format_date(1120153132.350850105, 0)
144
    'Thu 2005-06-30 17:38:52 +0000'
145
    >>> format_highres_date(1120153132.350850105, 0)
146
    'Thu 2005-06-30 17:38:52.350850105 +0000'
147
    >>> format_date(1120153132.350850105, -5*3600)
148
    'Thu 2005-06-30 12:38:52 -0500'
149
    >>> format_highres_date(1120153132.350850105, -5*3600)
150
    'Thu 2005-06-30 12:38:52.350850105 -0500'
151
    >>> format_highres_date(1120153132.350850105, 7200)
152
    'Thu 2005-06-30 19:38:52.350850105 +0200'
1793.3.7 by John Arbash Meinel
Properly handle non-hour timezone offsets.
153
    >>> format_highres_date(1152428738.867522, 19800)
154
    'Sun 2006-07-09 12:35:38.867522001 +0530'
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
155
    """
156
    import time
157
    assert isinstance(t, float)
158
    
159
    # This has to be formatted for "original" date, so that the
160
    # revision XML entry will be reproduced faithfully.
1963.2.6 by Robey Pointer
pychecker is on crack; go back to using 'is None'.
161
    if offset is None:
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
162
        offset = 0
163
    tt = time.gmtime(t + offset)
164
165
    return (time.strftime("%a %Y-%m-%d %H:%M:%S", tt)
166
            + ('%.9f' % (t - int(t)))[1:] # Get the high-res seconds, but ignore the 0
167
            + ' %+03d%02d' % (offset / 3600, (offset / 60) % 60))
168
169
170
def unpack_highres_date(date):
171
    """This takes the high-resolution date stamp, and
172
    converts it back into the tuple (timestamp, timezone)
173
    Where timestamp is in real UTC since epoch seconds, and timezone is an integer
174
    number of seconds offset.
175
176
    :param date: A date formated by format_highres_date
177
    :type date: string
178
179
    >>> import time, random
180
    >>> unpack_highres_date('Thu 2005-06-30 12:38:52.350850105 -0500')
181
    (1120153132.3508501, -18000)
182
    >>> unpack_highres_date('Thu 2005-06-30 17:38:52.350850105 +0000')
183
    (1120153132.3508501, 0)
184
    >>> unpack_highres_date('Thu 2005-06-30 19:38:52.350850105 +0200')
185
    (1120153132.3508501, 7200)
1793.3.7 by John Arbash Meinel
Properly handle non-hour timezone offsets.
186
    >>> unpack_highres_date('Sun 2006-07-09 12:35:38.867522001 +0530')
187
    (1152428738.867522, 19800)
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
188
    >>> from bzrlib.osutils import local_time_offset
189
    >>> t = time.time()
190
    >>> o = local_time_offset()
191
    >>> t2, o2 = unpack_highres_date(format_highres_date(t, o))
192
    >>> t == t2
193
    True
194
    >>> o == o2
195
    True
196
    >>> t -= 24*3600*365*2 # Start 2 years ago
197
    >>> o = -12*3600
198
    >>> for count in xrange(500):
199
    ...   t += random.random()*24*3600*30
200
    ...   o = ((o/3600 + 13) % 25 - 12)*3600 # Add 1 wrap around from [-12, 12]
201
    ...   date = format_highres_date(t, o)
202
    ...   t2, o2 = unpack_highres_date(date)
203
    ...   if t != t2 or o != o2:
204
    ...      print 'Failed on date %r, %s,%s diff:%s' % (date, t, o, t2-t)
205
    ...      break
206
207
    """
208
    import time, calendar
209
    # Up until the first period is a datestamp that is generated
210
    # as normal from time.strftime, so use time.strptime to
211
    # parse it
212
    dot_loc = date.find('.')
213
    if dot_loc == -1:
1907.2.1 by Hermann Kraus
Convert bundle errors from Exception to BzrNewError.
214
        raise ValueError(
215
            'Date string does not contain high-precision seconds: %r' % date)
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
216
    base_time = time.strptime(date[:dot_loc], "%a %Y-%m-%d %H:%M:%S")
217
    fract_seconds, offset = date[dot_loc:].split()
218
    fract_seconds = float(fract_seconds)
1793.3.11 by John Arbash Meinel
Cleanup unpack_highres_date from Aaron's suggestions.
219
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
220
    offset = int(offset)
1793.3.11 by John Arbash Meinel
Cleanup unpack_highres_date from Aaron's suggestions.
221
222
    hours = int(offset / 100)
223
    minutes = (offset % 100)
224
    seconds_offset = (hours * 3600) + (minutes * 60)
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
225
    
226
    # time.mktime returns localtime, but calendar.timegm returns UTC time
227
    timestamp = calendar.timegm(base_time)
1793.3.11 by John Arbash Meinel
Cleanup unpack_highres_date from Aaron's suggestions.
228
    timestamp -= seconds_offset
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
229
    # Add back in the fractional seconds
230
    timestamp += fract_seconds
1793.3.11 by John Arbash Meinel
Cleanup unpack_highres_date from Aaron's suggestions.
231
    return (timestamp, seconds_offset)
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
232
233
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
234
class BundleSerializer(object):
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
235
    """The base class for Serializers.
236
237
    Common functionality should be included here.
238
    """
239
    def __init__(self, version):
240
        self.version = version
241
242
    def read(self, f):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
243
        """Read the rest of the bundles from the supplied file.
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
244
245
        :param f: The file to read from
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
246
        :return: A list of bundle trees
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
247
        """
248
        raise NotImplementedError
249
1185.82.74 by Aaron Bentley
Allow custom base for any revision
250
    def write(self, source, revision_ids, forced_bases, f):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
251
        """Write the bundle to the supplied file.
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
252
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
253
        :param source: A source for revision information
254
        :param revision_ids: The list of revision ids to serialize
1185.82.74 by Aaron Bentley
Allow custom base for any revision
255
        :param forced_bases: A dict of revision -> base that overrides default
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
256
        :param f: The file to output to
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
257
        """
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
258
        raise NotImplementedError
259
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
260
261
def register(version, klass, overwrite=False):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
262
    """Register a BundleSerializer version.
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
263
264
    :param version: The version associated with this format
265
    :param klass: The class to instantiate, which must take a version argument
266
    """
267
    global _serializers
268
    if overwrite:
269
        _serializers[version] = klass
270
        return
271
1963.2.1 by Robey Pointer
remove usage of has_key()
272
    if version not in _serializers:
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
273
        _serializers[version] = klass
274
275
276
def register_lazy(version, module, classname, overwrite=False):
1185.82.130 by Aaron Bentley
Rename changesets to revision bundles
277
    """Register lazy-loaded bundle serializer.
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
278
279
    :param version: The version associated with this reader
280
    :param module: String indicating what module should be loaded
281
    :param classname: Name of the class that will be instantiated
282
    :param overwrite: Should this version override a default
283
    """
284
    def _loader(version):
285
        mod = __import__(module, globals(), locals(), [classname])
286
        klass = getattr(mod, classname)
287
        return klass(version)
1185.82.4 by John Arbash Meinel
Created output format, slightly simplified code
288
    register(version, _loader, overwrite=overwrite)
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
289
290
1185.82.96 by Aaron Bentley
Got first binary test passing
291
def binary_diff(old_filename, old_lines, new_filename, new_lines, to_file):
292
    temp = StringIO()
293
    internal_diff(old_filename, old_lines, new_filename, new_lines, temp,
294
                  allow_binary=True)
295
    temp.seek(0)
296
    base64.encode(temp, to_file)
297
    to_file.write('\n')
298
1551.7.3 by Aaron Bentley
Fix strict testaments, as_sha1
299
register_lazy('0.8', 'bzrlib.bundle.serializer.v08', 'BundleSerializerV08')
1910.2.50 by Aaron Bentley
start work on format 0.9 serializer
300
register_lazy('0.9', 'bzrlib.bundle.serializer.v09', 'BundleSerializerV09')
1551.7.3 by Aaron Bentley
Fix strict testaments, as_sha1
301
register_lazy(None, 'bzrlib.bundle.serializer.v08', 'BundleSerializerV08')
1185.82.3 by John Arbash Meinel
Working on creating a factor for serializing changesets.
302