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: Tue, 29 May 2012 17:10:29
Message-Id: 1338311195.2e76c1e480434d43b6be4ade11d6ebd7a7025718.dywi@gentoo
1 commit: 2e76c1e480434d43b6be4ade11d6ebd7a7025718
2 Author: Andre Erdmann <dywi <AT> mailerd <DOT> de>
3 AuthorDate: Tue May 29 17:06:35 2012 +0000
4 Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
5 CommitDate: Tue May 29 17:06:35 2012 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=2e76c1e4
7
8 roverlay, ebuildcreator: module that accepts package_files, schedules their processing into jobs and returns ebuilds (but is todo)
9 modified: ebuildcreator.py
10
11 ---
12 roverlay/ebuildcreator.py | 356 +++++++--------------------------------------
13 1 files changed, 54 insertions(+), 302 deletions(-)
14
15 diff --git a/roverlay/ebuildcreator.py b/roverlay/ebuildcreator.py
16 index fa648b8..f439c71 100644
17 --- a/roverlay/ebuildcreator.py
18 +++ b/roverlay/ebuildcreator.py
19 @@ -1,350 +1,102 @@
20 -# R Overlay -- ebuild creation
21 +# R Overlay -- ebuild creation, "master" module
22 # Copyright 2006-2012 Gentoo Foundation
23 # Distributed under the terms of the GNU General Public License v2
24
25 -# temporary import until logging is implemented
26 -from sys import stderr as logging
27 +from roverlay import ebuildjob.EbuildJob
28
29 -# temporary import until config and real constants are implemented
30 -from roverlay import tmpconst as const
31
32 -from roverlay.fileio import DescriptionReader
33 -
34 -# misc TODO notes:
35 -# * could use caching via decorators instead of wrappers (-> later)
36 -# * instead of including the ebuild header in every ebuild 'export' data:
37 -# ** link that header
38 -# ** ebuild_export = [ <header_link>, str, [,str]* ]
39 -#
40 +class EbuildCreator:
41
42 -class Ebuild:
43 - # could move this to const
44 - EBUILD_INDENT = "\t"
45
46 - # reading every ebuild header file (copyright, inherit <eclass>) once at most
47 - # <ebuild header file> => [<content of this file>]
48 - # shared among all ebuilds
49 - ebuild_headers = dict()
50
51 @classmethod
52 def __init__ ( self ):
53 - """Initializes an empty Ebuild. This is an object that can be used to
54 - create text lines for an ebuild file."""
55 -
56 - #self.name = ''
57 - #self.version = ''
58 - #self.origin = ''
59 - #self.pkg_file = ''
60 - #self.depend = ''
61 - #self.rdepend = ''
62 - #self.rsuggests = ''
63 - #self.description = ''
64 + """Initializes an EbuildCreator. This is an Object that controls the
65 + R package -> ebuild creation. It continuously creates EbuildJobs for
66 + every R package added.
67 + """
68 + self.ebuild_headers = dict ()
69 + self.depresolve_main = None # TODO
70 + self.ebuild_jobs = []
71
72 - # temporary var
73 - #self.TODO = ''
74 + # --- end of init (...) ---
75
76 - # this will be a list of str when exported data have been calculated
77 - self._ebuild_export = None
78
79 @classmethod
80 - def get_ebuild ( self, description_data, force_update=False ):
81 - """
82 - Wrapper function that returns ebuild 'export' data.
83 - This is a list of str that has no newline chars at the end of each str.
84 + def add_package ( self, package_file ):
85 + """Adds an R package to the EbuildCreator, which means that an EbuildJob
86 + will be created for it. Returns the EbuildJob, which is also stored
87 + in the job queue.
88
89 arguments:
90 - * force_update -- force calculation of export data
91 -
92 + * package_file -- path R package file
93 """
94 - if force_update or (self._ebuild_export is None):
95 - self._ebuild_export = self._make_export ( description_data )
96 + new_job = EbuildJob ( package_file, self.get_resolver ( False ) )
97
98 - return self._ebuild_export
99 + self.ebuild_jobs.append ( new_job )
100
101 - @classmethod
102 - def suggest_filename ( self ):
103 - """Suggests a file name for the ebuild.
104 - Calculated using ebuild data, but TODO
105 - """
106 - # name-version
107 - return None
108 + return new_job
109 +
110 + # --- end of add_package (...) ---
111
112 @classmethod
113 - def write_ebuild ( self, file_to_write, force_update=False ):
114 - """Writes this ebuild into a file
115 + def get_resolver ( self, readonly=True ):
116 + """Returns a communication channel to the dependency resolver.
117
118 arguments:
119 - * file_to_write -- path of the file to write (will be overwritten if existent)
120 - * force_update -- force calculation of ebuild data, don't use cached results
121 -
122 - **TODO notes : mkdir -p $(dirname)
123 + readonly -- whether the channel is listen-only (no write methods) or not
124 + defaults to True
125 """
126 - try:
127 - # try to get the ebuild lines before opening the file
128 - line = None
129 - # append newline here or add in _make_export()
130 - lines = [ line + "\n" for line in self.get_ebuild ( force_update ) ]
131 - del line
132 -
133 - fh = open ( file_to_write, 'w' )
134 - fh.writelines ( lines )
135 - fh.close ()
136 -
137 - del lines, fh
138 - return True
139 - except IOError as err:
140 - raise
141 -
142 - # catch failure
143 - return False
144 -
145 - @classmethod
146 - def _make_ebuild_lines ( self, ebuild_content ):
147 - ebuild_export = []
148 - last_line_empty = False
149 - line = None
150 -
151 - # remove repeated newlines ('repoman sez: ...')
152 - for line in ebuild_content:
153 - line = line.rstrip()
154 - if line:
155 - last_line_empty = False
156 - elif not last_line_empty:
157 - last_line_empty = True
158 - else:
159 - continue
160 -
161 - ebuild_export.append ( line )
162 + # <TODO>
163 + return None
164 + #return self.depresolve_main.get_channel()
165
166 - del last_line_empty, line
167 - return ebuild_content
168 + # --- end of get_resolver (...) ---
169
170 + @classmethod
171 + def run ( self ):
172 + """Tells all EbuildJobs to run."""
173 + for job in self.ebuild_jobs:
174 + job.run()
175
176 + @classmethod
177 + def collect_ebuilds ( self ):
178 + """Returns all ebuilds. (They may not be ready / TODO)"""
179 + return [ job.get_ebuild() for job in self.ebuild_jobs ]
180
181 - @staticmethod
182 - def _get_ebuild_header ( ebuild_header_file=None ):
183 + @classmethod
184 + def get_ebuild_header ( self, ebuild_header_file=None ):
185 """Reads and returns the content of an ebuild header file.
186 This is a normal file that can be included in ebuilds.
187 Every header file will only be read on first access, it's content will
188 - be stored in a dict that is shared among all Ebuild instances.
189 + be stored in a dict that is shared among all EbuildCreator instances.
190
191 arguments:
192 - ebuild_header_file -- path to the header file; defaults to none which
193 - means that nothing will be read and an empty list
194 - is returned
195 + * ebuild_header_file -- path to the header file; defaults to none which
196 + means that nothing will be read and an empty list
197 + is returned.
198 """
199 +
200 if ebuild_header_file is None:
201 # nothing to read
202 return []
203
204 - elif (ebuild_header_file in ebuild_headers):
205 + elif ebuild_header_file in self.ebuild_headers:
206 # previously read
207 - return ebuild_headers [ebuild_header_file]
208 + return self.ebuild_headers [ebuild_header_file]
209
210 else:
211 - # do read
212 + # read file
213 try:
214 - fh = open (ebuild_header_file, 'rU')
215 + fh = open ( ebuild_header_file, 'r' )
216 lines = fh.readlines()
217 fh.close()
218 - ebuild_headers [ebuild_header_file] = lines
219 - del lines, fh
220 - return ebuild_headers [ebuild_header_file]
221 + self.ebuild_headers [ebuild_header_file] = lines
222 + del fh
223 + return lines
224
225 except IOError as err:
226 + # todo
227 raise
228
229 - @staticmethod
230 - def _make_var ( varname, value=None, indent_level=0 ):
231 - """Returns a variable definitions that can be used in ebuilds, optionally
232 - with indention.
233 -
234 - arguments:
235 - * varname -- name of the variable (e.g. DEPEND)
236 - * value -- value of the variable; an empty var (DEPEND="") will be returned
237 - if unset (the default)
238 - * indent_level -- indent var definition by indent_level levels
239 - """
240 -
241 - if value:
242 - return indent_level * EBUILD_INDENT + varname + '"' + value + '"'
243 - else:
244 - # empty var
245 - return indent_level * EBUILD_INDENT + varname + '""'
246 -
247 - @classmethod
248 - def _make_export ( self, description_data, ebuild_header=None ):
249 - """Creates ebuild data that can be written into stdout or a file
250 -
251 - arguments:
252 - ebuild_header_file -- path to the header file; defaults to none which
253 - means that nothing will be read and an empty list
254 - is returned
255 - """
256 -
257 - # this method is todo
258 -
259 - if not isinstance (description_data, dict):
260 - #todo
261 - raise Exception ( "bad description data" )
262 -
263 - errors = dict()
264 -
265 - ebuild_content = Ebuild._get_ebuild_header ( ebuild_header )
266 -
267 - # repeated and leading empty lines will be removed later
268 - ebuild_content.append ( "" )
269 -
270 - # the code below this line does not work
271 - return
272 - #raise Exception ( "under construction ..." )
273 -
274 - if self.pkg_file:
275 - ebuild_content.append ( _make_var ( "PKG_FILE" , self.pkg_file ) )
276 - else:
277 - # absense of a pkg source file is an error
278 - errors ['PKG_FILE'] = "missing"
279 -
280 - if self.origin:
281 - ebuild_content.append ( _make_var ( "PKG_ORIGIN", self.origin ) )
282 - else:
283 - errors ['PKG_ORIGIN'] = "missing"
284 -
285 - ebuild_content.append ( "" )
286 -
287 - if self.description:
288 - ebuild_content.append ( _make_var ( "DESCRIPTION", self.TODO ) )
289 - else:
290 - ebuild_content.append ( _make_var ( "DESCRIPTION", "<none>" ) )
291 - #errors ['DESCRIPTION'] = "missing"
292 -
293 - # determine SRC_URI (origin + pkg_file)
294 - if self.pkg_file and self.origin and False:
295 - # SRC_URI ~= <> + origin + pkg_file
296 - ebuild_content.append ( _make_var ( "SRC_URI", "" ) )
297 - else:
298 - # either RESTRICT+=" fetch" or treat missing SRC_URI as critical
299 - errors ['SRC_URI'] = "missing"
300 -
301 - ebuild_content.append ( "" )
302 -
303 - #LICENSE (!!)
304 -
305 - rdepend = '${DEPEND:-} ' + self.rdepend
306 -
307 - # inherit IUSE from eclass
308 - iuse = '${IUSE:-}'
309 -
310 - if self.rsuggests:
311 - iuse += ' R_suggests'
312 - rdepend += ' R_suggests ? ${R_SUGGESTS}'
313 - ebuild_content.append ( _make_var ( "R_SUGGESTS", self.rsuggests ) )
314 -
315 - ebuild_content.append ( _make_var ( "IUSE", iuse ) )
316 - ebuild_content.append ( "" )
317 -
318 - # DEPEND="${DEPEND:-} <pkg dependencies>" to inherit deps from eclass
319 - ebuild_content.append ( _make_var (
320 - "DEPEND", '${DEPEND:-} ' + self.depend ) )
321 -
322 - ebuild_content.append ( _make_var ( "RDEPEND", rdepend ) )
323 -
324 - # (!!) TODO
325 - if errors:
326 - raise Exception ( "^^^missing components for ebuild^^^" )
327 - #return None
328 -
329 - return self._make_ebuild_lines ( ebuild_content )
330 -
331 -class EbuildCreator:
332 -# could move this to Ebuild
333 -
334 - @classmethod
335 - def __init__ ( self, description_data ):
336 - """"Initializes an EbuildCreator.
337 - [todo]
338 - """
339 - self._description_data = description_data
340 -
341 - self._ebuild = None
342 -
343 - @classmethod
344 - def run ( self ):
345 - """Tells this EbuildCreator to operate which produces an Ebuild object
346 - that can later be shown or written into a file.
347 - """
348 - #todo
349 - self._ebuild = None
350 -
351 - if self._description_data is None:
352 - return False
353 -
354 - ebuild = Ebuild()
355 - dref = self._description_data
356 -
357 - ebuild.name = dref ['Package']
358 - ebuild.version = dref ['Version']
359 -
360 - ebuild.origin = "TODO"
361 - ebuild.pkg_file = "TODO"
362 -
363 - # depend rdepend rsuggest
364 - ebuild.depend = "TODO"
365 - ebuild.rdepend = "TODO"
366 - ebuild.suggest = "TODO"
367 -
368 - if 'Description' in dref:
369 - ebuild.description = dref ['Description']
370 - elif 'Title' in dref:
371 - ebuild.description = dref ['Title']
372 - else:
373 - ebuild.description = "<none>"
374 -
375 - # <dep resolution here?>
376 -
377 - ebuild.get_ebuild ( self._description_data )
378 -
379 - # todo
380 - return None
381 -
382 -
383 - @classmethod
384 - def show ( self ):
385 - """Prints the ebuild to stdout/err or into log"""
386 - pass
387 -
388 - @classmethod
389 - def write ( self ):
390 - """Writes the ebuild into a file"""
391 - pass
392 -
393 - @classmethod
394 - def ready ( self ):
395 - """Returns true if an Ebuild has been produced, else false."""
396 - return not (self._ebuild is None)
397 -
398 -
399 -class EbuildFactory:
400 -
401 - @classmethod
402 - def __init__ ( self ):
403 - """Initializes an ebuild factory. This continously produces EbuildCreator
404 - for every get_ebuild_creator ( tarball ) call.
405 - """
406 - self.desc_reader = DescriptionReader()
407 -
408 - @classmethod
409 - def get_ebuild_creator ( self, tarball ):
410 - """Creates and returns an ebuild creator that will handle
411 - the data retrieved from <tarball>.
412 -
413 - arguments:
414 - * tarball -- tarball to read
415 - """
416 - data = self.desc_reader.readfile ( tarball )
417 - if data:
418 - return EbuildCreator ( data )
419 - else:
420 - return None
421 -
422 -
423 + # --- end of get_ebuild_header (...) ---