From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1SeUiu-0006DO-Um for garchives@archives.gentoo.org; Tue, 12 Jun 2012 17:17:45 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id E2E43E050E; Tue, 12 Jun 2012 17:17:27 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id 913DFE050E for ; Tue, 12 Jun 2012 17:17:27 +0000 (UTC) Received: from hornbill.gentoo.org (hornbill.gentoo.org [94.100.119.163]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id B5A6F1B4032 for ; Tue, 12 Jun 2012 17:17:26 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by hornbill.gentoo.org (Postfix) with ESMTP id 73786E5435 for ; Tue, 12 Jun 2012 17:17:25 +0000 (UTC) From: "André Erdmann" To: gentoo-commits@lists.gentoo.org Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "André Erdmann" Message-ID: <1339521194.4ceeb302c882e6cb9e18c4cda2896078eff91783.dywi@gentoo> Subject: [gentoo-commits] proj/R_overlay:master commit in: roverlay/ X-VCS-Repository: proj/R_overlay X-VCS-Files: roverlay/__init__.py roverlay/config.py roverlay/const.py roverlay/descriptionreader.py roverlay/ebuildcreator.py roverlay/ebuildjob.py roverlay/util.py X-VCS-Directories: roverlay/ X-VCS-Committer: dywi X-VCS-Committer-Name: André Erdmann X-VCS-Revision: 4ceeb302c882e6cb9e18c4cda2896078eff91783 X-VCS-Branch: master Date: Tue, 12 Jun 2012 17:17:25 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: quoted-printable X-Archives-Salt: 6f99d0c8-15bf-40c8-9df0-f43fbecf8fef X-Archives-Hash: bb50e770d1979759d25aac709b98f170 commit: 4ceeb302c882e6cb9e18c4cda2896078eff91783 Author: Andr=C3=A9 Erdmann mailerd de> AuthorDate: Tue Jun 12 17:13:14 2012 +0000 Commit: Andr=C3=A9 Erdmann mailerd de> CommitDate: Tue Jun 12 17:13:14 2012 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=3Dproj/R_overlay.git= ;a=3Dcommit;h=3D4ceeb302 roverlay * moved get_packageinfo to util.py 'cause it'll be used for metadata crea= tion * misc fixes * added value_type regex to config.py * use depres changes, cancel ebuild creation earlier when deps are unreso= lved modified: roverlay/__init__.py modified: roverlay/config.py modified: roverlay/const.py modified: roverlay/descriptionreader.py modified: roverlay/ebuildcreator.py modified: roverlay/ebuildjob.py new file: roverlay/util.py --- roverlay/__init__.py | 2 +- roverlay/config.py | 110 +++++++++++++++++++++++++----------= ------ roverlay/const.py | 17 +++--- roverlay/descriptionreader.py | 63 +++-------------------- roverlay/ebuildcreator.py | 23 +++++---- roverlay/ebuildjob.py | 87 ++++++++++++++++++-------------- roverlay/util.py | 48 ++++++++++++++++++ 7 files changed, 196 insertions(+), 154 deletions(-) diff --git a/roverlay/__init__.py b/roverlay/__init__.py index 2dab8ad..9ff69f7 100644 --- a/roverlay/__init__.py +++ b/roverlay/__init__.py @@ -4,7 +4,6 @@ =20 import logging =20 - from roverlay import config =20 config.access().load_config ( 'R-overlay.conf' ) @@ -18,6 +17,7 @@ logging.basicConfig ( datefmt=3D'%F %H:%M:%S' ) =20 + # add console output to the logger ch =3D logging.StreamHandler() ch.setLevel ( logging.INFO ) diff --git a/roverlay/config.py b/roverlay/config.py index 8cd99e3..6e5c433 100644 --- a/roverlay/config.py +++ b/roverlay/config.py @@ -82,6 +82,7 @@ class ConfigTree ( object ): # ** fs_path -- ~ will be expanded # ** fs_dir -- fs_path and value must be a dir if it exists # ** fs_file -- fs_path and value must be a file if it exists + # ** regex -- value is a regex and will be compiled (re.compile(..)) # # multiple types are generally not supported ('this is an int or a st= r'), # but subtypes are (list of yesno), which can be specified by either @@ -114,7 +115,6 @@ class ConfigTree ( object ): distfiles_dir =3D dict ( value_type =3D 'fs_dir', ), - ) =20 # often used regexes @@ -123,9 +123,9 @@ class ConfigTree ( object ): =20 =20 def __init__ ( self, import_const=3DTrue ): - """Initializes an ConfigTree, which is a container for options/config = values. - values can be stored directly (such as the field_definitions) or in a - tree-like { section -> subsection[s] -> option =3D value } structure. + """Initializes an ConfigTree, which is a container for options/values. + Values can be stored directly (such as the field_definitions) or + in a tree-like { section -> subsection[s] -> option =3D value } struct= ure. Config keys cannot contain dots because they're used as config path separator. =20 @@ -153,11 +153,13 @@ class ConfigTree ( object ): value to it. =20 arguments: - * path -- config path as path list ([a,b,c]) or as path str (a.b.c) - * root -- config root (dict expected). Uses self._config if None (the = default) + * path -- config path as path list ([a,b,c]) or as path str (a.b.c) + * root -- config root (dict expected). + Uses self._config if None (the default) * create -- create path if nonexistent - * value -- assign value to the last path element - an empty dict will be created if this is None and create is= True + * value -- assign value to the last path element + an empty dict will be created if this is None and + create is True """ if path is None: return root @@ -169,7 +171,10 @@ class ConfigTree ( object ): for k in path: if not k in config_position: if create: - config_position [k] =3D value if k =3D=3D path [-1] and value else = dict () + if k =3D=3D path [-1] and not value is None: + config_position [k] =3D value + else: + config_position [k] =3D dict() else: return None =20 @@ -206,8 +211,8 @@ class ConfigTree ( object ): """Adds an option to the config. =20 arguments: - * option -- name of the option as it appears in the (main) config file - * value -- value to assign, defaults to None + * option -- name of the option as it appears in the config file + * value -- value to assign, defaults to None * config_root -- root of the config (a dict), defaults to None which i= s later understood as self._config """ @@ -217,8 +222,9 @@ class ConfigTree ( object ): in the ConfigTree. =20 arguments: - * value_type -- type of the value, look above for explanation concern= ing this - * value -- value to verify and transform + * value_type -- type of the value, + look above for explanation concerning this + * value -- value to verify and transform * entryconfig_ref -- reference to the config entry config """ =20 @@ -269,8 +275,8 @@ class ConfigTree ( object ): # --- end of fs_path (...) --- =20 def fs_file ( val ): - """"val is a file - returns expanded path if it is an existent - file or it does not exist. + """"val is a file - returns expanded path if it is + an existent file or it does not exist. =20 arguments: * val -- @@ -284,8 +290,8 @@ class ConfigTree ( object ): # --- end of fs_file (...) --- =20 def fs_dir ( val ): - """val is a directory -- returns expanded path if it is an existent - dir or it does not exist. + """val is a directory -- returns expanded path if it is + an existent dir or it does not exist. =20 arguments: * val -- @@ -298,6 +304,15 @@ class ConfigTree ( object ): return None # --- end of fs_dir (...) --- =20 + def _regex ( val ): + """val is a regex -- compile it if possible + + arguments: + * val -- + """ + return re.compile ( val ) if not val is None else None + # --- end of _regex (...) --- + # replace whitespace with a single ' ' value =3D ConfigTree.WHITESPACE.sub ( ' ', value ) =20 @@ -320,10 +335,12 @@ class ConfigTree ( object ): 'int' : to_int, 'fs_path' : fs_path, 'fs_file' : fs_file, + 'regex' : _regex, } =20 # dofunc ( function f, v) calls f(x) for every str in v - dofunc =3D lambda f, v : [ f(x) for x in v ] if isinstance ( v, list = ) else f(v) + dofunc =3D lambda f, v : [ f(x) for x in v ] \ + if isinstance ( v, list ) else f(v) =20 retval =3D value =20 @@ -349,7 +366,9 @@ class ConfigTree ( object ): # check if cref is a link to another entry in CONFIG_ENTRY_MAP while isinstance ( cref, str ) and cref !=3D '': if cref =3D=3D original_cref and cref_level: - self.logger.critical ( "CONFIG_ENTRY_MAP is invalid! circular cref = detected." ) + self.logger.critical ( + "CONFIG_ENTRY_MAP is invalid! circular cref detected." + ) raise Exception ( "CONFIG_ENTRY_MAP is invalid!" ) =20 elif cref in ConfigTree.CONFIG_ENTRY_MAP: @@ -357,10 +376,9 @@ class ConfigTree ( object ): cref =3D ConfigTree.CONFIG_ENTRY_MAP [cref] cref_level +=3D 1 else: - # TODO %s self.logger.critical ( - "CONFIG_ENTRY_MAP is invalid! last cref =3D " + option + - ", current cref =3D " + cref + "." + 'CONFIG_ENTRY_MAP is invalid! ' + 'last cref =3D %s, current cref =3D %s.' % ( option, cref ) ) raise Exception ( "CONFIG_ENTRY_MAP is invalid!" ) =20 @@ -384,15 +402,16 @@ class ConfigTree ( object ): =20 # verify and convert value if value_type is set if 'value_type' in cref: - value =3D make_and_verify_value ( cref ['value_type'], value, cref = ) + value =3D make_and_verify_value ( + cref ['value_type'], value, cref + ) =20 # need a valid value if value: =20 self.logger.debug ( - "New config entry " + str ( option ) + - " with path " + str ( path ) + - " and value " + str ( value ) + "." + "New config entry %s with path %s and value %s." % + ( option, path, value ) ) =20 # add option/value to the config @@ -401,17 +420,17 @@ class ConfigTree ( object ): return True else: self.logger.error ( - "Option '" + str ( real_option ) + - "' has an unusable value '" + str ( value ) + "'." + "Option '%s' has an unusable value '%s'." % + ( real_option, value ) ) return False # --- =20 - self.logger.error ( "Option '" + str ( real_option ) + "' is unusable= ..." ) + self.logger.error ( "Option '%s' is unusable..." % real_option ) return False # --- =20 - self.logger.warning ( "Option '" + str ( real_option ) + "' is unknown= ." ) + self.logger.warning ( "Option '%s' is unknown." % real_option ) return False =20 # --- end of _add_entry (...) --- @@ -450,9 +469,10 @@ class ConfigTree ( object ): if equal =3D=3D '=3D': self._add_entry ( option, value, config_root ) else: + self.logger.warning ( - "In '" + config_file + "', cannot parse this line: '" + - str ( option ) + str ( equal ) + str ( value ) + "'." + "In '%s', cannot parse this line: '%s%s%s'." % + ( config_file, option, equal, value ) ) =20 option, equal, value =3D nextline () @@ -466,25 +486,30 @@ class ConfigTree ( object ): # --- end of load_config (...) --- =20 def load_field_definition ( self, def_file, lenient=3DFalse ): - """Loads a field definition file. Please see the example file for form= at - details. + """Loads a field definition file. + Please see the example file for format details. =20 arguments: - * def_file -- file (str) to read, this can be a list of str if lenient= is True - * lenient -- if True: do not fail if a file cannot be read; defaults = to False + * def_file -- file (str) to read, + this can be a list of str if lenient is True + * lenient -- if True: do not fail if a file cannot be read; + defaults to False """ if not 'field_def' in self.parser: - self.parser ['field_def'] =3D configparser.SafeConfigParser ( allow_n= o_value=3DTrue ) + self.parser ['field_def'] =3D \ + configparser.SafeConfigParser ( allow_no_value=3DTrue ) =20 try: - self.logger.debug ( "Reading description field definition file " + de= f_file + "." ) + self.logger.debug ( + "Reading description field definition file %s." % def_file + ) if lenient: self.parser ['field_def'] . read ( def_file ) else: fh =3D open ( def_file, 'r' ) self.parser ['field_def'] . readfp ( fh ) - if fh: - fh.close() + + if fh: fh.close() except IOError as err: self.logger.exception ( err ) raise @@ -521,14 +546,13 @@ class ConfigTree ( object ): l =3D value_str.split ( ', ' ) return [ e for e in l if e.strip() ] =20 - if not 'field_def' in self.parser: - return None + if not 'field_def' in self.parser: return None =20 fdef =3D descriptionfields.DescriptionFields () =20 for field_name in self.parser ['field_def'].sections(): field =3D descriptionfields.DescriptionField ( field_name ) - for option, value in self.parser ['field_def'].items ( field_name, 1 = ): + for option, value in self.parser ['field_def'].items( field_name, 1 )= : =20 if option =3D=3D 'alias' or option =3D=3D 'alias_withcase': for alias in get_list ( value ): diff --git a/roverlay/const.py b/roverlay/const.py index 32a7e89..7ab1891 100644 --- a/roverlay/const.py +++ b/roverlay/const.py @@ -18,14 +18,15 @@ _CONSTANTS =3D dict ( ), EBUILD =3D dict ( indent =3D '\t', - default_header =3D [ '# Copyright 1999-' + str ( time.gmtime() [0] ) += ' Gentoo Foundation', - '# Distributed under the terms of the GNU General Public Licens= e v2', - '# $Header: $', - '', - 'EAPI=3D4', - '', - 'inherit R-packages' - ], + default_header =3D [ + '# Copyright 1999-%i Gentoo Foundation' % ( time.gmtime() [0] ), + '# Distributed under the terms of the GNU General Public License v2', + '# $Header: $', + '', + 'EAPI=3D4', + '', + 'inherit R-packages' + ], ) ) =20 diff --git a/roverlay/descriptionreader.py b/roverlay/descriptionreader.p= y index ad70239..01eb92a 100644 --- a/roverlay/descriptionreader.py +++ b/roverlay/descriptionreader.py @@ -13,18 +13,20 @@ from roverlay import descriptionfields class DescriptionReader ( object ): """Description Reader""" =20 - LOGGER =3D logging.getLogger ( 'DescriptionReader' ) + #LOGGER =3D logging.getLogger ( 'DescriptionReader' ) =20 =20 - def __init__ ( self, package_file, read_now=3DFalse ): + def __init__ ( self, package_info, logger, read_now=3DFalse ): """Initializes a DESCRIPTION file reader.""" =20 if not config.access().get_field_definition(): - raise Exception ( "Field definition is missing, cannot initialize Des= criptionReader." ) + raise Exception ( + "Field definition is missing, cannot initialize DescriptionReader." + ) =20 self.field_definition =3D config.access().get_field_definition() - self.fileinfo =3D self.make_fileinfo ( package_file ) - self.logger =3D DescriptionReader.LOGGER.getChild ( self.get= _log_name() ) + self.fileinfo =3D package_info + self.logger =3D logger.getChild ( 'desc_reader' ) self.desc_data =3D None =20 =20 @@ -33,15 +35,6 @@ class DescriptionReader ( object ): =20 # --- end of __init__ (...) --- =20 - def get_log_name ( self ): - """Returns a logging name that can be used in other modules.""" - try: - return self.fileinfo ['filename'] - except Exception as any_exception: - return '__undef__' - # --- end of get_log_name (...) --- - - def get_desc ( self, run_if_unset=3DTrue ): if self.desc_data is None: self.run () @@ -49,43 +42,6 @@ class DescriptionReader ( object ): return self.desc_data # --- end of get_desc (...) --- =20 - def get_fileinfo ( self ): - return self.fileinfo - # --- end of get_fileinfo (...) --- - - def make_fileinfo ( self, filepath ): - """Returns some info about the given filepath as dict whose contents a= re - the file path, the file name ([as package_file with suffix and] - as filename with tarball suffix removed), the package name - and the package_version. - - arguments: - * filepath -- - """ - - package_file =3D os.path.basename ( filepath ) - - filename =3D re.sub ( config.get ( 'R_PACKAGE.suffix_regex' ) + '$', '= ', package_file ) - - package_name, sepa, package_version =3D filename.partition ( - config.get ( 'R_PACKAGE.name_ver_separator', '_' ) - ) - - if not sepa: - # file name unexpected, tarball extraction will (probably) fail - DescriptionReader.LOGGER.error ( "unexpected file name %s.'", filenam= e ) - - return dict ( - filepath =3D filepath, - filename =3D filename, - package_file =3D package_file, - package_name =3D package_name, - #package_origin =3D ?, - package_version =3D package_version, - ) - - # --- end of make_fileinfo (...) --- - def _parse_read_data ( self, read_data ): """Verifies and parses/fixes read data. =20 @@ -93,7 +49,6 @@ class DescriptionReader ( object ): * read_data -- data from file, will be modified """ =20 - # insert default values default_values =3D self.field_definition.get_fields_with_default_value= () for field_name in default_values.keys(): @@ -153,8 +108,8 @@ class DescriptionReader ( object ): -> split field values -> filter out unwanted/useless fields =20 - The return value is a dict { fileinfo , description_data } or None if - the read data are "useless" (not suited to create an ebuild for it, + The return value is a description_data dict or None if the read data + are "useless" (not suited to create an ebuild for it, e.g. if OS_TYPE is not unix). """ =20 diff --git a/roverlay/ebuildcreator.py b/roverlay/ebuildcreator.py index 4ece851..6daf471 100644 --- a/roverlay/ebuildcreator.py +++ b/roverlay/ebuildcreator.py @@ -2,8 +2,8 @@ # Copyright 2006-2012 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 =20 -import threading import logging +import threading =20 try: import queue @@ -11,6 +11,7 @@ except ImportError: # python2 import Queue as queue =20 + from roverlay import config from roverlay.ebuildjob import EbuildJob from roverlay.depres import depresolver @@ -34,7 +35,7 @@ class EbuildCreator ( object ): self.runlock =3D threading.Lock() self._threads =3D None =20 - self.logger =3D logging.getLogger ( 'EbuildCreator' ) + self.logger =3D logging.getLogger ( 'EbuildCreator' ) =20 # --- end of init (...) --- =20 @@ -46,7 +47,6 @@ class EbuildCreator ( object ): arguments: * package_file -- path R package file """ - new_job =3D EbuildJob ( package_file, self.get_resolver_channel ) =20 self.ebuild_jobs.put ( new_job ) @@ -55,14 +55,16 @@ class EbuildCreator ( object ): =20 # --- end of add_package (...) --- =20 - def get_resolver_channel ( self, name=3DNone ): + def get_resolver_channel ( self, name=3DNone, logger=3DNone ): """Returns a communication channel to the dependency resolver. =20 arguments: readonly -- whether the channel is listen-only (no write methods) or n= ot defaults to True """ - return self.depresolve_main.register_channel ( EbuildJobChannel ( name= =3Dname ) ) + return self.depresolve_main.register_channel ( + EbuildJobChannel ( name=3Dname, logger=3Dlogger ) + ) =20 # --- end of get_resolver_channel (...) --- =20 @@ -84,7 +86,7 @@ class EbuildCreator ( object ): =20 # --- end of _thread_run (...) --- =20 - def run ( self ): + def start ( self ): """Tells all EbuildJobs to run.""" =20 if not self.runlock.acquire ( False ): @@ -95,10 +97,9 @@ class EbuildCreator ( object ): jobcount =3D EbuildCreator.NUMTHREADS =20 if jobcount < 1: - if jobcount < 0: - self.logger.warning ( "Running in sequential mode." ) - else: - self.logger.debug ( "Running in sequential mode." ) + ( self.logger.warning if jobcount < 0 else self.logger.debug ) ( + "Running in sequential mode." + ) self._thread_run() else: self.logger.warning ( @@ -118,7 +119,7 @@ class EbuildCreator ( object ): =20 self.runlock.release() =20 - # --- end of run (...) --- + # --- end of start (...) --- =20 def collect_ebuilds ( self ): """Returns all ebuilds. (They may not be ready / TODO)""" diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py index ccd2f2a..8b13e67 100644 --- a/roverlay/ebuildjob.py +++ b/roverlay/ebuildjob.py @@ -5,9 +5,11 @@ import logging import re =20 +from roverlay import config, util +from roverlay.ebuild import Ebuild from roverlay.descriptionreader import DescriptionReader -from roverlay.ebuild import Ebuild -from roverlay import config + + =20 class EbuildJob ( object ): LOGGER =3D logging.getLogger ( 'EbuildJob' ) @@ -37,7 +39,7 @@ class EbuildJob ( object ): """Initializes an EbuildJob, which creates an ebuild for an R package. =20 arguments: - * package_file -- path to the R package file + * package_info -- R package file info * dep_resolver -- dependency resolver """ =20 @@ -46,10 +48,18 @@ class EbuildJob ( object ): dep resolver 'communication channel', status codes etc. """ =20 - # get description reader from args? - self.description_reader =3D DescriptionReader ( package_file ) + self.package_info =3D util.get_packageinfo ( package_file ) + + try: + self.logger =3D EbuildJob.LOGGER.getChild ( + self.package_info ['filename'] + ) + except KeyError: + self.logger =3D EbuildJob.LOGGER.getChild ( '__undef__' ) =20 - self.logger =3D EbuildJob.LOGGER.getChild ( self.description_reader.ge= t_log_name () ) + self.description_reader =3D DescriptionReader ( + self.package_info, logger=3Dself.logger + ) =20 self.ebuild =3D None =20 @@ -67,17 +77,19 @@ class EbuildJob ( object ): # --- end of __init__ (...) --- =20 def get_resolver ( self, dependency_type ): + # comment TODO if not dependency_type in self._depres: - self._depres [dependency_type] =3D self.request_resolver ( dependency= _type ) + self._depres [dependency_type] =3D \ + self.request_resolver ( dependency_type, self.logger ) =20 return self._depres [dependency_type] - + # --- end of get_resolver (...) --- =20 def get_ebuild ( self ): """Returns the Ebuild that is created by this object. Note that you sh= ould check the status with status ( $TODO::EBUILD_READY ) before trying to = use the Ebuild. - ##fixme: it is guaranteed that self.ebuild is None unless the Ebuild i= s successfully created## + ##fixme: it is (should be?) guaranteed that self.ebuild is None unless= the Ebuild is successfully created## """ return self.ebuild =20 @@ -103,7 +115,6 @@ class EbuildJob ( object ): =20 # --- end of done_success (...) --- =20 - def run ( self ): """Tells this EbuildJob to run. This means that it reads the package f= ile, resolves dependencies using its resolver (TODO) and creates @@ -124,7 +135,7 @@ class EbuildJob ( object ): self.logger.info ( 'Cannot create an ebuild for this package.' ) =20 =20 - fileinfo =3D self.description_reader.get_fileinfo () + fileinfo =3D self.package_info =20 ebuild =3D Ebuild ( self.logger.getChild ( "Ebuild" ) ) =20 @@ -180,35 +191,43 @@ class EbuildJob ( object ): else: resolver.add_depency ( desc [desc_field] ) =20 - del resolver =20 + # lazy depres: wait until done and stop if any resolver channel + # returns None (which implies failure) + # wait for depres and store results + resolved =3D True =20 - resolver_list =3D self._depres.values() - - # trigger depres... - for r in resolver_list: r.trigger_run() - - # and wait if not self._set_status ( 'WAIT_RESOLVE' ): return - for r in resolver_list: r.join() + + for resolver in self._depres.values(): + if resolver.satisfy_request() is None: + resolved =3D False + break =20 if not self._set_status ( 'BUSY' ): return =20 - # check if all deps resolved, which means that all channels have - # to return True - if not False in ( r.satisfy_request() for r in resolver_list ): + if not resolved: + # ebuild is not creatable, set status to FAIL and close dep resolve= rs + self.logger.info ( + "Failed to resolve dependencies for this package." + ) + for r in self._depres.values(): r.close () + self._set_status ( 'FAIL' ) + return + else: # add deps to the ebuild for dep_type, resolver in self._depres.items(): - # python3 requires list ( filter ( ... ) ) - deplist =3D list ( filter ( None, resolver.collect_dependencies ()= ) ) + deplist =3D list ( + filter ( None, resolver.collect_dependencies () ) + ) =20 if deplist is None: - ## false positive: "empty" channel - raise Exception ( - 'dep_resolver is broken: ' - 'lookup() returns None but satisfy_request() says ok.' - ) + ## FIXME: false positive: "empty" channel + raise Exception ( + 'dep_resolver is broken: ' + 'lookup() returns None but satisfy_request() says ok.' + ) elif isinstance ( deplist, ( list, set ) ): # add dependencies in no_append/override mode self.logger.debug ( "adding %s to %s", str (deplist), dep_type ) @@ -220,15 +239,9 @@ class EbuildJob ( object ): ) # --- end for =20 - # tell the dep resolver channels that we're done - for r in resolver_list: r.close () =20 - else: - # ebuild is not creatable, set status to FAIL and close dep resolve= rs - self.logger.info ( "Failed to resolve dependencies for this package= ." ) - for r in resolver_list: r.close () - self._set_status ( 'FAIL' ) - return + # tell the dep resolver channels that we're done + for r in self._depres.values(): r.close () =20 # --- end dep resolution =20 diff --git a/roverlay/util.py b/roverlay/util.py new file mode 100644 index 0000000..5e9690d --- /dev/null +++ b/roverlay/util.py @@ -0,0 +1,48 @@ +# R Overlay -- helper functions etc. +# Copyright 2006-2012 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +import re +import os.path +import logging + +from roverlay import config + +LOGGER =3D logging.getLogger ( 'util' ) + + +def get_packageinfo ( filepath ): + """Returns some info about the given filepath as dict whose contents ar= e + the file path, the file name ([as package_file with suffix and] + as filename with tarball suffix removed), the package name + and the package_version. + + arguments: + * filepath -- + """ + + package_file =3D os.path.basename ( filepath ) + + # remove .tar.gz .tar.bz2 etc. + filename =3D re.sub ( + config.get ( 'R_PACKAGE.suffix_regex' ) + '$', '', package_file + ) + + package_name, sepa, package_version =3D filename.partition ( + config.get ( 'R_PACKAGE.name_ver_separator', '_' ) + ) + + if not sepa: + # file name unexpected, tarball extraction will (probably) fail + LOGGER.error ( "unexpected file name '%s'." % filename ) + + return dict ( + filepath =3D filepath, + filename =3D filename, + package_file =3D package_file, + package_name =3D package_name, + #package_origin =3D ?, + package_version =3D package_version, + ) + +# --- end of get_packageinfo (...) ---