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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
g_collections.py
~~~~~~~~~~~~~~~~
Customized classes of standard python data types
for use withing g-sorcery for custom formatted string output
substitution in our ebuild templates and classes for storing
information about packages and dependencies.
:copyright: (c) 2013 by Brian Dolbec
:copyright: (c) 2013-2015 by Jauhien Piatlicki
:license: GPL-2, see LICENSE for more details.
"""
import portage
class elist(list):
'''Custom list type which adds a customized __str__()
and takes an optional separator argument
elist() -> new empty elist
elist(iterable) -> new elist initialized from iterable's items
elist(separator='\\n\\t') -> new empty elist with
newline & tab indented str(x) output
elist(iterable, ' ') -> new elist initialized from iterable's items
with space separated str(x) output
'''
__slots__ = ('_sep_')
def __init__(self, iterable=None, separator=' '):
'''
iterable: initialize from iterable's items
separator: string used to join list members with for __str__()
'''
list.__init__(self, iterable or [])
self._sep_ = separator
def __str__(self):
'''Custom output function
'x.__str__() <==> str(separator.join(x))'
'''
return self._sep_.join(map(str, self))
class serializable_elist(object):
"""
A JSON serializable version of elist.
"""
__slots__ = ('data')
def __init__(self, iterable=None, separator=' '):
'''
iterable: initialize from iterable's items
separator: string used to join list members with for __str__()
'''
self.data = elist(iterable or [], separator)
def __eq__(self, other):
return self.data == other.data
def __iter__(self):
return iter(self.data)
def __str__(self):
'''Custom output function
'''
return str(self.data)
def append(self, x):
self.data.append(x)
def serialize(self):
return {"separator": self.data._sep_, "data" : self.data}
@classmethod
def deserialize(cls, value):
return serializable_elist(value["data"], separator = value["separator"])
#todo: replace Package with something better
class Package(object):
"""
Class to store full package name: category/package-version
"""
__slots__ = ('category', 'name', 'version')
def __init__(self, category, package, version):
self.category = category
self.name = package
self.version = version
def __str__(self):
return self.category + '/' + self.name + '-' + self.version
def __eq__(self, other):
return self.category == other.category and \
self.name == other.name and \
self.version == other.version
def __hash__(self):
return hash(self.category + self.name + self.version)
def serialize(self):
return [self.category, self.name, self.version]
@classmethod
def deserialize(cls, value):
return Package(*value)
#todo equality operator for Dependency, as it can be used in backend dependency solving algorithm
class Dependency(object):
"""
Class to store a dependency. Uses portage Atom.
"""
__slots__ = ('atom', 'category', 'package', 'version', 'operator')
def __init__(self, category, package, version="", operator=""):
atom_str = operator + category + "/" + package
if version:
atom_str += "-" + str(version)
object.__setattr__(self, "atom", portage.dep.Atom(atom_str))
object.__setattr__(self, "category", category)
object.__setattr__(self, "package", package)
object.__setattr__(self, "version", version)
object.__setattr__(self, "operator", operator)
def __setattr__(self, name, value):
raise AttributeError("Dependency instances are immutable",
self.__class__, name, value)
def __str__(self):
return str(self.atom)
def serialize(self):
return str(self)
@classmethod
def deserialize(cls, value):
atom = portage.dep.Atom(value)
operator = portage.dep.get_operator(atom)
cpv = portage.dep.dep_getcpv(atom)
category, rest = portage.catsplit(cpv)
if operator:
package, version, revision = portage.pkgsplit(rest)
else:
package = rest
version = ""
operator = ""
return Dependency(category, package, version, operator)
|