aboutsummaryrefslogtreecommitdiff
blob: e997efe766745ff385b6637ade33b35983198413 (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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# Copyright(c) 2004-2010, Gentoo Foundation
#
# Licensed under the GNU General Public License, v2

"""Provides common methods on Gentoo GLEP 53 keywords.

http://www.gentoo.org/proj/en/glep/glep-0053.html
"""

__all__ = (
	'Keyword',
	'compare_strs',
	'reduce_keywords',
	'determine_keyword'
)

# =======
# Imports
# =======


# =======
# Classes
# =======

class Keyword:
	"""Provides common methods on a GLEP 53 keyword."""

	def __init__(self, keyword):
		self.keyword = keyword
		arch, sep, os = keyword.partition('-')
		self.arch = arch
		self.os = os

	def __eq__(self, other):
		if not isinstance(other, self.__class__):
			return False
		return self.keyword == other.keyword

	def __ne__(self, other):
		return not self == other

	def __lt__(self, other):
		if not isinstance(other, self.__class__):
			raise TypeError("other isn't of %s type, is %s" % (
				self.__class__, other.__class__)
			)
		if self.os < other.os:
			return True
		return self.arch < other.arch

	def __le__(self, other):
		return self == other or self < other

	def __gt__(self, other):
		return not self <= other

	def __ge__(self, other):
		return self == other or self > other

	def __str__(self):
		return self.keyword

	def __repr__(self):
		return "<{0.__class__.__name__} {0.keyword!r}>".format(self)

# =========
# Functions
# =========

def compare_strs(kw1, kw2):
	"""Similar to the builtin cmp, but for keyword strings. Usually called
	as: keyword_list.sort(keyword.compare_strs)

	An alternative is to use the Keyword descriptor directly:
	>>> keyword_list = ['~x86', '~amd64', 'x86']
	>>> kwds = sorted(Keyword(x) for x in keyword_list)

	@see: >>> help(cmp)
	"""

	kw1_arch, sep, kw1_os = kw1.partition('-')
	kw2_arch, sep, kw2_os = kw2.partition('-')
	if kw1_arch != kw2_arch:
		if kw1_os != kw2_os:
			return -1 if kw1_os < kw2_os else 1
		return -1 if kw1_arch < kw2_arch else 1
	if kw1_os == kw2_os:
		return 0
	return -1 if kw1_os < kw2_os else 1


def reduce_keywords(keywords):
	"""Reduce a list of keywords to a unique set of stable keywords.

	Example usage:
		>>> kw = reduce_keywords(['~amd64', 'x86', '~x86'])
		>>> isinstance(kw, set)
		True
		>>> sorted(kw)
		['amd64', 'x86']

	@type keywords: array
	@rtype: set
	"""
	return set(x.lstrip('~') for x in keywords)


abs_keywords = reduce_keywords


# FIXME: this is unclear
# dj, how about 'deduce_keyword'
# I was trying to avoid a 2nd use of determine_keyword name (in analyse.lib)
# but that one is a little different and not suitable for this task.
def determine_keyword(arch, accepted, keywords):
	"""Determine a keyword from matching a dep's KEYWORDS
	list against the ARCH & ACCEPT_KEYWORDS provided.

	@type arch: string
	@param arch: portage.settings["ARCH"]
	@type accepted: string
	@param accepted: portage.settings["ACCEPT_KEYWORDS"]
	@type keywords: string
	@param keywords: the pkg ebuilds keywords
	"""
	if not keywords:
		return ''
	keys = keywords.split()
	if arch in keys:
		return arch
	keyworded = "~" + arch
	if keyworded in keys:
		return keyworded
	match = list(set(accepted.split(" ")).intersection(keys))
	if len(match) > 1:
		if arch in match:
			return arch
		if keyworded in match:
			return keyworded
		return 'unknown'
	if match:
		return match[0]
	return 'unknown'