aboutsummaryrefslogtreecommitdiff
blob: a585de346c5141627fd5d6b413375ca0ff4dc278 (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# R overlay --
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

class DependencyRule ( object ):
	"""Prototype of a dependency rule. Not meant for instantiation."""

	def __init__ ( self, priority ):
		"""Initializes an rule pool.

		arguments:
		* priority -- used for sorting rule pools, lower means more important
		"""
		self.max_score = 1000
		self.priority  = priority
	# --- end of __init__ (...) ---

	def matches ( self, dep_env ):
		"""Returns an int > 0 if this rule matches the given DepEnv."""
		return 0
	# --- end of matches (...) ---

# --- end of DependencyRule ---


class DependencyRulePool ( object ):

	def __init__ ( self, name, priority ):
		"""Initializes an DependencyRulePool, which basically is a set of
		dependency rules with methods like "search for x in all rules."

		arguments:
		* name -- name of this rule pool
		* priority -- priority of this pool (lower is better)
		"""
		self.rules       = list ()
		self.name        = name
		self.priority    = priority
		# the "rule weight" is the sum of the rules' priorities - it's used to
		#  compare/sort dependency pools with the same priority (lesser weight is better)
		self.rule_weight = 0
	# --- end of __init__ (...) ---

	def sort ( self ):
		"""Sorts this rule pool and determines its weight which is used to compare
		rule pools."""

		self.rules.sort ( key=lambda rule : rule.priority )

		rule_priority_sum = 0
		for r in self.rules: rule_priority_sum += r.priority
		self.rule_weight = rule_priority_sum

		return None
	# --- end of sort (...) ---

	def add ( self, rule ):
		"""Adds a DependencyRule to this rule pool.

		arguments:
		* rule --
		"""
		if issubclass ( rule, DependencyRule ):
			self.rules.append ( rule )
		else:
			raise Exception ( "bad usage (dependency rule expected)." )

		return None
	# --- end of add (...) ---

	def matches ( self, dep_env, skip_matches=0 ):
		"""Tries to find a match in this dependency rule pool.
		The first match is immediatly returned unless skip_matches is != 0, in
		which case the first (>0) / last (<0) skip_matches matches are skipped.
		Returns a tuple ( score, portage dependency ),
		e.g. ( 1000, 'sys-apps/which' ), if match found, else None.

		arguments:
		* dep_env -- dependency to look up
		* skip_matches --
		"""

		if abs ( skip_matches ) >= len ( self.rules ):
			# all potential matches ignored,
			#  cannot expect a result in this case - abort now
			pass

		else:
			skipped = 0
			# python3 requires list ( range ... )
			order = list ( range ( len ( self.rules ) ) )

			if skip_matches < 0:
				skip_matches *= -1
				order.reverse()

			for index in order:
				score = self.rules [index].matches ( dep_env )
				if score:
					if skipped < skip_matches:
						skipped += 1
					else:
						return ( score, self.rules [index].get_dep () )


		return None
	# --- end of matches (...) ---