~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/testament.py

  • Committer: Robert Collins
  • Date: 2006-02-28 04:31:50 UTC
  • mto: This revision was merged to the branch mainline in revision 1583.
  • Revision ID: robertc@robertcollins.net-20060228043150-fdb9c7f7231b271b
Bugfix aliases to be backwards compatible with plugins providing command.run_argv.

Show diffs side-by-side

added added

removed removed

Lines of Context:
70
70
# revisions can be serialized.
71
71
 
72
72
from copy import copy
 
73
from cStringIO import StringIO
 
74
import string
73
75
from sha import sha
74
76
 
75
77
from bzrlib.osutils import contains_whitespace, contains_linebreaks
76
78
 
77
 
 
78
79
class Testament(object):
79
80
    """Reduced summary of a revision.
80
81
 
86
87
      - compared to a revision
87
88
    """
88
89
 
89
 
    long_header = 'bazaar-ng testament version 1\n'
90
 
    short_header = 'bazaar-ng testament short form 1\n'
91
 
 
92
90
    @classmethod
93
91
    def from_revision(cls, repository, revision_id):
94
92
        """Produce a new testament from a historical revision"""
117
115
        """
118
116
        r = []
119
117
        a = r.append
120
 
        a(self.long_header)
 
118
        a('bazaar-ng testament version 1\n')
121
119
        a('revision-id: %s\n' % self.revision_id)
122
120
        a('committer: %s\n' % self.committer)
123
121
        a('timestamp: %d\n' % self.timestamp)
131
129
        for l in self.message.splitlines():
132
130
            a('  %s\n' % l)
133
131
        a('inventory:\n')
134
 
        entries = self.inventory.iter_entries()
135
 
        entries.next()
136
 
        for path, ie in entries:
 
132
        for path, ie in self.inventory.iter_entries():
137
133
            a(self._entry_to_line(path, ie))
138
134
        r.extend(self._revprops_to_lines())
139
135
        if __debug__:
144
140
 
145
141
    def _escape_path(self, path):
146
142
        assert not contains_linebreaks(path)
147
 
        return unicode(path.replace('\\', '/').replace(' ', '\ '))
 
143
        return unicode(path.replace('\\', '/').replace(' ', '\ ')).encode('utf-8')
148
144
 
149
145
    def _entry_to_line(self, path, ie):
150
146
        """Turn an inventory entry into a testament line"""
 
147
        l = '  ' + str(ie.kind)
 
148
        l += ' ' + self._escape_path(path)
151
149
        assert not contains_whitespace(ie.file_id)
152
 
 
153
 
        content = ''
154
 
        content_spacer=''
 
150
        l += ' ' + unicode(ie.file_id).encode('utf-8')
155
151
        if ie.kind == 'file':
156
152
            # TODO: avoid switching on kind
157
153
            assert ie.text_sha1
158
 
            content = ie.text_sha1
159
 
            content_spacer = ' '
 
154
            l += ' ' + ie.text_sha1
160
155
        elif ie.kind == 'symlink':
161
156
            assert ie.symlink_target
162
 
            content = self._escape_path(ie.symlink_target)
163
 
            content_spacer = ' '
164
 
 
165
 
        l = u'  %s %s %s%s%s\n' % (ie.kind, self._escape_path(path),
166
 
                                   unicode(ie.file_id),
167
 
                                   content_spacer, content)
 
157
            l += ' ' + self._escape_path(ie.symlink_target)
 
158
        l += '\n'
168
159
        return l
169
160
 
170
161
    def as_text(self):
172
163
 
173
164
    def as_short_text(self):
174
165
        """Return short digest-based testament."""
175
 
        return (self.short_header + 
 
166
        s = sha()
 
167
        map(s.update, self.as_text_lines())
 
168
        return ('bazaar-ng testament short form 1\n'
176
169
                'revision-id: %s\n'
177
170
                'sha1: %s\n'
178
 
                % (self.revision_id, self.as_sha1()))
 
171
                % (self.revision_id, s.hexdigest()))
179
172
 
180
173
    def _revprops_to_lines(self):
181
174
        """Pack up revision properties."""
187
180
            assert not contains_whitespace(name)
188
181
            r.append('  %s:\n' % name)
189
182
            for line in value.splitlines():
190
 
                r.append(u'    %s\n' % line)
 
183
                if not isinstance(line, str):
 
184
                    line = line.encode('utf-8')
 
185
                r.append('    %s\n' % line)
191
186
        return r
192
 
 
193
 
    def as_sha1(self):
194
 
        s = sha()
195
 
        map(s.update, self.as_text_lines())
196
 
        return s.hexdigest()
197
 
 
198
 
 
199
 
class StrictTestament(Testament):
200
 
    """This testament format is for use as a checksum in changesets"""
201
 
 
202
 
    long_header = 'bazaar-ng testament version 2.1\n'
203
 
    short_header = 'bazaar-ng testament short form 2.1\n'
204
 
    def _entry_to_line(self, path, ie):
205
 
        l = Testament._entry_to_line(self, path, ie)[:-1]
206
 
        l += ' ' + ie.revision
207
 
        l += {True: ' yes\n', False: ' no\n'}[ie.executable]
208
 
        return l