Gentoo Archives: gentoo-commits

From: "André Erdmann" <dywi@×××××××.de>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/R_overlay:master commit in: roverlay/
Date: Wed, 06 Jun 2012 19:53:26
Message-Id: 1339012032.f0a5ee703f0d23a4968963f57817336486806451.dywi@gentoo
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