aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'roverlay/ebuild')
-rw-r--r--roverlay/ebuild/abstractcomponents.py36
-rw-r--r--roverlay/ebuild/creation.py82
-rw-r--r--roverlay/ebuild/depres.py23
-rw-r--r--roverlay/ebuild/ebuilder.py30
-rw-r--r--roverlay/ebuild/evars.py26
5 files changed, 157 insertions, 40 deletions
diff --git a/roverlay/ebuild/abstractcomponents.py b/roverlay/ebuild/abstractcomponents.py
index 73dac03..019c252 100644
--- a/roverlay/ebuild/abstractcomponents.py
+++ b/roverlay/ebuild/abstractcomponents.py
@@ -5,11 +5,23 @@
INDENT = '\t'
def listlike ( ref ):
+ """Returns True if ref is listlike (a non-str iterable)."""
return hasattr ( ref, '__iter__' ) and not isinstance ( ref, str )
class ListValue ( object ):
+ """An evar value with a list of elements."""
def __init__ ( self, value, indent_level=1, empty_value=None ):
+ """Initializes a ListValue.
+
+ arguments:
+ * value --
+ * indent_level -- indention level ('\t') for extra value lines
+ * empty_value -- if set: a string value that is always part
+ of this ListValue's elements but ignored
+ by len().
+ Use cases are '${IUSE:-}' in the IUSE var etc.
+ """
self.set_level ( indent_level )
self.empty_value = empty_value
@@ -23,13 +35,14 @@ class ListValue ( object ):
self.val_join = ' '
self.set_value ( value )
-
+ # --- end of __init__ (...) ---
def __len__ ( self ):
l = len ( self.value )
return l if self.empty_value is None else l - 1
def set_level ( self, level ):
+ """Sets the indention level."""
self.level = level
self.var_indent = (level - 1) * INDENT
self.val_indent = level * INDENT
@@ -37,6 +50,7 @@ class ListValue ( object ):
# --- end of set_level (...) ---
def set_value ( self, value ):
+ """Sets the value."""
self.value = list()
if self.empty_value is not None:
self.value.append ( self.empty_value )
@@ -44,6 +58,7 @@ class ListValue ( object ):
# --- end of set_value (...) ---
def add_value ( self, value ):
+ """Adds/Appends a value."""
if value is None:
pass
elif listlike ( value ):
@@ -55,6 +70,7 @@ class ListValue ( object ):
add = add_value
def to_str ( self ):
+ """Returns a string representing this ListValue."""
if len ( self.value ) == 0:
ret = ""
elif len ( self.value ) == 1:
@@ -73,21 +89,37 @@ class ListValue ( object ):
class EbuildVar ( object ):
+ """An ebuild variable."""
def __init__ ( self, name, value, priority ):
+ """Initializes an EbuildVar.
+
+ arguments:
+ * name -- e.g. 'SRC_URI'
+ * value --
+ * priority -- used for sorting (e.g. 'R_SUGGESTS' before 'DEPEND'),
+ lower means higher priority
+ """
self.name = name
self.priority = priority
self.value = value
self.set_level ( 0 )
def set_level ( self, level ):
+ """Sets the indention level."""
self.level = level
self.indent = self.level * INDENT
if hasattr ( self.value, 'set_level' ):
self.value.set_level ( level + 1 )
# --- end of set_level (...) ---
- def active ( self ): return True
+ def active ( self ):
+ """Returns True if this EbuildVar is enabled and has a string to
+ return.
+ (EbuildVar's active() returns always True, derived classes may
+ override this.)
+ """
+ return True
def __str__ ( self ):
return '%s%s="%s"' % ( self.indent, self.name, self.value )
diff --git a/roverlay/ebuild/creation.py b/roverlay/ebuild/creation.py
index e2f4872..fca864d 100644
--- a/roverlay/ebuild/creation.py
+++ b/roverlay/ebuild/creation.py
@@ -1,4 +1,4 @@
-# R Overlay -- ebuild creation, <?>
+# R Overlay -- ebuild creation
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
@@ -10,13 +10,26 @@ from roverlay.rpackage.descriptionreader import DescriptionReader
LOGGER = logging.getLogger ( 'EbuildCreation' )
+# USE_FULL_DESCRIPTION
+# * True: use Title and Description for ebuild's DESCRIPTION variable
+# * else: use Title _or_ Description
USE_FULL_DESCRIPTION = False
+# FALLBACK_DESCRIPTION is used as DESCRIPTION= value if not empty and
+# the R package has no Title/Description
+FALLBACK_DESCRIPTION = "<none>"
class EbuildCreation ( object ):
+ """Used to create an ebuild using DESCRIPTION data."""
def __init__ ( self, package_info, depres_channel_spawner=None ):
+ """Initializes the creation of an ebuild.
+ arguments:
+ * package_info --
+ * depres_channel_spawner -- function that returns a communication
+ channel to the resolver
+ """
self.package_info = package_info
self.logger = LOGGER.getChild ( package_info ['name'] )
@@ -24,7 +37,6 @@ class EbuildCreation ( object ):
# > 0 busy/working; 0 == done,success; < 0 done,fail
self.status = 1
-
self.depres_channel_spawner = depres_channel_spawner
self.package_info.set_readonly()
@@ -36,6 +48,7 @@ class EbuildCreation ( object ):
def fail ( self ) : return self.status < 0
def run ( self ):
+ """Creates an ebuild. Returns None (implicit)."""
if self.status < 1:
raise Exception ( "Cannot run again." )
@@ -58,6 +71,8 @@ class EbuildCreation ( object ):
# --- end of run (...) ---
def _lazyimport_desc_data ( self ):
+ """Reads R package description data."""
+ # TODO/FIXME: read this somewhere else?
if self.package_info.get ( 'desc_data',
fallback_value=None, do_fallback=True ) is None:
@@ -75,23 +90,51 @@ class EbuildCreation ( object ):
# --- end of _lazyimport_desc_data (...) ---
+ def _get_ebuild_description ( self ):
+ """Creates a DESCRIPTION variable."""
+ desc = self.package_info ['desc_data']
+
+ description = None
+ if USE_FULL_DESCRIPTION:
+ # use Title and Description for DESCRIPTION=
+ if 'Title' in desc:
+ description = desc ['Title']
+
+ if 'Description' in desc:
+ if description is None:
+ description = desc ['Description']
+ else:
+ description += '// ' + desc ['Description']
+ else:
+ # use either Title or Description for DESCRIPTION=
+ # (Title preferred 'cause it should be shorter)
+ if 'Title' in desc:
+ description = desc ['Title']
+ elif 'Description' in desc:
+ description = desc ['Description']
+
+
+ if description is not None:
+ return evars.DESCRIPTION ( description )
+ elif FALLBACK_DESCRIPTION:
+ return evars.DESCRIPTION ( FALLBACK_DESCRIPTION )
+ else:
+ return None
+ # --- end of _get_ebuild_description (...) ---
def _make_ebuild ( self ):
- desc = self.package_info ['desc_data']
- if desc is None:
+ """Tries to create ebuild data."""
+ if self.package_info ['desc_data'] is None:
self.logger (
'desc empty - cannot create an ebuild for this package.'
)
return False
- ebuild = ebuilder.Ebuilder()
-
_dep_resolution = depres.EbuildDepRes (
self.package_info, self.logger,
create_iuse=True, run_now=True,
depres_channel_spawner=self.depres_channel_spawner
)
-
if not _dep_resolution.success():
# log here? (FIXME)
return False
@@ -99,29 +142,15 @@ class EbuildCreation ( object ):
dep_result = _dep_resolution.get_result()
+ ebuild = ebuilder.Ebuilder()
+
# add *DEPEND, IUSE to the ebuild
ebuild.use ( *dep_result [1] )
- description = None
- if USE_FULL_DESCRIPTION:
- if 'Title' in desc:
- description = desc ['Title']
-
- if 'Description' in desc:
- if description is None:
- description = desc ['Description']
- else:
- description += '// ' + desc ['Description']
- else:
- if 'Title' in desc:
- description = desc ['Title']
- elif 'Description' in desc:
- description = desc ['Description']
-
-
- if description is not None:
- ebuild.use ( evars.DESCRIPTION ( description ) )
+ # DESCRIPTION
+ ebuild.use ( self._get_ebuild_description() )
+ # SRC_URI
ebuild.use ( evars.SRC_URI ( self.package_info ['SRC_URI'] ) )
ebuild_text = ebuild.to_str()
@@ -132,3 +161,4 @@ class EbuildCreation ( object ):
)
return True
+ # --- end of _make_ebuild (...) ---
diff --git a/roverlay/ebuild/depres.py b/roverlay/ebuild/depres.py
index db0f906..3838060 100644
--- a/roverlay/ebuild/depres.py
+++ b/roverlay/ebuild/depres.py
@@ -6,7 +6,7 @@ import roverlay.static.depres
from roverlay.ebuild import evars
-# move this to const / config
+# TODO/FIXME/IGNORE move this to const / config
FIELDS = {
'R_SUGGESTS' : [ 'Suggests' ],
'DEPENDS' : [ 'Depends', 'Imports' ],
@@ -21,11 +21,21 @@ EBUILDVARS = {
class EbuildDepRes ( object ):
+ """Handles dependency resolution for a single ebuild."""
def __init__ (
self, package_info, logger, depres_channel_spawner,
create_iuse=True, run_now=True
):
+ """Initializes an EbuildDepRes.
+
+ arguments:
+ * package_info --
+ * logger -- parent logger
+ * depres_channel_spawner -- used to get channels to the dep resolver
+ * create_iuse -- create an IUSE evar (if True)
+ * run_now -- immediately start after initialization
+ """
self.logger = logger.getChild ( 'depres' )
self.package_info = package_info
@@ -56,10 +66,14 @@ class EbuildDepRes ( object ):
def fail ( self ) : return self.status < 0
def get_result ( self ):
+ """Returns the result of dependency resolution,
+ as tuple ( <status>, <evars>, <has R suggests> )
+ """
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._init_channels()
@@ -80,6 +94,7 @@ class EbuildDepRes ( object ):
# --- end of resolve (...) ---
def _get_channel ( self, dependency_type ):
+ """Creates and returns a communication channel to the dep resolver."""
if dependency_type not in self._channels:
self._channels [dependency_type] = self.request_resolver (
name=dependency_type,
@@ -89,6 +104,9 @@ class EbuildDepRes ( object ):
# --- end of get_channel (...) ---
def _init_channels ( self ):
+ """Initializes the resolver channels, one for each existing
+ dependency type. Queues dependencies, too.
+ """
# collect dep strings and initialize resolver channels
if self.request_resolver is None:
@@ -125,6 +143,7 @@ class EbuildDepRes ( object ):
# --- end of _init_channels (...) ---
def _close_channels ( self ):
+ """Closes the resolver channels."""
if self._channels is None: return
for channel in self._channels.values(): channel.close()
@@ -132,6 +151,7 @@ class EbuildDepRes ( object ):
# --- end of _close_channels (...) ---
def _wait_resolve ( self ):
+ """Wait for dep resolution."""
# True if no channels
for c in self._channels.values():
if c.satisfy_request() is None:
@@ -140,6 +160,7 @@ class EbuildDepRes ( object ):
# --- end of _wait_resolve (...) ---
def _make_result ( self ):
+ """Make evars using the depres result."""
_result = list()
for dep_type, channel in self._channels.items():
deplist = list ( filter ( None, channel.collect_dependencies() ) )
diff --git a/roverlay/ebuild/ebuilder.py b/roverlay/ebuild/ebuilder.py
index 275c6d2..aa7d8f5 100644
--- a/roverlay/ebuild/ebuilder.py
+++ b/roverlay/ebuild/ebuilder.py
@@ -1,22 +1,31 @@
-# R Overlay -- ebuild creation, <?>
+# R Overlay -- ebuild construction
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
class Ebuilder ( object ):
+ """Used to create ebuilds."""
def __init__ ( self ):
self._evars = list()
+ # newlines \n will be inserted after an evar if the priority
+ # delta (current evar, next evar) is >= this value.
+ # <= 0 means newline after each statement
+ self.min_newline_distance = 20
def sort ( self ):
- self._evars.sort ( key=lambda e: e.priority )
+ """Sorts the content of the Ebuilder."""
+ self._evars.sort ( key=lambda e: ( e.priority, e.name ) )
+ #self._evars.sort ( key=lambda e: e.priority )
def get_lines ( self ):
+ """Creates and returns (ordered) text lines."""
+
self.sort()
last = len ( self._evars ) - 1
- newline = lambda i, k=1 : \
- abs ( self._evars [i + k].priority - self._evars [i].priority ) >= 20
-
+ newline = lambda i, k=1 : abs (
+ self._evars [i + k].priority - self._evars [i].priority
+ ) >= self.min_newline_distance
lines = list()
for index, e in enumerate ( self._evars ):
@@ -25,12 +34,17 @@ class Ebuilder ( object ):
if index < last and newline ( index ): lines.append ( '' )
return lines
+ # --- end of get_lines (...) ---
- def to_str ( self ):
- return '\n'.join ( self.get_lines() )
+ def to_str ( self ): return '\n'.join ( self.get_lines() )
__str__ = to_str
def use ( self, *evar_list ):
+ """Adds evars to this Ebuilder.
+
+ arguments:
+ * *evar_list --
+ """
for e in evar_list:
- self._evars.append ( e )
+ if e is not None: self._evars.append ( e )
diff --git a/roverlay/ebuild/evars.py b/roverlay/ebuild/evars.py
index 78a7326..da34c68 100644
--- a/roverlay/ebuild/evars.py
+++ b/roverlay/ebuild/evars.py
@@ -1,4 +1,4 @@
-# R Overlay -- ebuild creation, <?>
+# R Overlay -- ebuild construction, ebuild variables
# Copyright 2006-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
@@ -12,24 +12,40 @@ RSUGGESTS_NAME = "R_SUGGESTS"
# ignoring case policies here (camel case,..)
class DESCRIPTION ( EbuildVar ):
- def __init__ ( self, description ):
+ """A DESCRIPTION="..." statement."""
+ def __init__ ( self, description, maxlen=50 ):
+ """A DESCRIPTION="..." statement. Long values will be truncated.
+
+ arguments:
+ * description -- description text
+ * maxlen -- maximum value length (defaults to 50 chars)
+ """
super ( DESCRIPTION, self ) . __init__ ( 'DESCRIPTION', description, 80 )
+ self.maxlen = 50 if maxlen is None else maxlen
def __str__ ( self ):
return '%s%s="%s"' % (
self.indent,
self.name,
- shorten_str ( str ( self.value ) , 50, '... (see metadata)' )
+ shorten_str ( str ( self.value ) , self.maxlen, '... (see metadata)' )
)
class SRC_URI ( EbuildVar ):
+ """A SRC_URI="..." statement."""
def __init__ ( self, src_uri ):
super ( SRC_URI, self ) . __init__ ( 'SRC_URI', src_uri, 90 )
class IUSE ( EbuildVar ):
+ """An IUSE="..." statement."""
def __init__ ( self, use_flags=None, using_suggests=False ):
+ """An IUSE="..." statement.
+
+ arguments:
+ * use_flags -- IUSE value
+ * using_suggests -- if True: enable R_Suggests USE flag
+ """
super ( IUSE, self ) . __init__ (
'IUSE',
ListValue ( use_flags, empty_value='${IUSE:-}' ),
@@ -41,6 +57,7 @@ class IUSE ( EbuildVar ):
class R_SUGGESTS ( EbuildVar ):
+ """A R_SUGGESTS="..." statement."""
def __init__ ( self, deps, **kw ):
super ( R_SUGGESTS, self ) . __init__ (
RSUGGESTS_NAME,
@@ -50,6 +67,7 @@ class R_SUGGESTS ( EbuildVar ):
class DEPEND ( EbuildVar ):
+ """A DEPEND="..." statement."""
def __init__ ( self, deps, **kw ):
super ( DEPEND, self ) . __init__ (
'DEPEND',
@@ -59,6 +77,7 @@ class DEPEND ( EbuildVar ):
class RDEPEND ( EbuildVar ):
+ """A RDEPEND="..." statement."""
def __init__ ( self, deps, using_suggests=False, **kw ):
super ( RDEPEND, self ) . __init__ (
'RDEPEND',
@@ -68,4 +87,5 @@ class RDEPEND ( EbuildVar ):
if using_suggests: self.enable_suggests()
def enable_suggests ( self ):
+ """Adds the optional R_SUGGESTS dependencies to RDEPEND."""
self.value.add ( '%s? ( ${%s} )' % ( IUSE_SUGGESTS, RSUGGESTS_NAME ) )