* [gentoo-commits] proj/R_overlay:gsoc13/next commit in: roverlay/ebuild/, roverlay/depres/simpledeprule/, roverlay/depres/, roverlay/, ...
@ 2013-07-04 17:02 André Erdmann
0 siblings, 0 replies; only message in thread
From: André Erdmann @ 2013-07-04 17:02 UTC (permalink / raw
To: gentoo-commits
commit: 3187207842e4c7022f3129bf5343924a1e33b594
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jul 4 16:53:51 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jul 4 16:53:51 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=31872078
roverlay/depres: return depresult objects
Dependency resolution now creates depresult objects if a rule matches a
dependency string. Previously, it returned a 2-tuple (score,resolving_dep).
This is "necessary" for selfdep reduction (also see pseudocode in
overlay/root.py).
Additionally, this commit allows to define selfdeps that don't belong to the
default category ("sci-R") in rule files, either by OR-ing a deptype with
"#deptype <deptype>,selfdep" or by prefixing a single rule with "@selfdep".
The rule stub syntax ("zoo") is mostly unaffected by this change, but roverlay
is able to detect (non-)default-category selfdeps now.
---
roverlay/depres/channels.py | 8 +-
roverlay/depres/depenv.py | 3 +
roverlay/depres/depresolver.py | 16 +--
roverlay/depres/depresult.py | 131 +++++++++++++++++++++++++
roverlay/depres/deprule.py | 23 ++++-
roverlay/depres/deptype.py | 12 ++-
roverlay/depres/listeners.py | 2 +-
roverlay/depres/simpledeprule/abstractrules.py | 50 +++++-----
roverlay/depres/simpledeprule/console.py | 4 +-
roverlay/depres/simpledeprule/rulemaker.py | 76 ++++++++------
roverlay/ebuild/creation.py | 14 +--
roverlay/ebuild/depfilter.py | 4 +-
roverlay/ebuild/depres.py | 118 +++++++++++++---------
roverlay/ebuild/ebuilder.py | 6 +-
roverlay/overlay/category.py | 2 +-
roverlay/overlay/pkgdir/packagedir_base.py | 4 +
roverlay/overlay/root.py | 34 +++++++
roverlay/packageinfo.py | 25 +++--
18 files changed, 399 insertions(+), 133 deletions(-)
diff --git a/roverlay/depres/channels.py b/roverlay/depres/channels.py
index 3e0085f..b1f39bd 100644
--- a/roverlay/depres/channels.py
+++ b/roverlay/depres/channels.py
@@ -14,6 +14,8 @@ __all__ = [ 'EbuildJobChannel', ]
import logging
+import roverlay.depres.depresult
+
from roverlay.depres import deptype
from roverlay.depres.depenv import DepEnv
from roverlay.depres.communication import DependencyResolverChannel
@@ -192,9 +194,9 @@ class EbuildJobChannel ( _EbuildJobChannelBase ):
ret = True
elif deptype.mandatory & ~dep_env.deptype_mask:
# not resolved, but deptype has no mandatory bit set
- # => dep is not required, resolve as None and add it to
- # the list of unresolvable deps
- resolved ( None )
+ # => dep is not required, resolve it as "not resolved"
+ # and add it to the list of unresolvable deps
+ resolved ( roverlay.depres.depresult.DEP_NOT_RESOLVED )
unresolvable ( dep_env.dep_str )
ret = True
# else failed
diff --git a/roverlay/depres/depenv.py b/roverlay/depres/depenv.py
index c298447..3d324a4 100644
--- a/roverlay/depres/depenv.py
+++ b/roverlay/depres/depenv.py
@@ -191,6 +191,7 @@ class DepEnv ( object ):
result.append ( dict (
name = m.group ( 'name' ),
+ name_low = m.group ( 'name' ).lower(),
version_modifier = vmod,
version = version,
version_strlist = version_strlist,
@@ -267,3 +268,5 @@ class DepEnv ( object ):
def get_resolved ( self ):
return self.resolved_by
# --- end of get_resolved (...) ---
+
+# --- end of DepEnv ---
diff --git a/roverlay/depres/depresolver.py b/roverlay/depres/depresolver.py
index b9465fd..a49697a 100644
--- a/roverlay/depres/depresolver.py
+++ b/roverlay/depres/depresolver.py
@@ -177,7 +177,9 @@ class DependencyResolver ( object ):
# log this event
if event_type == events.DEPRES_EVENTS ['RESOLVED']:
self.logger_resolved.info (
- "{!r} as {!r}".format ( dep_env.dep_str, dep_env.resolved_by )
+ "{!r} as {!r}".format (
+ dep_env.dep_str, dep_env.resolved_by.dep
+ )
)
elif event_type == events.DEPRES_EVENTS ['UNRESOLVABLE']:
self.logger_unresolvable.info ( "{!r}".format ( dep_env.dep_str ) )
@@ -378,8 +380,8 @@ class DependencyResolver ( object ):
if p.accepts ( dep_env.deptype_mask, try_other=False )
):
result = rulepool.matches ( dep_env )
- if result [0] > 0:
- resolved = result [1]
+ if result:
+ resolved = result
is_resolved = 2
break
# TRY_OTHER searching is disabled for dynamic rule pools,
@@ -391,8 +393,8 @@ class DependencyResolver ( object ):
if p.accepts ( dep_env.deptype_mask, try_other=False )
):
result = rulepool.matches ( dep_env )
- if result [0] > 0:
- resolved = result [1]
+ if result:
+ resolved = result
is_resolved = 2
break
@@ -405,8 +407,8 @@ class DependencyResolver ( object ):
if p.accepts ( ~dep_env.deptype_mask, try_other=True )
):
result = rulepool.matches ( dep_env )
- if result [0] > 0:
- resolved = result [1]
+ if result:
+ resolved = result
is_resolved = 2
break
# --
diff --git a/roverlay/depres/depresult.py b/roverlay/depres/depresult.py
new file mode 100644
index 0000000..91a4688
--- /dev/null
+++ b/roverlay/depres/depresult.py
@@ -0,0 +1,131 @@
+# R overlay -- dependency resolution, depres result
+# -*- 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.
+
+__all__ = [ 'DepResult', 'DEP_NOT_RESOLVED', ]
+
+import roverlay.depres.depenv
+
+EMPTY_STR = ""
+
+class DepResult ( object ):
+
+ # TODO/FIXME: define those constants somewhere else
+ # (especially VMOD_??)
+ #
+ VMOD_COMPARE_MAP = {
+ # p.version_compare_* functions are TODO
+ roverlay.depres.depenv.DepEnv.VMOD_EQ: (
+ lambda p: p.version_compare_eq
+ ),
+ roverlay.depres.depenv.DepEnv.VMOD_NE: (
+ lambda p: p.version_compare_ne
+ ),
+ roverlay.depres.depenv.DepEnv.VMOD_GT: (
+ lambda p: p.version_compare_gt
+ ),
+ roverlay.depres.depenv.DepEnv.VMOD_GE: (
+ lambda p: p.version_compare_ge
+ ),
+ roverlay.depres.depenv.DepEnv.VMOD_LT: (
+ lambda p: p.version_compare_lt
+ ),
+ roverlay.depres.depenv.DepEnv.VMOD_LE: (
+ lambda p: p.version_compare_le
+ ),
+ }
+
+ def __init__ ( self,
+ dep, score, matching_rule, dep_env=None, fuzzy=None
+ ):
+ self.dep = dep
+ self.score = score
+ #assert hasattr ( matching_rule, 'is_selfdep' )
+ self.is_selfdep = matching_rule.is_selfdep if matching_rule else 0
+
+ if self.is_selfdep:
+ self.fuzzy = fuzzy
+ self.resolving_package = matching_rule.resolving_package
+ # --- end of DepResult ---
+
+ def __eq__ ( self, other ):
+ if isinstance ( other, str ):
+ return str ( self ) == other
+ elif isinstance ( other, DepResult ):
+ return (
+ self.score == other.score
+ and self.is_selfdep == other.is_selfdep
+ and self.dep == other.dep
+ )
+ else:
+ return NotImplemented
+ # --- end of __eq__ (...) ---
+
+ def __hash__ ( self ):
+ #return hash ( self.__dict__.values() )
+ return hash (( self.dep, self.score, self.is_selfdep ))
+ # --- end of __hash__ (...) ---
+
+ def __bool__ ( self ):
+ return self.score > 0
+ #and self.dep is not False
+ # --- end of __bool__ (...) ---
+
+ def __str__ ( self ):
+ return self.dep if self.dep is not None else EMPTY_STR
+ # --- end of __str__ (...) ---
+
+ def __getitem__ ( self, key ):
+ # for backwards compatibility, indexing is supported
+ if key == 0:
+ return self.score
+ elif key == 1:
+ return self.dep
+ elif isinstance ( key, int ):
+ raise IndexError ( key )
+ else:
+ raise KeyError ( key )
+ # --- end of __getitem__ (...) ---
+
+ def prepare_selfdep_reduction ( self ):
+ cat, sepa, pkg = self.resolving_package.rpartition ( '/' )
+ self.category = cat
+ self.package = pkg
+ self.candidates = list()
+ self.link = self.candidates.append
+
+ if self.fuzzy:
+ vmod = self.fuzzy ['vmod']
+ self.version = self.fuzzy ['version_tuple']
+ self._version_compare = self.VMOD_COMPARE_MAP [vmod]
+ self.version_compare = (
+ lambda p: self._version_compare ( p ) ( self.version )
+ )
+ # --- end of prepare_selfdep_reduction (...) ---
+
+ def deps_satisfiable ( self ):
+ return bool ( self.candidates )
+
+ def link_if_version_matches ( self, p ):
+ if not self.fuzzy or self.version_compare ( p ):
+ self.link ( p )
+ return True
+ else:
+ return False
+ # --- end of link_if_version_matches (...) ---
+
+ def reduce ( self ):
+ candidates = list (
+ p for p in self.candidates if p.has_valid_selfdeps()
+ )
+ num_removed = len ( self.candidates ) - len ( candidates )
+ if num_removed != 0:
+ self.candidates = candidates
+ return num_removed
+ # --- end of reduce (...) ---
+
+# --- end of DepResult ---
+
+DEP_NOT_RESOLVED = DepResult ( dep=None, score=-2, matching_rule=None )
diff --git a/roverlay/depres/deprule.py b/roverlay/depres/deprule.py
index 46c710d..1d36941 100644
--- a/roverlay/depres/deprule.py
+++ b/roverlay/depres/deprule.py
@@ -8,6 +8,8 @@
__all__ = [ 'DependencyRule', 'DependencyRulePool', ]
+import roverlay.depres.depresult
+
from roverlay.depres import deptype
class DependencyRule ( object ):
@@ -25,11 +27,19 @@ class DependencyRule ( object ):
# --- end of __init__ (...) ---
def matches ( self, dep_env ):
- """Returns a tuple ( score ::= int > 0, matching dep ::= str )
+ """Returns a tuple ( score ::= int > 0, matching dep ::= DepResult )
if this rule matches the given DepEnv, else None"""
return None
# --- end of matches (...) ---
+ def _make_result ( self, resolved_dep, score, *args, **kw ):
+ return roverlay.depres.depresult.DepResult (
+ resolved_dep, score, self, *args, **kw
+ )
+ # --- end of _make_result (...) ---
+
+ make_result = _make_result
+
# --- end of DependencyRule ---
@@ -114,6 +124,11 @@ 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:
skipped = 0
# python3 requires list ( range ... )
@@ -125,12 +140,12 @@ class DependencyRulePool ( object ):
for index in order:
result = self.rules [index].matches ( dep_env )
- if result is not None and result [0] > 0:
+ if result:
if skipped < skip_matches:
skipped += 1
else:
return result
-
- return ( -1, None )
+ # default return
+ return None
# --- end of matches (...) ---
diff --git a/roverlay/depres/deptype.py b/roverlay/depres/deptype.py
index 269f666..f430316 100644
--- a/roverlay/depres/deptype.py
+++ b/roverlay/depres/deptype.py
@@ -13,14 +13,22 @@
# <deptype> ::= 2**k | k in {0,1,2,...}
# try_other indicates that the dep can be checked world-wide (in non-accepting
# rule pools) after unsuccessful resolution
+#
try_other = 1
mandatory = 2
external = 4
internal = 8
+#internal does not imply selfdep
+# internal := dependency on package
+# selfdep := created overlay has dependency
+selfdep = 16
-_MAX = 15
+_MAX = 31
-ALL = external | internal | mandatory
+#VIRTUAL = try_other | mandatory | selfdep
+
+NONE = 0
+ALL = external | internal | mandatory
RESOLVE_ALL = external | internal
SYS = external | mandatory
diff --git a/roverlay/depres/listeners.py b/roverlay/depres/listeners.py
index 29dd539..3d5ceaf 100644
--- a/roverlay/depres/listeners.py
+++ b/roverlay/depres/listeners.py
@@ -111,7 +111,7 @@ class ResolvedFileListener ( FileListener ):
def notify ( self, event_type, dep_env=None, pkg_env=None, **extra ):
self._event ( event_type,
"{dep_str!r} as {dep!r}".format (
- dep_str=dep_env.dep_str, dep=dep_env.resolved_by
+ dep_str=dep_env.dep_str, dep=dep_env.resolved_by.dep
) )
# --- end of notify (...) ---
diff --git a/roverlay/depres/simpledeprule/abstractrules.py b/roverlay/depres/simpledeprule/abstractrules.py
index 0713c81..b80eb00 100644
--- a/roverlay/depres/simpledeprule/abstractrules.py
+++ b/roverlay/depres/simpledeprule/abstractrules.py
@@ -20,7 +20,7 @@ class SimpleRule ( deprule.DependencyRule ):
def __init__ ( self,
dep_str=None, priority=50, resolving_package=None,
- is_selfdep=False, logger_name='simple_rule'
+ is_selfdep=0, logger_name='simple_rule'
):
"""Initializes a SimpleIgnoreDependencyRule.
@@ -29,25 +29,22 @@ class SimpleRule ( deprule.DependencyRule ):
* priority -- priority of this rule
"""
super ( SimpleRule, self ) . __init__ ( priority )
- self.dep_alias = list()
-
- self.logger = TMP_LOGGER.getChild ( logger_name )
-
- self.is_selfdep = is_selfdep
-
- self.resolving_package = resolving_package
+ self.dep_alias = list()
+ self.logger = TMP_LOGGER.getChild ( logger_name )
+ self.is_selfdep = int ( is_selfdep or 0 )
+ self.resolving_package = resolving_package
self.prepare_lowercase_alias = True
- if not dep_str is None:
+ if dep_str is not None:
self.dep_alias.append ( dep_str )
- if self.is_selfdep and dep_str is not None:
- # add the actual package name (replace '_' by '.') to self.dep_alias
- actual_name = dep_str.replace ( '_', '.' )
- if actual_name != dep_str:
- self.dep_alias.append ( dep_str )
-
+ if self.is_selfdep:
+ # add the actual package name (replace '_' by '.')
+ # to self.dep_alias
+ actual_name = dep_str.replace ( '_', '.' )
+ if actual_name != dep_str:
+ self.dep_alias.append ( dep_str )
# --- end of __init__ (...) ---
def done_reading ( self ):
@@ -92,7 +89,9 @@ class SimpleRule ( deprule.DependencyRule ):
"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 self.make_result (
+ self.resolving_package, self.max_score, dep_env=dep_env
+ )
return None
# --- end of matches (...) ---
@@ -116,7 +115,7 @@ class SimpleRule ( deprule.DependencyRule ):
else:
resolving = self.resolving_package
- if self.is_selfdep:
+ if self.is_selfdep == 2:
resolving = resolving.rpartition ( '/' ) [2]
@@ -125,6 +124,8 @@ class SimpleRule ( deprule.DependencyRule ):
# -- end if;
if self.is_selfdep:
+ if self.is_selfdep == 1:
+ yield '@selfdep'
yield resolving
elif len ( self.dep_alias ) == 0:
@@ -164,18 +165,18 @@ class FuzzySimpleRule ( SimpleRule ):
elif self.resolving_package is None:
# ignore rule
for fuzzy in dep_env.fuzzy:
- if self._find ( fuzzy ['name'], lowercase=True ):
+ if self._find ( fuzzy ['name_low'], lowercase=True ):
return ( 1, fuzzy )
else:
for fuzzy in dep_env.fuzzy:
- if self._find ( fuzzy ['name'], lowercase=True ):
+ if self._find ( fuzzy ['name_low'], 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 ):
+ def log_fuzzy_match ( self, dep_env, dep, score, fuzzy ):
if dep is False:
return None
else:
@@ -185,7 +186,7 @@ class FuzzySimpleRule ( SimpleRule ):
dep_str=dep_env.dep_str, dep=dep, s=score
)
)
- return ( score, dep )
+ return self.make_result ( dep, score, dep_env=dep_env, fuzzy=fuzzy )
# --- end of log_fuzzy_match (...) ---
def log_standard_match ( self, dep_env, score ):
@@ -194,7 +195,7 @@ class FuzzySimpleRule ( SimpleRule ):
dep_str=dep_env.dep_str, s=score, p=self.priority
)
)
- return ( score, self.resolving_package )
+ return self.make_result ( self.resolving_package, score )
# --- end of log_standard_match (...) ---
def handle_version_relative_match ( self, dep_env, fuzzy ):
@@ -213,12 +214,13 @@ class FuzzySimpleRule ( SimpleRule ):
return self.log_fuzzy_match (
dep_env,
self.handle_version_relative_match ( dep_env, fuzzy ),
- score
+ score,
+ fuzzy
)
elif match_type == 1:
# name-only match (ignore rule?)
return self.log_fuzzy_match (
- dep_env, self.resolving_package, score
+ dep_env, self.resolving_package, score, fuzzy
)
else:
# non-fuzzy match
diff --git a/roverlay/depres/simpledeprule/console.py b/roverlay/depres/simpledeprule/console.py
index e4e5efc..a845d41 100644
--- a/roverlay/depres/simpledeprule/console.py
+++ b/roverlay/depres/simpledeprule/console.py
@@ -74,14 +74,14 @@ class PackageDirRuleMaker ( object ):
yield rules.SimpleFuzzyDependencyRule (
resolving_package = strutil.fix_ebuild_name ( cat + dep ),
dep_str = dep,
- is_selfdep=True
+ is_selfdep=2
)
else:
for dep in self._scan ( distdir ):
yield rules.SimpleDependencyRule (
resolving_package = strutil.fix_ebuild_name ( cat + dep ),
dep_str = dep,
- is_selfdep=True
+ is_selfdep=2
)
# --- end of make_rules (...) ---
diff --git a/roverlay/depres/simpledeprule/rulemaker.py b/roverlay/depres/simpledeprule/rulemaker.py
index a993341..ed39791 100644
--- a/roverlay/depres/simpledeprule/rulemaker.py
+++ b/roverlay/depres/simpledeprule/rulemaker.py
@@ -31,15 +31,24 @@ class SimpleRuleMaker ( object ):
'\s+::\s+' if rule_separator is None else rule_separator
)
+ self.DEPTYPE_MAP = {
+ 'all' : deptype.ALL,
+ 'sys' : deptype.external,
+ 'pkg' : deptype.internal,
+ 'selfdep' : deptype.selfdep,
+ }
+
self.multiline_start = '{'
self.multiline_stop = '}'
self.comment_char = '#'
+ self.kw_selfdep_once = '@selfdep'
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
+ self._deptype_once = deptype.NONE
self._next = None
# [ ( deptype, rule ), ... ]
self._rules = list()
@@ -72,19 +81,28 @@ class SimpleRuleMaker ( object ):
return ret
# --- end of done (...) ---
- def _get_deptype ( self, t ):
- if len ( t ) == 0 or t == 'all':
- return deptype.ALL
- elif t == 'sys':
- return deptype.external
- elif t == 'pkg':
- return deptype.internal
+ def _parse_deptype ( self, deptype_str ):
+ ret = deptype.NONE
+ try:
+ for item in deptype_str.split ( ',' ):
+ ret |= self.DEPTYPE_MAP [item]
+ except KeyError:
+ raise Exception ( "unknown deptype {!r}".format ( deptype_str ) )
+
+ return ret if ret != deptype.NONE else deptype.ALL
+ # --- end of _parse_deptype (...) ---
+
+ def _get_effective_deptype ( self, clear_temporary=True ):
+ if self._deptype_once is not deptype.NONE:
+ if clear_temporary:
+ ret = self._deptype_once
+ self._deptype_once = deptype.NONE
+ return ret
+ else:
+ self._deptype_once
else:
- try:
- return int ( t )
- except ValueError:
- return None
- # --- end of _get_deptype (...) ---
+ return self._deptype
+ # --- end of _get_effective_deptype (...) ---
def _single_line_rule ( self, dep, dep_str='' ):
# single line rule, either selfdep,
@@ -92,35 +110,38 @@ class SimpleRuleMaker ( object ):
# or normal rule 'dev-lang/R :: R'
# selfdeps are always single line statements (!)
+ rule_deptype = self._get_effective_deptype()
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,
+ resolving_package = resolving,
+ dep_str = dep_str,
+ is_selfdep = (
+ 1 if ( rule_deptype & deptype.selfdep ) else 0
+ ),
**kwargs
)
elif resolving is not None:
- # selfdep
+ # selfdep (rule stub)
dep_str = resolving
resolving = (
config.get_or_fail ( 'OVERLAY.category' ) + '/' + resolving
)
new_rule = rule_class (
- resolving_package=resolving,
- dep_str=dep_str,
- is_selfdep=True,
+ resolving_package = resolving,
+ dep_str = dep_str,
+ is_selfdep = 2,
**kwargs
)
else:
return False
new_rule.done_reading()
- self._rules.append ( ( self._deptype, new_rule ) )
+ self._rules.append ( ( rule_deptype, new_rule ) )
return True
# --- end of _single_line_rule (...) ---
@@ -144,23 +165,22 @@ class SimpleRuleMaker ( object ):
if line [ 1 : 1 + len ( self.deptype_kw ) ] == self.deptype_kw :
# changing deptype ("#deptype <type>")
dtype_str = line [ len ( self.deptype_kw ) + 2 : ].lstrip().lower()
- dtype = self._get_deptype ( dtype_str )
- if dtype is not None:
- self._deptype = dtype
- else:
- raise AssertionError (
- "Expected deptype, but got {!r}.".format ( dtype_str )
- )
+ self._deptype = self._parse_deptype ( dtype_str )
+
# else is a comment,
# it's intented that multi line rules cannot contain comments
return True
+ elif line == self.kw_selfdep_once:
+ self._deptype_once = self._deptype | deptype.selfdep
+ return True
+
elif len ( line ) > 1 and line [-1] == self.multiline_start:
l = line [:-1].rstrip()
rule_class, resolving, kwargs = self._kwmap.lookup ( l )
self._next = (
- self._deptype,
+ self._get_effective_deptype(),
rule_class ( resolving_package=resolving, **kwargs ),
)
return True
diff --git a/roverlay/ebuild/creation.py b/roverlay/ebuild/creation.py
index 9fda2b6..819616a 100644
--- a/roverlay/ebuild/creation.py
+++ b/roverlay/ebuild/creation.py
@@ -125,15 +125,16 @@ class EbuildCreation ( object ):
)
return False
- _dep_resolution = depres.EbuildDepRes (
+ dep_resolution = depres.EbuildDepRes (
self.package_info, self.logger,
run_now=True, depres_channel_spawner=self.depres_channel_spawner,
err_queue=self.err_queue
)
- if _dep_resolution.success():
- dep_result = _dep_resolution.get_result()
+ if dep_resolution.success():
+ #dep_result = dep_resolution.get_result()
ebuild = ebuilder.Ebuilder()
+ evars_dep = dep_resolution.get_evars()
evars_extra = self.package_info.get_evars()
if evars_extra:
@@ -145,10 +146,10 @@ class EbuildCreation ( object ):
# ...
# add *DEPEND to the ebuild
- ebuild.use ( *dep_result [1] )
+ ebuild.use_list ( evars_dep )
# IUSE
- if dep_result [2]:
+ if dep_resolution.has_suggests:
rsuggests = ebuild.get ( 'R_SUGGESTS' )
self.use_expand_flag_names = set ( rsuggests.get_flag_names() )
ebuild.use ( evars.IUSE ( sorted ( rsuggests.get_flags() ) ) )
@@ -170,8 +171,9 @@ class EbuildCreation ( object ):
self.package_info.update_now (
ebuild=ebuild_text,
- depres_result=dep_result
+ has_suggests=dep_resolution.has_suggests,
)
+ self.package_info.selfdeps = dep_resolution.get_selfdeps()
return True
diff --git a/roverlay/ebuild/depfilter.py b/roverlay/ebuild/depfilter.py
index a4c528a..4d59386 100644
--- a/roverlay/ebuild/depfilter.py
+++ b/roverlay/ebuild/depfilter.py
@@ -12,9 +12,11 @@ filter out redundant dependencies on dev-lang/R.
__all__ = [ 'dep_allowed', ]
-def dep_allowed ( dep ):
+def dep_allowed ( dep_result ):
"""Filters out redundant dependencies on dev-lang/R."""
+ dep = dep_result.dep
+
if not dep:
return 0
elif dep[0] in '|(':
diff --git a/roverlay/ebuild/depres.py b/roverlay/ebuild/depres.py
index ac65e31..4f12400 100644
--- a/roverlay/ebuild/depres.py
+++ b/roverlay/ebuild/depres.py
@@ -19,8 +19,8 @@ from roverlay.ebuild import evars, depfilter
FIELDS_TO_EVAR = {
'R_SUGGESTS' : ( 'Suggests', ),
- 'DEPENDS' : ( 'Depends', 'Imports' ),
- 'RDEPENDS' : ( 'LinkingTo', 'SystemRequirements' ),
+ 'DEPEND' : ( 'Depends', 'Imports' ),
+ 'RDEPEND' : ( 'LinkingTo', 'SystemRequirements' ),
# ? : ( 'Enhances', )
}
@@ -61,8 +61,8 @@ def create_use_expand_var ( *args, **kwargs ):
EBUILDVARS = {
'R_SUGGESTS' : create_use_expand_var,
- 'DEPENDS' : evars.DEPEND,
- 'RDEPENDS' : evars.RDEPEND,
+ 'DEPEND' : evars.DEPEND,
+ 'RDEPEND' : evars.RDEPEND,
}
@@ -89,11 +89,10 @@ class EbuildDepRes ( object ):
# > 0 busy/working; 0 == done,success; < 0 done,fail
self.status = 1
- self.result = None
+ self.depmap = None
+ self.missingdeps = None
self.has_suggests = None
-
self.err_queue = err_queue
-
self._channels = None
if run_now:
@@ -110,13 +109,15 @@ class EbuildDepRes ( object ):
"""Returns the result of dependency resolution,
as tuple ( <status>, <evars>, <has R suggests> )
"""
+ raise NotImplementedError()
return ( self.status, self.result, self.has_suggests )
# --- end of get_result (...) ---
def resolve ( self ):
"""Try to make/get dependency resolution results. Returns None."""
try:
- self.result = None
+ self.missingdeps = None
+ self.depmap = None
self._init_channels()
if self._wait_resolve():
@@ -126,7 +127,8 @@ class EbuildDepRes ( object ):
# unresolvable
self.logger.info ( "Cannot satisfy dependencies!" )
- self.result = None
+ self.missingdeps = None
+ self.depmap = None
self.status = -5
finally:
@@ -198,59 +200,81 @@ class EbuildDepRes ( object ):
def _make_result ( self ):
"""Make evars using the depres result."""
- # RDEPEND -> <deps>, DEPEND -> <deps>, ..
- _depmap = dict()
- # two for dep_type, <sth> loops to safely determine the actual deps
- # (e.g. whether to include R_SUGGESTS in RDEPEND)
-
+ # <ebuild varname> => <deps>
+ depmap = dict()
unresolvable_optional_deps = set()
for dep_type, channel in self._channels.items():
channel_result = channel.collect_dependencies()
- deplist = tuple ( filter (
- depfilter.dep_allowed, channel_result [0] )
- )
+ deps = set ( filter ( depfilter.dep_allowed, channel_result[0] ) )
- if len ( deplist ) > 0:
- self.logger.debug (
- "adding {deps} to {depvar}".format (
- deps=deplist, depvar=dep_type
+ if deps:
+ self.logger.debug ( "adding {deps} to {depvar}".format (
+ deps=deps, depvar=dep_type
) )
- _depmap [dep_type] = deplist
+ depmap [dep_type] = deps
# else: (effectively) no dependencies for dep_type
- if channel_result [1] is not None:
- unresolvable_optional_deps |= channel_result [1]
+ if channel_result[1]:
+ unresolvable_optional_deps |= channel_result[1]
self._close_channels()
- # empty R_SUGGESTS has been filtered out
- self.has_suggests = bool ( 'R_SUGGESTS' in _depmap )
-
- _result = list()
- for dep_type, deplist in _depmap.items():
- # add dependencies in no_append/override mode
- _result.append (
- EBUILDVARS [dep_type] (
- deplist,
- using_suggests=self.has_suggests,
- use_expand=True
- )
- )
+ # remove redundant deps (DEPEND in RDEPEND, RDEPEND,DEPEND in R_SUGGESTS)
+ if 'RDEPEND' in depmap and 'DEPEND' in depmap:
+ depmap ['RDEPEND'] -= depmap ['DEPEND']
+ if not depmap ['RDEPEND']:
+ del depmap ['RDEPEND']
+
+ self.has_suggests = False
+ if 'R_SUGGESTS' in depmap:
+ if 'RDEPEND' in depmap:
+ depmap ['R_SUGGESTS'] -= depmap ['RDEPEND']
+ if 'DEPEND' in depmap:
+ depmap ['R_SUGGESTS'] -= depmap ['DEPEND']
+
+ if depmap ['R_SUGGESTS']:
+ self.has_suggests = True
+ else:
+ del depmap ['R_SUGGESTS']
- # When using suggested dependencies, RDEPENDS is required even if empty
- if self.has_suggests and 'RDEPENDS' not in _depmap:
- _result.append (
- EBUILDVARS ['RDEPENDS'] (
+
+ self.depmap = depmap
+ if unresolvable_optional_deps:
+ self.missingdeps = unresolvable_optional_deps
+ # --- end of _make_result (...) ---
+
+ def get_selfdeps ( self ):
+ def gen_selfdeps():
+ for deps in self.depmap.values():
+ for dep_result in deps:
+ if dep_result.is_selfdep:
+ yield dep_result
+ # --- end of gen_selfdeps (...) ---
+
+ return frozenset ( gen_selfdeps() ) or None
+ # --- end of get_selfdeps (...) ---
+
+ def get_evars ( self ):
+ depgen = lambda D : ( k.dep for k in D )
+
+ evar_list = list (
+ EBUILDVARS [evar_name] (
+ depgen ( deps ),
+ using_suggests=self.has_suggests, use_expand=True
+ ) for evar_name, deps in self.depmap.items()
+ )
+ if self.has_suggests and 'RDEPEND' not in self.depmap:
+ evar_list.append (
+ EBUILDVARS ['RDEPEND'] (
None, using_suggests=True, use_expand=True
)
)
- if unresolvable_optional_deps:
-# if not self.has_suggests: raise AssertionError() #?
- _result.append (
- evars.MISSINGDEPS ( unresolvable_optional_deps, do_sort=True )
+ if self.missingdeps:
+ evar_list.append (
+ evars.MISSINGDEPS ( self.missingdeps, do_sort=True )
)
- self.result = tuple ( _result )
- # --- end of _make_result (...) ---
+ return evar_list
+ # --- end of get_evars (...) ---
diff --git a/roverlay/ebuild/ebuilder.py b/roverlay/ebuild/ebuilder.py
index 152cfc7..6806478 100644
--- a/roverlay/ebuild/ebuilder.py
+++ b/roverlay/ebuild/ebuilder.py
@@ -52,11 +52,15 @@ class Ebuilder ( object ):
arguments:
* *evar_list --
"""
+ self.use_list ( evar_list )
+ # --- end of use (...) ---
+
+ def use_list ( self, evar_list ):
for e in evar_list:
if e is not None:
assert e.name not in self._evars
self._evars [e.name] = e
- # --- end of use (...) ---
+ # --- end of use_list (...) ---
def has ( self, evar_name ):
"""Returns True if an evar with name evar_name exists.
diff --git a/roverlay/overlay/category.py b/roverlay/overlay/category.py
index aab8ff4..9c5c79f 100644
--- a/roverlay/overlay/category.py
+++ b/roverlay/overlay/category.py
@@ -160,7 +160,7 @@ class Category ( object ):
yield dict (
dep_str = name,
resolving_package = ( self.name + "/" + name ),
- is_selfdep = is_default_category,
+ is_selfdep = 2 if is_default_category else 1,
# prefer packages from the default category (really?)
priority = 80 if is_default_category else 90,
)
diff --git a/roverlay/overlay/pkgdir/packagedir_base.py b/roverlay/overlay/pkgdir/packagedir_base.py
index 1f033a0..8b5b634 100644
--- a/roverlay/overlay/pkgdir/packagedir_base.py
+++ b/roverlay/overlay/pkgdir/packagedir_base.py
@@ -379,6 +379,10 @@ class PackageDirBase ( object ):
self._need_metadata = True
self.modified = True
if self.runtime_incremental:
+ raise Exception (
+ '--write-immediate is currently not available '
+ '(blocked by selfdep reduction).'
+ )
with self._lock:
return self.write_ebuilds ( overwrite=False )
else:
diff --git a/roverlay/overlay/root.py b/roverlay/overlay/root.py
index 943518a..a5e847c 100644
--- a/roverlay/overlay/root.py
+++ b/roverlay/overlay/root.py
@@ -671,6 +671,40 @@ class Overlay ( object ):
)
# --- end of import_ebuilds (...) ---
+ def remove_bad_packages ( self ):
+ # "prepare"
+ #
+ ## collect:
+ ## find all <PackageInfo> p with selfdeps
+ ## p->selfdeps->prepare_selfdep_reduction()
+ ## add p->selfdeps to a list/listlike object S
+ ##
+ ## link:
+ ## foreach selfdep in S loop
+ ## find <PackageInfo> candidates in overlay and link them to selfdep
+ ## end loop
+ #
+ # "reduce"
+ #
+ ## num_removed <- 0
+ ## first <- True
+ ##
+ ## while num_removed > 0 or first loop
+ ## first <- False
+ ## foreach selfdep in S loop
+ ## num_removed += selfdep.reduce()
+ ## end loop
+ ## end loop
+ ##
+ #
+ # "balance" [if <anything removed>]
+ #
+ ## find all <PackageInfo> p with valid == False
+ ## drop p
+ ##
+ raise NotImplementedError ( "TODO" )
+ # --- end of remove_bad_packages (...) ---
+
def scan ( self, **kw ):
def scan_categories():
for x in os.listdir ( self.physical_location ):
diff --git a/roverlay/packageinfo.py b/roverlay/packageinfo.py
index b86d69d..bef9327 100644
--- a/roverlay/packageinfo.py
+++ b/roverlay/packageinfo.py
@@ -104,6 +104,7 @@ class PackageInfo ( object ):
'imported',
'physical_only',
'src_uri',
+ 'has_suggests',
))
_UPDATE_KEYS_SIMPLE_INITIAL = frozenset ((
'package_filename',
@@ -126,10 +127,13 @@ class PackageInfo ( object ):
arguments:
* **initial_info -- passed to update ( **kw )
"""
- self._info = dict()
- self.readonly = False
+ self._info = dict()
+ self.valid = True
+ self.readonly = False
+ self.logger = LOGGER
+ self.selfdeps = None
+
#self.overlay_package_ref = None
- self.logger = LOGGER
#self._evars = dict()
#self._lazy_actions = list()
#(or set(), but list preserves order for actions with the same condition)
@@ -137,6 +141,17 @@ class PackageInfo ( object ):
self.update ( **initial_info )
# --- end of __init__ (...) ---
+ def has_valid_selfdeps ( self ):
+ """Returns True if all selfdeps of this package are valid."""
+ v = self.valid
+ if v is True and self.selfdeps is not None and not all (
+ map ( lambda d: d.deps_satisfiable(), self.selfdeps )
+ ):
+ self.valid = False
+ return False
+ return v
+ # --- end of has_valid_selfdeps (...) ---
+
def attach_lazy_action ( self, lazy_action ):
"""Attaches a lazy action.
Unsafe operation (no locks will be acquired etc.).
@@ -664,11 +679,9 @@ class PackageInfo ( object ):
self._use_pvr ( value )
elif key == 'suggests':
+ # FIXME/TODO: remove
self._info ['has_suggests'] = value
- elif key == 'depres_result':
- self._info ['has_suggests'] = value [2]
-
elif key == 'filepath':
self._use_filepath ( value )
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2013-07-04 17:02 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-04 17:02 [gentoo-commits] proj/R_overlay:gsoc13/next commit in: roverlay/ebuild/, roverlay/depres/simpledeprule/, roverlay/depres/, roverlay/, André Erdmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox