summaryrefslogtreecommitdiff
blob: 869c52ea78afb66c99bedd1d22b6e2e9cd79f6ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import sys

from portage.manifest import guessManifestFileType
from portage.versions import pkgsplit, vercmp, _pkg_str

if sys.hexversion < 0x3000000:
	_filename_base = unicode
else:
	_filename_base = str

class _special_filename(_filename_base):
	"""
	Helps to sort file names by file type and other criteria.
	"""
	def __new__(cls, status_change, file_name):
		return _filename_base.__new__(cls, status_change + file_name)

	def __init__(self, status_change, file_name):
		_filename_base.__init__(status_change + file_name)
		self.status_change = status_change
		self.file_name = file_name
		self.file_type = guessManifestFileType(file_name)

	@staticmethod
	def file_type_lt(a, b):
		"""
		Defines an ordering between file types.
		"""
		first = a.file_type
		second = b.file_type
		if first == second:
			return False

		if first == "EBUILD":
			return True
		elif first == "MISC":
			return second in ("EBUILD",)
		elif first == "AUX":
			return second in ("EBUILD", "MISC")
		elif first == "DIST":
			return second in ("EBUILD", "MISC", "AUX")
		elif first is None:
			return False
		else:
			raise ValueError("Unknown file type '%s'" % first)

	def __lt__(self, other):
		"""
		Compare different file names, first by file type and then
		for ebuilds by version and lexicographically for others.
		EBUILD < MISC < AUX < DIST < None
		"""
		if self.__class__ != other.__class__:
			raise NotImplementedError

		# Sort by file type as defined by file_type_lt().
		if self.file_type_lt(self, other):
			return True
		elif self.file_type_lt(other, self):
			return False

		# Files have the same type.
		if self.file_type == "EBUILD":
			# Sort by version. Lowest first.
			ver = "-".join(pkgsplit(self.file_name[:-7])[1:3])
			other_ver = "-".join(pkgsplit(other.file_name[:-7])[1:3])
			return vercmp(ver, other_ver) < 0
		else:
			# Sort lexicographically.
			return self.file_name < other.file_name