136
138
Matcher.__init__(self)
137
139
self.entries = entries
139
def get_tree_layout(self, tree):
141
def get_tree_layout(self, tree, include_file_ids):
140
142
"""Get the (path, file_id) pairs for the current tree."""
141
143
with tree.lock_read():
142
144
for path, ie in tree.iter_entries_by_dir():
143
if ie.parent_id is None:
144
yield (u"", ie.file_id)
146
path += ie.kind_character()
148
yield (path, ie.file_id)
146
yield (path+ie.kind_character(), ie.file_id)
149
153
def _strip_unreferenced_directories(entries):
172
176
return 'HasLayout(%r)' % self.entries
174
178
def match(self, tree):
175
actual = list(self.get_tree_layout(tree))
176
if self.entries and isinstance(self.entries[0], (str, text_type)):
177
actual = [path for (path, fileid) in actual]
179
include_file_ids = self.entries and not isinstance(
180
self.entries[0], str)
181
actual = list(self.get_tree_layout(
182
tree, include_file_ids=include_file_ids))
178
183
if not tree.has_versioned_directories():
179
184
entries = list(self._strip_unreferenced_directories(self.entries))
182
187
return Equals(entries).match(actual)
190
class HasPathRelations(Matcher):
191
"""Matcher verifies that paths have a relation to those in another tree.
193
:ivar previous_tree: tree to compare to
194
:ivar previous_entries: List of expected entries, as (path, previous_path) pairs.
197
def __init__(self, previous_tree, previous_entries):
198
Matcher.__init__(self)
199
self.previous_tree = previous_tree
200
self.previous_entries = previous_entries
202
def get_path_map(self, tree):
203
"""Get the (path, previous_path) pairs for the current tree."""
204
previous_intertree = InterTree.get(self.previous_tree, tree)
205
with tree.lock_read(), self.previous_tree.lock_read():
206
for path, ie in tree.iter_entries_by_dir():
207
if tree.supports_rename_tracking():
208
previous_path = previous_intertree.find_source_path(path)
210
if self.previous_tree.is_versioned(path):
215
kind = self.previous_tree.kind(previous_path)
216
if kind == 'directory':
219
yield (u"", previous_path)
221
yield (path + ie.kind_character(), previous_path)
224
def _strip_unreferenced_directories(entries):
225
"""Strip all directories that don't (in)directly contain any files.
227
:param entries: List of path strings or (path, previous_path) tuples to process
229
directory_used = set()
231
for (path, previous_path) in entries:
232
if not path or path[-1] == "/":
234
directories.append((path, previous_path))
236
# Yield the referenced parent directories
237
for direntry in directories:
238
if osutils.is_inside(direntry[0], path):
239
directory_used.add(direntry[0])
240
for (path, previous_path) in entries:
241
if (not path.endswith("/")) or path in directory_used:
242
yield (path, previous_path)
245
return 'HasPathRelations(%r, %r)' % (self.previous_tree, self.previous_entries)
247
def match(self, tree):
248
actual = list(self.get_path_map(tree))
249
if not tree.has_versioned_directories():
250
entries = list(self._strip_unreferenced_directories(
251
self.previous_entries))
253
entries = self.previous_entries
254
if not tree.supports_rename_tracking():
256
(path, path if self.previous_tree.is_versioned(path) else None)
257
for (path, previous_path) in entries]
258
return Equals(entries).match(actual)
185
261
class RevisionHistoryMatches(Matcher):
186
262
"""A matcher that checks if a branch has a specific revision history.