153
154
supported_kinds = set(['file', 'directory', 'symlink'])
156
def write_inventory_to_string(self, inv):
157
"""Just call write_inventory with a StringIO and return the value"""
157
def write_inventory_to_lines(self, inv):
158
"""Return a list of lines with the encoded inventory."""
159
return self.write_inventory(inv, None)
161
def write_inventory_to_string(self, inv, working=False):
162
"""Just call write_inventory with a StringIO and return the value.
164
:param working: If True skip history data - text_sha1, text_size,
165
reference_revision, symlink_target.
158
167
sio = cStringIO.StringIO()
159
self.write_inventory(inv, sio)
168
self.write_inventory(inv, sio, working)
160
169
return sio.getvalue()
162
def write_inventory(self, inv, f):
171
def write_inventory(self, inv, f, working=False):
163
172
"""Write inventory to a file.
165
174
:param inv: the inventory to write.
166
:param f: the file to write.
175
:param f: the file to write. (May be None if the lines are the desired
177
:param working: If True skip history data - text_sha1, text_size,
178
reference_revision, symlink_target.
179
:return: The inventory as a list of lines.
168
181
_ensure_utf8_re()
174
187
root_path, root_ie = entries.next()
175
188
for path, ie in entries:
176
self._append_entry(append, ie)
189
if ie.parent_id != self.root_id:
190
parent_str = ' parent_id="'
191
parent_id = _encode_and_escape(ie.parent_id)
195
if ie.kind == 'file':
197
executable = ' executable="yes"'
201
append('<file%s file_id="%s name="%s%s%s revision="%s '
202
'text_sha1="%s" text_size="%d" />\n' % (
203
executable, _encode_and_escape(ie.file_id),
204
_encode_and_escape(ie.name), parent_str, parent_id,
205
_encode_and_escape(ie.revision), ie.text_sha1,
208
append('<file%s file_id="%s name="%s%s%s />\n' % (
209
executable, _encode_and_escape(ie.file_id),
210
_encode_and_escape(ie.name), parent_str, parent_id))
211
elif ie.kind == 'directory':
213
append('<directory file_id="%s name="%s%s%s revision="%s '
215
_encode_and_escape(ie.file_id),
216
_encode_and_escape(ie.name),
217
parent_str, parent_id,
218
_encode_and_escape(ie.revision)))
220
append('<directory file_id="%s name="%s%s%s />\n' % (
221
_encode_and_escape(ie.file_id),
222
_encode_and_escape(ie.name),
223
parent_str, parent_id))
224
elif ie.kind == 'symlink':
226
append('<symlink file_id="%s name="%s%s%s revision="%s '
227
'symlink_target="%s />\n' % (
228
_encode_and_escape(ie.file_id),
229
_encode_and_escape(ie.name),
230
parent_str, parent_id,
231
_encode_and_escape(ie.revision),
232
_encode_and_escape(ie.symlink_target)))
234
append('<symlink file_id="%s name="%s%s%s />\n' % (
235
_encode_and_escape(ie.file_id),
236
_encode_and_escape(ie.name),
237
parent_str, parent_id))
238
elif ie.kind == 'tree-reference':
239
if ie.kind not in self.supported_kinds:
240
raise errors.UnsupportedInventoryKind(ie.kind)
242
append('<tree-reference file_id="%s name="%s%s%s '
243
'revision="%s reference_revision="%s />\n' % (
244
_encode_and_escape(ie.file_id),
245
_encode_and_escape(ie.name),
246
parent_str, parent_id,
247
_encode_and_escape(ie.revision),
248
_encode_and_escape(ie.reference_revision)))
250
append('<tree-reference file_id="%s name="%s%s%s />\n' % (
251
_encode_and_escape(ie.file_id),
252
_encode_and_escape(ie.name),
253
parent_str, parent_id))
255
raise errors.UnsupportedInventoryKind(ie.kind)
177
256
append('</inventory>\n')
179
259
# Just to keep the cache from growing without bounds
180
260
# but we may actually not want to do clear the cache
183
264
def _append_inventory_root(self, append, inv):
184
265
"""Append the inventory root to output."""
186
266
if inv.root.file_id not in (None, ROOT_ID):
188
append(_encode_and_escape(inv.root.file_id))
189
append(' format="5"')
267
fileid1 = ' file_id="'
268
fileid2 = _encode_and_escape(inv.root.file_id)
190
272
if inv.revision_id is not None:
191
append(' revision_id="')
192
append(_encode_and_escape(inv.revision_id))
273
revid1 = ' revision_id="'
274
revid2 = _encode_and_escape(inv.revision_id)
278
append('<inventory%s%s format="5"%s%s>\n' % (
279
fileid1, fileid2, revid1, revid2))
195
def _append_entry(self, append, ie):
196
"""Convert InventoryEntry to XML element and append to output."""
197
# TODO: should just be a plain assertion
198
if ie.kind not in self.supported_kinds:
199
raise errors.UnsupportedInventoryKind(ie.kind)
204
append(' executable="yes"')
206
append(_encode_and_escape(ie.file_id))
208
append(_encode_and_escape(ie.name))
209
if self._parent_condition(ie):
210
assert isinstance(ie.parent_id, basestring)
211
append(' parent_id="')
212
append(_encode_and_escape(ie.parent_id))
213
if ie.revision is not None:
214
append(' revision="')
215
append(_encode_and_escape(ie.revision))
216
if ie.symlink_target is not None:
217
append(' symlink_target="')
218
append(_encode_and_escape(ie.symlink_target))
219
if ie.text_sha1 is not None:
220
append(' text_sha1="')
223
if ie.text_size is not None:
224
append(' text_size="%d"' % ie.text_size)
225
if getattr(ie, 'reference_revision', None) is not None:
226
append(' reference_revision="')
227
append(_encode_and_escape(ie.reference_revision))
231
def _parent_condition(self, ie):
232
return ie.parent_id != ROOT_ID
234
281
def _pack_revision(self, rev):
235
282
"""Revision object -> xml tree"""
236
283
# For the XML format, we need to write them as Unicode rather than as