public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/simpledeprule/, roverlay/depres/
  2012-07-20 16:16 [gentoo-commits] proj/R_overlay:overlay_wip " André Erdmann
@ 2012-07-30  8:52 ` André Erdmann
  0 siblings, 0 replies; 9+ messages in thread
From: André Erdmann @ 2012-07-30  8:52 UTC (permalink / raw
  To: gentoo-commits

commit:     464b87572270d1ba7a792e6bb3abaa3e93bcf2c8
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jul 20 16:08:09 2012 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jul 20 16:08:09 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=464b8757

add DynamicSelfdepPool to dependency resolution

	geändert:   roverlay/depres/depresolver.py
	geändert:   roverlay/depres/deprule.py
	geändert:   roverlay/depres/simpledeprule/abstractrules.py
	neue Datei:   roverlay/depres/simpledeprule/dynpool.py

---
 roverlay/depres/depresolver.py                 |   56 +++++++++++++++++++++---
 roverlay/depres/deprule.py                     |    5 ++
 roverlay/depres/simpledeprule/abstractrules.py |    5 +-
 roverlay/depres/simpledeprule/dynpool.py       |   40 +++++++++++++++++
 4 files changed, 97 insertions(+), 9 deletions(-)

diff --git a/roverlay/depres/depresolver.py b/roverlay/depres/depresolver.py
index 06ba6fc..a399454 100644
--- a/roverlay/depres/depresolver.py
+++ b/roverlay/depres/depresolver.py
@@ -15,6 +15,7 @@ except ImportError:
 from roverlay        import config
 from roverlay.depres import communication, deptype, events
 import roverlay.depres.simpledeprule.reader
+import roverlay.depres.simpledeprule.dynpool
 
 
 # if false: do not use the "negative" result caching which stores
@@ -78,7 +79,9 @@ class DependencyResolver ( object ):
 		self._depqueue_done = dict ()
 
 		# list of rule pools that have been created from reading files
-		self.static_rule_pools = list ()
+		self.static_rule_pools  = list()
+		# list of rule pools that are recreatable (at runtime)
+		self.dynamic_rule_pools = list()
 
 		if SAFE_CHANNEL_IDS:
 			# this lock is used in register_channel
@@ -91,7 +94,8 @@ class DependencyResolver ( object ):
 		"""Sorts the rule pools of this resolver."""
 		for pool in self.static_rule_pools: pool.sort()
 		poolsort = lambda pool : ( pool.priority, pool.rule_weight )
-		self.static_rule_pools.sort ( key=poolsort )
+		self.static_rule_pools.sort  ( key=poolsort )
+		self.dynamic_rule_pools.sort ( key=poolsort )
 	# --- end of sort (...) ---
 
 	def _reset_unresolvable ( self ):
@@ -112,18 +116,46 @@ class DependencyResolver ( object ):
 		)
 	# --- end of get_reader (...) ---
 
+	def make_selfdep_pool ( self, rule_kw_function, reload_now=False ):
+		"""Creates an dynamic selfdep pool and adds it to this resolver.
+
+		arguments:
+		* rule_kw_function -- function that returns an rule creation keyword
+		                      generator (basically, it has to return a list
+		                      of dicts)
+		"""
+		pool = roverlay.depres.simpledeprule.dynpool.get ( rule_kw_function )
+		self.dynamic_rule_pools.append ( pool )
+		if reload_now:
+			pool.reload()
+			self._new_rulepools_added()
+	# --- end of make_selfdep_pool (...) ---
+
 	def add_rulepool ( self, rulepool, pool_type=None ):
 		"""Adds a (static) rule pool to this resolver.
 		Calls self.sort() afterwards.
 
 		arguments:
-		* rulepool --
+		* rulepool  -- rule pool type, 1 for dynamic, else static
 		* pool_type -- ignored.
 		"""
-		self.static_rule_pools.append ( rulepool )
+		if pool_type == 1:
+			self.dynamic_rule_pools.append ( rulepool )
+		else:
+			self.static_rule_pools.append ( rulepool )
 		self._new_rulepools_added()
 	# --- end of add_rulepool (...) ---
 
+	def reload_pools ( self ):
+		one = False
+		for pool in self.dynamic_rule_pools:
+			one = True
+			pool.reload()
+
+		if one:
+			self._new_rulepools_added()
+	# --- end of reload_pools (...) ---
+
 	def _report_event ( self, event, dep_env=None, pkg_env=None, msg=None ):
 		"""Reports an event to the log and listeners.
 
@@ -335,10 +367,22 @@ class DependencyResolver ( object ):
 			is_resolved = 1
 
 		else:
+			for rulepool in (
+				p for p in self.dynamic_rule_pools \
+					if p.accepts ( dep_env.deptype_mask, try_other=False )
+			):
+				result = rulepool.matches ( dep_env )
+				if result [0] > 0:
+					resolved    = result [1]
+					is_resolved = 2
+					break
+			# TRY_OTHER searching is disabled for dynamic rule pools,
+			# (a) no dyn pool uses it, (b) probably not useful
+
 			# search for a match in the rule pools that accept the dep type
 			for rulepool in (
 				p for p in self.static_rule_pools \
-					if p.deptype_mask & dep_env.deptype_mask
+					if p.accepts ( dep_env.deptype_mask, try_other=False )
 			):
 				result = rulepool.matches ( dep_env )
 				if result [0] > 0:
@@ -352,7 +396,7 @@ class DependencyResolver ( object ):
 				#  that (normally) don't accept the dep type
 				for rulepool in (
 					p for p in self.static_rule_pools \
-						if p.deptype_mask & ~dep_env.deptype_mask
+						if p.accepts ( ~dep_env.deptype_mask, try_other=True )
 				):
 					result = rulepool.matches ( dep_env )
 					if result [0] > 0:

diff --git a/roverlay/depres/deprule.py b/roverlay/depres/deprule.py
index 50b921a..8c63987 100644
--- a/roverlay/depres/deprule.py
+++ b/roverlay/depres/deprule.py
@@ -70,6 +70,11 @@ class DependencyRulePool ( object ):
 		return None
 	# --- end of sort (...) ---
 
+	def accepts ( self, deptype_mask, try_other=False ):
+		"""Returns True if this pool accepts the given deptype_mask."""
+		return bool ( self.deptype_mask & deptype_mask )
+	# --- end of accepts (...) ---
+
 	def add ( self, rule ):
 		"""Adds a DependencyRule to this rule pool.
 

diff --git a/roverlay/depres/simpledeprule/abstractrules.py b/roverlay/depres/simpledeprule/abstractrules.py
index 1f0ba28..e4aa7b2 100644
--- a/roverlay/depres/simpledeprule/abstractrules.py
+++ b/roverlay/depres/simpledeprule/abstractrules.py
@@ -151,9 +151,8 @@ class FuzzySimpleRule ( SimpleRule ):
 
 						elif 'version' in fuzzy:
 
-							ver_pkg = '-'.join ( (
-								self.resolving_package, fuzzy ['version']
-							) )
+							ver_pkg = \
+								self.resolving_package + '-' +  fuzzy ['version']
 
 							vmod = fuzzy ['version_modifier'] \
 									if 'version_modifier' in fuzzy \

diff --git a/roverlay/depres/simpledeprule/dynpool.py b/roverlay/depres/simpledeprule/dynpool.py
new file mode 100644
index 0000000..eea146d
--- /dev/null
+++ b/roverlay/depres/simpledeprule/dynpool.py
@@ -0,0 +1,40 @@
+from roverlay.depres import deptype
+from roverlay.depres.simpledeprule.pool import SimpleDependencyRulePool
+from roverlay.depres.simpledeprule.rules import SimpleFuzzyDependencyRule
+
+class DynamicSelfdepRulePool ( SimpleDependencyRulePool ):
+	"""A rule pool that gets its rules from a function."""
+
+	def __init__ ( self, rule_kw_function, rule_class, priority=120, **kwargs ):
+		super ( DynamicSelfdepRulePool, self ). __init__ (
+			name='dynamic selfdeps', priority=priority,
+			deptype_mask=deptype.internal,
+			**kwargs
+		)
+
+		self._rule_class       = rule_class
+		self._rule_kw_function = rule_kw_function
+	# --- end of __init__ (...) ---
+
+	def accepts ( self, deptype_mask, try_other=False ):
+		if try_other:
+			# never resolve external deps as selfdeps
+			return False
+		else:
+			return self.deptype_mask & deptype_mask
+	# --- end of accepts (...) ---
+
+	def reload ( self ):
+		self.rules = list (
+			self._rule_class ( is_selfdep=True, **kwargs ) \
+				for kwargs in self._rule_kw_function()
+		)
+	# --- end of reload (...) ---
+
+
+def get ( rule_kw_function ):
+	"""Returns a default DynamicSelfdepRulePool for rule_kw_function."""
+	return DynamicSelfdepRulePool (
+		rule_kw_function, SimpleFuzzyDependencyRule
+	)
+# --- end of get (...) ---


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/simpledeprule/, roverlay/depres/
@ 2012-08-02 15:14 André Erdmann
  0 siblings, 0 replies; 9+ messages in thread
From: André Erdmann @ 2012-08-02 15:14 UTC (permalink / raw
  To: gentoo-commits

commit:     0e03d69ea4da114d891eeacf620262c901bd577b
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Aug  2 15:01:16 2012 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Aug  2 15:01:16 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=0e03d69e

depres: comments, string formatting and strutil

---
 roverlay/depres/depenv.py                      |   25 +++++++++++++++--------
 roverlay/depres/listeners.py                   |    8 +++---
 roverlay/depres/simpledeprule/abstractrules.py |   25 ++++++++++-------------
 roverlay/depres/simpledeprule/console.py       |    6 ++--
 4 files changed, 34 insertions(+), 30 deletions(-)

diff --git a/roverlay/depres/depenv.py b/roverlay/depres/depenv.py
index f9bef8c..f4405ce 100644
--- a/roverlay/depres/depenv.py
+++ b/roverlay/depres/depenv.py
@@ -9,16 +9,23 @@ class DepEnv ( object ):
 	# excluding A-Z since dep_str_low will be used to find a match
 	# _NAME ::= word{<whitespace><word>}
 	_NAME = '(?P<name>[a-z0-9_\-/.+-]+(\s+[a-z0-9_\-/.+-]+)*)'
+
+	# _VER              ::= [[<version_separator>]*<digit>[<digit>]*]*
+	# digit             ::= {0..9}
+	# version_separator ::= {'.','_','-'}
+	# examples: .9, 1.0-5, 3, 5..-_--2
 	_VER  = '(?P<ver>[0-9._\-]+)'
+
 	# { <, >, ==, <=, >=, =, != }
 	_VERMOD = '(?P<vmod>[<>]|[=<>!]?[=])'
 
+	# name/version regexes used for fuzzy dep rules
 	V_REGEX_STR = frozenset ( (
 		# 'R >= 2.15', 'R >=2.15' etc. (but not 'R>=2.15'!)
 		'^{name}\s+{vermod}?\s*{ver}\s*$'.format (
 			name=_NAME, vermod=_VERMOD, ver=_VER
 		),
-		# TODO: merge these regexes: () [] {} (but not (],{), ...)
+
 		# 'R (>= 2.15)', 'R(>=2.15)' etc.
 		'^{name}\s*\(\s*{vermod}?\s*{ver}\s*\)$'.format (
 			name=_NAME, vermod=_VERMOD, ver=_VER
@@ -34,14 +41,12 @@ class DepEnv ( object ):
 		),
 	) )
 
-	VERSION_REGEX = frozenset (
-		re.compile ( regex ) for regex in V_REGEX_STR
-	)
+	VERSION_REGEX    = frozenset ( re.compile ( r ) for r in V_REGEX_STR )
 	FIXVERSION_REGEX = re.compile ( '[_\-]' )
+	URI_PURGE        = re.compile ( '\s*from\s*(http|ftp|https)://[^\s]+' )
+	WHITESPACE       = re.compile ( '\s+' )
 
-	URI_PURGE = re.compile ( '\s*from\s*(http|ftp|https)://[^\s]+' )
-	WHITESPACE = re.compile ( '\s+' )
-
+	# try all version regexes if True, else break after first match
 	TRY_ALL_REGEXES  = False
 
 	STATUS_UNDONE       = 1
@@ -49,6 +54,9 @@ class DepEnv ( object ):
 	STATUS_UNRESOLVABLE = 4
 
 	def _depstr_fix ( self, dep_str ):
+		"""Removes cruft from a dep string."""
+		# unquote dep_str, remove "from <uri>.." entries and replace all
+		# whitespace by a single ' ' char
 		cls = self.__class__
 		return cls.WHITESPACE.sub ( ' ',
 			cls.URI_PURGE.sub ( '',
@@ -77,8 +85,7 @@ class DepEnv ( object ):
 
 		self._depsplit()
 
-		# TODO: analyze dep_str:
-		#   extract dep name, dep version, useless comments,...
+		# (maybe) TODO: analyze dep_str: remove useless comments,...
 
 	# --- end of __init__ (...) ---
 

diff --git a/roverlay/depres/listeners.py b/roverlay/depres/listeners.py
index 9d5b0fc..1a8cc2e 100644
--- a/roverlay/depres/listeners.py
+++ b/roverlay/depres/listeners.py
@@ -101,10 +101,12 @@ class ResolvedFileListener ( FileListener ):
 
 	def notify ( self, event_type, dep_env=None, pkg_env=None, **extra ):
 		self._event ( event_type,
-			"'%s' as '%s'" % ( dep_env.dep_str, dep_env.resolved_by )
-		)
+			"{dep_str!r} as {dep!r}".format (
+				dep_str=dep_env.dep_str, dep=dep_env.resolved_by
+		) )
 	# --- end of notify (...) ---
 
+
 class UnresolvableFileListener ( FileListener ):
 	"""A FileListener that listens to 'dependency unresolvable' events."""
 	def __init__ ( self, _file ):
@@ -114,7 +116,6 @@ class UnresolvableFileListener ( FileListener ):
 	# --- end of __init__ (...) ---
 
 	def notify ( self, event_type, dep_env=None, pkg_env=None, **extra ):
-		# <%s> % dep_env.dep_str? TODO
 		self._event ( event_type, dep_env.dep_str )
 	# --- end of notify (...) ---
 
@@ -129,6 +130,5 @@ class UnresolvableSetFileListener ( SetFileListener ):
 	# --- end of __init__ (...) ---
 
 	def notify ( self, event_type, dep_env=None, pkg_env=None, **extra ):
-		#self._event ( event_type, dep_env.dep_str_low )
 		self._event ( event_type, dep_env.dep_str )
 	# --- end of notify (...) ---

diff --git a/roverlay/depres/simpledeprule/abstractrules.py b/roverlay/depres/simpledeprule/abstractrules.py
index 18dc4b7..20644e3 100644
--- a/roverlay/depres/simpledeprule/abstractrules.py
+++ b/roverlay/depres/simpledeprule/abstractrules.py
@@ -79,9 +79,9 @@ class SimpleRule ( deprule.DependencyRule ):
 			dep_env.dep_str_low if lowercase else dep_env.dep_str, lowercase
 		):
 			self.logger.debug (
-				"matches %s with score %i and priority %i."
-					% ( dep_env.dep_str, self.max_score, self.priority )
-			)
+				"matches {dep_str} with score {s} and priority {p}.".format (
+					dep_str=dep_env.dep_str, s=self.max_score, p=self.priority
+			) )
 			return ( self.max_score, self.resolving_package )
 
 		return None
@@ -91,7 +91,6 @@ class SimpleRule ( deprule.DependencyRule ):
 		"""Generates text lines for this rule that can later be read using
 		the SimpleDependencyRuleReader.
 		"""
-		# todo hardcoded rule format here
 		if self.resolving_package is None:
 			resolving = ''
 		else:
@@ -111,7 +110,7 @@ class SimpleRule ( deprule.DependencyRule ):
 			pass
 
 		elif len ( self.dep_alias ) == 1:
-			yield "%s :: %s" % ( resolving, iter ( self.dep_alias ).next() )
+			yield "{} :: {}".format ( resolving, iter ( self.dep_alias ).next() )
 
 		else:
 			yield resolving + ' {'
@@ -138,9 +137,9 @@ class FuzzySimpleRule ( SimpleRule ):
 		if self._find ( dep_env.dep_str_low, lowercase=True ):
 			# non-fuzzy match
 			self.logger.debug (
-				"matches %s with score %i and priority %i."
-					% ( dep_env.dep_str, self.max_score, self.priority )
-			)
+				"matches {dep_str} with score {s} and priority {p}.".format (
+					dep_str=dep_env.dep_str, s=self.max_score, p=self.priority
+			) )
 			return ( self.fuzzy_score[3], self.resolving_package )
 
 		elif hasattr ( dep_env, 'fuzzy' ):
@@ -194,9 +193,10 @@ class FuzzySimpleRule ( SimpleRule ):
 
 
 						self.logger.debug (
-							"fuzzy-match: %s resolved as '%s' with score=%i."
-								% ( dep_env.dep_str, res, score )
-						)
+							'fuzzy-match: {dep_str} resolved as {dep!r} '
+							'with score={s}.'.format (
+								dep_str=dep_env.dep_str, dep=res, s=score
+						) )
 						return ( score, res )
 					# --- if find (=match found)
 				# --- if name in
@@ -205,6 +205,3 @@ class FuzzySimpleRule ( SimpleRule ):
 
 		return None
 	# --- end of matches (...) ---
-
-
-

diff --git a/roverlay/depres/simpledeprule/console.py b/roverlay/depres/simpledeprule/console.py
index 2677a44..8292f4c 100644
--- a/roverlay/depres/simpledeprule/console.py
+++ b/roverlay/depres/simpledeprule/console.py
@@ -4,7 +4,7 @@ import sys
 import shlex
 import logging
 
-from roverlay import config, util
+from roverlay import config, strutil
 from roverlay.errorqueue                     import ErrorQueue
 from roverlay.depres                         import deptype
 from roverlay.depres.depresolver             import DependencyResolver
@@ -42,14 +42,14 @@ class PackageDirRuleMaker ( object ):
 		if self.fuzzy:
 			for dep in self._scan ( distdir ):
 				yield rules.SimpleFuzzyDependencyRule (
-					resolving_package = util.fix_ebuild_name ( cat + dep ),
+					resolving_package = strutil.fix_ebuild_name ( cat + dep ),
 					dep_str = dep,
 					is_selfdep=True
 				)
 		else:
 			for dep in self._scan ( distdir ):
 				yield rules.SimpleDependencyRule (
-					resolving_package = util.fix_ebuild_name ( cat + dep ),
+					resolving_package = strutil.fix_ebuild_name ( cat + dep ),
 					dep_str = dep,
 					is_selfdep=True
 				)


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/simpledeprule/, roverlay/depres/
@ 2013-07-03 10:05 André Erdmann
  0 siblings, 0 replies; 9+ messages in thread
From: André Erdmann @ 2013-07-03 10:05 UTC (permalink / raw
  To: gentoo-commits

commit:     72af9d204837cbabf32c43ffcc50ebec93549f7f
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jun 28 06:19:14 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jun 28 06:19:14 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=72af9d20

roverlay/depres: add SLOT handling to fuzzy depres

---
 roverlay/depres/depenv.py                      |  32 ++++-
 roverlay/depres/deprule.py                     |   2 +
 roverlay/depres/simpledeprule/abstractrules.py | 148 +++++++++----------
 roverlay/depres/simpledeprule/rulemaker.py     |  42 ++----
 roverlay/depres/simpledeprule/rules.py         | 192 +++++++++++++++++++++++--
 5 files changed, 303 insertions(+), 113 deletions(-)

diff --git a/roverlay/depres/depenv.py b/roverlay/depres/depenv.py
index 3021728..9371ef6 100644
--- a/roverlay/depres/depenv.py
+++ b/roverlay/depres/depenv.py
@@ -62,6 +62,27 @@ class DepEnv ( object ):
    # { <, >, ==, <=, >=, =, != }
    _VERMOD = '(?P<vmod>[<>]|[=<>!]?[=])'
 
+   # integer representation of version modifiers
+   VMOD_NONE  = 0
+   VMOD_UNDEF = 1
+   VMOD_NOT   = 2
+   VMOD_EQ    = 4
+   VMOD_NE    = VMOD_NOT | VMOD_EQ
+   VMOD_GT    = 8
+   VMOD_GE    = VMOD_EQ | VMOD_GT
+   VMOD_LT    = 16
+   VMOD_LE    = VMOD_EQ | VMOD_LT
+
+   VMOD = {
+      '!=' : VMOD_NE,
+      '='  : VMOD_EQ,
+      #'==' : VMOD_EQ, # normalized by _depslit()
+      '>'  : VMOD_GT,
+      '>=' : VMOD_GE,
+      '<'  : VMOD_LT,
+      '<=' : VMOD_LE,
+   }
+
    # name/version regexes used for fuzzy dep rules
    VERSION_REGEX = frozenset (
       re.compile ( r ) for r in ((
@@ -146,12 +167,19 @@ class DepEnv ( object ):
             if version [0] == '.': version = '0' + version
 
             vmod = m.group ( 'vmod' )
-            if vmod == '==' : vmod = '='
+
+            if not vmod:
+               # version required, but no modifier: set vmod to '>='
+               vmod = '>='
+            elif vmod == '==':
+               # "normalize"
+               vmod = '='
 
             result.append ( dict (
                name             = m.group ( 'name' ),
                version_modifier = vmod,
-               version          = version
+               version          = version,
+               vmod             = self.VMOD.get ( vmod, self.VMOD_UNDEF ),
             ) )
 
             if not self.try_all_regexes: break

diff --git a/roverlay/depres/deprule.py b/roverlay/depres/deprule.py
index b440d36..46c710d 100644
--- a/roverlay/depres/deprule.py
+++ b/roverlay/depres/deprule.py
@@ -19,6 +19,7 @@ class DependencyRule ( object ):
       arguments:
       * priority -- used for sorting rule pools, lower means more important
       """
+      super ( DependencyRule, self ).__init__()
       self.max_score = 1000
       self.priority  = priority
    # --- end of __init__ (...) ---
@@ -42,6 +43,7 @@ class DependencyRulePool ( object ):
       * name -- name of this rule pool
       * priority -- priority of this pool (lower is better)
       """
+      super ( DependencyRulePool, self ).__init__()
       if initial_rules is None:
          self.rules = list()
       else:

diff --git a/roverlay/depres/simpledeprule/abstractrules.py b/roverlay/depres/simpledeprule/abstractrules.py
index 1025b01..85c365d 100644
--- a/roverlay/depres/simpledeprule/abstractrules.py
+++ b/roverlay/depres/simpledeprule/abstractrules.py
@@ -107,7 +107,7 @@ class SimpleRule ( deprule.DependencyRule ):
          resolving = self.resolving_package
 
          if self.is_selfdep:
-            resolving = resolving.split ( '/', 1 ) [1]
+            resolving = resolving.rpartition ( '/' ) [2]
 
 
       if hasattr ( self.__class__, 'RULE_PREFIX' ):
@@ -132,86 +132,90 @@ class SimpleRule ( deprule.DependencyRule ):
       return '\n'.join ( self.export_rule() )
 
 
-
 class FuzzySimpleRule ( SimpleRule ):
 
+   # 0 : version-relative, 1 : name only, 2 : std
+   FUZZY_SCORE = ( 1250, 1000, 750 )
+   max_score   = max ( FUZZY_SCORE )
+
    def __init__ ( self, *args, **kw ):
-      super ( FuzzySimpleRule, self ) . __init__ ( *args, **kw )
+      super ( FuzzySimpleRule, self ).__init__ ( *args, **kw )
       self.prepare_lowercase_alias = True
+   # --- end of __init__ (...) ---
 
-      # 0 : version with modifier, 1 : version w/o mod, 2 : name only, 3 : std
-      self.fuzzy_score = ( 1250, 1000, 750, 500 )
-      self.max_score   = max ( self.fuzzy_score )
-
-   def matches ( self, dep_env ):
+   def match_prepare ( self, dep_env ):
       if self._find ( dep_env.dep_str_low, lowercase=True ):
-         # non-fuzzy match
-         self.logger.debug (
-            "matches {dep_str} with score {s} and priority {p}.".format (
-               dep_str=dep_env.dep_str, s=self.max_score, p=self.priority
-         ) )
-         return ( self.fuzzy_score[3], self.resolving_package )
-
-      elif hasattr ( dep_env, 'fuzzy' ):
-         for fuzzy in dep_env.fuzzy:
-            if 'name' in fuzzy:
-               if self._find ( fuzzy ['name'], lowercase=True ):
-                  # fuzzy match found
-
-                  if self.resolving_package is None:
-                     # ignore rule
-                     res   = None
-                     score = self.fuzzy_score [2]
-
-
-                  elif 'version' in fuzzy:
-
-                     ver_pkg = \
-                        self.resolving_package + '-' +  fuzzy ['version']
-
-                     vmod = fuzzy ['version_modifier'] \
-                           if 'version_modifier' in fuzzy \
-                        else None
-
-                     if vmod:
-                        if '!' in vmod:
-                           # package matches, but specific version is forbidden
-                           # ( !<package>-<specific verion> <package> )
-                           res = '( !=%s %s )' % (
-                              ver_pkg,
-                              self.resolving_package
-                           )
+         return ( 2, None )
 
-                        else:
-                           # std vmod: >=, <=, =, <, >
-                           res = vmod + ver_pkg
+      elif not hasattr ( dep_env, 'fuzzy' ):
+         return None
 
-                        score = self.fuzzy_score[0]
-
-                     else:
-                        # version required, but no modifier: defaults to '>='
-
-                        res   = '>=' + ver_pkg
-                        score = self.fuzzy_score[1]
-
-                  else:
-                     # substring match
-                     #  currently not possible (see DepEnv's regexes)
-                     score = fuzzy[2]
-                     res   = self.resolving_package
-                  # --- if resolving... elif version ... else
+      elif self.resolving_package is None:
+         # ignore rule
+         for fuzzy in dep_env.fuzzy:
+            if self._find ( fuzzy ['name'], lowercase=True ):
+               return ( 1, fuzzy )
+      else:
+         for fuzzy in dep_env.fuzzy:
+            if self._find ( fuzzy ['name'], lowercase=True ):
+               return ( 0, fuzzy )
+            # -- end if find (=match found)
+      # -- end if
+      return None
+   # --- end of match_prepare (...) ---
 
+   def log_fuzzy_match ( self, dep_env, dep, score ):
+      if dep is False:
+         return None
+      else:
+         self.logger.debug (
+            'fuzzy-match: {dep_str} resolved as '
+            '{dep!r} with score={s}'.format (
+               dep_str=dep_env.dep_str, dep=dep, s=score
+            )
+         )
+         return ( score, dep )
+   # --- end of log_fuzzy_match (...) ---
+
+   def log_standard_match ( self, dep_env, score ):
+      if dep is False:
+         return None
+      else:
+         self.logger.debug (
+            "matches {dep_str} with score {s} and priority {p}.".format (
+               dep_str=dep_env.dep_str, s=score, p=self.priority
+            )
+         )
+         return ( score, self.resolving_package )
+   # --- end of log_standard_match (...) ---
 
-                  self.logger.debug (
-                     'fuzzy-match: {dep_str} resolved as {dep!r} '
-                     'with score={s}.'.format (
-                        dep_str=dep_env.dep_str, dep=res, s=score
-                  ) )
-                  return ( score, res )
-               # --- if find (=match found)
-            # --- if name in
-         # --- for fuzzy
-      # --- elif hasattr
+   def handle_version_relative_match ( self, dep_env, fuzzy ):
+      raise NotImplementedError()
+   # --- end of handle_version_relative_match (...) ---
 
-      return None
+   def matches ( self, dep_env ):
+      partial_result = self.match_prepare ( dep_env )
+      if partial_result is None:
+         return None
+      else:
+         match_type, fuzzy = partial_result
+         score = self.FUZZY_SCORE [match_type]
+         if match_type == 0:
+            # real version-relative match
+            return self.log_fuzzy_match (
+               dep_env,
+               self.handle_version_relative_match ( dep_env, fuzzy ),
+               score
+            )
+         elif match_type == 1:
+            # name-only match (ignore rule?)
+            return self.log_fuzzy_match (
+               dep_env, self.resolving_package, score
+            )
+         else:
+            # non-fuzzy match
+            return self.log_standard_match ( dep_env, score )
+      # -- end if partial_result
    # --- end of matches (...) ---
+
+# --- end of FuzzySimpleRule ---

diff --git a/roverlay/depres/simpledeprule/rulemaker.py b/roverlay/depres/simpledeprule/rulemaker.py
index 6c3bc0e..a993341 100644
--- a/roverlay/depres/simpledeprule/rulemaker.py
+++ b/roverlay/depres/simpledeprule/rulemaker.py
@@ -23,29 +23,6 @@ from roverlay.depres.simpledeprule.abstractrules import *
 from roverlay.depres.simpledeprule.pool import SimpleDependencyRulePool
 
 class SimpleRuleMaker ( object ):
-   class RuleKeywords ( object ):
-      def __init__ ( self ):
-         self._default_rule, self._rule_map = rules.get_rule_map()
-
-      def lookup ( self, keyworded_string ):
-         """Returns <matching rule class>, <keyworded_string without kw>."""
-         if len ( keyworded_string ) == 0:
-            cls    = self._default_rule
-            kwless = None
-         else:
-            # all keywords have length 1
-            kw = keyworded_string [0]
-            if kw in self._rule_map:
-               cls    = self._rule_map [kw]
-               kwless = keyworded_string[1:].lstrip()
-               if len ( kwless ) == 0:
-                  kwless = None
-            else:
-               cls    = self._default_rule
-               kwless = keyworded_string
-
-         return ( cls, kwless )
-      # --- end of lookup (...) ---
 
    def __init__ ( self, rule_separator=None ):
       self.logger = logging.getLogger ( self.__class__.__name__ )
@@ -57,7 +34,9 @@ class SimpleRuleMaker ( object ):
       self.multiline_start = '{'
       self.multiline_stop  = '}'
       self.comment_char    = '#'
-      self._kw             = self.__class__.RuleKeywords()
+      self._kwmap          = rules.RuleConstructor (
+         eapi = config.get_or_fail ( 'EBUILD.eapi' )
+      )
       # deptype_kw is '#deptype' (this keyword requires comment 'mode')
       self.deptype_kw      = 'deptype'
       self._deptype        = deptype.ALL
@@ -113,26 +92,29 @@ class SimpleRuleMaker ( object ):
       #  or normal rule 'dev-lang/R :: R'
       # selfdeps are always single line statements (!)
 
-      rule_class, resolving = self._kw.lookup ( dep )
+      rule_class, resolving, kwargs = self._kwmap.lookup ( dep )
 
       if dep_str:
          # normal rule
          new_rule = rule_class (
             resolving_package=resolving,
             dep_str=dep_str,
-            is_selfdep=False
+            is_selfdep=False,
+            **kwargs
          )
 
       elif resolving is not None:
          # selfdep
          dep_str   = resolving
-         resolving = \
+         resolving = (
             config.get_or_fail ( 'OVERLAY.category' ) + '/' + resolving
+         )
 
          new_rule = rule_class (
             resolving_package=resolving,
             dep_str=dep_str,
-            is_selfdep=True
+            is_selfdep=True,
+            **kwargs
          )
       else:
          return False
@@ -175,11 +157,11 @@ class SimpleRuleMaker ( object ):
 
       elif len ( line ) > 1 and line [-1] == self.multiline_start:
          l = line [:-1].rstrip()
-         rule_class, resolving = self._kw.lookup ( l )
+         rule_class, resolving, kwargs = self._kwmap.lookup ( l )
 
          self._next = (
             self._deptype,
-            rule_class ( resolving_package=resolving )
+            rule_class ( resolving_package=resolving, **kwargs ),
          )
          return True
 

diff --git a/roverlay/depres/simpledeprule/rules.py b/roverlay/depres/simpledeprule/rules.py
index 6f006e6..db208d4 100644
--- a/roverlay/depres/simpledeprule/rules.py
+++ b/roverlay/depres/simpledeprule/rules.py
@@ -23,16 +23,85 @@ __all__ = (
 from roverlay.depres.simpledeprule.abstractrules import \
    SimpleRule, FuzzySimpleRule
 
-def get_rule_map():
-   kwmap = { c.RULE_PREFIX : c for c in (
-      SimpleIgnoreDependencyRule,
-      SimpleFuzzyDependencyRule,
-      SimpleFuzzyIgnoreDependencyRule
-   ) }
+class RuleConstructor ( object ):
 
-   return ( SimpleDependencyRule, kwmap )
-# --- end of get_rule_map (...) ---
+   def __init__ ( self, eapi ):
+      self.eapi = eapi
 
+      self.kw_ignore       = SimpleIgnoreDependencyRule.RULE_PREFIX
+      self.kw_fuzzy        = SimpleFuzzyDependencyRule.RULE_PREFIX
+      self.kw_fuzzy_ignore = SimpleFuzzyIgnoreDependencyRule.RULE_PREFIX
+   # --- end of __init__ (...) ---
+
+   def lookup ( self, keyworded_str ):
+      get_kwless = lambda : keyworded_str[1:].lstrip() or None
+
+      kw = keyworded_str[0]
+      if kw == self.kw_ignore:
+         return ( SimpleIgnoreDependencyRule, get_kwless(), {} )
+      elif kw == self.kw_fuzzy_ignore:
+         return ( SimpleFuzzyIgnoreDependencyRule, get_kwless(), {} )
+      elif kw == self.kw_fuzzy:
+         ##TODO
+         ## > "default"
+         ## > "slot only"
+         ## > "combined"
+   ## syntax
+   ## ~cat/pkg:<slot suffix>
+   ## ~cat/pkg:/<slot suffix>
+   ## ~cat/pkg:{major}/{minor}<slot suffix>
+   ##
+         kwless = get_kwless()
+         resolving, sepa, remainder = kwless.partition ( ':' )
+
+         if sepa:
+            # fuzzy slot rule
+            kwargs = { 'resolving_package_name' : resolving, }
+            slot_head, slot_sepa, slot_rem = remainder.partition ( ':' )
+
+            if slot_sepa:
+               # slot restriction
+               istart, isepa, istop = slot_head.partition ( '..' )
+               if isepa:
+                  kwargs ['slot_restrict'] = frozenset (
+                     range ( int ( istart or 0 ), int ( istop or 100 ) + 1 )
+                  )
+               else:
+                  kwargs ['slot_restrict'] = frozenset (
+                     int ( k ) for k in slot_head.split ( ',' )
+                  )
+
+               remainder = slot_rem
+            else:
+               remainder = slot_head
+            # -- end if;
+
+
+            if not remainder:
+               # <cat>/<pkg>:
+               kwargs ['slot_suffix'] = sepa + '{slot}'
+
+            elif remainder[0] in { '/', '*', '=' }:
+               # subslot, "any slot" operators
+               assert self.eapi >= 5
+               kwargs ['slot_suffix'] = sepa + '{slot}' + remainder
+            else:
+               kwargs ['slot_suffix'] = sepa + remainder
+
+
+            # verify that slot_suffix can be formatted properly
+##            if kwargs ['slot_suffix'] [0] != ':':
+##               kwargs ['slot_suffix'] = ':' + kwargs ['slot_suffix']
+
+            DONT_CARE = kwargs ['slot_suffix'].format ( slot='_', version='_' )
+            return ( SimpleFuzzySlotDependencyRule, resolving, kwargs )
+         else:
+            return ( SimpleFuzzyDependencyRule, kwless, {} )
+      else:
+         return ( SimpleDependencyRule, keyworded_str, {} )
+   # --- end of lookup (...) ---
+
+# --- end of RuleConstructor ---
 
 class SimpleIgnoreDependencyRule ( SimpleRule ):
 
@@ -90,14 +159,119 @@ class SimpleFuzzyIgnoreDependencyRule ( FuzzySimpleRule ):
       else:
          return super ( self.__class__, self ) . __str__()
 
+   def handle_version_relative_match ( self, *args, **kwargs ):
+      raise Exception ( "should-be unreachable code" )
+   # --- end of handle_version_relative_match (...) ---
+
+# --- end of SimpleFuzzyIgnoreDependencyRule ---
+
+
 class SimpleFuzzyDependencyRule ( FuzzySimpleRule ):
 
    RULE_PREFIX = '~'
 
-   def __init__ ( self, priority=71, resolving_package=None, **kw ):
+   def __init__ ( self, priority=72, resolving_package=None, **kw ):
       super ( SimpleFuzzyDependencyRule, self ) . __init__ (
          priority=priority,
          resolving_package=resolving_package,
          logger_name = 'FUZZY.' + resolving_package,
          **kw
       )
+   # --- end of __init__ (...) ---
+
+   def handle_version_relative_match ( self, dep_env, fuzzy ):
+      ver_pkg  = self.resolving_package + '-' + fuzzy ['version']
+      vmod_str = fuzzy ['version_modifier']
+      vmod     = fuzzy ['vmod']
+
+      #if vmod & dep_env.VMOD_NOT:
+      if vmod == dep_env.VMOD_NE:
+         # package matches, but specific version is forbidden
+         # ( !<package>-<specific verion> <package> )
+         return "( !={vres} {res} )".format (
+            vres=ver_pkg, res=self.resolving_package
+         )
+      else:
+         # std vmod: >=, <=, =, <, >
+         return vmod_str + ver_pkg
+   # --- end of handle_version_relative_match (...) ---
+
+# --- end of SimpleFuzzyDependencyRule ---
+
+
+class SimpleFuzzySlotDependencyRule ( FuzzySimpleRule ):
+   # 2 slot variants
+   # "slot only": resolve dep_str as <cat>/<pkg>:<slot>
+   # "combined": resolve dep_str as <vmod><cat>/<pkg>-<ver>:<slot>
+
+#   FMT_DICT = {
+#      'slot' : '{slot}',
+#   }
+
+   #RULE_PREFIX = '~'
+   RULE_PREFIX = SimpleFuzzyDependencyRule.RULE_PREFIX
+
+   def __init__ ( self,
+      priority               = 71,
+      resolving_package      = None,
+      resolving_package_name = None,
+      slot_suffix            = None,
+      slot_restrict          = None,
+      **kw
+   ):
+      super ( SimpleFuzzySlotDependencyRule, self ) . __init__ (
+         priority=priority,
+         resolving_package = resolving_package,
+         logger_name       = 'FUZZY_SLOT.' + (
+            resolving_package_name if resolving_package_name is not None
+            else resolving_package.partition ( ':' )[0]
+         ),
+         **kw
+      )
+
+      self.slot_suffix = slot_suffix
+
+      if slot_restrict:
+         self.slot_restrict = frozenset ( int ( k ) for k in slot_restrict )
+      else:
+         self.slot_restrict = None
+   # --- end of __init__ (...) ---
+
+   def __str__ ( self ):
+      # FIXME/TODO
+      return 'TODO! {low}..{high} {s}'.format (
+         low  = ( min ( self.slot_restrict ) if self.slot_restrict else 'X' ),
+         high = ( max ( self.slot_restrict ) if self.slot_restrict else 'X' ),
+         s    = ( super ( SimpleFuzzySlotDependencyRule, self ).__str__() ),
+      )
+   # --- end of __str__ (...) ---
+
+   def handle_version_relative_match ( self, dep_env, fuzzy ):
+      res  = False
+      vmod = fuzzy ['vmod']
+
+      if not ( vmod & dep_env.VMOD_NOT ):
+         # can be resolved as slot(ted) dep
+
+         ver_str = fuzzy ['version']
+         v_major, sepa, v_remainder = ver_str.partition ( '.' )
+         try:
+            slot = int ( v_major )
+
+            # resolve '<' and '>' by decrementing/incrementing slot
+            if vmod == dep_env.VMOD_LT:
+               slot -= 1
+            elif vmod == dep_env.VMOD_GT:
+               slot += 1
+
+            if not self.slot_restrict or slot in self.slot_restrict:
+               res = self.resolving_package + self.slot_suffix.format (
+                  slot=slot, version=ver_str,
+                  #vmod=fuzzy ['version_modifier']
+               )
+         except ValueError:
+            pass
+      # -- end if vmod
+
+      return res
+   # --- end of handle_version_relative_match (...) ---


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/simpledeprule/, roverlay/depres/
  2013-07-02 21:09 [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
@ 2013-07-03 10:05 ` André Erdmann
  0 siblings, 0 replies; 9+ messages in thread
From: André Erdmann @ 2013-07-03 10:05 UTC (permalink / raw
  To: gentoo-commits

commit:     bd91581d7a6cc12e2cfe9aa45a69ac5cdfdc6f67
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Tue Jul  2 20:58:50 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Tue Jul  2 20:58:50 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=bd91581d

roverlay/depres: configurable slot values

This commit (mainly) adds feature to FuzzySlotDependencyRule
* the relevant parts of a version string that make up the slot or subslot value
  are configurable now
* slot rule modes: "open", "with version", "default"
* slot range restrict has been removed

---
 roverlay/depres/depenv.py              |  16 ++
 roverlay/depres/simpledeprule/rules.py | 339 +++++++++++++++++----------------
 roverlay/depres/simpledeprule/util.py  | 160 ++++++++++++++++
 3 files changed, 350 insertions(+), 165 deletions(-)

diff --git a/roverlay/depres/depenv.py b/roverlay/depres/depenv.py
index 9371ef6..c298447 100644
--- a/roverlay/depres/depenv.py
+++ b/roverlay/depres/depenv.py
@@ -175,10 +175,26 @@ class DepEnv ( object ):
                # "normalize"
                vmod = '='
 
+            version_strlist = version.split ( '.' )
+            version_iparts  = list()
+
+            for v in version_strlist:
+               #i = None
+               try:
+                  i = int ( v )
+                  version_iparts.append ( i )
+               except ValueError:
+                  v2 = v.partition ( '_' )[0].partition ( '-' ) [0]
+                  version_iparts.append ( int ( v2 ) if v2 else 0 )
+
+
+
             result.append ( dict (
                name             = m.group ( 'name' ),
                version_modifier = vmod,
                version          = version,
+               version_strlist  = version_strlist,
+               version_tuple    = tuple ( version_iparts ),
                vmod             = self.VMOD.get ( vmod, self.VMOD_UNDEF ),
             ) )
 

diff --git a/roverlay/depres/simpledeprule/rules.py b/roverlay/depres/simpledeprule/rules.py
index ac3fa89..999a8b4 100644
--- a/roverlay/depres/simpledeprule/rules.py
+++ b/roverlay/depres/simpledeprule/rules.py
@@ -20,88 +20,15 @@ __all__ = (
    'SimpleFuzzyDependencyRule', 'SimpleFuzzyIgnoreDependencyRule'
 )
 
-from roverlay.depres.simpledeprule.abstractrules import \
-   SimpleRule, FuzzySimpleRule
-
-class SlotRestrict ( object ):
-   def accepts ( self, k ):
-      """Returns True if k is allowed, else False.
 
-      arguments:
-      * k -- int
-      """
-      return True
+from roverlay.depres.simpledeprule.util import \
+   RuleFileSyntaxError, get_slot_restrict, get_slot_parser
 
-   def __bool__ ( self ):
-      return True
-
-   def noexport ( self ):
-      pass
-
-   def __str__ ( self ):
-      return ':'
-# --- end of SlotRestrict ---
-
-class SlotRangeRestrict ( SlotRestrict ):
-   DEFAULT_LOW  = 0
-   DEFAULT_HIGH = 1000
-
-   def __init__ ( self, low, high ):
-      super ( SlotRangeRestrict, self ).__init__()
-      if low:
-         self.low = int ( low )
-      else:
-         self.low = self.DEFAULT_LOW
-         self._implicit_low = True
-
-      if high:
-         self.high = int ( high )
-      else:
-         self.high = self.DEFAULT_HIGH
-         self._implicit_high = True
-   # --- end of __init__ (...) ---
-
-   def noexport ( self ):
-      if hasattr ( self, '_implicit_low' ):
-         del self._implicit_low
-      if hasattr ( self, '_implicit_high' ):
-         del self._implicit_high
-   # --- end of noexport (...) ---
-
-   def accepts ( self, k ):
-      """Returns True if k is allowed, else False.
-
-      arguments:
-      * k -- int
-      """
-      return k >= self.low and k <= self.high
-
-   def __str__ ( self ):
-      return ":{low}..{high}".format (
-         low  = ( '' if hasattr ( self, '_implicit_low'  ) else self.low  ),
-         high = ( '' if hasattr ( self, '_implicit_high' ) else self.high ),
-      )
-   # --- end of __str__ (...) ---
-
-# --- end of SlotRangeRestrict ---
-
-class SlotSetRestrict ( SlotRestrict ):
-   def __init__ ( self, iterable ):
-      self._iset = frozenset ( int ( k ) for k in iterable )
-
-   def accepts ( self, k ):
-      """Returns True if k is allowed, else False.
+from roverlay.depres.simpledeprule.abstractrules import \
+   SimpleRule, FuzzySimpleRule
 
-      arguments:
-      * k -- int
-      """
-      return k in self._iset
 
-   def __str__ ( self ):
-      return ':' + ','.join ( str ( k ) for k in sorted ( self._iset ) )
-   # --- end of __str__ (...) ---
 
-# --- end of SlotSetRestrict ---
 
 class RuleConstructor ( object ):
 
@@ -123,61 +50,85 @@ class RuleConstructor ( object ):
          return ( SimpleFuzzyIgnoreDependencyRule, get_kwless(), {} )
       elif kw == self.kw_fuzzy:
          ## syntax
-         ## ~cat/pkg:<slot range>:<slot suffix>
-         kwless = get_kwless()
-         resolving, sepa, remainder = kwless.partition ( ':' )
-
-         if sepa:
-            # fuzzy slot rule
+         ## ~<cat>/<pkg>[:[<slot option>]]*
+         ##  where slot option is any of
+         ##  * slot restrict (range, list)
+         ##  * "with version", "open" ("*" and "=" slot operators)
+         ##  * relevant version parts ("1.2.3.4" => "1" if 1, "1.2" if 2, ...)
+         ##  * relevant subslot version parts ("1.2.3.4" => <SLOT>/<SUBSLOT?>)
+         ##  * slot operator ("=")
+
+         kwless          = get_kwless()
+         line_components = kwless.split ( ':' )
+
+         if len ( line_components ) < 2:
+            # non-slot fuzzy rule
+            return ( SimpleFuzzyDependencyRule, kwless, {} )
+         else:
             kwargs = dict()
-            slot_head, slot_sepa, slot_rem = remainder.partition ( ':' )
-
-            if slot_sepa:
-               # int range restriction
-               istart, isepa, istop = slot_head.partition ( '..' )
-               if isepa:
-                  kwargs ['slot_restrict'] = SlotRangeRestrict (
-                     low=istart, high=istop
-                  )
-               else:
-                  # int list restriction
+            lc_iter = iter ( line_components )
+            # drop first item as it's the resolving string and not an option
+            next ( lc_iter )
+            for opt_str in lc_iter:
+               opt, has_value, value = opt_str.partition ( '=' )
 
-                  # "filter(None,...)" filters 0 but not '0'
-                  istr_list = list (
-                     filter ( None, slot_head.split ( ',' ) )
-                     #filter ( lambda s : s or s == 0, slot_head.split ( ',' ) )
-                  )
+               if not opt_str:
+                  # empty
+                  pass
+               elif opt == 'default':
+                  kwargs ['slot_mode'] = 0
 
-                  if istr_list:
-                     kwargs ['slot_restrict'] = SlotSetRestrict ( istr_list )
+               elif opt == 'with_version' or opt == '+v':
+                  kwargs ['slot_mode'] = 1
 
-               remainder = slot_rem
-            else:
-               #kwargs ['slot_restrict'] = SlotRestrict()
-               remainder = slot_head
-            # -- end if;
-
-            if remainder[:2] == '+v':
-               kwargs ['with_version'] = True
-               remainder = remainder[2:]
-            # -- end if;
-
-            if not remainder:
-               pass
-            elif remainder[0] in { '/', '*', '=' }:
-               # subslot, "any slot" operators
-               # (subslots don't seem to make much sense here)
-
-               ##if self.eapi < 5: raise ...
-               kwargs ['slot_suffix'] = remainder
+               elif opt == 'open':
+                  kwargs ['slot_mode'] = 2
+
+               elif ( opt == 'restrict' or opt == 'r' ) and value:
+                  kwargs ['slot_restrict'] = get_slot_restrict ( value )
+
+               elif ( opt == 'slotparts' or opt == 's' ) and value:
+                  kwargs ['slotparts'] = get_slot_parser ( value )
+
+               elif ( opt == 'subslotparts' or opt == '/' ) and value:
+                  kwargs ['subslotparts'] = get_slot_parser ( value )
+
+               elif opt_str[0] == '/' and not has_value:
+                  kwargs ['subslotparts'] = get_slot_parser ( opt_str[1:] )
+
+#               elif opt == 'operator' and value:
+#                  # unsafe, could be used to inject "$(rm -rf /)" etc.
+#                  kwargs ['slot_operator'] = value
+
+               elif opt == '*':
+                  kwargs ['slot_operator'] = '*'
+
+               elif not opt and has_value:
+                  # "="
+                  kwargs ['slot_operator'] = '='
+                  pass
+
+               else:
+                  raise RuleFileSyntaxError (
+                     "cannot parse option {!r} from {!r}".format (
+                        opt_str, kwless
+                     )
+                  )
+            # -- end for lc_iter
+
+            if (
+               kwargs.get ( 'slot_operator' ) == '*'
+               and kwargs.get ( 'slot_mode' ) != 2
+            ):
+               raise RuleFileSyntaxError (
+                  "The '*' slot operator needs an 'open' rule."
+               )
             else:
-               raise Exception (
-                  "unknown slot rule remainder {!r}".format ( remainder )
+               return (
+                  SimpleFuzzySlotDependencyRule, line_components[0], kwargs
                )
+         # -- end if line_components
 
-            return ( SimpleFuzzySlotDependencyRule, resolving, kwargs )
-         else:
-            return ( SimpleFuzzyDependencyRule, kwless, {} )
       else:
          return ( SimpleDependencyRule, keyworded_str, {} )
    # --- end of lookup (...) ---
@@ -295,9 +246,11 @@ class SimpleFuzzySlotDependencyRule ( FuzzySimpleRule ):
    def __init__ ( self,
       priority          = 71,
       resolving_package = None,
-      slot_suffix       = None,
+      slot_mode         = None,
       slot_restrict     = None,
-      with_version      = False,
+      slotparts         = None,
+      subslotparts      = None,
+      slot_operator     = None,
       **kw
    ):
       super ( SimpleFuzzySlotDependencyRule, self ) . __init__ (
@@ -307,39 +260,93 @@ class SimpleFuzzySlotDependencyRule ( FuzzySimpleRule ):
          **kw
       )
 
-      self.slot_suffix   = slot_suffix
+      self.mode          = 0 if slot_mode is None else slot_mode
       self.slot_restrict = slot_restrict
-
-      if with_version:
+      self.slot_operator = slot_operator
+      self.slotparts     = get_slot_parser ("0") if slotparts is None else slotparts
+      self.subslotparts  = subslotparts
+
+      if self.mode == 0:
+         # "default"
+         self._resolving_fmt = self.resolving_package + ':{slot}'
+         if self.slot_operator:
+            self._resolving_fmt += self.slot_operator
+
+      elif self.mode == 1:
+         # "with version"
          self._resolving_fmt = (
             '{vmod}' + self.resolving_package + '-{version}:{slot}'
-            + ( slot_suffix or '' )
          )
-         self.with_version = True
+         if self.slot_operator:
+            self._resolving_fmt += self.slot_operator
+
+      elif self.mode == 2:
+         # "open" slot
+         if not self.slot_operator:
+            self.slot_operator = '='
+
+         del self.slot_restrict
+
+         self._orig_resolving_package = self.resolving_package
+         self.resolving_package += ':' + self.slot_operator
       else:
-         self._resolving_fmt = (
-            self.resolving_package + ':{slot}' + ( slot_suffix or '' )
+         raise Exception (
+            "unknown fuzzy slot rule mode {}".format ( self.mode )
          )
-         self.with_version = False
+
+
 
       if self.is_selfdep:
          raise NotImplementedError ( "fuzzy slot rule must not be a selfdep." )
    # --- end of __init__ (...) ---
 
    def noexport ( self ):
-      del self.slot_suffix
-      del self.with_version
+      del self.slot_operator
+      del self.mode
       if self.slot_restrict:
          self.slot_restrict.noexport()
    # --- end of noexport (...) ---
 
    def get_resolving_str ( self ):
-      return "{prefix}{resolv}{restrict}:{flags}{slot}".format (
-         prefix   = self.RULE_PREFIX,
-         resolv   = self.resolving_package,
-         restrict = ( self.slot_restrict or '' ),
-         flags    = ( '+v' if self.with_version else '' ),
-         slot     = ( self.slot_suffix or '' ),
+      ## syntax
+      ## ~<cat>/<pkg>[:[<slot option>]]*
+      ##  where slot option is any of
+      ##  * slot restrict (range, list)
+      ##  * "with version", "open" ("*" and "=" slot operators)
+      ##  * relevant version parts ("1.2.3.4" => "1" if 1, "1.2" if 2, ...)
+      ##  * relevant subslot version parts ("1.2.3.4" => <SLOT>/<SUBSLOT?>)
+      ##  * slot operator ("=")
+
+      def gen_opts():
+         if self.mode == 2:
+            yield "open"
+         else:
+            if self.mode == 1:
+               yield "with_version"
+
+            if self.slot_restrict:
+               yield "restrict=" + str ( self.slot_restrict )
+
+            if self.slotparts and (
+               not hasattr ( self.slotparts, '_index' )
+               or  self.slotparts._index != 0
+            ):
+               yield "s=" + str ( self.slotparts )
+
+            if self.subslotparts:
+               yield "/" + str ( self.subslotparts )
+         # -- end if
+         if self.slot_operator:
+            yield self.slot_operator
+
+      return "{prefix}{resolv}:{opts}".format (
+         prefix = self.RULE_PREFIX,
+         resolv = (
+            self._orig_resolving_package
+            if hasattr ( self, '_orig_resolving_package' )
+            else self.resolving_package,
+         ),
+         opts   = ':'.join ( gen_opts() )
       )
    # --- end of get_resolving_str (...) ---
 
@@ -350,28 +357,30 @@ class SimpleFuzzySlotDependencyRule ( FuzzySimpleRule ):
       if not ( vmod & dep_env.VMOD_NOT ):
          # can be resolved as slot(ted) dep
 
-         ver_str = fuzzy ['version']
-         v_major, sepa, v_remainder = ver_str.partition ( '.' )
-         try:
-            # TODO/FIXME: slot != int(v_major);
-            #  example: sci-libs/fftw where slots are K.J (2.1, 3.0)
-            slot = int ( v_major )
-
-            # resolve '<' and '>' by decrementing/incrementing slot
-            if vmod == dep_env.VMOD_LT:
-               slot -= 1
-            elif vmod == dep_env.VMOD_GT:
-               slot += 1
-
-            if not self.slot_restrict or self.slot_restrict.accepts ( slot ):
-               res = self._resolving_fmt.format (
-                  slot=slot,
-                  version=ver_str,
-                  vmod=fuzzy ['version_modifier'],
-               )
-         except ValueError:
-            pass
-      # -- end if vmod
+         if self.mode == 2:
+            res = self._resolving_str
+         elif vmod & dep_env.VMOD_EQ:
+            slot_str = None
+            slot     = self.slotparts.get_slot ( fuzzy )
+
+            if slot is not None:
+               if self.subslotparts:
+                  subslot = self.subslotparts.get_slot ( fuzzy )
+                  if subslot is not None:
+                     slot_str = slot + '/' + subslot
+               else:
+                  slot_str = slot
+
+               if slot_str and (
+                  not self.slot_restrict
+                  or self.slot_restrict.accepts ( slot )
+               ):
+                  res = self._resolving_fmt.format (
+                     slot=slot_str,
+                     version=fuzzy['version'], vmod=fuzzy['version_modifier']
+                  )
+
+      # -- end if vmod != NOT
 
       return res
    # --- end of handle_version_relative_match (...) ---

diff --git a/roverlay/depres/simpledeprule/util.py b/roverlay/depres/simpledeprule/util.py
new file mode 100644
index 0000000..0a8311c
--- /dev/null
+++ b/roverlay/depres/simpledeprule/util.py
@@ -0,0 +1,160 @@
+# R overlay -- simple dependency rules
+# -*- coding: utf-8 -*-
+# Copyright (C) 2013 André Erdmann <dywi@mailerd.de>
+# Distributed under the terms of the GNU General Public License;
+# either version 2 of the License, or (at your option) any later version.
+
+
+class RuleFileSyntaxError ( Exception ):
+   pass
+
+
+def get_int_range_or_list (
+   value_str, default_low=0, default_high=1000, list_sepa=','
+):
+   low, sepa, high = value_str.partition ( '..' )
+   if sepa:
+      i_low  = int ( low ) if low else default_low
+      i_high = (
+         int ( high ) if high else (
+            i_low if default_high is True else default_high
+         )
+      )
+      return ( True, i_low, i_high )
+   else:
+      return ( False,
+         tuple ( int ( k ) for k in value_str.split ( list_sepa ) )
+      )
+# --- end get_int_range_or_list (...) ---
+
+
+
+class SlotRestrict ( object ):
+   def accepts ( self, k ):
+      """Returns True if k is allowed, else False.
+
+      arguments:
+      * k -- int
+      """
+      return True
+
+   def __bool__ ( self ):
+      return True
+
+   def noexport ( self ):
+      pass
+
+   def __str__ ( self ):
+      return ''
+# --- end of SlotRestrict ---
+
+class SlotSetRestrict ( SlotRestrict ):
+   def __init__ ( self, iterable ):
+      self._slotset = frozenset ( iterable )
+
+   def accepts ( self, k ):
+      """Returns True if k is allowed, else False.
+
+      arguments:
+      * k -- slot (str)
+      """
+      return k in self._slotset
+
+   def __str__ ( self ):
+      return ','.join ( sorted ( self._slotset ) )
+   # --- end of __str__ (...) ---
+
+# --- end of SlotSetRestrict ---
+
+class SlotValueCreatorBase ( object ):
+
+   def get_slot ( self, *args, **kwargs ):
+      raise NotImplementedError()
+   # --- end of get_slot (...) ---
+
+   def __str__ ( self ):
+      raise NotImplementedError()
+   # --- end of __str__ (...) ---
+
+
+class ImmediateSlotValueCreator ( SlotValueCreatorBase ):
+   def __init__ ( self, v_str ):
+      super ( ImmediateSlotValueCreator, self ).__init__()
+      self._value = v_str
+   # --- end of __init__ (...) ---
+
+   def get_slot ( self, *args, **kwargs ):
+      return self._value
+   # --- end of get_slot (...) ---
+
+   def __str__ ( self ):
+      return "i" + self._value
+
+class SingleIndexValueCreator ( SlotValueCreatorBase ):
+   def __init__ ( self, index ):
+      super ( SingleIndexValueCreator, self ).__init__()
+      self._index = index
+   # --- end of __init__ (...) ---
+
+   def get_slot ( self, fuzzy ):
+      version_components = fuzzy ['version_strlist']
+      if len ( version_components ) > self._index:
+         return version_components [self._index]
+      else:
+         return None
+   # --- end of get_slot (...) ---
+
+   def __str__ ( self ):
+      return str ( self._index )
+
+
+class IndexRangeSlotValueCreator ( SlotValueCreatorBase ):
+   def __init__ ( self, low, high ):
+      super ( IndexRangeSlotValueCreator, self ).__init__()
+      self._low  = low
+      self._high = high + 1 if high >= 0 else high
+
+   def get_slot ( self, fuzzy ):
+      # if self._low > self._high
+      # if self._high < 0: -- dont care
+      version_components = fuzzy ['version_strlist']
+      if len ( version_components ) >= self._high:
+         return '.'.join ( version_components [self._low:self._high] )
+      else:
+         return None
+   # --- end of get_slot (...) ---
+
+   def __str__ ( self ):
+      return str ( self._low ) + '..' + str (
+         ( self._high - 1 ) if self._high > 0 else self._high
+      )
+
+
+def get_slot_parser ( vstr ):
+   if vstr [0] == 'i':
+      # "immediate" value
+      s = vstr [1:]
+      return ImmediateSlotValueCreator ( v_str=s )
+   else:
+      range_or_list = get_int_range_or_list ( vstr, default_high=True )
+      if range_or_list [0]:
+         if range_or_list[1] == range_or_list[2]:
+            return SingleIndexValueCreator ( index=range_or_list[1] )
+         else:
+            return IndexRangeSlotValueCreator (
+               low=range_or_list[1], high=range_or_list[2]
+            )
+      elif len ( range_or_list[1] ) < 2:
+         return SingleIndexValueCreator ( index=range_or_list[1][0] )
+      else:
+         raise RuleFileSyntaxError (
+            "slot part selection must not be a list"
+         )
+# --- end of get_slot_parser (...) ---
+
+def get_slot_restrict ( vstr ):
+   if vstr:
+      return SlotSetRestrict ( vstr.split ( ',' ) )
+   else:
+      return None
+# --- end of get_slot_restrict (...) --


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/R_overlay:gsoc13/next commit in: roverlay/depres/simpledeprule/, roverlay/depres/
@ 2013-07-19 18:00 André Erdmann
  2013-07-23  7:51 ` [gentoo-commits] proj/R_overlay:master " André Erdmann
  0 siblings, 1 reply; 9+ messages in thread
From: André Erdmann @ 2013-07-19 18:00 UTC (permalink / raw
  To: gentoo-commits

commit:     e328ea22ba0d41c4ccab358ae3df49486e6e4e62
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jul 19 17:42:41 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jul 19 17:42:41 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=e328ea22

roverlay/depres/: replace rule pool export_rules()

---
 roverlay/depres/deprule.py            | 23 +++++++++++++++++++++++
 roverlay/depres/simpledeprule/pool.py | 14 +-------------
 2 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/roverlay/depres/deprule.py b/roverlay/depres/deprule.py
index 1d36941..ed6084d 100644
--- a/roverlay/depres/deprule.py
+++ b/roverlay/depres/deprule.py
@@ -40,6 +40,10 @@ class DependencyRule ( object ):
 
    make_result = _make_result
 
+   def export_rule ( self ):
+      raise NotImplementedError()
+   # --- end of export_rule (...) ---
+
 # --- end of DependencyRule ---
 
 
@@ -149,3 +153,22 @@ class DependencyRulePool ( object ):
       # default return
       return None
    # --- end of matches (...) ---
+
+   def export_rules ( self ):
+      """Exports all rules. Typically, this generates text lines."""
+      for rule in self.rules:
+         for item in rule.export_rule():
+            yield item
+   # --- end of export_rules (...) ---
+
+   def export_rules_into ( self, fh ):
+      """Writes all rules into the given file handle.
+
+      arguments:
+      * fh --
+      """
+      NL = '\n'
+      for item in self.export_rules():
+         fh.write ( str ( item ) )
+         fh.write ( NL )
+# --- end of DependencyRulePool ---

diff --git a/roverlay/depres/simpledeprule/pool.py b/roverlay/depres/simpledeprule/pool.py
index 6fcb714..677ad20 100644
--- a/roverlay/depres/simpledeprule/pool.py
+++ b/roverlay/depres/simpledeprule/pool.py
@@ -16,6 +16,7 @@ from roverlay.depres import deprule
 from roverlay.depres.simpledeprule.abstractrules import SimpleRule
 
 class SimpleDependencyRulePool ( deprule.DependencyRulePool ):
+
    def __init__ ( self, name, priority=70, **kw ):
       """Initializes a SimpleDependencyRulePool, which is a DependencyRulePool
       specialized in simple dependency rules;
@@ -43,16 +44,3 @@ class SimpleDependencyRulePool ( deprule.DependencyRulePool ):
       else:
          raise Exception ( "bad usage (simple dependency rule expected)." )
    # --- end of add (...) ---
-
-   def export_rules ( self, fh ):
-      """Exports all rules from this pool into the given file handle.
-
-      arguments:
-      * fh -- object that has a writelines ( list ) method
-
-      raises: IOError (fh)
-      """
-      for rule in self.rules:
-         fh.write ( str ( rule ) )
-         fh.write ( '\n' )
-   # --- end of export_rules (...) ---


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/simpledeprule/, roverlay/depres/
  2013-07-19 18:00 [gentoo-commits] proj/R_overlay:gsoc13/next commit in: roverlay/depres/simpledeprule/, roverlay/depres/ André Erdmann
@ 2013-07-23  7:51 ` André Erdmann
  0 siblings, 0 replies; 9+ messages in thread
From: André Erdmann @ 2013-07-23  7:51 UTC (permalink / raw
  To: gentoo-commits

commit:     e328ea22ba0d41c4ccab358ae3df49486e6e4e62
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jul 19 17:42:41 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jul 19 17:42:41 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=e328ea22

roverlay/depres/: replace rule pool export_rules()

---
 roverlay/depres/deprule.py            | 23 +++++++++++++++++++++++
 roverlay/depres/simpledeprule/pool.py | 14 +-------------
 2 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/roverlay/depres/deprule.py b/roverlay/depres/deprule.py
index 1d36941..ed6084d 100644
--- a/roverlay/depres/deprule.py
+++ b/roverlay/depres/deprule.py
@@ -40,6 +40,10 @@ class DependencyRule ( object ):
 
    make_result = _make_result
 
+   def export_rule ( self ):
+      raise NotImplementedError()
+   # --- end of export_rule (...) ---
+
 # --- end of DependencyRule ---
 
 
@@ -149,3 +153,22 @@ class DependencyRulePool ( object ):
       # default return
       return None
    # --- end of matches (...) ---
+
+   def export_rules ( self ):
+      """Exports all rules. Typically, this generates text lines."""
+      for rule in self.rules:
+         for item in rule.export_rule():
+            yield item
+   # --- end of export_rules (...) ---
+
+   def export_rules_into ( self, fh ):
+      """Writes all rules into the given file handle.
+
+      arguments:
+      * fh --
+      """
+      NL = '\n'
+      for item in self.export_rules():
+         fh.write ( str ( item ) )
+         fh.write ( NL )
+# --- end of DependencyRulePool ---

diff --git a/roverlay/depres/simpledeprule/pool.py b/roverlay/depres/simpledeprule/pool.py
index 6fcb714..677ad20 100644
--- a/roverlay/depres/simpledeprule/pool.py
+++ b/roverlay/depres/simpledeprule/pool.py
@@ -16,6 +16,7 @@ from roverlay.depres import deprule
 from roverlay.depres.simpledeprule.abstractrules import SimpleRule
 
 class SimpleDependencyRulePool ( deprule.DependencyRulePool ):
+
    def __init__ ( self, name, priority=70, **kw ):
       """Initializes a SimpleDependencyRulePool, which is a DependencyRulePool
       specialized in simple dependency rules;
@@ -43,16 +44,3 @@ class SimpleDependencyRulePool ( deprule.DependencyRulePool ):
       else:
          raise Exception ( "bad usage (simple dependency rule expected)." )
    # --- end of add (...) ---
-
-   def export_rules ( self, fh ):
-      """Exports all rules from this pool into the given file handle.
-
-      arguments:
-      * fh -- object that has a writelines ( list ) method
-
-      raises: IOError (fh)
-      """
-      for rule in self.rules:
-         fh.write ( str ( rule ) )
-         fh.write ( '\n' )
-   # --- end of export_rules (...) ---


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/simpledeprule/, roverlay/depres/
@ 2013-09-02 13:20 André Erdmann
  0 siblings, 0 replies; 9+ messages in thread
From: André Erdmann @ 2013-09-02 13:20 UTC (permalink / raw
  To: gentoo-commits

commit:     d686482b9be576f741d0eaa6e17f312dbf0e4e6b
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Sep  2 12:51:57 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Sep  2 12:51:57 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=d686482b

depres rule pools: accept dep_env, not mask

This allows to take the whole dep environment into account when deciding whether
it can be resolved by a specific rule pool or not.

---
 roverlay/depres/depresolver.py           | 10 ++++------
 roverlay/depres/deprule.py               | 15 ++++++++++++++-
 roverlay/depres/simpledeprule/dynpool.py | 11 ++++-------
 3 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/roverlay/depres/depresolver.py b/roverlay/depres/depresolver.py
index eeed396..b5ba075 100644
--- a/roverlay/depres/depresolver.py
+++ b/roverlay/depres/depresolver.py
@@ -390,8 +390,7 @@ class DependencyResolver ( object ):
 
       else:
          for rulepool in (
-            p for p in self.dynamic_rule_pools \
-               if p.accepts ( dep_env.deptype_mask, try_other=False )
+            p for p in self.dynamic_rule_pools if p.accepts ( dep_env )
          ):
             result = rulepool.matches ( dep_env )
             if result:
@@ -403,8 +402,7 @@ class DependencyResolver ( object ):
 
          # search for a match in the rule pools that accept the dep type
          for rulepool in (
-            p for p in self.static_rule_pools \
-               if p.accepts ( dep_env.deptype_mask, try_other=False )
+            p for p in self.static_rule_pools if p.accepts ( dep_env )
          ):
             result = rulepool.matches ( dep_env )
             if result:
@@ -417,8 +415,8 @@ class DependencyResolver ( object ):
             # search for a match in the rule pools
             #  that (normally) don't accept the dep type
             for rulepool in (
-               p for p in self.static_rule_pools \
-                  if p.accepts ( ~dep_env.deptype_mask, try_other=True )
+               p for p in self.static_rule_pools
+                  if p.accepts_other ( dep_env )
             ):
                result = rulepool.matches ( dep_env )
                if result:

diff --git a/roverlay/depres/deprule.py b/roverlay/depres/deprule.py
index ed6084d..800d2af 100644
--- a/roverlay/depres/deprule.py
+++ b/roverlay/depres/deprule.py
@@ -92,11 +92,24 @@ class DependencyRulePool ( object ):
       return None
    # --- end of sort (...) ---
 
-   def accepts ( self, deptype_mask, try_other=False ):
+   def accepts_mask ( self, deptype_mask ):
       """Returns True if this pool accepts the given deptype_mask."""
       return bool ( self.deptype_mask & deptype_mask )
+   # --- end of accepts_mask (...) ---
+
+   def accepts ( self, dep_env ):
+      """Returns True if this pool accepts the given dep env."""
+      return bool ( self.deptype_mask & dep_env.deptype_mask )
    # --- end of accepts (...) ---
 
+   def accepts_other ( self, dep_env ):
+      """Returns True if this pool can be used to resolve a dep env whose
+      deptype mask is rejected by this pool.
+      (Not necessarily the inverse of accepts().)
+      """
+      return not self.accepts ( dep_env )
+   # --- end of accepts_other (...) ---
+
    def add ( self, rule ):
       """Adds a DependencyRule to this rule pool.
 

diff --git a/roverlay/depres/simpledeprule/dynpool.py b/roverlay/depres/simpledeprule/dynpool.py
index 8b6cf20..21e5a1b 100644
--- a/roverlay/depres/simpledeprule/dynpool.py
+++ b/roverlay/depres/simpledeprule/dynpool.py
@@ -36,13 +36,10 @@ class DynamicSelfdepRulePool ( SimpleDependencyRulePool ):
       self._rule_kw_function = rule_kw_function
    # --- end of __init__ (...) ---
 
-   def accepts ( self, deptype_mask, try_other=False ):
-      if try_other:
-         # never resolve external deps as selfdeps
-         return False
-      else:
-         return self.deptype_mask & deptype_mask
-   # --- end of accepts (...) ---
+   def accepts_other ( self, dep_env ):
+      # never resolve external deps as selfdeps
+      return False
+   # --- end of accepts_other (...) ---
 
    def reload ( self ):
       self.rules = list (


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/simpledeprule/, roverlay/depres/
@ 2013-09-02 16:21 André Erdmann
  0 siblings, 0 replies; 9+ messages in thread
From: André Erdmann @ 2013-09-02 16:21 UTC (permalink / raw
  To: gentoo-commits

commit:     92289de61ffeb2cf33954d12f7fbc615111ed604
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Mon Sep  2 16:19:39 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Mon Sep  2 16:19:39 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=92289de6

dynamic selfdep pool: try repo-specific match first

Try to resolve selfdeps within a repo first, before trying to get a match in any
repo.

---
 roverlay/depres/depenv.py                |   4 +
 roverlay/depres/deprule.py               | 237 +++++++++++++++++++++----------
 roverlay/depres/simpledeprule/dynpool.py |  52 +++++--
 3 files changed, 210 insertions(+), 83 deletions(-)

diff --git a/roverlay/depres/depenv.py b/roverlay/depres/depenv.py
index 2e6417e..b20e0b5 100644
--- a/roverlay/depres/depenv.py
+++ b/roverlay/depres/depenv.py
@@ -176,8 +176,12 @@ class DepEnv ( object ):
       self.package_ref  = package_ref
       if package_ref is not None:
          self.get_package_info = self._deref_package_info
+         self.repo_id          = (
+            package_ref.deref_safe().get ( 'origin' ).get_identifier()
+         )
       else:
          self.get_package_info = self._deref_none
+         self.repo_id          = None
 
 
       self.dep_str      = dep_str

diff --git a/roverlay/depres/deprule.py b/roverlay/depres/deprule.py
index 800d2af..66a43f2 100644
--- a/roverlay/depres/deprule.py
+++ b/roverlay/depres/deprule.py
@@ -8,6 +8,8 @@
 
 __all__ = [ 'DependencyRule', 'DependencyRulePool', ]
 
+import roverlay.util.objects
+
 import roverlay.depres.depresult
 
 from roverlay.depres import deptype
@@ -47,26 +49,16 @@ class DependencyRule ( object ):
 # --- end of DependencyRule ---
 
 
-class DependencyRulePool ( object ):
-
-   def __init__ ( self, name, priority, deptype_mask, initial_rules=None ):
-      """Initializes an DependencyRulePool, which basically is a set of
-      dependency rules with methods like "search for x in all rules."
+class DependencyRulePoolBase ( object ):
+   """Base object for dependency rule pools."""
 
-      arguments:
-      * name -- name of this rule pool
-      * priority -- priority of this pool (lower is better)
-      """
-      super ( DependencyRulePool, self ).__init__()
-      if initial_rules is None:
-         self.rules = list()
-      else:
-         self.rules = list ( initial_rules )
-      self._rule_add    = self.rules.append
-      self.name         = name
-      self.priority     = priority
+   def __init__ ( self, name, priority, deptype_mask ):
+      super ( DependencyRulePoolBase, self ).__init__()
+      self.name = name
+      self.priority = priority
       # filter out deptype flags like "mandatory"
       self.deptype_mask = deptype_mask & deptype.RESOLVE_ALL
+
       # the "rule weight" is the sum of the rules' priorities
       #  it's used to compare/sort dependency pools with
       #  the same priority (lesser weight is better)
@@ -75,56 +67,50 @@ class DependencyRulePool ( object ):
 
    def empty ( self ):
       """Returns True if this pool has no rules."""
-      return len ( self.rules ) == 0
+      for rule in self.iter_rules():
+         return False
+      return True
    # --- end of empty (...) ---
 
+   @roverlay.util.objects.abstractmethod
+   def sort_rules ( self ):
+      pass
+   # --- end of sort_rules (...) ---
+
    def sort ( self ):
       """Sorts this rule pool and determines its weight which is used
       to compare rule pools.
       """
-
-      self.rules.sort ( key=lambda rule : rule.priority )
-
-      rule_priority_sum = 0
-      for r in self.rules: rule_priority_sum += r.priority
-      self.rule_weight = rule_priority_sum
-
-      return None
+      self.sort_rules()
+      self.set_rule_weight()
    # --- end of sort (...) ---
 
-   def accepts_mask ( self, deptype_mask ):
-      """Returns True if this pool accepts the given deptype_mask."""
-      return bool ( self.deptype_mask & deptype_mask )
-   # --- end of accepts_mask (...) ---
-
-   def accepts ( self, dep_env ):
-      """Returns True if this pool accepts the given dep env."""
-      return bool ( self.deptype_mask & dep_env.deptype_mask )
-   # --- end of accepts (...) ---
-
-   def accepts_other ( self, dep_env ):
-      """Returns True if this pool can be used to resolve a dep env whose
-      deptype mask is rejected by this pool.
-      (Not necessarily the inverse of accepts().)
-      """
-      return not self.accepts ( dep_env )
-   # --- end of accepts_other (...) ---
+   @roverlay.util.objects.abstractmethod
+   def iter_rules ( self ):
+      return
+   # --- end of iter_rules (...) ---
 
-   def add ( self, rule ):
-      """Adds a DependencyRule to this rule pool.
+   @roverlay.util.objects.abstractmethod ( params=[ 'dep_env' ] )
+   def iter_rules_resolving ( self, dep_env ):
+      pass
+   # --- end of iter_rules_resolving (...) ---
 
-      arguments:
-      * rule --
-      """
-      if issubclass ( rule, DependencyRule ):
-         self._rule_add ( rule )
-      else:
-         raise Exception ( "bad usage (dependency rule expected)." )
+   def get_all_matches ( self, dep_env ):
+      for rule in self.iter_rules_resolving ( dep_env ):
+         result = rule.matches ( dep_env )
+         if result:
+            yield result
+   # --- end of get_all_matches (...) ---
 
+   def matches ( self, dep_env ):
+      for rule in self.iter_rules_resolving ( dep_env ):
+         result = rule.matches ( dep_env )
+         if result:
+            return result
       return None
-   # --- end of add (...) ---
+   # --- end of matches (...) ---
 
-   def matches ( self, dep_env, skip_matches=0 ):
+   def matches_all ( self, dep_env, skip_matches=0 ):
       """Tries to find a match in this dependency rule pool.
       The first match is immediatly returned unless skip_matches is != 0, in
       which case the first (>0) / last (<0) skip_matches matches are skipped.
@@ -141,35 +127,55 @@ class DependencyRulePool ( object ):
          #  cannot expect a result in this case - abort now
          pass
 
-      elif skip_matches == 0:
-         for rule in self.rules:
-            result = rule.matches ( dep_env )
-            if result:
-               return result
-      else:
+      elif skip_matches >= 0:
          skipped = 0
-         # python3 requires list ( range ... )
-         order = list ( range ( len ( self.rules ) ) )
-
-         if skip_matches < 0:
-            skip_matches *= -1
-            order.reverse()
+         for result in self.get_all_matches ( dep_env ):
+            if skipped < skip_matches:
+               skipped += 1
+            else:
+               return result
 
-         for index in order:
-            result = self.rules [index].matches ( dep_env )
-            if result:
-               if skipped < skip_matches:
-                  skipped += 1
-               else:
-                  return result
+      else:
+         matches = list ( self.get_all_matches() )
+         try:
+            return matches [skip_matches]
+         except IndexError:
+            pass
 
       # default return
       return None
-   # --- end of matches (...) ---
+   # --- end of matches_all (...) ---
+
+   def set_rule_weight ( self ):
+      priosum = 0
+      for rule in self.iter_rules():
+         priosum += rule.priority
+      self.rule_weight = priosum
+      return self.rule_weight
+   # --- end of set_rule_weight (...) ---
+
+   def accepts_mask ( self, deptype_mask ):
+      """Returns True if this pool accepts the given deptype_mask."""
+      return bool ( self.deptype_mask & deptype_mask )
+   # --- end of accepts_mask (...) ---
+
+   def accepts ( self, dep_env ):
+      """Returns True if this pool accepts the given dep env."""
+      return bool ( self.deptype_mask & dep_env.deptype_mask )
+   # --- end of accepts (...) ---
+
+   @roverlay.util.objects.abstractmethod
+   def accepts_other ( self, dep_env ):
+      """Returns True if this pool can be used to resolve a dep env whose
+      deptype mask is rejected by this pool.
+      (Not necessarily the inverse of accepts().)
+      """
+      pass
+   # --- end of accepts_other (...) ---
 
    def export_rules ( self ):
       """Exports all rules. Typically, this generates text lines."""
-      for rule in self.rules:
+      for rule in self.iter_rules():
          for item in rule.export_rule():
             yield item
    # --- end of export_rules (...) ---
@@ -184,4 +190,85 @@ class DependencyRulePool ( object ):
       for item in self.export_rules():
          fh.write ( str ( item ) )
          fh.write ( NL )
+   # --- end of exports_rules_into (...) ---
+
+# --- end of DependencyRulePoolBase ---
+
+
+class DependencyRulePool ( DependencyRulePoolBase ):
+
+   def __init__ ( self, name, priority, deptype_mask, initial_rules=None ):
+      """Initializes an DependencyRulePool, which basically is a set of
+      dependency rules with methods like "search for x in all rules."
+
+      arguments:
+      * name -- name of this rule pool
+      * priority -- priority of this pool (lower is better)
+      """
+      super ( DependencyRulePool, self ).__init__(
+         name, priority, deptype_mask
+      )
+      if initial_rules is None:
+         self.rules = list()
+      else:
+         self.rules = list ( initial_rules )
+      self._rule_add    = self.rules.append
+   # --- end of __init__ (...) ---
+
+   def iter_rules ( self ):
+      return iter ( self.rules )
+   # --- end of iter_rules (...) ---
+
+   def iter_rules_resolving ( self, dep_env ):
+      return iter ( self.rules )
+   # --- end of iter_rules_resolving (...) ---
+
+   def empty ( self ):
+      """Returns True if this pool has no rules."""
+      return len ( self.rules ) == 0
+   # --- end of empty (...) ---
+
+   def sort_rules ( self ):
+      """Sorts this rule pool and determines its weight which is used
+      to compare rule pools.
+      """
+      self.rules.sort ( key=lambda rule : rule.priority )
+   # --- end of sort_rules (...) ---
+
+   def accepts_other ( self, dep_env ):
+      """Returns True if this pool can be used to resolve a dep env whose
+      deptype mask is rejected by this pool.
+      (Not necessarily the inverse of accepts().)
+      """
+      return not self.accepts ( dep_env )
+   # --- end of accepts_other (...) ---
+
+   def add ( self, rule ):
+      """Adds a DependencyRule to this rule pool.
+
+      arguments:
+      * rule --
+      """
+      if issubclass ( rule, DependencyRule ):
+         self._rule_add ( rule )
+      else:
+         raise Exception ( "bad usage (dependency rule expected)." )
+
+      return None
+   # --- end of add (...) ---
+
 # --- end of DependencyRulePool ---
+
+
+class DynamicDependencyRulePool ( DependencyRulePoolBase ):
+
+   @roverlay.util.objects.abstractmethod
+   def reload ( self ):
+      pass
+   # --- end of reload (...) ---
+
+   def accepts_other ( self, dep_env ):
+      return False
+   # --- end of accepts_other (...) ---
+
+# --- end of DynamicDependencyRulePool ---

diff --git a/roverlay/depres/simpledeprule/dynpool.py b/roverlay/depres/simpledeprule/dynpool.py
index 21e5a1b..7688bf1 100644
--- a/roverlay/depres/simpledeprule/dynpool.py
+++ b/roverlay/depres/simpledeprule/dynpool.py
@@ -18,36 +18,72 @@ whose dependency type contains deptype.internal.
 
 __all__ = [ 'DynamicSelfdepRulePool', 'get' ]
 
+import collections
+
 from roverlay.depres import deptype
-from roverlay.depres.simpledeprule.pool import SimpleDependencyRulePool
+from roverlay.depres.deprule import DynamicDependencyRulePool
 from roverlay.depres.simpledeprule.rules import SimpleFuzzyDependencyRule
 
-class DynamicSelfdepRulePool ( SimpleDependencyRulePool ):
+class DynamicSelfdepRulePool ( DynamicDependencyRulePool ):
    """A rule pool that gets its rules from a function."""
 
-   def __init__ ( self, rule_kw_function, rule_class, priority=120, **kwargs ):
+   def __init__ ( self, rule_generator, rule_class, priority=120, **kwargs ):
       super ( DynamicSelfdepRulePool, self ). __init__ (
          name='dynamic selfdeps', priority=priority,
          deptype_mask=deptype.internal,
          **kwargs
       )
 
-      self._rule_class       = rule_class
-      self._rule_kw_function = rule_kw_function
+      self.rules           = None
+      self._rule_generator = rule_generator
+      self.set_rule_class ( rule_class )
    # --- end of __init__ (...) ---
 
+   def sort_rules ( self ):
+      # TODO: sort self.rules itself ("sort repos")
+      priokey = lambda k: k.priority
+
+      if self.rules:
+         for rules in self.rules.values():
+            rules.sort ( key=priokey )
+   # --- end of sort_rules (...) ---
+
+   def iter_rules ( self ):
+      if self.rules:
+         for rules in self.rules.values():
+            for rule in rules:
+               yield rule
+   # --- end of iter_rules (...) ---
+
+   def iter_rules_resolving ( self, dep_env ):
+      specific_rules = self.rules.get ( dep_env.repo_id, None )
+      if specific_rules is not None:
+         for rule in specific_rules:
+            yield rule
+
+      for rules in self.rules.values():
+         if rules is not specific_rules:
+            for rule in rules:
+               yield rule
+   # --- end of iter_rules_resolving (...) ---
+
+   def set_rule_class ( self, rule_class ):
+      self._rule_generator.rule_class = rule_class
+   # --- end of set_rule_class (...) ---
+
    def accepts_other ( self, dep_env ):
       # never resolve external deps as selfdeps
       return False
    # --- end of accepts_other (...) ---
 
    def reload ( self ):
-      self.rules = list (
-         self._rule_class ( **kwargs ) for kwargs in self._rule_kw_function()
-      )
+      self.rules = self._rule_generator.make_rule_dict()
    # --- end of reload (...) ---
 
 
+# --- end of DynamicSelfdepRulePool ---
+
+
 def get ( rule_kw_function ):
    """Returns a default DynamicSelfdepRulePool for rule_kw_function."""
    return DynamicSelfdepRulePool (


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/simpledeprule/, roverlay/depres/
@ 2014-06-05 22:09 André Erdmann
  0 siblings, 0 replies; 9+ messages in thread
From: André Erdmann @ 2014-06-05 22:09 UTC (permalink / raw
  To: gentoo-commits

commit:     83d2732502634d7a91c5bf379d5ee3b6a252872f
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Wed May  7 01:38:05 2014 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Wed May  7 01:38:05 2014 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=83d27325

roverlay/depres, rule pools: also export #deptype

---
 roverlay/depres/deprule.py                     | 52 +++++++++++++++++++++++---
 roverlay/depres/simpledeprule/abstractrules.py |  4 +-
 roverlay/depres/simpledeprule/rulemaker.py     |  1 +
 3 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/roverlay/depres/deprule.py b/roverlay/depres/deprule.py
index f7b0acc..fa7f8a1 100644
--- a/roverlay/depres/deprule.py
+++ b/roverlay/depres/deprule.py
@@ -42,7 +42,7 @@ class DependencyRule ( object ):
 
    make_result = _make_result
 
-   def export_rule ( self ):
+   def export_rule ( self, with_selfdep_keyword=True ):
       raise NotImplementedError()
    # --- end of export_rule (...) ---
 
@@ -65,6 +65,15 @@ class DependencyRulePoolBase ( object ):
       self.rule_weight  = 0
    # --- end of __init__ (...) ---
 
+   def check_all_selfdep ( self ):
+      """
+      Returns True if this rule pool contains selfdep rules only, else False.
+      """
+      return all (
+         getattr ( rule, 'is_selfdep', None ) for rule in self.iter_rules()
+      )
+   # --- end of check_all_selfdep (...) ---
+
    def empty ( self ):
       """Returns True if this pool has no rules."""
       for rule in self.iter_rules():
@@ -178,25 +187,58 @@ class DependencyRulePoolBase ( object ):
       pass
    # --- end of accepts_other (...) ---
 
-   def export_rules ( self ):
+   def export_deptype_header ( self, _is_all_selfdep=None ):
+      """
+      Returns a '#deptype ...' string describing this rule pool's deptype mask.
+      """
+      words = [
+         word for k, word in (
+            ( deptype.internal, "pkg" ),
+            ( deptype.external, "sys" ),
+         )
+         if k & self.deptype_mask
+      ]
+
+      if _is_all_selfdep or (
+         _is_all_selfdep is None and self.check_all_selfdep()
+      ):
+         words.append ( "selfdep" )
+
+      return "#deptype " + ( ",".join(words) if words else "none" )
+   # --- end of export_deptype_header (...) ---
+
+   def export_rules ( self, **kwargs ):
       """Exports all rules. Typically, this generates text lines."""
       for rule in self.iter_rules():
-         for item in rule.export_rule():
+         for item in rule.export_rule ( **kwargs ):
             yield item
    # --- end of export_rules (...) ---
 
-   def export_rules_into ( self, fh ):
+   def export_rules_into ( self, fh, **kwargs ):
       """Writes all rules into the given file handle.
 
       arguments:
       * fh --
       """
       NL = '\n'
-      for item in self.export_rules():
+      for item in self.export_rules ( **kwargs ):
          fh.write ( str ( item ) )
          fh.write ( NL )
    # --- end of exports_rules_into (...) ---
 
+   def export_to_str ( self ):
+      """Exports the rule pool (header + all rules) as a single str."""
+      NL = '\n'
+      all_selfdep = self.check_all_selfdep()
+
+      return NL.join ((
+         self.export_deptype_header ( _is_all_selfdep=all_selfdep ),
+         NL.join (
+            self.export_rules ( with_selfdep_keyword=(not all_selfdep) )
+         )
+      ))
+   # --- end of export_to_str (...) ---
+
 # --- end of DependencyRulePoolBase ---
 
 

diff --git a/roverlay/depres/simpledeprule/abstractrules.py b/roverlay/depres/simpledeprule/abstractrules.py
index 37d3958..d31ffbe 100644
--- a/roverlay/depres/simpledeprule/abstractrules.py
+++ b/roverlay/depres/simpledeprule/abstractrules.py
@@ -119,7 +119,7 @@ class SimpleRule ( deprule.DependencyRule ):
       pass
    # --- end of noexport (...) ---
 
-   def export_rule ( self ):
+   def export_rule ( self, with_selfdep_keyword=True ):
       """Generates text lines for this rule that can later be read using
       the SimpleDependencyRuleReader.
       """
@@ -144,7 +144,7 @@ class SimpleRule ( deprule.DependencyRule ):
          yield resolving
 
       elif self.dep_alias:
-         if self.is_selfdep == 1:
+         if with_selfdep_keyword and self.is_selfdep == 1:
             yield '@selfdep'
 
          if len ( self.dep_alias ) == 1:

diff --git a/roverlay/depres/simpledeprule/rulemaker.py b/roverlay/depres/simpledeprule/rulemaker.py
index 8a4acc5..d7f7163 100644
--- a/roverlay/depres/simpledeprule/rulemaker.py
+++ b/roverlay/depres/simpledeprule/rulemaker.py
@@ -33,6 +33,7 @@ class SimpleRuleMaker ( roverlay.util.mapreader.MapFileParser ):
       self.logger = logging.getLogger ( self.__class__.__name__ )
 
       self.DEPTYPE_MAP = {
+         'none'    : 0,
          'all'     : deptype.ALL,
          'sys'     : deptype.external,
          'pkg'     : deptype.internal,


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2014-06-05 22:09 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-19 18:00 [gentoo-commits] proj/R_overlay:gsoc13/next commit in: roverlay/depres/simpledeprule/, roverlay/depres/ André Erdmann
2013-07-23  7:51 ` [gentoo-commits] proj/R_overlay:master " André Erdmann
  -- strict thread matches above, loose matches on Subject: below --
2014-06-05 22:09 André Erdmann
2013-09-02 16:21 André Erdmann
2013-09-02 13:20 André Erdmann
2013-07-03 10:05 André Erdmann
2013-07-02 21:09 [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
2013-07-03 10:05 ` [gentoo-commits] proj/R_overlay:master " André Erdmann
2012-08-02 15:14 André Erdmann
2012-07-20 16:16 [gentoo-commits] proj/R_overlay:overlay_wip " André Erdmann
2012-07-30  8:52 ` [gentoo-commits] proj/R_overlay:master " André Erdmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox