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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
#!/usr/bin/python
from geneticone import *
import gentoolkit
import portage
from portage_util import unique_array
class Package (gentoolkit.Package):
"""This is just a subclass of the Package-class of gentoolkit."""
def __init__ (self, cpv):
gentoolkit.Package.__init__(self, cpv)
def get_mask_status(self):
'''gets the numeric mask status of a package
can be translated as string:
maskmodes = [ " ", " ~", " -", "M ", "M~", "M-" ]
(0=unmasked 1=~arch 2=-arch etc.)
This method adapted from equery 0.1.4
Original author: Karl Trygve Kalleberg <karltk@gentoo.org>
'''
pkgmask = 0
if self.is_masked():
pkgmask = pkgmask + 3
keywords = self.get_env_var("KEYWORDS").split()
if "~" + gentoolkit.settings["ARCH"] in keywords:
pkgmask = pkgmask + 1
elif "-*" in keywords or "-" + gentoolkit.settings["ARCH"] in keywords:
pkgmask = pkgmask + 2
return pkgmask
def get_size (self):
return self.size()
def get_all_useflags (self):
"""Returns a list of _all_ useflags for this package."""
return self.get_env_var("IUSE").split()
def get_all_deps (self):
"""Returns a linearised list of all first-level dependencies for this package, on
the form [(comparator, [use flags], cpv), ...]"""
return unique_array(self.get_compiletime_deps()+self.get_runtime_deps()+self.get_postmerge_deps())
def get_dep_packages (self):
"""Returns a cpv-list of packages on which this package depends and which have not been installed yet.
raises: BlockedException, PackageNotFoundException."""
dep_pkgs = [] # the package list
# let portage do the main stuff ;)
# pay attention to any changes here
deps = portage.dep_check (self.get_env_var("RDEPEND")+" "+self.get_env_var("DEPEND"), vartree.dbapi, self._settings)
if not deps: # what is the difference to [1, []] ?
return []
deps = deps[1]
for dep in deps:
if dep[0] == '!':
blocked = find_installed_packages(dep[1:])
if blocked != []:
raise BlockedException, blocked[0].get_cpv()
else: # next flag
continue
pkg = find_best_match(dep)
if not dep:
raise PackageNotFoundException, dep
else:
dep_pkgs.append(pkg.get_cpv())
return dep_pkgs
def own_get_dep_packages (self, old_cpv_dict = {}):
# XXX: after having finished this, i realized, that there is already a portage function -.- ;
# will keep this in case portage changes anything
"""Returns a list of all packages (i.e. package-cpvs) which this package depends on and which not have been installed yet.
Param old_cpv_dict is a {cp: version}-dictionary holding already found deps.
Raises a BlockedException if the package is being blocked by another installed package."""
# XXX: This won't find blocking dependencies
# XXX: Has some problems with modular X (this has a very strange ebuild) ... we should enhance _parse_deps
print "Actual: "+self._cpv # debug output
uses = [] # list of actual useflags / useflags the package has been installed with
dep_packages = [] # list of packages returned
dep_cpv_dict = {} # all dependencies are inserted here
# get useflags
if self.is_installed():
uses = self.get_set_useflags()
else:
uses = self.get_settings("USE")
# cycle through dependencies
for (comp, flags, dep_cpv) in self.get_all_deps():
# find blocking packages
if comp and comp[0] == '!':
blocked = find_installed_packages(comp[1:]+dep_cpv)
if blocked != []:
raise BlockedException, blocked[0].get_cpv()
else: # next flag
continue
# look whether this package is really required
needDep = True
for flag in flags:
if (flag[0] == '!' and flag[1:] in uses) or (flag[0] != '!' and flag not in uses):
needDep = False
break
if needDep: # it is ...
if find_installed_packages(comp+dep_cpv) == []: # ... and not installed yet
d = find_best_match(comp+dep_cpv)
if not d: # no package found
raise PackageNotFoundException, dep_cpv
if d.get_cp() not in old_cpv_dict: # ... and not found already by an other package
dep_cpv_dict[d.get_cp()] = d.get_version()
print "Dep: "+d.get_cpv() # debug
dep_packages.append(d.get_cpv())
for dep in dep_packages: # find dependencies for each package
old_cpv_dict.update(dep_cpv_dict)
old_cpv_dict.update({self.get_cp() : self.get_version()})
dep_packages += find_packages("="+dep)[0].own_get_dep_packages(old_cpv_dict)
return unique_array(dep_packages)
def get_set_useflags (self):
"""Returns a list of the useflags enabled at installation time. If package is not installed, it returns an empty list."""
if self.is_installed():
uses = self.get_use_flags().split()
iuses = self.get_all_useflags()
set = []
for u in iuses:
if u in uses:
set.append(u)
return set
else:
return []
def get_cp (self):
"""Returns category/package."""
return self.get_category()+"/"+self.get_name()
def is_masked (self):
"""Returns True if either masked by package.mask or by profile."""
# XXX: Better solution than string comparison?
status = portage.getmaskingstatus(self._cpv)
if "profile" in status or "package.mask" in status:
return True
return False
def _parse_deps(self,deps,curuse=[],level=0):
"""Modified method "_parse_deps" of gentoolkit.Package.
Do NOT ignore blocks."""
# store (comparator, [use predicates], cpv)
r = []
comparators = ["~","<",">","=","<=",">="]
end = len(deps)
i = 0
while i < end:
blocked = False
tok = deps[i]
if tok == ')':
return r,i
if tok[-1] == "?":
tok = tok.replace("?","")
sr,l = self._parse_deps(deps[i+2:],curuse=curuse+[tok],level=level+1)
r += sr
i += l + 3
continue
if tok == "||":
sr,l = self._parse_deps(deps[i+2:],curuse,level=level+1)
r += sr
i += l + 3
continue
# conjonction, like in "|| ( ( foo bar ) baz )" => recurse
if tok == "(":
sr,l = self._parse_deps(deps[i+1:],curuse,level=level+1)
r += sr
i += l + 2
continue
# pkg block "!foo/bar" => ignore it
if tok[0] == "!":
#i += 1
#continue
blocked = True # added
tok = tok[1:] # added
# pick out comparator, if any
cmp = ""
for c in comparators:
if tok.find(c) == 0:
cmp = c
if blocked: cmp = "!"+cmp # added
tok = tok[len(cmp):]
r.append((cmp,curuse,tok))
i += 1
return r,i
|