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 1SZlTi-0005pf-Aq for garchives@archives.gentoo.org; Wed, 30 May 2012 16:10:30 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 633D5E0676; Wed, 30 May 2012 16:09:58 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id C3DB4E0676 for ; Wed, 30 May 2012 16:09:57 +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 EB9DE1B402C for ; Wed, 30 May 2012 16:09:56 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by hornbill.gentoo.org (Postfix) with ESMTP id AEFCDE5431 for ; Wed, 30 May 2012 16:09:55 +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: <1338389668.efc87322e3016a5178feb579b468ff44d8cc0b04.dywi@gentoo> Subject: [gentoo-commits] proj/R_overlay:master commit in: roverlay/ X-VCS-Repository: proj/R_overlay X-VCS-Files: roverlay/ebuildjob.py X-VCS-Directories: roverlay/ X-VCS-Committer: dywi X-VCS-Committer-Name: André Erdmann X-VCS-Revision: efc87322e3016a5178feb579b468ff44d8cc0b04 X-VCS-Branch: master Date: Wed, 30 May 2012 16:09:55 +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: 1fa86353-b584-4851-85cd-9121bdd8130d X-Archives-Hash: 801a3c1507c5b7f2ecdab5f56aeb74b3 commit: efc87322e3016a5178feb579b468ff44d8cc0b04 Author: Andre Erdmann mailerd de> AuthorDate: Wed May 30 14:54:28 2012 +0000 Commit: Andr=C3=A9 Erdmann mailerd de> CommitDate: Wed May 30 14:54:28 2012 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=3Dproj/R_overlay.git= ;a=3Dcommit;h=3Defc87322 roverlay, ebuildjob: status code and dep resolve logic modified: ebuildjob.py --- roverlay/ebuildjob.py | 260 ++++++++++++++++++++++++++++++++++---------= ------ 1 files changed, 181 insertions(+), 79 deletions(-) diff --git a/roverlay/ebuildjob.py b/roverlay/ebuildjob.py index 171150c..d45dfdf 100644 --- a/roverlay/ebuildjob.py +++ b/roverlay/ebuildjob.py @@ -6,11 +6,42 @@ from roverlay.fileio import DescriptionReader from roverlay.ebuild import Ebuild =20 class EbuildJob: - STATUS_LIST =3D [ 'INIT', 'BUSY', 'WAIT', 'SUCCESS', 'FAIL' ] - STATUS_MAP =3D dict ( ( name, code ) for code, name in enumerate ( STA= TUS_LIST ) ) + # move this to const / config + DEPENDENCY_FIELDS =3D { + 'R_SUGGESTS' : [ 'Suggests' ], + 'DEPENDS' : ['Depends', 'Imports' ], + 'RDEPENDS' : [ 'LinkingTo', 'SystemRequirements' ] + } + + ## + + + STATUS_LIST =3D [ 'INIT', 'BUSY', 'WAIT_RESOLVE', 'SUCCESS', 'FAIL' ] + + # status 'jump' control + # FAIL is always allowed, S -> S has to be explicitly allowed + STATUS_BRANCHMAP =3D dict ( + INIT =3D [ 'BUSY' ], + BUSY =3D [ 'BUSY', 'WAIT_RESOLVE', 'SUCCESS' ], + WAIT_RESOLVE =3D [ 'BUSY' ], + SUCCESS =3D [], + FAIL =3D [], + ) =20 @classmethod def __init__ ( self, package_file, dep_resolver=3DNone ): + """Initializes an EbuildJob, which creates an ebuild for an R package. + + arguments: + * package_file -- path to the R package file + * dep_resolver -- dependency resolver + """ + + """Note: + it is intended to run this job as thread, that's why it has its own + dep resolver 'communication channel', status codes etc. + """ + self.package_file =3D package_file self.dep_resolver =3D dep_resolver # get description reader from args? @@ -18,44 +49,10 @@ class EbuildJob: =20 self.ebuild =3D None =20 - self._status =3D 0 # todo + self.status =3D 'INIT' =20 # --- end of __init__ (...) --- =20 - @staticmethod - def get_statuscode ( status_id ): - if status_id =3D=3D 'ALL': - return EbuildJob.STATUS_LIST - elif isinstance ( status_id, int ): - if status_id > 0 and status_id < len ( STATUS_LIST ): - return EbuildJob.STATUS_LIST [status_id] - elif status_id in EbuildJob.STATUS_MAP: - return EbuildJob.STATUS_MAP [status_id] - - return None - - # --- end of get_statuscode (...) --- - - @classmethod - def status ( self, expected_status=3DNone ): - """Returns the current status of this job or a bool that indicates - whether to current status matches the expected one. - - arguments: - * expected_status -- if not None: check if this job's state is expecte= d_status - """ - if expected_status: - if isinstance ( expected_status, int ): - return bool ( self._status =3D=3D expected_status ) - elif expected_status in EbuildJob.STATUS_MAP: - return bool ( self._status =3D=3D EbuildJob.STATUS_MAP [expected_sta= tus] ) - else: - return False - - return self._status - - # --- end of status (...) --- - @classmethod def get_ebuild ( self ): """Returns the Ebuild that is created by this object. Note that you sh= ould @@ -68,73 +65,178 @@ class EbuildJob: # --- end of get_ebuild (...) --- =20 @classmethod - def _set_status ( self, new_status ): - self._status =3D EbuildJob.get_statuscode ( new_status ) - return True + def get_status ( self, expected_status=3DNone ): + """Returns the current status of this job or a bool that indicates + whether to current status matches the expected one. =20 - # --- end of _set_status (...) --- + arguments: + * expected_status -- if not None: check if this job's state is expecte= d_status + """ + if not expected_status is None: + return bool ( self.status =3D=3D expected_status ) + else: + return self.status + + # --- end of get_status (...) --- + + @classmethod + def done_success ( self ): + """Returns True if this has been successfully finished.""" + return get_status ( 'SUCCESS' ) + + # --- end of done_success (...) --- =20 =20 @classmethod def run ( self ): """Tells this EbuildJob to run. This means that it reads the package f= ile, - resolves dependencies (TODO) and creates an Ebuild object that is read= y - to be written into a file. + resolves dependencies using its resolver (TODO) and creates + an Ebuild object that is ready to be written into a file. """ =20 - # check status - if not self.status ( 'INIT' ): - return + # TODO move hardcoded entries to config/const =20 - if not self._set_status ( 'BUSY' ): - return False + try: =20 - read_data =3D self.description_reader.readfile ( self.package_file ) + # set status or return + if not self._set_status ( 'BUSY', True ): return =20 - if read_data is None: - # set status accordingly - self._set_status ( 'FAIL' ) - return False + read_data =3D self.description_reader.readfile ( self.package_file ) =20 - fileinfo =3D read_data ['fileinfo'] - desc =3D read_data ['description_data'] + if read_data is None: + # set status accordingly + self._set_status ( 'FAIL' ) + return =20 - ebuild =3D Ebuild() + fileinfo =3D read_data ['fileinfo'] + desc =3D read_data ['description_data'] =20 - have_description =3D False + ebuild =3D Ebuild() =20 - print ( str ( desc ) ) + have_description =3D False =20 - if 'Title' in desc: - have_description =3D True - ebuild.add ( 'DESCRIPTION', desc ['Title'] ) + if 'Title' in desc: + ebuild.add ( 'DESCRIPTION', desc ['Title'] ) + have_description =3D True =20 - if 'Description' in desc: - have_description =3D True - ebuild.add ( 'DESCRIPTION', ( '// ' if have_description else '' ) + d= esc ['Description'] ) + if 'Description' in desc: + ebuild.add ( 'DESCRIPTION', ( '// ' if have_description else '' ) + = desc ['Description'] ) + #have_description=3DTrue =20 - if not have_description: - ebuild.add ( 'DESCRIPTION', '' ) - del have_description =20 - # origin is todo (sync module knows the package origin) - ebuild.add ( 'PKG_ORIGIN', 'CRAN' ) + # origin is todo (sync module knows the package origin) + ebuild.add ( 'PKG_ORIGIN', 'CRAN' ) =20 - ebuild.add ( 'PKG_FILE', fileinfo ['package_file'] ) + ebuild.add ( 'PKG_FILE', fileinfo ['package_file'] ) =20 - ebuild.add ( 'ebuild_header', [ '# test header' ], False ) + ebuild.add ( 'ebuild_header', + [ '# test header, first line\n', + '# test header, second line\n\n\n\n', + '#third\n\n#fifth' ], + False + ) =20 - ## have to resolve deps here + if self.dep_resolver and self.dep_resolver.enabled(): =20 - # enter status that allows transferring ebuild -> self.ebuild - if self._set_status ( 'WAIT' ): - # finalize self.ebuild: forced text creation + make it readonly + # collect depdencies from desc and add them to the resolver + raw_depends =3D dict () + + dep_type =3D field =3D None + + for dep_type in EbuildJob.DEPENDENCY_FIELDS.keys(): + + raw_depends [dep_type] =3D [] + + for field in EbuildJob.DEPENDENCY_FIELDS [dep_type]: + + if field in desc: + if isinstance ( desc [field], list ): + raw_depends.extend ( desc [field] ) + self.dep_resolver.add_dependencies ( desc [field] ) + + else: + raw_depends.append ( desc [field] ) + self.dep_resolver.add_depency ( desc [field] ) + + del field, dep_type + + + while not self.dep_resolver.done(): + + if not self._set_status ( 'WAIT_RESOLVE' ): return + + # tell the resolver to run (again) + self.dep_resolver.run() + + if not self._set_status ( 'BUSY' ): return + + if self.dep_resolver.satisfy_request(): + + dep_type =3D dep_str =3D dep =3D None + + # dependencies resolved, add them to the ebuild + for dep_type in raw_depends.keys(): + + for dep_str in raw_depends [dep_type]: + # lookup (str) should return a str here + dep =3D self.dep_resolver.lookup ( dep_str ) + if dep is None: + raise Exception ( + "dep_resolver is broken: lookup() returns None but satisfy_requ= est() says ok." + ) + else: + # add depencies in append mode + dep =3D self.dep_resolver.lookup ( dep_str ) + ebuild.add ( dep_type, + self.dep_resolver.lookup ( dep_str ), + True + ) + + del dep, dep_str, dep_type + + # tell the dep resolver that we're done here + self.dep_resolver.close() + + else: + # ebuild is not creatable, set status to FAIL and close dep resolve= r + self._set_status ( 'FAIL' ) + self.dep_resolver.close() + return + + ## finalize self.ebuild: forced text creation + make it readonly if ebuild.prepare ( True, True ): self.ebuild =3D ebuild - return self._set_status ( 'SUCCESS' ) - - self._set_status ( 'FAIL' ) - return False + return None + else: + return None =20 + except Exception as any_exception: + # any exception means failure + self.status =3D 'FAIL' + raise =20 # --- end of run (...) --- + + @classmethod + def _set_status ( self, new_status, ignore_invalid=3DFalse ): + """Changes the status of this job. May refuse to do that if invalid ch= ange + requested (e.g. 'FAIL' -> 'SUCCESS'). + + arguments: + new_status -- + """ + + if new_status =3D=3D 'FAIL': + # always allowed + self.status =3D new_status + + if new_status and new_status in EbuildJob.STATUS_LIST: + # check if jumping from self.status to new_status is allowed + if new_status in EbuildJob.STATUS_BRANCHMAP [self.status]: + self.status =3D new_status + return True + + # default return + return False + + # --- end of _set_status (...) ---