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: Thu, 31 May 2012 18:24:29
Message-Id: 1338488565.2857235f05980e0ad98351850c1422993305c6e6.dywi@gentoo
1 commit: 2857235f05980e0ad98351850c1422993305c6e6
2 Author: André Erdmann <dywi <AT> mailerd <DOT> de>
3 AuthorDate: Thu May 31 18:22:45 2012 +0000
4 Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
5 CommitDate: Thu May 31 18:22:45 2012 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=2857235f
7
8 roverlay, 2012-05-31:
9 * basic logging
10 ** replaced some errors cases by log entries
11 * started with the config module
12
13 ---
14 roverlay/__init__.py | 19 ++++
15 roverlay/config.py | 60 +++++++++++++
16 roverlay/descriptionfields.py | 121 ++++++++++++++++++++++++++
17 roverlay/ebuild.py | 96 +++++++++++++++------
18 roverlay/ebuildjob.py | 38 ++++++---
19 roverlay/fileio.py | 186 +++++++++++++++++++++--------------------
20 6 files changed, 394 insertions(+), 126 deletions(-)
21
22 diff --git a/roverlay/__init__.py b/roverlay/__init__.py
23 index 863ab2b..b1557ef 100644
24 --- a/roverlay/__init__.py
25 +++ b/roverlay/__init__.py
26 @@ -2,4 +2,23 @@
27 # Copyright 2006-2012 Gentoo Foundation
28 # Distributed under the terms of the GNU General Public License v2
29
30 +import logging
31 +
32 +logging.basicConfig (
33 + level=logging.DEBUG,
34 + filename='roverlay.log',
35 + filemode='a',
36 + format='%(asctime)s %(levelname)-8s %(name)-14s -- %(message)s',
37 + datefmt='%F %H:%M:%S'
38 +)
39 +
40 +# add console output to the logger
41 +ch = logging.StreamHandler()
42 +ch.setLevel ( logging.INFO )
43 +ch.setFormatter (
44 + logging.Formatter ( '%(levelname)-8s %(name)-14s -- %(message)s' )
45 +)
46 +logging.getLogger().addHandler ( ch )
47 +del ch
48 +
49 VERSION = "0.0-pre1"
50
51 diff --git a/roverlay/config.py b/roverlay/config.py
52 new file mode 100644
53 index 0000000..248fc22
54 --- /dev/null
55 +++ b/roverlay/config.py
56 @@ -0,0 +1,60 @@
57 +# R overlay -- config module
58 +# Copyright 2006-2012 Gentoo Foundation
59 +# Distributed under the terms of the GNU General Public License v2
60 +
61 +import sys
62 +
63 +from roverlay import descriptionfields
64 +
65 +try:
66 + import configparser
67 +except ImportError:
68 + import ConfigParser as configparser
69 +
70 +def access():
71 + return ConfigTree() if ConfigTree.instance is None else ConfigTree.instance
72 +
73 +class InitialLogger:
74 +
75 + def __init__ ( self ):
76 + self.debug = lambda x : sys.stderr.write ( "DBG " + str ( x ) + "\n" )
77 + self.info = lambda x : sys.stderr.write ( "INFO " + str ( x ) + "\n" )
78 + self.warning = lambda x : sys.stderr.write ( "WARN " + str ( x ) + "\n" )
79 + self.error = lambda x : sys.stderr.write ( "ERR " + str ( x ) + "\n" )
80 + self.critical = lambda x : sys.stderr.write ( "CRIT " + str ( x ) + "\n" )
81 + self.exception = lambda x : sys.stderr.write ( "EXC! " + str ( x ) + "\n" )
82 +
83 +class ConfigTree:
84 + # static access to the first created ConfigTree
85 + instance = None
86 +
87 + def __init__ ( self ):
88 + if ConfigTree.instance is None:
89 + ConfigTree.instance = self
90 +
91 + self.logger = InitialLogger()
92 +
93 + self.parser = dict()
94 +
95 +
96 + def load_field_definition ( self, def_file, lenient=False ):
97 + if not 'field_def' in self.parser:
98 + self.parser ['field_def'] = configparser.SafeConfigParser ( allow_no_value=True )
99 +
100 + try:
101 + self.logger.debug ( "Reading description field definition file " + def_file + "." )
102 + if lenient:
103 + self.parser ['field_def'] . read ( def_file )
104 + else:
105 + fh = open ( def_file, 'r' )
106 + self.parser ['field_def'] . readfp ( fh )
107 + if fh:
108 + fh.close()
109 + except IOError as err:
110 + self.logger.exception ( err )
111 + raise
112 + except configparser.MissingSectionHeaderError as mshe:
113 + self.logger.exception ( mshe )
114 + raise
115 +
116 +
117
118 diff --git a/roverlay/descriptionfields.py b/roverlay/descriptionfields.py
119 new file mode 100644
120 index 0000000..9c028c2
121 --- /dev/null
122 +++ b/roverlay/descriptionfields.py
123 @@ -0,0 +1,121 @@
124 +# R overlay -- description fields
125 +# Copyright 2006-2012 Gentoo Foundation
126 +# Distributed under the terms of the GNU General Public License v2
127 +
128 +
129 +# split from tmpconst / fileio to make configuration possible, but TODO
130 +
131 +class DescriptionField:
132 +
133 + def __init__ ( self, name ):
134 + if not name:
135 + raise Exception ( "description field name is empty." )
136 +
137 + self.name = name
138 +
139 +
140 +
141 + def get_name ( self ):
142 + return self.name
143 +
144 + def add_flag ( self, flag, lowercase=True ):
145 + if not hasattr ( self, flags ):
146 + self.flags = set ()
147 +
148 + self.flags.add ( flag, flag.lower() if lowercase else flag )
149 +
150 + return None
151 +
152 +
153 + def del_flag ( self, flag ):
154 + if hasattr ( self, flags ):
155 + self.flags.discard ( flag )
156 + return None
157 +
158 +
159 + def add_alias ( self, alias, alias_type='withcase' ):
160 + if not hasattr ( self, aliases ):
161 + self.aliases = dict ()
162 +
163 + to_add = dict (
164 + withcase = alias,
165 + nocase = alias.lower(),
166 + ) [alias_type]
167 +
168 +
169 + if not alias_type in self.aliases:
170 + self.aliases [alias_type] = set ()
171 +
172 + self.aliases [alias_type] . add ( to_add )
173 +
174 + return None
175 +
176 +
177 +
178 + def add_simple_alias ( self, alias, withcase=True ):
179 + if withcase:
180 + return self.add_alias ( alias, alias_type='withcase' )
181 + else:
182 + return self.add_alias ( alias, alias_type='nocase' )
183 +
184 +
185 +
186 + def get_default_value ( self ):
187 + if hasattr ( self, 'default_value' ):
188 + return self.default_value
189 + else:
190 + return None
191 +
192 +
193 + def get ( self, key, fallback_value=None ):
194 + if hasattr ( self, key ):
195 + return self.key
196 + else:
197 + return fallback_value
198 +
199 + def matches ( self, field_identifier ):
200 + return bool ( self.name == field_identifier ) if field_identifier else False
201 +
202 + def matches_alias ( self, field_identifier ):
203 +
204 + if not field_identifier:
205 + return False
206 + if not hasattr ( self, aliases ):
207 + return False
208 +
209 + if 'withcase' in self.aliases:
210 + if field_identifier in self.aliases ['withcase']:
211 + return True
212 +
213 + if 'nocase' in self.aliases:
214 + field_id_lower = field_identifier.lower()
215 + if field_id_lower in self.aliases ['nocase']:
216 + return True
217 +
218 + def has_flag ( self, flag, lowercase=True ):
219 + if not hasattr ( self, flags ):
220 + return False
221 +
222 + return bool ( (flag.lower() if lowercase else flag) in self.flags )
223 +
224 +class DescriptionFields:
225 +
226 + def __init__ ( self ):
227 + fields = dict ()
228 +
229 + def add ( self, desc_field ):
230 + if desc_field:
231 + if isinstance ( desc_field, DescriptionField ):
232 + fields [desc_field.get_name()] = desc_field
233 + return 1
234 + elif isinstance ( desc_field, str ):
235 + fields [desc_field] = DescriptionField ( desc_field )
236 + return 2
237 +
238 + return 0
239 +
240 + def get ( self, field_name ):
241 + return self.fields [field_name] if field_name in self.fields else None
242 +
243 + # ... TODO
244 +
245
246 diff --git a/roverlay/ebuild.py b/roverlay/ebuild.py
247 index 8c960a2..1634ef3 100644
248 --- a/roverlay/ebuild.py
249 +++ b/roverlay/ebuild.py
250 @@ -6,16 +6,31 @@ class Ebuild:
251 # could move this to const
252 EBUILD_INDENT = "\t"
253
254 - def __init__ ( self ):
255 + ADD_REMAP = {
256 + # pkg vs package
257 + 'package_name' : 'pkg_name',
258 + 'package_version' : 'pkg_version',
259 + 'package_revision' : 'pkg_revision',
260 + # TITLE is in DESCRIPTION
261 + 'TITLE' : 'DESCRIPTION',
262 + }
263 +
264 + def __init__ ( self, logger ):
265 """Initializes an Ebuild.
266 This is an abstraction layer between the verified + calculated data
267 and the ebuild data, which can be written into a file / stdout / stdin.
268 Most functions here assume that everything is fine when it reaches them.
269 +
270 + arguments:
271 + * logger -- logger for this Ebuild
272 """
273
274 + self.logger = logger
275 +
276 # elements in ebuild_data are either a str or a list of str
277 self._data = dict ()
278 self._ebuild_lines = None
279 + self._ebuild_name = None
280
281 # --- end of __init__ (...) ---
282
283 @@ -24,6 +39,8 @@ class Ebuild:
284 This saves some memory but makes this Ebuild read-only.
285 """
286 if self._ebuild_lines:
287 + # determine the ebuild name first
288 + self._ebuild_name = self.suggest_name()
289 del self._data
290 self._data = None
291
292 @@ -56,12 +73,18 @@ class Ebuild:
293
294 # --- end of prepare (...) ---
295
296 + def has_ebuild ( self ):
297 + """Returns True if this object has ebuild text lines else False."""
298 + return bool ( self._ebuild_lines )
299 + # --- end of has_ebuild (...) ---
300 +
301 def add ( self, key, value, append=True ):
302 """Adds data to this Ebuild.
303
304 arguments:
305 * key -- identifier of the data (e.g. DEPEND).
306 - May be remapped here (e.g. merging 'Title' and 'Description')
307 + May be remapped (e.g. merging 'Title' and 'Description')
308 + or even refused here
309 * value --
310 * append -- whether to append values or overwrite existing ones,
311 defaults to True.
312 @@ -72,17 +95,22 @@ class Ebuild:
313 # -- todo
314 raise Exception ("Ebuild data are readonly.")
315
316 - if append and key in self._data:
317 - if not isinstance ( self._data [key], list ):
318 - self._data [key] = [ self._data [key] ]
319 -
320 - if isinstance ( value, list ):
321 - self._data [key].extend ( value )
322 - else:
323 - self._data [key].append ( value )
324 + _key = Ebuild.ADD_REMAP [key] if key in Ebuild.ADD_REMAP else key
325
326 + if _key is None:
327 + self.logger.debug ( "add (%s, %s): filtered key.", key, str ( value ) )
328 else:
329 - self._data [key] = value
330 + if append and _key in self._data:
331 + if not isinstance ( self._data [_key], list ):
332 + self._data [_key] = [ self._data [_key] ]
333 +
334 + if isinstance ( value, list ):
335 + self._data [_key].extend ( value )
336 + else:
337 + self._data [_key].append ( value )
338 +
339 + else:
340 + self._data [_key] = value
341
342 # --- end of add (...) ---
343
344 @@ -99,14 +127,12 @@ class Ebuild:
345 self.show ( fh )
346 fh.close()
347 del fh
348 - return True
349 except IOError as err:
350 - # ? todo
351 + self.logger.exception ( err )
352 raise
353
354 else:
355 - # todo log this
356 - raise Exception ("cannot write ebuild")
357 + self.logger.warning ( "Cannot write ebuild - it's empty! (check with has_ebuild() before calling this method.)" )
358
359 # --- end of write (...) ---
360
361 @@ -128,20 +154,39 @@ class Ebuild:
362
363 # --- end of show (...) ---
364
365 - def suggest_name ( self, fallback_name=None ):
366 + def suggest_dir_name ( self ):
367 + """Suggests a direcory name for this Ebuild."""
368 + return self._data ['pkg_name'] if 'pkg_name' in self._data else self.suggest_name().partition ( '-' )
369 + # --- end of suggest_dir_name (...) ---
370 +
371 + def suggest_name ( self, fallback_name='' ):
372 """Suggests a file name for the ebuild. This is calculated using
373 pkg_name/version/revision. Returns a fallback_name if this is not
374 possible.
375
376 arguments:
377 - fallback_name -- name to return if no suggestion available, defaults to None
378 + fallback_name -- name to return if no suggestion available, defaults to empty string
379 """
380
381 - if 'pkg_name' in self._data and 'pkg_version' in self._data:
382 - join = [ 'pkg_name' , 'pkg_version' ]
383 - if 'pkg_revision' in self._data: join.append ('pkg_revision')
384 + if self._ebuild_name:
385 + return self._ebuild_name
386 + elif (not self._data is None) and 'pkg_name' in self._data:
387 + name_components = [ self._data ['pkg_name'] ]
388 +
389 + if 'pkg_version' in self._data:
390 + name_components.append ( self._data ['pkg_version'] )
391 + else:
392 + # default ver
393 + name_components.append ( '1.0' )
394 +
395 + if 'pkg_revision' in self._data:
396 + rev = self._data ['pkg_revision']
397 +
398 + # omit rev == 0 and invalid revisions
399 + if isinstance ( rev, int ) and rev > 0:
400 + name_components.append ( 'r' + rev )
401
402 - return '-' . join ( [ self._data [c] for c in join ] )
403 + return '-'.join ( name_components )
404
405 else:
406 return fallback_name
407 @@ -316,7 +361,7 @@ class Ebuild:
408 if 'SRC_URI' in self._data:
409 add_easyvar ( ebuild_lines, "SRC_URI" )
410 else:
411 - # > calculate SRC_URI using self._data ['origin']
412 + # > calculate SRC_URI using self._data ['origin'] -- either here or in eclass
413 ebuild_lines.append ( make_var ( "SRC_URI" , None ) )
414 # (temporary, todo) setting restrict to fetch
415 ebuild_lines.append ( make_var ( "RESTRICT" , "fetch" ) )
416 @@ -345,9 +390,8 @@ class Ebuild:
417 del dep_and_use
418 return remove_newlines ( ebuild_lines )
419
420 - except Exception as err:
421 - # log this
422 - ## ..
423 - raise
424 + except ( ValueError, KeyError, NameError ) as err:
425 + self.logger.error ( "Cannot create ebuild text lines. The error message was %s.", str ( err ) )
426 + return None
427
428 # --- end of make_ebuild_lines (...) ---
429
430 diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py
431 index 2d29643..0357e77 100644
432 --- a/roverlay/ebuildjob.py
433 +++ b/roverlay/ebuildjob.py
434 @@ -3,11 +3,15 @@
435 # Distributed under the terms of the GNU General Public License v2
436
437 import time
438 +import logging
439 +import re
440
441 from roverlay.fileio import DescriptionReader
442 from roverlay.ebuild import Ebuild
443
444 class EbuildJob:
445 + LOGGER = logging.getLogger ( 'EbuildJob' )
446 +
447 # move this to const / config
448 DEPENDENCY_FIELDS = {
449 'R_SUGGESTS' : [ 'Suggests' ],
450 @@ -43,10 +47,12 @@ class EbuildJob:
451 dep resolver 'communication channel', status codes etc.
452 """
453
454 - self.package_file = package_file
455 + #self.package_file = package_file
456 self.dep_resolver = dep_resolver
457 # get description reader from args?
458 - self.description_reader = DescriptionReader()
459 + self.description_reader = DescriptionReader ( package_file )
460 +
461 + self.logger = EbuildJob.LOGGER.getChild ( self.description_reader.get_log_name () )
462
463 self.ebuild = None
464
465 @@ -92,23 +98,29 @@ class EbuildJob:
466 """
467
468 # TODO move hardcoded entries to config/const
469 + # TODO metadata.xml creation
470
471 try:
472
473 # set status or return
474 if not self._set_status ( 'BUSY', True ): return
475
476 - read_data = self.description_reader.readfile ( self.package_file )
477 -
478 - if read_data is None:
479 - # set status accordingly
480 + desc = self.description_reader.get_desc ( True )
481 + if desc is None:
482 self._set_status ( 'FAIL' )
483 - return
484 + self.logger.info ( 'Cannot create an ebuild for this package.' )
485 +
486
487 - fileinfo = read_data ['fileinfo']
488 - desc = read_data ['description_data']
489 + fileinfo = self.description_reader.get_fileinfo ()
490 +
491 + ebuild = Ebuild ( self.logger.getChild ( "Ebuild" ) )
492 +
493 + ebuild.add ( 'pkg_name', fileinfo ['package_name'] )
494 + # TODO move regex to config/const
495 + ebuild.add ( 'pkg_version',
496 + re.sub ( '[-]{1,}', '.', fileinfo ['package_version'] )
497 + )
498
499 - ebuild = Ebuild()
500
501 have_description = False
502
503 @@ -216,7 +228,7 @@ class EbuildJob:
504
505 except Exception as any_exception:
506 # any exception means failure
507 - self.status = 'FAIL'
508 + self._set_status ( 'FAIL' )
509 raise
510
511 # --- end of run (...) ---
512 @@ -231,15 +243,19 @@ class EbuildJob:
513
514 if new_status == 'FAIL':
515 # always allowed
516 + self.logger.info ( "Entering status '%s'.", new_status )
517 self.status = new_status
518 + return True
519
520 if new_status and new_status in EbuildJob.STATUS_LIST:
521 # check if jumping from self.status to new_status is allowed
522 if new_status in EbuildJob.STATUS_BRANCHMAP [self.status]:
523 + self.logger.debug ( "Entering status '%s'.", new_status )
524 self.status = new_status
525 return True
526
527 # default return
528 + self.logger.error ( "Cannot enter status '%s'.", new_status )
529 return False
530
531 # --- end of _set_status (...) ---
532
533 diff --git a/roverlay/fileio.py b/roverlay/fileio.py
534 index 7c89356..5c01527 100644
535 --- a/roverlay/fileio.py
536 +++ b/roverlay/fileio.py
537 @@ -3,11 +3,10 @@
538 # Distributed under the terms of the GNU General Public License v2
539
540 import re
541 -import os.path
542 import tarfile
543 +import logging
544 +import os.path
545
546 -# temporary import until logging is implemented
547 -from sys import stderr as logging
548
549 # temporary import until config and real constants are implemented
550 from roverlay import tmpconst as const
551 @@ -15,12 +14,70 @@ from roverlay import tmpconst as const
552 class DescriptionReader:
553 """Description Reader"""
554
555 - def __init__ ( self ):
556 + LOGGER = logging.getLogger ( 'DescriptionReader' )
557 +
558 + def __init__ ( self, package_file, read_now=False ):
559 """Initializes a DESCRIPTION file reader."""
560 - pass
561 +
562 + self.fileinfo = self.make_fileinfo ( package_file )
563 + self.logger = DescriptionReader.LOGGER.getChild ( self.get_log_name() )
564 + self.desc_data = None
565 +
566 +
567 + if read_now:
568 + self.run()
569
570 # --- end of __init__ (...) ---
571
572 + def get_log_name ( self ):
573 + try:
574 + return self.fileinfo ['filename']
575 + except Exception as any_exception:
576 + return '__undef__'
577 +
578 + def get_desc ( self, run_if_unset=True ):
579 + if self.desc_data is None:
580 + self.run ()
581 +
582 + return self.desc_data
583 + # --- end of get_desc (...) ---
584 +
585 + def get_fileinfo ( self ):
586 + return self.fileinfo
587 + # --- end of get_fileinfo (...) ---
588 +
589 + def make_fileinfo ( self, filepath ):
590 + """Returns some info about the given filepath as dict whose contents are
591 + the file path, the file name ([as package_file with suffix and]
592 + as filename with tarball suffix removed), the package name
593 + and the package_version.
594 +
595 + arguments:
596 + * filepath --
597 + """
598 +
599 + package_file = os.path.basename ( filepath )
600 +
601 + filename = re.sub ( const.RPACKAGE_SUFFIX_REGEX + '$', '', package_file )
602 +
603 + # todo move that separator to const
604 + package_name, sepa, package_version = filename.partition ( '_' )
605 +
606 + if not sepa:
607 + # file name unexpected, tarball extraction will (probably) fail
608 + DescriptionReader.LOGGER.error ( "unexpected file name %s.'", filename )
609 +
610 + return dict (
611 + filepath = filepath,
612 + filename = filename,
613 + package_file = package_file,
614 + package_name = package_name,
615 + #package_origin = ?,
616 + package_version = package_version,
617 + )
618 +
619 + # --- end of make_fileinfo (...) ---
620 +
621
622 def _parse_read_data ( self, read_data ):
623 """Verifies and parses/fixes read data.
624 @@ -91,44 +148,31 @@ class DescriptionReader:
625
626
627 # check for fields that allow only certain values
628 - unsuitable_fields = list()
629 + unsuitable_fields = dict()
630
631 for field in read_data.keys():
632 - # skip _fileinfo
633 - if field != '_fileinfo':
634 - if 'allowed_values' in const.DESCRIPTION_FIELD_MAP [field]:
635 - if not value_in_strlist ( read_data [field],
636 - const.DESCRIPTION_FIELD_MAP [field] ['allowed_values']
637 - ): unsuitable_fields.append ( field )
638 + if 'allowed_values' in const.DESCRIPTION_FIELD_MAP [field]:
639 + if not value_in_strlist (
640 + read_data [field],
641 + const.DESCRIPTION_FIELD_MAP [field] ['allowed_values']
642 + ):
643 + unsuitable_fields.append [field] = read_data [field]
644
645 - valid = True
646 -
647 - if len ( missing_fields ):
648 - valid = False
649 -
650 - logging.write (
651 - "Verification of mandatory fields failed, the result leading to this was: " +
652 - str ( missing_fields ) + "\n"
653 - )
654 -
655 - #<raise custom exception>
656 - raise Exception ("^^^look above")
657 -
658 - if len ( unsuitable_fields ):
659 - valid = False
660 -
661 - logging.write (
662 - "Some fields have values that forbid further parsing, the result leading to this was: " +
663 - str ( unsuitable_fields ) + "\n"
664 - )
665 -
666 - del missing_fields
667 del field
668
669 + valid = not bool ( len ( missing_fields ) or len ( unsuitable_fields ) )
670 + if not valid:
671 + self.logger.info ( "Cannot use R package" ) # name?
672 + if len ( missing_fields ):
673 + self.logger.debug ( "The following mandatory description fields are missing: %s.", str ( missing_fields ) )
674 + if len ( unsuitable_fields ):
675 + self.logger.debug ( "The following fields have unsuitable values: %s.", str ( unsuitable_fields ) )
676 +
677 return valid
678 +
679 # --- end of _parse_read_data (...) ---
680
681 - def readfile ( self, filepath ):
682 + def run ( self ):
683 """Reads a DESCRIPTION file and returns the read data if successful, else None.
684
685 arguments:
686 @@ -145,40 +189,6 @@ class DescriptionReader:
687 e.g. if OS_TYPE is not unix).
688 """
689
690 - def get_fileinfo ( filepath ):
691 - """Returns some info about the given filepath as dict whose contents are
692 - the file path, the file name ([as package_file with suffix and]
693 - as filename with tarball suffix removed), the package name
694 - and the package_version.
695 -
696 - arguments:
697 - * filepath --
698 - """
699 -
700 - package_file = os.path.basename ( filepath )
701 -
702 - filename = re.sub ( const.RPACKAGE_SUFFIX_REGEX + '$', '', package_file )
703 -
704 - # todo move that separator to const
705 - package_name, sepa, package_version = filename.partition ( '_' )
706 -
707 - if not sepa:
708 - # file name unexpected, tarball extraction will (probably) fail
709 - #raise Exception ("file name unexpected")
710 - logging.write ( "unexpected file name '" + filename + "'.\n" )
711 -
712 - return dict (
713 - filepath = filepath,
714 - filename = filename,
715 - package_file = package_file,
716 - package_name = package_name,
717 - #package_origin = ?,
718 - package_version = package_version,
719 - )
720 -
721 - # --- end of get_fileinfo (...) ---
722 -
723 -
724 def make_values ( value_str, field_context=None ):
725 """Extracts relevant data from value_str and returns them as list.
726
727 @@ -252,7 +262,7 @@ class DescriptionReader:
728 file is read (<pkg_name>/DESCRIPTION) or a normal file.
729 """
730
731 - logging.write ( "Starting to read file '" + str ( filepath ) + "' ...\n" )
732 + self.logger.debug ( "Starting to read file '" + str ( filepath ) + "' ...\n" )
733
734 if not ( isinstance ( filepath, str ) and filepath ):
735 raise Exception ( "bad usage" )
736 @@ -338,16 +348,19 @@ class DescriptionReader:
737 # --- end of find_field (...) ---
738
739
740 + self.desc_data = None
741 read_data = dict ()
742 - fileinfo = get_fileinfo ( filepath )
743
744
745 try:
746 - desc_lines = get_desc_from_file ( filepath, fileinfo ['package_name'] )
747 + desc_lines = get_desc_from_file (
748 + self.fileinfo ['filepath'],
749 + self.fileinfo ['package_name']
750 + )
751
752 except IOError as err:
753 - # <todo>
754 - raise
755 + self.logger.exception ( err )
756 + return self.desc_data
757
758
759 field_context = val = line = sline = None
760 @@ -393,18 +406,15 @@ class DescriptionReader:
761
762 else:
763 # useless line, skip
764 - logging.write (
765 - "Skipping a line, first line component (field identifier?) was: '"
766 - + line_components [0] + "'\n"
767 - )
768 + self.logger.info ( "Skipped a description field: '%s'.", line_components [0] )
769
770 else:
771 # reaching this branch means that
772 # (a) line has no leading whitespace
773 # (b) line has no separator (:)
774 # this should not occur in description files (bad syntax?)
775 - logging.write ( "***" + line_components [0] + "***\n")
776 - raise Exception ( "bad file" )
777 + self.logger.warning ( "Unexpected line in description file: '%s'.", line_components [0] )
778 +
779
780 del line_components
781
782 @@ -412,14 +422,12 @@ class DescriptionReader:
783
784
785 if self._parse_read_data ( read_data ):
786 - #logging.write ( '## success ##\n' )
787 - #logging.write ( ( str ( read_data ) ) )
788 - return dict (
789 - fileinfo = fileinfo,
790 - description_data = read_data
791 - )
792 - else:
793 - logging.write ( '## fail ##\n' )
794 - return None
795 + self.logger.debug ( "Successfully read file '%s' with data = %s.",
796 + self.fileinfo ['filepath'], str ( read_data )
797 + )
798 + self.desc_data = read_data
799 +
800 + # get_desc() is preferred, but this method returns the desc data, too
801 + return self.desc_data
802
803 # --- end of readfile (...) ---