1 |
commit: f0a5ee703f0d23a4968963f57817336486806451 |
2 |
Author: André Erdmann <dywi <AT> mailerd <DOT> de> |
3 |
AuthorDate: Wed Jun 6 19:47:12 2012 +0000 |
4 |
Commit: André Erdmann <dywi <AT> mailerd <DOT> de> |
5 |
CommitDate: Wed Jun 6 19:47:12 2012 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=f0a5ee70 |
7 |
|
8 |
add dependency resolution to ebuild creation |
9 |
|
10 |
modified: roverlay/ebuildcreator.py |
11 |
modified: roverlay/ebuildjob.py |
12 |
|
13 |
--- |
14 |
roverlay/ebuildcreator.py | 11 +++-- |
15 |
roverlay/ebuildjob.py | 111 ++++++++++++++++++++++++++++----------------- |
16 |
2 files changed, 75 insertions(+), 47 deletions(-) |
17 |
|
18 |
diff --git a/roverlay/ebuildcreator.py b/roverlay/ebuildcreator.py |
19 |
index bc74490..3713c3b 100644 |
20 |
--- a/roverlay/ebuildcreator.py |
21 |
+++ b/roverlay/ebuildcreator.py |
22 |
@@ -3,6 +3,8 @@ |
23 |
# Distributed under the terms of the GNU General Public License v2 |
24 |
|
25 |
from roverlay.ebuildjob import EbuildJob |
26 |
+from roverlay.depres import depresolver |
27 |
+from roverlay.depres.communication import EbuildJobChannel |
28 |
|
29 |
class EbuildCreator: |
30 |
|
31 |
@@ -12,7 +14,7 @@ class EbuildCreator: |
32 |
every R package added. |
33 |
""" |
34 |
self.ebuild_headers = dict () |
35 |
- self.depresolve_main = None # TODO |
36 |
+ self.depresolve_main = depresolver.DependencyResolver () |
37 |
self.ebuild_jobs = [] |
38 |
|
39 |
# --- end of init (...) --- |
40 |
@@ -26,7 +28,7 @@ class EbuildCreator: |
41 |
* package_file -- path R package file |
42 |
""" |
43 |
|
44 |
- new_job = EbuildJob ( package_file, self.get_resolver ( False ) ) |
45 |
+ new_job = EbuildJob ( package_file, self.get_resolver_channel ) |
46 |
|
47 |
self.ebuild_jobs.append ( new_job ) |
48 |
|
49 |
@@ -34,15 +36,14 @@ class EbuildCreator: |
50 |
|
51 |
# --- end of add_package (...) --- |
52 |
|
53 |
- def get_resolver ( self, readonly=True ): |
54 |
+ def get_resolver_channel ( self, name=None ): |
55 |
"""Returns a communication channel to the dependency resolver. |
56 |
|
57 |
arguments: |
58 |
readonly -- whether the channel is listen-only (no write methods) or not |
59 |
defaults to True |
60 |
""" |
61 |
- # <TODO> |
62 |
- return None |
63 |
+ return self.depresolve_main.register_channel ( EbuildJobChannel ( name=name ) ) |
64 |
#return self.depresolve_main.get_channel() |
65 |
|
66 |
# --- end of get_resolver (...) --- |
67 |
|
68 |
diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py |
69 |
index be8e5e3..fa13a48 100644 |
70 |
--- a/roverlay/ebuildjob.py |
71 |
+++ b/roverlay/ebuildjob.py |
72 |
@@ -36,7 +36,7 @@ class EbuildJob: |
73 |
FAIL = [], |
74 |
) |
75 |
|
76 |
- def __init__ ( self, package_file, dep_resolver=None ): |
77 |
+ def __init__ ( self, package_file, depres_channel_spawner=None ): |
78 |
"""Initializes an EbuildJob, which creates an ebuild for an R package. |
79 |
|
80 |
arguments: |
81 |
@@ -49,8 +49,6 @@ class EbuildJob: |
82 |
dep resolver 'communication channel', status codes etc. |
83 |
""" |
84 |
|
85 |
- #self.package_file = package_file |
86 |
- self.dep_resolver = dep_resolver |
87 |
# get description reader from args? |
88 |
self.description_reader = DescriptionReader ( package_file ) |
89 |
|
90 |
@@ -58,10 +56,26 @@ class EbuildJob: |
91 |
|
92 |
self.ebuild = None |
93 |
|
94 |
+ # only allow a function (at least callable) for self.get_resolver |
95 |
+ if hasattr ( depres_channel_spawner, '__call__' ): |
96 |
+ self.request_resolver = depres_channel_spawner |
97 |
+ # _depres contains (almost) dependency resolution data/.., including |
98 |
+ # communication channels and should only be modified in run() |
99 |
+ self._depres = dict () |
100 |
+ else: |
101 |
+ self.request_resolver = None |
102 |
+ |
103 |
self.status = 'INIT' |
104 |
|
105 |
# --- end of __init__ (...) --- |
106 |
|
107 |
+ def get_resolver ( self, dependency_type ): |
108 |
+ if not dependency_type in self._depres: |
109 |
+ self._depres [dependency_type] = self.request_resolver () |
110 |
+ |
111 |
+ return self._depres [dependency_type] |
112 |
+ |
113 |
+ |
114 |
def get_ebuild ( self ): |
115 |
"""Returns the Ebuild that is created by this object. Note that you should |
116 |
check the status with status ( $TODO::EBUILD_READY ) before trying to use |
117 |
@@ -148,73 +162,86 @@ class EbuildJob: |
118 |
False |
119 |
) |
120 |
|
121 |
- if self.dep_resolver and self.dep_resolver.enabled(): |
122 |
+ if not self.request_resolver is None: |
123 |
+ |
124 |
+ dep_type = desc_field = None |
125 |
|
126 |
- # collect depdencies from desc and add them to the resolver |
127 |
- raw_depends = dict () |
128 |
|
129 |
- dep_type = field = None |
130 |
+ for dep_type in EbuildJob.DEPENDENCY_FIELDS: |
131 |
|
132 |
- for dep_type in EbuildJob.DEPENDENCY_FIELDS.keys(): |
133 |
+ resolver = None |
134 |
|
135 |
- raw_depends [dep_type] = [] |
136 |
+ for desc_field in EbuildJob.DEPENDENCY_FIELDS [dep_type]: |
137 |
|
138 |
- for field in EbuildJob.DEPENDENCY_FIELDS [dep_type]: |
139 |
+ if desc_field in desc: |
140 |
+ if not resolver: |
141 |
+ resolver = self.get_resolver ( dep_type ) |
142 |
|
143 |
- if field in desc: |
144 |
- if isinstance ( desc [field], list ): |
145 |
- raw_depends.extend ( desc [field] ) |
146 |
- self.dep_resolver.add_dependencies ( desc [field] ) |
147 |
+ if isinstance ( desc [desc_field], list ): |
148 |
+ resolver.add_dependencies ( desc [desc_field] ) |
149 |
|
150 |
else: |
151 |
- raw_depends.append ( desc [field] ) |
152 |
- self.dep_resolver.add_depency ( desc [field] ) |
153 |
+ resolver.add_depency ( desc [desc_field] ) |
154 |
|
155 |
- del field, dep_type |
156 |
+ del resolver |
157 |
|
158 |
|
159 |
- while not self.dep_resolver.done(): |
160 |
+ # wait |
161 |
+ resolver_list = self._depres.values() |
162 |
+ wait_resolve = True |
163 |
+ while wait_resolve: |
164 |
+ wait_resolve = False |
165 |
|
166 |
if not self._set_status ( 'WAIT_RESOLVE' ): return |
167 |
|
168 |
+ self.logger.debug ( "WAITING" ) |
169 |
+ |
170 |
# tell the resolver to run (again) |
171 |
- self.dep_resolver.run() |
172 |
+ for r in resolver_list : r.trigger_run () |
173 |
|
174 |
if not self._set_status ( 'BUSY' ): return |
175 |
|
176 |
- if self.dep_resolver.satisfy_request(): |
177 |
+ for r in resolver_list : |
178 |
+ if not r.done (): |
179 |
+ wait_resolve = True |
180 |
+ break |
181 |
|
182 |
- dep_type = dep_str = dep = None |
183 |
|
184 |
+ # check if all deps resolved |
185 |
+ deps_resolved = True |
186 |
+ for r in resolver_list: |
187 |
+ if not r.satisfy_request(): |
188 |
+ deps_resolved = False |
189 |
+ break |
190 |
+ |
191 |
+ if deps_resolved: |
192 |
# dependencies resolved, add them to the ebuild |
193 |
- for dep_type in raw_depends.keys(): |
194 |
- |
195 |
- for dep_str in raw_depends [dep_type]: |
196 |
- # lookup (str) should return a str here |
197 |
- dep = self.dep_resolver.lookup ( dep_str ) |
198 |
- if dep is None: |
199 |
- raise Exception ( |
200 |
- "dep_resolver is broken: lookup() returns None but satisfy_request() says ok." |
201 |
- ) |
202 |
- else: |
203 |
- # add depencies in append mode |
204 |
- dep = self.dep_resolver.lookup ( dep_str ) |
205 |
- ebuild.add ( dep_type, |
206 |
- self.dep_resolver.lookup ( dep_str ), |
207 |
- True |
208 |
- ) |
209 |
+ for dep_type, resolver in self._depres.items(): |
210 |
+ |
211 |
+ deplist = resolver.collect_dependencies () |
212 |
|
213 |
- del dep, dep_str, dep_type |
214 |
+ if deplist is None or not isinstance ( deplist, list ): |
215 |
+ ## false positive: "empty" channel |
216 |
+ raise Exception ( |
217 |
+ "dep_resolver is broken: lookup() returns None but satisfy_request() says ok." |
218 |
+ ) |
219 |
+ else: |
220 |
+ # add dependencies in no_append/override mode |
221 |
+ ebuild.add ( dep_type, deplist, False ) |
222 |
|
223 |
- # tell the dep resolver that we're done here |
224 |
- self.dep_resolver.close() |
225 |
+ # tell the dep resolver channels that we're done |
226 |
+ for r in resolver_list: r.close () |
227 |
|
228 |
else: |
229 |
- # ebuild is not creatable, set status to FAIL and close dep resolver |
230 |
+ # ebuild is not creatable, set status to FAIL and close dep resolvers |
231 |
+ self.logger.info ( "Failed to resolve dependencies for this package." ) |
232 |
+ for r in resolver_list: r.close () |
233 |
self._set_status ( 'FAIL' ) |
234 |
- self.dep_resolver.close() |
235 |
return |
236 |
|
237 |
+ # --- end dep resolution |
238 |
+ |
239 |
+ |
240 |
## finalize self.ebuild: forced text creation + make it readonly |
241 |
if ebuild.prepare ( True, True ): |
242 |
self.ebuild = ebuild |