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 1SbxaZ-000639-Sv for garchives@archives.gentoo.org; Tue, 05 Jun 2012 17:30:43 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id DF313E060D; Tue, 5 Jun 2012 17:30:25 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id A07E6E060D for ; Tue, 5 Jun 2012 17:30:25 +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 D85381B4039 for ; Tue, 5 Jun 2012 17:30:24 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by hornbill.gentoo.org (Postfix) with ESMTP id 97E8CE5431 for ; Tue, 5 Jun 2012 17:30:23 +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: <1338916839.f65931ef830da61d738dab1dcc9f5588cc260243.dywi@gentoo> Subject: [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/ X-VCS-Repository: proj/R_overlay X-VCS-Files: roverlay/depres/__init__.py roverlay/depres/depresolver.py roverlay/depres/deprule.py roverlay/depres/rulereader.py X-VCS-Directories: roverlay/depres/ X-VCS-Committer: dywi X-VCS-Committer-Name: André Erdmann X-VCS-Revision: f65931ef830da61d738dab1dcc9f5588cc260243 X-VCS-Branch: master Date: Tue, 5 Jun 2012 17:30:23 +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: 3cc194e6-d436-4d3b-b733-49455d0f78c5 X-Archives-Hash: 435a6a5a7178ca1ac305bd6ef7625a92 commit: f65931ef830da61d738dab1dcc9f5588cc260243 Author: Andr=C3=A9 Erdmann mailerd de> AuthorDate: Tue Jun 5 17:20:39 2012 +0000 Commit: Andr=C3=A9 Erdmann mailerd de> CommitDate: Tue Jun 5 17:20:39 2012 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=3Dproj/R_overlay.git= ;a=3Dcommit;h=3Df65931ef dependency resolution * added simple rule reader * started with the dependency resolver --- roverlay/depres/depresolver.py | 78 +++++++++++++++++++++++++++--- roverlay/depres/deprule.py | 103 +++++++++++++++++++++++++++++++++-= ------ roverlay/depres/rulereader.py | 88 ++++++++++++++++++++++++++++++++++ 3 files changed, 245 insertions(+), 24 deletions(-) diff --git a/roverlay/depres/__init__.py b/roverlay/depres/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/roverlay/depres/depresolver.py b/roverlay/depres/depresolver= .py index 7d7c5e6..ebb88cd 100644 --- a/roverlay/depres/depresolver.py +++ b/roverlay/depres/depresolver.py @@ -2,22 +2,55 @@ # Copyright 2006-2012 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 =20 + class DependencyResolver: =20 def __init__ ( self ): - self.channels =3D dict() - self.listeners =3D dict() + self.logger =3D None + self.channels =3D list () + self.listeners =3D list () + + + def _report_event ( self, event, pkg_env=3DNone, **extra ): + """Reports an event to the log, channels and listeners.""" + pass + + + def set_logmask ( self, logmask ): + """Sets the logmask for this DependencyResolver which can be used to + filter events that would normally go into the log file. + Useful if a listener module reports such events in an extra file. + + arguments: + * logmask -- new logmask + """ + pass =20 =20 - def get_listener (): + def add_listener ( self ): + """Adds a listener, which listens to events such as + "dependency is unresolvable". Possible use cases include redirecting + such events into a file for further parsing. + + arguments: + * listener_type + """ new_listener =3D DependencyResolverListener() # register the new listener self.listeners [new_listener.ident] =3D new_listener return new_listener =20 - def get_channel ( readonly=3DFalse ): - # ... TODO - pass + def get_channel ( self, readonly=3DFalse ): + """Returns a communication channel to the DependencyResolver. + This channel can be used to _talk_, e.g. queue dependencies for resolu= tion + and collect the results later. + + arguments: + * readonly -- whether this channel has write access or not + """ + new channel =3D DependencyResolverChannel ( self ) + self.channels [new_channel.ident] =3D new_channel + return new_channel =20 =20 =20 @@ -26,8 +59,39 @@ class DependencyResolverListener: def __init__ ( self ): self.ident =3D id ( self ) =20 + def notify ( event_type, pkg_env=3DNone, **extra ): + """Notify this listener about an event.""" + pass + + class DependencyResolverChannel ( DependencyResolverListener ): =20 def __init__ ( self, main_resolver, *args ): - super ( DependencyResolverChannel, self ) . __init__ ( args ) + super ( DependencyResolverChannel, self ) . __init__ () self._depres_master =3D main_resolver + + def close ( self ): + """Closes this channel.""" + pass + + +class EbuildJobChannel ( DependencyResolverChannel ): + def __init__ ( self, main_resolver, *args ): + super ( EbuildJobChannel, self ) . __init__ ( main_resolver ) + + + def done ( self ): + pass + + def add_dependency ( self, dep_str ): + pass + + def add_dependencies ( self, dep_list ): + pass + + def satisfy_request ( self ): + pass + + def lookup ( self, dep_str ): + return None + diff --git a/roverlay/depres/deprule.py b/roverlay/depres/deprule.py index 3a82cbe..b5d1116 100644 --- a/roverlay/depres/deprule.py +++ b/roverlay/depres/deprule.py @@ -4,20 +4,20 @@ =20 class DependencyRule: def __init__ ( self ): - pass + self.max_score =3D 1000 =20 - def matches ( pkg_env ): - return False + def matches ( dep_str ): + return 0 =20 class SimpleDependencyRule ( DependencyRule ): =20 def __init__ ( self, resolving_package, dep_str=3DNone, priority=3D100 = ): - super ( SimpleDependencyRule, self ) . __init__ ( self ) + super ( SimpleDependencyRule, self ) . __init__ ( ) self.dep_alias =3D set () if dep_str: self.dep_alias.add ( dep_str ) =20 - self.package =3D resolving_package + self.resolving_package =3D resolving_package =20 self.priority =3D priority # --- end of __init__ (...) --- @@ -26,35 +26,104 @@ class SimpleDependencyRule ( DependencyRule ): self.dep_alias.add ( dep_str ) # --- end of add_resolved (...) --- =20 - def matches ( self, pkg_env, lowercase=3DTrue ): + def matches ( self, dep_str, lowercase=3DTrue ): if lowercase: - lower_dep_str =3D pkg_env.dep_str + lower_dep_str =3D dep_str for alias in self.dep_alias: if alias.lower() =3D=3D lower_dep_str: - return True - elif pkg_env.dep_str in self.dep_alias: - return True + return self.max_score + elif dep_str in self.dep_alias: + return self.max_score =20 - return False + return 0 # --- end of matches (...) --- =20 + def get_dep ( self ): + return self.resolving_package + + def export_rule ( self ): + pass + class DependencyRulePool: =20 - def __init__ ( self ): - self.rules =3D list () - self._priofunc =3D lambda x : x.priority + def __init__ ( self, name ): + self.rules =3D list () + self.name =3D name + self.priority =3D 0 # --- end of __init__ (...) --- =20 - def _sort_rules ( self ): - self.rules.sort ( key=3Dself._priofunc ) + def sort ( self ): + self.rules.sort ( key=3Dlambda rule : rule.priority ) + + priority_sum =3D 0 + for r in self.rules: + priority_sum +=3D r.priority + + self.priority =3D int ( priority_sum / len ( self.rules ) ) if len ( s= elf.rules ) else 0 + return None # --- end of _sort_rules (...) --- =20 def add ( self, rule ): if issubclass ( rule, DependencyRule ): - self.rules.add ( rule ) + self.rules.append ( rule ) else: raise Exception ( "bad usage (dependency rule expected)." ) =20 return None # --- end of add (...) --- + + def matches ( self, dep_str, skip_matches=3D0 ): + """Tries to find a match in this dependency rule pool. + The first match is immediatly returned unless skip_matches is !=3D 0, = in + which case the first (>0) / last (<0) skip_matches matches are skipped= . + + arguments: + * dep_str -- dependency to look up + * skip_matches -- + """ + + if abs ( skip_matches ) >=3D len ( self.rules ): + # all matches ignored; cannot expect a result in this case - abort no= w + pass + + else: + skipped =3D 0 + order =3D range ( len ( self.rules ) ) + + if skip_matches < 1: + skip_matches *=3D -1 + order.reverse() + + for index in order: + score =3D self.rules [index].matches ( dep_str ) + if score: + if skipped < skip_matches: + skipped +=3D 1 + else: + return score, self.rules [index].get_dep () + + + return 0, None + + +class SimpleDependencyRulePool ( DependencyRulePool ) + + def __init__ ( self, name ): + super ( SimpleDependencyRulePool, self ) . __init__ ( name ) + # --- end of __init__ (...) --- + + def add ( self, rile ): + if isinstance ( rule, SimpleDependencyRule ): + self.rules.append ( rule ) + else: + raise Exception ( "bad usage (simple dependency rule expected)." ) + # --- end of add (...) --- + + def export_rules ( self, fh ): + for rule in self.rules: + to_write =3D fh.export_rule() + if isinstance ( to_write, str ): + fh.write ( to_write ) + else: + fh.writelines ( to_write ) diff --git a/roverlay/depres/rulereader.py b/roverlay/depres/rulereader.p= y new file mode 100644 index 0000000..6998cb2 --- /dev/null +++ b/roverlay/depres/rulereader.py @@ -0,0 +1,88 @@ + +import re +import logging + +from roverlay.depres.deprule import SimpleDependencyRule + +class SimpleDependencyRuleReader: + + one_line_separator =3D re.compile ( '\s+::\s+' ) + multiline_start =3D '{' + multiline_stop =3D '}' + comment_chars =3D list ( '#;' ) + + + def __init__ ( self ): + pass + # --- end of __init__ (...) --- + + def read_file ( self, filepath ): + """Reads a file that contains SimpleDescriptionRules. + + arguments: + * filepath -- file to read + """ + + lineno =3D 0 + + try: + logging.debug ( "Reading simple dependency rule file " + filepath + "= ." ) + fh =3D open ( filepath, 'r' ) + + next_rule =3D None + rules =3D list ()f + + for line in fh.readlines(): + lineno +=3D 1 + line =3D line.strip() + + if not line: + pass + + elif not next_rule is None: + # in a multiline rule + if line [0] =3D=3D SimpleDependencyRuleReader.multiline_stop: + # end of a multiline rule + rules.append ( next_rule ) + next_rule =3D None + else: + # new resolved str + next_rule.add_resolved ( line ) + + elif line [0] in SimpleDependencyRuleReader.comment_chars: + # comment + pass + + elif line [-1] =3D=3D SimpleDependencyRuleReader.multiline_start: + # start of multiline rule + next_rule =3D SimpleDependencyRule ( line [:-1].rstrip(), None, 100= ) + + else: + # one line rule? + rule_str =3D SimpleDependencyRuleReader.one_line_separator.split ( = line, 1 ) + + if len ( rule_str ) =3D=3D 2: + rules.append ( + SimpleDependencyRule ( rule_str [0], rule_str [1], 90 ) + ) + else: + logging.error ( + "In " + filepath + ", line " + str ( lineno ) + ": cannot use thi= s line." + ) + # --- + + if fh: fh.close () + + logging.info ( filepath + ": read " + str ( len ( rules ) ) + " depen= dency rules." ) + + return rules + + except IOError as ioerr: + if lineno: + logging.error ( "Failed to read file " + filepath + " after " + str = ( lineno ) " lines." + else: + logging.error ( "Could not read file " + filepath + "." ) + raise + + # --- end of read_file (...) --- +