* [gentoo-commits] proj/R_overlay:gsoc13/next commit in: roverlay/depres/simpledeprule/, roverlay/depres/
2013-07-03 10:05 [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/simpledeprule/, roverlay/depres/ André Erdmann
@ 2013-06-28 6:19 ` André Erdmann
0 siblings, 0 replies; 4+ messages in thread
From: André Erdmann @ 2013-06-28 6:19 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] 4+ messages in thread
* [gentoo-commits] proj/R_overlay:gsoc13/next commit in: roverlay/depres/simpledeprule/, roverlay/depres/
@ 2013-07-02 21:09 André Erdmann
0 siblings, 0 replies; 4+ messages in thread
From: André Erdmann @ 2013-07-02 21:09 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] 4+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/simpledeprule/, roverlay/depres/
@ 2013-07-03 10:05 André Erdmann
2013-06-28 6:19 ` [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
0 siblings, 1 reply; 4+ 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] 4+ messages in thread
* [gentoo-commits] proj/R_overlay:gsoc13/next commit in: roverlay/depres/simpledeprule/, roverlay/depres/
@ 2013-07-19 18:00 André Erdmann
0 siblings, 0 replies; 4+ 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] 4+ messages in thread
end of thread, other threads:[~2013-07-19 18:00 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-03 10:05 [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/simpledeprule/, roverlay/depres/ André Erdmann
2013-06-28 6:19 ` [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
-- strict thread matches above, loose matches on Subject: below --
2013-07-19 18:00 André Erdmann
2013-07-02 21:09 André Erdmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox