* [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