~bzr/ubuntu/lucid/bzr/beta-ppa

« back to all changes in this revision

Viewing changes to bzrlib/bundle/serializer/__init__.py

  • Committer: Martin Pool
  • Date: 2010-07-02 07:29:40 UTC
  • mfrom: (129.1.7 packaging-karmic)
  • Revision ID: mbp@sourcefrog.net-20100702072940-hpzq5elg8wjve8rh
* PPA rebuild.
* PPA rebuild for Karmic.
* PPA rebuild for Jaunty.
* PPA rebuild for Hardy.
* From postinst, actually remove the example bash completion scripts.
  (LP: #249452)
* New upstream release.
* New upstream release.
* New upstream release.
* Revert change to Build-depends: Dapper does not have python-central.
  Should be python-support..
* Target ppa..
* Target ppa..
* Target ppa..
* Target ppa..
* New upstream release.
* Switch to dpkg-source 3.0 (quilt) format.
* Bump standards version to 3.8.4.
* Remove embedded copy of python-configobj. Closes: #555336
* Remove embedded copy of python-elementtree. Closes: #555343
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* Change section from 'Devel' to 'Vcs'..
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* debian/control: Fix obsolete-relation-form-in-source
  lintian warning. 
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Split out docs into bzr-doc package.
* New upstream release.
* Added John Francesco Ferlito to Uploaders.
* Fix install path to quick-reference guide
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to doc paths changing
* New upstream release.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to doc paths changing
* New upstream release.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to doc paths changing
* New upstream release.
* Fix FTBFS due to path changes, again, again.
* Fix FTBFS due to path changes, again.
* Fix FTBFS due to path changes.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Bump standards version to 3.8.3.
* Remove unused patch system.
* New upstream release.
* New upstream release.
* New upstream release.
* Fix copy and paste tab error in .install file
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
 + Fixes compatibility with Python 2.4. Closes: #537708
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream version.
* Bump standards version to 3.8.2.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Add python-pyrex to build-deps to ensure C extensions are always build.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Split documentation into bzr-doc package. ((LP: #385074)
* Multiple packaging changes to make us more linitan clean.
* New upstream release.
* Split documentation into bzr-doc package. ((LP: #385074)
* Multiple packaging changes to make us more linitan clean.
* New upstream release.
* Split documentation into bzr-doc package. ((LP: #385074)
* Multiple packaging changes to make us more linitan clean.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Fix API compatibility version. (Closes: #526233)
* New upstream release.
  + Fixes default format for upgrade command. (Closes: #464688)
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Add missing dependency on zlib development library. (Closes:
  #523595)
* Add zlib build-depends.
* Add zlib build-depends.
* Add zlib build-depends.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Move to section vcs.
* Bump standards version to 3.8.1.
* New upstream release.
* Remove temporary patch for missing .c files from distribution
* New upstream release.
* Remove temporary patch for missing .c files from distribution
* New upstream release.
* Remove temporary patch for missing .c files from distribution
* Add temporary patch for missing .c files from distribution
* Add temporary patch for missing .c files from distribution
* Add temporary patch for missing .c files from distribution
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Recommend ca-certificates. (Closes: #452024)
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Update watch file. bazaar now uses launchpad to host its sources.
* Remove patch for inventory root revision copy, applied upstream.
* New upstream release.
* New upstream release.
* New upstream release
* Force removal of files installed in error to /etc/bash_completion.d/
  (LP: #249452)
* New upstream release.
* New upstream release
* New upstream release.
* Bump standards version.
* Include patch for inventory root revision copy, required for bzr-svn.
* New upstream release.
* Remove unused lintian overrides.
* Correct the package version not to be native.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* New upstream release.
* Final 1.5 release.
* New upstream release.
* New upstream release.
* New upstream release.
* Add myself as a co-maintainer.
* Add a Dm-Upload-Allowed: yes header.
* New upstream bugfix release.
* New upstream release.
* Final 1.3 release.
* New upstream release.
* First release candidate of the upcoming 1.3 release.
* Rebuild to fix the problem caused by a build with a broken python-central.
* New upstream release.
* Rebuild for dapper PPA.
* Apply Lamont's patches to fix build-dependencies on dapper.
  (See: https://bugs.launchpad.net/bzr/+bug/189915)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006 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
"""Serializer factory for reading and writing bundles.
 
18
"""
 
19
 
 
20
import base64
 
21
from StringIO import StringIO
 
22
import re
 
23
 
 
24
import bzrlib.errors as errors
 
25
from bzrlib.diff import internal_diff
 
26
from bzrlib.revision import NULL_REVISION
 
27
# For backwards-compatibility
 
28
from bzrlib.timestamp import unpack_highres_date, format_highres_date
 
29
 
 
30
 
 
31
# New bundles should try to use this header format
 
32
BUNDLE_HEADER = '# Bazaar revision bundle v'
 
33
BUNDLE_HEADER_RE = re.compile(
 
34
    r'^# Bazaar revision bundle v(?P<version>\d+[\w.]*)(?P<lineending>\r?)\n$')
 
35
CHANGESET_OLD_HEADER_RE = re.compile(
 
36
    r'^# Bazaar-NG changeset v(?P<version>\d+[\w.]*)(?P<lineending>\r?)\n$')
 
37
 
 
38
 
 
39
_serializers = {}
 
40
 
 
41
v4_string = '4'
 
42
 
 
43
def _get_bundle_header(version):
 
44
    return '%s%s\n' % (BUNDLE_HEADER, version)
 
45
 
 
46
def _get_filename(f):
 
47
    return getattr(f, 'name', '<unknown>')
 
48
 
 
49
 
 
50
def read_bundle(f):
 
51
    """Read in a bundle from a filelike object.
 
52
 
 
53
    :param f: A file-like object
 
54
    :return: A list of Bundle objects
 
55
    """
 
56
    version = None
 
57
    for line in f:
 
58
        m = BUNDLE_HEADER_RE.match(line)
 
59
        if m:
 
60
            if m.group('lineending') != '':
 
61
                raise errors.UnsupportedEOLMarker()
 
62
            version = m.group('version')
 
63
            break
 
64
        elif line.startswith(BUNDLE_HEADER):
 
65
            raise errors.MalformedHeader(
 
66
                'Extra characters after version number')
 
67
        m = CHANGESET_OLD_HEADER_RE.match(line)
 
68
        if m:
 
69
            version = m.group('version')
 
70
            raise errors.BundleNotSupported(version,
 
71
                'old format bundles not supported')
 
72
 
 
73
    if version is None:
 
74
        raise errors.NotABundle('Did not find an opening header')
 
75
 
 
76
    # Now we have a version, to figure out how to read the bundle
 
77
    if version not in _serializers:
 
78
        raise errors.BundleNotSupported(version,
 
79
            'version not listed in known versions')
 
80
 
 
81
    serializer = _serializers[version](version)
 
82
 
 
83
    return serializer.read(f)
 
84
 
 
85
 
 
86
def get_serializer(version):
 
87
    try:
 
88
        return _serializers[version](version)
 
89
    except KeyError:
 
90
        raise errors.BundleNotSupported(version, 'unknown bundle format')
 
91
 
 
92
 
 
93
def write(source, revision_ids, f, version=None, forced_bases={}):
 
94
    """Serialize a list of bundles to a filelike object.
 
95
 
 
96
    :param source: A source for revision information
 
97
    :param revision_ids: The list of revision ids to serialize
 
98
    :param f: The file to output to
 
99
    :param version: [optional] target serialization version
 
100
    """
 
101
 
 
102
    source.lock_read()
 
103
    try:
 
104
        return get_serializer(version).write(source, revision_ids,
 
105
                                             forced_bases, f)
 
106
    finally:
 
107
        source.unlock()
 
108
 
 
109
 
 
110
def write_bundle(repository, revision_id, base_revision_id, out, format=None):
 
111
    """Write a bundle of revisions.
 
112
 
 
113
    :param repository: Repository containing revisions to serialize.
 
114
    :param revision_id: Head revision_id of the bundle.
 
115
    :param base_revision_id: Revision assumed to be present in repositories
 
116
         applying the bundle.
 
117
    :param out: Output file.
 
118
    """
 
119
    repository.lock_read()
 
120
    try:
 
121
        return get_serializer(format).write_bundle(repository, revision_id,
 
122
                                                   base_revision_id, out)
 
123
    finally:
 
124
        repository.unlock()
 
125
 
 
126
 
 
127
class BundleSerializer(object):
 
128
    """The base class for Serializers.
 
129
 
 
130
    Common functionality should be included here.
 
131
    """
 
132
    def __init__(self, version):
 
133
        self.version = version
 
134
 
 
135
    def read(self, f):
 
136
        """Read the rest of the bundles from the supplied file.
 
137
 
 
138
        :param f: The file to read from
 
139
        :return: A list of bundle trees
 
140
        """
 
141
        raise NotImplementedError
 
142
 
 
143
    def write_bundle(self, repository, target, base, fileobj):
 
144
        """Write the bundle to the supplied file.
 
145
 
 
146
        :param repository: The repository to retrieve revision data from
 
147
        :param target: The revision to provide data for
 
148
        :param base: The most recent of ancestor of the revision that does not
 
149
            need to be included in the bundle
 
150
        :param fileobj: The file to output to
 
151
        """
 
152
        raise NotImplementedError
 
153
 
 
154
    def write(self, source, revision_ids, forced_bases, f):
 
155
        """Write the bundle to the supplied file.
 
156
 
 
157
        DEPRECATED: see write_bundle
 
158
        :param source: A source for revision information
 
159
        :param revision_ids: The list of revision ids to serialize
 
160
        :param forced_bases: A dict of revision -> base that overrides default
 
161
        :param f: The file to output to
 
162
        """
 
163
        raise NotImplementedError
 
164
 
 
165
    def _write_bundle(self, repository, revision_id, base_revision_id, out):
 
166
        """Helper function for translating write_bundle to write"""
 
167
        forced_bases = {revision_id:base_revision_id}
 
168
        if base_revision_id is NULL_REVISION:
 
169
            base_revision_id = None
 
170
        revision_ids = set(repository.get_ancestry(revision_id,
 
171
                           topo_sorted=False))
 
172
        revision_ids.difference_update(repository.get_ancestry(
 
173
            base_revision_id, topo_sorted=False))
 
174
        revision_ids = list(repository.get_graph().iter_topo_order(
 
175
            revision_ids))
 
176
        revision_ids.reverse()
 
177
        self.write(repository, revision_ids, forced_bases, out)
 
178
        return revision_ids
 
179
 
 
180
 
 
181
def register(version, klass, overwrite=False):
 
182
    """Register a BundleSerializer version.
 
183
 
 
184
    :param version: The version associated with this format
 
185
    :param klass: The class to instantiate, which must take a version argument
 
186
    """
 
187
    global _serializers
 
188
    if overwrite:
 
189
        _serializers[version] = klass
 
190
        return
 
191
 
 
192
    if version not in _serializers:
 
193
        _serializers[version] = klass
 
194
 
 
195
 
 
196
def register_lazy(version, module, classname, overwrite=False):
 
197
    """Register lazy-loaded bundle serializer.
 
198
 
 
199
    :param version: The version associated with this reader
 
200
    :param module: String indicating what module should be loaded
 
201
    :param classname: Name of the class that will be instantiated
 
202
    :param overwrite: Should this version override a default
 
203
    """
 
204
    def _loader(version):
 
205
        mod = __import__(module, globals(), locals(), [classname])
 
206
        klass = getattr(mod, classname)
 
207
        return klass(version)
 
208
    register(version, _loader, overwrite=overwrite)
 
209
 
 
210
 
 
211
def binary_diff(old_filename, old_lines, new_filename, new_lines, to_file):
 
212
    temp = StringIO()
 
213
    internal_diff(old_filename, old_lines, new_filename, new_lines, temp,
 
214
                  allow_binary=True)
 
215
    temp.seek(0)
 
216
    base64.encode(temp, to_file)
 
217
    to_file.write('\n')
 
218
 
 
219
register_lazy('0.8', 'bzrlib.bundle.serializer.v08', 'BundleSerializerV08')
 
220
register_lazy('0.9', 'bzrlib.bundle.serializer.v09', 'BundleSerializerV09')
 
221
register_lazy(v4_string, 'bzrlib.bundle.serializer.v4',
 
222
              'BundleSerializerV4')
 
223
register_lazy(None, 'bzrlib.bundle.serializer.v4', 'BundleSerializerV4')
 
224