keyword: remove shebang from module without __name__ == '__main__' block
[gentoolkit.git] / pym / gentoolkit / keyword.py
1 # Copyright(c) 2004-2010, Gentoo Foundation
2 #
3 # Licensed under the GNU General Public License, v2
4 #
5 # $Header$
6
7 """Provides common methods on Gentoo GLEP 53 keywords.
8
9 http://www.gentoo.org/proj/en/glep/glep-0053.html
10 """
11
12 __all__ = (
13         'Keyword',
14         'compare_strs',
15         'reduce_keywords',
16         'determine_keyword'
17 )
18
19 # =======
20 # Imports
21 # =======
22
23
24 # =======
25 # Classes
26 # =======
27
28 class Keyword(object):
29         """Provides common methods on a GLEP 53 keyword."""
30
31         def __init__(self, keyword):
32                 self.keyword = keyword
33                 arch, sep, os = keyword.partition('-')
34                 self.arch = arch
35                 self.os = os
36
37         def __eq__(self, other):
38                 if not isinstance(other, self.__class__):
39                         return False
40                 return self.keyword == other.keyword
41
42         def __ne__(self, other):
43                 return not self == other
44
45         def __lt__(self, other):
46                 if not isinstance(other, self.__class__):
47                         raise TypeError("other isn't of %s type, is %s" % (
48                                 self.__class__, other.__class__)
49                         )
50                 if self.os < other.os:
51                         return True
52                 return self.arch < other.arch
53
54         def __le__(self, other):
55                 return self == other or self < other
56
57         def __gt__(self, other):
58                 return not self <= other
59
60         def __ge__(self, other):
61                 return self == other or self > other
62
63         def __str__(self):
64                 return self.keyword
65
66         def __repr__(self):
67                 return "<{0.__class__.__name__} {0.keyword!r}>".format(self)
68
69 # =========
70 # Functions
71 # =========
72
73 def compare_strs(kw1, kw2):
74         """Similar to the builtin cmp, but for keyword strings. Usually called
75         as: keyword_list.sort(keyword.compare_strs)
76
77         An alternative is to use the Keyword descriptor directly:
78         >>> kwds = sorted(Keyword(x) for x in keyword_list)
79
80         @see: >>> help(cmp)
81         """
82
83         kw1_arch, sep, kw1_os = kw1.partition('-')
84         kw2_arch, sep, kw2_os = kw2.partition('-')
85         if kw1_arch != kw2_arch:
86                 if kw1_os != kw2_os:
87                         return -1 if kw1_os < kw2_os else 1
88                 return -1 if kw1_arch < kw2_arch else 1
89         if kw1_os == kw2_os:
90                 return 0
91         return -1 if kw1_os < kw2_os else 1
92
93
94 def reduce_keywords(keywords):
95         """Reduce a list of keywords to a unique set of stable keywords.
96
97         Example usage:
98                 >>> reduce_keywords(['~amd64', 'x86', '~x86'])
99                 set(['amd64', 'x86'])
100
101         @type keywords: array
102         @rtype: set
103         """
104         return set(x.lstrip('~') for x in keywords)
105
106
107 abs_keywords = reduce_keywords
108
109
110 # FIXME: this is unclear
111 # dj, how about 'deduce_keyword'
112 # I was trying to avoid a 2nd use of determine_keyword name (in analyse.lib)
113 # but that one is a little different and not suitable for this task.
114 def determine_keyword(arch, accepted, keywords):
115         """Determine a keyword from matching a dep's KEYWORDS
116         list against the ARCH & ACCEPT_KEYWORDS provided.
117
118         @type arch: string
119         @param arch: portage.settings["ARCH"]
120         @type accepted: string
121         @param accepted: portage.settings["ACCEPT_KEYWORDS"]
122         @type keywords: string
123         @param keywords: the pkg ebuilds keywords
124         """
125         if not keywords:
126                 return ''
127         keys = keywords.split()
128         if arch in keys:
129                 return arch
130         keyworded = "~" + arch
131         if keyworded in keys:
132                 return keyworded
133         match = list(set(accepted.split(" ")).intersection(keys))
134         if len(match) > 1:
135                 if arch in match:
136                         return arch
137                 if keyworded in match:
138                         return keyworded
139                 return 'unknown'
140         if match:
141                 return match[0]
142         return 'unknown'