changeset 247:f5847d29e838

Fixed: match='re' could produce duplicate test identifiers files.Files.regexp(pattern) now makes sure to return only one metafile for each matching virtual path, namely, the one that would be returned for that virtual path by files.Files.from_virtual_path.
author Oleg Oshmyan <chortos@inbox.lv>
date Thu, 03 Oct 2013 01:19:09 +0300
parents 6dd29475ae9b (current diff) 1bc89faac941 (diff)
children acd70a60bc17
files upreckon/files.py
diffstat 1 files changed, 24 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/upreckon/files.py	Wed Oct 02 23:32:37 2013 +0300
+++ b/upreckon/files.py	Thu Oct 03 01:19:09 2013 +0300
@@ -297,6 +297,12 @@
 			for filename in archives:
 				yield self.__add__(filename, False)
 	
+	def _also_add_tests(self):
+		yield self
+		if not self._has_tests:
+			for metafile in self._add_tests():
+				yield metafile
+	
 	def _add_virtual(self, filename):
 		return File(posixpath.join(self.virtual_path, filename),
 		            self._external_path,
@@ -324,29 +330,29 @@
 			            _has_tests=self._has_tests)
 	
 	@classmethod
-	def regexp(cls, pattern):
+	def regexp(cls, pattern, _unique=True):
 		if not pattern:
 			yield cls('', os.curdir)
 			return
 		dirname, basename = posixpath.split(pattern)
-		dirs = cls.regexp(dirname)
+		dirs = cls.regexp(dirname, False)
 		reobj = re.compile(pattern + '$', re.UNICODE)
+		if _unique:
+			yielded = set()
 		while dirs:
 			newdirs = []
-			for directory in dirs:
-				try:
-					names = directory.listdir()
-				except Exception:
-					continue
-				for name in names:
-					dir_entry = directory + name
-					if re.match(reobj, dir_entry.virtual_path):
-						yield dir_entry
-					if not directory._has_tests:
-						if name == 'tests':
-							dir_entry = directory.__add__(name, False)
-							dir_entry._has_tests = True
-							newdirs.append(dir_entry)
-						elif not directory.archive and name in archives:
-							newdirs.append(directory.__add__(name, False))
+			for testless_directory in dirs:
+				for directory in testless_directory._also_add_tests():
+					try:
+						names = directory.listdir()
+					except Exception:
+						continue
+					for name in names:
+						dir_entry = directory + name
+						if re.match(reobj, dir_entry.virtual_path):
+							if not _unique:
+								yield dir_entry
+							elif dir_entry.virtual_path not in yielded:
+								yield dir_entry
+								yielded.add(dir_entry.virtual_path)
 			dirs = newdirs